diff --git a/phy/byte_lane.v b/phy/byte_lane.v
index 96b3a86e92a6d4eba94b5590e445537ea417a58c..80948edf700721b937ac9133dcb2a4ff8cba7e7f 100644
--- a/phy/byte_lane.v
+++ b/phy/byte_lane.v
@@ -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
diff --git a/phy/cmd_addr.v b/phy/cmd_addr.v
index 7f9dffa1763f2eeb99225e7a95a1c82a5dfb6b11..9c3dc8585f77e5cb2b44e0ce573de9cd210b0498 100644
--- a/phy/cmd_addr.v
+++ b/phy/cmd_addr.v
@@ -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),
diff --git a/phy/ddr3c16.v b/phy/ddr3c16.v
new file mode 100644
index 0000000000000000000000000000000000000000..71c680089d2d0754ca3bc93819b60956391df8ee
--- /dev/null
+++ b/phy/ddr3c16.v
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * 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 .
+ *******************************************************************************/
+`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, 60064r) - 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
+
diff --git a/phy/phy_cmd.v b/phy/phy_cmd.v
new file mode 100644
index 0000000000000000000000000000000000000000..44fb4229d86377643fdd153899f26a712382161a
--- /dev/null
+++ b/phy/phy_cmd.v
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Module: phy_cmd
+ * Date:2014-05-15
+ * Author: Andrey Filippov
+ * Description: Executes a stream of commands to DDR3 phy at 1/2 ddr3 clock, global
+ * (also proveides r/w interface to the x64 external buffer)
+ *
+ * Copyright (c) 2014 Elphel, Inc.
+ * phy_cmd.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.
+ *
+ * phy_cmd.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 .
+ *******************************************************************************/
+`timescale 1ns/1ps
+
+module phy_cmd#(
+ parameter ADDRESS_NUMBER = 15,
+ 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, 6001 and 1->0)
+ wire phy_dqs_tri_in; // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
+ wire phy_dci_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
+ wire [ 6:0] phy_buf_addr; // connect to extrenal buffer
+ wire phy_buf_wr; // connect to extrenal buffer
+ wire phy_buf_rd; // connect to extrenal buffer
+
+// wire clk;
+ wire clk_div;
+
+ reg [7:0] dly_data_r; // delay value (3 LSB - fine delay)
+ reg [6:0] dly_addr_r; // select which delay to program
+ reg ld_delay_r; // load delay data to selected iodelayl (clk_div synchronous)
+ reg set_r; // clk_div synchronous set all delays from previously loaded values
+
+ wire [2*ADDRESS_NUMBER-1:0] phy_addr; // also provides pause length when the command is NOP
+ wire [ 5:0] phy_bank;
+ wire [ 5:0] phy_rcw; // {ras,cas,we}
+ wire [1:0] phy_odt; // may be optimized?
+ wire [1:0] phy_cke; // may be optimized?
+ wire [7:0] phy_dq_tri; // tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
+ wire [7:0] phy_dqs_tri; // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
+ wire phy_dci_dis_dq;
+ wire phy_dci_dis_dqs;
+
+ reg dqs_tri_prev, dq_tri_prev;
+ wire phy_locked;
+ wire phy_ps_rdy;
+ wire [PHASE_WIDTH-1:0] phy_ps_out;
+ reg locked_r1,locked_r2;
+ reg ps_rdy_r1,ps_rdy_r2;
+ reg [PHASE_WIDTH-1:0] ps_out_r1,ps_out_r2;
+ wire [63:0] phy_rdata; // data read from ddr3 iserdese2 at posedge clk_div
+ reg [63:0] phy_rdata_r; // registered @ posedge mclk
+// output [63:0] buf_wdata, // data to be written to the buffer (from DDR3)
+
+
+ assign {
+ phy_addr_in,
+ phy_bank_in,
+ phy_rcw_in, // {ras,cas,we}
+ phy_odt_in, // may be optimized?
+ phy_cke_in, // may be optimized?
+ phy_sel_in, // fitst/second half-cycle, oter will be nop (cke+odt applicable to both)
+ phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
+ phy_dqs_tri_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
+ phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
+ phy_buf_addr, // connect to extrenal buffer
+ phy_buf_wr, // connect to extrenal buffer
+ phy_buf_rd // connect to extrenal buffer
+ } = phy_cmd;
+
+ assign buf_addr = phy_buf_addr;
+ assign buf_wr = phy_buf_wr;
+ assign buf_rd = phy_buf_rd;
+
+ assign phy_addr= {phy_addr_in,phy_addr_in}; // also provides pause length when the command is NOP
+ assign phy_bank= {phy_bank_in,phy_bank_in};
+ assign phy_rcw= {phy_sel_in?phy_rcw_in:3'h0, phy_sel_in?3'h0:phy_rcw_in}; // {ras,cas,we}
+ assign phy_odt= {phy_odt_in,phy_odt_in}; // may be optimized?
+ assign phy_cke= {phy_cke_in,phy_cke_in}; // may be optimized?
+
+ // tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
+ assign phy_dq_tri= (dq_tri_prev==phy_dq_tri_in)?{{8{phy_dq_tri_in}}}:
+ (dq_tri_prev?{DQTRI_FIRST,DQTRI_FIRST}:{DQTRI_LAST,DQTRI_LAST});
+ // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
+ assign phy_dqs_tri= (dqs_tri_prev==phy_dqs_tri_in)?{{8{phy_dqs_tri_in}}}:
+ (dqs_tri_prev?{DQSTRI_FIRST,DQSTRI_FIRST}:{DQSTRI_LAST,DQSTRI_LAST});
+ assign phy_dci_dis_dq = phy_dci_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
+ assign phy_dci_dis_dqs = phy_dci_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
+
+ assign locked = locked_r2;
+ assign ps_rdy = ps_rdy_r2;
+ assign ps_out = ps_out_r2;
+
+ assign buf_wdata[63:0] = phy_rdata_r[63:0];
+
+ always @ (posedge mclk) begin
+ dqs_tri_prev <= phy_dqs_tri_in;
+ dq_tri_prev <= phy_dq_tri_in;
+ end
+
+// cross clock boundary posedge mclk -> posedge clk_div (mclk is later than clk_div)
+ always @ (posedge clk_div or posedge rst_in) begin
+ if (rst_in) begin
+ dly_data_r <= 0;
+ dly_addr_r <= 0;
+ ld_delay_r <= 0;
+ set_r <= 0;
+ end else begin
+ dly_data_r <= dly_data;
+ dly_addr_r <= dly_addr;
+ ld_delay_r <= ld_delay;
+ set_r <= set;
+ end
+ end
+
+
+// cross clock boundary posedge posedge clk_div->negedge clk_div -> posedge mclk (mclk is later than clk_div)
+ always @ (negedge clk_div) begin
+ locked_r1 <= phy_locked;
+ ps_rdy_r1 <= phy_ps_rdy;
+ ps_out_r1 <= phy_ps_out;
+ end
+ always @ (posedge mclk) begin
+ locked_r2 <= locked_r1;
+ ps_rdy_r2 <= ps_rdy_r1;
+ ps_out_r2 <= ps_out_r1;
+ end
+
+
+ always @ (negedge mclk) begin
+ phy_rdata_r[63:0] <= phy_rdata[63:0];
+ end
+
+
+/*
+phy_rdata
+
+ wire phy_locked;
+ wire phy_ps_rdy;
+ wire [PHASE_WIDTH-1:0] phy_ps_out;
+
+
+ output locked,
+ output ps_rdy,
+ output [PHASE_WIDTH-1:0] ps_out,
+
+*/
+
+
+ phy_top #(
+ .IOSTANDARD_DQ ("SSTL15_T_DCI"),
+ .IOSTANDARD_DQS ("DIFF_SSTL15_T_DCI"),
+ .IOSTANDARD_CMDA ("SSTL15"),
+ .IOSTANDARD_CLK ("DIFF_SSTL15"),
+ .SLEW_DQ (SLEW_DQ),
+ .SLEW_DQS (SLEW_DQS),
+ .SLEW_CMDA (SLEW_CMDA),
+ .SLEW_CLK (SLEW_CLK),
+ .IBUF_LOW_PWR (IBUF_LOW_PWR),
+ .IODELAY_GRP ("IODELAY_MEMORY"),
+ .REFCLK_FREQUENCY (REFCLK_FREQUENCY),
+ .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE),
+ .ADDRESS_NUMBER (ADDRESS_NUMBER),
+ .PHASE_WIDTH (8),
+ .BANDWIDTH ("OPTIMIZED"),
+ .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_top_i (
+ .ddr3_clk (SDCLK), // output
+ .ddr3_nclk (SDNCLK), // output
+ .ddr3_a (SDA[ADDRESS_NUMBER-1:0]), // output[14:0]
+ .ddr3_ba (SDBA[2:0]), // output[2:0]
+ .ddr3_we (SDWE), // output
+ .ddr3_ras (SDRAS), // output
+ .ddr3_cas (SDCAS), // output
+ .ddr3_cke (SDCKE), // output
+ .ddr3_odt (SDODT), // output
+ .dq (SDD[15:0]), // inout[15:0]
+ .dml (SDDML), // inout
+ .dqsl (DQSL), // inout
+ .ndqsl (NDQSL), // inout
+ .dmu (SDDMU), // inout
+ .dqsu (DQSU), // inout
+ .ndqsu (NDQSU), // inout
+ .clk_in (clk_in), // input
+// .clk (clk), // output
+ .clk (), // output
+ .clk_div (clk_div), // output
+ .mclk (mclk), // output
+ .rst_in (rst_in), // input
+ .in_a (phy_addr[2*ADDRESS_NUMBER-1:0]), // input[29:0]
+ .in_ba (phy_bank[5:0]), // input[5:0]
+ .in_we ({phy_rcw[3],phy_rcw[0]}), // input[1:0]
+ .in_ras ({phy_rcw[5],phy_rcw[2]}), // input[1:0]
+ .in_cas ({phy_rcw[4],phy_rcw[1]}), // input[1:0]
+ .in_cke (phy_cke), // input[1:0]
+ .in_odt (phy_odt), // input[1:0]
+ .in_tri (cmda_tri), // input
+ .din (buf_rdata[63:0]), // input[63:0]
+ .din_dm (dqm_pattern[7:0]), // input[7:0]
+ .tin_dq (phy_dq_tri[7:0]), // input[7:0]
+ .din_dqs (dqs_pattern[7:0]), // input[7:0]
+ .tin_dqs (phy_dqs_tri[7:0]), // input[7:0]
+ .dout (phy_rdata[63:0]), // output[63:0] @posedge clk_div
+ .inv_clk_div (inv_clk_div), // input
+ .dci_disable_dqs (phy_dci_dis_dqs), // input
+ .dci_disable_dq (phy_dci_dis_dq), // input
+ .dly_data (dly_data_r), // input[7:0]
+ .dly_addr (dly_addr_r), // input[6:0]
+ .ld_delay (ld_delay_r), // input
+ .set (set_r), // input
+ .locked (phy_locked), // output
+ .ps_rdy (phy_ps_rdy), // output
+ .ps_out (phy_ps_out) // output[7:0]
+ );
+
+endmodule
+
diff --git a/phy/phy_top.v b/phy/phy_top.v
index 9df09e10af587d1a32a65676e0e05b765b0fd074..3a18dd7f0eee19b7501cf070dc97db4c633c3965 100644
--- a/phy/phy_top.v
+++ b/phy/phy_top.v
@@ -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
);
diff --git a/phy/test_phy_top_01.v b/phy/test_phy_top_01.v
index c1ddab5f97224c095d2ad47a4574df2125e9182f..d40410b4eba1731ccaed25ae80935d4aebd6a74c 100644
--- a/phy/test_phy_top_01.v
+++ b/phy/test_phy_top_01.v
@@ -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;
diff --git a/wrap/ram_1kx32_1kx32.v b/wrap/ram_1kx32_1kx32.v
index 6b5c8f9823f5597bd1698073b5fa30d9b6f5a3ae..45121cf1d7eb6048e1e5b96dc01658a0605c47bc 100644
--- a/wrap/ram_1kx32_1kx32.v
+++ b/wrap/ram_1kx32_1kx32.v
@@ -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
diff --git a/wrap/ram_1kx32w_512x64r.v b/wrap/ram_1kx32w_512x64r.v
new file mode 100644
index 0000000000000000000000000000000000000000..98a1fccc3277508c0f43372371558c4e62f1044e
--- /dev/null
+++ b/wrap/ram_1kx32w_512x64r.v
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * 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 .
+ *******************************************************************************/
+/*
+ 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
+
diff --git a/wrap/ram_512x64w_1kx32r.v b/wrap/ram_512x64w_1kx32r.v
new file mode 100644
index 0000000000000000000000000000000000000000..e699909c51ec59bbf6e30e06eae9df951895b4cd
--- /dev/null
+++ b/wrap/ram_512x64w_1kx32r.v
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * 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 .
+ *******************************************************************************/
+/*
+ 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
+