E
E. Backhus
Guest
Hi everybody,
while I was trying to create a statemachine with registered outputs
which shouldn't be delayed by one clock cycle (as usual when just
putting a register behind the outputs of the FSM) I modified some
sourcecode from the XILINX ISE Language Templates for sythesis. As an
example I tried to recreate the stopwatch statemachine from the ISE 5
In depth tutorial.
Everything works fine insofar that the function is correct and
itentical to the original design and it also synthesizes fine with one
little exeption:
The XST-Synthesis Tool does not recognize my coding style as a FSM,
therefore it wont do the neccessary optimizations. For comparision
purposes I have added some XST-synthesis report snippets to outline
the differences:
While my coding style produces a register and some feedback logic
around it, for the original code (Produced by StateCAD) XST inferes a
FSM and applies all optimizations on it.
(When I comment out the enum_encoding attributes in my code then
register CS will become One-State-Hot encoded, but no OSH-FSM will be
created. Instead some clumsy binary FSM with an unreal OSH encoding
(all statebits zero!!! - not allowed for OSH encoding!!!) will be
generated.
So, what trick makes the XST-Synthesis tool recognize my coding style
to be a FSM working in the way I want (that is with registered outputs
but no delay by one clock cycle)?
All help is appreciated.
Thanks
Eilert
=========================================================================
* HDL Synthesis
*
=========================================================================
Synthesizing Unit <elis_statemachine>.
Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/ELIS_Statemachine.vhd.
Found 1-bit register for signal <clockenableout>.
Found 1-bit register for signal <resetout>.
Found 3-bit register for signal <cs>.
Summary:
inferred 5 D-type flip-flop(s).
Unit <elis_statemachine> synthesized.
=========================================================================
HDL Synthesis Report
Macro Statistics
# Registers : 3
3-bit register : 1
1-bit register : 2
=========================================================================
=========================================================================
* HDL Synthesis
*
=========================================================================
Synthesizing Unit <stmach>.
Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/STMACH.vhd.
Found finite state machine <FSM_0> for signal <sreg>.
-----------------------------------------------------------------------
| States | 6
|
| Transitions | 11
|
| Inputs | 1
|
| Outputs | 2
|
| Reset type | asynchronous
|
| Encoding | automatic
|
| State register | d flip-flops
|
-----------------------------------------------------------------------
Summary:
inferred 1 Finite State Machine(s).
Unit <stmach> synthesized.
=========================================================================
HDL Synthesis Report
Macro Statistics
# FSMs : 1
=========================================================================
Optimizing FSM <FSM_0> with One-Hot encoding and d flip-flops.
Sourcecode of elis_statemachine.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ELIS_Statemachine is
Port ( Clock : in std_logic;
Reset : in std_logic;
StartStop : in std_logic;
ClockEnableOut : out std_logic;
ResetOut : out std_logic);
end ELIS_Statemachine;
architecture Behavioral of ELIS_Statemachine is
type STATE_TYPE is (Clear,Zero,Start,Counting,Stop,Stopped);
attribute ENUM_ENCODING: STRING;
attribute ENUM_ENCODING of STATE_TYPE: type is "000 101 010 001 011
100";
signal CS : STATE_TYPE;
signal NS : STATE_TYPE;
begin
SYNC_PROC: process (CLOCK, RESET)
begin
if (RESET='1') then
CS <= Clear;
elsif (CLOCK'event and CLOCK = '1') then
CS <= NS;
end if;
end process;
COMB_PROC: process (CS, StartStop)
begin
case CS is
when clear => NS <= Zero;
when Zero => If StartStop = '1' then
NS <= Start;
else
NS <= Zero;
end if;
when Start => If StartStop = '0' then
NS <= Counting;
else
NS <= Start;
end if;
when Counting => If StartStop = '1' then
NS <= Stop;
else
NS <= Counting;
end if;
when Stop => If StartStop = '0' then
NS <= Stopped;
else
NS <= Stop;
end if;
when Stopped => If StartStop = '1' then
NS <= Zero;
else
NS <= Stopped;
end if;
when others => NS <= Clear;
end case;
end process;
Sync_Output : process (Reset, Clock)
begin
if (RESET='1') then
ClockEnableOut <= '0';
ResetOut <= '1';
elsif (CLOCK'event and CLOCK = '1') then
case NS is
when clear => ClockEnableOut <= '0';
ResetOut <= '1';
when Zero => ClockEnableOut <= '0';
ResetOut <= '0';
when Start => ClockEnableOut <= '1';
ResetOut <= '0';
when Counting => ClockEnableOut <= '1';
ResetOut <= '0';
when Stop => ClockEnableOut <= '0';
ResetOut <= '0';
when Stopped => ClockEnableOut <= '0';
ResetOut <= '0';
when others => ClockEnableOut <= '0';
ResetOut <= '1';
end case;
end if;
end process;
end Behavioral;
Sourcecode of stmach.vhd :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY STMACH IS
PORT (CLK,RESET,strtstop: IN std_logic;
clkout,rst : OUT std_logic);
END;
ARCHITECTURE BEHAVIOR OF STMACH IS
SIGNAL sreg : std_logic_vector (2 DOWNTO 0);
SIGNAL next_sreg : std_logic_vector (2 DOWNTO 0);
CONSTANT clear : std_logic_vector (2 DOWNTO 0) :="000";
CONSTANT counting : std_logic_vector (2 DOWNTO 0) :="001";
CONSTANT start : std_logic_vector (2 DOWNTO 0) :="010";
CONSTANT stop : std_logic_vector (2 DOWNTO 0) :="011";
CONSTANT stopped : std_logic_vector (2 DOWNTO 0) :="100";
CONSTANT zero : std_logic_vector (2 DOWNTO 0) :="101";
BEGIN
PROCESS (CLK, RESET, next_sreg)
BEGIN
IF ( RESET='1' ) THEN
sreg <= clear;
ELSIF CLK='1' AND CLK'event THEN
sreg <= next_sreg;
END IF;
END PROCESS;
PROCESS (sreg,strtstop)
BEGIN
clkout <= '0'; rst <= '0';
next_sreg<=clear;
CASE sreg IS
WHEN clear =>
clkout<='0';
rst<='1';
IF TRUE THEN
next_sreg<=zero;
ELSE
next_sreg<=clear;
END IF;
WHEN counting =>
clkout<='1';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=counting;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=counting;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=stop;
END IF;
WHEN start =>
clkout<='1';
rst<='0';
IF NOT ( (( strtstop='1' ) ) OR (( strtstop='0' ) ) ) THEN
next_sreg<=start;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=counting;
END IF;
WHEN stop =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='1' ) ) OR (( strtstop='0' ) ) ) THEN
next_sreg<=stop;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=stop;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=stopped;
END IF;
WHEN stopped =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=stopped;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=stopped;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
WHEN zero =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=zero;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=zero;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
WHEN OTHERS =>
END CASE;
END PROCESS;
END BEHAVIOR;
while I was trying to create a statemachine with registered outputs
which shouldn't be delayed by one clock cycle (as usual when just
putting a register behind the outputs of the FSM) I modified some
sourcecode from the XILINX ISE Language Templates for sythesis. As an
example I tried to recreate the stopwatch statemachine from the ISE 5
In depth tutorial.
Everything works fine insofar that the function is correct and
itentical to the original design and it also synthesizes fine with one
little exeption:
The XST-Synthesis Tool does not recognize my coding style as a FSM,
therefore it wont do the neccessary optimizations. For comparision
purposes I have added some XST-synthesis report snippets to outline
the differences:
While my coding style produces a register and some feedback logic
around it, for the original code (Produced by StateCAD) XST inferes a
FSM and applies all optimizations on it.
(When I comment out the enum_encoding attributes in my code then
register CS will become One-State-Hot encoded, but no OSH-FSM will be
created. Instead some clumsy binary FSM with an unreal OSH encoding
(all statebits zero!!! - not allowed for OSH encoding!!!) will be
generated.
So, what trick makes the XST-Synthesis tool recognize my coding style
to be a FSM working in the way I want (that is with registered outputs
but no delay by one clock cycle)?
All help is appreciated.
Thanks
Eilert
=========================================================================
* HDL Synthesis
*
=========================================================================
Synthesizing Unit <elis_statemachine>.
Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/ELIS_Statemachine.vhd.
Found 1-bit register for signal <clockenableout>.
Found 1-bit register for signal <resetout>.
Found 3-bit register for signal <cs>.
Summary:
inferred 5 D-type flip-flop(s).
Unit <elis_statemachine> synthesized.
=========================================================================
HDL Synthesis Report
Macro Statistics
# Registers : 3
3-bit register : 1
1-bit register : 2
=========================================================================
=========================================================================
* HDL Synthesis
*
=========================================================================
Synthesizing Unit <stmach>.
Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/STMACH.vhd.
Found finite state machine <FSM_0> for signal <sreg>.
-----------------------------------------------------------------------
| States | 6
|
| Transitions | 11
|
| Inputs | 1
|
| Outputs | 2
|
| Reset type | asynchronous
|
| Encoding | automatic
|
| State register | d flip-flops
|
-----------------------------------------------------------------------
Summary:
inferred 1 Finite State Machine(s).
Unit <stmach> synthesized.
=========================================================================
HDL Synthesis Report
Macro Statistics
# FSMs : 1
=========================================================================
Optimizing FSM <FSM_0> with One-Hot encoding and d flip-flops.
Sourcecode of elis_statemachine.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ELIS_Statemachine is
Port ( Clock : in std_logic;
Reset : in std_logic;
StartStop : in std_logic;
ClockEnableOut : out std_logic;
ResetOut : out std_logic);
end ELIS_Statemachine;
architecture Behavioral of ELIS_Statemachine is
type STATE_TYPE is (Clear,Zero,Start,Counting,Stop,Stopped);
attribute ENUM_ENCODING: STRING;
attribute ENUM_ENCODING of STATE_TYPE: type is "000 101 010 001 011
100";
signal CS : STATE_TYPE;
signal NS : STATE_TYPE;
begin
SYNC_PROC: process (CLOCK, RESET)
begin
if (RESET='1') then
CS <= Clear;
elsif (CLOCK'event and CLOCK = '1') then
CS <= NS;
end if;
end process;
COMB_PROC: process (CS, StartStop)
begin
case CS is
when clear => NS <= Zero;
when Zero => If StartStop = '1' then
NS <= Start;
else
NS <= Zero;
end if;
when Start => If StartStop = '0' then
NS <= Counting;
else
NS <= Start;
end if;
when Counting => If StartStop = '1' then
NS <= Stop;
else
NS <= Counting;
end if;
when Stop => If StartStop = '0' then
NS <= Stopped;
else
NS <= Stop;
end if;
when Stopped => If StartStop = '1' then
NS <= Zero;
else
NS <= Stopped;
end if;
when others => NS <= Clear;
end case;
end process;
Sync_Output : process (Reset, Clock)
begin
if (RESET='1') then
ClockEnableOut <= '0';
ResetOut <= '1';
elsif (CLOCK'event and CLOCK = '1') then
case NS is
when clear => ClockEnableOut <= '0';
ResetOut <= '1';
when Zero => ClockEnableOut <= '0';
ResetOut <= '0';
when Start => ClockEnableOut <= '1';
ResetOut <= '0';
when Counting => ClockEnableOut <= '1';
ResetOut <= '0';
when Stop => ClockEnableOut <= '0';
ResetOut <= '0';
when Stopped => ClockEnableOut <= '0';
ResetOut <= '0';
when others => ClockEnableOut <= '0';
ResetOut <= '1';
end case;
end if;
end process;
end Behavioral;
Sourcecode of stmach.vhd :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY STMACH IS
PORT (CLK,RESET,strtstop: IN std_logic;
clkout,rst : OUT std_logic);
END;
ARCHITECTURE BEHAVIOR OF STMACH IS
SIGNAL sreg : std_logic_vector (2 DOWNTO 0);
SIGNAL next_sreg : std_logic_vector (2 DOWNTO 0);
CONSTANT clear : std_logic_vector (2 DOWNTO 0) :="000";
CONSTANT counting : std_logic_vector (2 DOWNTO 0) :="001";
CONSTANT start : std_logic_vector (2 DOWNTO 0) :="010";
CONSTANT stop : std_logic_vector (2 DOWNTO 0) :="011";
CONSTANT stopped : std_logic_vector (2 DOWNTO 0) :="100";
CONSTANT zero : std_logic_vector (2 DOWNTO 0) :="101";
BEGIN
PROCESS (CLK, RESET, next_sreg)
BEGIN
IF ( RESET='1' ) THEN
sreg <= clear;
ELSIF CLK='1' AND CLK'event THEN
sreg <= next_sreg;
END IF;
END PROCESS;
PROCESS (sreg,strtstop)
BEGIN
clkout <= '0'; rst <= '0';
next_sreg<=clear;
CASE sreg IS
WHEN clear =>
clkout<='0';
rst<='1';
IF TRUE THEN
next_sreg<=zero;
ELSE
next_sreg<=clear;
END IF;
WHEN counting =>
clkout<='1';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=counting;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=counting;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=stop;
END IF;
WHEN start =>
clkout<='1';
rst<='0';
IF NOT ( (( strtstop='1' ) ) OR (( strtstop='0' ) ) ) THEN
next_sreg<=start;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=counting;
END IF;
WHEN stop =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='1' ) ) OR (( strtstop='0' ) ) ) THEN
next_sreg<=stop;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=stop;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=stopped;
END IF;
WHEN stopped =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=stopped;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=stopped;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
WHEN zero =>
clkout<='0';
rst<='0';
IF NOT ( (( strtstop='0' ) ) OR (( strtstop='1' ) ) ) THEN
next_sreg<=zero;
END IF;
IF ( strtstop='0' ) THEN
next_sreg<=zero;
END IF;
IF ( strtstop='1' ) THEN
next_sreg<=start;
END IF;
WHEN OTHERS =>
END CASE;
END PROCESS;
END BEHAVIOR;