Commit bb5c2299 authored by Andrey Filippov's avatar Andrey Filippov

added missing files

parent e79823db
/*******************************************************************************
* Module: fifo_same_clock_fill
* Date:2014-05-20
* Author: Andrey Filippov
* Description: Configurable synchronous FIFO using the same clock for read and write.
* Provides fill level - number of words currently in FIFO
*
* Copyright (c) 2014 Elphel, Inc.
* fifo_same_clock_fill.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.
*
* fifo_same_clock_fill.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 <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
`include "system_defines.vh"
module fifo_same_clock_fill
#(
parameter integer DATA_WIDTH=16,
parameter integer DATA_DEPTH=4
)
(
input rst, // reset, active high
input clk, // clock - positive edge
input sync_rst, // synchronously reset fifo;
input we, // write enable
input re, // read enable
input [DATA_WIDTH-1:0] data_in, // input data
output [DATA_WIDTH-1:0] data_out, // output data
output nempty, // FIFO has some data
output reg half_full, // FIFO half full
output reg under, // debug outputs - under - attempt to read from empty
output reg over, // overwritten
output reg [DATA_DEPTH-1:0] wcount,
output reg [DATA_DEPTH-1:0] rcount,
output [DATA_DEPTH: 0] num_in_fifo
);
localparam integer DATA_2DEPTH=(1<<DATA_DEPTH)-1;
//ISExst: FF/Latch ddrc_test01.axibram_write_i.waddr_i.fill[4] has a constant value of 0 in block <ddrc_test01>. This FF/Latch will be trimmed during the optimization process.
//ISExst: FF/Latch ddrc_test01.axibram_read_i.raddr_i.fill[4] has a constant value of 0 in block <ddrc_test01>. This FF/Latch will be trimmed during the optimization process.
//ISExst: FF/Latch ddrc_test01.axibram_write_i.wdata_i.fill[4] has a constant value of 0 in block <ddrc_test01>. This FF/Latch will be trimmed during the optimization process.
// Do not understand - why?
reg [DATA_DEPTH: 0] fill=0; // RAM fill
reg [DATA_WIDTH-1:0] inreg;
reg [DATA_WIDTH-1:0] outreg;
reg [DATA_DEPTH-1:0] ra;
reg [DATA_DEPTH-1:0] wa;
wire [DATA_DEPTH:0] next_fill;
reg wem;
wire rem;
reg out_full=0; //output register full
reg [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH];
reg ram_nempty;
assign next_fill = fill[DATA_DEPTH:0]+((wem && ~rem)?1:((~wem && rem && ram_nempty)?-1:0));
assign rem= ram_nempty && (re || !out_full);
assign data_out=outreg;
assign nempty=out_full;
assign num_in_fifo=fill[DATA_DEPTH:0];
always @ (posedge clk or posedge rst) begin
if (rst) fill <= 0;
else if (sync_rst) fill <= 0;
else fill <= next_fill;
if (rst) wem <= 0;
else if (sync_rst) wem <= 0;
else wem <= we;
if (rst) ram_nempty <= 0;
else if (sync_rst) ram_nempty <= 0;
else ram_nempty <= (next_fill != 0);
if (rst) wa <= 0;
else if (sync_rst) wa <= 0;
else if (wem) wa <= wa+1;
if (rst) ra <= 0;
else if (sync_rst) ra <= 0;
else if (rem) ra <= ra+1;
else if (!ram_nempty) ra <= wa; // Just recover from bit errors
if (rst) out_full <= 0;
else if (sync_rst) out_full <= 0;
else if (rem && ~re) out_full <= 1;
else if (re && ~rem) out_full <= 0;
if (rst) wcount <= 0;
else if (sync_rst) wcount <= 0;
else if (we) wcount <= wcount + 1;
if (rst) rcount <= 0;
else if (sync_rst) rcount <= 0;
else if (re) rcount <= rcount + 1;
end
// no reset elements
always @ (posedge clk) begin
half_full <=(fill & (1<<(DATA_DEPTH-1)))!=0;
if (wem) ram[wa] <= inreg;
if (we) inreg <= data_in;
if (rem) outreg <= ram[ra];
under <= ~we & re & ~nempty; // underrun error
over <= we & ~re & (fill == (1<< (DATA_DEPTH-1))); // overrun error
end
endmodule
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* Dual port memory wrapper, with variable width write and variable width read
* using "SDP" mode of RAMB36E1
* ram_var_w_var_r.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_var_w_var_r.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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
/*
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_var_w_var_r
#(
parameter integer REGISTERS = 0, // 1 - registered output
parameter integer LOG2WIDTH_WR = 6, // WIDTH= 1 << LOG2WIDTH
parameter integer LOG2WIDTH_RD = 6 // WIDTH= 1 << LOG2WIDTH
)
(
input rclk, // clock for read port
// input [ 9:0] raddr, // read address
input [14-LOG2WIDTH_RD:0] raddr, // read address
input ren, // read port enable
input regen, // output register enable
output [(1 << LOG2WIDTH_RD)-1:0] data_out, // data out
input wclk, // clock for read port
input [14-LOG2WIDTH_WR:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [(1 << LOG2WIDTH_WR)-1:0] data_in // data out
);
generate
if ((LOG2WIDTH_WR == 6) && (LOG2WIDTH_RD == 6))
ram_64w_64r #(
.REGISTERS (REGISTERS)
) ram_i (
.rclk (rclk), // input
.raddr (raddr), // input[8:0]
.ren (ren), // input
.regen (regen), // input
.data_out (data_out), // output[63:0]
.wclk (wclk), // input
.waddr (waddr), // input[8:0]
.we (we), // input
.web (web), // input[7:0]
.data_in (data_in) // input[63:0]
);
else if ((LOG2WIDTH_WR == 6) && (LOG2WIDTH_RD < 6))
ram_64w_lt64r #(
.REGISTERS (REGISTERS),
.LOG2WIDTH_RD (LOG2WIDTH_RD)
) ram_i (
.rclk (rclk), // input
.raddr (raddr), // input[(>8):0]
.ren (ren), // input
.regen (regen), // input
.data_out (data_out), // output[(<32):0]
.wclk (wclk), // input
.waddr (waddr), // input[8:0]
.we (we), // input
.web (web), // input[7:0]
.data_in (data_in) // input[63:0]
);
else if ((LOG2WIDTH_WR < 6) && (LOG2WIDTH_RD == 6))
ram_lt64w_64r #(
.REGISTERS (REGISTERS),
.LOG2WIDTH_WR (LOG2WIDTH_WR)
) ram_i (
.rclk (rclk), // input
.raddr (raddr), // input[8:0]
.ren (ren), // input
.regen (regen), // input
.data_out (data_out), // output[63:0]
.wclk (wclk), // input
.waddr (waddr), // input[(>8):0]
.we (we), // input
.web (web), // input[7:0]
.data_in (data_in) // input[(<32):0]
);
else if ((LOG2WIDTH_WR < 6) && (LOG2WIDTH_RD < 6))
ram_lt64w_lt64r #(
.REGISTERS (REGISTERS),
.LOG2WIDTH_WR (LOG2WIDTH_WR),
.LOG2WIDTH_RD (LOG2WIDTH_RD)
) ram_i (
.rclk (rclk), // input
.raddr (raddr), // input[(>8):0]
.ren (ren), // input
.regen (regen), // input
.data_out (data_out), // output[(<32):0]
.wclk (wclk), // input
.waddr (waddr), // input[(>8):0]
.we (we), // input
.web (web), // input[7:0]
.data_in (data_in) // input[(<32):0]
);
endgenerate
endmodule
// Both ports with 64 bit widths
module ram_64w_64r
#(
parameter integer REGISTERS = 0 // 1 - registered output
)
(
input rclk, // clock for read port
input [8:0] raddr, // read address
input ren, // read port enable
input regen, // output register enable
output [63:0] data_out, // data out
input wclk, // clock for read port
input [ 8:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [63:0] data_in // data out
);
localparam PWIDTH_WR=72;
localparam PWIDTH_RD=72;
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 (PWIDTH_RD), // 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 (PWIDTH_WR), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.RAM_MODE ("SDP"), // 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)
) 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 (data_in[31:0]), // Port A data/LSB data[31:0], input
.DIPADIP (4'h0), // Port A parity/LSB parity[3:0], input
.ADDRARDADDR ({1'b1,raddr[8:0],6'b111111}), // 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 (data_out[63:32]),// Port B data/MSB data[31:0], output
.DOPBDOP (), // Port B parity/MSB parity[3:0], output
.DIBDI (data_in[63:32]), // Port B data/MSB data[31:0], input
.DIPBDIP (4'b0), // Port B parity/MSB parity[3:0], input
.ADDRBWRADDR ({1'b1,waddr[8:0],6'b111111}), // 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 (web), // 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
// Both ports with less than 64 bit widths
module ram_lt64w_lt64r
#(
parameter integer REGISTERS = 0, // 1 - registered output
parameter integer LOG2WIDTH_WR = 5, // WIDTH= 1 << LOG2WIDTH
parameter integer LOG2WIDTH_RD = 5 // WIDTH= 1 << LOG2WIDTH
)
(
input rclk, // clock for read port
// input [ 9:0] raddr, // read address
input [14-LOG2WIDTH_RD:0] raddr, // read address
input ren, // read port enable
input regen, // output register enable
output [(1 << LOG2WIDTH_RD)-1:0] data_out, // data out
input wclk, // clock for read port
input [14-LOG2WIDTH_WR:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [(1 << LOG2WIDTH_WR)-1:0] data_in // data out
);
localparam PWIDTH_WR = (LOG2WIDTH_WR > 2)? (9 << (LOG2WIDTH_WR - 3)): (1 << LOG2WIDTH_WR);
localparam PWIDTH_RD = (LOG2WIDTH_RD > 2)? (9 << (LOG2WIDTH_RD - 3)): (1 << LOG2WIDTH_RD);
localparam WIDTH_WR = 1 << LOG2WIDTH_WR;
localparam WIDTH_RD = 1 << LOG2WIDTH_RD;
wire [31:0] data_out32;
wire [WIDTH_WR+31:0] data_in_ext = {32'b0,data_in};
wire [31:0] data_in32=data_in_ext[31:0];
assign data_out=data_out32[WIDTH_RD-1:0];
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 (PWIDTH_RD), // 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 (PWIDTH_WR), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.RAM_MODE ("SDP"), // 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_out32), // 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,{LOG2WIDTH_RD{1'b1}}}), // 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_in32), // Port B data/MSB data[31:0], input
.DIPBDIP (4'b0), // Port B parity/MSB parity[3:0], input
.ADDRBWRADDR ({1'b1,waddr,{LOG2WIDTH_WR{1'b1}}}), // 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 (web[7: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
// Write port less than 64bits, read port 64 bit widths
module ram_lt64w_64r
#(
parameter integer REGISTERS = 0, // 1 - registered output
parameter integer LOG2WIDTH_WR = 5 // WIDTH= 1 << LOG2WIDTH
)
(
input rclk, // clock for read port
// input [ 9:0] raddr, // read address
input [8:0] raddr, // read address
input ren, // read port enable
input regen, // output register enable
output [63:0] data_out, // data out
input wclk, // clock for read port
input [14-LOG2WIDTH_WR:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [(1 << LOG2WIDTH_WR)-1:0] data_in // data out
);
localparam PWIDTH_WR = (LOG2WIDTH_WR > 2)? (9 << (LOG2WIDTH_WR - 3)): (1 << LOG2WIDTH_WR);
localparam PWIDTH_RD = 72;
localparam WIDTH_WR = 1 << LOG2WIDTH_WR;
// localparam WIDTH_RD = 64;
wire [WIDTH_WR+31:0] data_in_ext = {32'b0,data_in};
wire [31:0] data_in32=data_in_ext[31:0];
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 (PWIDTH_RD), // 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 (PWIDTH_WR), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.RAM_MODE ("SDP"), // 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)
) 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[8:0],6'b111111}), // 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 (data_out[63:32]), // Port B data/MSB data[31:0], output
.DOPBDOP (), // Port B parity/MSB parity[3:0], output
.DIBDI (data_in32), // Port B data/MSB data[31:0], input
.DIPBDIP (4'b0), // Port B parity/MSB parity[3:0], input
.ADDRBWRADDR ({1'b1,waddr,{LOG2WIDTH_WR{1'b1}}}), // 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 (web[7: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
// Write port 64 bita, read port - less than 64 bits
module ram_64w_lt64r
#(
parameter integer REGISTERS = 0, // 1 - registered output
// parameter integer LOG2WIDTH_WR = 5, // WIDTH= 1 << LOG2WIDTH
parameter integer LOG2WIDTH_RD = 5 // WIDTH= 1 << LOG2WIDTH
)
(
input rclk, // clock for read port
// input [ 9:0] raddr, // read address
input [14-LOG2WIDTH_RD:0] raddr, // read address
input ren, // read port enable
input regen, // output register enable
output [(1 << LOG2WIDTH_RD)-1:0] data_out, // data out
input wclk, // clock for read port
input [8:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [63:0] data_in // data out
);
localparam PWIDTH_WR = 72;
localparam PWIDTH_RD = (LOG2WIDTH_RD > 2)? (9 << (LOG2WIDTH_RD - 3)): (1 << LOG2WIDTH_RD);
localparam WIDTH_RD = 1 << LOG2WIDTH_RD;
wire [31:0] data_out32;
assign data_out=data_out32[WIDTH_RD-1:0];
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 (PWIDTH_RD), // 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 (PWIDTH_WR), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.RAM_MODE ("SDP"), // 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)
) RAMB36E1_i
(
// Port A (Read port in SDP mode):
.DOADO (data_out32), // Port A data/LSB data[31:0], output
.DOPADOP (), // Port A parity/LSB parity[3:0], output
.DIADI (data_in[31:0]), // Port A data/LSB data[31:0], input
.DIPADIP (4'h0), // Port A parity/LSB parity[3:0], input
.ADDRARDADDR ({1'b1,raddr,{LOG2WIDTH_RD{1'b1}}}), // 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[63:32]), // Port B data/MSB data[31:0], input
.DIPBDIP (4'b0), // Port B parity/MSB parity[3:0], input
.ADDRBWRADDR({1'b1,waddr[8:0],6'b111111}), // 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 (web[7: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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment