如何在FPGA中正确存储寄存器

How to correctly storage registers in an FPGA

我需要用 VHDL 编写一个使用 i2c 初始化传感器寄存器的程序。我的问题是编写一个不浪费所有 FPGA space 的高效程序。我需要存储的寄存器个数是400个由8位地址和8位数据组成的寄存器。

我写的程序是:

entity i2cReg is
    port (
            RegSel : in std_logic;
            Address : out std_logic_vector (15 downto 0);
            Data : out std_logic_vector (7 downto 0);
            RegStop : out std_logic;
            ModuleEN : in std_logic
    );
end i2cReg;

architecture i2cReg_archi of i2cReg is
    signal counter :integer := 0;

    begin
        process(RegSel, ModuleEN)
        begin
            if ModuleEN = '0' then
                    Address <= x"10";  
                    Data <= x"10";
                    RegStop <= '0';
                    counter <= 0;
            elsif rising_edge(RegSel) then
                counter <= counter + 1;
                case counter is
                    when 0 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 1 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 2 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 3 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 4 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 5 =>
                     Address <= x"10";
                     Data <= x"10";
                    when 400 =>
                        RegStop <= '1';
                    when others =>
                end case;
            end if;
        end process;

end i2cReg_archi;

有办法优化这段代码吗?或者你建议我使用外部 eeprom?

Yaro - 您没有提到 FPGA 供应商或设备,但答案是:是的,您可以在 FPGA 中初始化 ROM,以便在配置后显示您需要的值。 Altera 和 Xilinx 都允许您在综合期间提供包含初始值的文件。

凯文

如果您使用的是 Xilinx 或 Altera,则初始化 BlockRAM 通常是正确的解决方案。

但也有逻辑实现也可以工作的例外情况: 例如,如果您的 400 个寄存器的内容具有重复模式或许多具有相同值的寄存器(如您的示例代码)。在这种情况下,如果您将其实现为逻辑,您的综合工具将对其进行大量优化。如果寄存器内容非常重复,您实际上可能会得到非常少量的逻辑。有时也可以通过巧妙地重新排序寄存器来改进优化。

100-200 个逻辑单元通常被认为 "cheaper" 而不是 BlockRAM。但这主要取决于您的特定应用程序中哪种资源最稀缺。

无论您是使用初始化的 BlockRAM 还是逻辑,我都建议您将其建模为 std_logic_vector 的数组,而不是使用 case/when。 "array of std_logic_vector" 方法与平台无关,可以综合为 BlockRAM 或逻辑。您的综合工具通常会尝试自动 select 最佳实现。但您也可以通过使用供应商特定属性强制综合工具使用逻辑或 BlockRAM。 (我不能告诉你使用哪些属性,因为我不知道你使用的是哪个平台)

示例:

type REG_TYPE is array (0 to 3) of std_logic_vector(15 downto 0);
constant REGISTERS : REG_TYPE :=
    (x"0000",
     x"0001",
     x"0010",
     x"0100");

在您的过程中,类似:

if rising_edge(RegSel) then
    Address <= REGISTERS( counter )(15 downto 8);
    Data    <= REGISTERS( counter )( 7 downto 0);
end if;