我目前正在用VHDL进行一个项目,因为我不是专家,所以我遇到了一些问题。
我会尽力澄清一切。所以让我们分成几部分。
我要做的是在两个不同的RAM存储器中写入某些值,然后从它们读取并将不同的值存储到一个阵列中,该阵列将由不同的块用于执行MAC过滤。
这是我正在使用的RAM代码(是Weijun Zhang提供的代码的修改)我不知道是否必须在此处发布链接。如果有人需要它会发布它
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------------------
entity SRAM is
generic( width: integer:=32;
depth: integer:=1024;
addr: integer:=10);
port( clk: in std_logic;
enable: in std_logic;
read_en: in std_logic;
write_en: in std_logic;
read_addr: in std_logic_vector(addr-1 downto 0);
write_addr: in std_logic_vector(addr-1 downto 0);
Data_in: in std_logic_vector(width-1 downto 0);
Data_out: out std_logic_vector(width-1 downto 0)
);
end SRAM;
--------------------------------------------------------------
architecture behav of SRAM is
-- use array to define the bunch of internal temporary signals
type ram_type is array (0 to depth-1) of std_logic_vector(width-1 downto 0);
signal tmp_ram: ram_type:= ((others=> (others=>'0')));
begin
-- read_en Functional Section
process(clk, read_en)
begin
if (clk'event and clk='1') then
if enable='1' then
if read_en='1' then
-- buildin function conv_integer change the type
-- from std_logic_vector to integer
Data_out <= tmp_ram(conv_integer(read_addr));
else
Data_out <= (Data_out'range => 'Z');
end if;
end if;
end if;
end process;
-- write_en Functional Section
process(clk, write_en)
begin
if (clk'event and clk='1') then
if enable='1' then
if write_en='1' then
tmp_ram(conv_integer(write_addr)) <= Data_in;
end if;
end if;
end if;
end process;
end behav;
这个RAM代码工作正常,我无法附加图像,因为我没有足够的声誉(这对我来说听起来很熟悉......) 我想用图像解释的是,在设置地址的同时,输出值是该地址中包含的值。
现在让我们转到实际问题:
我要做的是创建一个包含两个这些RAM内存的块。其中一个RAM用于存储要过滤的输入值,另一个用于存储滤波器系数的值。所以执行将是这样的:
我将尝试保存所有可以删除多行的空间(初始化和端口声明)
library IEEE; -- declare the library
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
library work;
use work.mypackage.all; -- use of mypackage to use arrays as inputs
entity MAC_1024 is
port( clk: in std_logic;
enable: in std_logic;
enable_MAC: in std_logic;
rst: in std_logic;
read_input_en: in std_logic;
write_input_en: in std_logic;
read_coeff_en: in std_logic;
write_coeff_en: in std_logic;
X: in std_logic_vector(31 downto 0);
W: in std_logic_vector(31 downto 0);
Yt: out std_logic_vector(31 downto 0);
Yn: out std_logic_vector(31 downto 0)
);
end MAC_1024;
现在声明两个RAM
input_RAM: SRAM generic map (width=> t_width, depth=> t_depth, addr=> t_addr)
port map (clk, enable, read_input_en, write_input_en,read_input_addr, write_input_addr, X, saved_input);
coeff_RAM: SRAM generic map (width=> t_width, depth=> t_depth, addr=> t_addr)
port map (clk, enable, read_coeff_en, write_coeff_en,read_coeff_addr, write_coeff_addr, W, saved_coeff);
此过程(常量值为“0000000001”)
process (clk, write_input_en, write_coeff_en)
begin
if (clk'event and clk='1') then
if (write_coeff_en='1') then
write_coeff_addr <= cont2;
cont2 <= unsigned(cont2) + unsigned(one);
end if;
if (write_input_en='1') then
i:=0;
write_input_addr <= cont1;
cont1 <= unsigned(cont1) + unsigned(one);
end if;
if (read_input_en='1' and read_coeff_en='1') then
read_input_addr <= cont3;
read_coeff_addr <= cont4;
X_in(i) <= saved_input;
W_in(i) <= saved_coeff;
cont3 <= unsigned(cont3) + unsigned(one);
cont4 <= unsigned(cont4) + unsigned(one);
X_in(i) <= saved_input;
W_in(i) <= saved_coeff;
i:=i+1;
if(i=4) then
i:=0;
end if;
end if;
end if;
end process;
Yn <= X_in(0);
Yt <= saved_input;
正如您所看到的,我使用变量i从0开始并填充数组X_in和W_in。当值为4时,放置在该数组中的位置将返回0.
输出Y_n和Y_t用于测试功能。 Y_n输出存储在X_in [0]中的值,Y_t输出系数RAM的输出值
所以,让我们说保持简单,我有一系列输入值(X),即1,2,3,4 .... 1024,这些值中的每一个都存储在地址1,2,3中, 4 .... 1024
我希望在下一个序列之后将值放在数组中:
X_in [Z Z Z 1]
X_in [Z Z 2 1]
X_in [Z 3 2 1]
X_in [4 3 2 1]
X_in [4 3 2 5]
X_in [4 3 6 5]
...
(当读启用激活时)
输出Y_n(读取X_in [0])将为1 1 1 1 5 5 5 5 9 9 9 9 ...
输出Y_t(读取RAM输出)将为1 2 3 4 5 6 7 8 9 ...
但我获得的是
Y_n Z Z Z Z 4 4 4 4 8 8 8 8 ....
Y_t 1 2 3 4 5 6 7 8 9 ...(预期)
它看起来像索引i的问题(如果读取输出值X_in [1]我获得了与我预期的X_in [0]相对应的值),但是如果它是在我获得的同一时刻在Y_t值4我应该在Y_n中获得值4但是我仍然得到之前的Z.(粗体)
阵列W_in ...
也是如此坦率地说,我有点迷茫,我不知道我是否有问题,有延迟或有什么问题。
我试图明确但我能理解这是一个解释相当复杂的问题
非常感谢你的帮助
更新1: 我不想重置地址计数器,因为我想写入1到1024的顺序地址。由于地址深度为1024是10位,我将地址加到常数,这是一个10位常数(“ 0000000001" )。一旦到达“1111111111”,下一个地址将是“0000000000”。现在的代码是为1024 FIR滤波器准备的,稍后我会尝试做更灵活的。另外我只想在存储器中添加一个输入值值,但每个滤波器周期增加1024个新系数,因此系统的计数器可以在写入操作后复位,但我不重置输入值的计数器,因为我需要知道我在哪里将存储此值。
更新2:我一直在读到,在将地址设置为在RAM中读取(通常为一个周期)后,数据输出会出现一些周期。这可能是我的问题的原因,但那为什么我的RAM代码没有任何延迟工作???
答案 0 :(得分:0)
你不应该在另外两个if语句中驱动i
。尝试更改为if...elseif
。也许这不是你的错误的原因,但它是一个基本规则。