Vhdl How Can I reset this signal - vhdl

I'm trying to send two data to PC according to a counter. I need to send this two data just once, so I'm using a signal called "New_data_s". But my problem is this signal stays "High" too much and the data is being sent more than once. I'm sending "Datafll_s" by the way.
This is a picture of the first simulation: Sim1
Then I added another signal called "Stop_s" to reset this "New_data_s". Okay it sends the data just once, but this time, I can't reset "Stop_s". Once it goes "High" it stays "High" until I press the button. So I can't send the second data.
This is a picture of the second simulation: Sim2
I know if I don't press the button this "ELSIF(Go_s='1' and Go_s_ff='0')Then" condition is not TRUE, so that's why "Stop_s" stays "High" until I press the button. But, I couldn't find a way to do this.
Counter part:
IF(Cnt_Spc_P1>15 and Cnt_Spc_P1<=30)Then
Three_spc_s<='1';
Seven_spc_s<='0';
ELSIF(Cnt_Spc_P1>30 and Cnt_Spc_P1<50)Then
Three_spc_s<='0';
Seven_spc_s<='1';
ELSIF(Cnt_Spc_P1=50)Then
Three_spc_s<='0';
Seven_spc_s<='1';
Enable_1_s<='0';
Cnt_Spc_P1<=0;
ELSE
Three_spc_s<='0';
Seven_spc_s<='0';
END IF;
Main part:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Letters is
Port(
Clk: in std_logic;
Reset: in std_logic;
Dot: in std_logic;
Dash: in std_logic;
Error : out std_logic;
New_data: out std_logic;
three_spc: in std_logic;
seven_spc: in std_logic;
d_out_d: out std_logic_vector(6 downto 0);
d_out_a: out std_logic_vector(7 downto 0)
);
END Letters;
-------------------------------------------------------------------------------
Architecture Letters_a of Letters is
-------------------------------------------------------------------------------
Type state is (Start, Space, T, E);
Signal current_s: state;
Signal Go_s, Go_s_ff: std_logic:='0';
signal data_d : std_logic_vector(6 downto 0):="1100100";
signal data_a : std_logic_vector(7 downto 0):="00000000";
Signal Error_s, New_data_s : std_logic:='0';
Signal Stop_s : std_logic:='0';
-------------------------------------------------------------------------------
BEGIN
-------------------------------------------------------------------------------
PROCESS(Clk, three_spc, seven_spc, current_s, Reset)
BEGIN
IF(Reset='1')Then
current_s<=Start;
data_d<="0000000";
data_a<="00000000";
d_out_d<="1100100";
Error_s<='0';
New_data_s<='0';
Stop_s<='0';
ELSIF(Rising_Edge(Clk))Then
IF(three_spc='1')Then
d_out_d<=data_d;
d_out_a<=data_a;
New_data_s<='1';
Stop_s<='1';
current_s<=Start;
ELSIF(seven_spc='1')Then
current_s<=Space;
d_out_d<=data_d;
d_out_a<="00100000";
New_data_s<='1';
Stop_s<='1';
current_s<=Start;
ELSIF(Go_s='1' and Go_s_ff='0')Then
Case current_s is
When Start =>
New_data_s<='0';
Stop_s<='0';
IF(Dash='1')Then
current_s<=T;
data_d<="1100100";
data_a<="01010100";
Error_s<='0';
ELSIF(Dot='1')Then
current_s<=E;
Error_s<='0';
data_d<="0000110";
data_a<="01000101";
END IF;
-------------------------------------------------------------------------------
When T =>
IF(Dash='1')Then
current_s<=M;
data_d<="1100100";
data_a<="01001101";
ELSIF(Dot='1')Then
current_s<=N;
data_d<="0101011";
data_a<="01001110";
END IF;
-------------------------------------------------------------------------------
When E =>
IF(Dash='1')Then
current_s<=A;
data_d<="0001000";
data_a<="01000001";
ELSIF(Dot='1')Then
current_s<=I;
data_d<="1111001";
data_a<="01001001";
END IF;
When OTHERS =>
current_s <= Start;
Error_s<='1'; -- Unidentified letter.
data_d<="1100100";
New_data_s<='0';
Stop_s<='0';
END Case;
END IF;
IF(Stop_s='1')Then
New_data_s<='0';
END IF;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
PROCESS(Clk, Dot, Dash, Reset)
BEGIN
Go_s<=Dash or Dot;
IF(Reset='1')Then
Go_s<='0';
Go_s_ff<='0';
ELSIF(Rising_Edge(Clk))Then
Go_s_ff<=Go_s;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
Error<=Error_s;
New_data<=New_data_s;
-------------------------------------------------------------------------------
END Letters_a;
Thank you.

