I'm writing a VHDL code to model an 8x1 multiplexer where each input has 32-bit width. So I created an array to model the MUX but now I'm stuck with the Test Bench, it's gotten so complicated. Here is my original file (I'm sure it has so many redundancies) How can I actually make the test bench to recognize my array (R_in) from the component's file and then how will I stimulate it?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY mux8_1 IS
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
ARCHITECTURE behaviour OF mux8_1 IS
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal R_in:t_array_mux;
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
process(R_in, Rs)
BEGIN
CASE Rs IS
WHEN "000"=>R_out<=R_in(0);
WHEN "001"=>R_out<=R_in(1);
WHEN "010"=>R_out<=R_in(2);
WHEN "011"=>R_out<=R_in(3);
WHEN "100"=>R_out<=R_in(4);
WHEN "101"=>R_out<=R_in(5);
WHEN "110"=>R_out<=R_in(6);
WHEN "111"=>R_out<=R_in(7);
WHEN OTHERS=>R_out<= (others => '0');
END CASE;
END process;
END behaviour;
And here is my "in progress" test bench file. Just ignore the "stimulus process" part I know it's wrong I just couldn't figure out how to write it for a 32-bit signal.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY mux8_1_TB IS
END mux8_1_TB;
ARCHITECTURE behaviour OF mux8_1_TB IS
COMPONENT mux8_1
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
--Inputs
signal R_in:t_array_mux:=(others=>'0');
signal in0,in1,in2,in3,in4,in5,in6,in7 :STD_LOGIC_VECTOR(31 DOWNTO 0):=(others=>'0');
signal Rs :STD_LOGIC_VECTOR(2 DOWNTO 0):=(others=>'0');
--Outputs
signal R_out:STD_LOGIC_VECTOR(31 DOWNTO 0);
-- Instantiate the Unit Under Test + connect the ports to my signal
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
uut: mux8_1 PORT MAP(
Rs=>Rs,
R_in=>R_in,
R_out=>R_out
);
-- Stimulus process (where the values -> inputs are set)
PROCESS
begin
R_in<="01010101";
wait for 10 ns;
Rs<="001";
wait for 10 ns;
Rs<="010";
wait for 20 ns;
Rs<="011";
wait for 30 ns;
Rs<="100";
wait for 40 ns;
Rs<="101";
wait for 50 ns;
Rs<="110";
wait for 60 ns;
Rs<="111";
wait for 70 ns;
END PROCESS;
END;
You need to change your uut
port map so instead of R_in
, it has individual in0 - in7
ports to match your mux8_1
component definition. Then, map in0 - in7
testbench signals directly to these ports:
uut: mux8_1 port map(
...
in0 => in0,
in1 => in1,
...
);
Or if you want to keep the R_in
signal, port map like this:
uut: mux8_1 port map(
...
in0 => R_in(0),
in1 => R_in(1),
...
);
This assignment to R_in
in your testbench is incorrect:
R_in<="01010101";
R_in
is defined as a t_array_mux
type, so it can't be assigned a bit vector value. It has to be assigned to an array of 32-bit std_logic_vector
. That line should really be removed altogether, as you're already making assignments to R_in
in another location outside of the process. Multiple assignments will cause signal contention.
You're initializing R_in
in your testbench like this:
signal R_in:t_array_mux:=(others=>'0');
The others
keyword as you've used it will only work on an individual std_logic_vector
. You need to nest others
for your array of std_logic_vector
:
signal R_in:t_array_mux:=(others=>(others=>'0'));
You'll want to assign values to your 32-bit in0 - in7
signals so you can see the output of your mux change in the sim. They can be assigned outside the stimulus process. You can assign them using hex-notation (x preceding "") or just binary:
in0 <= x"12345678"; --hex
or
in0 <= "00010010001101000101011001111000"; --binary
Your stimulus process looks fine. As you change Rs
, you would expect to see the different input values on R_out
. You could add a single wait;
at the end of the process, or the process will keep repeating until the end of sim.
Component ports with user-defined types
Alternatively, you could port map
your R_in
testbench signal directly to a R_in
port on your component as you've done, but it would take a bit more work. Your mux8_1
component definition does not have an R_in
port. You can add a t_array_mux
type port named R_in
, if you define the t_array_mux
type in a package which you then include in your component and testbench files
library work;
use work.your_package_name.all;
in addition to library IEEE
, etc. Then you can use the t_array_mux
type in your component port definition:
ENTITY mux8_1 IS
PORT(Rs : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
R_in : IN T_ARRAY_MUX; --User-defined port type
R_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
This will allow you to do the port mapping of your uut
the way you currently have it. You'll have to add the package to the project or compile list in whatever tool you're using.