------------------------------------- -- Define datapath width -- ------------------------------------- package mypackage is constant NBITS :INTEGER := 8; constant MBITS :INTEGER := 6; end mypackage; --------------------------------------------------------------- -- RESTORING Division Algorithm for natural operands -- An NBITS natural divided by an MBITS natural -- The resulting quotient is also naturals -- Quotient Q of NBITS, and remainder R of MBITS --------------------------------------------------------------- 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 div_rest_nat is port ( A: in STD_LOGIC_VECTOR (NBITS-1 downto 0); B: in STD_LOGIC_VECTOR (MBITS-1 downto 0); Q: out STD_LOGIC_VECTOR (NBITS-1 downto 0); R: out STD_LOGIC_VECTOR (MBITS-1 downto 0) ); end div_rest_nat; architecture div_arch of div_rest_nat is component restoring_cell is port ( a: in STD_LOGIC_VECTOR (MBITS downto 0); b: in STD_LOGIC_VECTOR (MBITS-1 downto 0); q: out STD_LOGIC; r: out STD_LOGIC_VECTOR (MBITS downto 0) ); end component; type conections is array (0 to NBITS-1) of STD_LOGIC_VECTOR (MBITS downto 0); Signal wires_in, wires_out: conections; Signal zeros: STD_LOGIC_VECTOR (MBITS-1 downto 0); begin zeros <= (others => '0'); wires_in(0) <= zeros & A(NBITS-1); divisor: for i in 0 to NBITS-1 generate rest_cell: restoring_cell port map (a => wires_in(i), b => B, q => Q(NBITS-I-1), r => wires_out(i)); end generate; wires_conections: for i in 0 to NBITS-2 generate wires_in(i+1) <= wires_out(i)(MBITS-1 downto 0) & A(NBITS-i-2); end generate; R <= wires_out(NBITS-1)(MBITS-1 downto 0); end div_arch; --------------------------------------------------------- -- restoring cell -- division step for restoring base-2 division algorithm --------------------------------------------------------- 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 restoring_cell is port ( a: in STD_LOGIC_VECTOR (MBITS downto 0); b: in STD_LOGIC_VECTOR (MBITS-1 downto 0); q: out STD_LOGIC; r: out STD_LOGIC_VECTOR (MBITS downto 0) ); end restoring_cell; architecture cel_arch of restoring_cell is signal subst: STD_LOGIC_VECTOR (MBITS downto 0); begin subst <= a - b; multiplexer: process (a,b,subst) begin if subst(MBITS) = '1' then r <= a; else r <= subst; end if; end process; q <= not subst(MBITS); end cel_arch; ----------------------------------------------------------------------------- -- VHDL Test Bench Restoring divisor -- -- Exhaustive Analysis -- 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 testbench IS END testbench; ARCHITECTURE behavior OF testbench IS FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; COMPONENT div_rest_nat PORT( A: in STD_LOGIC_VECTOR (NBITS-1 downto 0); B: in STD_LOGIC_VECTOR (MBITS-1 downto 0); Q: out STD_LOGIC_VECTOR (NBITS-1 downto 0); R: out STD_LOGIC_VECTOR (MBITS-1 downto 0) ); END COMPONENT; CONSTANT DELAY: time := 100 ns; CONSTANT print_ok: boolean := false; SIGNAL A: STD_LOGIC_VECTOR (NBITS-1 downto 0); SIGNAL B: STD_LOGIC_VECTOR (MBITS-1 downto 0); SIGNAL Q: STD_LOGIC_VECTOR (NBITS-1 downto 0); SIGNAL R: STD_LOGIC_VECTOR (MBITS-1 downto 0); BEGIN uut: div_rest_nat PORT MAP( A => A, B => B, Q => Q, R => R ); tb_gen : PROCESS BEGIN for I in 0 to 2**NBITS-1 loop for J in 1 to 2**MBITS-1 loop A <= CONV_STD_LOGIC_VECTOR (I, NBITS); B <= CONV_STD_LOGIC_VECTOR (J, MBITS); WAIT FOR DELAY; end loop; end loop; WAIT FOR DELAY; END PROCESS; tb_test : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); Variable iQ, iR: natural; BEGIN WAIT FOR 10 ns; for I in 0 to 2**NBITS -1 loop for J in 1 to 2**MBITS -1 loop iQ := CONV_INTEGER(Q); iR := CONV_INTEGER(R); IF (I /= (J * iQ) + iR) THEN write(TX_LOC,string'("Error!!! -> A=")); write(TX_LOC, A); write(TX_LOC,string'(" B=")); write(TX_LOC, B); write(TX_LOC,string'(" Q=")); write(TX_LOC, Q); write(TX_LOC,string'(" R=")); write(TX_LOC, R); write(TX_LOC,string'(" (i=")); write(TX_LOC, i); write(TX_LOC,string'(" j=")); write(TX_LOC, j); write(TX_LOC,string'(" iQ=")); write(TX_LOC, iQ); write(TX_LOC,string'(" iR=")); write(TX_LOC, iR); 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; elsif (iR > J) then write(TX_LOC,string'("Error Remainder bigger than Divider !!! -> A=")); write(TX_LOC, A); write(TX_LOC,string'(" B=")); write(TX_LOC, B); write(TX_LOC,string'(" Q=")); write(TX_LOC, Q); write(TX_LOC,string'(" R=")); write(TX_LOC, R); write(TX_LOC,string'(" (i=")); write(TX_LOC, i); write(TX_LOC,string'(" j=")); write(TX_LOC, j); write(TX_LOC,string'(" iQ=")); write(TX_LOC, iQ); write(TX_LOC,string'(" iR=")); write(TX_LOC, iR); 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; elsif (print_ok) then write(TX_LOC,string'("OK -> A=")); write(TX_LOC, A); write(TX_LOC,string'(" B=")); write(TX_LOC, B); write(TX_LOC,string'(" Q=")); write(TX_LOC, Q); write(TX_LOC,string'(" R=")); write(TX_LOC, R); 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 WARNING; END IF; WAIT FOR DELAY; end loop; end loop; ASSERT (FALSE) REPORT "Simulation successful (not a failure). No problems detected. " SEVERITY FAILURE; END PROCESS; END;