// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: ddr_io.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program 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; version 2 of the License.
// This program 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
`ifdef AXIS_FBDIMM_NO_FSR
`endif // AXIS_FBDIMM_NO_FSR
dram_2x_clk, // 2x dram clock
clk_int, //internal clock
command_in, // 24bit command register
command_rdy, // command ready signal
command_type, // A. B or C
data_out, // dram data OUT
dcalcsr, // fbdimm register
clear_dcalcsr31, // to clear bit 31
dcaladdr, // fbdimm register
frm_boundary, // frame boundary signal
get_wbuffer_data, // get write buffer data
put_rbuffer_data, // put read buffer data
init, // initialization signal
drams_on_out, // special signal
output [18:0] cke_rank0,cke_rank1,bcs,bras,bcas,bwe,dqs,bdqs,dm_rdqs,brdqs,odt,areset,term;
`ifdef AXIS_FBDIMM_NO_FSR
`endif // AXIS_FBDIMM_NO_FSR
input [1:0] command_type;
inout [31:0] dcalcsr,dcaladdr,drc;
output ddrio_nbencode_rd;
// Internal registers/wires
wire [23:0] cmd_fifo_rd_data ;
wire [23:0] cmd_fifo_rd_data_bc ;
wire [23:0] command=cmd_fifo_rd_data;
wire [23:0] command_bc=cmd_fifo_rd_data_bc;
wire [23:0] write_cycle,read_cycle;
reg write_cycle_start,read_cycle_start;
wire dqs_driver = get_wbuffer_data & dram_dqs_clk ;
reg [18:0] cke_rank0_reg,cke_rank1_reg,bcs_reg,bdqs_reg,bras_reg,bcas_reg,bwe_reg,dqs_reg;
reg [18:0] dm_rdqs_reg,brdqs_reg,odt_reg,term_reg,areset_reg;
reg [4:0] self_refresh_fsm_state;
reg issue_auto_refresh_cmd;
reg issue_enter_self_refresh_cmd;
reg issue_exit_self_refresh_cmd;
reg [10:0] dram_clk_counter;
wire [18:0] bcs = bcs_reg;
wire [18:0] bras = bras_reg;
wire [18:0] bcas = bcas_reg;
wire [18:0] bwe = bwe_reg;
wire [18:0] dm_rdqs = dm_rdqs_reg ;
wire [18:0] brdqs = brdqs_reg;
wire [18:0] odt = odt_reg;
wire [18:0] term = term_reg;
wire [15:0] addr = addr_reg;
wire [18:0] areset= { 10 { init } };
wire cke_reg_1,cke_reg_delayed,dram_cmd_vld_1,dram_cmd_vld_delayed;
assign ddrio_nbencode_rd = read_cycle_start;
assign cke_rank0 = cke_rank0_reg ;
assign cke_rank1 = cke_rank1_reg;
assign drams_on_out = drams_on;
assign rs = issue_pre_all_cmd | issue_auto_refresh_cmd | issue_enter_self_refresh_cmd | issue_exit_self_refresh_cmd ? RS_pre : RS ;
assign dqs[0]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[1]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[2]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[3]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[4]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[5]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[6]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[7]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[8]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[9]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[10]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[11]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[12]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[13]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[14]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[15]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[16]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[17]= (dqs_cycle) ? dqs_driver: 1'bz;
assign dqs[18]= (dqs_cycle) ? dqs_driver: 1'bz;
assign bdqs[0] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[1] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[2] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[3] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[4] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[5] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[6] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[7] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[8] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[9] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[10] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[11] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[12] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[13] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[14] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[15] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[16] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[17] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign bdqs[18] = ( dqs_cycle ) ? ~dqs_driver : 1'bz;
assign clear_dcalcsr31 = dcalcsr_complete;
// Create a race free clock for driving dqs signals
// Read/Write pipleline stages
dff_p #(2) wc1( .signal_in ({write_cycle_start,read_cycle_start}),
.signal_out ({write_cycle[1],read_cycle[1]}),
.clk (dram_clk & drams_on ));
dff_p #(2) wc2( .signal_in ({write_cycle[1],read_cycle[1]}),
.signal_out ({write_cycle[2],read_cycle[2]}),
dff_p #(2) wc3( .signal_in ({write_cycle[2],read_cycle[2]}),
.signal_out ({write_cycle[3],read_cycle[3]}),
dff_p #(2) wc4( .signal_in ({write_cycle[3],read_cycle[3]}),
.signal_out ({write_cycle[4],read_cycle[4]}),
dff_p #(2) wc5( .signal_in ({write_cycle[4],read_cycle[4]}),
.signal_out ({write_cycle[5],read_cycle[5]}),
dff_p #(2) wc6( .signal_in ({write_cycle[5],read_cycle[5]}),
.signal_out ({write_cycle[6],read_cycle[6]}),
dff_p #(2) wc7( .signal_in ({write_cycle[6],read_cycle[6]}),
.signal_out ({write_cycle[7],read_cycle[7]}),
dff_p #(2) wc8( .signal_in ({write_cycle[7],read_cycle[7]}),
.signal_out ({write_cycle[8],read_cycle[8]}),
dff_p #(2) wc9( .signal_in ({write_cycle[8],read_cycle[8]}),
.signal_out ({write_cycle[9],read_cycle[9]}),
dff_p #(2) wc10( .signal_in ({write_cycle[8],read_cycle[9]}),
.signal_out ({write_cycle[9],read_cycle[10]}),
dff_p #(2) wc11( .signal_in ({write_cycle[8],read_cycle[10]}),
.signal_out ({write_cycle[9],read_cycle[11]}),
dff_p #(2) wc12( .signal_in ({write_cycle[8],read_cycle[11]}),
.signal_out ({write_cycle[9],read_cycle[12]}),
dff_p #(2) wc13( .signal_in ({write_cycle[8],read_cycle[12]}),
.signal_out ({write_cycle[9],read_cycle[13]}),
dff_p #(2) wc14( .signal_in ({write_cycle[8],read_cycle[13]}),
.signal_out ({write_cycle[9],read_cycle[14]}),
dff_p #(2) wc15( .signal_in ({write_cycle[8],read_cycle[14]}),
.signal_out ({write_cycle[9],read_cycle[15]}),
dff_p #(2) wc16( .signal_in ({write_cycle[8],read_cycle[15]}),
.signal_out ({write_cycle[9],read_cycle[16]}),
wire [9:0] delay_reg=((drc[7:4]+drc[3:0]))-10'h1;
wire write_cycle_pre = (delay_reg[7:0] == 7'h5 ) ? write_cycle[5] :
(delay_reg[7:0] == 7'h4 ) ? write_cycle[4] :
(delay_reg[7:0] == 7'h3 ) ? write_cycle[3] :
(delay_reg[7:0] == 7'h2 ) ? write_cycle[2] : 1'b0;
wire write_cycle0 = (delay_reg[7:0] == 7'h5 ) ? write_cycle[6] :
(delay_reg[7:0] == 7'h4 ) ? write_cycle[5] :
(delay_reg[7:0] == 7'h3 ) ? write_cycle[4] :
(delay_reg[7:0] == 7'h2 ) ? write_cycle[3] : 1'b0;
wire write_cycle1 = (delay_reg[7:0] == 7'h5 ) ? write_cycle[7] :
(delay_reg[7:0] == 7'h4 ) ? write_cycle[6] :
(delay_reg[7:0] == 7'h3 ) ? write_cycle[5] :
(delay_reg[7:0] == 7'h2 ) ? write_cycle[4] : 1'b0;
wire write_cycle2 = (delay_reg[7:0] == 7'h5 ) ? write_cycle[8] :
(delay_reg[7:0] == 7'h4 ) ? write_cycle[7] :
(delay_reg[7:0] == 7'h3 ) ? write_cycle[6] :
(delay_reg[7:0] == 7'h2 ) ? write_cycle[5] : 1'b0;
wire write_cycle3 = (delay_reg[7:0] == 7'h5 ) ? write_cycle[9] :
(delay_reg[7:0] == 7'h4 ) ? write_cycle[8] :
(delay_reg[7:0] == 7'h3 ) ? write_cycle[7] :
(delay_reg[7:0] == 7'h2 ) ? write_cycle[6] : 1'b0;
// Signal to get data from write fifo
assign get_wbuffer_data = ( write_cycle0 & dram_clk) |
( write_cycle0 & ~dram_clk) |
( write_cycle1 & dram_clk) |
( write_cycle1 & ~dram_clk) |
( write_cycle2 & dram_clk & ( sng_channel | dram_bl ) ) |
( write_cycle2 & ~dram_clk & ( sng_channel | dram_bl ) ) |
( write_cycle3 & dram_clk & ( sng_channel | dram_bl ) ) |
( write_cycle3 & ~dram_clk & ( sng_channel | dram_bl ) ) ;
// Signal to put data into read fifo
reg [3:0] dqs_curr_state;
reg put_rbuffer_data_alt;
wire axis_ddr2_dram_model;
reg put_rbuffer_data; // RALI
`endif // AXIS_DDR2_MODEL
assign put_rbuffer_data = put_rbuffer_data_alt; // RALI
`endif // AXIS_DDR2_MODEL
put_rbuffer_data=1'b0; //RALI
`endif // AXIS_DDR2_MODEL
always@(posedge dram_cmd_vld)
always@(negedge dram_2x_clk) //RALI
always@(posedge dram_2x_clk) //RALI
`endif // AXIS_DDR2_MODEL
if ( (dqs_in == 1 ) & !( get_wbuffer_data ) ) begin
always@(negedge dram_2x_clk)
assign dqs_cycle = ( write_cycle_pre & dram_clk ) |
( write_cycle_pre & ~dram_clk ) |
( write_cycle0 & dram_clk) |
( write_cycle0 & ~dram_clk) |
( write_cycle1 & dram_clk) |
( write_cycle1 & ~dram_clk) |
( write_cycle2 & dram_clk) |
( write_cycle2 & ~dram_clk & ( sng_channel | dram_bl ) ) |
( write_cycle3 & dram_clk & ( sng_channel | dram_bl ) ) |
( write_cycle3 & ~dram_clk & ( sng_channel | dram_bl ) );
wire [71:0] dq = get_wbuffer_data ? data_in : 72'bz;
reg [71:0] dq_shift_half_cycle;
dq_shift_half_cycle = 72'h0; //RALI
if ( $test$plusargs("SNG_CHANNEL") )
assign data_out = dq_shft; //RALI
assign data_out = dq_shift_half_cycle; //RALI
`endif // AXIS_DDR2_MODEL
always@(posedge dram_2x_clk) begin // RALI
dq_shift_half_cycle <= dq_shft;
always@(negedge dram_2x_clk) begin // RALI
dq_shift_half_cycle <= dq_shft;
put_rbuffer_data <= put_rbuffer_data_alt;
`endif // AXIS_DDR2_MODEL
always@(dram_clk or write_cycle0)
bdqs_reg[18:0] <= 19'h1ff;
bdqs_reg[18:0] <= 19'h7ffff;
dqs_reg[18:0] <= 19'h1ff;
dqs_reg[18:0] <= 19'h7ffff;
bdqs_reg[18:0] <= 19'h1ff;
bdqs_reg[18:0] <= 19'h7ffff;
wire enter_self_refresh_fsm = (( ch_state == `AMB_INIT_DISABLE ) | ( ch_state == `AMB_INIT_TRAIN )) ;
initial self_refresh_fsm_state = 1;
always@(posedge dram_clk) if ( dram_clk_counter_en )
dram_clk_counter <= dram_clk_counter + 11'h1;
dram_clk_counter <= 11'h0;
// taken from fbdimm spec oct 2004
always@(posedge dram_clk) if ( drams_on )
case ( self_refresh_fsm_state )
issue_pre_all_cmd <= 1'b0;
issue_auto_refresh_cmd <= 1'b0;
issue_enter_self_refresh_cmd <= 1'b0;
issue_exit_self_refresh_cmd <= 1'b0;
if (enter_self_refresh_fsm )
self_refresh_fsm_state <= 5'h2;
//if ( ch_state == `AMB_INIT_TRAIN )
// self_refresh_fsm_state <= 5'h2;
//`ifdef FBDIMM_ENABLE_SELF_REF_FSM
cke_rank0_reg[18:0] <= 19'h7ffff;
cke_rank1_reg[18:0] <= 19'h7ffff;
5'h2: begin self_refresh_fsm_state <= 5'h3; end
5'h3: begin self_refresh_fsm_state <= 5'h4; end
5'h4: begin self_refresh_fsm_state <= 5'h5; end
// self_refresh_fsm_state <= 5'h6;
dram_clk_counter_en <=1'b1;
if ( dram_clk_counter == 11'd30 ) begin
self_refresh_fsm_state <= 5'h6;
dram_clk_counter_en <= 1'b0;
cke_rank0_reg[18:0] <= 19'h7ffff;
cke_rank1_reg[18:0] <= 19'h7ffff;
self_refresh_fsm_state <= 5'h7;
issue_pre_all_cmd <= 1'b1;
self_refresh_fsm_state <= 5'h8;
issue_pre_all_cmd <= 1'b0;
self_refresh_fsm_state <= 5'h9;
issue_pre_all_cmd <= 1'b0;
self_refresh_fsm_state <= 5'ha;
5'ha: begin self_refresh_fsm_state <= 5'hb; end
`ifdef FBDIMM_ENABLE_SELF_REF_FSM
issue_auto_refresh_cmd <= 1'b1;
self_refresh_fsm_state <= 5'hc;
self_refresh_fsm_state <= 5'h16;
issue_auto_refresh_cmd <= 1'b0;
self_refresh_fsm_state <= 5'hd;
issue_auto_refresh_cmd <= 1'b0;
dram_clk_counter_en <=1'b1;
if ( dram_clk_counter == 11'd30 ) begin
self_refresh_fsm_state <= 5'he;
dram_clk_counter_en <= 1'b0;
`ifdef FBDIMM_ENABLE_SELF_REF_FSM
issue_enter_self_refresh_cmd <= 1'b1;
self_refresh_fsm_state <= 5'hf;
issue_enter_self_refresh_cmd <= 1'b0;
self_refresh_fsm_state <= 5'h10;
issue_enter_self_refresh_cmd <= 1'b0;
self_refresh_fsm_state <= 5'h11;
self_refresh_fsm_state <= 5'h12;
self_refresh_fsm_state <= 5'h13;
if ( ch_state == `AMB_INIT_TRAIN ) begin
`ifdef FBDIMM_ENABLE_SELF_REF_FSM
issue_exit_self_refresh_cmd <= 1'b1;
self_refresh_fsm_state <= 5'h14;
self_refresh_fsm_state <= 5'h15;
issue_exit_self_refresh_cmd <= 1'b0;
self_refresh_fsm_state <= 5'h16;
if ( ch_state == `AMB_INIT_LO )
self_refresh_fsm_state <= 5'h1;
self_refresh_fsm_state <=1;
issue_pre_all_cmd <= 1'b0;
always@(negedge dram_clk)
bcas_reg[18:0] <= 19'h7ffff;
addr_reg[15:0] <= 16'h400;
cke_rank0_reg[18:0] <= 19'h7ffff;
cke_rank1_reg[18:0] <= 19'h7ffff;
else if ( issue_auto_refresh_cmd) begin
bwe_reg[18:0] <= 19'h7ffff;
cke_rank0_reg[18:0] <= 19'h7ffff;
cke_rank1_reg[18:0] <= 19'h7ffff;
else if ( issue_enter_self_refresh_cmd ) begin
bwe_reg[18:0] <= 19'h7ffff;
else if ( issue_exit_self_refresh_cmd ) begin
bcas_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
else if ( drams_on ) begin
bcas_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
write_cycle_start <= 1'b0;
read_cycle_start <= 1'b0;
if ( !cmd_fifo_empty & !sb_crc_error ) begin
if ( command[23:0] == 24'h0 ) // NOP
bcas_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
if ( command[23:0] != 24'h0 ) // command is not a NOP
// all commands have the Rank Select bit at the same position
if (( command[20:18] == 3'b011 ) )
if (( command[20:18] == 3'b011 ) && ( command[23:21] == DS ) )
`endif // AXIS_FBDIMM_1AMB
bras_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command[15:13];
// For read/write, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {4'h0,command[11:0]};
//addr_reg[15:0] <= {4'h0,command[11],command[9:0]};
write_cycle_start <= 1'b1;
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Write command sent to DRAM - Address = %h BA=%h DS=%h RS=%h\n",addr_reg,ba_reg,command[23:21],RS);
if (( command[20:18] == 3'b010 ) )
if (( command[20:18] == 3'b010 ) && ( command[23:21] == DS ) )
`endif // AXIS_FBDIMM_1AMB
read_cycle_start <= 1'b1;
bwe_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command[15:13];
// For read/write, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {4'h0,command[11:0]};
if (( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b111) ) || issue_pre_all_cmd )
if (( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b111) && ( command[23:21] == DS )) || issue_pre_all_cmd )
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Precharge All command sent to DRAM\n");
bcas_reg[18:0] <= 19'h7ffff;
// precharge single command
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b110))
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b110) && ( command[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Precharge Single command sent to DRAM bank = %h\n",command[16:13]);
bcas_reg[18:0] <= 19'h7fff;
ba_reg[2:0] <= command[16:13];
// precharge signle command
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b101) )
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b101) && ( command[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: AutoRefresh command sent to DRAM\n");
bwe_reg[18:0] <= 19'h7ffff;
// Self refresh entry command
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b100))
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b100) && ( command[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Self Refresh Entry command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h0;
cke_rank0_reg[18:0] <= 19'h0;
bwe_reg[18:0] <= 19'h7ffff;
// Self refresh entry command
// Power Down entry command
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b0-10) )
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b0-10) && ( command[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Power Down Entry command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h0;
cke_rank0_reg[18:0] <= 19'h0;
bcas_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
// Power Down entry command
// Self refresh exit / power down exit command
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b011) )
if ( ( command[20:18] == 3'b001) && ( command[12:10] == 3'b011) && ( command[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Self Refresh/Power Down Exit command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h7ffff;
cke_rank0_reg[18:0] <= 19'h7ffff;
bcas_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
// Self refres hexit / power down exit command
if ( ( command[20] == 1'b1) )
if ( ( command[20] == 1'b1) && ( command[23:21] == DS ))
bcas_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command[15:13];
// For activate, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {command[19],command[18],command[16],command[12:0]};
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Activate command sent to DRAM - Address = %h BA =%h DS=%h RS=%h\n",addr_reg,command[15:13],command[23:21],RS);
// DRAM CKE per DIMM command
if ( ( command[20:14] == 7'b0000111) )
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: DRAM CKE per DIMM command detected\n");
if ( command[13] == 0 ) // bcst = 0
cke_rank1_reg[18:0] <= {19{command[0]}};
cke_rank0_reg[18:0] <= {19{command[0]}};
cke_rank1_reg[18:0] <= {19{command[1]}};
cke_rank0_reg[18:0] <= {19{command[1]}};
cke_rank1_reg[18:0] <= {19{command[2]}};
cke_rank0_reg[18:0] <= {19{command[2]}};
cke_rank1_reg[18:0] <= {19{command[3]}};
cke_rank0_reg[18:0] <= {19{command[3]}};
cke_rank1_reg[18:0] <= {19{command[4]}};
cke_rank0_reg[18:0] <= {19{command[4]}};
cke_rank1_reg[18:0] <= {19{command[5]}};
cke_rank0_reg[18:0] <= {19{command[5]}};
cke_rank1_reg[18:0] <= {19{command[6]}};
cke_rank0_reg[18:0] <= {19{command[6]}};
cke_rank1_reg[18:0] <= {19{command[7]}};
cke_rank0_reg[18:0] <= {19{command[7]}};
if ( command[13] == 1 ) // bcst = 1
cke_rank1_reg[18:0] <= {19{command[0]}};
cke_rank0_reg[18:0] <= {19{command[0]}};
cke_rank1_reg[18:0] <= {19{command[1]}};
cke_rank0_reg[18:0] <= {19{command[1]}};
cke_rank1_reg[18:0] <= {19{command[2]}};
cke_rank0_reg[18:0] <= {19{command[2]}};
cke_rank1_reg[18:0] <= {19{command[3]}};
cke_rank0_reg[18:0] <= {19{command[3]}};
cke_rank1_reg[18:0] <= {19{command[4]}};
cke_rank0_reg[18:0] <= {19{command[4]}};
cke_rank1_reg[18:0] <= {19{command[5]}};
cke_rank0_reg[18:0] <= {19{command[5]}};
cke_rank1_reg[18:0] <= {19{command[6]}};
cke_rank0_reg[18:0] <= {19{command[6]}};
cke_rank1_reg[18:0] <= {19{command[7]}};
cke_rank0_reg[18:0] <= {19{command[7]}};
// DRAM CKE per DIMM command
// DRAM CKE per Rank command
if ( ( command[20:14] == 7'b0000110) )
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: DRAM CKE per Rank command detected\n");
if ( command[13] == 0 ) // bcst = 0
3'b000: cke_rank1_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command[7]}};
3'b000: cke_rank0_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command[7]}};
if ( command[23:21] == DS )
3'b000: cke_rank1_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command[7]}};
3'b000: cke_rank0_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command[7]}};
if ( command[13] == 1 ) // bcst = 1
3'b000: cke_rank1_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command[7]}};
3'b000: cke_rank0_reg[18:0] <= {19{command[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command[7]}};
// DRAM CKE per Rank command
end // if (command[23:0] != 24'h0 )
end // if ( !cmd_fifo_empty)
if ( !cmd_fifo_empty_bc & !sb_crc_error ) begin
if ( command_bc[23:0] != 24'h0 ) // command is not a NOP
// all commands have the Rank Select bit at the same position
if (( command_bc[20:18] == 3'b011 ) )
if (( command_bc[20:18] == 3'b011 ) && ( command_bc[23:21] == DS ) )
`endif // AXIS_FBDIMM_1AMB
bras_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command_bc[15:13];
// For read/write, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {4'h0,command_bc[11:0]};
write_cycle_start <= 1'b1;
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Write command sent to DRAM - Address = %h BA=%h DS=%h RS=%h\n",addr_reg,ba_reg,command[23:21],RS);
if (( command_bc[20:18] == 3'b010 ) )
if (( command_bc[20:18] == 3'b010 ) && ( command_bc[23:21] == DS ) )
`endif // AXIS_FBDIMM_1AMB
read_cycle_start <= 1'b1;
bwe_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command_bc[15:13];
// For read/write, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {4'h0,command_bc[11:0]};
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Read command sent to DRAM - Address = %h BA = %h DS=%h RS=%h\n",addr_reg, ba_reg,command[23:21],RS);
if (( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b111)) || issue_pre_all_cmd )
if (( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b111) && ( command_bc[23:21] == DS )) || issue_pre_all_cmd )
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Precharge All command sent to DRAM\n");
bcas_reg[18:0] <= 19'h7ffff;
// precharge single command
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b110))
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b110) && ( command_bc[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Precharge Single command sent to DRAM bank = %h\n",command[16:13]);
bcas_reg[18:0] <= 19'h7fff;
ba_reg[2:0] <= command_bc[16:13];
// precharge signle command
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b101) )
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b101) && ( command_bc[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: AutoRefresh command sent to DRAM\n");
bwe_reg[18:0] <= 19'h7ffff;
// Self refresh entry command
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b100))
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b100) && ( command_bc[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Self Refresh Entry command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h0;
cke_rank0_reg[18:0] <= 19'h0;
bwe_reg[18:0] <= 19'h7ffff;
// Self refresh entry command
// Power Down entry command
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b010) )
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b010) && ( command_bc[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Power Down Entry command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h0;
cke_rank0_reg[18:0] <= 19'h0;
bcas_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
// Power Down entry command
// Self refresh exit / power down exit command
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b011) )
if ( ( command_bc[20:18] == 3'b001) && ( command_bc[12:10] == 3'b011) && ( command_bc[23:21] == DS ))
`endif // AXIS_FBDIMM_1AMB
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Self Refresh/Power Down Exit command sent to DRAM\n");
cke_rank1_reg[18:0] <= 19'h7ffff;
cke_rank0_reg[18:0] <= 19'h7ffff;
bcas_reg[18:0] <= 19'h7ffff;
bras_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
// Self refres hexit / power down exit command
if ( ( command_bc[20] == 1'b1) )
if ( ( command_bc[20] == 1'b1) && ( command_bc[23:21] == DS ))
bcas_reg[18:0] <= 19'h7ffff;
bwe_reg[18:0] <= 19'h7ffff;
ba_reg[2:0] <= command_bc[15:13];
// For activate, in 2GB(512MB X 4) config:
addr_reg[15:0] <= {command_bc[19],command_bc[18],command_bc[16],command_bc[12:0]};
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: Activate command sent to DRAM - Address = %h BA =%h DS=%h RS=%h\n",addr_reg,command[15:13],command[23:21],RS);
// DRAM CKE per DIMM command
if ( ( command_bc[20:14] == 7'b0000111) )
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: DRAM CKE per DIMM command detected\n");
if ( command_bc[13] == 0 ) // bcst = 0
cke_rank1_reg[18:0] <= {19{command_bc[0]}};
cke_rank0_reg[18:0] <= {19{command_bc[0]}};
cke_rank1_reg[18:0] <= {19{command_bc[1]}};
cke_rank0_reg[18:0] <= {19{command_bc[1]}};
cke_rank1_reg[18:0] <= {19{command_bc[2]}};
cke_rank0_reg[18:0] <= {19{command_bc[2]}};
cke_rank1_reg[18:0] <= {19{command_bc[3]}};
cke_rank0_reg[18:0] <= {19{command_bc[3]}};
cke_rank1_reg[18:0] <= {19{command_bc[4]}};
cke_rank0_reg[18:0] <= {19{command_bc[4]}};
cke_rank1_reg[18:0] <= {19{command_bc[5]}};
cke_rank0_reg[18:0] <= {19{command_bc[5]}};
cke_rank1_reg[18:0] <= {19{command_bc[6]}};
cke_rank0_reg[18:0] <= {19{command_bc[6]}};
cke_rank1_reg[18:0] <= {19{command_bc[7]}};
cke_rank0_reg[18:0] <= {19{command_bc[7]}};
if ( command_bc[13] == 1 ) // bcst = 1
cke_rank1_reg[18:0] <= {19{command_bc[0]}};
cke_rank0_reg[18:0] <= {19{command_bc[0]}};
cke_rank1_reg[18:0] <= {19{command_bc[1]}};
cke_rank0_reg[18:0] <= {19{command_bc[1]}};
cke_rank1_reg[18:0] <= {19{command_bc[2]}};
cke_rank0_reg[18:0] <= {19{command_bc[2]}};
cke_rank1_reg[18:0] <= {19{command_bc[3]}};
cke_rank0_reg[18:0] <= {19{command_bc[3]}};
cke_rank1_reg[18:0] <= {19{command_bc[4]}};
cke_rank0_reg[18:0] <= {19{command_bc[4]}};
cke_rank1_reg[18:0] <= {19{command_bc[5]}};
cke_rank0_reg[18:0] <= {19{command_bc[5]}};
cke_rank1_reg[18:0] <= {19{command_bc[6]}};
cke_rank0_reg[18:0] <= {19{command_bc[6]}};
cke_rank1_reg[18:0] <= {19{command_bc[7]}};
cke_rank0_reg[18:0] <= {19{command_bc[7]}};
// DRAM CKE per DIMM command
// DRAM CKE per Rank command
if ( ( command_bc[20:14] == 7'b0000110) )
`PR_ALWAYS ("dram",`DBG_0,"FBDIMM: DRAM CKE per Rank command detected\n");
if ( command_bc[13] == 0 ) // bcst = 0
if ( command_bc[17]) begin
3'b000: cke_rank1_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command_bc[7]}};
3'b000: cke_rank0_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command_bc[7]}};
if ( command_bc[23:21] == DS )
if ( command_bc[17]) begin
3'b000: cke_rank1_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command_bc[7]}};
3'b000: cke_rank0_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command_bc[7]}};
if ( command_bc[13] == 1 ) // bcst = 1
if ( command_bc[17]) begin
3'b000: cke_rank1_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank1_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank1_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank1_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank1_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank1_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank1_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank1_reg[18:0] <= {19{command_bc[7]}};
if ( command_bc[17]) begin
3'b000: cke_rank0_reg[18:0] <= {19{command_bc[0]}};
3'b001: cke_rank0_reg[18:0] <= {19{command_bc[1]}};
3'b010: cke_rank0_reg[18:0] <= {19{command_bc[2]}};
3'b011: cke_rank0_reg[18:0] <= {19{command_bc[3]}};
3'b100: cke_rank0_reg[18:0] <= {19{command_bc[4]}};
3'b101: cke_rank0_reg[18:0] <= {19{command_bc[5]}};
3'b110: cke_rank0_reg[18:0] <= {19{command_bc[6]}};
3'b111: cke_rank0_reg[18:0] <= {19{command_bc[7]}};
// DRAM CKE per Rank command
end // if (command_bc[23:0] != 24'h0 )
end // if ( !cmd_fifo_empty_bc)
// DCAL CSR register needs to send a command to drams
addr_reg<=dcaladdr[31:16];
wire write_cmd = command_rdy & ( command_in[23:0] != 24'h0);
// This fifo gets commands from sb decoder and sends to drams
beh_fifo #(24,9) cmd_fifo_A (.rdata (cmd_fifo_rd_data),
.rempty (cmd_fifo_empty),
.wdata (command_in[23:0]),
.winc (write_cmd & ( command_type[1:0] == 2'b11) ),
.rclk ( frm_boundary ), // dram_clk),
wire [23:0] command_in_bc = ( command_type[1:0] == 2'b11 ) ? 24'h0 : command_in;
beh_fifo #(24,9) cmd_fifo_BC (.rdata (cmd_fifo_rd_data_bc),
.wfull (cmd_fifo_full_bc),
.rempty (cmd_fifo_empty_bc),
.rclk ( frm_boundary ), // dram_clk),
// Dram devices for X8 configuration
ddr2_dram dram_1 ( .CK (dram_clk),
ddr2_dram dram_2 ( .CK (dram_clk),
ddr2_dram dram_3 ( .CK (dram_clk),
ddr2_dram dram_4 ( .CK (dram_clk),
ddr2_dram dram_5 ( .CK (dram_clk),
ddr2_dram dram_6 ( .CK (dram_clk),
ddr2_dram dram_7 ( .CK (dram_clk),
ddr2_dram dram_8 ( .CK (dram_clk),
ddr2_dram dram_9 ( .CK (dram_clk),
// Dram devices for X4 configuration
ddr2_dram dram_1 ( .CK (dram_clk),
ddr2_dram dram_2 ( .CK (dram_clk),
ddr2_dram dram_3 ( .CK (dram_clk),
ddr2_dram dram_4 ( .CK (dram_clk),
ddr2_dram dram_5 ( .CK (dram_clk),
ddr2_dram dram_6 ( .CK (dram_clk),
ddr2_dram dram_7 ( .CK (dram_clk),
ddr2_dram dram_8 ( .CK (dram_clk),
ddr2_dram dram_9 ( .CK (dram_clk),
ddr2_dram dram_10 ( .CK (dram_clk),
ddr2_dram dram_11 ( .CK (dram_clk),
ddr2_dram dram_12 ( .CK (dram_clk),
ddr2_dram dram_13 ( .CK (dram_clk),
ddr2_dram dram_14 ( .CK (dram_clk),
ddr2_dram dram_15 ( .CK (dram_clk),
ddr2_dram dram_16 ( .CK (dram_clk),
ddr2_dram dram_17 ( .CK (dram_clk),
ddr2_dram dram_18 ( .CK (dram_clk),
// !!!!! If we run on AXIS HW, we will not need tasks to initialize the DDR2 dram
cke_rank0_reg[18:1]={18{value}};
cke_rank1_reg[18:1]={18{value}};
bcas_reg[18:0]=19'h7ffff;
bras_reg[18:0]=19'h7ffff;
// refresh command emulation
// precharge command emulation
bcas_reg[18:0]=19'h7ffff;
// simulation of delay cycles
for(index=1; index<=cycle; index=index+1)
// Self Refresh Entry by AMB
`PR_ALWAYS ("dram_init",`DBG_0,"FBDIMM: Self Refresh Entry Started\n");
// Step:1 Wait tCKE then take all CKE signals high
cke_rank0_reg[18:0]=19'h7ffff; // keep CKE high
cke_rank1_reg[18:0]=19'h7ffff; // keep CKE high
// Step: 2 Wait tXSNR(tRFC + 10ns for ddr2)
// Note: OD must be low during the previous two steps
// Step:3 Issue precharge all to all ranks
// Step: 5 Assure ODT signals are low
// Step: 6 Issue enter self refresh
`PR_ALWAYS ("dram_init",`DBG_0,"FBDIMM: DRAMs in self refresh mode\n");
`endif //ifdef AXIS_DDR2_MODEL
// Initialization task for DRAMs
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init started\n");
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : CKE & ODT Driven Low\n");
bcs_reg[18:1]=0; // disable the chip
odt_reg[18:1]=0; // kep ODT low
cke_rank0_reg[18:1]=0; // keep CKE low
cke_rank1_reg[18:1]=0; // keep CKE low
bcas_reg[18:0]=19'h7ffff;
bras_reg[18:0]= 19'h7ffff;
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : NOP Driven on DRAM Control Signals\n");
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : CKE Driven High\n");
cke_rank0_reg[18:0]= 19'h7ffff;
cke_rank1_reg[18:0]= 19'h7ffff;
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Waiting for Delay 1 to End\n");
delays(45); // wait 400ns
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Precharge All\n");
delays(7); // changed for ST
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Issue EMRS(2)\n");
mrs_command(3'b010, 0); // issue mrs2
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Issue EMRS(3)\n");
mrs_command(3'b011, 0); // issue mrs3
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : EMRS(1) to enable DLL\n");
mrs_command(3'b001,{drc[6:4],1'b0,1'b0,1'b0}); // emrs to enable dll
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : MRS for DLL Reset\n");
mrs_command(3'b000, {3'b101,1'b1,1'b0,drc[2:0],1'b0,2'b01,drc[8]});
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Precharge all\n");
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : Refresh\n");
delays(42); // tRFC changed for ST
delays(42); // tRFC changed for ST
delays(42); // tRFC changed for ST
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : MRS to set A8 low to initialize device operation\n");
mrs_command(3'b000, {3'b101,1'b0,1'b0,drc[2:0],1'b0,2'b01,drc[8]});
delays(200); // make sure 200 cycles are consumed
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : EMRS1 for OCD default comand\n");
mrs_command(3'b001, {3'b111,1'b0,drc[6:4],3'b000});
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : EMRS1 to OCD Calibration Mode Exit\n");
mrs_command(3'b001, {3'b000,1'b0,drc[6:4], 3'b000}); // OCD exit
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init ended\n");
// Initialization task for DRAMs
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init started\n");
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St1: CKE & ODT Driven Low\n");
bcs_reg[18:1]=0; // disable the chip
odt_reg[18:1]=0; // kep ODT low
cke_rank0_reg[18:1]=0; // keep CKE low
cke_rank1_reg[18:1]=0; // keep CKE low
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St2: Everything high on dram interface\n");
bcas_reg[18:0]=19'h7ffff;
bras_reg[18:0]= 19'h7ffff;
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St3: NOP Driven on DRAM Control Signals\n");
cke_rank0_reg[18:0]= 19'h7ffff;
cke_rank1_reg[18:0]= 19'h7ffff;
delays(45); // wait 400ns
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init: St4: Precharge\n");
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St5: Mrs2\n");
mrs_command(3'b010, 0); // issue mrs2
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St6: mrs3\n");
mrs_command(3'b011, 0); // issue mrs3
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St7: Emrs1\n");
mrs_command(3'b001,{drc[6:4],1'b0,1'b0,1'b0}); // emrs to enable dll
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St8: Mrs\n");
mrs_command(3'b000, {3'b001,1'b1,1'b0,drc[2:0],1'b0,3'b011}); // BL = 8
mrs_command(3'b000, {3'b001,1'b1,1'b0,drc[2:0],1'b0,2'b01,drc[8]});
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init : St9: Precharge\n");
mrs_command(3'b000, {3'b001,1'b0,1'b0,drc[2:0],1'b0,3'b011}); // BL = 8
mrs_command(3'b000, {3'b001,1'b0,1'b0,3'b011,1'b0,2'b01,drc[8]});
delays(200); // make sure 200 cycles are consumed
mrs_command(3'b001, {3'b111,7'b11000});
mrs_command(3'b001, {3'b000,7'b11000}); // OCD exit
`PR_ALWAYS ("dram_init",`DBG_4,"FBDIMM: DRAM Init ended\n");
`endif // AXIS_DDR2_MODEL
if ( $test$plusargs("fbdimm_dbg_4"))
$ch_dispmon("dram_init",`DBG_4,1);
if ( $test$plusargs("fbdimm_dbg"))
$ch_dispmon("dram",`DBG_0,1);
bcas_reg[18:0] = 19'h7ffff;
bwe_reg[18:0] = 19'h7ffff;
bras_reg[18:0] = 19'h7ffff;
always@(posedge start_init_dram)
`endif // AXIS_DDR2_MODEL
if ( !$test$plusargs("AMB_DRAM_INIT"))
RS=0; // initialize rank 0 first
`endif // ifdef AXIS_DDR2_MODEL