我尝试使用语言std_logic_vector
实现VHDL
的除数。
在我实现它之后,我必须使用GHDL但遇到了这个错误:
vhdl:error: bound check failure at divisor.vhdl
这与此相对应:
else ....
nb_reg <= (2*nb);
我的代码是:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port (
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end div;
architecture rtl of div is
-- Build a 2-D array type for the RAM
subtype word_t is unsigned((DATA_WIDTH-1) downto 0);
type memory_t is array(natural range <>) of word_t;
-- Declare the RAM signal.
signal ram, div : memory_t((2**ADDR_WIDTH)-1 downto 0);
-- Declare the n and max_reg signal.
signal n,m : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal max_reg : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb_reg : unsigned(((4*DATA_WIDTH)-3) downto 0);
-- Build div_reg, ram_reg
type memory_reg is array(natural range <>) of unsigned(((2*DATA_WIDTH)-1) downto 0);
signal ram_reg: memory_reg((2**ADDR_WIDTH)-1 downto 0);
begin
process(clk,reset)
begin
if (reset = '1') then
ram(waddr) <= X"00";
div(waddr) <= X"00";
max_reg <= X"0000";
ram_reg(waddr) <= X"0000";
n <= X"0000";
nb <= X"0000";
--nb_reg(((4*DATA_WIDTH)-3) downto 0) <= "0";
m <= X"0000";
elsif(rising_edge(clk)) then
ram(waddr) <= unsigned(data);
max_reg((DATA_WIDTH -1) downto 0) <= unsigned(max);
ram_reg(waddr)((DATA_WIDTH-1) downto 0) <= ram(waddr)((DATA_WIDTH-1) downto 0);
nb <= (nb+1);
if (ram(waddr) = max_reg)then
div(waddr) <= div(waddr)+1;
elsif (ram(waddr) > max_reg)then
while ((div(waddr)*(ram(waddr)) > max_reg) or (m <(DATA_WIDTH -1))) loop
div(waddr) <= (div(waddr))+1;
max_reg <= (max_reg) - (ram_reg(waddr));
m <= m+1;
end loop;
m <= (m-1);
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (nb*2);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
else
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (2*nb);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
end if;
else null;
end if;
end process;
q <= std_logic_vector(div(waddr));
end rtl;
测试台:
-- descrizione del Test_bench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity div_tb is
end div_tb;
architecture behaviour of div_tb is
--dichiarazione dei COMPONENT ovvero la Unit Under Test
component div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port
(
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
-- Clock period definitions
constant clk_period : time := 1 us;
constant DATA_WIDTH : natural := 8;
constant ADDR_WIDTH : natural := 3;
signal CLK_tb: std_logic := '0';
signal RESET_tb: std_logic := '1';
signal raddr_tb, waddr_tb : natural range 0 to 2**ADDR_WIDTH - 1;
signal data_tb, q_tb, max_tb : std_logic_vector((DATA_WIDTH -1) downto 0);
signal I : integer := 0; -- variabile per il conteggio dei clock
begin
clk_process: process --processo di generazione del CLK
begin
CLK_tb <= '0';
wait for clk_period/2;
CLK_tb <= '1';
wait for clk_period/2;
I<=I+1;
if I=200 then wait; -- durata della simulazione: 30 colpi di CLK
else null;
end if;
end process;
-- istanziazione della Unit Under Test
UUT: div generic map (ADDR_WIDTH => 3, DATA_WIDTH => 8)
port map (clk=>clk_tb, reset=>RESET_tb, raddr => raddr_tb, waddr => waddr_tb , data => data_tb, q => q_tb, max => max_tb);
stimoli: process
begin
RESET_tb <= '1';
wait for clk_period*3;
RESET_tb <= '0';
wait;
end process;
we: process
begin
max_tb <= "11100110";
wait;
end process;
Data : process
begin
data_tb <= "00000000"; raddr_tb <= 0; waddr_tb <= 0; wait for clk_period*3;
data_tb <= "01010110"; raddr_tb <= 1; waddr_tb <= 1; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 2; waddr_tb <= 2; wait for clk_period*8;
data_tb <= "11001110"; raddr_tb <= 3; waddr_tb <= 3; wait for clk_period*8;
data_tb <= "01000111"; raddr_tb <= 4; waddr_tb <= 4; wait for clk_period*8;
data_tb <= "11100110"; raddr_tb <= 5; waddr_tb <= 5; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 6; waddr_tb <= 6; wait for clk_period*8;
data_tb <= "01010110"; raddr_tb <= 7; waddr_tb <= 7; wait for clk_period*8;
wait;
end process;
end behaviour;
我使用GHDL的2007
版本,我无法更新,我的老师要我使用这个版本。
有人可以帮我这个代码吗?
答案 0 :(得分:0)
Booking.payment_authorized.or(Booking.payment_captured)
包中的乘法运算符定义为numeric_std
乘以natural
:
unsigned
如您所见,输出是 -- Id: A.18
function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0)
-- Result: Multiplies an UNSIGNED vector, R, with a nonnegative
-- INTEGER, L. L is converted to an UNSIGNED vector of
-- SIZE R'LENGTH before multiplication.
参数宽度的两倍减去1.在此行中
unsigned
您要将结果分配回nb <= std_logic_vector(2*unsigned(nb));
操作数,这显然与自身的宽度不同。
那么,您需要一个正确宽度的中间变量,还是需要左移?