インテルのみ表示可能 — GUID: mwh1409959591173
Ixiasoft
1.4.1.1. 同期メモリーブロックの使用
1.4.1.2. サポートされないリセットおよびコントロール条件の回避
1.4.1.3. Read-During-Write動作の確認
1.4.1.4. RAMの推論と実装の制御
1.4.1.5. シングルクロック同期RAM (古いデータでのRead-During-Write動作)
1.4.1.6. シングルクロック同期RAM (新しいデータでのRead-During-Write動作)
1.4.1.7. シンプル・デュアルポート、デュアルクロック同期RAM
1.4.1.8. トゥルー・デュアルポート同期RAM
1.4.1.9. 混合幅デュアルポートRAM
1.4.1.10. バイト・イネーブル信号を備えるRAM
1.4.1.11. 電源投入時の初期のメモリーコンテンツの指定
インテルのみ表示可能 — GUID: mwh1409959591173
Ixiasoft
1.4.2. HDLコードからのROM機能の推論
合成ツールでは、CASE ステートメントが存在し、CASE ステートメントのすべての選択肢において値が定数に設定されている場合に、ROMを推論します。
小さなROMは一般的に、通常のロジックのレジスターを使用して実装している場合に最高のパフォーマンスを実現するため、それぞれのROM機能では、最小サイズ要件を満たすことで、推論とメモリーへの配置を行う必要があります。
同期RAMブロックを備えるデバイス・アーキテクチャーでROMブロックを推論する場合は、合成でアドレスまたは出力のいずれかにレジスターを使用する必要があります。デザインで出力レジスターを使用している場合、合成ではRAMブロックの入力レジスターからレジスターを実装します。ROMの機能に影響はありません。アドレスをレジスターしている場合は、推論ROMの電源投入時の状態がHDLのデザインと異なることがあります。このシナリオにおいて、 インテル® Quartus® Primeの合成では警告が発行されます。
次のROMの例は、インテルFPGAのメモリー・アーキテクチャーに直接マッピングされます。
Verilog HDL同期ROM
module sync_rom (clock, address, data_out); input clock; input [7:0] address; output reg [5:0] data_out; reg [5:0] data_out; always @ (posedge clock) begin case (address) 8'b00000000: data_out = 6'b101111; 8'b00000001: data_out = 6'b110110; ... 8'b11111110: data_out = 6'b000001; 8'b11111111: data_out = 6'b101010; endcase end endmodule
VHDL同期ROM
LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY sync_rom IS PORT ( clock: IN STD_LOGIC; address: IN STD_LOGIC_VECTOR(7 downto 0); data_out: OUT STD_LOGIC_VECTOR(5 downto 0) ); END sync_rom; ARCHITECTURE rtl OF sync_rom IS BEGIN PROCESS (clock) BEGIN IF rising_edge (clock) THEN CASE address IS WHEN "00000000" => data_out <= "101111"; WHEN "00000001" => data_out <= "110110"; ... WHEN "11111110" => data_out <= "000001"; WHEN "11111111" => data_out <= "101010"; WHEN OTHERS => data_out <= "101111"; END CASE; END IF; END PROCESS; END rtl;
Verilog HDLデュアルポート同期ROM (readmemb使用)
module dual_port_rom #(parameter data_width=8, parameter addr_width=8) ( input [(addr_width-1):0] addr_a, addr_b, input clk, output reg [(data_width-1):0] q_a, q_b ); reg [data_width-1:0] rom[2**addr_width-1:0]; initial // Read the memory contents in the file //dual_port_rom_init.txt. begin $readmemb("dual_port_rom_init.txt", rom); end always @ (posedge clk) begin q_a <= rom[addr_a]; q_b <= rom[addr_b]; end endmodule
VHDLデュアルポート同期ROM (初期化関数使用)
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dual_port_rom is generic ( DATA_WIDTH : natural := 8; ADDR_WIDTH : natural := 8 ); port ( clk : in std_logic; addr_a : in natural range 0 to 2**ADDR_WIDTH - 1; addr_b : in natural range 0 to 2**ADDR_WIDTH - 1; q_a : out std_logic_vector((DATA_WIDTH -1) downto 0); q_b : out std_logic_vector((DATA_WIDTH -1) downto 0) ); end entity; architecture rtl of dual_port_rom is -- Build a 2-D array type for the ROM subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); type memory_t is array(2**ADDR_WIDTH - 1 downto 0) of word_t; function init_rom return memory_t is variable tmp : memory_t := (others => (others => '0')); begin for addr_pos in 0 to 2**ADDR_WIDTH - 1 loop -- Initialize each address with the address itself tmp(addr_pos) := std_logic_vector(to_unsigned(addr_pos, DATA_WIDTH)); end loop; return tmp; end init_rom; -- Declare the ROM signal and specify a default initialization value. signal rom : memory_t := init_rom; begin process(clk) begin if (rising_edge(clk)) then q_a <= rom(addr_a); q_b <= rom(addr_b); end if; end process; end rtl;