Commit d6733779 authored by Andrey Filippov's avatar Andrey Filippov

just a snapshot

parent c7b65d94
......@@ -111,10 +111,12 @@ generate
.rst(rst),
.dci_disable(dci_disable_dq_r), // disable DCI termination during writes and idle
.dly_data(dly_data_r), // delay value (3 LSB - fine delay)
.din(din_r[4*i+3:4*i]) , // parallel data to be sent out
.din({din_r[i+24],din_r[i+16],din_r[i+8],din_r[i]}) , // parallel data to be sent out
// .din(din_r[4*i+3:4*i]) , // parallel data to be sent out
// .din(din_r[4*i+3-:4]) , // parallel data to be sent out
.tin(tin_dq_r), // tristate for data out (sent out earlier than data!)
.dout(dout[4*i+3:4*i]), // parallel data received from DDR3 memory
.dout({dout[i+24],dout[i+16],dout[i+8],dout[i]}), // parallel data received from DDR3 memory
// .dout(dout[4*i+3:4*i]), // parallel data received from DDR3 memory
.set_odelay(set_r), // clk_div synchronous load odelay value from dly_data
.ld_odelay(ld_odly[i]), // clk_div synchronous set odealy value from loaded
.set_idelay(set_r), // clk_div synchronous load idelay value from dly_data
......
......@@ -49,7 +49,7 @@ module cmd_addr #(
input in_tri, // tristate command/address outputs - same timing, but no odelay
input [7:0] dly_data, // delay value (3 LSB - fine delay)
input [4:0] dly_addr, // select which delay to program
input ld_delay, // load delay data to selected iodelayl (clk_iv synchronous)
input ld_delay, // load delay data to selected iodelayl (clk_div synchronous)
input set // clk_div synchronous set all delays from previously loaded values
);
reg [2*ADDRESS_NUMBER-1:0] in_a_r=0;
......@@ -110,7 +110,7 @@ generate
.clk_div(clk_div), // free-running half clk frequency, front aligned to clk (shared for R/W)
.rst(rst),
.dly_data(dly_data_r[7:0]), // delay value (3 LSB - fine delay)
.din(in_a_r[2*i+1:2*i]), // parallel data to be sent out
.din({in_a_r[ADDRESS_NUMBER+i],in_a_r[i]}), // parallel data to be sent out
// .tin(in_tri_r[1:0]), // tristate for data out (sent out earlier than data!)
.tin(in_tri_r), // tristate for data out (sent out earlier than data!)
.set_delay(set_r), // clk_div synchronous load odelay value from dly_data
......@@ -132,7 +132,7 @@ endgenerate
.clk_div(clk_div),
.rst(rst),
.dly_data(dly_data_r[7:0]),
.din(in_ba_r[1:0]),
.din({in_ba_r[3],in_ba_r[0]}),
// .tin(in_tri_r[1:0]),
.tin(in_tri_r),
.set_delay(set_r),
......@@ -150,7 +150,7 @@ endgenerate
.clk_div(clk_div),
.rst(rst),
.dly_data(dly_data_r[7:0]),
.din(in_ba_r[3:2]),
.din({in_ba_r[4],in_ba_r[1]}),
// .tin(in_tri_r[1:0]),
.tin(in_tri_r),
.set_delay(set_r),
......@@ -168,7 +168,7 @@ endgenerate
.clk_div(clk_div),
.rst(rst),
.dly_data(dly_data_r[7:0]),
.din(in_ba_r[5:4]),
.din({in_ba_r[5],in_ba_r[2]}),
// .tin(in_tri_r[1:0]),
.tin(in_tri_r),
.set_delay(set_r),
......
/*******************************************************************************
* Module: ddr3c16
* Date:2014-05-16
* Author: Andrey Filippov
* Description: ddr3 controller, 16 channel
*
* Copyright (c) 2014 Elphel, Inc.
* ddr3c16.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.
*
* ddr3c16.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
module ddr3c16 #(
parameter PHASE_WIDTH = 8,
parameter SLEW_DQ = "SLOW",
parameter SLEW_DQS = "SLOW",
parameter SLEW_CMDA = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter IBUF_LOW_PWR = "TRUE",
parameter real REFCLK_FREQUENCY = 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 10, //ns >1.25, 600<Fvco<1200
parameter CLKFBOUT_MULT = 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter CLKFBOUT_MULT_REF = 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter CLKFBOUT_DIV_REF = 3, // To get 300MHz for the reference clock
parameter DIVCLK_DIVIDE= 1,
parameter CLKFBOUT_PHASE = 0.000,
parameter ICLK_PHASE = 0.000,
parameter CLK_PHASE = 0.000,
parameter CLK_DIV_PHASE = 0.000,
parameter MCLK_PHASE = 90.000,
parameter REF_JITTER1 = 0.010,
parameter SS_EN = "FALSE",
parameter SS_MODE = "CENTER_HIGH",
parameter SS_MOD_PERIOD = 10000,
parameter DQSTRI_FIRST= 4'h3, // DQS tri-state control word, first when enabling output
parameter DQSTRI_LAST= 4'hc, // DQS tri-state control word, first after disabling output
parameter DQTRI_FIRST= 4'h7, // DQ tri-state control word, first when enabling output
parameter DQTRI_LAST= 4'he // DQ tri-state control word, first after disabling output
)(
// DDR3 interface
output SDCLK, // DDR3 clock differential output, positive
output SDNCLK,// DDR3 clock differential output, negative
output [ADDRESS_NUMBER-1:0] SDA, // output address ports (14:0) for 4Gb device
output [2:0] SDBA, // output bank address ports
output SDWE, // output WE port
output SDRAS, // output RAS port
output SDCAS, // output CAS port
output SDCKE, // output Clock Enable port
output SDODT, // output ODT port
inout [15:0] SDD, // DQ I/O pads
inout SDDML, // LDM I/O pad (actually only output)
inout DQSL, // LDQS I/O pad
inout NDQSL, // ~LDQS I/O pad
inout SDDMU, // UDM I/O pad (actually only output)
inout DQSU, // UDQS I/O pad
inout NDQSU, // ~UDQS I/O pad
// clocks, reset
input clk_in,
input rst_in,
output mclk, // global clock, half DDR3 clock, synchronizes all I/O thorough the command port
// command port 0 (filled by software - 32w->64r) - used for mode set, refresh, write levelling, ...
input cmd0_we,
input [9:0] cmd0_addr,
input [31:0] cmd0_data,
// TODO: add automatic command port1 , filled by the PL, 36w 36r, used for actual page R/W
input cmd1_we,
input [9:0] cmd1_addr,
input [35:0] cmd1_data,
// Controller run interface, posedge mclk
input [10:0] run_addr, // controller sequencer start address (0..11'h1ff - cmd0, 11'h400..11'h7ff - cmd1)
input [3:0] run_chn, // data channel to use
input run_seq, // start controller sequence
output run_done, // controller sequence finished
// inteface to control I/O delays and mmcm
input [7:0] dly_data, // delay value (3 LSB - fine delay)
input [6:0] dly_addr, // select which delay to program
input ld_delay, // load delay data to selected iodelayl (clk_div synchronous)
input set, // clk_div synchronous set all delays from previously loaded values
output locked,
output ps_rdy,
output [PHASE_WIDTH-1:0] ps_out,
// read port 0
input port0_clk,
input port0_re,
input port0_regen,
input [1:0] port0_page,
input [1:0] port0_int_page,
input [7:0] port0_addr,
output [31:0] port0_data,
// write port 1
input port1_clk,
input port1_we,
input [1:0] port1_page,
input [1:0] port1_int_page,
input [7:0] port1_addr,
input [31:0] port1_data,
// extras
input cmda_tri, // tristate command and address lines // not likely to be used
input inv_clk_div,
input [7:0] dqs_pattern, // 8'h55
input [7:0] dqm_pattern // 8'h00
);
localparam ADDRESS_NUMBER = 15;
wire [35:0] phy_cmd; // input[35:0]
wire [6:0] buf_addr; // output[6:0]
wire [63:0] buf_wdata; // output[63:0]
wire [63:0] buf_rdata; // input[63:0]
wire buf_wr; // output
wire buf_rd; // output
phy_cmd #(
.ADDRESS_NUMBER (ADDRESS_NUMBER),
.PHASE_WIDTH (PHASE_WIDTH),
.SLEW_DQ (SLEW_DQ),
.SLEW_DQS (SLEW_DQS),
.SLEW_CMDA (SLEW_CMDA),
.SLEW_CLK (SLEW_CLK),
.IBUF_LOW_PWR (IBUF_LOW_PWR),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.CLKIN_PERIOD (CLKIN_PERIOD),
.CLKFBOUT_MULT (CLKFBOUT_MULT),
.CLKFBOUT_MULT_REF (CLKFBOUT_MULT_REF),
.CLKFBOUT_DIV_REF (CLKFBOUT_DIV_REF),
.DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.ICLK_PHASE (ICLK_PHASE),
.CLK_PHASE (CLK_PHASE),
.CLK_DIV_PHASE (CLK_DIV_PHASE),
.MCLK_PHASE (MCLK_PHASE),
.REF_JITTER1 (REF_JITTER1),
.SS_EN (SS_EN),
.SS_MODE (SS_MODE),
.SS_MOD_PERIOD (SS_MOD_PERIOD)
) phy_cmd_i (
.SDCLK (SDCLK), // output
.SDNCLK (SDNCLK), // output
.SDA (SDA[ADDRESS_NUMBER-1:0]), // output[14:0]
.SDBA (SDBA[2:0]), // output[2:0]
.SDWE (SDWE), // output
.SDRAS (SDRAS), // output
.SDCAS (SDCAS), // output
.SDCKE (SDCKE), // output
.SDODT (SDODT), // output
.SDD (SDD[15:0]), // inout[15:0]
.SDDML (SDDML), // inout
.DQSL (DQSL), // inout
.NDQSL (NDQSL), // inout
.SDDMU (SDDMU), // inout
.DQSU (DQSU), // inout
.NDQSU (NDQSU), // inout
.clk_in (clk_in), // input
.rst_in (rst_in), // input
.mclk (mclk), // output
.dly_data (dly_data[7:0]), // input[7:0]
.dly_addr (dly_addr[6:0]), // input[6:0]
.ld_delay (ld_delay), // input
.set (set), // input
.locked (locked), // output
.ps_rdy (ps_rdy), // output
.ps_out (ps_out[7:0]), // output[7:0]
.phy_cmd (phy_cmd[35:0]), // input[35:0]
.buf_addr (buf_addr[6:0]), // output[6:0]
.buf_wdata (buf_wdata[63:0]), // output[63:0]
.buf_rdata (buf_rdata[63:0]), // input[63:0]
.buf_wr (buf_wr), // output
.buf_rd (buf_rd), // output
.cmda_tri (cmda_tri), // input
.inv_clk_div (inv_clk_div), // input
.dqs_pattern (dqs_pattern), // input[7:0]
.dqm_pattern (dqm_pattern) // input[7:0]
);
endmodule
This diff is collapsed.
......@@ -46,7 +46,7 @@ module phy_top #(
parameter ICLK_PHASE = 0.000,
parameter CLK_PHASE = 0.000,
parameter CLK_DIV_PHASE = 0.000,
parameter MCLK_PHASE = 0.000,
parameter MCLK_PHASE = 90.000,
parameter REF_JITTER1 = 0.010,
parameter SS_EN = "FALSE",
parameter SS_MODE = "CENTER_HIGH",
......@@ -100,7 +100,7 @@ module phy_top #(
input [7:0] dly_data, // delay value (3 LSB - fine delay)
input [6:0] dly_addr, // select which delay to program
input ld_delay, // load delay data to selected iodelayl (clk_iv synchronous)
input ld_delay, // load delay data to selected iodelayl (clk_div synchronous)
input set, // clk_div synchronous set all delays from previously loaded values
output locked,
output ps_rdy,
......@@ -148,7 +148,7 @@ module phy_top #(
.in_tri (in_tri), // tristate command/address outputs - same timing, but no odelay
.dly_data (dly_data[7:0]), // delay value (3 LSB - fine delay)
.dly_addr (dly_addr[4:0]), // select which delay to program
.ld_delay (ld_cmda), // load delay data to selected iodelayl (clk_iv synchronous)
.ld_delay (ld_cmda), // load delay data to selected iodelayl (clk_div synchronous)
.set (set) // clk_div synchronous set all delays from previously loaded values
);
......
......@@ -105,7 +105,7 @@ module test_phy_top_01#(
reg dci_disable_dq; // disable DCI termination during writes and idle for dq and dm signals
reg [7:0] dly_data; // delay value (3 LSB - fine delay)
reg [6:0] dly_addr; // select which delay to program
reg ld_delay; // load delay data to selected iodelayl (clk_iv synchronous)
reg ld_delay; // load delay data to selected iodelayl (clk_div synchronous)
reg set; // clk_div synchronous set all delays from previously loaded values
reg [63:0] dout_r;
......
......@@ -142,12 +142,12 @@ module ram_1kx32_1kx32
.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 (read port in SDP) clock, input
.ENBWREN(we), // Port B (read port in SDP) Enable, input
.REGCEB(1'b0), // Port B (read port in SDP) register enable, input
.RSTRAMB(1'b0), // Port B (read port in SDP) set/reset, input
.RSTREGB(1'b0), // Port B (read port in SDP) register set/reset, input
.WEBWE({4'b0,web[3:0]}), // Port B (read port in SDP) Write Enable[7:0], 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
......
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* ram_1kx32w_512x64r.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_1kx32w_512x64r.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_1kx32w_512x64r
#(
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 [ 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(72), // 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("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_out[31:0]), // Port A data/LSB data[63:0], output
.DOPADOP(), // Port A parity/LSB parity[7: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_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
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* ram_512x64w_1kx32r.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_512x64w_1kx32r.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_512x64w_1kx32r
#(
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 [ 8:0] waddr, // write address
input we, // write port enable
input [ 7:0] web, // write byte enable
input [63: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(72), // 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_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[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[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