Hello every body
I want code for division in VHDL
Hello every body
I want code for division in VHDL
Hi,
Please elaborate !
Hi,
It's a pipeline divider.
Just to elaborate
You can also edit the specifications of pipline divider by going to CORE GENERATOR
(a tool from Xilinx within project navigator)
And then go to MATH FUNCTION and then DIVIDERS
From there u can change the width of input output ports. and the output type (fractional or remainder)
Hi,
If you need divide by two it is simple.
signal divby2:std_logic;
if (clk'event and clk = '1' ) then
divby2 <= divby2;
end if;
To get div by 4 use divby2 as clock and take one more signal and continue. If you want more details post your question with details.
Regards,
N.Muralidhara
--Hi
--a division 32 by 32 in 32 cycles
--scuse me for french inside....
--best regards
-- Division.vhd
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 library IEEE; use IEEE.Std_Logic_1164.all; use IEEE.Std_Logic_arith.all; use IEEE.Std_Logic_unsigned.all; Entity Division Is port( Clock : in std_logic; Reset : in std_logic; Load : in std_logic; Numerateur : in std_logic_vector(31 downto 0); Denominateur : in std_logic_vector(31 downto 0); Ready : out std_logic; Quotient : out std_logic_vector(31 downto 0); Reste : out std_logic_vector(31 downto 0) ); end; architecture Division_RTL of Division is constant ALL_ZERO : std_Logic_vector(31 downto 0) := "00000000000000000000000000000000"; signal ni : std_logic_vector(63 downto 0); signal sub : std_logic_vector(63 downto 0); signal n : std_logic_vector(63 downto 0); signal i : std_logic_vector(63 downto 0); signal d : std_logic_vector(63 downto 0); signal d_int : std_logic_vector(31 downto 0); signal counter : std_logic_vector(5 downto 0); -- attribute syn_keep : boolean; -- attribute syn_keep of d_int, N : signal is true; signal ReadTempo : Std_Logic; begin Ready <= ReadTempo; NI(63 downto 0) <= ALL_ZERO & Numerateur; D(30 downto 0) <= "0000000000000000000000000000000"; D(62 downto 31) <= d_int; D(63) <= '0'; Quotient <=n(31 downto 0); Reste <=n(63 downto 32); Process(Reset, ReadTempo, n ,d ) Begin If Reset = '1' Then sub <= (Others=>'0'); ElsIf ReadTempo = '0' Then sub<= n - d; Else sub <= (Others=>'0'); End If; End Process; Process(clock, reset, ReadTempo) begin If Reset = '1' Then n(63 downto 0) <= (Others=>'0'); D_Int(31 downto 0) <= (others=>'0'); ElsIf Rising_Edge(Clock) Then If load='1' Then n(63 downto 0) <= NI(63 downto 0); D_int(31 downto 0) <= Denominateur(31 downto 0); Else If ReadTempo ='0' Then n(63 downto 0) <= I(63 downto 0); End If; End If; End If; End Process; Process(Reset, Sub, n, ReadTempo) Begin If Reset = '1' Then I <= (others=>'0'); ElsIf ReadTempo ='0' Then If Sub(47)='1' Then I(0) <='0'; I(63 Downto 1) <= N(62 Downto 0); Else I(0) <='1'; I(63 Downto 1) <= Sub(62 Downto 0); End If; Else I <= (others=>'0'); End If; End process; Process(clock,reset) Begin If Reset = '1' Then counter <="111111"; ReadTempo <= '0'; ElsIf Rising_Edge(Clock) Then If Load = '1' Then Counter <= (Others=>'0'); ReadTempo <= '0'; Else If counter="011111" Then counter <="111111"; ReadTempo <= '1'; Elsif counter="011110" Then counter <=counter+'1'; ReadTempo <= '0'; Elsif counter="111111" Then ReadTempo <='1'; Else counter <=counter+'1'; ReadTempo <='0'; End if; End If; End If; End Process; End;
Last edited by alexan_e; 18-08-12 at 22:47. Reason: added SYNTAX tags
you can test , this code :
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all; entity division is generic(SIZE: INTEGER := 8); port(reset: in STD_LOGIC; en: in STD_LOGIC; clk: in STD_LOGIC; num: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); den: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); res: out STD_LOGIC_VECTOR((SIZE - 1) downto 0); rm: out STD_LOGIC_VECTOR((SIZE - 1) downto 0) ); end division; architecture behav of division is signal buf: STD_LOGIC_VECTOR((2 * SIZE - 1) downto 0); signal dbuf: STD_LOGIC_VECTOR((SIZE - 1) downto 0); signal sm: INTEGER range 0 to SIZE; alias buf1 is buf((2 * SIZE - 1) downto SIZE); alias buf2 is buf((SIZE - 1) downto 0); begin p_001: process(reset, en, clk) begin if reset = '1' then res <= (others => '0'); rm <= (others => '0'); sm <= 0; elsif rising_edge(clk) then if en = '1' then case sm is when 0 => buf1 <= (others => '0'); buf2 <= num; dbuf <= den; res <= buf2; rm <= buf1; sm <= sm + 1; when others => if buf((2 * SIZE - 2) downto (SIZE - 1)) >= dbuf then buf1 <= '0' & (buf((2 * SIZE - 3) downto (SIZE - 1)) - dbuf((SIZE - 2) downto 0)); buf2 <= buf2((SIZE - 2) downto 0) & '1'; else buf <= buf((2 * SIZE - 2) downto 0) & '0'; end if; if sm /= SIZE then sm <= sm + 1; else sm <= 0; end if; end case; end if; end if; end process; end behav;
Last edited by alexan_e; 18-08-12 at 22:48. Reason: added SYNTAX tags
use counter
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; entity div_binary is Port ( ina : in std_logic_vector (15 downto 0);-- range 0 to 99; inb: in std_logic_vector (15 downto 0);-- range 1 to 9; quot: out std_logic_vector (15 downto 0);-- range 0 to 99; rest : out std_logic_vector (15 downto 0));-- range 0 to 99 ); end div_binary; architecture Behavioral of div_binary is signal a,b: integer range 0 to 65535; begin a <= CONV_INTEGER(ina); b <= CONV_INTEGER(inb); process (a,b) variable temp1,temp2: integer range 0 to 65535; variable y : std_logic_vector (15 downto 0); begin temp1:=a; temp2:=b; for i in 15 downto 0 loop if (temp1>temp2 * 2**i) then y(i):= '1'; temp1:= temp1- temp2 * 2**i; else y(i):= '0'; end if; end loop; rest <= CONV_STD_LOGIC_VECTOR (temp1 ,16); quot<= y; --quot<= conv_integer (y); end process; end Behavioral;
Last edited by alexan_e; 18-08-12 at 22:48. Reason: added SYNTAX tags
HI.
abhi_459, regarding your code for division.
I'm just curious. I'm trying to modify it a bit to accommodate a 17 bit divisor and dividend but errors keep popping up whenever I simulate it on Modelsim. I changed all the 15s to 16s, the 65535 to 131071, and the one 16 to a 17 (where the remainder conversion is). Any thoughts?
Hi
please tell me which algorithm is used for this code
If you want to divide with an odd number then you could use the following way, this is an example to divide by a factor of 5 but it can be used for any number (7,9,11,13....)
This is the simulation resultCode:-- Divide clock by 5 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity clk_div5 is port ( clk :in std_logic; clk_out :out std_logic:='0'); end clk_div5; architecture Structural of clk_div5 is signal set_clk_out, reset_clk_out: std_logic:='0'; signal counter :std_logic_vector(2 downto 0):="000"; begin process (clk) begin if (clk'event and clk='1') then -- rising edge of clock if (counter(2)='1') then -- check for counter=4 (100 binary, but we check only bit2) counter<="000"; -- reset counter value set_clk_out <= not reset_clk_out; -- set clk_out to 1 else counter<=counter+1; end if; end if; end process; process (clk) begin if (clk'event and clk='0') then -- falling edge of clock if (counter(1)='1') then -- check for counter=2 (10 binary) and since we are in a falling edge this is actually 2,5 reset_clk_out <= set_clk_out; -- set clk_out to 0 end if; end if; end process; clk_out <= set_clk_out xor reset_clk_out; end Structural;
http://images.elektroda.net/98_1290037522.gif
The attachment includes the code , test-bench and simulation result
Alex
Anyone have a VHDL code for a programmable divider which can change the dividing frequency by a integer number from outside (Let's say DIP switches will give the dividing frequency)
what is "dividing frequency"?
I suspect he means a frequency divider. In which case you use either the DCM/PLL on the fpga, and then configure that. OR you implement a prescaler (counter), and use that to divide. The counter approach should be particularly easy to write yourself...
Hello,
Division is multiplication and is sometimes possible to replace by multiplication. You just have to find a way to comfortably get the inverse of the B (say C) in the divisions A/B and then perform a A*C. But this is not necessarily always obvious.
A different solution is to check the existing division algorithms. There is a long history in the theory of binary dividers and I most like the Booth algorithm for its theoretical insight. Go take a look at this algorithm -- you shall find it useful. I found it here: http://people.ee.duke.edu/~sorin/pri.../3.3-arith.pdf
but you can google for diferent presentations.
This is an inherently parallel algorithm -- so it is parallel, most-probably low frecquency and expensive in resources. There are bit-serial variants byt you seem to need something of the first kind.
Have good luck with your task/
Last edited by alexan_e; 19-08-12 at 13:35. Reason: removed signature link