I
info_
Guest
Hi,
I would make a few of suggestions :
* use an enumeration and traditional "case state is when =>"
construct. This facilitates a lot of things, if only for the
synthesis tool to properly recognize your FSM, but also for
HSL simulation, readability, reliability, optimization etc...
* to output the state vector, use a simple decoder (which
will be probably eliminated by synthesis). And maybe you don't
want the one-hot vector vector to come out, but an binary
(more compact) version ?
* Single-process style is easier to write (imo) and not prone
to the usual errors in combinational processes.
(you're not the first and not the last to get caught)
You can even write Moore style in one process if
you don't want to move your actions in the transitions.
* Keep in mind that the synthesizer sometimes can guess
the "parallel case" and sometime can't.
This is likely your case (can't guess). It should have
trouble understanding that individual bit comparisons are
(probably) mutually exclusive.
So I'm afraid it would code the priority you've told him
implicitly to implement (last "if" does win).
I think this is inefficient synthesis-wise.
On my Website, you'll find many FSM examples, FWIW
http://www.alse-fr.com/English/ips.html
I never really liked the "textbook" two-processes style,
and I've seen lots of problems in code written this way...
But Text editors, FSM coding and VHDL vs Verilog are
almost religious issues ...
Bert
Preben Holm wrote:
I would make a few of suggestions :
* use an enumeration and traditional "case state is when =>"
construct. This facilitates a lot of things, if only for the
synthesis tool to properly recognize your FSM, but also for
HSL simulation, readability, reliability, optimization etc...
* to output the state vector, use a simple decoder (which
will be probably eliminated by synthesis). And maybe you don't
want the one-hot vector vector to come out, but an binary
(more compact) version ?
* Single-process style is easier to write (imo) and not prone
to the usual errors in combinational processes.
(you're not the first and not the last to get caught)
You can even write Moore style in one process if
you don't want to move your actions in the transitions.
* Keep in mind that the synthesizer sometimes can guess
the "parallel case" and sometime can't.
This is likely your case (can't guess). It should have
trouble understanding that individual bit comparisons are
(probably) mutually exclusive.
So I'm afraid it would code the priority you've told him
implicitly to implement (last "if" does win).
I think this is inefficient synthesis-wise.
On my Website, you'll find many FSM examples, FWIW
http://www.alse-fr.com/English/ips.html
I never really liked the "textbook" two-processes style,
and I've seen lots of problems in code written this way...
But Text editors, FSM coding and VHDL vs Verilog are
almost religious issues ...
Bert
Preben Holm wrote:
Hi everyone,
I try to construct this statemachine as described in VHDL below:
(the machine is supposed to set the hold as soon as the trig-signal is
asserted (initialized only when all signals have been low for a
clock-cycle) and go low when both the read and holdoff signals have been
asserted for some time...
------------------------------------------
entity holdoffcontroller is
Port ( clk : in std_logic;
reset : in std_logic;
save : in std_logic;
trig : in std_logic;
read : in std_logic;
holdoff : in std_logic;
hold : out std_logic;
state : out std_logic_vector(4 downto 0));
end holdoffcontroller;
architecture Behavioral of holdoffcontroller is
constant stateStart : std_logic_vector(4 downto 0) := "00001";
constant stateWait : std_logic_vector(4 downto 0) := "00010";
constant stateTrigger : std_logic_vector(4 downto 0) := "00100";
constant stateHold : std_logic_vector(4 downto 0) := "01000";
constant stateRead : std_logic_vector(4 downto 0) := "10000";
begin
STATEMACHINE: block
signal current_state, next_state : std_logic_vector(4 downto 0)
:= stateStart;
begin
stateRegister : process(clk, reset)
begin
if reset = '1' then
current_state <= stateStart;
elsif rising_edge(clk) then
current_state <= next_state;
end if;
end process;
stateTransitions : process(current_state, holdoff, read, trig)
begin
-- stateStart
if current_state(0) = '1' then
hold <= '0';
if holdoff = '0' and read = '0' and trig = '0' then
next_state <= stateWait;
end if;
end if;
etc..