Commit 3d67d687 authored by Andrey Filippov's avatar Andrey Filippov

debugging, next snapshot

parent 8b1e18d4
......@@ -51,7 +51,7 @@
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140522174846453.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
......@@ -61,12 +61,12 @@
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140522174846453.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140522174846453.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
......@@ -76,7 +76,7 @@
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140522174846453.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
......@@ -86,7 +86,7 @@
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140522174846453.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
......@@ -96,7 +96,7 @@
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140522152648076.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140522174846453.log</location>
</link>
<link>
<name>vivado_state/eddr3-opt-phys.dcp</name>
......@@ -106,7 +106,7 @@
<link>
<name>vivado_state/eddr3-place.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140522152648076.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140522174846453.dcp</location>
</link>
<link>
<name>vivado_state/eddr3-route.dcp</name>
......@@ -116,7 +116,7 @@
<link>
<name>vivado_state/eddr3-synth.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140522152648076.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140522174846453.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -61,7 +61,11 @@ module ddrc_control #(
parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter CMDA_EN_REL = 'h022, // address to enable('h823)/disable('h822) command/address outputs
parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h024, // address to set extra parameters (currently just inv_clk_div)
parameter SDRST_ACT_REL = 'h024, // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory
parameter SDRST_ACT_REL_MASK ='h3fe, // address mask for reset DDR3
parameter CKE_EN_REL = 'h026, // address to enable('h827)/disable('h826) CKE signal to memory
parameter CKE_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h028, // address to set extra parameters (currently just inv_clk_div)
parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters
)(
input clk,
......@@ -85,7 +89,10 @@ module ddrc_control #(
output ld_delay, // write dly_data to dly_address, one mclk active pulse
output dly_set, // transfer (activate) all delays simultaneosly, 1 mclk pulse
// control: additional signals
output cmda_tri, // tri-state all command and address lines to DDR chip
output cmda_en, // tri-state all command and address lines to DDR chip
output ddr_rst, // generate DDR3 memory reset signal
output ddr_cke, // control DDR3 memory CKE signal
output inv_clk_div, // invert clk_div to ISERDES
output [ 7:0] dqs_pattern, // DQS pattern during write (normally 8'h55)
output [ 7:0] dqm_pattern, // DQM pattern (just for testing, should be 8'h0)
......@@ -108,6 +115,12 @@ module ddrc_control #(
localparam PAGES_ADDR_MASK = CONTROL_ADDR_MASK | PAGES_REL_MASK; // address mask to set DQM and DQS patterns
localparam CMDA_EN_ADDR = CONTROL_ADDR | CMDA_EN_REL; // address to enable('h823)/disable('h822) command/address outputs
localparam CMDA_EN_ADDR_MASK = CONTROL_ADDR_MASK | CMDA_EN_REL_MASK; // address mask for command/address outputs
localparam SDRST_ACT_ADDR = CONTROL_ADDR | SDRST_ACT_REL; // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory
localparam SDRST_ACT_ADDR_MASK =CONTROL_ADDR_MASK | SDRST_ACT_REL_MASK; // address mask for reset DDR3
localparam CKE_EN_ADDR = CONTROL_ADDR | CKE_EN_REL; // address to enable('h827)/disable('h826) CKE signal to memory
localparam CKE_EN_ADDR_MASK = CONTROL_ADDR_MASK | CKE_EN_REL_MASK; // address mask for CKE
localparam EXTRA_ADDR = CONTROL_ADDR | EXTRA_REL; // address to set extra parameters (currently just inv_clk_div)
localparam EXTRA_ADDR_MASK = CONTROL_ADDR_MASK | EXTRA_REL_MASK; // address mask for extra parameters
......@@ -133,6 +146,9 @@ module ddrc_control #(
reg [ 1:0] port1_page_r; // port 1 buffer write page (to be controlled by arbiter later, set to 2'b0)
reg [ 1:0] port1_int_page_r; // port 1 PHY-side buffer read page (to be controlled by arbiter later, set to 2'b0)
reg cmda_en_r; // enable (tri-state off) all command and address lines to DDR chip
reg ddr_rst_r; // generate DDR3 memory reset
reg ddr_cke_r; // enable CKE to memory
reg inv_clk_div_r; // invert clk_div to ISERDES
assign ld_delay = dly_ld_r;
......@@ -141,7 +157,7 @@ module ddrc_control #(
assign dly_addr = waddr_fifo_out_r[ 6:0]; //WARNING: [Synth 8-3936] Found unconnected internal register 'waddr_fifo_out_r_reg' and it is trimmed from '12' to '7' bits. [ddrc_control.v:101]
assign run_addr = wdata_fifo_out_r[10:0];
assign run_chn = waddr_fifo_out_r[3:0];
assign run_seq = run_seq_r;
assign run_seq = run_seq_r && !ddr_rst;
assign busy=busy_r && (start_wburst?(((pre_waddr ^ BUSY_WR_ADDR) & BUSY_WR_ADDR_MASK)==0): selected_busy);
......@@ -151,7 +167,9 @@ module ddrc_control #(
assign port0_int_page = port0_int_page_r[1:0];
assign port1_page = port1_page_r[1:0];
assign port1_int_page = port1_int_page_r[1:0];
assign cmda_tri = ~cmda_en_r;
assign cmda_en = cmda_en_r;
assign ddr_rst= ddr_rst_r;
assign ddr_cke= ddr_cke_r;
assign inv_clk_div = inv_clk_div_r;
always @ (posedge clk or posedge rst) begin
......@@ -202,6 +220,14 @@ module ddrc_control #(
else if (fifo_re && (((waddr_fifo_out ^ CMDA_EN_ADDR) & CMDA_EN_ADDR_MASK)==0))
cmda_en_r <= waddr_fifo_out[0];
if (rst) ddr_rst_r <= 1'b1; // enable DDR3 reset at system reset
else if (fifo_re && (((waddr_fifo_out ^ SDRST_ACT_ADDR) & SDRST_ACT_ADDR_MASK)==0))
ddr_rst_r <= waddr_fifo_out[0];
if (rst) ddr_cke_r <= 1'b0;
else if (fifo_re && (((waddr_fifo_out ^ CKE_EN_ADDR) & CKE_EN_ADDR_MASK)==0))
ddr_cke_r <= waddr_fifo_out[0];
if (rst) inv_clk_div_r <= 1'b0;
else if (fifo_re && (((waddr_fifo_out ^ EXTRA_ADDR) & EXTRA_ADDR_MASK)==0))
inv_clk_div_r <= wdata_fifo_out[0];
......
......@@ -72,12 +72,15 @@ module ddrc_test01 #(
parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns
parameter CMDA_EN_REL = 'h022, // address to enable('h823)/disable('h822) command/address outputs
parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h024, // address to set extra parameters (currently just inv_clk_div)
parameter SDRST_ACT_REL = 'h024, // address to activate('h825)/deactivate('h824) active-low reset signal to DDR3 memory
parameter SDRST_ACT_REL_MASK = 'h3fe, // address mask for reset DDR3
parameter CKE_EN_REL = 'h026, // address to enable('h827)/disable('h826) CKE signal to memory
parameter CKE_EN_REL_MASK = 'h3fe, // address mask for command/address outputs
parameter EXTRA_REL = 'h028, // address to set extra parameters (currently just inv_clk_div)
parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters
)(
// DDR3 interface
output SDRST, // DDR3 reset (active low)
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
......@@ -99,9 +102,7 @@ module ddrc_test01 #(
);
localparam ADDRESS_NUMBER=15;
// Source for reset and clock
(* keep = "true" *)
wire [3:0] fclk; // PL Clocks [3:0], output
(* keep = "true" *)
wire [3:0] frst; // PL Clocks [3:0], output
......@@ -110,7 +111,7 @@ module ddrc_test01 #(
(* keep = "true" *)
wire axi_aclk; // clock - should be buffered
// wire axi_aresetn; // reset, active low
(* keep = "true" *)
(* dont_touch = "true" *)
wire axi_rst; // reset, active high
// AXI Write Address
wire [31:0] axi_awaddr; // AWADDR[31:0], input
......@@ -209,7 +210,10 @@ module ddrc_test01 #(
wire [ 1:0] port1_int_page;// input[1:0]
// additional control signals
wire cmda_tri; // input
wire cmda_en; // enable DDR3 memory control and addreee outputs
wire ddr_rst; // generate DDR3 memory reset (active hight)
wire ddr_cke; // control of the DDR3 memory CKE signal
wire inv_clk_div; // input
wire [ 7:0] dqs_pattern; // input[7:0] 8'h55
wire [ 7:0] dqm_pattern; // input[7:0] 8'h00
......@@ -236,13 +240,26 @@ module ddrc_test01 #(
always @ (posedge axi_rst or posedge axi_aclk) begin
if (axi_rst) select_port0 <= 1'b0;
else if (axird_start_burst) select_port0 <= (((axird_pre_araddr[11:10]^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
else if (axird_start_burst) select_port0 <= (((axird_pre_araddr^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
if (axi_rst) select_status <= 1'b0;
else if (axird_start_burst) select_status <= (((axird_pre_araddr[11:10]^ STATUS_ADDR) & STATUS_ADDR_MASK)==0);
else if (axird_start_burst) select_status <= (((axird_pre_araddr^ STATUS_ADDR) & STATUS_ADDR_MASK)==0);
end
/*
// Clock and reset from PS
BUFG bufg_axi_rst_i (.O(axi_rst),.I(~frst[0]));
reg frst_inv;
always @ (negedge frst[0] or posedge axi_aclk) begin
if (!frst[0]) frst_inv <= 1'b1;
else frst_inv <= 1'b0;
end
*/
`ifndef IVERILOG
(* dont_touch = "true" *)
`endif
wire frst_inv= ~frst[0];
//BUFG bufg_axi_rst_i (.O(axi_rst),.I(~frst[0]));
BUFG bufg_axi_rst_i (.O(axi_rst),.I(frst_inv));
BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
axibram_write #(
......@@ -325,6 +342,10 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
.PAGES_REL_MASK (PAGES_REL_MASK),
.CMDA_EN_REL (CMDA_EN_REL),
.CMDA_EN_REL_MASK (CMDA_EN_REL_MASK),
.SDRST_ACT_REL (SDRST_ACT_REL),
.SDRST_ACT_REL_MASK(SDRST_ACT_REL_MASK),
.CKE_EN_REL (CKE_EN_REL),
.CKE_EN_REL_MASK (CKE_EN_REL_MASK),
.EXTRA_REL (EXTRA_REL),
.EXTRA_REL_MASK (EXTRA_REL_MASK)
) ddrc_control_i (
......@@ -344,7 +365,9 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
.dly_addr (dly_addr[6:0]), // output[6:0]
.ld_delay (ld_delay), // output
.dly_set (set), // output
.cmda_tri (cmda_tri), // output
.cmda_en (cmda_en), // output
.ddr_rst (ddr_rst), // output
.ddr_cke (ddr_cke), // output
.inv_clk_div (inv_clk_div), // output
.dqs_pattern (dqs_pattern[7:0]), // output[7:0]
.dqm_pattern (dqm_pattern[7:0]), // output[7:0]
......@@ -406,6 +429,7 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
.CMD_PAUSE_BITS (CMD_PAUSE_BITS),
.CMD_DONE_BIT (CMD_DONE_BIT)
) ddrc_sequencer_i (
.SDRST (SDRST), // output
.SDCLK (SDCLK), // output
.SDNCLK (SDNCLK), // output
.SDA (SDA[14:0]), // output[14:0] // BUG with localparam - fixed
......@@ -437,7 +461,8 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
.run_addr (run_addr[10:0]), // input[10:0]
.run_chn (run_chn[3:0]), // input[3:0]
.run_seq (run_seq), // input
.run_seq (run_seq), // input #################### DISABLED ####################
// .run_seq (1'b0 && run_seq), // input #################### DISABLED ####################
// .run_done (run_done), // output
.run_done (), // output
.run_busy (run_busy), // output
......@@ -462,7 +487,9 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
.port1_int_page (port1_int_page[1:0]), // input[1:0]
.port1_addr (axiwr_bram_waddr[7:0]), // input[7:0]
.port1_data (axiwr_bram_wdata[31:0]), // input[31:0]
.cmda_tri (cmda_tri), // input
.cmda_en (cmda_en), // input
.ddr_rst (ddr_rst), // input
.ddr_cke (ddr_cke), // input
.inv_clk_div (inv_clk_div), // input
.dqs_pattern (dqs_pattern), // input[7:0]
.dqm_pattern (dqm_pattern) // input[7:0]
......
......@@ -19,6 +19,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/> .
#################################################################################
# output SDRST, // output SDRST, active low
set_property IOSTANDARD SSTL15 [get_ports {SDRST}]
set_property PACKAGE_PIN J4 [get_ports {SDRST}]
# output SDCLK, // DDR3 clock differential output, positive
set_property IOSTANDARD DIFF_SSTL15 [get_ports {SDCLK}]
set_property PACKAGE_PIN K3 [get_ports {SDCLK}]
......
This diff is collapsed.
This diff is collapsed.
......@@ -56,7 +56,7 @@ reg [2*ADDRESS_NUMBER-1:0] in_a_r=0;
reg [5:0] in_ba_r=0;
reg [1:0] in_we_r=2'h3, in_ras_r=2'h3, in_cas_r=2'h3, in_cke_r=2'h3, in_odt_r=2'h0;
//reg [1:0] in_tri_r=2'h0; // or tri-state on reset?
reg in_tri_r=1'b0; // or tri-state on reset?
reg in_tri_r=1'b1; // or tri-state on reset?
// Preventing register duplication
(* keep = "true" *) reg [7:0] dly_data_r=0;
(* keep = "true" *) reg set_r=0;
......@@ -78,7 +78,7 @@ always @ (posedge clk_div or posedge rst) begin
in_a_r <= 0; in_ba_r <= 6'b0;
in_we_r <= 2'h3; in_ras_r <= 2'h3; in_cas_r <= 2'h3; in_cke_r <= 2'h3; in_odt_r <= 2'h0;
// in_tri_r <= 2'h0; // or tri-state on reset?
in_tri_r <= 1'b0; // or tri-state on reset?
in_tri_r <= 1'b1; // or tri-state on reset?
dly_data_r<=8'b0;set_r<=1'b0;
ld_dly_cmd <= 8'b0; ld_dly_addr <= 0;
end else begin
......
......@@ -47,6 +47,7 @@ module ddrc_sequencer #(
parameter CMD_DONE_BIT= 6
)(
// DDR3 interface
output SDRST, // DDR3 reset (active low)
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
......@@ -81,7 +82,7 @@ module ddrc_sequencer #(
// Controller run interface, posedge mclk
input [10:0] run_addr, // controller sequencer start address (0..11'h3ff - cmd0, 11'h400..11'h7ff - cmd1)
input [3:0] run_chn, // data channel to use
input run_seq, // start controller sequence
input run_seq, // start controller sequence (will and with !ddr_rst for stable mclk)
output run_done, // controller sequence finished
output run_busy, // controller sequence in progress
// inteface to control I/O delays and mmcm
......@@ -108,7 +109,9 @@ module ddrc_sequencer #(
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 cmda_en, // enable (!tristate) command and address lines // not likely to be used
input ddr_rst, // generate reset to DDR3 memory (active high)
input ddr_cke, // DDR clock enable , XOR-ed with command bit
input inv_clk_div,
input [7:0] dqs_pattern, // 8'h55
input [7:0] dqm_pattern // 8'h00
......@@ -153,14 +156,16 @@ module ddrc_sequencer #(
assign run_done=sequence_done;
assign run_busy=cmd_busy[0]; //earliest
assign pause=cmd_fetch? (phy_cmd_nop && (pause_len != 0)): (cmd_busy[2] && (pause_cntr[CMD_PAUSE_BITS-1:1]!=0));
assign phy_cmd_word = phy_cmd_word?phy_cmd1_word:phy_cmd0_word;
/// debugging
assign phy_cmd_word = cmd_sel?phy_cmd1_word:phy_cmd0_word; // TODO: hangs even with 0-s in phy_cmd
/// assign phy_cmd_word = phy_cmd_word?0:0;
assign buf_rdata[63:0] = ({64{buf_sel_1hot[1]}} & buf1_rdata[63:0]); // ORR with other read channels terms
assign buf_rdata[63:0] = ({64{buf_sel_1hot[1]}} & buf1_rdata[63:0]); // ORed with other read channels terms
always @ (posedge mclk or posedge rst) begin
if (rst) cmd_busy <= 0;
else if (sequence_done) cmd_busy <= 0;
else cmd_busy <= {cmd_busy[1:0],run_seq};
else cmd_busy <= {cmd_busy[1:0],run_seq | cmd_busy[0]};
// Pause counter
if (rst) pause_cntr <= 0;
else if (!cmd_busy[1]) pause_cntr <= 0; // not needed?
......@@ -169,7 +174,7 @@ module ddrc_sequencer #(
// Fetch - command data valid
if (rst) cmd_fetch <= 0;
else cmd_fetch <= cmd_busy[0] && !pause;
// Command read adderss
// Command read address
if (rst) cmd_addr <= 0;
else if (run_seq) cmd_addr <= run_addr[9:0];
else if (cmd_busy[0] && !pause) cmd_addr <= cmd_addr + 1;
......@@ -181,7 +186,7 @@ module ddrc_sequencer #(
else if (run_seq) case (run_chn)
4'h0: buf_page <= port0_int_page;
4'h1: buf_page <= port1_int_page;
// Add other channles later
// Add other channels later
default: buf_page <= 2'bxx;
endcase
......@@ -206,6 +211,12 @@ module ddrc_sequencer #(
if (rst) buf_raddr <= 9'h0;
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_seq_d <= 0;
else run_seq_d <= run_seq;
end
// re-register buffer write address to match DDR3 data
always @ (negedge mclk) begin
......@@ -213,21 +224,19 @@ module ddrc_sequencer #(
buf_wr_negedge <= buf_wr;
buf_wdata_negedge <= buf_wdata;
end
always @ (posedge mclk) begin
run_chn_d <= run_chn;
run_seq_d <= run_seq;
end
// Command sequence memories:
// Command sequence memory 0 ("manual"):
wire ren0=!cmd_sel && cmd_busy[0] && !pause; // cmd_busy - multibit
wire ren1= cmd_sel && cmd_busy[0] && !pause;
ram_1kx32_1kx32 #(
.REGISTERS(1) // register output
.REGISTERS(1) // (0) // register output
) cmd0_buf_i (
.rclk (mclk), // input
.raddr (cmd_addr), // input[9:0]
.ren (!cmd_sel && cmd_busy && !pause), // input
.regen (!cmd_sel && cmd_busy && !pause), // input
/// .ren (!cmd_sel && cmd_busy && !pause), // input
/// .regen (!cmd_sel && cmd_busy && !pause), // input
.ren (ren0), // input TODO: verify cmd_busy[0] is correct (was cmd_busy )
.regen (ren0), // input
.data_out (phy_cmd0_word), // output[31:0]
.wclk (cmd0_clk), // input
.waddr (cmd0_addr), // input[9:0]
......@@ -238,12 +247,14 @@ module ddrc_sequencer #(
// Command sequence memory 0 ("manual"):
ram_1kx32_1kx32 #(
.REGISTERS(1) // register output
.REGISTERS(1) // (0) // register output
) cmd1_buf_i (
.rclk (mclk), // input
.raddr (cmd_addr), // input[9:0]
.ren ( cmd_sel && cmd_busy && !pause), // input
.regen ( cmd_sel && cmd_busy && !pause), // input
/// .ren ( cmd_sel && cmd_busy && !pause), // input
/// .regen ( cmd_sel && cmd_busy && !pause), // input
.ren ( ren1), // input
.regen ( ren1), // input
.data_out (phy_cmd1_word), // output[31:0]
.wclk (cmd1_clk), // input
.waddr (cmd1_addr), // input[9:0]
......@@ -302,7 +313,8 @@ module ddrc_sequencer #(
.CLKFBOUT_DIV_REF (CLKFBOUT_DIV_REF),
.DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.SDCLK_PHASE (SDCLK_PHASE),
.SDCLK_PHASE (SDCLK_PHASE),/// debugging
.CLK_PHASE (CLK_PHASE),
.CLK_DIV_PHASE (CLK_DIV_PHASE),
.MCLK_PHASE (MCLK_PHASE),
......@@ -314,6 +326,7 @@ module ddrc_sequencer #(
.CMD_DONE_BIT (CMD_DONE_BIT) // bit number (address) to signal sequence done
) phy_cmd_i (
.SDRST (SDRST), // output ****************
.SDCLK (SDCLK), // output
.SDNCLK (SDNCLK), // output
.SDA (SDA[ADDRESS_NUMBER-1:0]), // output[14:0]
......@@ -340,7 +353,9 @@ module ddrc_sequencer #(
.locked (locked), // output
.ps_rdy (ps_rdy), // output
.ps_out (ps_out[7:0]), // output[7:0]
.phy_cmd_word (phy_cmd_word[31:0]), // input[35:0]
/// debugging
// .phy_cmd_word (32'h0), //phy_cmd_word[31:0]), // input[31:0]
.phy_cmd_word (phy_cmd_word[31:0]), // input[31:0]
.phy_cmd_nop (phy_cmd_nop), // output
.pause_len (pause_len), // output [CMD_PAUSE_BITS-1:0]
.sequence_done (sequence_done), // output
......@@ -349,7 +364,9 @@ module ddrc_sequencer #(
.buf_rdata (buf_rdata[63:0]), // input[63:0]
.buf_wr (buf_wr), // output
.buf_rd (buf_rd), // output
.cmda_tri (cmda_tri), // input
.cmda_en (cmda_en), // input
.ddr_rst (ddr_rst), // input ***************
.ddr_cke (ddr_cke), // input ***************
.inv_clk_div (inv_clk_div), // input
.dqs_pattern (dqs_pattern), // input[7:0]
.dqm_pattern (dqm_pattern) // input[7:0]
......
......@@ -49,9 +49,10 @@ module phy_cmd#(
parameter CMD_DONE_BIT= 6 // bit number (address) to signal sequence done
)(
// DDR3 interface
output SDRST, // DDR3 reset (active low)
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 [ADDRESS_NUMBER-1:0] SDA, // output address ports (14:0) for 4Gb deviceencode_seq_word
output [2:0] SDBA, // output bank address ports
output SDWE, // output WE port
output SDRAS, // output RAS port
......@@ -91,7 +92,10 @@ module phy_cmd#(
output buf_wr, // write buffer (next cycle!)
output buf_rd, // read buffer (ready next cycle)
// extras
input cmda_tri, // tristate command and address lines // not likely to be used
// input cmda_tri, // tristate command and address lines // not likely to be used
input cmda_en, // tristate command and address lines // not likely to be used
input ddr_rst, // generate reset to DDR3 memory (active high)
input ddr_cke, // DDR clock enable , XOR-ed with command bit
input inv_clk_div,
input [7:0] dqs_pattern, // 8'h55
input [7:0] dqm_pattern // 8'h00
......@@ -104,16 +108,22 @@ module phy_cmd#(
// Decoding phy_cmd[35:0] into individual fields;
wire [ADDRESS_NUMBER-1:0] phy_addr_in; // also provides pause length when the command is NOP
wire [ 2:0] phy_bank_in;
wire [ 2:0] phy_rcw_pos; // positive lof=gic for RAS, CAS, WE (0 - NOP)
wire [ 2:0] phy_rcw_in; // {ras,cas,we}
wire phy_odt_in; // may be optimized?
wire phy_cke_dis; // command bit 0: enable CKE, 1 - disable CKE
wire phy_cke_in; // may be optimized?
wire phy_sel_in; // fitst/second half-cycle, oter will be nop (cke+odt applicable to both)
wire phy_sel_in; // first/second half-cycle, oter will be nop (cke+odt applicable to both)
wire phy_dq_en_in;
wire phy_dqs_en_in;
wire phy_dq_tri_in; // tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
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 [ 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 cmda_tri;
// wire clk;
wire clk_div;
......@@ -127,7 +137,7 @@ module phy_cmd#(
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 [1:0] phy_cke; // may be optphy_dqs_tri_inimized?
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;
......@@ -148,20 +158,25 @@ module phy_cmd#(
assign {
phy_addr_in,
phy_bank_in,
phy_rcw_in, // {ras,cas,we}
phy_rcw_pos, // {ras,cas,we}
phy_odt_in, // may be optimized?
phy_cke_in, // may be optimized?
phy_cke_dis, // disable cke (0 - enable), also controlled by a command bit ddr_cke (XOR-ed)
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_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_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)
phy_buf_rd, // connect to external buffer (but only if not paused)
phy_spare // Reserved for future use
} = phy_cmd_word;
assign phy_cmd_nop= (phy_rcw_in==0);
assign sequence_done= (phy_rcw_in==0) && phy_addr_in[CMD_DONE_BIT];
assign phy_cke_in= phy_cke_dis ^ ddr_cke;
assign phy_dq_tri_in= ~phy_dq_en_in;
assign phy_dqs_tri_in=~phy_dqs_en_in;
assign phy_dci_in= ~phy_dci_en_in;
assign phy_rcw_in= ~phy_rcw_pos;
assign phy_cmd_nop= (phy_rcw_pos==0);
assign sequence_done= phy_cmd_nop && phy_addr_in[CMD_DONE_BIT];
assign pause_len= phy_addr_in[CMD_PAUSE_BITS-1:0];
// assign buf_addr = phy_buf_addr;
......@@ -170,7 +185,7 @@ module phy_cmd#(
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_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?
......@@ -189,6 +204,8 @@ module phy_cmd#(
assign buf_wdata[63:0] = phy_rdata_r[63:0];
assign cmda_tri=!cmda_en;
always @ (posedge mclk) begin
dqs_tri_prev <= phy_dqs_tri_in;
dq_tri_prev <= phy_dq_tri_in;
......@@ -274,6 +291,7 @@ phy_rdata
.SS_MODE (SS_MODE),
.SS_MOD_PERIOD (SS_MOD_PERIOD)
) phy_top_i (
.ddr3_nrst (SDRST), // output
.ddr3_clk (SDCLK), // output
.ddr3_nclk (SDNCLK), // output
.ddr3_a (SDA[ADDRESS_NUMBER-1:0]), // output[14:0]
......@@ -295,7 +313,9 @@ phy_rdata
.clk (), // output
.clk_div (clk_div), // output
.mclk (mclk), // output
.rst_in (rst_in), // input
.ddr_rst (ddr_rst), // 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]
......
......@@ -52,6 +52,7 @@ module phy_top #(
parameter SS_MODE = "CENTER_HIGH",
parameter SS_MOD_PERIOD = 10000
)(
output ddr3_nrst, // output NRST port
output ddr3_clk, // DDR3 clock differential output, positive
output ddr3_nclk,// DDR3 clock differential output, negative
output [ADDRESS_NUMBER-1:0] ddr3_a, // output address ports (14:0) for 4Gb device
......@@ -75,7 +76,7 @@ module phy_top #(
output clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W), BUFR output
output mclk, // same as clk_div, through separate BUFG and static phase adjust
input rst_in, // reset delays/serdes
input ddr_rst, // active high - generate NRST to memory
input [2*ADDRESS_NUMBER-1:0] in_a, // input address, 2 bits per signal (first, second) (29:0) for 4Gb device
input [5:0] in_ba, // input bank address, 2 bits per signal (first, second)
input [1:0] in_we, // input WE, 2 bits (first, second)
......@@ -119,6 +120,19 @@ module phy_top #(
wire clk_ref; // 200MHz/300Mhz to calibrate I/O delays
wire locked_mmcm,locked_pll, dly_ready;
assign locked=locked_mmcm && locked_pll && dly_ready; // both PLL ready, I/O delay calibrated
/* memory reset */
obuf #(
.CAPACITANCE("DONT_CARE"),
.DRIVE(12),
.IOSTANDARD(IOSTANDARD_CMDA),
.SLEW("SLOW")
) obuf_i (
.O(ddr3_nrst), // output
.I(~ddr_rst) // input
);
cmd_addr #(
.IODELAY_GRP(IODELAY_GRP),
.IOSTANDARD(IOSTANDARD_CMDA),
......
......@@ -65,9 +65,10 @@ module fifo_cross_clocks
// False positive in nempty can only happen if
// a) it is transitioning from empty to non-empty due to we pulse
// b) it is transitioning to overrun - too bad already
// false negative - OK, just wait fro the next rclk
// false negative - OK, just wait for the next rclk
// assign nempty=waddr_gray_rclk != raddr_gray;
assign nempty=waddr_gray_rclk[3:0] != raddr_gray[3:0];
// assign nempty=waddr_gray_rclk[3:0] != raddr_gray[3:0];
assign nempty= (waddr_gray_rclk[3:0] ^ raddr_gray[3:0]) != 4'b0;
assign data_out=ram[raddr];
always @ (posedge wclk or posedge rst) begin
if (rst) waddr <= 0;
......
/*******************************************************************************
* Module: obuf
* Date:2014-05-27
* Author: Andrey Filippov
* Description: Wrapper for OBUF primitive
*
* Copyright (c) 2014 Elphel, Inc.
* obuf.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.
*
* obuf.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 obuf # (
parameter CAPACITANCE="DONT_CARE",
parameter DRIVE = 12,
parameter IOSTANDARD = "DEFAULT",
parameter SLEW = "SLOW"
) (
output O,
input I
);
OBUF #(
.CAPACITANCE(CAPACITANCE),
.DRIVE(DRIVE),
.IOSTANDARD(IOSTANDARD),
.SLEW(SLEW)
) OBUF_i (
.O(O), // output
.I(I) // input
);
endmodule
......@@ -21,7 +21,7 @@
`timescale 1ns/1ps
module oddr_ds # (
parameter CAPACITANCE ="DONT_CARE",
parameter CAPACITANCE = "DONT_CARE",
parameter IOSTANDARD = "DIFF_SSTL15",
parameter SLEW = "SLOW",
parameter DDR_CLK_EDGE = "OPPOSITE_EDGE",
......
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