vhdl-ram模块及寄存器的使用
好的,VHDL中的另一个问题。下面是我的代码。假设我希望我的输入存储在ram中。假设我想加上两个。(不要强调它,以后会被替换)。这是我的代码:vhdl-ram模块及寄存器的使用,vhdl,Vhdl,好的,VHDL中的另一个问题。下面是我的代码。假设我希望我的输入存储在ram中。假设我想加上两个。(不要强调它,以后会被替换)。这是我的代码: library IEEE; use IEEE.STD_LOGIC_1164.all; USE ieee.numeric_std.ALL; use work.my_package.all; entity landmark_1 is generic (data_length :integer := 8; address
library IEEE;
use IEEE.STD_LOGIC_1164.all;
USE ieee.numeric_std.ALL;
use work.my_package.all;
entity landmark_1 is
generic
(data_length :integer := 8;
address_length:integer:=3 );
port ( clk:in std_logic;
vin:in std_logic;
rst:in std_logic;
flag: in std_logic;
din: in signed(data_length -1 downto 0);
done: out std_logic
);
end landmark_1;
architecture TB_ARCHITECTURE of landmark_1 is
component ram IS
generic
(
ADDRESS_WIDTH : integer := 4;
DATA_WIDTH : integer := 8
);
port
(
clock : IN std_logic;
data : IN signed(DATA_WIDTH - 1 DOWNTO 0);
write_address : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0);
read_address : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0);
we : IN std_logic;
q : OUT signed(DATA_WIDTH - 1 DOWNTO 0)
);
end component;
signal inp1,inp2: matrix1_t(0 to address_length);
signal out_temp: signed(data_length-1 downto 0);
signal k:unsigned(address_length-1 downto 0);
signal i: integer range 0 to 100:=0;
begin
read1:ram generic map( ADDRESS_WIDTH=>address_length, DATA_WIDTH=>data_length) port map (clk,din,k,k,vin,out_temp);
inp1(i)<=out_temp;
process (clk)
begin
if (clk'event and clk='1') then
if (flag='1') then out_temp<=inp1(0)+inp1(1);
end if;
end if;
end process ;
end TB_ARCHITECTURE;
3.谁能告诉我为什么q(输出)在一个时钟后被估计
编辑:总而言之,有人告诉我应该使用ram,这是我的实现。问题是我通过改变我的
inp1(I)得到了什么,我假设你试图用信号inp1
表示一个RAM。但是,在RAM
实体中,表示RAM的信号是RAM\u块
您以一种奇怪的方式使用实体,因为您将信号k
连接为读写地址。这有两个问题。首先,k
在您的设计中似乎没有被驱动到任何地方。其次,您可能不希望这两个地址相同
我假设您想将一些值写入RAM,同时读取两个值并将它们相加。我建议您使用设置写入地址的进程和设置读取地址的进程。您还需要至少一个具有RAM输出宽度的寄存器。从RAM读取的第一个值存储在该寄存器中。然后将该寄存器中的值和从RAM读取的第二个值相加,并将结果存储在另一个寄存器中。我假设您试图用信号inp1
表示RAM。但是,在RAM
实体中,表示RAM的信号是RAM\u块
您以一种奇怪的方式使用实体,因为您将信号k
连接为读写地址。这有两个问题。首先,k
在您的设计中似乎没有被驱动到任何地方。其次,您可能不希望这两个地址相同
我假设您想将一些值写入RAM,同时读取两个值并将它们相加。我建议您使用设置写入地址的进程和设置读取地址的进程。您还需要至少一个具有RAM输出宽度的寄存器。从RAM读取的第一个值存储在该寄存器中。然后,将该寄存器中的值和从RAM读取的第二个值相加,并将结果存储在另一个寄存器中。您没有将i
设置为0
以外的任何值,因此您将只分配给inp1(0)
假设RAM用于存储许多值,并且您需要在每个时钟周期读取其中两个值以进行加法,那么您需要两个RAM块(或一个单双端口块),然后将这两个地址放入这些RAM块中。下一个周期,您想要的两个值将出现在数据输出上,您可以对它们求和
您观察到的时钟周期延迟属于同步RAM的性质(这是大多数FPGA的“大存储”功能)-有些可以创建更小的异步RAM,其中数据在读取地址更改后出现短暂延迟,与时钟完全异步。您没有将i
设置为0
以外的任何对象,因此您将只分配给inp1(0)
假设RAM用于存储许多值,并且您需要在每个时钟周期读取其中两个值以进行加法,那么您需要两个RAM块(或一个单双端口块),然后将这两个地址放入这些RAM块中。下一个周期,您想要的两个值将出现在数据输出上,您可以对它们求和
您观察到的时钟周期延迟属于同步RAM的性质(这是大多数FPGA的“大存储”功能)-一些FPGA可以创建较小的异步RAM,其中数据在读取地址更改后出现短暂延迟,与时钟完全异步
为什么要使用该ram而不仅仅是inp(i)
为什么要使用那个ram,而不仅仅是把inp(i)做好是的。我被告知应该使用ram,这是我的实现。问题是我通过改变inp1(I)获得了什么,但实现了什么?您能否显示编辑的矩阵类型的定义。想象一下,我以前的代码是这样的。进程(clk)inp(i)假设ram_块阵列的深度为2。最初,数组的内容是未定义的。如果要将值写入RAM,可将din
设置为要存储的值,将写入地址设置为0或1(取决于要存储值的位置),并将vin
设置为1,持续一个周期。该值将保留在ram内部ram_块
数组中,直到被覆盖。您可以通过将读取地址设置为0或1(与您将值写入的地址相同)来检索它。然后,该值将在下一个周期的输出中。是的,在您更改读取地址后,输出将在该周期中更改。一次只能有一个存储在RAM中的值出现在输出中。我被告知应该使用ram,这是我的实现。问题是我通过改变inp1(I)获得了什么,但实现了什么?您能否显示编辑的矩阵类型的定义。想象一下,我以前的代码是这样的。进程(clk)inp(i)假设ram_块阵列的深度为2。最初,数组的内容是未定义的。如果要将值写入RAM,可将din
设置为要存储的值,将写入地址设置为0或1(取决于要存储值的位置),并将vin
设置为1,持续一个周期。该值将保留在ram内部ram_块
数组中,直到被覆盖。您可以通过将读取地址设置为0或1(与您将值写入的地址相同)来检索它。然后,该值将在下一个周期的输出中。是的,在您更改读取地址后,输出将在该周期中更改。此时只能存在一个存储在RAM中的值
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ram IS
GENERIC
(
ADDRESS_WIDTH : integer := 4;
DATA_WIDTH : integer := 8
);
PORT
(
clock : IN std_logic;
data : IN signed(DATA_WIDTH - 1 DOWNTO 0);
write_address : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0);
read_address : IN unsigned(ADDRESS_WIDTH - 1 DOWNTO 0);
we : IN std_logic;
q : OUT signed(DATA_WIDTH - 1 DOWNTO 0)
);
END ram;
ARCHITECTURE rtl OF ram IS
TYPE RAM IS ARRAY(0 TO 2 ** ADDRESS_WIDTH - 1) OF signed(DATA_WIDTH - 1 DOWNTO 0);
SIGNAL ram_block : RAM;
BEGIN
PROCESS (clock)
BEGIN
IF (clock'event AND clock = '1') THEN
IF (we = '1') THEN
ram_block(to_integer(unsigned(write_address))) <= data;
END IF;
q <= ram_block(to_integer(unsigned(read_address)));
END IF;
END PROCESS;
END rtl;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
package my_package is
type matrix1_t is array(integer range<>) of signed(7 downto 0);
type big_matrix is array(integer range<>) of signed(23 downto 0);
type matrix2d is array (integer range<>) of big_matrix(0 to 3);
end my_package;