I see that you've declared an enumerated type state and instantiated a signal current_s of type state. The enumerated type includes the literals, (Start, Space, T, E), but you assign literals M, N and A to signal current_s which are not members of the state type. Your compiler should complain about that. Does it?
The fsm included in your code is a bit difficult to follow because state transition code is mixed with output signal logic. So, I've rewritten it and posted it below. My fsm may not exactly represent the functionality you're looking for, however, you can use it as a template. It illustrates how to generate a one clock wide edge detector for the dot and dash signals. It also illustrates how to control the data strobe signal that you were having difficulty switching on and off.
The output logic does not take full advantage of the default signal values that proceed the output logic case statement so that it will be easier for you to see what's happening. However, many of the statements within the case could be eliminated for compactness.
Also, I haven't compiled the code, so you may find a few syntax errors, but the template should be of use to you.
-- Note, not all signals are declared here, refer to the posted code for them
Type state_t is (Idle, start_dot, start_dash, E_dot, strobe_3spc_data,
wait_1, strobe_7spc_data, wait_2, E_dash);
signal state_snoop : state_t; -- use to monitor state in simulator
signal dash_ff : std_logic;
signal dash_pulse : std_logic;
signal dot_ff : std_logic;
signal dot_pulse : std_logic;
fsm: process (clk)
variable current_s : state_t;
begin
if rising_edge(clk) then
if Reset = '1' then
current_s := Idle;
else
case Idle is
when Idle =>
if dot_pulse = '1' then
current_s := start_dot;
elsif dash_pulse = '1' then
current_s := start_dash;
end if;
-- dot related states ----------------------
when start_dot =>
current_s := E_dot;
when E_dot =>
if three_spc = '1' then
current_s := strobe_3spc_data;
end if;
when strobe_3spc_data =>
if seven_spc = '1' then -- counter strobe from external source
current_s := wait_1;
end if;
when wait_1 =>
if seven_spc = '1' then -- counter strobe from external source
current_s := strobe_7spc_data;
end if;
when strobe_7spc_data =>
current_s := wait_2;
when wait_2 =>
current_s := idle;
-- dash related states ----------------------
when start_dash =>
current_s := E_dash;
when E_dash =>
if three_spc = '1' then
current_s := strobe_3spc_data;
end if;
end case;
end if;
end if;
state_snoop <= current_s; -- monitor state in simulator. variables are hard to monitor
-------------- outputs decoded from state variable -------------------
-- default signal values
New_data_s <= '0';
data_d <= "0000000"; data_a <= "00000000"; d_out_d <= "0000000";
Stop_s <= '0'; Error_s <= '0';
case current_s is
when Idle =>
data_d <= "0000000";
data_a <= "00000000";
d_out_d <= "1100100";
Error_s <= '0';
New_data_s <= '0';
when start_dot =>
data_d <= "0000110"; --'ACK'
data_a <= "01000101"; -- ascii dash -> 'E'
Error_s <= '0';
New_data_s <= '0';
when E_dot =>
data_d <= "1111001";
data_a <= "01001001";
when strobe_3spc_data =>
d_out_d <= data_d;
d_out_a <= data_a;
New_data_s <= '1';
when wait_1 => -- switch data strobe off for first data transmission
New_data_s <= '0';
when strobe_7spc_data =>
d_out_d <= data_d;
d_out_a <= "00100000";
New_data_s <= '1';
when wait_2 => -- switch data strobe off for second data transmission
New_data_s <= '0';
-- dash related outputs
when start_dash =>
data_d <= "1100100"; --'t'
data_a <= "01010100"; --'T'
Error_s <= '0';
New_data_s <= '0';
when E_dash =>
data_d <= "0001000";
data_a <= "01000001";
when others => null;
end case;
-- rising edge detector for dash and dot input.
if Reset = '1' then
dash_pulse <= '0'
else
dash_ff << not(Dash);
dash_pulse << dash_ff and dash;
end if;
if Reset = '1' then
dot_pulse <= '0'
else
dot_ff << not(dot);
dot_pulse << dot_ff and dot;
end if;
end process fsm

Related

In behavioral simulation, my FSM have a state that take more than 1 clock cycle ... And i don't like it

