NAND basic cell using structural vhdl - vhdl

I have a problem designing memory circuits in VHDL. I am trying to figure out a soultion to the following prompt:
Create a NAND basic cell in the Xilinx tools using structural VHDL methods. Add a 1ns gate delay to both NAND gates (for both rising and falling transitions). Label inputs S and R and the outputs Q and QN as appropriate. Create a VHDL test bench to simulate the circuit, driving the inputs as specified below.
De-assert both inputs at the start of the simulation. At 100ns, asset S. At 200ns, de-assert S. At 300ns, assert R. At 400ns, de-assert R. At 500ns, assert both inputs. At 600ns, de-assert both inputs. At 700ns, assert both inputs.
An undefined output
A set operation
A reset operation
A ‘0’ being stored in memory
A ‘1’ being stored in memory
A state where the Q and QN outputs are both driven to the same value
A metastable state
If i could get just a basic example of what the code will look like i can design a NOR circuit also (That is the actual problem i wish to solve) but a NAND example will be sufficient.
I have tried using this model for the structural code
import std_logic from the IEEE library
library ieee;
use ieee.std_logic_1164.all;
--ENTITY DECLARATION: name, inputs, outputs
entity nandGate is
port( A, B : in std_logic;
F : out std_logic);
end nandGate;
--FUNCTIONAL DESCRIPTION: how the NAND Gate works
architecture func of nandGate is
begin
F <= A nand B;
end func;
and this model for the test bench
architecture tb of nandGate_tb is
--pass nandGate entity to the testbench as component
component nandGate is
port( A, B : in std_logic;
F : out std_logic);
end component;
signal inA, inB, outF : std_logic;
begin
--map the testbench signals to the ports of the nandGate
mapping: nandGate port map(inA, inB, outF);
process
--variable to track errors
variable errCnt : integer := 0;
begin
--TEST 1
inA <= '0';
inB <= '0';
wait for 15 ns;
assert(outF = '1') report "Error 1" severity error;
if(outF /= '1') then
errCnt := errCnt + 1;
end if;
--TEST 2
inA <= '0';
inB <= '1';
wait for 15 ns;
assert(outF = '1') report "Error 2" severity error;
if(outF /= '1') then
errCnt := errCnt + 1;
end if;
--TEST 3
inA <= '1';
inB <= '1';
wait for 15 ns;
assert(outF = '0') report "Error 3" severity error;
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
-------------- SUMMARY -------------
if(errCnt = 0) then
assert false report "Good!" severity note;
else
assert true report "Error!" severity error;
end if;
end process;
end tb;

The question is asking you to create an SR latch (called NAND basic cell in the instructions) from a cross-coupled pair of NAND gates.
The delay mentioned would be in the logic equation for the functional description of the NAND gate.
The following is a structural VHDL model of an SR latch made of two NAND gates:
entity nandCell is
port( S, R : in std_logic; --S and R are active low
Q, QN : out std_logic);
end nandCell;
architecture structural of nandCell is
--NAND gate component declaration
signal Qint, QNint : std_logic; --these internal signals are required to be able to read the "outputs"
begin
n1 : nandGate port map(S, QNint, Qint);
n2 : nandGate port map(R, Qint, QNint);
Q <= Qint;
QN <= QNint;
end structural;

Related

VHDL - Adding/Removing Pipeline Register with Generics

