In my introductory Digital System design course. We were asked to simulate a 4 to 16 decoder using VHDL and modelSim.Everything compiled correctly. However, when I try to test bench my program, I get a weird error that even my instructor couldn't pinpoint the problem.
–Code for 4 to 16 decoder
library ieee;
use ieee.std_logic_1164.all;
entity decoder4to16 is
port
(
X: in STD_LOGIC_VECTOR(3 downto 0);
EN: in STD_LOGIC;
Y: out STD_LOGIC_VECTOR (0 TO 15));
end decoder4to16;
architecture decoder4to16_arch of decoder4to16 is
signal Y_t: STD_LOGIC_VECTOR (0 TO 15);
begin
process(X,EN)
begin
case X is
when "0000" => Y_t<="0111111111111111";
when "0001" => Y_t<="1011111111111111";
when "0010" => Y_t<="1101111111111111";
when "0011" => Y_t<="1110111111111111";
when "0100" => Y_t<="1111011111111111";
when "0101" => Y_t<="1111101111111111";
when "0110" => Y_t<="1111110111111111";
when "0111" => Y_t<="1111111011111111";
when "1000" => Y_t<="1111111101111111";
when "1001" => Y_t<="1111111110111111";
when "1010" => Y_t<="1111111111011111";
when "1011" => Y_t<="1111111111101111";
when "1100" => Y_t<="1111111111110111";
when "1101" => Y_t<="1111111111111011";
when "1110" => Y_t<="1111111111111101";
when "1111" => Y_t<="1111111111111110";
when others => Y_t<="1111111111111111";
end case;
if(EN)='0' then Y<=Y_t;
else Y<="1111111111111111";
end if;
end process;
end decoder4to16_arch;
— and here is the code for my test bench
library ieee;
use ieee.std_logic_1164.all;
entity decoder4to16_tb is
end decoder4to16_tb;
architecture decoder4to16_tb of decoder4to16_tb is
component decoder4to16
port
(
X: in STD_LOGIC_VECTOR(3 downto 0);
EN: in STD_LOGIC;
Y: out STD_LOGIC_VECTOR (0 TO 15));
end component;
signal X: STD_LOGIC_VECTOR (3 downto 0):="0000";
signal E: STD_LOGIC:='0';
signal Y: STD_LOGIC_VECTOR (0 TO 15);
begin
U0: decoder4to16 port map (X,E,Y);
process
begin
E<='1'; X<="0000"; wait for 100 ns;
E<='0'; X<="0000"; wait for 100 ns;
X<="0001"; wait for 100 ns;
X<="0010"; wait for 100 ns;
X<="0011"; wait for 100 ns;
wait;
end process;
end decoder4to16_tb;
Now the weird part, when I try to simulate the test bencha and display the waveforms, it's like there is a delay for inputs "0001" and above.
it's like there is some delay of some sort
To make sure that this "delay" is there
Thank you.
Best Answer
You might do a better job in your question describing what's wrong with the results, instead of providing a picture.
It becomes apparent if you look at the process:
You have a process that's sensitive to
X
andEN
but (rightly so) notY_t
.VHDL signal assignments are queued to a projected output waveform.
A signal assignment can be of the form (IEEE Std 1076-2008, 10.5.2 Simple signal assignments):
Where a waveform:
can be a waveform element which can have an after time expression:
which specifies when in relative simulation time the update is available. (see 10.5.2.2 Executing a simple assignment statement):
A signal value is never updated when any process statement is pending for execution in the current simulation cycle.
An assignment without an after time expression, meaning assignment to the current simulation time is guaranteed to incur a delta cycle (a simulation cycle without a change to simulation time).
And because the value of the newly assigned value of
Y_t
is not available in the current simulation cycle in whichY
is assigned you'll get a delay based not on updating the value ofY_t
but waiting until the end of the simulation cycle, suspending and waiting for an event on a signal in the process sensitivity list.Simulation cycle
The VHDL standard can be hard for someone just starting out to understand, it requires among other thing inculcation in the vocabulary of VHDL and curricula don't always do that.
There's a couple of paragraphs in Peter Ashenden's book The Designer's Guide to VHDL that can help with understanding what VHDL does in simulation:
Elaboration
Everything in an elaborated VHDL design is driven by signal events which are scheduled in the projected output waveform for each signal.
Concurrent statements are devolved into processes or block statements providing hierarchy and processes during elaboration. Function calls are expressions and sequential procedure calls are statements. (Concurrent procedure call statements become processes containing sequential procedure call statements when elaborated).
So What does this means to your model?
Signal events drive execution of the model. Your design model is missing a signal event on
Y_t
causing a process to resume execution.Sensitivity lists in a process prevent the inclusion of an explicit wait statement and implicitly provide:
as the last statement of the process, which means among other things execution resumes with the first statement.
Now if we simply added
Y_t
to the sensitivity list our process would have feed back and potentially endless delta cycles because we'd updateY_t
which would schedule and event to which the process would be sensitive.To cure this you can leave the sensitivity list alone and either move the assignment to
Y
outside this process, or eliminate the signalY_t
and assign toY
directly in the case statement which you can embed in the following if statement where the assignment of the value ofY_t
occurs.You could potentially concatenate
EN
withX
to a named variable and require the element position of the variable used as a case statement expression representingEN
be '0', theothers
choice would cover every case whenY
should be all '1's and you could eliminate the if statement.That might then look like:
When the leftmost position of
case_exp
is a '1'EN
is invalid and noY
element position is a '0'.