我尝试使用RAM行为实现FSM。在描述此FSM时,应该初始化此ram的多个地址。所以,我使用数组聚合技术来初始化 ram_block 的前20个地址。但是,我在每行发生聚合时出现错误的语法错误,或者ram_block(i)的部分部分已初始化。任何帮助将不胜感激。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
entity RegisterController is
port(
r1_p: inout std_logic_vector(31 downto 0);
r2_p: inout std_logic_vector(31 downto 0);
write_p: in std_logic;
enable_p: in std_logic;
clk_p: in std_logic;
ram_rw: in std_logic; -- 0 => Read from ram | 1 => Write to the ram
reset_p: in std_logic
);
end RegisterController;
architecture RTL of RegisterController is
-- Create the ram word
subtype ram_word is std_logic_vector(66 downto 0);
-- Create the ram block of 32 ram_words
type ram_block is array (31 downto 0) of ram_word;
-- Address to read from the ram
signal R_ADDR_S: std_logic_vector(4 downto 0) := "00000";
begin
RAM_LOAD: process(clk)
begin
-- We're gonna load the 32 words of this ram with clock first
-- Outputs are being updated in the runtime :D
if(rising_edge(clk)) then
if(ram_rw = '1') then
-- STATE 0 DESCRIPTION
ram_block(0) <= ("000", std_logic_vector(to_unsigned(0, 32)), std_logic_vector(to_unsgined(0, 32)));
ram_block(1) <= ("000", std_logic_vector(to_unsigned(0, 32)), std_logic_vector(to_unsigned(0, 32)));
ram_block(2) <= ("001", std_logic_vector(to_unsigned(0, 32)), std_logic_vector(to_unsigned(0, 32)));
ram_block(3) <= ("001", std_logic_vector(to_unsigned(0, 32)), std_logic_vector(to_unsigned(0, 32)));
-- STATE 1 DESCRIPTION
ram_block(4) <= (66 downto 64) => "001";
ram_block(5) <= (66 downto 64) => "001";
ram_block(6) <= ("001", r2_p, r1_p);
ram_block(7) <= (66 downto 64) => "010";
-- STATE 2 DESCRIPTION
ram_block(8) <= (66 downto 64) => "010";
ram_block(9) <= (66 downto 64) => "010";
ram_block(10) <= (66 downto 64) => "011";
ram_block(11) <= (66 downto 64) => "011";
-- STATE 3 DESCRIPTION
ram_block(12) <= (66 downto 64) => "011";
ram_block(13) <= (66 downto 64) => "011";
ram_block(14) <= (66 downto 64) => "100";
ram_block(15) <= (66 downto 64) => "100";
-- STATE 4 DESCRIPTION
ram_block(16) <= (66 downto 64) => "100";
ram_block(17) <= (66 downto 64) => "100";
ram_block(18) <= (66 downto 64) => "001";
ram_block(19) <= (66 downto 64) => "001";
ram_block(31 downto 20) <= std_logic_vector(to_unsigned(0, 67));
end if;
end if;
end process;
START_FSM: process(clk)
-- TEMPORARY VARIABLE TO STORE THE READ VALUE FROM THE RAM BLOCK
variable temp_read_ram: std_logic_vector(66 downto 0);
variable temp_read_ram2: std_logic_vector(66 downto 0);
-- R3 Declaration as a variable
variable R3_V: std_logic_vector(31 downto 0);
begin
if(rising_edge(clk)) then
if(ram_rw = '0') then
-- START READING THE RAM FROM ADDRESS 0
temp_read_ram := ram_block(to_integer(unsigned(R_ADDR_S)));
R_ADDR_S(4 downto 2) <= temp_read_ram(66 downto 64);
R_ADDR_S(1 downto 0) <= (enable_p, write_p);
-- UPDATE THE OUTPUTS
if(R_ADDR_S = "00110") then
-- READ THE PREVIOUS VALUE IN THAT ADDRESS
temp_read_ram2 <= ram_block(R_ADDR_S);
-- UPDATE THE OUTPUT VALUES INSIDE RAM
ram_block(R_ADDR_S) <= (temp_read_ram2(66 downto 64), r2_p, r1_p);
-- NO NEED TO UPDATE r2_p and r1_p
elsif(R_ADDR_S = "00111") then
-- PUT THE CURRENT VALUE OF R1 TO THE R3
temp_read_ram2 <= ram_block(R_ADDR_S);
-- SAVE R1 TO THE R3_V
R3_V := temp_read_ram2(31 downto 0);
elsif(R_ADDR_S = "01110" or R_ADDR_S = "01111") then
-- READ THE PREVIOUS VALIE IN THOSE ADDRESSES
temp_read_ram2 <= ram_block(R_ADDR_S);
-- UPDATE THE OUTPUT VALUE OF R2 INSIDE RAM
ram_block(R_ADDR_S) <= (temp_read_ram2(66 downto 64), R3_V, temp_read_ram2(31 downto 0));
-- UPDATE THE OUTPUT VALUE OF r2_p
r2_p <= R3_V;
else
else
-- NO CHANGE
ram_block(R_ADDR_S) <= ram_block(R_ADDR_S);
end if;
end if;
end if;
end process;
end RTL;
答案 0 :(得分:-1)
代码中没有一个,但语法错误很多。
首先,ram_block
是类型,而不是信号。那么你为什么要给它赋值?你需要先声明一个信号。即。
-- Create the ram block of 32 ram_words
type ram_block_type is array (31 downto 0) of ram_word;
signal ram_block : ram_block_type := (others => (others => '0'));
^我在这里也包括,是信号的初始化。同样可以做到:
signal R_ADDR_S: std_logic_vector(4 downto 0) := (others => '0');
在此过程中,您将同时为RAM中的许多位置分配值!那不像RAM那样。随机存取存储器通常只有1或2个端口,访问1个resp。一次2个元素。您正在设计通用分布式内存,因此imho不应将其称为RAM。
分配给数组的一部分有一个特定的语法。您可以一次性分配整个矩阵(顺便说一下,这是VHDL-2008):
ram_block <= (4 => (66 downto 64 => "001", others => '0'), others => '0');
注意:您需要在此处分配所有值,因此需要others
语句。
第二个选项,分配一个子数组
ram_block(4) <= (66 downto 64 => "001", others => '0');
最后,也许你想要的,分配一个子数组的特定子集:
ram_block(4)(66 downto 64) <= "001";
但是在这种情况下,你想要初始化数组,因为未分配的std_logic
将具有默认值'U'。
然后:
ram_block(31 downto 20) <= std_logic_vector(to_unsigned(0, 67));
这不起作用。您将数组结构分配给数组数组。
变量R3_V
在一种情况下分配,但不直接使用:它使用不同的时钟周期。在这种情况下,不要使用变量:这是错误的编码风格。它应该是一个信号。
并且您必须记住,在时钟进程中分配的信号在下一个增量周期之前无法访问其新值。因此,对于以下if语句,信号R_ADDR_S(4 downto 2) <= temp_read_ram(66 downto 64);
的分配将不可用!
其他事项:
clk
应该是clk_p
to_unsgined
- &gt; to_unsigned
ram_block(to_integer(unsigned(R_ADDR_S)))
,但稍后(第86行)你做错了ram_block(R_ADDR_S)
:=
正确分配变量,但稍后(第86行)又使用了不正确的<=
。else
。