I have a basic morse code decoder design implemented in VHDL. It is working fine on an FPGA board but does not work in the test bench.
I guess there is something wrong with the buttons, but I am not sure.
I've tried playing with the clock times in the test bench to no avail.
ARCHITECTURE behavior OF ProjTest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT LabProject
PORT(
char : IN std_logic_vector(4 downto 0);
save : IN std_logic;
start_read : IN std_logic;
clk : IN std_logic;
p_out : OUT std_logic
);
END COMPONENT;
--Inputs
signal char : std_logic_vector(4 downto 0) := (others => '0');
signal save : std_logic := '0';
signal start_read : std_logic := '0';
signal clk : std_logic := '0';
--Outputs
signal p_out : std_logic := '0';
-- Clock period definitions
constant clk_period : time := 2 ns;
constant wait_time : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: LabProject PORT MAP (
char => char,
save => save,
start_read => start_read,
clk => clk,
p_out => p_out
);
-- 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
wait for wait_time;
char <= "00001";
wait for wait_time;
save <= '1';
wait for wait_time;
save <= '0';
wait for wait_time;
char <= "00010";
wait for wait_time;
save <= '1';
wait for wait_time;
save <= '0';
wait for wait_time;
char <= "00000";
wait for wait_time;
save <= '1';
wait for wait_time;
save <= '0';
wait for wait_time;
start_read <= '1';
-- wait for wait_time;
-- start_read <= '0';
wait;
end process;
END;
Here is the entire test bench. The start_read and save signals are controlled with push buttons on the FPGA.
The p_out signal should give the Morse code representation of the given letter bit by bit but it never changes in the test bench. There are no problems on the FPGA as I mentioned.
I am somewhat new to VHDL and am trying to create a simple code for a Flip Flop D. My code compiles correctly, however when I run my Testbench tb_FlipFlopD in ModelSim Altera, the program opens but there's no wave, and I don't have the option to add it either.
The bug is problaby in my Testbench.
My Top-level identity code FlipFlopD:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FlipFlopD is
port( clock: in std_logic;
D: in std_logic;
Q: out std_logic
);
end FlipFlopD;
architecture RTL of FlipFlopD is
begin
Q <= D when clock = '1' and clock'event;
end RTL;
My Testbench tb_FlipFlopD:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_FlipFlopD is
end tb_FlipFlopD;
architecture teste of tb_FlipFlopD is
component FlipFlopD is
port (
clock : in std_logic;
D : in std_logic;
Q : out std_logic
);
end component;
signal I: std_logic;
signal O: std_logic;
signal C: std_logic := '0';
constant clk_period : time := 1 ns;
begin
instancia_FlipFlopD: FlipFlopD port map( D => I, Q => O, clock => C);
I <= '0', '1' after 1 ns, '1' after 2 ns, '0' after 3 ns, '1' after 4 ns;
clk_process : process
begin
C <= '0';
wait for clk_period/2;
C <= '1';
wait for clk_period/2;
end process;
end teste;
Your problem is that you simulation runs, but never stops; it just keeps on running forever.
Any VHDL (or Verilog) simulation will keep running if there is still stuff to do. This process:
clk_process : process
begin
C <= '0';
wait for clk_period/2;
C <= '1';
wait for clk_period/2;
end process;
generates an event (a change) on the the signal C every clk_period/2. Forever. To cure this, you need to put something in to stop this, eg:
clk_process : process
begin
while not STOP loop
C <= '0';
wait for clk_period/2;
C <= '1';
wait for clk_period/2;
end loop;
wait;
end process;
The wait; at the end of the process, waits forever. Signal STOP is a boolean:
signal STOP : boolean := false;
Then you need something like this to drive signal STOP:
STOP <= false, true after 10 ns;
I'm new on StackOverflow and I'm sorry for eventual error.
I'm workin on VHDL and I have a problem with the Post-Place & Route. While behavioral works correctly, Post-Place & Route has problem and the result remain UNDEFINED for the all the time.
entity step1 is
port ( d: in std_logic_vector (0 to 5);
clk : in std_logic;
RESET: in std_logic;
q: out std_logic_vector (0 to 5)
);
end step1;
architecture Behavioral of step1 is
begin
ff: process (clk)
begin
if (clk'event and clk='1') then
if (RESET = '1') then
q <= "000000";
else
q <= d;
end if;
end if;
end process;
end Behavioral;
I place here the code. It should be a flip flop D that I use to make a pipeline architecture. Thanks for your reply, and please excuse me for any mistake.
Here's the test bench:
entity test_step1 is
end test_step1
ARCHITECTURE behavior OF test_step1 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT step1
PORT(
input : IN std_logic_vector(0 to 5);
clk : IN std_logic;
RESET : IN std_logic;
output : OUT std_logic_vector(0 to 5)
);
END COMPONENT;
--Inputs
signal input : std_logic_vector(0 to 5) := (others => '0');
signal clk : std_logic := '0';
signal RESET : std_logic := '0';
--Outputs
signal output : std_logic_vector(0 to 5);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: step1 PORT MAP (
input => input,
clk => clk,
RESET => RESET,
output => output
);
-- 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.
RESET <= '1';
wait for 10 ns;
RESET <= '0';
input <= "111111";
wait for clk_period*10;
input <= "101010";
-- insert stimulus here
wait;
end process;
END;
The first warning messages for HDL Compiler 89 and 648 found on the internet are:
WARNING:HDLCompiler:89 - "my_module" remains a black-box since it has no binding entity.
WARNING:Simulator:648 - "Top_LCD_test.vhd" Line 35. Instance top_lcd is unboundCompiling architecture behavior of entity testbench
This means that the compiler has not fount any entity corresponding to the component used in your testbench.
In your case, the port names of your entity and component didn't match !
Try to use the same names in port for the component and entity :
entity test_step1 is
end test_step1;
ARCHITECTURE behavior OF test_step1 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT step1
PORT(
d : IN std_logic_vector(0 to 5);
clk : IN std_logic;
RESET : IN std_logic;
q : OUT std_logic_vector(0 to 5)
);
END COMPONENT;
--Inputs
signal input : std_logic_vector(0 to 5) := (others => '0');
signal clk : std_logic := '0';
signal RESET : std_logic := '0';
--Outputs
signal output : std_logic_vector(0 to 5);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: step1 PORT MAP (
d => input,
clk => clk,
RESET => RESET,
q => output
);
-- 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.
RESET <= '1';
wait for 10 ns;
RESET <= '0';
input <= "111111";
wait for clk_period*10;
input <= "101010";
-- insert stimulus here
wait;
end process;
I am currently slightly confused about my simple counter.
It is implemented as follows:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity simple_counter is
port(
DOUT : out std_logic_vector(3 downto 0);
CE : in std_logic;
CLK : in std_logic;
RSTN : in std_logic
);
end simple_counter;
architecture behavioral of simple_counter is
signal temp : unsigned(3 downto 0);
begin
process(CLK)
begin
if RSTN = '0' then
temp <= (others => '0');
elsif(rising_edge(CLK)) then
if CE = '1' then
if std_logic_vector(temp) = (temp'range => '1') then
temp <= (others => '0');
else
temp <= temp + 1;
end if;
end if;
end if;
end process;
DOUT <= std_logic_vector(temp);
end behavioral;
I use the following testbench for simulation:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
use work.tools_pkg.all;
library work;
--! #class tools_tb
--! #brief Test bench for the tools_tb design
entity counter_tb is
generic (
VOID : integer := 0);
port (
void_i : in std_logic);
end entity counter_tb;
--! #brief
--! #details
architecture sim of counter_tb is
-- Clock period definitions
-- Clock, reset and baud rate definitions
constant CLK_FREQ : integer := 100_000_000;
constant clk_period : time := (1.0 / real(CLK_FREQ)) * (1 sec);
signal end_sim : boolean := false;
signal rstn : std_logic;
signal clk : std_logic;
signal s_en : std_logic := '0';
------------------------------------------------------------------------------
-- DUT signals
------------------------------------------------------------------------------
signal s_dout : std_logic_vector(3 downto 0) := (others => '0');
signal s_ce : std_logic := '0';
begin -- architecture
fifo : entity work.simple_counter
port map (
DOUT => s_dout,
CE => s_ce,
RSTN => rstn,
CLK => clk
);
-- Clock process definitions (clock with 50% duty cycle is generated here).
clk_process : process
begin
if end_sim = false then
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
else
wait;
end if;
end process;
-- Stimulus process
stim_proc: process
begin
-- startup and wait for some time
rstn <= '0';
wait for clk_period;
rstn <= '1';
wait for clk_period;
wait for clk_period;
wait for clk_period;
s_ce <= '1';
wait;
end process;
end architecture sim;
I am confused why the counter increases instantly when I set CE <= '1
(see the attached simulation).
Since the counter is implemented in a synchrous process, shouldn't it take a single clock cycle until it is increased from '0' to '1'?
Thanks a lot!
You most likely have a race condition between s_ce and clk. If you will generate the s_ce on the rising edge of clk then you should see that counter works correctly.
I don't know this simulator but to check the race you can expand deltas when counter changes 0->1
I am a beginner in VHDL coding and I have some problem with my simple state machine. I just want this machine to change the output value loc_RL when the state changes. When I am simulating, there is no value (like 'U') for loc_RL.
Here is my code:
library ieee;
use ieee.std_logic_1164.all;
entity RL is
port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
loc_RL : out std_logic);
end RL;
architecture behavioral of RL is
type STATE_TYPE is (LOCS, REMS, LWLS, RWLS);
signal state : STATE_TYPE;
begin
process(clk, reset)
begin
if reset='1' then
state <= LOCS;
elsif (rising_edge(clk)) then
case state is
when LOCS =>
if pon_RL = '1' then
state <= REMS;
else
state <= LOCS;
end if;
when REMS =>
if pon_RL = '1' then
state <= LWLS;
else
state <= REMS;
end if;
when LWLS =>
if pon_RL = '1' then
state <= RWLS;
else
state <= LWLS;
end if;
when RWLS =>
if pon_RL = '1' then
state <= LOCS;
else
state <= RWLS;
end if;
end case;
end if;
end process;
process(state)
begin
case state is
when LOCS =>
loc_RL <= '1';
when REMS =>
loc_RL <= '0';
when LWLS =>
loc_RL <= '1';
when RWLS =>
loc_RL <= '0';
end case;
end process;
end behavioral;
testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity RL_tb is
end RL_tb;
architecture testbench of RL_tb is
component RL
port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
loc_RL : out std_logic);
end component;
--wejscia
signal tclk : std_logic;
signal treset: std_logic;
signal tpon_RL : std_logic;
signal trtl_RL : std_logic;
signal tACDS_RL : std_logic;
signal tLADS_RL : std_logic;
signal tREN_RL : std_logic;
signal tLLO_RL : std_logic;
signal tMLA_RL : std_logic;
signal tGTL_RL : std_logic;
--wyjscia
signal loc_RL : std_logic;
--definicja zegara
constant clk_period : time := 40 ns;
begin
--inicjalizacja UUT
uut: RL port map (
tclk,
treset,
tpon_RL,
trtl_RL,
tACDS_RL,
tLADS_RL,
tREN_RL,
tLLO_RL,
tMLA_RL,
tGTL_RL
);
process
begin
tclk <= '0';
wait for clk_period/2;
tclk <= '1';
wait for clk_period/2;
end process;
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
end;
It is compiling correctly, I can proceed to the simulation. I am using NCLaunch from Cadence. Thanks in advance for help.
Analyzing, elaborating and simulating your design and testbench gives:
And looking at the testbench shows:
architecture testbench of RL_tb is
component RL
port (
clk,
reset,
pon_RL,
rtl_RL,
ACDS_RL,
LADS_RL,
REN_RL,
LLO_RL,
MLA_RL,
GTL_RL: in std_logic;
loc_RL: out std_logic
);
end component;
--wejscia
signal tclk: std_logic;
signal treset: std_logic;
signal tpon_RL: std_logic;
signal trtl_RL: std_logic;
signal tACDS_RL: std_logic;
signal tLADS_RL: std_logic;
signal tREN_RL: std_logic;
signal tLLO_RL: std_logic;
signal tMLA_RL: std_logic;
signal tGTL_RL: std_logic;
--wyjscia
signal loc_RL: std_logic;
--definicja zegara
constant clk_period: time := 40 ns;
begin
--inicjalizacja UUT
uut:
RL
port map (
tclk,
treset,
tpon_RL,
trtl_RL,
tACDS_RL,
tLADS_RL,
tREN_RL,
tLLO_RL,
tMLA_RL,
tGTL_RL
);
process
begin
tclk <= '0';
wait for clk_period/2;
tclk <= '1';
wait for clk_period/2;
end process;
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
end architecture;
No where is there an assignment to or initial value assigned to an input to the device under test other than clk, reset and tpon_RL.
Looking in the RL process we find that actual state branching out of LOCS depends on reset not being '1':
process (clk, reset)
begin
if reset = '1' then
state <= LOCS;
elsif (rising_edge(clk)) then
case state is
when LOCS =>
if pon_RL = '1' then
state <= REMS;
else
state <= LOCS;
end if;
when REMS =>
What's missing in your testbench stimulus is a release of the reset.
In the unlabeled process:
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
end process;
You're missing a final wait statement:
process
begin
treset <= '1';
wait for 10 ns;
treset <= '0';
tpon_RL <= '1';
wait; -- added
end process;
Which prevents you from immediately assigning reset to a '1' again. Without suspension a process will loop, it's only suspending at the one wait statement, after setting reset to a '0' it's immediately setting it to a '1' before the process suspends, reset will only have a '1' value. No signal is updated while any process is active, there's only one projected output waveform value for any time, including the current simulation time. The assignment to a '1' overwrites the assignment to a '0'.
Fixing that gives:
And now we see the state machine is active.