------------------------------------------------------------ -- test_mult.vhd -- -- This file contains the test bench for the multiply unit. -- -- For simulation you should also compile the files: -- mult.vhd which contains the components of the VMU -- controller.vhd which contains a model for a simple controller -- ------------------------------------------------------------ ------------------------------------------------------------ -- Entity and architecture for test_vmu ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity test_vmu is end entity test_vmu; architecture test_bench of test_vmu is component vmu is port (clock12MHz : in std_logic; clock : in std_logic; nReset, H2, C3, C2 : in std_logic; portB : inout std_logic_vector(7 downto 0); H3, H1 : inout std_logic; -- not INOUT but readable OUT Start, LsbB, EmptyB, FullB : inout std_logic; -- not INOUT but readable OUT UpdateA, UpdateB, UpdateP, Shift, ZeroP, Subtract, EnableP : in std_logic; segA, segB, segC, segD, segE, segF, segG, ucRESET, ramDISABLE: out std_logic); end component vmu; component controller is port (clock, nReset : in std_logic; Start : in std_logic; LsbB, EmptyB, FullB : in std_logic; UpdateA, UpdateB, UpdateP, Shift, ZeroP, Subtract, EnableP: out std_logic ); end component controller; signal clock12MHz : std_logic := '0'; -- not used here signal clock : std_logic := '1'; signal nReset : std_logic; signal H2, C3, C2 : std_logic; signal PortB : std_logic_vector(7 downto 0); signal H3, H1 : std_logic; signal Start, LsbB, EmptyB, FullB : std_logic; signal UpdateA, UpdateB, UpdateP, Shift, ZeroP, Subtract, EnableP : std_logic; signal segA, segB, segC, segD, segE, segF, segG : std_logic; signal ucRESET, ramDISABLE : std_logic; signal PortBout : std_logic_vector(7 downto 0); signal PortBin : std_logic_vector(7 downto 0); signal multiplicand, multiplier, result : std_logic_vector(31 downto 0); begin vmu_inst : vmu port map (clock12MHz, clock, nReset, H2, C3, C2, PortB, H3, H1, Start, LsbB, EmptyB, FullB, UpdateA, UpdateB, UpdateP, Shift, ZeroP, Subtract, EnableP, segA, segB, segC, segD, segE, segF, segG, ucRESET, ramDISABLE ); controller_inst : controller port map (clock, nReset, Start, LsbB, EmptyB, FullB, UpdateA, UpdateB, UpdateP, Shift, ZeroP, Subtract, EnableP ); PortB <= PortBout when H1='1' else (others => 'Z'); PortBin <= PortB; clock <= not clock after 500 us; -- 1kHz Clock source stimulus : process is procedure trigger_output is begin H2 <= '0'; wait until H1='1'; wait until H1='0'; H2 <= '1'; end procedure; procedure trigger_calculation is begin C2 <= '1'; wait until H3='1'; C2 <= '0'; wait until H3='0'; end procedure; procedure output_data8 (AnotD : in std_logic; data8 : in std_logic_vector(7 downto 0)) is begin C3 <= AnotD; PortBout <= data8; wait for 100 us; trigger_output; wait for 100 us; end procedure; procedure output_data32 (addr: in std_logic; data32 : in std_logic_vector(31 downto 0)) is begin output_data8 ('1', "00000" & addr & "00" ); output_data8 ('0', data32(07 downto 00) ); output_data8 ('1', "00000" & addr & "01" ); output_data8 ('0', data32(15 downto 08) ); output_data8 ('1', "00000" & addr & "10" ); output_data8 ('0', data32(23 downto 16) ); output_data8 ('1', "00000" & addr & "11" ); output_data8 ('0', data32(31 downto 24) ); end procedure; procedure input_data32 (data32 : out std_logic_vector(31 downto 0)) is begin output_data8 ('1', "00000000" ); data32(07 downto 00) := PortBin; output_data8 ('1', "00000001" ); data32(15 downto 08) := PortBin; output_data8 ('1', "00000010" ); data32(23 downto 16) := PortBin; output_data8 ('1', "00000011" ); data32(31 downto 24) := PortBin; end procedure; procedure multiply (op1 : in std_logic_vector(31 downto 0); op2 : in std_logic_vector(31 downto 0); res : out std_logic_vector(31 downto 0)) is begin output_data32 ( '0', op1 ); output_data32 ( '1', op2 ); trigger_calculation; input_data32 ( res ); end procedure; variable temp : std_logic_vector(31 downto 0); begin C3 <= '1'; C2 <= '0'; H2 <= '1'; nReset <= '0'; wait for 100 us; nReset <= '1'; wait for 10 ms; -- 6x9 should give 54 -- multiplicand <= std_logic_vector( to_unsigned( 6, 32 )); multiplier <= std_logic_vector( to_unsigned( 9, 32 )); multiply ( multiplicand, multiplier, temp ); result <= temp; wait for 10 ms; -- 21x54 should give 1134 -- multiplicand <= std_logic_vector( to_unsigned( 21, 32 )); multiplier <= std_logic_vector( to_unsigned( 54, 32 )); multiply ( multiplicand, multiplier, temp ); result <= temp; wait for 10 ms; -- 255x255 should give 65025 -- this is the largest value we can get from an -- eight bit unsigned multiplication -- multiplicand <= std_logic_vector( to_unsigned( 255, 32 )); multiplier <= std_logic_vector( to_unsigned( 255, 32 )); multiply ( multiplicand, multiplier, temp ); result <= temp; wait for 10 ms; -- 150x400 should give 60000 -- but 400 is too big for 8 bits -- so we get 150 x (400 mod 256) = 150 x 144 = 21600 -- multiplicand <= std_logic_vector( to_unsigned( 150, 32 )); multiplier <= std_logic_vector( to_unsigned( 400, 32 )); multiply ( multiplicand, multiplier, temp ); result <= temp; wait; -- process stops here. end process stimulus; end architecture test_bench;