------------------------------------- -- Define data width -- ------------------------------------- package mypackage is constant HORZ_CELL :natural := 2; constant VERT_CELL :natural := 5; constant NBITS :natural := VERT_CELL * 2; constant MBITS :natural := HORZ_CELL * 4; end mypackage; --------------------------------------------------------- -- Ripple-carry multiplier for unsigned operands (base 2) -- using 4x2 bits multipleier cell ---------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.mypackage.all; entity ripple_carry_4x2_mult is Port ( X : in std_logic_vector(NBITS-1 downto 0); Y : in std_logic_vector(MBITS-1 downto 0); P : out std_logic_vector(MBITS+NBITS-1 downto 0)); end ripple_carry_4x2_mult; architecture Behavioral of ripple_carry_4x2_mult is component mul_4x2_cell Port ( X_i : in std_logic_vector(1 downto 0); Y_j : in std_logic_vector(3 downto 0); Cin : in std_logic_vector(1 downto 0); Din : in std_logic_vector(3 downto 0); Cout : out std_logic_vector(1 downto 0); Dout : out std_logic_vector(3 downto 0) ); end component; type connect_2 is array (0 to VERT_CELL, 0 to HORZ_CELL) of STD_LOGIC_VECTOR (1 downto 0); Signal Cin, Cout: connect_2; type connect_4 is array (0 to VERT_CELL, 0 to HORZ_CELL) of STD_LOGIC_VECTOR (3 downto 0); Signal Din, Dout: connect_4; begin iniH: for i in 0 to HORZ_CELL-1 generate Din(0, i) <= "0000"; end generate; iniV: for i in 0 to VERT_CELL-1 generate Cin(i, 0) <= "00"; end generate; ext_loop: for i in 0 to VERT_CELL-1 generate int_loop: for j in 0 to HORZ_CELL-1 generate cell: mul_4x2_cell port map( X_i => X((i+1)*2-1 downto i*2), Y_j => Y((j+1)*4-1 downto j*4), Cin => Cin(i,j), Din => Din(i,j), Cout => Cout(i,j), Dout => Dout(i,j) ); Cin(i,j+1) <= Cout(i,j); j_0: if J = 0 generate P((i+1)*2-1 downto i*2) <= Dout(i,j)(1 downto 0); Din(i+1,j)(1 downto 0) <= Dout(i,j)(3 downto 2); end generate; jn0: if J > 0 generate Din(i+1,j-1)(3 downto 2) <= Dout(i,j)(1 downto 0); Din(i+1,j)(1 downto 0) <= Dout(i,j)(3 downto 2); end generate; end generate; Din(i+1,HORZ_CELL-1)(3 downto 2) <= Cin(i,HORZ_CELL); end generate; out_loop: for i in 0 to HORZ_CELL-1 generate P((i+1)*4+NBITS-1 downto i*4+NBITS) <= Din(VERT_CELL,i); end generate; end Behavioral; --------------------------------------------------------- -- Basic 4x2 bits multiplier cell -- used in ripple-carry 4x2 multiplier -- ---------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; entity mul_4x2_cell is Port ( X_i : in std_logic_vector(1 downto 0); Y_j : in std_logic_vector(3 downto 0); Cin : in std_logic_vector(1 downto 0); Din : in std_logic_vector(3 downto 0); Cout : out std_logic_vector(1 downto 0); Dout : out std_logic_vector(3 downto 0) ); end mul_4x2_cell; architecture Behavioral of mul_4x2_cell is signal int_prod, int_result: std_logic_vector(5 downto 0); begin int_prod <= X_i * Y_j; int_result <= int_prod + Cin + Din; Dout <= int_result(3 downto 0); Cout <= int_result(5 downto 4); end Behavioral; ---------------------------------------------------------------------- -- VHDL Test Bench for Ripple carry 4x2 multiplier -- -- Notes: ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_unsigned.all; USE work.mypackage.all; LIBRARY ieee; USE IEEE.STD_LOGIC_TEXTIO.ALL; USE STD.TEXTIO.ALL; ENTITY test_rc_exhaustive IS END test_rc_exhaustive; ARCHITECTURE behavioural OF test_rc_exhaustive IS constant DELAY: time := 100 ns; FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; COMPONENT ripple_carry_4x2_mult PORT( X : IN std_logic_vector(NBITS-1 downto 0); Y : IN std_logic_vector(MBITS-1 downto 0); P : OUT std_logic_vector(MBITS+NBITS-1 downto 0) ); END COMPONENT; SIGNAL x : std_logic_vector(NBITS-1 downto 0); SIGNAL y : std_logic_vector(MBITS-1 downto 0); SIGNAL p : std_logic_vector(MBITS+NBITS-1 downto 0); BEGIN uut: ripple_carry_4x2_mult PORT MAP(X => x, Y => y, P => p); tb_test : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); BEGIN for I in 0 to 2**NBITS-1 loop for J in 0 to 2**MBITS-1 loop x <= CONV_STD_LOGIC_VECTOR (I, NBITS); y <= CONV_STD_LOGIC_VECTOR (J, MBITS); WAIT FOR DELAY/2; IF ( I*J /= CONV_INTEGER(P)) THEN write(TX_LOC,string'("ERROR!!! X=")); write(TX_LOC, X); write(TX_LOC,string'(" Y=")); write(TX_LOC, Y); write(TX_LOC,string'(" P=")); write(TX_LOC, P); write(TX_LOC, string'(" ")); TX_STR(TX_LOC.all'range) := TX_LOC.all; writeline(results, TX_LOC); Deallocate(TX_LOC); ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR; END IF; WAIT FOR DELAY/2; end loop; end loop; ASSERT (FALSE) REPORT "Simulation successful (not a failure). No problems detected. " SEVERITY FAILURE; END PROCESS; END;