VHDL-код выполняется, но временная диаграмма ничего не показывает
Я пытаюсь реализовать кэш-память 16 * 37 в VHDL в DesignWorks 5. Код приведен ниже. Код выполняется, но когда я изменяю значения с панели ввода-вывода или даже симулирую в любом случае, временная диаграмма ничего не показывает, и в основном код по какой-то причине не работает. Любые предложения будут действительно полезны.
Код:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity Cache is
port(cs, r, clr : in std_logic;
data : in std_logic_vector(31 downto 0);
addr : in std_logic_vector(7 downto 0);
cline : out std_logic_vector(31 downto 0);
ctag: out std_logic_vector(3 downto 0);
v : out std_logic);
end Cache;
architecture behav of Cache is
type RAM is array (0 to 15) of std_logic_vector(36 downto 0);
begin
process is
variable M : RAM;
variable locn : natural;
variable temp_val : std_logic_vector(36 downto 0);
variable cline_val : std_logic_vector(31 downto 0);
variable ctag_val : std_logic_vector(3 downto 0);
variable v_val : std_logic;
begin
if cs = '1' then
locn := to_integer(addr);
if r = '1' then
temp_val := M(locn);
cline_val := temp_val(31 downto 0);
ctag_val := temp_val(35 downto 32);
v_val := temp_val(36);
else
temp_val(31 downto 0) := data;
temp_val(35 downto 32) := addr(3 downto 0);
temp_val(36) := '1';
M(locn) := temp_val;
v_val := 'Z';
ctag_val:= "ZZZZ";
cline_val:= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
end if;
end if;
if clr ='1' then
locn := 0;
while(locn<16) loop
M(locn) := X"000000000" + "0";
locn:=locn+1;
end loop;
end if;
cline <= cline_val;
ctag <= ctag_val;
v <= v_val;
wait on cs;
end process;
end behav;
1 ответ
Эта строка:
M(locn) := X"000000000" + "0";
кажется неверным.
M - это тип массива ram с длиной элемента 37. Ноль с 36 битами, добавленный к нулю, по-прежнему равен 36 битам (не похоже, что вы достигли этого утверждения, это будет ошибка времени выполнения).
Чтобы сделать вектор длиной 37 из значений "0", используйте `(others => '0').
Вы также можете использовать цикл for для сброса оперативной памяти, вам не нужно использовать индекс 16, он выходит за пределы диапазона, что говорит о том, что вы также не достигли очистки.
Я думаю, что вы должны показать нам свой стимул, иначе ваши проблемы не могут быть воспроизведены.
Ваш пропавший data
а также addr
в качестве элементов чувствительности (и, да, вы используете cs Surround, но вы хотите построить здесь аппаратную модель).
Переключиться на список чувствительности (cs, data, addr)
,
locn
является естественным неограниченным и должен иметь диапазон, соответствующий типу массива ram (от 0 до 15). Обратите внимание, что ваш цикл while достигает 16. Действительно, используйте цикл for (как показано ниже). Причина сдерживания locn
чтобы предотвратить связанную ошибку при доступе ram(locn)
,
Примечание для конвертации addr
к естественному (locn
) вам нужно и маску addr
с длиной четыре прогона '1', чтобы предотвратить ошибку диапазона для нормальных операций оперативной памяти.
Пакет numeric_std является влиянием, это проще, чем передать пару параметров командной строки в ghdl (ieee=synopsys -fexplict
) во время анализа и разработки.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cache is
port (
cs, r, clr: in std_logic;
data: in std_logic_vector(31 downto 0);
addr: in std_logic_vector(7 downto 0);
cline: out std_logic_vector(31 downto 0);
ctag: out std_logic_vector(3 downto 0);
v: out std_logic
);
end entity;
architecture behav of cache is
type ram is array (0 to 15) of std_logic_vector(36 downto 0);
begin
process (cs, data, addr)
variable m : ram;
variable locn : natural range (ram'range);
variable temp_val : std_logic_vector(36 downto 0);
variable cline_val : std_logic_vector(31 downto 0);
variable ctag_val : std_logic_vector(3 downto 0);
variable v_val : std_logic;
begin
if cs = '1' then
locn := to_integer(unsigned(addr and x"0F"));
if r = '1' then
temp_val := m(locn);
cline_val := temp_val(31 downto 0);
ctag_val := temp_val(35 downto 32);
v_val := temp_val(36);
else
temp_val(31 downto 0) := data;
temp_val(35 downto 32) := addr(3 downto 0);
temp_val(36) := '1';
m(locn) := temp_val;
v_val := 'Z';
ctag_val:= "ZZZZ";
cline_val:= (others => 'Z');
end if;
end if;
if clr ='1' then
for i in ram'range loop
m(i) := (others => '0');
end loop;
end if;
cline <= cline_val;
ctag <= ctag_val;
v <= v_val;
end process;
end architecture;
Этот код анализирует и разрабатывает, вы могли бы иметь ошибку где-то, о чем я не упомянул, и ошибки привязки (диапазона) появляются во время выполнения в присваиваниях (выражения не заботятся).
И последний момент:
temp_val(31 downto 0) := data;
temp_val(35 downto 32) := addr(3 downto 0);
temp_val(36) := '1';
можно выразить:
temp_val:= '1' & addr(3 downto 0) & data;
Так же как:
locn := to_integer(addr);
выражается как:
locn := to_integer(addr(3 downto 0));
Вы также можете создать маску AND с длиной, определенной алгоритмически из ram'range
Если вы установите размер оперативной памяти с универсальным.
И не видя вашего стимула, есть несколько мест, которые могут вызвать ошибки во время выполнения. Проверьте вывод вашей консоли.