Please forgive myself if you will find some trivial errors in my code .. I'm still a beginner with VHDL.
Well, I have to deal with a serial interface from an ADC. The interface is quite simple ... there is a wire for the serial data (a frame of 24 bits), a signal DRDY that tells me when the new sample data is available and a serial clock (SCLK) that push the bit into (rising edge). Everything is running continuously...
I need to capture correctly the 24 bit of the sample, put them on a parallel bus (shift register) and provide a "data valid" signal for the blocks that will process the samples ...
Due to the fact that my system clock is x4 the frequency of the serial interface, i was thinking that doing the job with a FSM will be easy ...
When you look into the code you will see a process to capture the rising edges of the DRDY and SCLK.
Then a FSM with few states (Init, wait_drdy, wait_sclk, inc_count, check_count).
I use a counter (cnt unsigned) to check if I've already captured the 24 bits, using also to redirect the states of the FSM in "check_count" state.
Here a picture:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity serial_ads1675 is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
sclk : in std_logic;
sdata : in std_logic;
drdy : in std_logic;
pdata : out std_logic_vector(23 downto 0);
pdready : out std_logic
);
end serial_ads1675;
architecture Behavioral of serial_ads1675 is
-- Internal declarations
signal ipdata : std_logic_vector (23 downto 0);
signal ipdready : std_logic;
signal tmp1, tmp2, tmp3, tmp4 : std_logic;
signal rise_drdy, rise_sclk : std_logic;
signal cnt : unsigned (4 downto 0);
type state is (init, wait_drdy, wait_sclk, inc_count, check_count);
signal actual_state, next_state : state;
begin
-- Concurrent statements
pdata <= ipdata;
pdready <= ipdready;
rise_drdy <= '1' when ((tmp1 = '1') and (tmp2 = '0')) else '0';
rise_sclk <= '1' when ((tmp3 = '1') and (tmp4 = '0')) else '0';
-- Process
process (clk, reset)
begin
if(reset = '0') then
tmp1 <= '0';
tmp2 <= '0';
tmp3 <= '0';
tmp4 <= '0';
elsif (falling_edge(clk)) then
tmp1 <= drdy;
tmp2 <= tmp1;
tmp3 <= sclk;
tmp4 <= tmp3;
end if;
end process;
process (reset, clk)
begin
if (reset = '0') then
actual_state <= init;
elsif (rising_edge(clk)) then
actual_state <= next_state;
end if;
end process;
process (rise_sclk, rise_drdy) -- Next State affectation
begin
case actual_state is
when init =>
next_state <= wait_drdy;
ipdata <= (others => '0');
ipdready <= '0';
cnt <= (others => '0');
when wait_drdy =>
if (rise_drdy = '0') then
next_state <= actual_state;
else
next_state <= wait_sclk;
end if;
cnt <= (others => '0');
when wait_sclk =>
if (rise_sclk = '0') then
next_state <= actual_state;
else
next_state <= inc_count;
end if;
ipdready <= '0';
when inc_count =>
next_state <= check_count;
cnt <= cnt + 1;
ipdready <= '0';
ipdata(23 downto 1) <= ipdata(22 downto 0);
ipdata(0) <= sdata;
when check_count =>
case cnt is
when "11000" =>
next_state <= wait_drdy;
ipdready <= '1';
when others =>
next_state <= wait_sclk;
ipdready <= '0';
end case;
when others =>
next_state <= init;
end case;
end process;
end Behavioral;
My problem is during the check_count state ...
I'm expecting that this state should last one system clock cycle, but actually it last much more.
Here a snapshot of the behavioral simulation:
Due to the fact that this state last more than expected, i miss the following SCLK pulse and don't record the next bit ...
I don't understand why this state last so many system clock cycles instead of just one ...
Anyone has some clues and bring some light in my dark night ?
Thanks in advance.
Edit: I've tried to change the signal cnt for an integer variable internal to the process of the FSM ... Same results
The error is this:
process (rise_sclk, rise_drdy) -- Next State affectation
begin
-- code omitted, but does generally this:
next_state <= SOME_VALUE;
end process;
Because the sensitivity list includes only the signals rise_sclk and rise_drdy, the process is "executed" only if any of these signals changes. You can follow this in the wave diagram.
You don't have a synchronous design running on clk. Put clk on the sensitivity list and base the decisions on the levels of rise_sclk and rise_drdy. As an excerpt:
process (clk) -- Next State affectation
begin
if rising_edge(clk) then
case actual_state is
when init =>
next_state <= wait_drdy;
-- and so on
end case;
end if;
end process;