Let's assume I have two processes PROC_A and PROC_B, and they share a signal between them. Let me write a dummy example:
library ieee;
use ieee.std_logic_1164.all;
entity example is
port (
clk : in std_logic;
rst_n : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
z_out : out std_logic);
end entity example;
architecture rtl of example is
signal a_and_b : std_logic;
signal ab_xor_c : std_logic;
begin -- architecture rtl
z_out <= ab_xor_c;
PROC_A : process (clk, rst_n) is
begin -- process PROC_A
if rst_n = '0' then -- asynchronous reset (active low)
a_and_b <= '0';
elsif rising_edge(clk) then -- rising clock edge
a_and_b <= a and b;
end if;
end process PROC_A;
PROC_B : process (clk, rst_n) is
begin -- process PROC_B
if rst_n = '0' then -- asynchronous reset (active low)
ab_xor_c <= '0';
elsif rising_edge(clk) then -- rising clock edge
ab_xor_c <= a_and_b xor c;
end if;
end process PROC_B;
end architecture rtl;
Now, I want to have a pipeline register between a_and_b and ab_xor_c signals, and I want to hardcode it but also enable/disable it with ease. I really want something like a ifdef in C/C++. I could think of a generic to do that but I am also open to any other method (maybe with pragmas?). I am writing an example below, I know that it is so wrong in terms of VHDL but just see it as an idea:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic (
PIPELINE_EN : std_logic := '1');
port (
clk : in std_logic;
rst_n : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
z_out : out std_logic);
end entity example;
architecture rtl of example is
signal a_and_b : std_logic;
signal ab_xor_c : std_logic;
if PIPELINE_EN = '1' then
signal pipeline_reg : std_logic;
end if;
begin -- architecture rtl
z_out <= ab_xor_c;
PROC_A : process (clk, rst_n) is
begin -- process PROC_A
if rst_n = '0' then -- asynchronous reset (active low)
a_and_b <= '0';
elsif rising_edge(clk) then -- rising clock edge
a_and_b <= a and b;
end if;
end process PROC_A;
PROC_B : process (clk, rst_n) is
begin -- process PROC_B
if rst_n = '0' then -- asynchronous reset (active low)
ab_xor_c <= '0';
if PIPELINE_EN = '1' then
pipeline_reg <= '0'
end if;
elsif rising_edge(clk) then -- rising clock edge
if PIPELINE_EN = '1' then
pipeline_reg <= a_and_b;
ab_xor_c <= pipeline_reg xor c;
else
ab_xor_c <= a_and_b xor c;
end if;
end if;
end process PROC_B;
end architecture rtl;
Your example has been modified to removed the register from process A and show a generic controlling the presence of the register. Additional pipeline registers could be added generically as well.
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic ( PIPELINED: BOOLEAN := TRUE);
port (
clk: in std_logic;
rst_n: in std_logic;
a: in std_logic;
b: in std_logic;
c: in std_logic;
z_out: out std_logic
);
end entity example;
architecture genericly_pipelined of example is
signal a_and_b: std_logic;
signal ab_xor_c: std_logic;
begin
NO_PIPELINE:
if not PIPELINED generate
PROC_A:
process (a, b) is
begin
a_and_b <= a and b; -- could be a concurrent statement instead
end process;
end generate;
GEN_PIPELINED:
if PIPELINED generate
PIPELINED_PROC_A:
process (clk, rst_n) is
begin
if rst_n = '0' then
a_and_b <= '0';
elsif rising_edge(clk) then
a_and_b <= a and b;
end if;
end process;
end generate;
PROC_B:
process (clk, rst_n) is
begin
if rst_n = '0' then
ab_xor_c <= '0';
elsif rising_edge(clk) then
ab_xor_c <= a_and_b xor c;
end if;
end process;
end architecture genericly_pipelined;
The granularity using a generate statement is to a concurrent statement. For purposes of changing signal names you can declare intermediary signals in the block statement elaborated by the generate statement's block declarative region. Generate statements can be nested (it's a concurrent statement) which can be used to add more pipeline registers.
A generate statement body can have a block declarative part prior to any concurrent statements in the block statement body. Concurrent statements are delineated by the reserved words begin and end followed by a semicolon when any declarations are present in the block declarative part. E.g. IEEE Std 10786-2008:
11.8 Generate statements
if_generate_statement ::=
    generate_label :
        if [ alternative_label : ] condition generate
            generate_statement_body
        { elsif [ alternative_label : ] condition generate
            generate_statement_body }
        [ else [ alternative_label : ] generate
            generate_statement_body ]
    end generate [ generate_label ] ;
generate_statement_body ::=
        [ block_declarative_part
    begin ]
        { concurrent_statement }
    [ end [ alternative_label ] ; ]
