------------------------------------- --Define el ancho de la ruta de datos -- ------------------------------------- package mypackage is constant NDIGITS :INTEGER := 4; constant PDIGITS :INTEGER := 5; constant BASE :INTEGER := 10; 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 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; --------------------------------------------------------------- -- NON-RESTORING base-B Divisor -- --------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use work.mypackage.all; entity div_nr_baseB is port ( A: in digit_vector(NDIGITS-1 downto 0); B: in digit_vector(NDIGITS-1 downto 0); Q: out digit_vector(PDIGITS-1 downto 0); R: out digit_vector(NDIGITS-1 downto 0) ); end div_nr_baseB; architecture div_arch of div_nr_baseB is component nr_baseB_step port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS-1 downto 0); q1, q0: out digit; r: out digit_vector(NDIGITS downto 0) ); end component; component base_B_adder port ( a: in digit_vector(PDIGITS-1 downto 0); b: in digit_vector(PDIGITS-1 downto 0); s: out digit_vector(PDIGITS-1 downto 0) ); end component; component rem_adjust port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS-1 downto 0); adjust: out digit; r: out digit_vector(NDIGITS-1 downto 0) ); end component; type conections is array (0 to PDIGITS) of digit_vector(NDIGITS downto 0); Signal wires: conections; signal Q_1, Q_0: digit_vector(PDIGITS downto 0); begin wires(0) <= 0 & A; divisor: for i in 0 to PDIGITS-1 generate rest_step: nr_baseB_step port map (a => wires(i), b => B, q1 => Q_1(PDIGITS-i), q0 => Q_0(PDIGITS-i-1), r => wires(i+1)); end generate; correction: rem_adjust port map (a => wires(PDIGITS), b => B, adjust => Q_1(0), r => R ); final_adder: base_B_adder port map (a => Q_1(PDIGITS-1 downto 0), b => Q_0(PDIGITS-1 downto 0), s => Q); end div_arch; --------------------------------------------------------------- -- NON-RESTORING base-B Division step -- --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity nr_baseB_step is port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS-1 downto 0); q1, q0: out digit; r: out digit_vector(NDIGITS downto 0) ); end nr_baseB_step; architecture behavioural of nr_baseB_step is component look_up_table port ( rt: in digit_vector(4 downto 0); yt: in digit_vector(2 downto 0); qt1: out digit; qt0: out digit ); end component; component base_b_2_x_n_mult port ( a: in digit_vector(1 downto 0); b: in digit_vector(NDIGITS-1 downto 0); m: out digit_vector(NDIGITS downto 0) ); end component; component base_b_subt port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS downto 0); s: out digit_vector(NDIGITS downto 0) ); end component; signal rt: digit_vector(4 downto 0); signal yt: digit_vector(2 downto 0); signal q: digit_vector(1 downto 0); signal qt1,qt0: digit; signal a_x_BASE, q_x_b, remainder: digit_vector(NDIGITS downto 0); begin rt <= a(NDIGITS downto NDIGITS-4); yt <= b(NDIGITS-1 downto NDIGITS-3); a_x_BASE(NDIGITS downto 1) <= a(NDIGITS-1 downto 0); a_x_BASE(0) <= 0; q <= qt1 & qt0; q1 <= qt1; q0 <= qt0; LookUpTable: look_up_table port map (rt => rt, yt => yt, qt1 => qt1, qt0 => qt0); mult: base_b_2_x_n_mult port map (a => q, b => B, m => q_x_b); subtrator: base_b_subt port map (a => a_x_BASE, b => q_x_b, s => remainder); r <= remainder; end behavioural; --------------------------------------------------------------- -- NON-RESTORING base-B Division step: base B multiplier -- -- 2 by ndigits multiplier. --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity base_B_2_x_n_mult is port ( a: in digit_vector(1 downto 0); b: in digit_vector(NDIGITS-1 downto 0); m: out digit_vector(NDIGITS downto 0) ); end base_B_2_x_n_mult; architecture behavior of base_B_2_x_n_mult is begin process(B,A) variable carry: digit_vector(NDIGITS+1 downto 0); variable m_0: digit_vector(NDIGITS downto 0); begin carry(0) := 0; for i in 0 to NDIGITS-1 loop m_0(i) := (B(i) * A(0) + carry(i)) mod BASE; carry(i+1) := ( B(i) * A(0) + carry(i) ) / BASE; end loop; m_0(NDIGITS) := carry(NDIGITS); carry(0) := 0; m(0) <= m_0(0); for i in 0 to NDIGITS-1 loop m(i+1) <= (B(i) * A(1) + carry(i) + m_0(i+1)) mod BASE; carry(i+1) := ( B(i) * A(1) + carry(i) + m_0(i+1)) / BASE; end loop; end process; end behavior; --------------------------------------------------------------- -- RESTORING base-B Division step: base B subtractor -- --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity base_B_subt is port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS downto 0); s: out digit_vector(NDIGITS downto 0) ); end base_B_subt; architecture behavior of base_B_subt is begin process(b,a) variable borrow: digit_vector(NDIGITS+1 downto 0); begin borrow(0) := 0; for i in 0 to NDIGITS loop s(i) <= (A(i) - B(i) - borrow(i)) mod BASE; if (A(i) - B(i) - borrow(i)) < 0 then borrow(i+1) := 1; else borrow(i+1) := 0; end if; end loop; end process; end behavior; --------------------------------------------------------------- -- NON-RESTORING base-B Division step: Look Up Table -- --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity look_up_table is port ( rt: in digit_vector(4 downto 0); yt: in digit_vector(2 downto 0); qt1: out digit; qt0: out digit ); end look_up_table; architecture behavior of look_up_table is begin process(rt,yt) variable rt_i,yt_i,qt_i: integer ; begin qt1 <= 0; qt0 <= 0; rt_i := (((rt(4)*BASE + rt(3))*BASE + rt(2))*BASE + rt(1))*BASE+ rt(0); yt_i := yt(2)*BASE*BASE + yt(1)*BASE + yt(0) + 1; if yt_i > 0 then qt_i := rt_i / yt_i; if qt_i < 2*BASE then qt1 <= qt_i / BASE; qt0 <= qt_i rem BASE; end if; end if; end process; end behavior; --------------------------------------------------------------- -- RESTORING base-B Division step: base B adder -- --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity base_B_adder is port ( a: in digit_vector(PDIGITS-1 downto 0); b: in digit_vector(PDIGITS-1 downto 0); s: out digit_vector(PDIGITS-1 downto 0) ); end base_B_adder; architecture behavior of base_B_adder is begin process(B,A) variable carry: digit_vector(PDIGITS downto 0); begin carry(0) := 0; for i in 0 to PDIGITS-1 loop s(i) <= (B(i) + A(i) + carry(i)) mod BASE; carry(i+1) := (B(i) + A(i) + carry(i)) / BASE; end loop; end process; end behavior; --------------------------------------------------------------- -- RESTORING base-B Division step: Remainder correction step -- --------------------------------------------------------------- library IEEE; use work.mypackage.all; entity rem_adjust is port ( a: in digit_vector(NDIGITS downto 0); b: in digit_vector(NDIGITS-1 downto 0); adjust: out digit; r: out digit_vector(NDIGITS-1 downto 0) ); end rem_adjust; architecture behavior of rem_adjust is signal s: digit_vector(NDIGITS-1 downto 0); signal last_borrow: digit; begin substract: process(b,a) variable borrow: digit_vector(NDIGITS+1 downto 0); begin borrow(0) := 0; for i in 0 to NDIGITS-1 loop s(i) <= (A(i) - B(i) - borrow(i)) mod BASE; if (A(i) - B(i) - borrow(i)) < 0 then borrow(i+1) := 1; else borrow(i+1) := 0; end if; end loop; if (A(NDIGITS) - borrow(NDIGITS)) < 0 then last_borrow <= 1; else last_borrow <= 0; end if; end process; mux: process(b,a,s,last_borrow ) begin if (last_borrow = 0) then r <= s; adjust <= 1; else r <= a(NDIGITS-1 downto 0); adjust <= 0; end if; end process; end behavior; -------------------------------------------------------- -- VHDL Test Bench: NON-RESTORING base-B Divisor (div_nr_baseB) -- -------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; use work.mypackage.all; LIBRARY ieee; USE IEEE.STD_LOGIC_TEXTIO.ALL; USE STD.TEXTIO.ALL; ENTITY test_div_nonrest_baseB_exhaustive IS END test_div_nonrest_baseB_exhaustive; ARCHITECTURE behavior OF test_div_nonrest_baseB_exhaustive IS COMPONENT div_nr_baseB PORT( A : IN digit_vector(NDIGITS-1 downto 0); B : IN digit_vector(NDIGITS-1 downto 0); Q : OUT digit_vector(PDIGITS-1 downto 0); R : OUT digit_vector(NDIGITS-1 downto 0) ); END COMPONENT; SIGNAL A : digit_vector(NDIGITS-1 downto 0); SIGNAL B : digit_vector(NDIGITS-1 downto 0); SIGNAL Q : digit_vector(PDIGITS-1 downto 0); SIGNAL R : digit_vector(NDIGITS-1 downto 0); constant AMOUNTS_TRIALS : integer := 100; constant DELAY : time := 100 ns; BEGIN uut: div_nr_baseB PORT MAP( A => A, B => B, Q => Q, R => R ); tb_gen : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); VARIABLE t1,te : String(1 to 4096); VARIABLE iQ,iR : integer; BEGIN for iA in BASE**(NDIGITS-1) to BASE**NDIGITS-1 loop for iB in iA+1 to BASE**NDIGITS-1 loop A <= int_2_baseB(iA,NDIGITS); B <= int_2_baseB(iB,NDIGITS); WAIT FOR DELAY; iQ := baseB_2_int(Q); iR := baseB_2_int(R); IF ((iA*(BASE**(PDIGITS))) /= (iB * iQ) + iR) or (iR >= iB )THEN write(TX_LOC,string'("ERROR!!! A=")); write(TX_LOC, iA); write(TX_LOC,string'(" B=")); write(TX_LOC, iB); write(TX_LOC,string'(" Q=")); write(TX_LOC, iQ); write(TX_LOC,string'(" R=")); write(TX_LOC, iR); TX_STR(TX_LOC.all'range) := TX_LOC.all; Deallocate(TX_LOC); ASSERT (FALSE) REPORT TX_STR SEVERITY FAILURE; 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;