为什么读取寄存器文件没有提供预期的结果

问题描述 投票:0回答:0

问题 - 无法读取寄存器文件数组中寄存器的内容。我有一个 11 位宽的寄存器文件,其中每个寄存器都应该有两个独立的地址——一个用于读取,另一个用于写入。寄存器文件的大小(深度)由 Proj_Pack 包文件中声明的常量 ADDRESS_BITS 设置。常量的值当前为 5,因此地址总数为 32。由于设计上每个寄存器应有 2 个地址,因此寄存器总数当前为 16。从 0 到 15 的地址是用于 READ 操作的地址,从 16 开始的地址至 31 用于 WRITE。请注意,随着项目的进一步进展,ADDRESS_BITS 值(以及因此寄存器文件中的寄存器数量)可能会在以后发生变化。

我从创建实体和声明端口信号开始。当然,端口中的信号要多得多,但为了清楚和简单起见,这里省略了它们。然后我创建架构并声明代表我的寄存器文件的内部信号和内存阵列。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.Proj_Pack.all;

entity Reg_File is
port( i_ADDRESS   :  in std_logic_vector(ADDRESS_BITS - 1 downto 0);    --  input, ADDRESS bus.
      o_DATA_XMIT : out std_logic_vector(10 downto 0)           -- output, DATA_XMIT bus.
     );
end entity Reg_File;

architecture Behavioral of Reg_File is

      -- Declaration of the Reg_File_Data register file
      type t_Reg_File_Data is array (0 to 2**(ADDRESS_BITS-1)-1) of std_logic_vector(10 downto 0); -- Register File with the total of 2**(ADDRESS_BITS-1) registers.
      signal mem_Reg_File_Data :    t_Reg_File_Data := ( "10101010101", "10000100001",             -- Internal signal, Register File data bus with initial registers'content.
                                                             "10001000010", "10001100011",             -- Initial registers'content continuous.
                                                             "10010000100", "10010100101",             -- Initial registers'content continuous.
                                                             "10011000110", "10011100111",             -- Initial registers'content continuous.
                                                             "10100001000", "10100101001",             -- Initial registers'content continuous.
                                 "10101001010", "10101101011",             -- Initial registers'content continuous.
                                 "10110001100", "10110101101",             -- Initial registers'content continuous.
                                 "10111001110", "10111101111"              -- Initial registers'content continuous.
                                                            );

      -- Declaration of the internal signals
      signal int_Decoder       : std_logic_vector(2**ADDRESS_BITS - 1 downto 0);               -- Internal Decoder bus, enables one location of the register file at a time.
          signal int_DATA_XMIT     : std_logic_vector(10 downto 0);                                    -- Internal DATA_XMIT bus.

-- My first step is to decode the incoming binary address to enable the register corresponding to that address. Note that the decoder code below seems to operate as expected based on the simulation waveforms.

begin
      
      gen_Decoder : for i in 0 to (2**ADDRESS_BITS - 1) generate   -- Binary decoder starts here,
                                                                       -- generates active HIGH outputs,
                                                                       -- from 0 to 31, one active output at
                                                                       -- a time.
     int_Decoder(i) <= '1' when i_ADDRESS = std_logic_vector(to_unsigned(i, ADDRESS_BITS)) else
               '0';
            end generate gen_Decoder;

-- My next step is to create some association between the currently enabled location of the Register File and value of the data placed on the int_DATA_XMIT bus. The idea is that while gen_Decoder above operates with input addresses from 0 to 15, the respective register's content is placed on the int_DATA_XMIT bus by the gen_DATA_XMIT and when input address value is from 16 to 31, the gen_DATA_XMIT sets int_DATA_XMIT bus to "11111111111".
-- Note that this statement **doesn't provide the expected output**. What happens instead is in the address range from 16 to 31 the int_DATA_XMIT = "11111111111" as expected but the output is XXX in the 0 to 14 range and XXF for address 15. Please refer to the attached simulation waveforms for visual results.

        gen_DATA_XMIT : for i in 0 to (2**(ADDRESS_BITS-1) - 1) generate
                int_DATA_XMIT <= mem_Reg_File_Data(i) when int_Decoder(i) = '1' else
                             (others => '1');
                end generate gen_DATA_XMIT;
                    
                    
            o_DATA_XMIT <= int_DATA_XMIT;
                               
end Behavioral;

所以我的问题很传统:

  1. 我做错了什么?
  2. 这些 X 是从哪里来的?
  3. 如何解决问题?
  4. 有没有更优雅的方式来完成我的任务?

另请注意以下几点——这里不涉及任何时钟,因为此代码必须立即执行,不必等到下一个时钟(时钟稍后会处理结果)并且最终代码必须完全可合成。

感谢您耐心阅读这篇冗长的文章。

附言。我试图用敏感列表上带有 i_ADDRESS 的进程替换 gen_DATA_XMIT,但首先,传统输出偏移了一个 i_ADDRESS 状态,其次,它导致了一些其他问题。

Simulation Results as Described Above

arrays vhdl hardware generate
© www.soinside.com 2019 - 2024. All rights reserved.