vhdl clock input to output as a finite state machine

I have to generate the vhdl code for the signal generator above as a finite state machine. What I cant manage to implement is this. How to generate
the clock values to output. To be more specific, I want for half period
output 0 and the other half 1, when the state machine is in state clock. My implementation, as you can see on the
code below, is output <= clock but this obviously does not work. I made a finite machine with 4 states (s1, s2, s3, s4)
My testbench and my vhdl code are these:
testbench
library ieee;
use ieee.std_logic_1164.all;
entity signal_generator_tb is
end entity;
architecture signal_generator_tb_arch of signal_generator_tb is
signal clock_tb, reset_tb: std_logic;
signal output_tb: std_logic;
component signal_generator
port(clock, reset: in std_logic;
output: out std_logic);
end component;
begin
dut : signal_generator port map(clock_tb, reset_tb, output_tb);
stim_reset : process
begin
reset_tb <= '0'; wait for 10 ns;
reset_tb <= '1'; wait;
end process;
stim_clock : process
begin
clock_tb <= '1'; wait for 10 ns;
clock_tb <= '0'; wait for 10 ns;
end process;
end architecture;
and my vhdl code is that:
library ieee;
use ieee.std_logic_1164.all;
entity signal_generator is
port (clock, reset: in std_logic;
output: out std_logic);
end entity;
architecture signal_generator_arch of signal_generator is
type state_type is (s0, s1, s2, s3); --This is the states of the
finite state machine and we can create signlas with this type
signal current_state, next_state: state_type; --We can only assign
w_open and w_closed because there are type of state_type
begin
STATE_MEMORY : process(clock, reset)
begin
if(reset = '0') then
current_state <= s0;
elsif(falling_edge(clock)) then
current_state <= next_state;
end if;
end process;
NEXT_STATE_LOGIC : process(current_state)
begin
case(current_state) is
when s0 => next_state <= s1;
when s1 => next_state <= s2;
when s2 => next_state <= s3;
when s3 => next_state <= s0;
when others => next_state <= s0;
end case;
end process;
OUTPUT_LOGIC : process(current_state)
begin
case(current_state) is
when s0 => output <= '1';
when s1 => if(rising_edge(clock)) then
output <= '1';
else
output <= '0';
end if;
when s2 => output <= '1';
when s3 => output <= '0';
when others => output <= '0';
end case;
end process;
end architecture;
wave form
Your state machine does not work because of your OUTPUT_LOGIC process. It should also be sensitive to clock and when in state s1 it should output clock itself:
OUTPUT_LOGIC : process(current_state, clock)
begin
case(current_state) is
when s0 => output <= '1';
when s1 => output <= clock;
when s2 => output <= '1';
when s3 => output <= '0';
when others => output <= '0';
end case;
end process;
Note that you could simplify all this by simply passing your clock through a AND gate (to force it to 0) and a OR gate (to force it to 1) and output the result. A two bits counter that you would initialize to "11" and decrement would provide the current state, encoded in a very convenient way to force the output to 0 and 1:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity signal_generator is
port(clock, reset: in std_ulogic;
output: out std_ulogic);
end entity signal_generator;
architecture arc of signal_generator is
signal cnt: std_ulogic_vector(1 downto 0); -- the state
begin
process(clock, reset)
begin
if reset = '0' then
cnt <= "11";
elsif falling_edge(clock) then
cnt <= cnt - 1;
end if;
end process;
output <= (clock and cnt(1)) or cnt(0);
end architecture arc;
Note: always prefer std_ulogic (unresolved) to std_logic (resolved) when you do not plan to have multiple drive situations on a signal. This way, if you accidentally create a multiple drive situation you will get a meaningful error message instead of spending hours trying to understand where all these X values in your waveforms come from.

Uart Vhdl, simulation is ok but in fpga not work