The generate statements in the above VHDL code have no declarations. Braces { } enclosing the item concurrent_statement indicate you can use the 'long form' with the begin and end reserved words with zero or more concurrent statements. You'd declare any intermediary signals used to communicate between statements found in different generate statements in the same design hierarchy. (The block statement elaborated by a generate statement is a separate declarative region.)
The BNF found in the standard's numbered sections is normative.
Note you didn't assign z_out.
Here's an example compatible with the OP's code:
library ieee;
use ieee.std_logic_1164.all;
entity example1 is
generic ( PIPELINES: natural := 1);
port (
clk: in std_logic;
rst_n: in std_logic;
a: in std_logic;
b: in std_logic;
c: in std_logic;
z_out: out std_logic
);
end entity example1;
architecture generic_pipeline_stages of example1 is
signal a_and_b: std_logic;
signal ab_xor_c: std_logic;
begin
NO_PIPELINE:
if PIPELINES = 0 generate
PROC_A:
process (a, b) is
begin
a_and_b <= a and b; -- could be a concurrent statement instead
end process;
end generate;
GEN_PIPELINED:
if PIPELINES > 0 generate
type pipeline is array (0 to PIPELINES - 1) of std_logic;
signal pipeline_reg: pipeline;
begin
PIPELINED_PROC_A:
process (clk, rst_n) is
begin
if rst_n = '0' then
pipeline_reg <= (others => '0');
elsif rising_edge(clk) then
for i in pipeline'range loop
if i = 0 then
pipeline_reg(i) <= a and b;
else
pipeline_reg(i) <= pipeline_reg(i - 1);
end if;
end loop;
end if;
end process;
a_and_b <= pipeline_reg(PIPELINES - 1); -- a separate process
end generate;
PROC_B:
process (clk, rst_n) is
begin
if rst_n = '0' then
ab_xor_c <= '0';
elsif rising_edge(clk) then
ab_xor_c <= a_and_b xor c;
end if;
end process;
end architecture generic_pipeline_stages;
which produces:
And shows the two clock delays using natural generic PIPELINES.
With PIPELINES = 1:
The signals a_and_b and a_xor_b show up one clock earlier. It's compatible with the first VHDL example in this answer with PIPELINED = TRUE.
Note the block declarative part contains a composite signal declaration for the pipeline stages. A generate statement is it's own declarative region which means pipeline_reg wouldn't be visible outside the elaborated block. To access intermediary pipeline stages you'd either move the pipeline_reg declaration to the top level (example1, here) or assign signals declared in the top level assigned in the generate statement.
Principles in the design you wrote are fine, except for the if PIPELINE_EN = '1' then part in the declaration of pipeline_reg, which should be skipped, since the synthesis will then just remove the unused pipeline_reg. Also I would suggest that PIPELINE_EN is declared as type boolean instead, since that is a more obvious choice, and the = '1' can then be skipped in the conditions.
If for some reason you want to avoid declaration of the pipeline signal 'pipeline_reg' in the actual design, then you can declare a variable in the process, with code like below. It is required to assign the variable after use in the code, to get a flip-flop, since it otherwise just becomes combinatorial logic. However, such creation of flip-flops through use of variables is advised against, since it is hard to read and get right, thus error prone, and should be avoided in general. Though here it comes:
PROC_B : process (clk, rst_n) is
variable pipeline_reg_v : std_logic; -- Results in pipeline register if PIPELINE_EN, otherwise removed by synthesis
begin -- process PROC_B
if rst_n = '0' then -- asynchronous reset (active low)
ab_xor_c <= '0';
if PIPELINE_EN then
pipeline_reg_v := '0';
end if;
elsif rising_edge(clk) then -- rising clock edge
if PIPELINE_EN then
ab_xor_c <= pipeline_reg_v xor c;
pipeline_reg_v := a_and_b;
else
ab_xor_c <= a_and_b xor c;
end if;
end if;
end process PROC_B;
An alternative is to use the VHDL block construction, together with generate, whereby you can have signal declarations that are local to the block, as shown below. Though note that the block construction is rarely used in VHDL, thus there is a higher risk of encountering bugs in tools.
PIPELINE_EN_TRUE_GENERATE : if PIPELINE_EN generate
PIPELINE_EN_TRUE_BLOCK : block
signal pipeline_reg : std_logic;
begin
PROC_B : process (clk, rst_n) is
begin -- process PROC_B
if rst_n = '0' then -- asynchronous reset (active low)
ab_xor_c <= '0';
pipeline_reg <= '0';
elsif rising_edge(clk) then -- rising clock edge
pipeline_reg <= a_and_b;
ab_xor_c <= pipeline_reg xor c;
end if;
end process PROC_B;
end block PIPELINE_EN_TRUE_BLOCK;
end generate PIPELINE_EN_TRUE_GENERATE;
PIPELINE_EN_FALSE_GENERATE : if not PIPELINE_EN generate
PROC_B : process (clk, rst_n) is
begin -- process PROC_B
if rst_n = '0' then -- asynchronous reset (active low)
ab_xor_c <= '0';
elsif rising_edge(clk) then -- rising clock edge
ab_xor_c <= a_and_b xor c;
end if;
end process PROC_B;
end generate PIPELINE_EN_FALSE_GENERATE;
With a generic parameter for the pipeline depth:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic(
depth: natural := 0
);
port(
clk: in std_logic;
rst_n: in std_logic;
a: in std_logic;
b: in std_logic;
c: in std_logic;
z_out: out std_logic
);
end entity example;
architecture rtl of example is
signal a_and_b: std_logic;
signal ab_xor_c: std_logic_vector(0 to depth);
begin
z_out <= ab_xor_c(depth);
process(clk, rst_n) is
begin
if rst_n = '0' then
a_and_b <= '0';
ab_xor_c <= (others => '0');
elsif rising_edge(clk) then
a_and_b <= a and b;
ab_xor_c <= ab_xor_c srl 1;
ab_xor_c(0) <= a_and_b xor c;
end if;
end process;
end architecture rtl;
And then, with depth=2:
use std.env.all;
library ieee;
use ieee.std_logic_1164.all;
entity example_sim is
end entity example_sim;
architecture sim of example_sim is
signal clk: std_logic;
signal rst_n: std_logic;
signal a: std_logic;
signal b: std_logic;
signal c: std_logic;
signal z_out: std_logic;
begin
u0: entity work.example(rtl)
generic map(
depth => 2
)
port map(
clk => clk,
rst_n => rst_n,
a => a,
b => b,
c => c,
z_out => z_out
);
process
begin
clk <= '0';
wait for 1 ns;
clk <= '1';
wait for 1 ns;
end process;
process
begin
rst_n <= '0';
a <= '1';
b <= '1';
c <= '1';
wait until rising_edge(clk);
rst_n <= '1';
for i in 1 to 15 loop
wait until rising_edge(clk);
c <= not c;
end loop;
finish;
end process;
end architecture sim;
Demo:
$ ghdl -a --std=08 example_sim.vhd
$ ghdl -r --std=08 example_sim --vcd=example_sim.vcd
simulation finished #21ns
$ open example_sim.vcd
Of course, if your data type (T) is more complex than a single std_logic you will need some extra work.
Define a vector type of your data type (T_vector).
Define a "zero" constant value for your base type (T_zero), this will be the value that enters on the left when shifting to the right.
Overload the srl operator for the T_vector vector type.
Example with a T type (not tested):
type T_vector is array(natural range <>) of T;
constant T_zero: T := <some zero value for your type>;
...
function "srl"(l: T_vector; r: natural) return T_vector is
constant size: positive := l'length;
constant tmp: T_vector(0 to size - 1) := l;
variable res: T_vector(0 to size - 1);
begin
if r = 0 then
res := tmp;
elsif r = 1 then
res := T_zero & tmp(0 to size - 2);
else
res := (l srl 1) srl (r - 1);
end if;
return res;
end function "srl";

