vhdl ram模块和寄存器的使用
好了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_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;
下面是我的问题:
- 为什么要使用RAM,而不是只是做
inp(i)<=din;
。我认为这将有助于合成器理解这是一个内存,但还有什么?此外,我需要inp1
寄存器。如果我打算使用它们,为什么要使用ram作为中间件? - 如果inp1是不必要的,我将如何在我的过程中获取这两个元素?我的意思是我需要像
ram(address1)+ram(address2)
这样的东西,对吧?
下面是我的ram_code:
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;
3,可谁能告诉我为什么Q(输出)以后估计一个时钟?
编辑:总而言之,我被告知我应该使用内存,这是我的实现。问题是当我插入RAM模型时,通过更改我的inp1(i)<=din;
获得了什么。那么我该如何使用它? (在使用公羊之前,我刚刚写下了例如np1(i)+inp2(i+1)
)。
编辑2:包装类型。
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;
为什么要使用该ram,而不只是做inp(i)< = din;
在现实世界中设计使用的RAM来存储大量的数据,因为他们是小(物理,在芯片上)是翻转的阵列无人问津。在合成过程中,RAM被替换为供应商库中的一个。这个RAM看起来很小,但我猜你已经被告知使用一个作为练习。
此外,我需要inp1寄存器。如果我打算使用它们,为什么要使用ram作为中间件?
我不太确定imp1是什么,因为我不知道matrix_t
是什么,但我猜测它是RAM的寄存器版本。在这种情况下,这是多余的。
如果inp1是不必要的,我将如何在我的过程中获取这两个元素?我的意思是我需要像ram(address1)+ ram(address2)这样的东西,对吧?
...这是真正的问题。你需要问自己'如果你不能在一个循环中读更多的东西,你如何添加两个数字?'
谁能告诉我为什么q(输出)是估计一个钟后?
因为这就是RAM的工作原理。您在一个周期内应用地址,并且数据稍后会出现一些周期(通常是一个周期,但不总是)由于RAM尺寸较小,RAM是必需的。您需要了解使用它们的问题以及如何使用它们。
伟大的职位,以帮助我理解。所以最后一个问题,我会检查你的答案。假设我想从ram中获取元素的时间不是在同一个周期,而是在一段时间后。我将不得不再次移植地图,并从我的输出中获取我想要的元素(例如we ='0')?我的意思是,这不是一个简单的方法 - 只需编写ram_block(address)并获取该元素,就像我通常在寄存器中执行的那样,对吗? Inp1只是一个复制ram元素的数组,因此是多余的。 – 2012-03-28 17:22:34
你的问题不清楚。我想你是问你是否可以在同一个周期内读写,答案将取决于RAM的设计。一些RAM具有独立的读写端口以允许这样做。其他人有一个合并端口。你有一个单独的读取地址和写入地址,所以你可以独立执行这两个操作,但当它们都是同一个地址时要小心。 – 2012-03-29 09:35:02
我假设你试图用信号inp1
表示一个RAM。但是,表示RAM的信号在您的ram
实体中为ram_block
。
由于您连接信号k
作为读写地址,因此您使用的是实体。这有两个问题。首先,k
在您的设计中似乎没有被驱动到任何地方。其次,你可能不希望这两个地址是一样的。
我假设你想写一些值到RAM,同时读取两个值并添加它们。我建议你使用一个进程来设置一个写地址和一个设置读地址的进程。您还需要至少一个具有RAM输出宽度的寄存器。从RAM中读取的第一个值存储在该寄存器中。然后,您将该寄存器中的值和RAM中读取的第二个值相加,并将结果存储在另一个寄存器中。
好的。有人告诉我应该使用内存,这是我的实现。问题是我通过改变我的inp1(i) 2012-03-27 23:14:22
但要实施什么?你能显示'matrix_1t'类型的定义吗? – simon 2012-03-28 07:29:54
编辑。好吧,想象我以前的代码是这样的。 过程(CLK) INP(I) 2012-03-28 08:16:56
您不会将i
设置为0
以外的任何值,因此您只能指定inp1(0)
。
假设RAM有多个存储值,并且您需要在每个时钟周期读取其中的两个以进行添加,则需要2个RAM块(或单个双端口块),然后将两个地址到这些RAM块中。下一个周期你想要的两个值将出现在数据输出中,你可以将它们相加。您观察到的时钟周期延迟属于同步RAM(这是大多数FPGA对其“大容量存储器”所具有的特性) - 有些可以创建更小的异步RAM,其中数据在读取地址之后出现短暂延迟改变,完全异步的时钟。
实际计算与此差异不同。并且我从一个测试平台更改它的值。只是为了了解如何使写入过程独立于从RAM读取(我的计算要求所有数据已被首先读取)。 – 2012-03-28 10:58:59
请你可以编辑你的代码,删除被注释掉的位,并正确缩进它。如果您希望我们帮助您,只要您尽可能简单地阅读您的问题,就会得到更好的答复。 – 2012-03-28 09:45:45
好吧,我编辑了我的答案并删除了评论 – 2012-03-28 09:58:08
我并不是说删除评论 - 只是注释掉的*代码*的位! – 2012-03-28 10:25:52