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

ID 683082
日付 4/13/2020
Public

このドキュメントの新しいバージョンが利用できます。お客様は次のことを行ってください。 こちらをクリック 最新バージョンに移行する。

ドキュメント目次

1.4.1.6. 新しいデータのRead-During-Write動作を備えたシングルクロック同期RAM

このセクションの例では、書き込み中のリード動作がメモリーアドレスに書き込まれている新しい値を返すRAMブロックについて説明します。

この動作をターゲットデバイスに実装するために、合成ツールはRAMブロックの周りにバイパスロジックを追加します。このバイパスロジックにより、デザインの領域使用率が増加し、RAMブロックがデザインのクリティカルパスの一部である場合、パフォーマンスが低下します。シングル・ポート・モード(同じクロック、同じリードアドレス、同じ書き込みアドレス)でデバイスメモリーが書き込み中の新しいデータリード動作をサポートする場合、Verilogメモリーブロックはバイパスロジックを必要としません。ターゲットデバイスの仕様については、該当するデバイス・ハンドブックを参照してください。

次の例では、ライトにブロック割り当てを使用して、データが中間的に割り当てられるようにします。

Verilog HDL Single-Clock, Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior

module single_clock_wr_ram(
    output reg [7:0] q,
    input [7:0] d,
    input [6:0] write_address, read_address,
    input we, clk
);
    reg [7:0] mem [127:0];

    always @ (posedge clk) begin
        if (we)
            mem[write_address] = d;
        q = mem[read_address]; // q does get d in this clock 
                               // cycle if we is high
    end
endmodule

VHDL Single-Clock, Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY single_clock_ram IS
    PORT (
        clock: IN STD_LOGIC;
        data: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
        write_address: IN INTEGER RANGE 0 to 31;
        read_address: IN INTEGER RANGE 0 to 31;
        we: IN STD_LOGIC;
        q: OUT STD_LOGIC_VECTOR (2 DOWNTO 0)
    );
END single_clock_ram;

ARCHITECTURE rtl OF single_clock_ram IS
    TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
    
BEGIN
    PROCESS (clock)
    VARIABLE ram_block: MEM;
    BEGIN
        IF (rising_edge(clock)) THEN
            IF (we = '1') THEN
                ram_block(write_address) := data;
            END IF;
            q <= ram_block(read_address); 
            -- VHDL semantics imply that q doesn't get data 
            -- in this clock cycle
        END IF;
    END PROCESS;
END rtl;

assignステートメントを使用してmemのアドレスをリード、出力qを作成することにより、単一クロックRAMを作成することができます。 RTLは、それ自体で、新しいデータのread-during-writeを記述します。ただし、RAM出力が別の階層のレジスターに入力される場合、read-during-writeを使用すると古いデータが発生します。合成ツールは、メモリーがハード階層パーティションの境界に供給する場合など、どの動作が記述されているかをツールが判断できない場合、RAMブロックを推測しない場合があります。このタイプのRTLを避けてください。

Avoid Verilog Coding Style with Vague read-during-write Behavior

reg [7:0] mem [127:0];
reg [6:0] read_address_reg;

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

Avoid VHDL Coding Style with Vague read-during-write Behavior

次の例では、同時信号割り当てを使用してRAMからリード、同様の動作を示しています。

ARCHITECTURE rtl OF single_clock_rw_ram IS
	TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL ram_block: MEM;
	SIGNAL read_address_reg: INTEGER RANGE 0 to 31;
BEGIN
	PROCESS (clock)
	BEGIN
		IF (rising_edge(clock)) THEN
			IF (we = '1') THEN
				ram_block(write_address) <= data;
			END IF;
			read_address_reg <= read_address;
		END IF;
	END PROCESS;
	q <= ram_block(read_address_reg);
END rtl;