Unexpected result from VHDL design

It should output value of Qpl when all inputs are x and clk = 1 but it does not. What is the problem with the following code;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--This is a D Flip-Flop with Synchronous Reset,Set and Clock Enable(posedge clk).
--Note that the reset input has the highest priority,Set being the next highest
--priority and clock enable having the lowest priority.
ENTITY syn IS
PORT (
Q : OUT std_logic; -- Data output
CLK : IN std_logic; -- Clock input
Qpl : IN std_logic;
RESET : IN std_logic; -- Synchronous reset input
D : IN std_logic; -- Data input
SET : IN std_logic -- Synchronous set input
);
END syn;
ARCHITECTURE Behavioral OF syn IS --architecture of the circuit.
BEGIN
--"begin" statement for architecture.
PROCESS (CLK) --process with sensitivity list.
BEGIN
--"begin" statment for the process.
IF (CLK'EVENT AND CLK = '1') THEN --This makes the process synchronous(with clock)
IF (RESET = '1') THEN
Q <= '0';
ELSE
IF (SET = '1') THEN
Q <= D;
ELSE
Q <= Qpl;
END IF;
END IF;
END IF;
END PROCESS; --end of process statement.
END Behavioral;
Following diagram is showing the waveform of the above design, and desired operation requirements;
From the waveform diagram, it seems that everything works alright, when the input signal SET becomes U, the if condition cannot be evaluated, thus the output Q also becomes as such, namely U. You can see while SET was 0, the output Q was getting the value of Qpl correctly.
Sorry for the crude drawing, but you can see at the circled clock rising while SET is 0, Q gets the value of Qpl as expected. Only after SET signal becomes U, the output Q also loses its value in the next clock rising event, and also becomes U
You code and comments differ. As does the table/diagram. A D-flipflop/register is a very simple component. Example:
entity dff is
port (
clk : in std_logic;
rst : in std_logic;
set : in std_logic;
load : in std_logic;
d : in std_logic;
q : out std_logic
);
architecture rtl of dff is
begin
dff_proc : process(clk)
begin
if rising_edge(clk) then
if rst='1' then
q <= '0';
elsif set='1' then
q <= '1';
elsif load='1' then
q <= d;
end if;
end if;
end process;
end architecture;

Quartus II : simple counter but weird behaviour

First of all I'm sorry to bother you guys with my very noob question, but I can't find any sense to what's happening with my (ModelSim simulated) circuit.
Here's my code, simple as can be :
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY Counter IS
PORT(
enable : in std_logic;
clk : in std_logic;
count : out integer range 0 to 255);
END Counter;
ARCHITECTURE LogicFunction OF Counter IS
signal count_i : integer range 0 to 255;
begin
cnt : process(clk, enable, count_i)
begin
count <= count_i;
if (enable = '0') then
count_i <= 0;
else
count_i <= count_i + 1;
end if;
end process;
end LogicFunction;
My problem is : when I perform a timing simulation with ModelSim, with a clock signal, "enabled" is first '0' and then '1', the output ("count") stays at zero all the time. I tried a lot of different things, like setting the "count" out as a vector, doing all sorts of casts, but it still stays the same.
The increment "count_i <= count_i + 1;" seems to be the problem : I tried to replace it with something like "count_i <= 55", and then the output changes (to "55" in the previous example).
I've seen the exact same increment in the code on that webpage for example :
http://surf-vhdl.com/how-to-connect-serial-adc-fpga/
I've created a project, simulated it and... it works ! I really don't get what the guy did that I didn't, excepted for a bunch of "if" that I don't need in my code.
Any help would be greatly appreciated, I've spent like 3 hours of trial and errors...
Thanx in advance !
In addition to not using a clock edge to increment i_count you're using enable as a clear because it's both in the sensitivity list and encountered first in an if statement condition.
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all;
entity counter is
port(
enable : in std_logic;
clk : in std_logic;
count : out integer range 0 to 255);
end counter;
architecture logicfunction of counter is
signal count_i : integer range 0 to 255;
begin
cnt : process (clk) -- (clk, enable, count_i)
begin
-- count <= count_i; -- MOVED
-- if (enable = '0') then -- REWRITTEN
-- count_i <= 0;
-- else
-- count_i <= count_i + 1;
-- end if;
if rising_edge(clk) then
if enable = '1' then
count_i <= count_i + 1;
end if;
end if;
end process;
count <= count_i; -- MOVED TO HERE
end architecture logicfunction;
Your code is modified to using the rising edge of clk and require enable = '1' before i_count increment. The superfluous use clause referencing package numeric_std has been commented out. The only numeric operation you're performing is on an integer and those operators are predefined in package standard.
Note the replacement if statement doesn't surround it's condition with parentheses. This isn't a programming language and they aren't needed.
The count assignment is moved to a concurrent signal assignment. This removes the need of having i_count in the sensitivity list just to update count.
Throw in a testbench to complete a Miminal Complete and Verifiable Example:
library ieee;
use ieee.std_logic_1164.all;
entity counter_tb is
end entity;
architecture foo of counter_tb is
signal enable: std_logic := '0';
signal clk: std_logic := '0';
signal count: integer range 0 to 255;
begin
DUT:
entity work.counter
port map (
enable => enable,
clk => clk,
count => count
);
CLOCK:
process
begin
wait for 5 ns; -- 1/2 clock period
clk <= not clk;
if now > 540 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 30 ns;
enable <= '1';
wait for 60 ns;
enable <= '0';
wait for 30 ns;
enable <= '1';
wait;
end process;
end architecture;
And that gives:
Which shows that the counter doesn't counter when enable is '0' nor does enable = '0' reset the value of i_count.
The Quartus II Handbook Volume 1 Design and Synthesis doesn't give an example using a clock edge and an enable without an asynchronous clear or load signal.
The secret here is anything inside the if statement condition specified using a clock edge will be synchronous to the clock. Any condition outside will be asynchronous.
The form of synthesis eligible sequential logic is derived from the now withdrawn IEEE Std 1076.6-2004 IEEE Standard for VHDL Register
Transfer Level (RTL) Synthesis. Using those behavioral descriptions guarantees you can produce hardware through synthesis that matches simulation.

VHDL MUX Test Bench Issue

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)

VHDL simulation won't run

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;

Resources