VHDL从RAM中读取并存储在数组延迟中?

问题描述 投票:0回答:1

我目前正在用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用于存储要过滤的输入值,另一个用于存储滤波器系数的值。所以执行将是这样的:

  1. 仅将输入系数写入其专用存储器(地址从1到1024)
  2. 将所有新系数写入其内存(同样地址从1到1024)
  3. 从两个存储器中读取一个系数和一个输入值(从地址1开始)并将它们存储在两个数组中(在这种情况下是4个向量的数组)
  4. 填充阵列(步骤3中多3个循环)
  5. 阵列完成后,使用4个输入值和4个系数执行过滤(仍未实现)
  6. 再次点3点

我将尝试保存所有可以删除多行的空间(初始化和端口声明)

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代码没有任何延迟工作?

arrays vhdl ram
1个回答
0
投票

你不应该在另外两个if语句中驱动i。尝试更改为if...elseif。也许这不是你的bug的原因,但这是一个基本规则。

© www.soinside.com 2019 - 2024. All rights reserved.