I have just picked up The Designer's Guide to VHDL and I am working through the exercises in the first chapter. I ran into an issue with my 2 bit multiplexer that I don't understand.
The code for my multiplexer:
library ieee;
use ieee.std_logic_1164.all;
entity multi2 is
port
(
a,b : in bit;
sel : in boolean;
z : out bit
);
end multi2;
architecture behave of multi2 is
begin
storage : process is
variable stored_d0 : bit;
begin
wait for 1 ns;
if sel then
z <= a;
else
z <= b;
end if;
end process storage;
end architecture behave;
I can't figure out why I need the "wait for 1 ns;" line. If I move it to below the "end if" line the simulation won't work and I won't get my .vcd output from GHDL. Without the wait line, or it being in the wrong spot gives me an error in my vcd file about beginning and end time being the same.
Do I need wait statements in my process in order to work?
My test bench code is below:
library ieee;
use ieee.std_logic_1164.all;
entity multi2_tb is
end multi2_tb;
architecture test of multi2_tb is
component multi2
port
(
a,b : in bit;
sel : in boolean;
z : out bit
);
end component;
signal a,b : bit;
signal sel : boolean;
signal z : bit;
begin
multiplexer2: multi2 port map (a => a, b => b, sel => sel, z => z);
process begin
a <= '0';
b <= '1';
sel <= false;
wait for 3 ns;
a <= '0';
b <= '1';
sel <= true;
wait for 3 ns;
a <= '0';
b <= '1';
sel <= false;
wait for 3 ns;
assert false report "Reached end of test";
wait;
end process;
end test;
Related
My code will not simulate an output when running the VWF file.
I have tried changing the code several different time and don't really understand what I'm doing wrong.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
up_down : in std_logic;
LED : out std_logic;
Q : Buffer integer Range 0 to 7);
end Counter_JM;
architecture archi of Counter_JM is
Begin
-- up/down counter
process (up_down)
begin
if (Q=7) then
Q<=0;
end if;
if (up_down = '1') then
Q <= Q + 1;
else
Q<=0;
end if;
if (Q=0 or Q=1) then
LED <= '0';
else
LED <= '1';
end if;
end process;
end archi;
The LED output should show high for 4 cycles and low for 2 on the VWF file
I don't know why you use up_down. But as Oldfart said, you don't have a clock. I have simplified and modified your code (it works for me (in modelsim):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
clk: in std_logic;
up_down : in std_logic;
LED : out std_logic
);
end Counter_JM;
architecture archi of Counter_JM is
Begin
process (clk)
variable Q: integer range 0 to 7;
begin
if rising_edge(clk) then
-- up/down counter
Q := Q + 1;
if Q=1 or Q=2 then
LED <= '0';
else
LED <= '1';
end if;
if Q = 7 then
Q := 0;
end if;
end if;
end process;
end archi;
and also created/generated a simple testbench here :
`-- Testbench automatically generated online
-- at http://vhdl.lapinoo.net
-- Generation date : 7.6.2019 11:22:53 GMT
library ieee;
use ieee.std_logic_1164.all;
entity tb_Counter_JM is
end tb_Counter_JM;
architecture tb of tb_Counter_JM is
component Counter_JM
port (clk : in std_logic;
up_down : in std_logic;
LED : out std_logic);
end component;
signal clk : std_logic;
signal up_down : std_logic;
signal LED : std_logic;
constant TbPeriod : time := 1000 ns; -- EDIT Put right period here
signal TbClock : std_logic := '0';
signal TbSimEnded : std_logic := '0';
begin
dut : Counter_JM
port map (clk => clk,
up_down => up_down,
LED => LED);
-- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
-- EDIT: Check that clk is really your main clock signal
clk <= TbClock;
stimuli : process
begin
-- EDIT Adapt initialization as needed
up_down <= '0';
-- EDIT Add stimuli here
wait for 100 * TbPeriod;
-- Stop the clock and hence terminate the simulation
TbSimEnded <= '1';
wait;
end process;
end tb;
-- Configuration block below is required by some simulators. Usually no need to edit.
configuration cfg_tb_Counter_JM of tb_Counter_JM is
for tb
end for;
end cfg_tb_Counter_JM;`
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 have a project submission that requires me to design a pattern detector that detects and counts the occurrence of '11100' in the given input sequence. I have 2 codes. One is the actual code to generate the pattern and count it. the 2nd code is a testbench. I have very little experience with VHDL so please guide me.
I am trying to send a '11100' such that it goes in bit by bit automatically.
pattern_recogniser.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--Sequence detector for detecting the sequence "11100".
--Non overlapping type.
entity pattern_recogniser is
port( clk : in std_logic; --clock signal
reset : in std_logic; --reset signal
data : in std_logic; --serial bit sequence
-- det_vld : out std_logic; --A '1' indicates the pattern "1011" is detected in the sequence.
count : out integer);
end pattern_recogniser;
architecture Behavioral of pattern_recogniser is
type state_type is (A,B,C,D,E); --Defines the type for states in the state machine
signal state : state_type := A; --Declare the signal with the corresponding state type.
signal ct : integer;
begin
process(clk)
begin
if( reset = '0' ) then --resets state and output signal when reset is asserted.
-- det_vld <= '0';
ct <= 00000000;
state <= A;
elsif ( rising_edge(clk) ) then --calculates the next state based on current state and input bit.
case state is
when A => --when the current state is A.
-- det_vld <= '0';
if ( data = '0' ) then
state <= A;
else
state <= B;
end if;
when B => --when the current state is B.
if ( data = '0' ) then
state <= A;
else
state <= C;
end if;
when C => --when the current state is C.
if ( data = '0' ) then
state <= A;
else
state <= D;
end if;
when D => --when the current state is C.
if ( data= '0' ) then
state <= E;
else
state <= D;
end if;
when E => --when the current state is D.
if ( data = '0' ) then
state <= A;
-- det_vld <= '1';
ct <= ct + 1;
else
state <= B;
--Output is asserted when the pattern "11100" is found in the sequence.
end if;
when others =>
NULL;
end case;
end if;
end process;
process (ct)
begin
if(ct >=99) then
count <= 99; -- the count must show a "--" on the 7 segment display after it exceeds 99.
else
count <= ct;
end if;
end process;
end Behavioral;
and the second: testbench.vhd:
library ieee;
use ieee.std_logic_1164.all;
entity testbench is
port(count_t: out integer);
end testbench;
architecture behav of testbench is
component testset
port( ck : out std_logic;
rst : out std_logic;
dout : out std_logic);
end component;
component pattern_recogniser
port( clk : in std_logic; --clock signal
reset : in std_logic; --reset signal
data : in std_logic; --serial bit sequence
count : out integer);
end component;
signal clk_1 : std_logic := '0';
signal reset_1 : std_logic := '0';
signal data_1 : std_logic := '1';
signal count_s : integer := 0;
begin
--tb: testset port map (ck => clk_1, rst => reset_1, dout => data_1);
pat_rec : pattern_recogniser port map (clk => clk_1, reset => reset_1, data => data_1, count => count_s);
process(clk_1)
begin
clk_1 <= not clk_1 after 100 ps;
end process;
process is
begin
wait for 600 ps;
data_1 <= '0';
wait for 400 ps;
end process;
count_t <= count_s;
end behav;
I am not able to generate this sequence automatically using the ifs in the testbench. I have to generate it 110 times, then perform a rest and then 50 times more. How do I achieve this? Any help would be highly appreciated!!!
Im trying to make a counter which counts up to 3 then counts down to 0 etc..
example: 0 1 2 3 2 1 0 1 2 3 2 1 0...
What I did:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
port(
Clock: in std_logic;
Reset: in std_logic;
Output: out std_logic_vector(0 to 1 ));
end Counter;
architecture Behavioral of Counter is
signal temp: std_logic_vector(0 to 1);
signal down: std_logic := '0';
begin process(Clock,Reset)
begin
if Reset='0' then
temp <= "00";
down<= '0';
elsif(rising_edge(Clock)) then
if temp="11" then
down<= '1';
elsif temp="00" then
down<='0';
end if;
if down='0' then
temp <= temp +1;
else
temp <= temp-1;
end if;
end if;
end process;
Output <= temp;
end Behavioral;
Somehow the output is going from 3 to 0 without showing the middle numbers..
What is wrong?
You are not looking at all the signals: look at down to see what happens. Because you are using clocked/synchronous logic, down is changed in the clock cycle where temp is detected 3, so it will have effect one clock cycle later. I.e. when temp is 3, down will still be 0, thus (3+1) mod 4 = 0.
One possible solution is to be one step ahead of this: Change down one clock cycle earlier... when temp=2.
One other problem is that you are combining the non-standardized packages STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED with logic arrays in reverse direction. That can give unpredictable results. Please use standardized packages. Example:
library ieee;
use ieee.STD_LOGIC_1164.ALL;
entity counter is
port(
clk : in std_logic;
rst_n : in std_logic;
output : out std_logic_vector(1 downto 0)
);
end entity;
architecture behavioral of counter is
use ieee.numeric_std.ALL;
signal temp : unsigned(output'range) := (others => '0');
signal down : std_logic := '0';
begin
process(clk, rst_n)
begin
if rst_n = '0' then -- why asynchronous reset??
temp <= (others => '0');
down <= '0';
elsif(rising_edge(clk)) then
if temp = 2 then
down <= '1';
elsif temp = 1 then
down <= '0';
end if;
if down = '0' then
temp <= temp + 1;
else
temp <= temp - 1;
end if;
end if;
end process;
output <= std_logic_vector(temp);
end architecture;
-
entity counter_tb is end entity;
library ieee;
use IEEE.STD_LOGIC_1164.ALL;
architecture behavioral of counter_tb is
signal clk : std_logic;
signal rst_n : std_logic;
signal output : std_logic_vector(1 downto 0);
begin
DUT: entity work.Counter
port map(
clk => clk,
rst_n => rst_n,
output => output
);
rst_n <= '1';
process
begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
end architecture;
Next time please add your test bench to form a complete set...
and please don't use 3-space indentation :( use 4, like everybody does)
I'm trying to learn VHDL through P. Ashenden's book: Designer's Guide to VHDL. Chapter one's exercise 10 asks you to write 2-to-1 (I'm assuming 1 bit wide) MUX in VHDL and simulate it. I apologize in advance for being a complete noob. This is my first VHDL code.
My MUX didn't produce any errors or warnings in synthesis. My test bench doesn't produce errors or warnings, either. However, the simulation comes up completely blank, except for the names of the signals.
I've tried looking at a multitude of other MUX examples online (as well as a bench test example from the book), all of which gave errors when I tried sythesizing them, so I wasn't confident enough to use them as guides and didn't get much out of them. I'm not sure what I'm doing wrong here. I'd include an image of the simulation, but I don't have enough rep points :(
Also, I realize that a good MUX should also have cases for when it receives no select input/high impedance values, ect.. In this case, I'm just trying to get the toy model working.
The MUX code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
The test bench code is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
b <= '1';
wait;
end process stimulus;
END architecture behavior;
You don't need a use clause for package std_logic_1164 when using type bit (declared in package standard).
Your process statement choose in MUXtop has no sensitivity clause which cause the process to continually execute in simulation. (It won't do anything until you trip over a delta cycle iteration limit which might be set to infinity).
I added a sensitivity list, commented out the superfluous use clauses in the two design units and added some more stimulus steps as well as a final wait for 10 ns; to allow the last action to be seen in your testbench:
library IEEE;
-- use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process (a, b, sel) -- is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
LIBRARY ieee;
-- USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
sel <= '0'; -- added
wait for 10 ns; -- added
b <= '1';
wait for 10 ns; -- added
wait;
end process stimulus;
END architecture behavior;
And that gives:
(clickable)