------------------------------------- -- Define Data Width -- ------------------------------------- package mypackage is constant NBITS: natural := 7; constant PBITS: natural := 11; end mypackage; --------------------------------------------------------------- -- SRT radix 2, Carry save remainder -- X and Y positives, 0.25 < X < 0.5 and Y > 0.5 -- i.e.: 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 srt_cs_r2 is port ( X: in std_logic_vector (NBITS-1 downto 0); -- .01XXXXX Y: in std_logic_vector (NBITS-1 downto 0); -- .1XXXXX Q: out std_logic_vector (PBITS-1 downto 0); R: out std_logic_vector (NBITS-1 downto 0) ); end srt_cs_r2; architecture rtl of srt_cs_r2 is component srt_cs_step port ( b: in std_logic_vector (NBITS-1 downto 0); c, s: in std_logic_vector (NBITS+1 downto 0); q_pos, q_neg: out std_logic; next_c, next_s: out std_logic_vector (NBITS+1 downto 0) ); end component; type step_outputs is array (0 to PBITS) of std_logic_vector (NBITS+1 downto 0); signal c, s, c_o, s_o: step_outputs; signal q_pos, q_neg: std_logic_vector (PBITS downto 0); signal qq: std_logic_vector (PBITS-1 downto 0); signal rr: std_logic_vector (NBITS+1 downto 0); begin s(0) <= '0' & X &'0' ; c(0) <= (others => '0'); gen_p: for i in 0 to PBITS-1 generate cell: srt_cs_step port map (b => Y, c=> c(i), s => s(i), q_pos => q_pos(PBITS-i-1), q_neg => q_neg(PBITS-i-1), next_c => c_o(i), next_s => s_o(i) ); c(i+1) <= c_o(i)(NBITS downto 0) & '0'; s(i+1) <= s_o(i)(NBITS downto 0) & '0'; end generate; rr <= c_o(PBITS-1) + s_o(PBITS-1); qq <= q_pos(PBITS-1 downto 0) - q_neg(PBITS-1 downto 0); adjust: process (rr, qq, Y) begin if (rr(NBITS) = '1') then --if remainder negative r <= rr(NBITS-1 downto 0) + Y; q <= qq - 1; else r <= rr(NBITS-1 downto 0); q <= qq; end if; end process; end rtl; --------------------------------------------------------------- -- SRT radix 2, Carry save remainder -- Division 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_cs_step is port ( b: in std_logic_vector (NBITS-1 downto 0); s, c: in std_logic_vector (NBITS+1 downto 0); q_pos, q_neg: out std_logic; next_s, next_c: out std_logic_vector (NBITS+1 downto 0) ); end srt_cs_step; architecture behavioural of srt_cs_step is signal t: std_logic_vector (2 downto 0); signal long_b, op_b, sum: std_logic_vector (NBITS+1 downto 0); signal carry: std_logic_vector (NBITS+2 downto 0); begin t <= s(NBITS+1 downto NBITS-1) + c(NBITS+1 downto NBITS-1); long_b <= "00"& b; process (t, long_b) begin case t is when "000" | "001" | "010" => q_pos <= '1'; q_neg <= '0'; op_b <= not(long_b) + 1; when "011" | "100" | "101" | "110" => q_pos <= '0'; q_neg <= '1'; op_b <= long_b; when others => -- "111" q_pos <= '0'; q_neg <= '0'; op_b <= (others => '0'); end case; end process; carry (0) <= '0'; adder: for i in 0 to NBITS+1 generate sum(i) <= op_b(i) xor c(i) xor s(i); carry(i+1) <= (op_b(i) and c(i)) or (op_b(i) and s(i)) or (s(i) and c(i)); end generate; next_s <= sum; next_c(NBITS+1 downto 0) <= carry (NBITS+1 downto 0); end behavioural; ----------------------------------------------------------------------------- -- VHDL Test Bench SRT Radix-2 carry save remiander representation -- -- 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_nr_unsigned IS END testbench_nr_unsigned; ARCHITECTURE behavior OF testbench_nr_unsigned IS FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; COMPONENT srt_cs_r2 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; CONSTANT DELAY: time := 100 ns; CONSTANT print_ok: boolean := false; SIGNAL A: STD_LOGIC_VECTOR (NBITS-1 downto 0); SIGNAL B: 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: srt_cs_r2 PORT MAP( X => A, Y => B, Q => Q, R => R ); 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)-1 loop for J in 2**(NBITS-1) to 2**NBITS-1 loop A <= CONV_STD_LOGIC_VECTOR (I, NBITS); B <= CONV_STD_LOGIC_VECTOR (J, NBITS); WAIT FOR DELAY/2; iQ := CONV_INTEGER(Q); iR := CONV_INTEGER(R); IF (I*2**(PBITS) /= (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/2; end loop; end loop; ASSERT (FALSE) REPORT "Simulation successful (not a failure). No problems detected. " SEVERITY FAILURE; END PROCESS; END;