我尝试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;
我使用的2007
是 GHDL 版本,我无法更新,我的老师要我使用这个版本。
有人可以帮我处理这段代码吗?