OkDL的另一个问题。以下是我的代码。假设我希望我的输入存储在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;
以下是我的问题:
inp(i)<=din;
。我认为这将有助于合成器理解这是一个公羊,但还有什么?此外,我需要inp1
个寄存器吗?如果我打算使用它们,为什么还要使用ram作为中间体?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,这是我的实现。问题是我在插入ram模型时通过更改inp1(i)<=din;
获得了什么。那么我怎么能用呢? (在使用ram之前,我只是写了一下i np1(i)+inp2(i+1)
)。
EDIT2:包装类型。
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;
答案 0 :(得分:2)
您没有将i
设置为0
以外的任何内容,因此您只能分配到inp1(0)
。
假设RAM存储了很多值,并且你需要在每个时钟周期读取其中的两个以便进行添加,你需要2块RAM块(或者一个双端口块),然后放入两块地址到那些RAM块。下一个周期,您想要的两个值将出现在数据输出上,您可以将它们相加。
您观察到的时钟周期延迟属于同步RAM的性质(这是大多数FPGA对其“大型存储”所具有的) - 有些可以创建更小的异步RAM,其中数据在读取地址更改后出现短暂延迟,与时钟完全异步。
答案 1 :(得分:2)
为什么要使用那个ram而不仅仅是inp(i)&lt; = din;
在现实世界的设计中,您使用RAM来存储大量数据,因为它们比触发器阵列更小(物理上,在芯片上)。在合成过程中,RAM将替换为供应商库中的RAM。这个RAM看起来很小,但我猜你已经被告知要用一个作为练习。
此外,我需要inp1寄存器吗?如果我要使用它们,为什么还要使用ram作为中间体?
我不太确定imp1是什么,因为我不知道matrix_t
是什么,但我猜它是RAM的寄存器版本。在这种情况下,它是多余的。
如果不需要inp1,我将如何在我的进程中获取这两个元素?我的意思是我需要像ram(address1)+ ram(address2)这样的东西,对吧?
......这是真正的问题。你需要问问自己'如果你不能在一个周期中阅读更多的东西,你如何添加两个数字?'
谁能告诉我为什么q(输出)估计一个时钟后呢?
因为这就是RAM的工作原理。您在一个周期中应用一个地址,数据会在一些周期后出现(通常是一个,但不总是)
这些是您在真实设计中将面临的实际问题。 RAM是必要的,因为它们的尺寸较小。您需要了解使用它们的问题以及如何使用它们。
答案 2 :(得分:1)
我假设您尝试用信号inp1
表示RAM。但是,代表RAM的信号在ram_block
实体中为ram
。
您正以奇怪的方式使用该实体,因为您将信号k
连接为读写地址。这有两个问题。首先,k
似乎并未在您的设计中的任何位置驱动。其次,您可能不希望这两个地址相同。
我假设您想要将一些值写入RAM,同时读取两个值并将它们相加。我建议你使用一个设置写地址的过程和一个设置读地址的过程。您还需要至少一个具有RAM输出宽度的寄存器。从RAM读取的第一个值存储在该寄存器中。然后添加该寄存器中的值和从RAM读取的第二个值,并将结果存储在不同的寄存器中。