VHDL RAM-модуль и использование регистров - PullRequest
0 голосов
/ 28 марта 2012

Хорошо, еще один вопрос в VHDL.Ниже мой код.Предположим, что я хочу, чтобы мой вклад хранился в оперативной памяти.И скажем, я хочу добавить два из них.(не делайте акцент на этом, позже это будет заменено).Это мой код:

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. Зачем использовать этот баран, а не просто inp(i)<=din;.Я думаю, что это поможет синтезатору понять, что это баран, но что еще?Более того, мне нужны inp1 регистры.И если я собираюсь их использовать, опять же зачем использовать ram в качестве промежуточного звена?
  2. Если 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 (вывод) оценивается как одинчасы спустя?

РЕДАКТИРОВАТЬ: Подводя итог, мне сказали, что я должен использовать оперативную память, и это моя реализация.Вопрос в том, что я получил, изменив свой inp1(i)<=din;, когда я вставил модель оперативной памяти.И как я могу это использовать?(перед использованием барана я просто написал, например, 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 ]

2 голосов
/ 28 марта 2012

Вы не устанавливаете i для чего-либо, кроме 0, поэтому вы всегда будете назначать только inp1(0).

Предполагая, что в ОЗУ имеется много значений, и вам необходимо прочитатьдва из них каждый такт, чтобы выполнить добавление, вам нужно 2 блока ОЗУ (или один двухпортовый), а затем поместить два адреса в эти блоки ОЗУ.В следующем цикле два значения, которые вы хотите, появятся на выходах данных, и вы сможете их суммировать.

Задержка тактового цикла, которую вы наблюдаете, имеет характер синхронных ОЗУ (что и есть у большинства FPGA для их "большое хранилище ") - некоторые могут создавать меньшие асинхронные ОЗУ, в которых данные появляются с небольшой задержкой после изменения адреса чтения, полностью асинхронно по отношению к часам.

2 голосов
/ 28 марта 2012

Зачем использовать этого барана, а не просто делать inp (i) <= din; </p>

В реальных разработках вы используете ОЗУ для хранения больших объемов данных, потому что они меньше (физически, на кристалле) массивов триггеров. В процессе синтеза оперативная память заменяется на одну из библиотеки вашего поставщика. Это ОЗУ выглядит довольно маленьким, но, полагаю, вам сказали использовать его в качестве упражнения.

Кроме того, мне нужны регистры inp1. И если я собираюсь их использовать, опять же зачем использовать ОЗУ в качестве промежуточного звена?

Я не совсем уверен, что такое imp1, так как я не знаю, что такое matrix_t, но я предполагаю, что это зарегистрированная версия RAM. В этом случае это избыточно.

Если inp1 не нужен, как я собираюсь получить эти два элемента в моем процессе? Я имею в виду, мне нужно что-то вроде оперативной памяти (адрес1) + оперативной памяти (адрес2), верно?

... и есть реальная проблема. Вы должны спросить себя: «Если вы не можете прочитать больше одной вещи в цикле, как вы добавите два числа?»

Может кто-нибудь сказать мне, почему q (выход) оценивается через один час?

Потому что так работают ОЗУ. Вы применяете адрес за один цикл, и данные появляются через несколько циклов (обычно один, но не всегда)

Это реальные проблемы, с которыми вы столкнетесь в реальных проектах. RAM необходимы из-за их меньшего размера. Вам нужно знать проблемы, связанные с их использованием, и как с ними работать.

1 голос
/ 28 марта 2012

Я предполагаю, что вы пытаетесь представить ОЗУ с сигналом inp1. Однако сигнал, который представляет ОЗУ, ram_block в вашей сущности ram.

Вы используете сущность странным образом, потому что вы подключаете сигнал k в качестве адреса для чтения и записи. Есть две проблемы с этим. Во-первых, кажется, что k нигде не используется в вашем дизайне. Во-вторых, вы, вероятно, не хотите, чтобы два адреса были одинаковыми.

Я предполагаю, что вы хотите записать некоторые значения в ОЗУ и одновременно прочитать два значения и сложить их. Я предлагаю вам использовать процесс, который устанавливает адрес записи, и процесс, который устанавливает адрес чтения. Вам также нужен хотя бы один регистр с шириной вывода ОЗУ. Первое значение, которое вы читаете из ОЗУ, сохраняется в этом регистре. Затем вы добавляете значение в этот регистр, а второе значение считываете из ОЗУ и сохраняете результат в другом регистре.

...