Intel® Quartus® Prime Pro Edition用户指南: 设计建议

ID 683082
日期 9/28/2020
Public

本文档可提供新的版本。客户应 单击此处 前往查看最新版本。

文档目录

1.4.1.11. 上电时指定初始存储器内容

综合工具可以提供多种方法来指定一个推断存储器的初始内容。由于连续读取MLAB,专用RAM模块和MLAB存储器之间的上电和初始化差异很小。

Intel FPGA专用RAM模块输出始终上电到零,并在第一次读取时设置成初始值。例如,如果地址0预初始化为FF,那么RAM模块通过0上的输出进行上电 。从地址0上电后的后续读取将输出FF预初始化值。因此,如果RAM上电并且使能(读取使能或时钟使能)保持为低电平,那么上电输出0保持到第一个有效读取周期为止。综合工具使用上电到0的寄存器来实现MLAB,但在上电或复位后立即将其初始化为初始值。因此,无论使能状态如何,都可以看到初始值。当HDL代码指定相应的ramstyle属性时, Intel® Quartus® Prime软件会将推断的存储器映射到MLAB。

在Verilog HDL中,您可以使用初始模块对一个推断的存储器的内容进行初始化。 Intel® Quartus® Prime Pro Edition synthesis自动将初始模块转换为Memory Initialization File (.mif),用于推断的RAM。

包含初始化内容的Verilog HDL RAM

module ram_with_init(
   output reg [7:0] q,
   input [7:0] d,
   input [4:0] write_address, read_address,
   input we, clk
);
   reg [7:0] mem [0:31];
   integer i;

   initial begin
      for (i = 0; i < 32; i = i + 1)
         mem[i] = i[7:0];
   end

   always @ (posedge clk) begin
      if (we)
         mem[write_address] <= d;
      q <= mem[read_address];
   end
endmodule

Intel® Quartus® Prime Pro Edition synthesis和其他综合工具也支持$readmemb$readmemh属性。这些属性支持RAM初始化和ROM初始化在综合和仿真中完全相同。

使用readmemb命令初始化的Verilog HDL RAM

reg [7:0] ram[0:15];
initial 
begin
	$readmemb("ram.txt", ram);
end

在VHDL中,您可以通过对相应信号指定默认值对一个推断存储器的内容进行初始化。 Intel® Quartus® Prime Pro Edition synthesis自动将默认值转换成.mif文件,用于推断的RAM。

包含初始化内容的VHDL RAM

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;

ENTITY ram_with_init IS
    PORT(
            clock: IN STD_LOGIC;
            data: IN UNSIGNED (7 DOWNTO 0);
            write_address: IN integer RANGE 0 to 31;
            read_address: IN integer RANGE 0 to 31;
            we: IN std_logic;
            q: OUT UNSIGNED (7 DOWNTO 0));
END;

ARCHITECTURE rtl OF ram_with_init IS

    TYPE MEM IS ARRAY(31 DOWNTO 0) OF unsigned(7 DOWNTO 0);
    FUNCTION initialize_ram
        return MEM is
        variable result : MEM;
    BEGIN 
        FOR i IN 31 DOWNTO 0 LOOP
            result(i) := to_unsigned(natural(i), natural'(8));
        END LOOP; 
        RETURN result;
    END initialize_ram;

    SIGNAL ram_block : MEM := initialize_ram;
BEGIN
    PROCESS (clock)
    BEGIN
        IF (rising_edge(clock)) THEN
            IF (we = '1') THEN
            ram_block(write_address) <= data;
            END IF;
            q <= ram_block(read_address);
        END IF;
    END PROCESS;
END rtl;