P
Paul Boven
Guest
Hi everyone,
The very first piece of VHDL I've written is a divisor (long division),
the final part of a reciprocal counter I've built (in a Spartan-3).
Because of the counter's high resolution, the number to be divided is 54
bits long. Instead of assigning 54 bit long vectors to my signals, I'd
rather use conv_std_logic_vector just to improve the readability of the
code. But the Xilinx tools I'm using won't go beyond 32 bits integers.
Is there a 64 bit or other equivalent of conv_std_logic_vector I could use?
Below is the long divisor I've coded, any hints on improving the
functionality or coding style would be welcomed.
Regards, Paul Boven.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity reciprocal is
port (clk, start: in std_logic;
done: out std_logic;
bits: out std_logic_vector(31 downto 0);
b: in std_logic_vector(27 downto 0));
end reciprocal;
architecture Behavioral of reciprocal is
signal bitsreg : std_logic_vector(31 downto 0);
signal counter: std_logic_vector(4 downto 0):= "00000";
signal aw,bw: std_logic_vector(53 downto 0);
begin
process (clk)
begin
if (clk'event and clk='1') then
if (counter = 0) then
done <= '0';
if (start = '1') then
bitsreg <= conv_std_logic_vector(0,32);
counter <= "00001";
-- aw = 800000000 (MHz, reference)
-- * 2^21 (prescaler)
-- * 10 (0.1Hz resolution)
aw <= "111011100110101100101000000000000000000000000000000000";
-- aw <= conv_std_logic_vector(16777216000000000,54);
-- aw <= std_logic_vector((800000000 * 2**21 * 10), 54);
bw <= b & conv_std_logic_vector(0,54-32);
end if; -- start = 1
elsif (counter = 28) then -- do 27 divisions
bits <= bitsreg;
done <= '1';
counter <= "00000";
else -- 0 < counter < 28
if (aw >= bw) then
bitsreg <= bitsreg (30 downto 0) & '1';
aw <= aw - bw;
else -- aw < bw
bitsreg <= bitsreg (30 downto 0) & '0';
end if;
counter <= counter + 1;
bw <= '0'& bw(53 downto 1);
end if; -- counter
end if; -- clk
end process;
end Behavioral;
The very first piece of VHDL I've written is a divisor (long division),
the final part of a reciprocal counter I've built (in a Spartan-3).
Because of the counter's high resolution, the number to be divided is 54
bits long. Instead of assigning 54 bit long vectors to my signals, I'd
rather use conv_std_logic_vector just to improve the readability of the
code. But the Xilinx tools I'm using won't go beyond 32 bits integers.
Is there a 64 bit or other equivalent of conv_std_logic_vector I could use?
Below is the long divisor I've coded, any hints on improving the
functionality or coding style would be welcomed.
Regards, Paul Boven.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity reciprocal is
port (clk, start: in std_logic;
done: out std_logic;
bits: out std_logic_vector(31 downto 0);
b: in std_logic_vector(27 downto 0));
end reciprocal;
architecture Behavioral of reciprocal is
signal bitsreg : std_logic_vector(31 downto 0);
signal counter: std_logic_vector(4 downto 0):= "00000";
signal aw,bw: std_logic_vector(53 downto 0);
begin
process (clk)
begin
if (clk'event and clk='1') then
if (counter = 0) then
done <= '0';
if (start = '1') then
bitsreg <= conv_std_logic_vector(0,32);
counter <= "00001";
-- aw = 800000000 (MHz, reference)
-- * 2^21 (prescaler)
-- * 10 (0.1Hz resolution)
aw <= "111011100110101100101000000000000000000000000000000000";
-- aw <= conv_std_logic_vector(16777216000000000,54);
-- aw <= std_logic_vector((800000000 * 2**21 * 10), 54);
bw <= b & conv_std_logic_vector(0,54-32);
end if; -- start = 1
elsif (counter = 28) then -- do 27 divisions
bits <= bitsreg;
done <= '1';
counter <= "00000";
else -- 0 < counter < 28
if (aw >= bw) then
bitsreg <= bitsreg (30 downto 0) & '1';
aw <= aw - bw;
else -- aw < bw
bitsreg <= bitsreg (30 downto 0) & '0';
end if;
counter <= counter + 1;
bw <= '0'& bw(53 downto 1);
end if; -- counter
end if; -- clk
end process;
end Behavioral;