I need to connect an ALU with a two-port data memory, but I can only implement this far, and I don't know what is missing, plus I am a bit confused as to what to write for the testbench code epsecially when it come to what time intervals I should put, can someone please help?
Here is the VHDL code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity micro is
port( alu: in signed (31 downto 0);
rom: in unsigned (4 downto 0);
c: out std_logic));
end entity micro;
architecture comb of micro is
signal romalucon: std_logic_vector (31 downto 0);
begin
g1: entity.work.rom(comb)
port ( data_out1 => romalucon, data_out2 => romalucon);
g2: entity.work.alu(comb)
port ( a => roamlucon, b => romalucon);
end architecture comb;
And the testbench, so far:
library IEEE;
use IEEE.std_logic_1164.all;
entity micro_test is
end entity micro_test;
architecture end_product of micro_test is
signal alu_input: std_logic_vector (31 downto 0);
signal rom_input: std_logic_vector (4 downto 0);
signal c_output: std_logic;
begin
g3: entity.work.micro(comb)
port map ( alu => alu_input, rom => rom_input, c => c_output );
Additionally, here is the VHDL code for the ALU:
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_signed.ALL; --In this case signed arithmetic is used due to the fact that one of the variable operations utilised in this code is the absolute value function which only exists for signed values, therefore the values in this code need to be signed numbers.
entity alu is
port (
A, B: in std_logic_vector(31 downto 0);
opcode: in std_logic_vector(5 downto 0);
Result: out std_logic_vector(31 downto 0));
end entity alu;
architecture dataoperations of alu is begin Result <= A + B when opcode="001010" else A - B when opcode="001000" else abs(A) when opcode="001011" else -A when opcode="001101" else abs(B) when opcode="000001" else -B when opcode="001001" else A or B when opcode="000110" else not A when opcode="001111" else not B when opcode="000101" else A and B when opcode="001100" else A xor B when opcode="000010"; end architecture dataoperations;
The testbench for ALU:
library IEEE;
use IEEE.std_logic_1164.all;
entity alu_test is
end entity alu_test;
architecture test of alu_test is
signal in1, in2, out1: std_logic_vector (31 downto 0);
signal in3: std_logic_vector (5 downto 0);
begin
g1: entity work.alu(dataoperations)
port map ( A => in1, B => in2, opcode => in3, Result => out1 );
in1 (6) <= '0';
in1 (5 downto 0) <= x"000000",
x"000001" after 10 ns,
x"2" after 20 ns,
x"3" after 30 ns,
x"4" after 40 ns,
x"5" after 50 ns;
in2 (6) <= '0';
in2 (5 downto 0) <= x"6",
x"7" after 60 ns,
x"8" after 70 ns,
x"9" after 80 ns,
x"A" after 90 ns,
x"B" after 100 ns;
in3 <= "000000";
end architecture test;
The VHDL code for the 5-bit input, 32-bit output ROM:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all; --The reason why unsigned arithmetic is used here is because we will need to convert the hexadecimal inputs to integers, and by using unsigned we allow ourselves to get values within the number the number range requested in line 11 of the code, ie from 0 to 31. If we didn't use unsigned, then except from positive value, we would also probably get neagtive addr values, which would not fall within our request.
entity rom is
port ( addr1, addr2: in std_logic_vector(4 downto 0);
data_out1, data_out2: out std_logic_vector(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");
begin
data_out1 <= rom_data (conv_integer (addr1) );
data_out2 <= rom_data (conv_integer (addr2) );
end architecture dataflow;
And the testbench for the ROM:
library IEEE;
use IEEE.std_logic_1164.all;
entity rom_test is
end entity rom_test;
architecture dataflow of rom_test is
signal input_address1, input_address2: std_logic_vector (4 downto 0);
signal output_data1, output_data2: std_logic_vector (31 downto 0);
begin
g1: entity work.rom(dataflow)
port map ( addr1 => input_address1, addr2 => input_address2, data_out1 => output_data1, data_out2 => output_data2 );
input_address1 (4) <= '0';
input_address1 (3 downto 0) <= x"0",
x"1" after 1 ns,
x"2" after 2 ns,
x"3" after 3 ns,
x"4" after 4 ns,
x"5" after 5 ns,
x"6" after 6 ns,
x"7" after 7 ns,
x"8" after 8 ns,
x"9" after 9 ns,
x"A" after 10 ns,
x"B" after 11 ns,
x"C" after 12 ns,
x"D" after 13 ns,
x"E" after 14 ns,
x"F" after 15 ns,
x"10" after 16 ns,
input_address2 (4 downto 0) <= x"11",
x"12" after 17 ns,
x"13" after 18 ns,
x"14" after 19 ns,
x"15" after 20 ns,
x"16" after 21 ns,
x"17" after 22 ns,
x"18" after 23 ns,
x"19" after 24 ns,
x"1A" after 25 ns,
x"1B" after 26 ns,
x"1C" after 27 ns,
x"1D" after 28 ns,
x"1E" after 29 ns,
x"1F" after 30 ns;
end architecture dataflow;