Reputation: 77
So for a school assignment we have to make a clock using different modules and I have an up-down counter and a finite state machine. I should be able to press a button so the counter goes up by one or down by one and this for the hours, minutes and seconds. The problem is in the testbench of my fsm. When you add a number the up_down signal should go to 1 so the counter knows it has to count up, but when this happens the signal goes to unknown and when I want decrease it the signal goes back to 0 as it should.
I have looked for why it could do this but have no clue whatsoever, does anybody know why? I'll ad my code and a screenshot of the testbench.
a) The finite state machine
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tijd_FSM is
Port ( clk_1ms : in std_logic;
BTU : in std_logic;
BTD : in STD_LOGIC;
BTR : in std_logic;
mo_tijd : in std_logic;
EupH : out std_logic;
EdownH : out std_logic;
EupM : out std_logic;
EdownM : out std_logic;
EupS : out std_logic;
EdownS : out std_logic;
up_down : out std_logic;
blink_tijd: out std_logic_vector (1 downto 0)
);
end tijd_FSM;
architecture Behavioral of tijd_FSM is
type state is (s0, s1, s2, s3);
signal present_state, next_state : state;
begin
state_reg: process (clk_1ms)
begin
if rising_edge(clk_1ms) then
if(BTR = '1' and mo_tijd = '1') then
present_state <= next_state;
else
present_state <= present_state;
end if;
end if;
end process;
--state machine process.
outputs: process (present_state, BTU, BTD)
begin
case present_state is
when s0 => --Gewone weergave
blink_tijd <= "00";
up_down <= '0';
when s1 => --Instellen UU
if(BTU ='1') then
up_down <= '1';
EupH <= '1';
elsif(BTD='1') then
up_down <= '0';
EdownH <= '1';
else
EupH <= '0';
EdownH <= '0';
end if;
blink_tijd <= "10";
when s2 => --Instellen MM
if(BTU ='1') then
up_down <= '1';
EupM <= '1';
elsif(BTD='1') then
up_down <= '0';
EdownM <= '1';
else
EupM <= '0';
EdownM <= '0';
end if;
blink_tijd <= "10";
when s3 => --Instellen SS
if(BTU ='1') then
up_down <= '1';
EupS <= '1';
elsif(BTD='1') then
up_down <= '0';
EdownS <= '1';
else
EupS <= '0';
EdownS <= '0';
end if;
blink_tijd <= "01";
when others => null;
end case;
end process;
nxt_state: process (BTR, present_state)
begin
case present_state is
when s0 =>
if BTR = '1' then next_state <= s1;
else next_state <= s0;
end if;
when s1 =>
if BTR = '1' then next_state <= s2;
else next_state <= s1;
end if;
when s2 =>
if BTR = '1' then next_state <= s3;
else next_state <= s2;
end if;
when s3 =>
if BTR = '1' then next_state <= s0;
else next_state <= s3;
end if;
when others => next_state <= s0;
end case;
end process;
end Behavioral;
b) The testbench
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 tb_tijd_FSM IS
END tb_tijd_FSM;
ARCHITECTURE behavior OF tb_tijd_FSM IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT tijd_FSM
PORT(
clk_1ms : IN std_logic;
BTU : IN std_logic;
BTD : IN std_logic;
BTR : IN std_logic;
mo_tijd : IN std_logic;
EupH : OUT std_logic;
EdownH : OUT std_logic;
EupM : OUT std_logic;
EdownM : OUT std_logic;
EupS : OUT std_logic;
EdownS : OUT std_logic;
up_down : OUT std_logic;
blink_tijd : OUT std_logic_vector(1 downto 0)
);
END COMPONENT;
--Inputs
signal clk_1ms : std_logic := '0';
signal BTU : std_logic := '0';
signal BTD : std_logic := '0';
signal BTR : std_logic := '0';
signal mo_tijd : std_logic := '0';
--Outputs
signal EupH : std_logic;
signal EdownH : std_logic;
signal EupM : std_logic;
signal EdownM : std_logic;
signal EupS : std_logic;
signal EdownS : std_logic;
signal up_down : std_logic;
signal blink_tijd : std_logic_vector(1 downto 0);
-- Clock period definitions
constant clk_1ms_period : time := 1 ms;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: tijd_FSM PORT MAP (
clk_1ms => clk_1ms,
BTU => BTU,
BTD => BTD,
BTR => BTR,
mo_tijd => mo_tijd,
EupH => EupH,
EdownH => EdownH,
EupM => EupM,
EdownM => EdownM,
EupS => EupS,
EdownS => EdownS,
up_down => up_down,
blink_tijd => blink_tijd
);
-- Clock process definitions
clk_1ms_process :process
begin
clk_1ms <= '0';
wait for clk_1ms_period/2;
clk_1ms <= '1';
wait for clk_1ms_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
up_down <= '0';
mo_tijd <= '1';
--Hij begint in state s0
wait for 1 ms;
BTR <= '1'; --s1
wait for 1 ms;
BTR <= '0';
wait for 1 ms;
BTU <= '1';
wait for 1 ms;
BTU <= '0';
wait for 1 ms;
BTD <= '1';
wait for 1 ms;
BTD <= '0';
wait for 1 ms;
BTR <= '1'; --s2
wait for 1 ms;
BTR <= '0';
wait for 1 ms;
BTU <= '1';
wait for 1 ms;
BTU <= '0';
wait for 1 ms;
BTD <= '1';
wait for 1 ms;
BTD <= '0';
wait for 1 ms;
BTR <= '1'; -- s3
wait for 1 ms;
BTR <= '0';
wait for 1 ms;
BTU <= '1';
wait for 1 ms;
BTU <= '0';
wait for 1 ms;
BTD <= '1';
wait for 1 ms;
BTD <= '0';
wait;
end process;
END;
c) The waveform image
Upvotes: 2
Views: 311
Reputation: 2470
In stim_proc
you have up_down <= '0'
, which drives 0
on the same signal that the output of your state machine is connected.
As long as the state machine also drives 0
everything is fine as the combination resolves to 0
. When the state machine drives 1
however, the resolution is X
, undefined.
As far as I can see, there is no reason for stim_proc
to drive this signal, so removing that line should give you what you want.
Upvotes: 2