Commit 4bacb90a authored by Andrey Filippov's avatar Andrey Filippov

write leveling done, working on write buffer

parent 1b719ff1
com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->
com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->iverilog_84_IncludeDir<-@\#\#@->
eclipse.preferences.version=1
iverilog_77_Param_Exe=/usr/local/bin/iverilog
iverilog_78_VVP_Exe=/usr/local/bin/vvp
iverilog_81_TopModulesOther=glbl<-@\#\#@->
iverilog_83_ExtraFiles=glbl.v<-@\#\#@->
iverilog_84_IncludeDir=/data/vdt/vdt-projects/eddr3/ddr3<-@\#\#@->
iverilog_88_ShowNoProblem=true
iverilog_99_GrepFindErrWarn=error|warning|sorry
......@@ -115,7 +115,7 @@ module ddr3 (
`elsif den2048Mb
`include "2048Mb_ddr3_parameters.vh"
`elsif den4096Mb
`include "ddr3/4096Mb_ddr3_parameters.vh"
`include "4096Mb_ddr3_parameters.vh"
`else
// NOTE: Intentionally cause a compile fail here to force the users
// to select the correct component density before continuing
......@@ -606,11 +606,11 @@ module ddr3 (
floor = number;
endfunction
function integer max( input integer a, b );
function integer max( input integer a, input integer b );
max = (a < b) ? b : a;
endfunction
function integer min( input integer a, b );
function integer min( input integer a, input integer b );
min = (a > b) ? b : a;
endfunction
......
......@@ -43,8 +43,8 @@ module ddrc_test01 #(
parameter SS_EN = "FALSE",
parameter SS_MODE = "CENTER_HIGH",
parameter SS_MOD_PERIOD = 10000,
parameter CMD_PAUSE_BITS= 6,
parameter CMD_DONE_BIT= 6,
parameter CMD_PAUSE_BITS= 10,
parameter CMD_DONE_BIT= 10,
parameter AXI_WR_ADDR_BITS = 13,
parameter AXI_RD_ADDR_BITS = 13,
parameter CONTROL_ADDR = 'h1000, // AXI write address of control write registers
......@@ -92,10 +92,10 @@ module ddrc_test01 #(
output SDODT, // output ODT port
inout [15:0] SDD, // DQ I/O pads
inout SDDML, // LDM I/O pad (actually only output)
output 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)
output SDDMU, // UDM I/O pad (actually only output)
inout DQSU, // UDQS I/O pad
inout NDQSU // ~UDQS I/O pad
// AXI write (ps -> pl)
......
This diff is collapsed.
This diff is collapsed.
......@@ -59,10 +59,10 @@ module ddrc_sequencer #(
output SDODT, // output ODT port
inout [15:0] SDD, // DQ I/O pads
inout SDDML, // LDM I/O pad (actually only output)
output 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)
output SDDMU, // UDM I/O pad (actually only output)
inout DQSU, // UDQS I/O pad
inout NDQSU, // ~UDQS I/O pad
// clocks, reset
......@@ -164,7 +164,8 @@ module ddrc_sequencer #(
always @ (posedge mclk or posedge rst) begin
if (rst) cmd_busy <= 0;
else if (sequence_done) cmd_busy <= 0;
// else if (sequence_done) cmd_busy <= 0;
else if (sequence_done && cmd_busy[2]) cmd_busy <= 0;
else cmd_busy <= {cmd_busy[1:0],run_seq | cmd_busy[0]};
// Pause counter
if (rst) pause_cntr <= 0;
......@@ -212,8 +213,8 @@ module ddrc_sequencer #(
else if (run_seq_d) buf_raddr <= {buf_page,7'h0};
else if (buf_wr || buf_rd) buf_raddr <= buf_raddr +1; // Separate read/write address? read address re-registered @ negedge
if (rst) run_chn_d <= 0;
else run_chn_d <= run_chn;
if (rst) run_chn_d <= 0;
else if (run_seq) run_chn_d <= run_chn;
if (rst) run_seq_d <= 0;
else run_seq_d <= run_seq;
......
......@@ -45,8 +45,8 @@ module phy_cmd#(
parameter SS_EN = "FALSE",
parameter SS_MODE = "CENTER_HIGH",
parameter SS_MOD_PERIOD = 10000,
parameter CMD_PAUSE_BITS= 6, // numer of (address) bits to encode pause
parameter CMD_DONE_BIT= 6 // bit number (address) to signal sequence done
parameter CMD_PAUSE_BITS= 10, // numer of (address) bits to encode pause
parameter CMD_DONE_BIT= 10 // bit number (address) to signal sequence done
)(
// DDR3 interface
output SDRST, // DDR3 reset (active low)
......@@ -61,10 +61,10 @@ module phy_cmd#(
output SDODT, // output ODT port
inout [15:0] SDD, // DQ I/O pads
inout SDDML, // LDM I/O pad (actually only output)
output 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)
output SDDMU, // UDM I/O pad (actually only output)
inout DQSU, // UDQS I/O pad
inout NDQSU, // ~UDQS I/O pad
// clocks, reset
......@@ -121,6 +121,7 @@ module phy_cmd#(
wire phy_dqs_tri_in; // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
wire phy_dci_en_in; // DCI disable, both DQ and DQS lines (internal logic and 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 phy_dqs_toggle_en; //enable toggle DQS according to the pattern
wire phy_buf_wr; // connect to extrenal buffer
wire phy_buf_rd; // connect to extrenal buffer
wire cmda_tri;
......@@ -152,9 +153,14 @@ module phy_cmd#(
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
reg [ADDRESS_NUMBER-1:0] phy_addr_prev;
reg [ 2:0] phy_bank_prev;
wire [ADDRESS_NUMBER-1:0] phy_addr_calm;
wire [ 2:0] phy_bank_calm;
// output [63:0] buf_wdata, // data to be written to the buffer (from DDR3)
// SuppressWarnings VEditor
(* keep = "true" *) wire [2:0] phy_spare;
(* keep = "true" *) wire [1:0] phy_spare;
assign {
phy_addr_in,
phy_bank_in,
......@@ -164,6 +170,7 @@ module phy_cmd#(
phy_sel_in, // fitst/second half-cycle, oter will be nop (cke+odt applicable to both)
phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
phy_dqs_en_in, //phy_dqs_tri_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
phy_dqs_toggle_en, //enable toggle DQS according to the pattern
phy_dci_en_in, //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 external buffer (is it needed? maybe just autoincrement?)
phy_buf_wr, // connect to external buffer (but only if not paused)
......@@ -179,12 +186,16 @@ module phy_cmd#(
assign sequence_done= phy_cmd_nop && phy_addr_in[CMD_DONE_BIT];
assign pause_len= phy_addr_in[CMD_PAUSE_BITS-1:0];
assign phy_addr_calm= phy_cmd_nop ? phy_addr_prev : phy_addr_in;
assign phy_bank_calm= phy_cmd_nop ? phy_bank_prev : phy_bank_in;
// 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_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_addr= {phy_addr_calm,phy_addr_calm}; // also provides pause length when the command is NOP
assign phy_bank= {phy_bank_calm,phy_bank_calm};
assign phy_rcw= {phy_sel_in?phy_rcw_in:3'h7, phy_sel_in?3'h7: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?
......@@ -210,6 +221,17 @@ module phy_cmd#(
dqs_tri_prev <= phy_dqs_tri_in;
dq_tri_prev <= phy_dq_tri_in;
end
always @ (posedge mclk or posedge rst_in) begin
if (rst_in) begin
phy_addr_prev <= 0;
phy_bank_prev <= 0;
end else if (!phy_cmd_nop) begin
phy_addr_prev <= phy_addr_in;
phy_bank_prev <= phy_bank_in;
end
end
// cross clock boundary posedge mclk -> posedge clk_div (mclk is later than clk_div)
always @ (posedge clk_div or posedge rst_in) begin
......@@ -259,7 +281,8 @@ phy_rdata
*/
wire [7:0] dqs_data;
assign dqs_data=phy_dqs_toggle_en?dqs_pattern[7:0]:8'h0;
phy_top #(
.IOSTANDARD_DQ ("SSTL15_T_DCI"),
.IOSTANDARD_DQS ("DIFF_SSTL15_T_DCI"),
......@@ -327,7 +350,7 @@ phy_rdata
.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]
.din_dqs (dqs_data), // 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
......
......@@ -64,10 +64,10 @@ module phy_top #(
output ddr3_odt, // output ODT port
inout [15:0] dq, // DQ I/O pads
inout dml, // LDM I/O pad (actually only output)
output dml, // LDM I/O pad (actually only output)
inout dqsl, // LDQS I/O pad
inout ndqsl, // ~LDQS I/O pad
inout dmu, // UDM I/O pad (actually only output)
output dmu, // UDM I/O pad (actually only output)
inout dqsu, // UDQS I/O pad
inout ndqsu, // ~UDQS I/O pad
......
This diff is collapsed.
......@@ -38,12 +38,13 @@ module fifo_same_clock
);
localparam integer DATA_2DEPTH=(1<<DATA_DEPTH)-1;
reg [DATA_DEPTH :0] fill=0;
reg just_one=0;
reg just_one,two_or_less;
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;
wire outreg_use_inreg;
reg wem;
wire rem;
reg out_full=0; //output register full
......@@ -52,10 +53,11 @@ module fifo_same_clock
// assign data_out = just_one?inreg:outreg;
assign data_out = out_full?outreg:inreg;
assign rem = (!out_full || re)&& (just_one? wem : re);
assign outreg_use_inreg=(out_full && two_or_less) || just_one;
// assign next_fill = fill[4:0]+((we && ~rem)?1:((~we && rem)?5'b11111:5'b00000));
// TODO: verify rem is not needed instead of re
assign next_fill = fill[4:0]+((we && ~re)?1:((~we && re)?5'b11111:5'b00000));
always @ (posedge clk or posedge rst) begin
......@@ -79,10 +81,12 @@ module fifo_same_clock
always @ (posedge clk) begin
if (wem) ram[wa] <= inreg;
just_one <= (next_fill == 1);
two_or_less <= (next_fill == 1) | (next_fill == 2);
half_full <=(fill & (1<<(DATA_DEPTH-1)))!=0;
full <= (fill & (1<< DATA_DEPTH ))!=0;
if (we) inreg <= data_in;
if (rem) outreg <= just_one?inreg:ram[ra];
// if (rem) outreg <= just_one?inreg:ram[ra];
if (rem) outreg <= outreg_use_inreg ? inreg : ram[ra];
wem <= we;
end
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