I need an help with my code. I wrote that code for a simple project and now when I try to test it the output are all U.
The code is for a door, when badge go to 1 you have 3 attempts to send the right password for open the door. When the badge go on 0 the door closes.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Porta is
Port ( Badge : in STD_LOGIC;
Comb : in STD_LOGIC_VECTOR(15 downto 0);
Lock : out STD_LOGIC);
end Porta;
architecture Behavioral of Porta is
signal pass: STD_LOGIC_VECTOR(15 downto 0) := "1001100110011001";
signal tent: unsigned(1 downto 0) := "00"; --Tent
signal l: STD_LOGIC := '0';
begin
p_badge: process(Badge)
begin
report "Process Badge!";
if Badge = '1' then
report "Process Badge dentro IF=1";
tent <= (others => '0');
else
l <= '0';
end if;
end process p_badge;
--Contatore tentativi e controllo combinazione
p_pass: process(Comb)
begin
report "Process Confirm!";
if tent /= "11" then
if Comb = pass then
report "Process Confirm, Comb=pass";
l <= '1';
tent <= (others => '0');
elsif Comb /= pass then
report "Process Confirm, Comb!=pass";
tent <= tent+"01";
end if;
else
report "tent=11";
end if;
end process p_pass;
--Processo per il lock
p_lock: process(l)
begin
report "Process LOCK!!";
if l = '1' then
Lock <= '1';
else
Lock <= '0';
end if;
end process p_lock;
end Behavioral;
EDIT: I simplify the code, but the value of Lock don't show in ISIM and an error occur many times: Instance /porta_tb4/uut/ : Warning: NUMERIC_STD."/=": metavalue detected, returning TRUE.
I post the simple test I create
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY Porta_tb4 IS
END Porta_tb4;
ARCHITECTURE behavior OF Porta_tb4 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Porta
PORT(
Badge : IN std_logic;
Comb : IN std_logic_vector(15 downto 0);
Lock : OUT std_logic
);
END COMPONENT;
--Inputs
signal Badge : std_logic := '0';
signal Comb : std_logic_vector(15 downto 0) := (others => '0');
--Outputs
signal Lock : std_logic;
BEGIN
uut: Porta PORT MAP (
Badge => Badge,
Comb => Comb,
Lock => Lock
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
Badge <= '1';
wait for 100 ns;
Comb <= "1001100110010011";
wait for 100 ns;
Comb <= "1001100110110011";
wait for 100 ns;
Comb <= "1001101110010011";
wait for 100 ns;
Comb <= "1011101110010011";
wait for 100 ns;
Badge <= '1';
wait for 100 ns;
Comb <= "1001100110011001";
wait for 100 ns;
Badge <= '0';
-- insert stimulus here
wait;
end process;
END;
Related
I have this code which is a bidirectional counter that loops around.
I now want to add an input (maybe from switches or something), which controls the maximum value of the counter, for example if the max value from the input is "0111" the counter will count up to 0111 and then loop back around to 0000, and if the counter is counting down to 0000 it will loop back to 0111. I'm getting a bit confused on how/where I should do this because I've used nested ifs to implement an enable and reset input.
Here is the code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity UPDOWN_COUNTER is
Port ( clk: in std_logic; -- clock input
reset: in std_logic; -- reset input
up_down: in std_logic; -- up or down
enable: in std_logic; -- enable
max: in std_logic_vector(3 downto 0); -- max value counter
counter: out std_logic_vector(3 downto 0) -- output 4-bit counter
);
end UPDOWN_COUNTER;
architecture Behavioral of UPDOWN_COUNTER is
signal counter_updown: std_logic_vector(3 downto 0);
begin
process(clk,reset,enable,max)
begin
if(enable ='1') then
if(rising_edge(clk)) then
if(reset='1') then
counter_updown <= x"0";
elsif(up_down='1') then
counter_updown <= counter_updown - x"1"; -- count down
else
counter_updown <= counter_updown + x"1"; -- count up
end if;
end if;
end if;
end process;
counter <= counter_updown;
end Behavioral;
Here is the test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_counters is
end tb_counters;
architecture Behavioral of tb_counters is
component UPDOWN_COUNTER
Port ( clk: in std_logic; -- clock input
reset: in std_logic; -- reset input
up_down: in std_logic; -- up or down input
enable: in std_logic; -- enable input
max: in std_logic_vector(3 downto 0); -- max value counter
counter: out std_logic_vector(3 downto 0) -- output 4-bit counter
);
end component;
signal reset,clk,enable,up_down: std_logic;
signal max,counter:std_logic_vector(3 downto 0);
begin
dut: UPDOWN_COUNTER port map (clk => clk, reset=>reset,enable => enable, up_down => up_down, max => max,counter => counter);
-- Clock
clock_process :process
begin
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end process;
stim_proc: process
begin
max <= "1000"; -- Test value for Counter max value
enable <= '1';
reset <= '1';
up_down <= '0';
wait for 20 ns;
reset <= '0';
wait for 300 ns;
up_down <= '1';
--
wait for 50 ns;
enable <= '0';
wait for 50 ns;
enable <= '1';
wait;
end process;
end Behavioral;
You've specified a synchronous reset. There's at least one synthesis issue, where enable is inferred to gate the clock. The numeric package has been switched to ieee.numeric_std in the following (the example can be modified for the non-standard Synopsys numeric package):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity updown_counter is
port (
clk: in std_logic;
reset: in std_logic;
up_down: in std_logic;
enable: in std_logic;
max: in std_logic_vector(3 downto 0);
counter: out std_logic_vector(3 downto 0)
);
end entity updown_counter;
architecture behavioral of updown_counter is
signal counter_updown: unsigned(3 downto 0);
begin
process (clk) -- other signals evaluated inside clock edge
begin
if rising_edge(clk) then
if enable = '1' then -- don't gate the clock
if reset = '1' then
counter_updown <= (others => '0');
elsif up_down = '1' then -- down
if counter_updown = 0 then
counter_updown <= unsigned(max);
else
counter_updown <= counter_updown - 1;
end if;
else -- count up
if counter_updown = unsigned(max) then
counter_updown <= (others => '0');
else
counter_updown <= counter_updown + 1;
end if;
end if;
end if;
end if;
end process;
counter <= std_logic_vector(counter_updown);
end architecture behavioral;
And that gives:
with your testbench.
This is the similar to #user1155120's answer (which I recommend you accept as the answer), but I've used an asynchronous reset instead. Also added a generic to specify the number bits in the counter.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity UpdownCounter is
generic
(
COUNTER_BITS: natural := 4
);
port
(
clk: in std_logic; -- clock input
reset: in std_logic; -- reset input
up_down: in std_logic; -- up or down input
enable: in std_logic; -- enable input
max: in std_logic_vector(COUNTER_BITS - 1 downto 0); -- max value counter
counter: out std_logic_vector(COUNTER_BITS - 1 downto 0) -- output N-bit counter
);
end UpdownCounter;
architecture V1 of UpdownCounter is
signal counter_updown: unsigned(COUNTER_BITS - 1 downto 0);
begin
process(clk, reset)
begin
if reset then
-- Do asynchronous reset.
counter_updown <= (others => '0');
elsif rising_edge(clk) then
-- Do synchronous stuff.
if enable then
if up_down then
-- Count down to zero cyclically.
if counter_updown = 0 then
counter_updown <= unsigned(max);
else
counter_updown <= counter_updown - 1;
end if;
else
-- Count up to max cyclically.
if counter_updown = unsigned(max) then
counter_updown <= (others => '0');
else
counter_updown <= counter_updown + 1;
end if;
end if;
end if;
end if;
end process;
counter <= std_logic_vector(counter_updown);
end V1;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity UpdownCounter_TB is
end UpdownCounter_TB;
architecture V1 of UpdownCounter_TB is
component UpdownCounter
generic
(
COUNTER_BITS: natural := 4
);
port
(
clk: in std_logic; -- clock input
reset: in std_logic; -- reset input
up_down: in std_logic; -- up or down input
enable: in std_logic; -- enable input
max: in std_logic_vector(COUNTER_BITS - 1 downto 0); -- max value counter
counter: out std_logic_vector(COUNTER_BITS - 1 downto 0) -- output 4-bit counter
);
end component;
signal reset, clk, enable, up_down: std_logic;
signal max, counter: std_logic_vector(3 downto 0);
signal halt_clk: boolean := false;
begin
DUT: UpdownCounter
generic map
(
COUNTER_BITS => 4
)
port map
(
clk => clk,
reset => reset,
enable => enable,
up_down => up_down,
max => max,
counter => counter
);
-- Clock
ClockProocess :process
begin
while not halt_clk loop
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end loop;
wait;
end process;
StimulusProcess: process
begin
max <= "1000"; -- Test value for Counter max value
enable <= '1';
reset <= '1';
up_down <= '0';
wait for 20 ns;
reset <= '0';
wait for 300 ns;
up_down <= '1';
--
wait for 50 ns;
enable <= '0';
wait for 50 ns;
enable <= '1';
wait for 1000 ns;
halt_clk <= true;
wait;
end process;
end V1;
I have this code which counts clock cycles between two asychronous (and random ) trigger events. I wish to make the counter stop if it reaches the value 1200d and reset to zero.
The code is provided without my attempts to reset the counter.
I've tried to add an ( if counter reaches 1200 then counter to be done zero ) statement in the clock process but no result.
I simulate with two cases. First: I have a pair of trigger events with 85 clock cycles between them and the second pair of trigger events with 1500 clock cycles between them . In the second case I want the counter to stop when it reaches 1200 and go back to 0.
I apologise but I can't yet post an image of my simulation
Thanks in advance for any help.
The module
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity main is
Port ( clk : in STD_LOGIC;
trigger : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(11 DOWNTO 0) );
end main;
architecture Behavioral of main is
signal counter : STD_LOGIC_VECTOR(11 DOWNTO 0) := "000000000000";
signal enable : STD_LOGIC:='0';
begin
trigger_proc : process(trigger)
variable state : std_logic := '0';
begin
if(falling_edge(trigger))then
if(state = '0')then
enable <= '1';
state := '1';
elsif(state = '1')then
enable <= '0';
state := '0';
end if;
end if;
end process;
counter_proc : process(clk)
begin
if(rising_edge(clk))then
if(enable = '1')then
counter <= counter + "1";
elsif(enable = '0' )then
counter <= "000000000000";
end if;
end if;
end process;
output <= counter;
end Behavioral;
and the TEST BENCH
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY test IS
END test;
ARCHITECTURE behavior OF test IS
COMPONENT main
PORT(
clk : IN std_logic;
trigger : IN std_logic;
output : OUT std_logic_vector(11 downto 0)
);
END COMPONENT;
signal clk : std_logic := '0';
signal trigger : std_logic := '1';
signal output : std_logic_vector(11 downto 0);
constant clk_period : time := 25 ns;
BEGIN
kyklwma: main PORT MAP (
clk => clk,
trigger => trigger,
output => output
);
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
trigger_stim: process
begin
wait for 100 ns;
trigger <= '0';-- first trigger event with counter <1200
wait for clk_period;
trigger <= '1';
wait for clk_period*85;
trigger <= '0';--second trigger event with counter <1200
wait for clk_period;
trigger <= '1';
wait for 10000 ns;
trigger <= '0';-- first trigger event with counter > 1200
wait for clk_period;
trigger <= '1';
wait for clk_period*1500;
trigger <= '0';--second trigger event with counter > 1200
wait for clk_period;
trigger <= '1';
wait;
end process;
END;
I have been trying to make a generic sequence detector. When i try to simulate my design, I get a simulator 45-1 Fatal run time error. Can somebody please help me with this. Here is my Test bench and design.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Sequence_tb is
end Sequence_tb;
architecture Behavioral of Sequence_tb is
component sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port(din,CLK,RST:in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end component;
constant CLK_period: time := 10ns;
constant width: integer := 4;
constant sequence0: std_logic_vector(width-1 downto 0) := "1010";
signal din,CLK,RST,dout: std_logic := '0';
signal temp : std_logic_vector(0 to width-1) := (others=>'0');
begin
uut: sequence generic map(width=>width,sequence=>sequence0)
port map(din=>din,CLK=>CLK,RST=>RST,dout=>dout,temp=>temp);
CLK_proc: process
begin
CLK <= not CLK;
wait for CLK_period;
end process;
RST_proc: process
begin
RST <= '1';
wait for 20 ns;
RST <= '0';
wait;
end process;
din_proc: process
begin
din <= '1';
wait for 30 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
wait;
end process;
end Behavioral;
Design File:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port (din, CLK, rst: in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end Sequence;
architecture Beh of Sequence is
subtype statetype is integer range 0 to width-1;
signal prstate,nxstate: statetype := 0;
begin
process(RST,CLK)
begin
if RST='1' then
temp <= (others => '0');
nxstate <= 0;
elsif CLK'event and CLK='1' then
temp(prstate) <= din;
for k in prstate downto 0 loop
if temp(k downto 0) = sequence(k downto 0) then
nxstate <= k;
exit;
else temp <= temp(1 to width-1) & '0';
end if;
end loop;
end if;
prstate <= nxstate;
end process;
dout <= '1' when prstate = width-1 and din = sequence(sequence'left) else '0';
end Beh;
In the Isim wave window my internal signals and outputs appear green and as initialized but all of my inputs appear as "UU" even though they are initialized as well. I am simply trying to add 1 whenever either of the two inputs are 1. The code synthesizes fine without warnings.
Any ideas?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity scoreboard2 is
Port ( clk : in STD_LOGIC;
T1 : in STD_LOGIC;
T2 : in STD_LOGIC;
Output : out STD_LOGIC_VECTOR (3 downto 0));
end scoreboard2;
architecture Behavioral of scoreboard2 is
signal output_temp: STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal score1,score2: unsigned(1 downto 0) := "00";
signal score3: unsigned(3 downto 0):= "0000";
begin
proc: process(T1,T2,clk)
begin
if(rising_edge(clk)) then
if(T1 = '1') then
score1 <= score1 + 1;
end if;
if(T2 = '1') then
score2 <= score2 + 1;
end if;
end if;
end process proc;
score3 <= score1 & score2;
output_temp <= STD_LOGIC_VECTOR(score3);
Output <= output_temp;
end Behavioral;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY test6 IS
END test6;
ARCHITECTURE behavior OF test6 IS
COMPONENT scoreboard2
PORT(
clk : IN std_logic;
T1 : IN std_logic;
T2 : IN std_logic;
Output : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '1';
signal T1 : std_logic := '1';
signal T2 : std_logic := '1';
--Outputs
signal Output : std_logic_vector(3 downto 0) := "0000";
signal output_temp: STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal score1,score2: unsigned(1 downto 0) := "00";
signal score3: unsigned(3 downto 0):= "0000";
constant clk_period : time := 10 ns;
BEGIN
uut: scoreboard2 PORT MAP (
clk => clk,
T1 => T1,
T2 => T2,
Output => Output
);
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
begin
wait for 100 ns;
T1 <= '1';
wait;
end process;
END;
I don't have Isim but some simulators allow you to run a top level design with a port having unconnected inputs. It's usually synonymous with the ability to do interactive simulation (run, stop, step, force inputs, etc.).
Chapter 5 of ise_tutorial_ug695.pdf, March 1, 2011 (v13.1) says you need a test bench, i don't have all the documentation to determine whether that is enforced or not.
For a test bench:
library ieee;
use ieee.std_logic_1164.all;
entity scoreboard_tb is
end entity;
architecture test of scoreboard_tb is
signal clk: std_logic := '0';
signal T1: std_logic := '0';
signal T2: std_logic := '0';
signal RESULT: std_logic_vector(3 downto 0);
begin
UNDER_TEST:
entity work.scoreboard2
port map (
clk => clk,
T1 => T1,
T2 => T2,
Output => RESULT
);
CLOCK:
process
begin
if Now > 340 ns then -- simulation stops with no signal events
wait;
end if;
clk <= not clk;
wait for 20 ns;
end process;
STIMULUS:
process
begin
wait for 40 ns;
T1 <= '1';
wait for 40 ns;
T2 <= '1';
wait for 40 ns;
T1 <= '0';
T2 <= '0';
wait for 40 ns;
T2 <= '1';
wait for 40 ns;
T2 <= '0';
T1 <= '1';
wait for 40 ns;
T1 <= '0';
wait;
end process;
end architecture;
ghdl produces:
for you're scoreboard2 entity/architecture pair analyzed unchanged.
I don't have Isim either. Probably the softwave itself didn't work well. If there is a wave editor or something similar in Isim, use it instead of a testbench. Then simulate your project again. Hope this helps:)
I am attempting to build a counter in VHDL. Eventual goal is to hook the "do_count" to a button. The total will be converted to BCD and displayed on a 7-segment display. Push the button, watch the numbers increment.
I'm using ModelSim and I can see the internal "counter_value" correctly increment by 1. But the output signal "total" becomes "000X" then "00X0" during my two test "do_count"s. Why am I getting an X'd signal?
I've moved the "output <= current_value" around inside the process, outside the process, inside the 'if's, etc. Still the "000X".
I've tried using a variable 'tmp' inside the process.
count_up : process(clk) is
variable tmp : unsigned (15 downto 0 );
begin
tmp := current_value;
-- snip
if do_count='1' then
current_value <= tmp + to_unsigned(1,16);
end if;
Still I get the "000X".
Full code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity d_counter is
port ( rst : in std_logic;
clk : in std_logic;
do_count : in std_logic;
total : out unsigned (15 downto 0)
);
end entity d_counter;
architecture counter_arch of d_counter is
signal current_value : unsigned (15 downto 0) := (others=>'0');
begin
count_up : process(clk) is
begin
if rst='1' then
current_value <= (others=>'0');
total <= (others=>'0');
elsif rising_edge(clk) then
if do_count='1' then
current_value <= current_value + to_unsigned(1,16);
end if;
end if;
end process count_up;
total <= current_value;
end architecture counter_arch;
Testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity test_counter is
begin
end entity test_counter;
architecture run_test_counter of test_counter is
signal t_rst : std_logic := '1';
signal t_clk : std_logic := '0';
signal t_do_count : std_logic;
signal t_total : unsigned( 15 downto 0 );
component d_counter is
port ( rst : in std_logic;
clk : in std_logic;
do_count : in std_logic;
total : out unsigned( 15 downto 0 )
);
end component d_counter;
begin
uut : d_counter
port map( rst => t_rst,
clk => t_clk,
do_count => t_do_count,
total => t_total );
clock : process is
begin
t_clk <= '0'; wait for 10 ns;
t_clk <= '1'; wait for 10 ns;
end process clock;
stimulus : process is
begin
t_rst <= '1';
t_do_count <= '0';
t_total <= (others =>'0');
wait for 15 ns;
t_rst <= '0';
wait for 10 ns;
t_do_count <= '1';
wait for 10 ns;
t_do_count <= '0';
wait for 10 ns;
t_do_count <= '1';
wait for 10 ns;
t_do_count <= '0';
wait for 10 ns;
wait;
end process stimulus;
end architecture run_test_counter;
Update 03-Oct-2012.
BOTH the answers helped. Moving "total <= current_value" inside the process (From #simon) and removing the extra "t_total <= (others =>'0');" (From #peter-bennett) in my testbench was required. I had to do both to get rid of the X's.
It looks like your mistake is in your testbench. The signal t_total is mapped to the total output of your counter component, yet you are writing to it with the t_total <= (others => '0') assignment. If you remove this I think your problem will go away.
uut : d_counter
port map( rst => t_rst,
clk => t_clk,
do_count => t_do_count,
total => t_total );
clock : process is
begin
t_clk <= '0'; wait for 10 ns;
t_clk <= '1'; wait for 10 ns;
end process clock;
stimulus : process is
begin
t_rst <= '1';
t_do_count <= '0';
t_total <= (others =>'0'); <-- Do not assign to t_total (its an output)
Your code write multi-driven with "total". You should delete assigment in process count_up.
count_up : process(clk) is
begin
if rst='1' then
current_value <= (others=>'0');
total <= (others=>'0'); --> Remove it
elsif rising_edge(clk) then
if do_count='1' then
current_value <= current_value + to_unsigned(1,16);
end if;
end if;
end process count_up;
total <= current_value; -- Keep it