インテル® Quartus® Prime プロ・エディションのユーザーガイド: デザインの推奨事項

ID 683082
日付 8/03/2023
Public
ドキュメント目次

1.4.1.11. 電源投入時の初期のメモリーコンテンツの指定

合成ツールでは、さまざまな方法によって推論メモリーの初期コンテンツを指定します。専用のRAMブロックとMLABメモリーには、電源投入と初期化にわずかな違いがあります。この差は、MLABの連続する読み出しによって生じるものです。

インテルFPGAの専用RAMブロックの出力は起動時は常に0になり、最初の読み出しで初期値に設定されます。例えば、アドレス 0 が事前にFFに初期化されている場合は、RAMブロックの起動時の出力は 0 になります。起動後にアドレス 0 から読み出しを行うと、出力は事前に初期化されている値のFFになります。したがって、RAMが起動し、イネーブル (読み出しイネーブルまたはクロックイネーブル) がLowに保持されている場合は、起動時の出力 0 が最初の有効な読み出しサイクルまで維持されます。合成ツールでは、レジスターを使用してMLABを実装します。このレジスターは起動時に 0 になりますが、電源投入またはリセット時にすぐに初期値に初期化されます。したがって、イネーブルの状態に関係なく初期値が示されます。 インテル® Quartus® Prime開発ソフトウェアは、HDLコードで適切な ramstyle 属性を指定している場合に、推論メモリーをMLABにマッピングします。

Verilog HDLでは、初期ブロックを使用して推論メモリーのコンテンツを初期化することができます。 インテル® Quartus® Prime プロ・エディションの合成では、初期ブロックを自動的に推論RAMのメモリー初期化ファイル (.mif) に変換します。

初期化コンテンツのあるRAM (Verilog HDL)

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

インテル® Quartus® Prime プロ・エディションの合成および他の合成ツールでは、$readmemb および $readmemh 属性もサポートされます。これらの属性により、RAMの初期化とROMの初期化が合成とシミュレーションで同じように動作します。

Verilog HDLにおけるRAMの初期化 (readmembコマンド使用)

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

VHDLでは、推論メモリーのコンテンツの初期化は、対応する信号のデフォルト値を指定することによって行うことができます。 インテル® Quartus® Prime プロ・エディションの合成では、デフォルト値を自動的に推論RAMの .mif ファイルに変換します。

初期化コンテンツのあるRAM (VHDL)

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;