In-depth analysis of block ram resources and primitive RAMB18E1 inside 7 series FPGA

I am based on my original articles: The first article – Xilinx block memory generator user manual pg058 translation and learning (24), mainly introduces Selectable Memory Algorithm; the second article – Xilinx block memory generator user manual pg058 Translation and Learning (25), mainly introduces Table 3-1: Memory Primitives Used Based on Architecture (Supported in Native BMG), extended, rumination and review.

Combined with an article found on csdn: FPGA-7 series FPGA internal structure value Memory Resources-01-block RAM resources (author Vuko-wxh), re-understand the two resource modules/primitives of blockram: 36kb and 18kb. (This article is about block ram)

Articles found by extension: The author of csdn talks about the distributed RAM of XILINX FPGA CLB unit (Distributed RAM Available in SLICEM Only, RAM128X1D, Verilog primitive description) through the vicissitudes of life. This article is about distributed ram, that is, distributed ram, It is easy to understand how primitives are used here. The commonly used ram primitive here is RAM32X1S, which is smaller than the RAMB18E1 example below)

ug473 Chapter 1 Block ram resources inside 7 series FPGA
There are two types of block ram resource modules: 36kb and 18kb (How much are the total block RAM resources? K7325T has a total of 16M bit Block RAM)
Each 36kb can be configured into simple dual-port mode such as 4kx9 2kx18
Each 18kb can be configured into simple dual-port mode such as 2kx9 1kx18
Is the primitive RAMB18E1 used directly? What are the similarities and differences with the graphical wizard to generate IP?

Block RAM library primitives
The block RAM library primitives RAMB18E1 and RAMB36E1 for 7 Series FPGAs are the basic building blocks for all block RAM configurations. Other block RAM primitives and macros are based on these primitives. Some Block RAM properties can only be configured using one of these primitives (e.g., pipeline registers, cascade). See Block RAM Properties section.

The input and output data buses are represented by two buses configured in 9-bit width (8 + 1), 18-bit width (16 + 2), and 36-bit width (32 + 4). The ninth bit associated with each byte can store parity/error correction bits or be used as additional data bits. Bit 9 performs no specific function. A separate bus for parity bits is helpful in some designs. However, other designs safely use 9-bit, 18-bit, or 36-bit buses by merging the regular data bus with the parity bus. Read/write and store operations are identical for all bits, including the parity bit.
picture

Attached, the code of the primitive RAMB18E1 itself:
K7 verilog version

/ RAMB18E1: In order to incorporate this function into the design,

// Verilog: the following instance declaration needs to be placed

// instance : in the body of the design code. The instance name

// declaration : (RAMB18E1_inst) and/or the port declarations within the

// code: parenthesis may be changed to properly reference and

// : connect this function to the design. All inputs

// : and outputs must be connected.

// <-----Cut code below this line---->

// RAMB18E1: 18K-bit Configurable Synchronous Block RAM

// Kintex-7

// Xilinx HDL Language Template, version 2017.4

RAMB18E1 #(

// Address Collision Mode: "PERFORMANCE" or "DELAYED_WRITE"

.RDADDR_COLLISION_HWCONFIG("DELAYED_WRITE"),

// Collision check: Values ("ALL", "WARNING_ONLY", "GENERATE_X_ONLY" or "NONE")

.SIM_COLLISION_CHECK("ALL"),

// DOA_REG, DOB_REG: Optional output register (0 or 1)

.DOA_REG(0),

.DOB_REG(0),

// INITP_00 to INITP_07: Initial contents of parity memory array

