vhdl ram模块和寄存器的使用

时间:2012-03-27 21:43:02

标签: vhdl

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; 

以下是我的问题:

  1. 为什么要使用那个ram而不只是inp(i)<=din;。我认为这将有助于合成器理解这是一个公羊,但还有什么?此外,我需要inp1个寄存器吗?如果我打算使用它们,为什么还要使用ram作为中间体?
  2. 如果不需要inp1,我将如何在我的进程中获取这两个元素?我的意思是我需要像ram(address1)+ram(address2)这样的东西,对吧?
  3. 下面是我的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;
    

3 个答案:

答案 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读取的第二个值,并将结果存储在不同的寄存器中。