Как я могу заменить синтаксис "wait on a" в vhdl эквивалентным синтаксисом, который не будет инициировать бесконечный цикл и может быть синтезирован в quartus? - PullRequest
0 голосов
/ 02 января 2019

Я работаю на процессоре с одним циклом, используя VHDL. Я пытался устранить ошибки в коде, но в итоге мы попали в две ситуации в памяти команд и памяти данных (в imem & dmem):

  1. в коде есть часть ("wait on a"), которая не может быть синтезирована в quarus, а также проблема с циклами, которые делают цикл кода бесконечно циклическим в quartus
  2. мы попытались заменить циклы и (подождите a) на (process (a)), но у нас также есть проблема, заключающаяся в том, что внутри другого процесса не может быть процесса.

Как я могу решить эти ошибки?

library IEEE;
use IEEE.STD_LOGIC_1164.all; use STD.TEXTIO.all;
use IEEE.STD_LOGIC_arith.all;

entity imem is -- instruction memory
port(a: in STD_LOGIC_VECTOR(31 downto 0);
   rd: out STD_LOGIC_VECTOR(31 downto 0));
end;

architecture behave of imem is -- instruction memory
type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);

begin
process is
  file mem_file: TEXT;
  variable L: line;
  variable ch: character;
  variable i, index, result: integer;
  --type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  variable mem: ramtype;
begin
  -- initialize memory from file
  for i in 0 to 63 loop -- set all contents low
    mem(i) := (others => '0');
  end loop;
  index := 0;
  FILE_OPEN(mem_file, "memfile.dat", READ_MODE);
  while not endfile(mem_file) loop
    readline(mem_file, L);
    result := 0;
    for i in 1 to 8 loop
    read(L, ch);
      if '0' <= ch and ch <= '9' then
        result := character'pos(ch) - character'pos('0');
      elsif 'a' <= ch and ch <= 'f' then
        result := character'pos(ch) - character'pos('a') + 10;
      elsif 'A' <= ch and ch <= 'F' then
        result := character'pos(ch) - character'pos('A') + 10;
      else report "Formaterror on line " & integer'image(index)
        severity error;
      end if;
      mem(index)(35-i*4 downto 32-i*4) :=conv_std_logic_vector(result,4);
    end loop;
    index := index + 1;
  end loop;
  -- read memory
  loop 
    rd <= mem(conv_integer(unsigned(a(7 downto 2))));
    wait on a;
  end loop;
end process;
end;

1 Ответ

0 голосов
/ 02 января 2019

Как сообщает @Tricky, я упустил из виду, что вы используете . Насколько мы оба знаем, Quartus не поддерживает чтение файлов в функциях инициализатора. Весь пакет textio для файлового ввода-вывода не поддерживается / игнорируется. Вам необходимо использовать примитивы мега-функции Altera из библиотеки VHDL altera_mf с именем altsyncram для представления ОЗУ или ПЗУ. В PoC-библиотеке есть реализация.

altsyncram пример для однопортовой оперативной памяти:

library altera_mf;
use     altera_mf.all;

mem : altsyncram
    generic map (
        address_aclr_a         => "NONE",
        indata_aclr_a          => "NONE",
        init_file              => INIT_FILE,
        intended_device_family => getAlteraDeviceName(DEVICE),
        lpm_hint               => "ENABLE_RUNTIME_MOD = NO",
        lpm_type               => "altsyncram",
        numwords_a             => DEPTH,
        operation_mode         => "SINGLE_PORT",
        outdata_aclr_a         => "NONE",
        outdata_reg_a          => "UNREGISTERED",
        power_up_uninitialized => "FALSE",
        widthad_a              => A_BITS,
        width_a                => D_BITS,
        width_byteena_a        => 1,
        wrcontrol_aclr_a       => "NONE"
    )
    port map (
        clocken0   => ce,
        wren_a     => we,
        clock0     => clk,
        address_a  => a_sl,
        data_a     => d,
        q_a        => q
    );

Источник: https://github.com/VLSI-EDA/PoC/blob/master/src/mem/ocram/altera/ocram_sp_altera.vhdl?ts=2


Оригинальный ответ:
Вам нужно поместить код инициализации вашей RAM в функцию, которая возвращает начальные значения для вашей RAM. В функции вы читаете внешний файл и конвертируете каждую строку в значение памяти.

Вот несколько фрагментов, которые помогут вам выбрать правильный путь:

architecture a of e is
  type ram_type is array(natural range <>) of std_logic_vector(31 downto 0);

  function initialize(
    constant file_name : string;
    constant size      : positive
  ) return ram_type is
    file mem_file   : text;
    variable result : ram_type(0 to size - 1);
  begin
    file_open(mem_file, file_name, READ_MODE);

    while not endfile(mem_file) loop
      -- ... read and convert content
    end loop;

    file_close(mem_file);

    return result;
  end function;

  signal mem : ram_type := initialize("memfile.dat", 64);

begin
  process(a)
  begin
    rd <= mem(to_integer(unsigned(a(7 downto 2))));
  end process;

Дополнительные подсказки:

  • Обычно чтение памяти команд (BlockRAM) является синхронизированным процессом. В настоящее время вы читаете асинхронно при каждом изменении адреса.
  • Оператор wait on эквивалентен процессу со списком чувствительности.
  • Вы должны закрыть открытые файлы.
  • Не используйте пакет STD_LOGIC_arith, используйте numeric_std.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...