/******************************************************************************* * Copyright (c) 2014 Elphel, Inc. * ram_1kx32_1kx32.v is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ram_1kx32_1kx32.v is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ /* Address/data widths Connect unused data to 1b0, unused addresses - to 1'b1 RAMB18E1 in True Dual Port (TDP) Mode - each port individually +-----------+---------+---------+---------+ |Data Width | Address | Data | Parity | +-----------+---------+---------+---------+ | 1 | A[13:0] | D[0] | --- | | 2 | A[13:1] | D[1:0] | --- | | 4 | A[13:2] | D[3:0[ | --- | | 9 | A[13:3] | D[7:0] | DP[0] | | 18 | A[13:4] | D[15:0] | DP[1:0] | +-----------+---------+---------+---------+ RAMB18E1 in Simple Dual Port (SDP) Mode one of the ports (r or w) - 32/36 bits, other - variable +------------+---------+---------+---------+ |Data Widths | Address | Data | Parity | +------------+---------+---------+---------+ | 32/ 1 | A[13:0] | D[0] | --- | | 32/ 2 | A[13:1] | D[1:0] | --- | | 32/ 4 | A[13:2] | D[3:0[ | --- | | 36/ 9 | A[13:3] | D[7:0] | DP[0] | | 36/ 18 | A[13:4] | D[15:0] | DP[1:0] | | 36/ 36 | A[13:5] | D[31:0] | DP[3:0] | +------------+---------+---------+---------+ RAMB36E1 in True Dual Port (TDP) Mode - each port individually +-----------+---------+---------+---------+ |Data Width | Address | Data | Parity | +-----------+---------+---------+---------+ | 1 | A[14:0] | D[0] | --- | | 2 | A[14:1] | D[1:0] | --- | | 4 | A[14:2] | D[3:0[ | --- | | 9 | A[14:3] | D[7:0] | DP[0] | | 18 | A[14:4] | D[15:0] | DP[1:0] | | 36 | A[14:5] | D[31:0] | DP[3:0] | |1(Cascade) | A[15:0] | D[0] | --- | +-----------+---------+---------+---------+ RAMB36E1 in Simple Dual Port (SDP) Mode one of the ports (r or w) - 64/72 bits, other - variable +------------+---------+---------+---------+ |Data Widths | Address | Data | Parity | +------------+---------+---------+---------+ | 64/ 1 | A[14:0] | D[0] | --- | | 64/ 2 | A[14:1] | D[1:0] | --- | | 64/ 4 | A[14:2] | D[3:0[ | --- | | 64/ 9 | A[14:3] | D[7:0] | DP[0] | | 64/ 18 | A[14:4] | D[15:0] | DP[1:0] | | 64/ 36 | A[14:5] | D[31:0] | DP[3:0] | | 64/ 72 | A[14:6] | D[63:0] | DP[7:0] | +------------+---------+---------+---------+ */ module ram_1kx32_1kx32 #( parameter integer REGISTERS = 0 // 1 - registered output ) ( input rclk, // clock for read port input [ 9:0] raddr, // read address input ren, // read port enable input regen, // output register enable output [31:0] data_out, // data out input wclk, // clock for read port input [ 9:0] waddr, // write address input we, // write port enable input [ 3:0] web, // write byte enable input [31:0] data_in // data out ); RAMB36E1 #( .RSTREG_PRIORITY_A("RSTREG"), // Valid: "RSTREG" or "REGCE" .RSTREG_PRIORITY_B("RSTREG"), // Valid: "RSTREG" or "REGCE" .DOA_REG(REGISTERS), // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36) .DOB_REG(REGISTERS), // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36) .RAM_EXTENSION_A("NONE"), // Cascading, valid: "NONE","UPPER", LOWER" .RAM_EXTENSION_B("NONE"), // Cascading, valid: "NONE","UPPER", LOWER" .READ_WIDTH_A(36), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) .READ_WIDTH_B(0), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) .WRITE_WIDTH_A(0), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) .WRITE_WIDTH_B(36), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) .RAM_MODE("TDP"), // Valid "TDP" (true dual-port) and "SDP" - simple dual-port .WRITE_MODE_A("WRITE_FIRST"), // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE" .WRITE_MODE_B("WRITE_FIRST"), // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE" .RDADDR_COLLISION_HWCONFIG("DELAYED_WRITE"),// Valid: "DELAYED_WRITE","PERFORMANCE" (no access to the same page) .SIM_COLLISION_CHECK("ALL"), // Valid: "ALL", "GENERATE_X_ONLY", "NONE", and "WARNING_ONLY" .INIT_FILE("NONE"), // "NONE" or filename with initialization data .SIM_DEVICE("7SERIES"), // Simulation device family - "VIRTEX6", "VIRTEX5" and "7_SERIES" // "7SERIES" .EN_ECC_READ("FALSE"), // Valid:"FALSE","TRUE" (ECC decoder circuitry) .EN_ECC_WRITE("FALSE") // Valid:"FALSE","TRUE" (ECC decoder circuitry) // .INIT_A(36'h0), // Output latches initialization data // .INIT_B(36'h0), // Output latches initialization data // .SRVAL_A(36'h0), // Output latches initialization data (copied at when RSTRAM/RSTREG activated) // .SRVAL_B(36'h0) // Output latches initialization data (copied at when RSTRAM/RSTREG activated) /* parameter IS_CLKARDCLK_INVERTED = 1'b0; parameter IS_CLKBWRCLK_INVERTED = 1'b0; parameter IS_ENARDEN_INVERTED = 1'b0; parameter IS_ENBWREN_INVERTED = 1'b0; parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; parameter IS_RSTRAMB_INVERTED = 1'b0; parameter IS_RSTREGARSTREG_INVERTED = 1'b0; parameter IS_RSTREGB_INVERTED = 1'b0; */ ) RAMB36E1_i ( // Port A (Read port in SDP mode): .DOADO(data_out[31:0]), // Port A data/LSB data[31:0], output .DOPADOP(), // Port A parity/LSB parity[3:0], output .DIADI(32'h0), // Port A data/LSB data[31:0], input .DIPADIP(4'h0), // Port A parity/LSB parity[3:0], input .ADDRARDADDR({1'b1,raddr[9:0],5'b11111}), // Port A (read port in SDP) address [15:0]. used from [14] down, unused should be high, input .CLKARDCLK(rclk), // Port A (read port in SDP) clock, input .ENARDEN(ren), // Port A (read port in SDP) Enable, input .REGCEAREGCE(regen), // Port A (read port in SDP) register enable, input .RSTRAMARSTRAM(1'b0), // Port A (read port in SDP) set/reset, input .RSTREGARSTREG(1'b0), // Port A (read port in SDP) register set/reset, input .WEA(4'b0), // Port A (read port in SDP) Write Enable[3:0], input // Port B .DOBDO(), // Port B data/MSB data[31:0], output .DOPBDOP(), // Port B parity/MSB parity[3:0], output .DIBDI(data_in[31:0]), // Port B data/MSB data[31:0], input .DIPBDIP(4'b0), // Port B parity/MSB parity[3:0], input .ADDRBWRADDR({1'b1,waddr[9:0],5'b11111}), // Port B (write port in SDP) address [15:0]. used from [14] down, unused should be high, input .CLKBWRCLK(wclk), // Port B (write port in SDP) clock, input .ENBWREN(we), // Port B (write port in SDP) Enable, input .REGCEB(1'b0), // Port B (write port in SDP) register enable, input .RSTRAMB(1'b0), // Port B (write port in SDP) set/reset, input .RSTREGB(1'b0), // Port B (write port in SDP) register set/reset, input .WEBWE({4'b0,web[3:0]}), // Port B (write port in SDP) Write Enable[7:0], input // Error correction circuitry .SBITERR(), // Single bit error status, output .DBITERR(), // Double bit error status, output .ECCPARITY(), // Genearted error correction parity [7:0], output .RDADDRECC(), // ECC read address[8:0], output .INJECTSBITERR(1'b0),// inject a single-bit error, input .INJECTDBITERR(1'b0),// inject a double-bit error, input // Cascade signals to create 64Kx1 .CASCADEOUTA(), // A-port cascade, output .CASCADEOUTB(), // B-port cascade, output .CASCADEINA(1'b0), // A-port cascade, input .CASCADEINB(1'b0) // B-port cascade, input ); endmodule