I write simple vhdl code for Uart receiver.
Simulation (iSIM) is fine but when implemented I have wrong reading behavior.
When synthetized ISE tell me there are latches on state machine end on data_fill(x).
have you any suggestion.
thanks in advance
gian
here the code
library ieee;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity rx_uart is
port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
rx_data : in STD_LOGIC;
data_out: out STD_LOGIC_VECTOR(7 downto 0)
);
end rx_uart;
architecture fizzim of rx_uart is
-- state bits
subtype state_type is STD_LOGIC_VECTOR(2 downto 0);
constant idle: state_type:="000"; -- receive_en=0 load_en=0 cnt_en=0
constant receive: state_type:="101"; -- receive_en=1 load_en=0 cnt_en=1
constant stop_load: state_type:="010"; -- receive_en=0 load_en=1 cnt_en=0
signal state,nextstate: state_type;
signal cnt_en_internal: STD_LOGIC;
signal load_en_internal: STD_LOGIC;
signal receive_en_internal: STD_LOGIC;
signal count : integer range 0 to 54686:=0;
signal cnt_en : STD_LOGIC;
signal load_en : STD_LOGIC;
signal receive_en : STD_LOGIC;
signal data_fill : STD_LOGIC_VECTOR(9 downto 0);
-- comb always block
begin
COUNTER_EN : process(clk,rst,cnt_en) begin
if (rst ='1') then
count <= 0;
elsif rising_edge(clk) then
if (cnt_en ='1') then
count <= count+1;
else
count <= 0;
end if;
end if;
end process;
LOADER: process(clk,rst,load_en) begin
if (rst='1') then
data_out <= (others =>'0');
elsif (rising_edge(clk) and load_en='1')then
data_out <= data_fill(8 downto 1);
end if;
end process;
ASSIGNATION : process(clk,rst,receive_en) begin
if (rst ='1') then
data_fill <= (others =>'0');
elsif (receive_en='1') then
case count is
when 7812 =>
data_fill(1) <= rx_data;
when 13020 =>
data_fill(2) <= rx_data;
when 18228 =>
data_fill(3) <= rx_data;
when 23436 =>
data_fill(4) <= rx_data;
when 28664 =>
data_fill(5) <= rx_data;
when 33852 =>
data_fill(6) <= rx_data;
when 39060 =>
data_fill(7) <= rx_data;
when 44268 =>
data_fill(8) <= rx_data;
when 49476 =>
data_fill(9) <= rx_data;
when others =>
data_fill(0) <= '0';
end case;
end if;
end process;
COMB: process(state,clk,count,rst,rx_data) begin
case state is
when idle =>
if (rx_data='0') then
nextstate <= receive;
elsif (rx_data='1') then
nextstate <= idle;
end if;
when receive =>
if (count<=54685) then
nextstate <= receive;
elsif (count>54685) then
nextstate <= stop_load;
end if;
when stop_load =>
nextstate <= idle;
when others =>
end case;
end process;
-- Assign reg'd outputs to state bits
cnt_en_internal <= state(0);
load_en_internal <= state(1);
receive_en_internal <= state(2);
-- Port renames for vhdl
cnt_en <= cnt_en_internal;
load_en <= load_en_internal;
receive_en <= receive_en_internal;
-- sequential always block
FF: process(clk,rst,nextstate) begin
if (rst='1') then
state <= idle;
elsif (rising_edge(clk)) then
state <= nextstate;
end if;
end process;
end fizzim;
You need to understand when latches are generated. Latches are generated when you have an incomplete assignment in combinational logic. Your case statements are combinational. You do not completely assign all possibilities of your data signal and your state machine. When you have an incomplete assignment in a combinational process you will always generate a latch. Latches are bad!
Use your when others properly to assign all of your signals under all conditions. Your data_fill signal will always generate a latch because you don't handle all conditions for data 0:9 on all cases.
Read more about how to avoid latches in VHDL
Edit: It seems too that you don't consistently create sequential logic in VHDL. You need to be creating a clocked process or remove clk from your sensitivity list in a combinational process.
your design has several bad code sites besides your latch problem. I'll number them for better reference.
(1)
Xilinx XST won't recognize the implemented state machine as a FSM. See your XST report or the *.syr file. There won't be a FSM section. If XST finds no FSM it's not able to choose "the best" state encoding and optimize your FSM.
You should use an enum as a state-type and also initialize your state signal:
type t_state is (st_idle, st_receive, st_stop);
signal state : t_state := st_idle;
signal nextstate : t_state;
Your FSM process also needs default assignments (see Russell's explanation) like
nextstate <= state;
(2)
asynchronous resets are no good design practice and complicate timing closure calculations.
(3)
you are handling raw input signals from outside you FPGA without any timing information. to prevent meta stability problems place two D-flip-flops on the rx_data path. you should also add the async-reg and no-srl-extract attribute to these 2 registers to prevent XST optimizations
SIGNAL I_async : STD_LOGIC := '0';
SIGNAL I_sync : STD_LOGIC := '0';
-- Mark register "I_async" as asynchronous
ATTRIBUTE ASYNC_REG OF I_async : SIGNAL IS "TRUE";
-- Prevent XST from translating two FFs into SRL plus FF
ATTRIBUTE SHREG_EXTRACT OF I_async : SIGNAL IS "NO";
ATTRIBUTE SHREG_EXTRACT OF I_sync : SIGNAL IS "NO";
[...]
BEGIN
[...]
I_async <= In WHEN rising_edge(Clock);
I_sync <= I_async WHEN rising_edge(Clock);
Let 'In' be your asynchronous input. Now you can use I_sync in your clock domain. I choose to describe these 2 registers in a one-liner, you can also use a classic process :) The suffix '_async' allows you to define a matching timing rule in your *.xcf and *.ucf files.