.INITP_00(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_01(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INITP_03(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_04(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_05(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_06(256'h000000000000000000000000000000000000000000000000000000000000000),

.INITP_07(256'h000000000000000000000000000000000000000000000000000000000000000),

// INIT_00 to INIT_3F: Initial contents of data memory array

.INIT_00(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_0A(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_0B(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_0F(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_14(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_15(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_16(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_1A(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_1B(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_27(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_2B(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_2C(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_2F(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_31(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_37(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_38(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_3A(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_3C(256'h000000000000000000000000000000000000000000000000000000000000000),

.INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),

.INIT_3F(256'h000000000000000000000000000000000000000000000000000000000000000),

// INIT_A, INIT_B: Initial values on output ports

.INIT_A(18'h00000),

.INIT_B(18'h00000),

// Initialization File: RAM initialization file

.INIT_FILE("NONE"),

// RAM Mode: "SDP" or "TDP"

.RAM_MODE("TDP"),

// READ_WIDTH_A/B, WRITE_WIDTH_A/B: Read/write width per port

.READ_WIDTH_A(0), // 0-72

.READ_WIDTH_B(0), // 0-18

 .WRITE_WIDTH_A(0), // 0-18

.WRITE_WIDTH_B(0), // 0-72

// RSTREG_PRIORITY_A, RSTREG_PRIORITY_B: Reset or enable priority ("RSTREG" or "REGCE")

.RSTREG_PRIORITY_A("RSTREG"),

.RSTREG_PRIORITY_B("RSTREG"),

// SRVAL_A, SRVAL_B: Set/reset value for output

.SRVAL_A(18'h00000),

.SRVAL_B(18'h00000),

// Simulation Device: Must be set to "7SERIES" for simulation behavior

.SIM_DEVICE("7SERIES"),

// WriteMode: Value on output upon a write ("WRITE_FIRST", "READ_FIRST", or "NO_CHANGE")

.WRITE_MODE_A("WRITE_FIRST"),

.WRITE_MODE_B("WRITE_FIRST")

)

RAMB18E1_inst (

// Port A Data: 16-bit (each) output: Port A data

.DOADO(DOADO), // 16-bit output: A port data/LSB data

.DOPADOP(DOPADOP), // 2-bit output: A port parity/LSB parity

// Port B Data: 16-bit (each) output: Port B data

.DOBDO(DOBDO), // 16-bit output: B port data/MSB data

.DOPBDOP(DOPBDOP), // 2-bit output: B port parity/MSB parity

// Port A Address/Control Signals: 14-bit (each) input: Port A address and control signals (read port

// when RAM_MODE="SDP")

.ADDRARDADDR(ADDRARDADDR), // 14-bit input: A port address/Read address

.CLKARDCLK(CLKARDCLK), // 1-bit input: A port clock/Read clock

.ENARDEN(ENARDEN), // 1-bit input: A port enable/Read enable

.REGCEAREGCE(REGCEAREGCE), // 1-bit input: A port register enable/Register enable

.RSTRAMARSTRAM(RSTRAMARSTRAM), // 1-bit input: A port set/reset

.RSTREGARSTREG(RSTREGARSTREG), // 1-bit input: A port register set/reset

.WEA(WEA), // 2-bit input: A port write enable

// Port A Data: 16-bit (each) input: Port A data

.DIADI(DIADI), // 16-bit input: A port data/LSB data

.DIPADIP(DIPADIP), // 2-bit input: A port parity/LSB parity

// Port B Address/Control Signals: 14-bit (each) input: Port B address and control signals (write port

// when RAM_MODE="SDP")

.ADDRBWRADDR(ADDRBWRADDR), // 14-bit input: B port address/Write address

  .CLKBWRCLK(CLKBWRCLK), // 1-bit input: B port clock/Write clock

.ENBWREN(ENBWREN), // 1-bit input: B port enable/Write enable

.REGCEB(REGCEB), // 1-bit input: B port register enable

.RSTRAMB(RSTRAMB), // 1-bit input: B port set/reset

.RSTREGB(RSTREGB), // 1-bit input: B port register set/reset

.WEBWE(WEBWE), // 4-bit input: B port write enable/Write enable

// Port B Data: 16-bit (each) input: Port B data

.DIBDI(DIBDI), // 16-bit input: B port data/MSB data

.DIPBDIP(DIPBDIP) // 2-bit input: B port parity/MSB parity

);

// End of RAMB18E1_inst instantiation