I'm trying to write a code in vhdl to create a 16 to 1 mux using 2 to 1 mux.
I actually thought that to do this we may need 15 two to one multiplexers and by wiring them together and using structural model I wrote the code below.
First I wrote a 2 to 1 mux:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MUX_2_1 is
port (
w0 , w1 : IN STD_LOGIC;
SELECT_I: IN std_logic;
DATA_O: out std_logic
);
end MUX_2_1;
architecture MUX_2_1_arch of MUX_2_1 is
--
begin
--
WITH SELECT_I SELECT
DATA_O <= w0 WHEN '0',
w1 WHEN '1',
'X' when others;
--
end MUX_2_1_arch;
and made a package from it, just to use it simple and easy:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
PACKAGE mux2to1_package IS
COMPONENT mux2to1
PORT (w0, w1: IN STD_LOGIC ;
SELECT_I: IN std_logic;
DATA_O: out std_logic ) ;
END COMPONENT ;
END mux2to1_package ;
and then my 16 to 1 mux looks like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;
ENTITY mux16to1 IS
PORT (w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
f : OUT STD_LOGIC ) ;
END mux16to1 ;
ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
Mux1: mux2to1 PORT MAP ( w(0), w(1), s(0), im(0)) ;
Mux2: mux2to1 PORT MAP ( w(2), w(3), s(0), im(1)) ;
Mux3: mux2to1 PORT MAP ( w(4), w(5), s(0), im(2)) ;
Mux4: mux2to1 PORT MAP ( w(6), w(7), s(0), im(3)) ;
Mux5: mux2to1 PORT MAP ( w(8), w(9), s(0), im(4)) ;
MUX6: mux2to1 PORT MAP ( w(10), w(11), s(0), im(5));
Mux7: mux2to1 PORT MAP ( w(12), w(13), s(0), im(6)) ;
Mux8: mux2to1 PORT MAP ( w(14), w(15), s(0), im(7)) ;
Mux9: mux2to1 PORT MAP ( im(0), im(1), s(1), q(0)) ;
Mux10: mux2to1 PORT MAP ( im(2), im(3), s(1), q(1)) ;
Mux11: mux2to1 PORT MAP ( im(4), im(5), s(1), q(2)) ;
Mux12: mux2to1 PORT MAP ( im(6), im(7), s(1), q(3)) ;
Mux13: mux2to1 PORT MAP ( q(0), q(1), s(2), p(0)) ;
Mux14: mux2to1 PORT MAP ( q(2), q(3), s(2), p(1)) ;
Mux15: mux2to1 PORT MAP ( p(0), p(1), s(3), f) ;
END Structure ;
and also my testbench is:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;
ENTITY Mux_test IS
END Mux_test;
ARCHITECTURE test OF Mux_test IS
COMPONENT mux16to1 PORT(w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
f : OUT STD_LOGIC ) ;
END COMPONENT;
SIGNAL wi : STD_LOGIC_VECTOR(15 DOWNTO 0) ;
SIGNAL selecting : STD_LOGIC_VECTOR(3 DOWNTO 0) ;
SIGNAL fi : STD_LOGIC ;
BEGIN
a1: mux16to1 PORT MAP(wi , selecting , fi);
wi<= "0101110010001010" , "1001000101010101" after 100 ns;
selecting <= "0011" , "1010" after 20 ns , "1110" after 40 ns, "1100" after 60 ns , "0101" after 80 ns,
"0011" after 100 ns , "1010" after 120 ns , "1110" after 140 ns, "1100" after 160 ns , "0101" after 180 ns;
END ARCHITECTURE;
my simulation:
But when I try to simulate this nothing shows in my output. I'm thinking that maybe that's because I wrote my code in concurrent part and signals im and q and p are not initialized yet so I tried using default values "00000000" for im and "0000" for q and "00" for p when I was declaring the signals, but then I got bunch of errors saying "Instance mux2to1 is unbound" in simulation and nothing actually changed.
Any idea what is the problem??
Also I think there is something wrong with my select input logically.
but I don't understand how i should use the select to be correct for this problem.
I would appreciate if anyone can help me with my problem.
Virtual component binding using component declarations can either be explicit using a configuration specification to supply a binding indication, or rely on a default binding indication.
A default binding indication would rely on finding an entity declared in a reference library whose name matches the component name. That's not the case here, your entity is named MUX_2_1 (case insensitive) while the component name is mux2to1.
It's not illegal to have components unbound in VHDL, it's the equivalent of not loading a component in a particular location in a printed circuit or bread board, it simply produces no output which shows in simulation here as a 'U'.
Here the solutions could be to either change the name of the entity in both the entity declaration and it's architecture from MUX_2_1 to mux2to1, change the component declaration to MUX_2_1 or provide a configuration specification providing an explicit binding indication as a block declarative item in the architecture for mux16to1 of the form
ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);
for all: mux2to1 use entity work.MUX_2_1; -- ADDED
When used the latter method provides '1' and '0' outputs on testbench signal fi during simulation.
The testbench can be made more elaborate to demonstrate that the selects are valid. One way would be with marching '0's or '1's in w elements while scanning all the elements and looking for a mismatch:
library ieee;
use ieee.std_logic_1164.all;
entity mux16to1_tb is
end mux16to1_tb;
architecture test of mux16to1_tb is
component mux16to1 is
port (
w: in std_logic_vector(15 downto 0);
s: in std_logic_vector(3 downto 0);
f: out std_logic
);
end component;
signal w: std_logic_vector(15 downto 0);
signal s: std_logic_vector(3 downto 0);
signal f: std_logic;
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
begin
DUT:
mux16to1
port map (
w => w,
s => s,
f => f
);
STIMULI:
process
use ieee.numeric_std.all;
begin
for i in w'reverse_range loop
w <= (others => '1');
w(i) <= '0';
for j in w'reverse_range loop
s <= std_logic_vector(to_unsigned(j, s'length));
wait for 10 ns;
end loop;
end loop;
wait;
end process;
VALIDATE:
process
begin
for x in w'reverse_range loop
for y in w'reverse_range loop
wait for 10 ns;
assert f = w(y)
report
LF & HT & "f = " & std_ulogic'image(f) & " " &
"expected " & std_ulogic'image(w(y)) &
LF & HT & "w = " & to_string(w) &
LF & HT & "s = " & to_string(s)
severity ERROR;
end loop;
end loop;
wait;
end process;
end architecture;
The output f of mux16to1 is selected for each value of w using a marching '0's pattern. Any mismatch between f and the selected name element value of w is reported with diagnostic information.
Here we see that mux16t01 implements a 16:1 selection properly without the need to modify the original posters design.
Without error injection the testbench waveforms for w, s and f can be viewed in a waveform display to validate correct operation.
Related
I have a type declared in a package which I use in the port entity:
Package:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package ports_type is
constant N: positive := 3;
type t_ports_types is array(0 to N-1) of std_logic_vector (N-1 downto 0);
end package ports_type;
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports is
generic (
N : positive := 3
);
port(
inp : in t_ports_types;
outp : out std_logic_vector(N-1 downto 0)
);
end ports;
architecture Behavioral of ports is
begin
process(inp)
variable result : std_logic;
begin
for y in 0 to N-1 loop
result := '0';
for x in 0 to N-1 loop
result := result or inp(x)(y);
end loop;
outp(y) <= result;
end loop;
end process;
end Behavioral;
The problem is that I have to manually change the value of Nin the package, which is a problem if I want to instantiate the ports entity in another module, like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports_top is
generic (
N : positive := 3
);
Port (
A : in std_logic_vector(N-1 downto 0);
B : in std_logic_vector(N-1 downto 0);
C : in std_logic_vector(N-1 downto 0);
Outp : out std_logic_vector(N-1 downto 0)
);
end ports_top;
architecture Behavioral of ports_top is
signal s_ports : t_ports_types;
begin
s_ports(0) <= A;
s_ports(1) <= B;
s_ports(2) <= C;
ports_0: entity work.ports(Behavioral)
generic map (
N => N
)
port map(
inp => s_ports,
outp => Outp
);
end Behavioral;
The goal would be to only change N in the top module and not in the package as well. Is that possible with vhdl'93?
Thanks for the help.
I am doing my first project in VHDL, I try to implement 8-bit barrel shifter using mux.
This is code for one block (8 mux in chain):
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.sample_package.all;
-------------------------------------
ENTITY Shifter IS
GENERIC (n : INTEGER );
PORT ( x,y: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
redB: IN Integer;
out_m: OUT STD_LOGIC_VECTOR(n-1 downto 0));
END Shifter;
--------------------------------------------------------------
ARCHITECTURE dfl OF Shifter IS
SIGNAL sm : STD_LOGIC;
SIGNAL what_b : STD_LOGIC;
BEGIN
--redB in the number of the red block in the diagram
--The first mux port map is the same for all three blocks
sm <= y(redB);
first : MUX port map(
a => x(0),
b => '0',
s0 => sm,
y => out_m(0)
);
b0: if redB=0 generate --First block - only the first mux has b=0
rest : for i in 1 to n-1 generate
chain : MUX port map(
a => x(i),
b => x(i-1),
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
b1: if redB=1 generate
rest : for i in 1 to n-1 generate
what_b <= '0' when i=1 else --Second block - 2 first mux has b=0
x(i-2);
chain : MUX port map(
a => x(i),
b => what_b,
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
b2: if redB=2 generate
rest : for i in 1 to n-1 generate
what_b <= '0' when i=1 or i=2 or i=3 else --Third block - 4 first mux has b=0
x(i-4);
chain : MUX port map(
a => x(i),
b => what_b,
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
END dfl;
In this is the code for changing 3 shifters:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.sample_package.all;
-------------------------------------
ENTITY Barrel IS
GENERIC (n : INTEGER);
PORT ( x,y: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
out_shifter0,out_shifter1,out_shifter2: OUT STD_LOGIC_VECTOR(n-1 downto 0));
END Barrel;
--------------------------------------------------------------
ARCHITECTURE dfl OF Barrel IS
SIGNAL temp_out0 : std_logic_vector(n-1 DOWNTO 0);
SIGNAL temp_out1 : std_logic_vector(n-1 DOWNTO 0);
SIGNAL temp_out2 : std_logic_vector(n-1 DOWNTO 0);
BEGIN
y0: Shifter GENERIC MAP(n) port map (x=>x,y=>y,redB=>0,out_m=>temp_out0);
out_shifter0 <= temp_out0;
y1: Shifter GENERIC MAP(n) port map (x=>temp_out0,y=>y,redB=>1,out_m=>temp_out1);
out_shifter1 <= temp_out1;
y2: Shifter GENERIC MAP(n) port map (x=>temp_out1,y=>y,redB=>2,out_m=>temp_out2);
out_shifter2 <= temp_out2;
END dfl;
All the files are compiling, but when I try to run a simulation I get this warning:
# ** Warning: (vsim-8684) No drivers exist on out port /tb/L0/y1/out_m(7 downto 1), and its initial value is not used.
#
# Therefore, simulation behavior may occur that is not in compliance with
#
# the VHDL standard as the initial values come from the base signal /tb/L0/temp_out1(7 downto 1).
I am using ModelSim.
Anyone got any idea of what could be the problem?
Thanks!
You have done a generate with a signal, and compared its value to something. Integers initialise to -2^31, so none of the generate blocks exist because the values you have assigned externally do not get assigned until after the simulation is started, but the generates get created during elaboration (before the simulation starts) using the initial value of redB. Hence no drivers for out_m. Instead of using a signal in the generate condition, use generics instead, as their values are fixed and assigned during elaboration.
I'm a newbie in VHDL and hardware world.
I'm trying to make a Count&Compare example using Top Level Hierarchy and test it with testbench and see the results on ISIM.
Here is my block diagram sketch:
So I end up these 3 vhd source files:
Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Count_src is
Port ( CLK : in STD_LOGIC;
Reset : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0));
end Count_src;
architecture Behavioral of Count_src is
signal count : STD_LOGIC_VECTOR (3 downto 0);
begin
process (Reset, CLK)
begin
if Reset = '1' then -- Active high reset
count <= "0000"; -- Clear count to 0
elsif (rising_edge(CLK)) then -- Positive edge
count <= count + "0001"; -- increment count
end if;
end process;
S <= count; -- Export count
end Behavioral;
Compare
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Compare_src is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
S : out STD_LOGIC);
end Compare_src;
architecture Behavioral of Compare_src is
begin
S <= '1' when (A = B) else -- Test if A and B are same
'0'; -- Set when S is different
end Behavioral;
CountCompare (Top Level)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CountCompare_src is
Port ( Clock : in STD_LOGIC;
Reset : in STD_LOGIC;
Value : in STD_LOGIC_VECTOR (3 downto 0);
Flag : out STD_LOGIC);
end CountCompare_src;
architecture Behavioral of CountCompare_src is
-- COMPONENT DECLERATIONS
component counter is
port ( CLK : in std_logic;
Reset : in std_logic;
S : out std_logic_vector(3 downto 0)
);
end component;
component compare is
port (A : in std_logic_vector(3 downto 0);
B : in std_logic_vector(3 downto 0);
S : out std_logic
);
end component;
-- Component Spesification and Binding
for all : counter use entity work.Count_src(behavioral);
for all : compare use entity work.Compare_src(behavioral);
-- Internal Wires
signal count_out : std_logic_vector(3 downto 0);
begin
-- Component instantiation
C1: counter PORT MAP ( Reset => Reset,
CLK => Clock,
S => count_out
);
C2: compare PORT MAP ( A => count_out,
B => Value,
S => Flag
);
end Behavioral;
To test the design I wrote a testbench as follows:
TestBench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY TopLevelTester_tb IS
END TopLevelTester_tb;
ARCHITECTURE behavior OF TopLevelTester_tb IS
--Input and Output definitions.
signal Clock : std_logic := '0';
signal Reset : std_logic := '0';
signal Value : std_logic_vector(3 downto 0) := "1000";
signal Flag : std_logic;
-- Clock period definitions
constant clk_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.CountCompare_src PORT MAP
(
Clock => Clock,
Reset => Reset,
Value => Value
);
proc: process
begin
Clock <= '0';
wait for clk_period/2;
Clock <= '1';
wait for clk_period/2;
end process;
END;
When I simulate behavioral model, the ISIM pops up, but I see no changes on the Compare Flag. Here is the ss of the ISIM:
What am I missing here? Why does'nt the Flag change?
My best regards.
You have two problems, both in your testbench.
The first is that you never reset count in the counter, it will always be 'U's or 'X's (after you increment it).
The second is that the directly entity instantiation in the testbench is missing an association for the formal flag output to the actual flag signal:
begin
uut:
entity work.countcompare_src
port map (
clock => clock,
reset => reset,
value => value,
flag => flag
);
proc:
process
begin
clock <= '0';
wait for clk_period/2;
clock <= '1';
wait for clk_period/2;
if now > 20 ns then
wait;
end if;
end process;
stimulus:
process
begin
wait for 1 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
Fix those two things and you get:
I'm in the process of writing the VHDL code for Salsa20 stream cipher. Its main function is the 'quarterround' which I have successfully written. I want to test it in Modelsim before moving on but I am encountering difficulties. I understand I have to 'stimulate' the inputs to observe the outputs. All attempts I've made have resulted in the output, z, not giving any values.
The code for the Quarterround (which is top level):
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round is
GENERIC(l:integer:=9);
PORT(y : in unsigned(127 downto 0);
z : out unsigned( 127 downto 0)
);
END quarter_round;
ARCHITECTURE quarter_round_arch of quarter_round is
COMPONENT left is
GENERIC(l:integer);
PORT( a: in unsigned( 31 downto 0);
b: out unsigned( 31 downto 0));
end COMPONENT;
signal i1,i2,i3,i4 :unsigned( 31 downto 0);
signal j1,j2,j3,j4 :unsigned( 31 downto 0);
signal z0,z1,z2,z3 :unsigned( 31 downto 0);
signal y0 : unsigned( 31 downto 0);
signal y1 : unsigned( 31 downto 0);
signal y2 : unsigned( 31 downto 0);
signal y3 : unsigned( 31 downto 0);
BEGIN
y0 <=y(127 downto 96);
y1 <=y(95 downto 64);
y2 <=y(63 downto 32);
y3 <=y(31 downto 0);
i1<=y0+y3;
a1:left generic map(7) port map(i1,j1);
z1<=j1 xor y1;
i2<=z1+y0;
a2:left generic map(9) port map(i2,j2);
z2<=j2 xor y2;
i3<=z2+z1;
a3:left generic map(13) port map(i3,j3);
z3<=j3 xor y3;
i4<=z3+z2;
a4:left generic map(18) port map(i4,j4);
z0<=j4 xor y0;
z<=z0&z1&z2&z3;
END quarter_round_arch;
The COMPONENT left:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY left is
GENERIC (l:integer:=7);
PORT( n: in unsigned( 31 downto 0);
m: out unsigned( 31 downto 0));
END left;
ARCHITECTURE dataflow of left is
begin
m<=n(31-l downto 0)& n(31 downto 31-l+1);
END dataflow;
The testbench I'm trying to write will be assigned a value for y (128 bits), process the function and z should output the correct answer in Modelsim. I realize this is a basic VHDL question, but it's driving me nuts!
This code is failing Modelsim:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round_vhd_tst IS
END quarter_round_vhd_tst;
ARCHITECTURE test of quarter_round_vhd_tst IS
COMPONENT quarter_round
PORT (
y : IN STD_LOGIC_VECTOR(127 DOWNTO 0);
z : OUT STD_LOGIC_VECTOR(127 DOWNTO 0)
);
END COMPONENT;
SIGNAL clk : std_logic := '0';
SIGNAL reset : std_logic := '0';
SIGNAL y : STD_LOGIC_VECTOR(127 DOWNTO 0);
SIGNAL z : STD_LOGIC_VECTOR(127 DOWNTO 0);
BEGIN
DUT : quarter_round
PORT MAP (
y => y,
z => z
);
y <= x"201f1e1d1c1b1a191817161514131211";
PROCESS
BEGIN
clk <= '0' ;
wait for 10 ns;
z <= y ;
clk <= '1';
wait for 10 ns;
END PROCESS;
END test;
Edit: this is latest attempt. Code is compiling but Modelsim giving errors saying types do not match.. Any ideas appreciated. CT
david_koontz#Macbook: ghdl -a quarter_round.vhdl
david_koontz#Macbook: ghdl -e quarter_round_vhd_tst
quarter_round.vhdl:100:1: type of signal interface "y" from component
"quarter_round" and port "y" from entity "quarter_round" are not
compatible for an association quarter_round.vhdl:100:1: type of
signal interface "z" from component "quarter_round" and port "z" from
entity "quarter_round" are not compatible for an association ghdl:
compilation error
So the problem you describe after the edit shows up during elaboration. Note the type in the component declaration and the entity quarter_round don't match.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity quarter_round_vhd_tst is
end quarter_round_vhd_tst;
architecture test of quarter_round_vhd_tst is
component quarter_round
port (
y: in unsigned(127 downto 0);
z: out unsigned(127 downto 0)
);
end component;
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal y : unsigned(127 downto 0);
signal z : unsigned(127 downto 0);
begin
DUT: quarter_round
port map (
y => y,
z => z
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 30 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 10 ns;
y <= x"201f1e1d1c1b1a191817161514131211";
wait for 10 ns;
-- z <= y ;
wait;
end process;
end test;
The changes are for a separate process for clock, likely you'll need it once you add more in. You originally tried to assign z in the testbench, z is an output of quarter_round.
I moved the y assignment into the stimulus process. If the reset gets used you can put that in there too.
The idea behind using wait statements without arguments is to stop processes from repeating endlessly. As long as you assign signals they'd go until Time'HIGH. The comparison for Now in process CLOCK can be changed for multiple stimulus or length of time to execute. Likewise you can introduce a signal used to stop the clock that is assigned in a process (e.g. STIMULUS) that is used instead of Now to stop the clock, if there's something coming out of the (eventual) model that signals end of simulation.
Without the DUT relying on clock (or reset) as soon as y is assigned, z is assigned with the result. (This is why I put the delay before the y assignment, to demonstrate this).
I used the quarter_round and left I corrected yesterday, so mine has a and b instead of m and n.
So does the result look right?
Once over the hurtle of getting something back, then sequential (clocked) processes and you should start making good progress.
And you can use type conversions in the port map for quarter round:
signal y : std_logic_vector(127 downto 0);
signal z : std_logic_vector(127 downto 0);
begin
DUT: quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
But the component declaration still needs to match the entity declaration for quarter_round.
And if you're sure you'll never need to configure quarter_round in the testbench you can use direct entity instantiation, eliminating the component declaration:
-- component quarter_round
-- port (
-- y: in unsigned(127 downto 0);
-- z: out unsigned(127 downto 0)
-- );
-- end component;
...
begin
DUT: -- quarter_round
entity work.quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
It's generally useful to have a valid component declaration or to at least use formal association (instead of positional, the above shows formal). That way someone reading the code doesn't have to count arguments while looking somewhere else.
Notice the directly instantiated entity is specified with a selected name specifying the library the entity is found in.
You must have overlooked the compilation errors relating to "left.vhd". Signals "a" and "b" are undeclared.
I'm new to VHDL and I'm making a 4bit adder using 4 Full Adders. I created a test bench to see if the adder is working and in the ans I'm getting values of UUUU. From what I read is that the process is not being executed. I have no idea how to fix this, any help would be appreciated.
Here is the TestBench
ENTITY Adder4_Test IS
END Adder4_Test;
ARCHITECTURE behavior OF Adder4_Test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Adder4
PORT(
X : IN STD_LOGIC_vector(3 downto 0);
Y : IN STD_LOGIC_vector(3 downto 0);
Ans : OUT STD_LOGIC_VECTOR(3 downto 0);
Cout : OUT STD_LOGIC
);
END COMPONENT;
--Inputs
signal X : STD_LOGIC_vector(3 downto 0) := (others => '0');
signal Y : STD_LOGIC_vector(3 downto 0) := (others => '0');
--Outputs
signal Ans : STD_LOGIC_vector(3 downto 0);
signal Cout : STD_LOGIC;
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
--constant <clock>_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Adder4 PORT MAP (
X,
Y,
Ans,
Cout
);
-- Clock process definitions
--<clock>_process :process
--begin
--<clock> <= '0';
--wait for <clock>_period/2;
--<clock> <= '1';
--wait for <clock>_period/2;
--end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
--wait for 100 ns;
--wait for <clock>_period*10;
-- insert stimulus here
-- Case 1 that we are testing.
X <= "0000";
Y <= "0000";
wait for 10 ns;
assert ( Ans = "0000" )report "Failed Case 1 - Ans" severity error;
assert ( Cout = '0' ) report "Failed Case 1 - Cout" severity error;
wait for 40 ns;
-- Case 2 that we are testing.
X <= "1111";
Y <= "1111";
wait for 10 ns;
assert ( Ans = "1110" )report "Failed Case 2 - Ans" severity error;
assert ( Cout = '1' ) report "Failed Case 2 - Cout" severity error;
wait for 40 ns;
wait;
end process;
END;
Here is the Adder4
entity Adder4 is
Port ( X : in STD_LOGIC_vector (3 DOWNTO 0);
Y : in STD_LOGIC_vector (3 DOWNTO 0);
Ans: out STD_LOGIC_vector (3 DOWNTO 0);
Cout: out STD_LOGIC);
end Adder4;
architecture Structure of Adder4 is
component FullAdder is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC);
end component;
signal c0, c1, c2, c3: STD_LOGIC;
begin
c0 <='0';
b_adder0: FullAdder port map (X(0), Y(0), c0, Ans(0), c1);
b_adder1: FullAdder port map (X(1), Y(1), c1, Ans(1), c2);
b_adder2: FullAdder port map (X(2), Y(2), c2, Ans(2), c3);
b_adder3: FullAdder port map (X(3), Y(3), c3, Ans(3), Cout);
end Structure;
Here is the FullAdder
entity FullAdder is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC);
end FullAdder;
architecture Behavioral of FullAdder is
component Xor_Model is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
Z : out STD_LOGIC);
end component;
begin
Cout <= ((X and Y) or (Y and Cin) or (X and Cin));
Sum <= (X AND (NOT Y) AND (NOT Cin)) OR ((NOT X) AND Y AND (NOT Cin)) OR
((NOT X) AND (NOT Y) AND Cin) OR (X AND Y AND Cin) after 5ns;
xorLabel: Xor_Model
Port Map ( A => X, B => Y, C => Cin, Z => Sum);
end Behavioral;
After adding context clauses you didn't supply, separating 5ns into 5 ns and insuring the entities needed in Addr4 were analyzed in the right order, I tried to run a simulation using ghdl where I promptly got an error message"
Adder4.vhdl:28:1:warning: component instance "xorlabel" is not bound
Adder4.vhdl:12:15:warning: (in default configuration of fulladder(behavioral))
This for the FullAdder. Seeing it was a 3 input XOR, I added one:
library ieee;
use ieee.std_logic_1164.all;
entity Xor_model is
Port (A: in std_logic;
B: in std_logic;
C: in std_logic;
Z: out std_logic
);
end entity;
architecture behavioral of Xor_model is
begin
Z <= A xor B xor C;
end behavioral;
There were 'U's on ans until 5 ns, from the Sum assignment delay in FullAdder.
I got 'X's at 50 ns on ans cleared 5 ns later from the same delayed assignment. Notice the LSB is '0' due to a short circuit logical operator.
Adding FF to FF got FE (correct without regards to carryout which showed up correctly as '1').
Getting rid of the initial 'U's could be done one of two ways. Either assign a known value to Sum as a default value instead of relying on the default, or removing the delay in the assignment to Sum.
The 'X's are dependent on Sum from the FullAdders as well, there are transitions on inputs while waiting for 5 ns.
In a behavioral combinatoric model delays aren't particularly expressive, in particular when you don't use delays for sub terms. If you delay contributing signals all along then signal path for a particular net based on gate delays, Sum would show up at the correct cumulative delay time. You could also use an intermediary Sum (with a different signal name) generated without delay and assign it to the output port Sum after a delay, eliminating the 'X's. Move the after 5 ns from FullAdder to Adder4:
In FullAdder:
((NOT X) AND (NOT Y) AND Cin) OR (X AND Y AND Cin) ; --after 5 ns;
In Adder4:
architecture Structure of Adder4 is
signal sum: std_logic_vector(3 downto 0);
b_adder0: FullAdder port map (X(0), Y(0), c0, sum(0), c1);
b_adder1: FullAdder port map (X(1), Y(1), c1, sum(1), c2);
b_adder2: FullAdder port map (X(2), Y(2), c2, sum(2), c3);
b_adder3: FullAdder port map (X(3), Y(3), c3, sum(3), Cout);
And add delay assigning sum to the ans:
Ans <= sum after 5 ns;
And where if you set a default value of '0's on Ans in the Adder4 port:
Ans: out STD_LOGIC_vector (3 DOWNTO 0) := (others => '0');
You can get rid of the initial 'U's:
And to clarify the 'U's are there until there is a transaction on the output (Ans) following the after 5 ns delay. It might be more proper to use (others => 'X')