I am writing two VHDL codes; one for an ALU and another one for a two-port data memory.
After some useful recommendations from contibutors here in Stack Overflow, I have managed to come up with the following VHDL codes for an ALU and a two-port data memory.
The problem is, I don't know what to put on the memory's testbench to actually make all the addresses show up in the simulation, and as for the ALU code, I am not sure that simulation result is the correct one.
The purpose of the testbench for the ALU is to show all the operations dictated in the VHDL code, are showing up on the simulation, and the purpose of the testbench for the memory is to test if all the address values implemented on VHDL code are showing up on the simulation. Can someone please help as this is really important for me to finish it. Many thanks in advance to whoever decides to help. I have just started learning VHDL so sorry if the mistakes are too many.
Here is the VHDL code for the ALU:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity alu is
port (
A, B: in signed (31 downto 0);
opcode: in std_logic_vector(5 downto 0);
Result: out signed (31 downto 0));
end entity alu;
architecture dataoperations of alu is
begin
process (A, B, opcode)
begin
Result <= A + B when opcode="001010" -- Addition
else A - B when opcode="001000" --Subtraction
else abs(A) when opcode="001011" --Absolute value of A
else -A when opcode="001101" --Minus A
else abs(B) when opcode="000001" -- Absolute value of B
else -B when opcode="001001" --Minus B
else A or B when opcode="000110" --A or B
else not A when opcode="001111" --Not A
else not B when opcode="000101" --Not B
else A and B when opcode="001100" -- A and B
else A xor B when opcode="000010"; --A exclusive or B
end process;
end architecture dataoperations;
Here is the testbench for the ALU:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity alu_test is
end entity alu_test;
architecture test of alu_test is
-- Introducing the Unit Under Test (UUT), in this case, the ALU
component alu
port ( A, B: in signed (31 downto 0) := (others => '0');
opcode: in std_logic_vector(5 downto 0) := (others => '0');
Result: out signed (31 downto 0));
end component;
-- Input generator
signal A, B: signed (31 downto 0) := (others => '0');
signal opcode: std_logic_vector (5 downto 0) := (others => '0') ;
-- Output display
signal Result: signed (31 downto 0);
begin
uut:alu
port map ( A => A, B => B, opcode => opcode, Result => Result );
stimulus_process: process
begin
wait for 5 ns;
A <= "00000000000000000000000000001001";
B <= "00000000000000000000000000001111";
opcode <= "001010";
wait for 5 ns;
opcode <= "001000";
wait for 5 ns;
opcode <= "001011";
wait for 5 ns;
opcode <= "001101";
wait for 5 ns;
opcode <= "000001";
wait for 5 ns;
opcode <= "001001";
wait for 5 ns;
opcode <= "000110";
wait for 5 ns;
opcode <= "001111";
wait for 5 ns;
opcode <= "000101";
wait for 5 ns;
opcode <= "001100";
wait for 5 ns;
opcode <= "000010";
end process;
end;
The VHDL code for the data memory:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity rom is
port ( addr1, addr2: in unsigned (4 downto 0);
data_out1, data_out2: out unsigned (31 downto 0));
end entity rom;
architecture dataflow of rom is
type rom_array is array (0 to 31)
of std_logic_vector (31 downto 0);
signal rom_data: rom_array :=
(x"00000000", x"00000000", x"000005E4", x"0000EE7C", x"000175FE", x"00000BAE", x"0000E4E0", x"00000F20", x"00013CE3", x"000072B0", x"000075BE", x"00005974", x"0000DC71", x"00009064", x"0000D246", x"00017CE1", x"00015275", x"00011CD8",x"000131F3", x"00013B3F", x"00000149", x"000124D5", x"000051CD", x"00015A16", x"00016EAE", x"0000A312", x"00007F96", x"000161A4", x"0001673C", x"00005E6F", x"000154B5", x"00000000");
end architecture dataflow;
And the testbench:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity rom_test is
end entity rom_test;
architecture behaviour of rom_test is
-- Introducing the UUT, here it is rom
component rom
port ( addr1, addr2: in unsigned (4 downto 0);
data_out1, data_out2: out unsigned (31 downto 0));
end component;
signal addr1, addr2: unsigned (4 downto 0);
signal data_out1, data_out2: unsigned (31 downto 0);
begin
uut: rom
port map ( addr1 => addr1, addr2 => addr2, data_out1 => data_out1, data_out2 => data_out2 );
Additionally, it is a 32-bit ALU with 6-bit opcode, and it is a two-port data memory with 5-bit input (on each port) and 32-bit output.