自定义类型的数组聚合?

Array aggregation on self-defined types?

我正在尝试实现具有 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;

您的代码中没有一个,而是很多语法错误。

首先,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 个。一次 2 个元素。您正在设计通用分布式内存,所以恕我直言,不应将其称为 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在一种情况下被分配,但不直接使用:它被用于不同的时钟周期。在那种情况下不要使用变量:那是糟糕的编码风格。应该是个信号。

并且您必须记住,在时钟进程中分配的信号在下一个增量周期之前无法访问它们的新值。因此,信号 R_ADDR_S(4 downto 2) <= temp_read_ram(66 downto 64); 的分配将不适用于以下 if 语句!

其他:

  • clk 应该是 clk_p
  • to_unsgined -> to_unsigned
  • 在第 79 行你使用了正确的 ram_block(to_integer(unsigned(R_ADDR_S))),但后来(第 86 行)你用错了 ram_block(R_ADDR_S)
  • 在第 79 行中,您还使用 := 正确地分配了一个变量,但后来(又是第 86 行)您使用了不正确的 <=.
  • 代码末尾有一个双 else