------------------------------------- --Define el ancho de la ruta de datos -- ------------------------------------- package mypackage is constant NBITS :INTEGER := 8; constant PBITS :INTEGER := 10; end mypackage; --------------------------------------------------------------- -- SRT radix-4 -- X and Y positives, 0.25 < X < 0.5 and Y > 0.5 -- ie: X(NBITS-1) = 0, X(NBITS-2) = 1, and X(NBITS-1) = 1 -- --------------------------------------------------------------- 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_SRT_r4 is port ( X: in STD_LOGIC_VECTOR (NBITS-1 downto 0); Y: in STD_LOGIC_VECTOR (NBITS-1 downto 0); Q: out STD_LOGIC_VECTOR (PBITS-1 downto 0); R: out STD_LOGIC_VECTOR (NBITS-1 downto 0) ); end div_SRT_r4; architecture mult_arch of div_SRT_r4 is component srt_r4_step port ( r: in STD_LOGIC_VECTOR (NBITS+2 downto 0); b: in STD_LOGIC_VECTOR (NBITS-1 downto 0); Q: out STD_LOGIC_VECTOR (2 downto 0); r_n: out STD_LOGIC_VECTOR (NBITS+2 downto 0) ); end component; type conections is array (0 to PBITS) of STD_LOGIC_VECTOR (NBITS+2 downto 0); Signal wires: conections; type Qmatrix is array (0 to PBITS-2) of STD_LOGIC_VECTOR (2 downto 0); Signal Q_digit: Qmatrix; Signal add,subst,the_adjust: STD_LOGIC_VECTOR (PBITS-1 downto 0); signal adjust: STD_LOGIC; begin wires(0) <= "0" & X & "00"; divisor: for I in 0 to PBITS-1 generate div_in: if I mod 2 = 0 generate in_step: srt_r4_step port map (r => wires(I), b => Y, Q => Q_digit(i), r_n => wires(I+1) ); wires(i+2) <= wires(i+1)(NBITS downto 0) & "00"; --X4 end generate; end generate; adjust <= wires(PBITS-1)(NBITS+2); correction_step: process (adjust, wires(PBITS)) begin if adjust = '0' then R <= wires(PBITS-1)(NBITS-1 downto 0); else R <= wires(PBITS-1)(NBITS-1 downto 0) + Y; end if; end process; Quotient: process(Q_digit) begin for I in 0 to PBITS-1 loop if I mod 2 = 0 then if Q_digit(I)(2) = '1' then --positive add(PBITS-I-1 downto PBITS-I-2) <= Q_digit(I)(1 downto 0); subst(PBITS-I-1 downto PBITS-I-2) <= "00"; else -- it's negative add(PBITS-I-1 downto PBITS-I-2) <= "00"; subst(PBITS-I-1 downto PBITS-I-2) <= Q_digit(I)(1 downto 0); end if; end if; end loop; end process; the_adjust(0) <= adjust; the_adjust(PBITS-1 downto 1) <= (others => '0'); Q <= add-subst-the_adjust; end mult_arch; --------------------------------------------------------------- -- SRT radix-4: basic step -- --------------------------------------------------------------- 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 srt_r4_step is port ( r: in STD_LOGIC_VECTOR (NBITS+2 downto 0); b: in STD_LOGIC_VECTOR (NBITS-1 downto 0); Q: out STD_LOGIC_VECTOR (2 downto 0); r_n: out STD_LOGIC_VECTOR (NBITS+2 downto 0) ); end srt_r4_step; architecture behavioural of srt_r4_step is component Qsel PORT( rt : in std_logic_vector(3 downto 0); d_2 : in std_logic; q : out std_logic_vector(2 downto 0) ); end component; signal mult_m: std_logic_vector(NBITS+1 downto 0); signal Q_digit: std_logic_vector(2 downto 0); begin selection: Qsel port map (rt => r(NBITS+2 downto NBITS-1), d_2 => b(NBITS-2), q => Q_digit); mult_m <= b * Q_digit(1 downto 0); suma_resta: process(mult_m,Q_digit,r) begin if Q_digit(2) = '1' then --'1' add, '0' substract r_n <= r - mult_m; else r_n <= r + mult_m; end if; end process; Q <= Q_digit; end behavioural; --------------------------------------------------------------- -- SRT radix-4: Qsel table -- --------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Qsel is Port ( rt : in std_logic_vector(3 downto 0); d_2 : in std_logic; q : out std_logic_vector(2 downto 0)); end Qsel; architecture Behavioral of Qsel is signal num: std_logic_vector(2 downto 0); begin q(2) <= not rt(3); absolute_value: Process (rt) begin if rt(3) = '1' then num <= not (rt(2 downto 0)); else num <= rt(2 downto 0); end if; end process; select_a_q: process (num, d_2) begin case num is when "000" => q(1 downto 0) <= "00"; when "001" => q(1 downto 0) <= "01"; when "010" => q(1 downto 0) <= "10"; when "011" => if d_2 = '0' then q(1 downto 0) <= "11"; else q(1 downto 0) <= "10"; end if; when "100" => q(1 downto 0) <= "11"; when "101" => q(1 downto 0) <= "11"; when "110" => q(1 downto 0) <= "11"; when "111" => q(1 downto 0) <= "11"; when others => q(1 downto 0) <= "11"; end case; end process; end Behavioral; ---------------------------------------------------------------------- -- VHDL Test Bench for SRT radix 4 divider -- -- 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 div_SRT_r4 PORT( x : IN std_logic_vector(NBITS-1 downto 0); y : IN std_logic_vector(NBITS-1 downto 0); q : OUT std_logic_vector(PBITS-1 downto 0); r : OUT std_logic_vector(NBITS-1 downto 0) ); END COMPONENT; SIGNAL x : std_logic_vector(NBITS-1 downto 0); SIGNAL y : std_logic_vector(NBITS-1 downto 0); SIGNAL q : std_logic_vector(PBITS-1 downto 0); SIGNAL r : std_logic_vector(NBITS-1 downto 0); BEGIN uut: div_SRT_r4 PORT MAP(x => x, y => y, q => q, r => r); tb_test : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); BEGIN for I in 2**(NBITS-2) to (2**(NBITS-1))-1 loop for J in 2**(NBITS-1) to 2**NBITS-1 loop x <= CONV_STD_LOGIC_VECTOR (I, NBITS); y <= CONV_STD_LOGIC_VECTOR (J, NBITS); WAIT FOR DELAY/2; IF ((I*(2**(PBITS))) /= (J * CONV_INTEGER(Q)) + CONV_INTEGER(R)) THEN write(TX_LOC,string'("ERROR!!! X=")); write(TX_LOC, X); write(TX_LOC,string'(" Y=")); write(TX_LOC, Y); 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 FAILURE; ELSIF (J < CONV_INTEGER(R)) THEN write(TX_LOC,string'("--> Remiander grater than Y =")); write(TX_LOC, 0.0); write(TX_LOC,string'("ns X=")); write(TX_LOC, X); write(TX_LOC,string'(" Y=")); write(TX_LOC, Y); 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 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;