------------------------------------- -- Defines data path width ------------------------------------- package mypackage is constant NDIGITS :INTEGER := 3; constant MDIGITS :INTEGER := 5; constant BASE :INTEGER := 7; subtype digit is INTEGER range 0 to BASE-1; type digit_vector is array (natural range <>) of digit; function baseB_2_int (signal a: in digit_vector) return integer; function int_2_baseB (int: in integer; size: in integer) return digit_vector; end mypackage; package body mypackage is --Used in simulation testbench function baseB_2_int (signal a: in digit_vector) return INTEGER is variable int: INTEGER := 0; begin for i in a'Length-1 downto 0 loop int := int * BASE + A(i); end loop; return int; end baseB_2_int; function int_2_baseB (int: in INTEGER; size: in integer ) return digit_vector is variable s: digit_vector(size-1 downto 0); variable aux1, aux2: integer; begin aux1 := int; for i in 0 to size-1 loop s(i) := aux1 mod BASE; aux2 := aux1 / BASE; aux1 := aux2; end loop; return s; end int_2_baseB; end mypackage; --------------------------------------------------------- -- Basic base B multiplier (unsigned operands) ---------------------------------------------------------- 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 basic_base_B_mult is port ( X: in digit_vector(NDIGITS-1 downto 0); Y: in digit_vector(MDIGITS-1 downto 0); P: out digit_vector(NDIGITS+MDIGITS-1 downto 0) ); end basic_base_B_mult; architecture simple_arch of basic_base_B_mult is component mult_by_1_digit is port ( A: in digit_vector(MDIGITS-1 downto 0); B: in digit_vector(MDIGITS-1 downto 0); x_i : in digit; P: out digit_vector(MDIGITS downto 0) ); end component; type conections is array (0 to NDIGITS) of digit_vector(MDIGITS downto 0); Signal wires: conections; begin wires(0) <= (others => 0); iterac: for I in 0 to NDIGITS-1 generate mult: mult_by_1_digit port map (A => wires(i)(MDIGITS downto 1), B => Y, x_i => X(i), P => wires(i+1) ); p(i) <= wires(i+1)(0); end generate; p(MDIGITS+NDIGITS-1 downto NDIGITS) <= wires(NDIGITS)(MDIGITS downto 1); end simple_arch; ---------------------------------------------------- -- Mult_by_1_digit: Caclutate P <= A + (x_i*B) -- where x_i is a digit; A and B are digit vectors ---------------------------------------------------- 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 mult_by_1_digit is Port ( A: in digit_vector(MDIGITS-1 downto 0); B: in digit_vector(MDIGITS-1 downto 0); x_i : in digit; P: out digit_vector(MDIGITS downto 0) ); end mult_by_1_digit; architecture Behavioral of mult_by_1_digit is begin process(B,A, x_i) variable carry: digit_vector(MDIGITS downto 0); begin carry(0) := 0; for i in 0 to MDIGITS-1 loop P(i) <= (B(i) * X_i + A(i) + carry(i)) mod BASE; carry(i+1) := (B(i) * X_i + A(i) + carry(i)) / BASE; end loop; P(MDIGITS) <= carry(MDIGITS); end process; end Behavioral; ---------------------------------------------------------------------- -- VHDL Test Bench for basic_base_B_mult -- -- 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 basic_base_B_mult PORT( X: in digit_vector(NDIGITS-1 downto 0); Y: in digit_vector(MDIGITS-1 downto 0); P: out digit_vector(NDIGITS+MDIGITS-1 downto 0) ); END COMPONENT; SIGNAL x : digit_vector(NDIGITS-1 downto 0); SIGNAL y : digit_vector(MDIGITS-1 downto 0); SIGNAL p : digit_vector(NDIGITS+MDIGITS-1 downto 0); BEGIN uut: basic_base_B_mult PORT MAP(X => x, Y => y, P => p); tb_test : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); VARIABLE iP : natural; BEGIN for i in 0 to BASE**NDIGITS-1 loop for j in 0 to BASE**MDIGITS-1 loop x <= int_2_baseB(i,NDIGITS); y <= int_2_baseB(j,MDIGITS); WAIT FOR DELAY/2; iP := baseB_2_int(P); IF ( I*J /= iP) THEN write(TX_LOC,string'("ERROR!!! X=")); write(TX_LOC, i); write(TX_LOC,string'(" Y=")); write(TX_LOC, j); write(TX_LOC,string'(" P=")); write(TX_LOC, iP); 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;