------------------------------------- -- Define data width -- ------------------------------------- package mypackage is constant NBITS :natural := 8; constant MBITS :natural := 10; end mypackage; --------------------------------------------------------- -- Ripple-carry multiplier for unsigned operands (base 2) -- ---------------------------------------------------------- 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_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_mult; architecture Behavioral of ripple_carry_mult is component basic_mul_cell Port ( X_i : in std_logic; Y_j : in std_logic; Cin : in std_logic; Pin : in std_logic; Cout : out std_logic; Pout : out std_logic ); end component; type conections is array (0 to NBITS) of STD_LOGIC_VECTOR (MBITS downto 0); Signal Cin, Pin, Cout, Pout: conections; begin init: for i in 0 to NBITS-1 generate Cin(i)(0) <= '0'; end generate; Pin(0) <= (others => '0'); ext_loop: for i in 0 to NBITS-1 generate int_loop: for j in 0 to MBITS-1 generate cell: basic_mul_cell port map( X_i => X(i), Y_j => Y(j), Cin => Cin(i)(j), Pin => Pin(i)(j), Cout => Cout(i)(j), Pout => Pout(i)(j) ); Cin(i)(j+1) <= Cout(i)(j); j_0: if J = 0 generate P(i) <= Pout(i)(j); end generate; jn0: if J > 0 generate Pin(i+1)(j-1) <= Pout(i)(j); end generate; end generate; Pin(i+1)(MBITS-1) <= Cin(i)(MBITS); end generate; P(MBITS+NBITS-1 downto NBITS) <= Pin(NBITS)(MBITS-1 downto 0); end Behavioral; --------------------------------------------------------- -- Basic multiplier cell -- ---------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity basic_mul_cell is Port ( X_i : in std_logic; Y_j : in std_logic; Cin : in std_logic; Pin : in std_logic; Cout : out std_logic; Pout : out std_logic ); end basic_mul_cell; architecture Behavioral of basic_mul_cell is signal int_and: std_logic; begin int_and <= X_i and Y_j; Cout <= (Cin and Pin) or (Cin and int_and) or (Pin and int_and); Pout <= Cin xor int_and xor Pin; end Behavioral; ---------------------------------------------------------------------- -- VHDL Test Bench for Ripple carry 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_exhaustive IS END test_exhaustive; ARCHITECTURE behavioural OF test_exhaustive IS constant DELAY: time := 100 ns; FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; COMPONENT ripple_carry_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_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;