AN 307: Intel® FPGA Design Flow for AMD* Xilinx* Users

ID 683562
Date 4/01/2024
Public
Document Table of Contents

4.2.1.5. Example: Converting Simple Dual-Port RAM

This example includes Verilog HDL and VHDL code for the top level that instantiates the AMD* Xilinx* simple dual-port RAM.

In this example, the top-level entity test instantiates sdp_ram, a AMD* Xilinx* simple dual-port RAM generated through Block Memory Generator, with the following properties:

Table 50.  Properties of Simple Dual-Port RAM
Input data width 16 bits
Memory depth 8 words
Clocking Mode Different input and output clocks
ECC feature Selected
Out data registered status Output registered (one stage pipeline)
Read-during-write WRITE_FIRST (New Data)

The original Verilog HDL Code in the Vivado* Software is:

module test(
		input clka,
		input ena,
		input [0:0]wea,
		input [2:0]addra,
		input [15:0]dina,
		input clkb,
		input enb,
		input [2:0]addrb,
		output [1 5:0]doutb,
		output sbiterr,
		output dbiterr,
		output [2:0]rdaddrecc);
	simple dual port ip i1(
		.clka(clka),
		.ena(ena),
		.wea(wea),
		.addra(addra),
		.dina(dina),
		.clkb(clkb),
		.enb(enb),
		.addrb(addrb),
		.doutb(doutb),
		.sbiterr(sbiterr),
		.dbiterr(dbiterr),
		.rdaddrecc(rdaddrecc));
endmodule

The original VHDL Code in the Vivado* Software is:

LIBRARY ieee;
USE ieee.STD_LOGIC 1164.all; LIBRARY work;
ENTITY test IS
	port (
		clka: IN STD_LOGIC;
		ena: IN STD_LOGIC;
		wea: IN STD_LOGIC_VECTOR(0 DOWNTO 0);
		addra: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		dina: IN STD_LOGIC_VECTOR(15 DOWNTO 0);
		clkb: IN STD_LOGIC;
		enb: IN STD_LOGIC;
		addrb: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
		doutb: OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
		dbiterr: OUT STD_LOGIC;
		sbiterr: OUT STD_LOGIC;
		rdaddrecc: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END test;
ARCHITECTURE arch OF test IS
component simple dual port ip
	PORT(
		clka: IN STD_LOGIC;
		ena: IN STD_LOGIC;
		wea: IN STD_LOGIC_VECTOR(0 DOWNTO 0);
		addra: IN STD_LOGIC VECTOR(2 DOWNTO 0);
		dina: IN STD_LOGIC VECTOR(15 DOWNTO 0);
		clkb: IN STD_LOGIC;
		enb: IN STD_LOGIC;
		addrb: IN STD_LOGIC VECTOR(2 DOWNTO 0);
		doutb: OUT STD_LOGIC VECTOR(15 DOWNTO 0);
		dbiterr: OUT STD_LOGIC;
		sbiterr: OUT STD_LOGIC;
		rdaddrecc: OUT STD_LOGIC vector ( 2 DOWNTO 0)
end component;
BEGIN
	il: simple_dual_port_ip
		PORT MAP(
			clka => clka,
			ena => ena,
			wea => wea,
			addra => addra,
			dina => dina,
			clkb => clkb,
			enb => enb,
			addrb => addrb,
			doutb => doutb,
			dbiterr => dbiterr,
			sbiterr => sbiterr,
			rdaddrecc => rdaddrecc);
END;

To convert a AMD* Xilinx* Simple Dual Port RAM to Intel® FPGA:

  1. Create an Intel® FPGA simple dual-port RAM through the Quartus® Prime software IP Catalog/Parameter Editor.
  2. Configure the RAM with the following options:
    Table 51.  Parameters of Simple Dual-Port RAM
    How will you be using the dual port RAM? Specifies how you use the dual port RAM.
      With one read port and one write port  
    Read/Write Ports Specifies the width of the input and output ports.
      How wide should the 'q_a' output bus be? 16 bits  
      How wide should the 'q_b' output bus be? 16 bits  
    What should the memory type be? Specifies the memory block type. The available memory blocks depend on the target device.
      RAM Block Type M20K  
    What clocking method do you want to use? Specifies the clocking method to use.
      Dual clock: use separate ‘read’ and ‘write’ clock A write clock controls the data-input, write-address, and write-enable registers while the read clock controls the data-output, read-address, and read-enable registers.
    ECC Checking  
      Enable Error Correction Check (ECC) On Specifies whether to enable the ECC feature that corrects single bit errors, double adjacent bit errors, and detects triple adjacent bit errors at the output of the memory
      Enable ECC Pipeline Registers On Specifies whether to enable the ECC pipeline registers before the output decoder to achieve that same performance as non-ECC mode at the expense of one cycle of latency
    Clock Enables Specifies whether to create clock enables for read and write registers.
      Use different clock enables for registers On  
      Use clock enable for write input registers On  
      Use clock enable for output registers On  
  3. Instantiate the new Intel® FPGA RAM. to replace the AMD* Xilinx* RAM.
    The converted Verilog HDL code in the Quartus® Prime Software after instantiating the new RAM:
    module test(
    	input clka,
    	input ena,
    	input [0:0]wea,
    	input [2:0]addra,
    	input [15:0]dina,
    	input clkb,
    	input enb,
    	input [2:0]addrb,
    	output [15:0]doutb,
    	output sbiterr,
    	output dbiterr,
    	output [2:0]rdaddrecc);
    simple_dual_port_ip i1(
    			.wrclock (clka),
    			.wrclocken (ena),
    			.wren (wea),
    			.wraddress (addra),
    			.data (dina),
    			.rdclock (clkb),
    			.rdoutclocken (regceb | enb),
    			.rdaddress (addrb),
    			.q (doutb),
    			.eccstatus ({dbiterr, sbiterr})
    			);
    			endmodule

    The converted VHDL code in the Quartus® Prime Software:

    LIBRARY ieee;
    USE ieee.STD_LOGIC_1164.all; LIBRARY work;
    ENTITY test IS
    		port (
    			clka: IN STD_LOGIC;
    			ena: IN STD_LOGIC;
    			wea: IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    			addra: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
    			dina: IN STD_LOGIC_VECTOR(15 DOWNTO 0);
    			clkb: IN STD_LOGIC;
    			end: IN std_Iogic;
    			addrb: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
    			doutb: OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
    			dbiterr: OUT STD_LOGIC;
    			sbiterr: OUT STD_LOGIC;
    			rdaddrecc: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
    END test,
    ARCHITECTURE arch OF test IS
    component simple_dual_port_ip
    	PORT(
    		wrclock: IN STD_LOGIC;
    		wrclocken: IN STD_LOGIC;
    		wren: IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    		wraddress: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
    		data: IN STD_LOGIC_VECTOR(15 DOWNTO 0);
    		rdclock: IN STD_LOGIC;
    		rdaddress: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
    		q: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    		eccstatus: OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
    		);
    end component;
    signal eccstatus_o: STD_LOGIC_VECTOR(1 DOWNTO 0);
    BEGIN
    	dbiterr <= eccstatus_o(1);
    	sbiterr <= eccstatus_o(0);
    	i1: simple_dual_port_ip
    			PORT MAP(
    				wrclock => clka,
    				wrclocken => ena,
    				wren => wea,
    				wraddress => addra,
    				data => dina,
    				rdclock => clkb,
    				rdaddress => addrb,
    				q => doutb,
    				eccstatus => eccstatus_o);
    END;