VHDL state transitions based on if statements - works on board but doesn't work in simulator

I hate to ask yet another question on here but apparently I'm really useless with simulators :(.
Basically, I have a traffic light controller that is made up of a bunch of different states and a few timers running for different lengths of time. When the system enters a state, it activates a timer and there is an if statement that watches the timer output and points the system to the next state when the timer output value is 1.
This all works fine on the board, but when I simulate it the count ticks to '1' but the next state isn't selected. This can be seen, here:
I've tried to boil the code down into the essentials below, but if you need more context (and are feeling far more generous than I deserve) then the full code is here.
Initialisation:
entity trafficlightcontroller is
port
(
clk : in std_logic;
reset : in std_logic;
ambulance : in std_logic;
smr : in std_logic;
sml : in std_logic;
ssr : in std_logic;
rlmr : out std_logic;
almr : out std_logic;
glmr : out std_logic;
rlsr : out std_logic;
alsr : out std_logic;
glsr : out std_logic
);
end entity;
architecture rtl of trafficlightcontroller is
-- Build an enumerated type for the state machine
-- r=red;a=amber;g=green;c=car waiting;m=main road;s=side road
type state_type is (rmgs, rmas, rmrs, amrs, gmrs, gmrcs, ramrs, rmacs, rmrcs, ramrcs, rmras, rmrs2);
-- Signals to hold the states
signal present_state, next_state : state_type;
signal divclk, reset2, reset2b, reset3, reset3b, reset10, reset20, reset20b, count2, count2b, count3, count3b, count10, count20, count20b: std_logic;
component timer is
generic (
trigger_cnt: natural := 20
);
port (
clk: in std_logic;
reset: in std_logic;
count: buffer std_logic
);
end component timer;
component clockdivider
port(clkin : in std_logic;
dividedclk : out std_logic
);
end component clockdivider;
begin
timer2 : timer generic map (trigger_cnt => 2) port map(divclk,reset2,count2);
timer2b : timer generic map (trigger_cnt => 2) port map(divclk,reset2b,count2b);
timer3 : timer generic map (trigger_cnt => 3) port map(divclk,reset3,count3);
timer3b : timer generic map (trigger_cnt => 3) port map(divclk,reset3b,count3b);
timer10 : timer generic map (trigger_cnt => 10) port map(divclk,reset10,count10);
timer20 : timer generic map (trigger_cnt => 20) port map(divclk,reset20,count20);
timer20b : timer generic map (trigger_cnt => 20) port map(divclk,reset20b,count20b);
divider : clockdivider port map(clk, divclk);
The beginning of the states (including the state shown in the simulation):
case present_state is
--Red light main; green side road
when rmgs=>
reset2 <= '0';
reset2b <= '0';
reset3 <= '0';
reset3b <= '0';
reset20 <= '0';
reset20b <= '0';
rlmr <= '1';
almr <= '0';
glmr <= '0';
rlsr <= '0';
alsr <= '0';
glsr <= '1';
reset10 <= '1';
--if count is complete then move to next state
if ( count10='1' ) THEN
next_state <= rmas;
--otherwise, return to current state
else
next_state <= rmgs;
end if;
Clock process:
--Every clock tick, the next state is selected as the present state.
state_clocked: process(clk)
begin
if ( rising_edge( clk ) ) THEN
present_state <= next_state;
end if;
end process state_clocked;
The line I entered into the simulator to initialise the clock:
force clk 0 0ns, 1 10 ns -repeat 20ns
Your next_state process is missing lots of signals in the sensitivity list. This will probably fix it. VHDL-2008 allows you to use the keyword "all" instead of signal names. If your synthesis tool supports this, it might be worth using.
The rest are suggestions:
With a two process statemachine, reset logic is most often captured in the state_clocked process. And hence, look more like this:
state_clocked: process(clk)
begin
if ( rising_edge( clk ) ) THEN
if Reset = '0' then
present_state <= rmrs;
else
present_state <= next_state;
end if ;
end if;
end process state_clocked;
You can shorten your code significantly if you use a default assignment to assign the "off" value to all signal outputs of the next_state process:
next_state_proc : process (present_state, ssr, ambulance, Count10, Count3, ... )
begin
-- default assignments
reset2 <= '0';
reset2b <= '0';
reset3 <= '0';
reset3b <='0';
reset10 <= '0';
reset20 <= '0';
reset20b <= '0';
rlmr <= '1';
almr <= '0';
glmr <= '0';
rlsr <= '1';
alsr <= '0';
glsr <= '0';
next_state <= present_state ; -- optional
-- Statemachine code starts here
-- Only do assignments that are different from the default.
if ssr = '0' then
-- Do you change the values from the defaults here?
-- with the defaults, it is not necessary to do any assignments here, however,
-- without the defaults these outputs would have latches on them.
case present_state is
when gmrs => next_state <= gmrcs;
when rmas => next_state <= rmacs;
...
end case ;
elsif ambulance = '0' then
-- Do you change the values from the defaults here?
-- with the defaults, it is not necessary to do any assignments here, however,
-- without the defaults these outputs would have latches on them.
case present_state is
when gmrs | ramrs | ramrcs => next_state <= amrs;
-- when rmas => ???
when rmgs | rmras => next_state <= rmas;
...
end case ;
else
-- main statemachine
case present_state is
when rmgs=>
-- Only drive outputs that are different from the defaults here.
rlsr <= '0';
glsr <= '1';
reset10 <= '1';
--if count is complete then move to next state
if ( count10='1' ) THEN
next_state <= rmas;
--otherwise, return to current state
else
next_state <= rmgs;
end if;
when rmas=>
. . .
end case ;
The reset for the present_state register isn't strictly needed for simulation, but should be there for synthesis.
state_clocked:
process(reset,clk)
begin
if reset = '0' then
present_state <= rmrs;
elsif rising_edge( clk ) THEN
present_state <= next_state;
end if;
end process;
(Jim beat me to it).
process (present_state, reset, ssr, ambulance, count2, count2b,
count3, count3b, count10, count20, count20b)
Adding the process sensitivity elements (and using reset):
(I added a bit more to it. A lot of your design appears to be working to a good extent.)
And think about using a test bench, it would allow automated testing by generating inputs on ambulance, smr, sml and ssr.
library ieee;
use ieee.std_logic_1164.all;
entity tb_tfc is
end entity;
architecture foo of tb_tfc is
signal clk: std_logic := '0';
signal reset: std_logic;
signal ambulance: std_logic := '1';
signal smr: std_logic := '1';
signal sml: std_logic := '1';
signal ssr: std_logic := '1';
signal rlmr: std_logic;
signal almr: std_logic;
signal glmr: std_logic;
signal rlsr: std_logic;
signal alsr: std_logic;
signal glsr: std_logic;
begin
DUT:
entity work.trafficlightcontroller
port map (
clk,
reset,
ambulance,
smr,
sml,
ssr,
rlmr, -- out
almr, -- out
glmr, -- out
rlsr, -- out
alsr, -- out
glsr -- out
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 1280 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
reset <= '0'; --
wait for 20 ns;
reset <= '1';
wait for 1020 ns;
ssr <= '0';
wait;
end process;
end architecture;

Implementing a FSM in VHDL

Just wondering if I'm implementing a finite state machine in VHDL whether or not I need to state what all of the outputs are in every possible state? Even if I know that some outputs won't change from one state to the other and I know that the order of the states will also be in the same order?
For example, in this (forced) example:
entity test is
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic;
);
end test;
architecture Behavioral of test is
type executionStage is (s1,s2,s3);
signal currentstate, nextstate: executionStage;
begin
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
else
currentstate <= currentstate;
end if;
end process;
process(currentstate)
begin
case currentstate is
when s1 =>
if (a = '1') then
b <= '1';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s2;
when s2 =>
-- b doesnt change state from s1 to here, do I need to define what it is here?
if (a = '1') then
b <= '1';
c <= '1';
else
b <= '1';
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s1;
end case;
end process;
end Behavioral;
From my understanding if I don't do this then latches are created?
It's not a big deal in something like that example but if I have a machine with more than 10 outputs and more than 10 states then my VHDL files start to look incredibly messy and I'm sure it must be bad practice to copy and paste the same thing over and over. Is there a better way of doing this?
edit: Can I define a 'default' state for an ouput? IE set b to be 1 outside of all the processes and then only define what it is in the case statements where it is 0? Would that work?
Yes, you will infer latches if you only drive signals intended to be combinatorial in some branches of the process.
However, you can define a 'default' state for the signal simply by assigning a value to it before the case statement (but within the same process). For example:
process(currentstate, a)
begin
b <= '1';
c <= '1';
case currentstate is
when s1 =>
if (a = '1') then
c <= '0';
end if;
nextstate <= s2;
when s2 =>
-- b doesnt change state from s1 to here, do I need to define what it is here?
if (a /= '1') then
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
end if;
nextstate <= s1;
end case;
end process;
Three problems with your example code:
The last port in your port list should not have a semicolon:
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic -- no semicolon here!!!
);
In your register process, you should not have an "else" statement. While this will probably be accepted by the tools, it will confuse your fellow-VHDL designers.
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
end if;
end process;
In your combinational logic, the sensitivity list should contain all signals that you read: process(a, currentstate). In this particular case (again) things will probably work out fine, but you are bound to infer latches or cause other problems if your sensitivity list is not correct.
As for your question:
Yes, you need to assign a value (for each state) to each signal in the combinational process.
As Tomi mentions, you can easily do this by assigning a default value in the beginning of the process.
But you can also write the entire state machine in one single synchronous process. This way, you do not have to assign a value to every signal in every state.
Just a note to Philippe's response (can't comment on it directly?)..
I do prefer to write state machines in the two process style. It makes it very clear where you expect inferred flipflops and where you don't. It's also a bit more along the lines of
describing the hardware - imagine building a state machine with board level logic for example.
The registered device matches the state <= next_state process,
and the case statement maps to the and/or array in front of the state register..
Having said that, I typically use one process state machines for small simple tasks, and move over to two process machines for bigger ones.
I will even sometimes use a third process for organizing state outputs into different "task" groups.. but not often. A really large state machine tends to tell me the architecture needs work..
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
end if;
end process;
Hi
the above process is problematic but not due to the sensitivity list. It is ok to only declare clk for sequential process. Both simulation and synthesis tools won't have problems with it. clk is the fastest changing/transitioning signal after all in your code.
However, you should use an (preferrably) asynchronous reset. Of course, vendors nowadays say that for FPGA design, resets are not even necessary; they happen at boot time. Or they propose a synchronous reset.
Still, an asynchronous reset is valuable for a board-based environment.
In short: add a reset to your design and fix its behavior properly.
Kind regards
Nikolaos Kavvadias
The following VHDL code is edge sensitive state machine.
The edge sensitive process in this example will make both “out1” and “out2” in phase with “clk”.
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_edge_sensitive : process (clk)
begin
if rising_edge (clk) then
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end if;
end process state_process_edge_sensitive;
end Behavioral;
here is the test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY my_test_bench IS
END my_test_bench;
ARCHITECTURE behavior OF my_test_bench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT main_code
PORT(
clk : IN std_logic;
in1 : IN std_logic;
in2 : IN std_logic;
out1 : OUT std_logic;
out2 : OUT std_logic
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal in1 : std_logic := '0';
signal in2 : std_logic := '0';
--Outputs
signal out1 : std_logic;
signal out2 : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: main_code PORT MAP (
clk => clk,
in1 => in1,
in2 => in2,
out1 => out1,
out2 => out2
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
-- wait for 100 ns;
--
-- wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
The following VHDL code is level sensitive state machine.
The level sensitive process in this example will make “out1” out of phase with “clk” and “out2” in phase with “clk”.
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_level_sensitive : process (clk)
begin
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end process state_process_level_sensitive;
end Behavioral;
here is the test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY my_test_bench IS
END my_test_bench;
ARCHITECTURE behavior OF my_test_bench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT main_code
PORT(
clk : IN std_logic;
in1 : IN std_logic;
in2 : IN std_logic;
out1 : OUT std_logic;
out2 : OUT std_logic
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal in1 : std_logic := '0';
signal in2 : std_logic := '0';
--Outputs
signal out1 : std_logic;
signal out2 : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: main_code PORT MAP (
clk => clk,
in1 => in1,
in2 => in2,
out1 => out1,
out2 => out2
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
-- wait for 100 ns;
--
-- wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;

Resources