OpenCores
URL https://opencores.org/ocsvn/wbddr3/wbddr3/trunk

Subversion Repositories wbddr3

[/] [wbddr3/] [trunk/] [rtl/] [wbddrsdram.v] - Diff between revs 9 and 10

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 9 Rev 10
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    wbddrsdram.v
// Filename:    wbddrsdram.v
//
//
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
//
//
// Purpose:     
// Purpose:     
//
//
/*
 
Stall logic:
 
        1. First clock sets r_* variables.
 
        2. Second clock sets need_* variables.  If need_open, need_close, or
 
                need_refresh are true, that should also set the o_wb_stall
 
                variable.  Well also move r_* info to s_* (think s=stall)
 
        3. If stalled, the next command comes from s_*.  Otherwise, from r_*.
 
        4. Bus FIFO fills from s_*
 
//
 
//
 
        For every transaction, one of 4 possibilities:
 
        1. Wait for refresh to complete
 
        2. Wait for precharge and activate to complete
 
        3. Wait for activate to complete
 
        4. Issue RW cmd
 
                5. Wait for bus transaction to complete
 
                6. ACK
 
*/
 
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// 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
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
 
 
// Possible commands to the DDR3 memory.  These consist of settings for the
// Possible commands to the DDR3 memory.  These consist of settings for the
// bits: o_wb_cs_n, o_wb_ras_n, o_wb_cas_n, and o_wb_we_n, respectively.
// bits: o_wb_cs_n, o_wb_ras_n, o_wb_cas_n, and o_wb_we_n, respectively.
`define DDR_MRSET       4'b0000
`define DDR_MRSET       4'b0000
`define DDR_REFRESH     4'b0001
`define DDR_REFRESH     4'b0001
`define DDR_PRECHARGE   4'b0010
`define DDR_PRECHARGE   4'b0010
`define DDR_ACTIVATE    4'b0011
`define DDR_ACTIVATE    4'b0011
`define DDR_WRITE       4'b0100
`define DDR_WRITE       4'b0100
`define DDR_READ        4'b0101
`define DDR_READ        4'b0101
`define DDR_ZQS         4'b0110
`define DDR_ZQS         4'b0110
`define DDR_NOOP        4'b0111
`define DDR_NOOP        4'b0111
//`define       DDR_DESELECT    4'b1???
//`define       DDR_DESELECT    4'b1???
//
//
// In this controller, 24-bit commands tend to be passed around.  These 
// In this controller, 24-bit commands tend to be passed around.  These 
// 'commands' are bit fields.  Here we specify the bits associated with
// 'commands' are bit fields.  Here we specify the bits associated with
// the bit fields.
// the bit fields.
`define DDR_RSTDONE     24      // End the reset sequence?
`define DDR_RSTDONE     24      // End the reset sequence?
`define DDR_RSTTIMER    23      // Does this reset command take multiple clocks?
`define DDR_RSTTIMER    23      // Does this reset command take multiple clocks?
`define DDR_RSTBIT      22      // Value to place on reset_n
`define DDR_RSTBIT      22      // Value to place on reset_n
`define DDR_CKEBIT      21      // Should this reset command set CKE?
`define DDR_CKEBIT      21      // Should this reset command set CKE?
//
//
// Refresh command bit fields
// Refresh command bit fields
`define DDR_NEEDREFRESH 23
`define DDR_NEEDREFRESH 23
`define DDR_RFTIMER     22
`define DDR_RFTIMER     22
`define DDR_RFBEGIN     21
`define DDR_RFBEGIN     21
//
//
`define DDR_CMDLEN      21
`define DDR_CMDLEN      21
`define DDR_CSBIT       20
`define DDR_CSBIT       20
`define DDR_RASBIT      19
`define DDR_RASBIT      19
`define DDR_CASBIT      18
`define DDR_CASBIT      18
`define DDR_WEBIT       17
`define DDR_WEBIT       17
`define DDR_NOPTIMER    16      // Steal this from BA bits
`define DDR_NOPTIMER    16      // Steal this from BA bits
`define DDR_BABITS      3       // BABITS are really from 18:16, they are 3 bits
`define DDR_BABITS      3       // BABITS are really from 18:16, they are 3 bits
`define DDR_ADDR_BITS   14
`define DDR_ADDR_BITS   14
//
//
`define BUSREG  7
`define BUSREG  7
`define BUSNOW  8
`define BUSNOW  8
 
 
module  wbddrsdram(i_clk, i_reset,
module  wbddrsdram(i_clk, i_reset,
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
                        o_wb_ack, o_wb_stall, o_wb_data,
                        o_wb_ack, o_wb_stall, o_wb_data,
                o_ddr_reset_n, o_ddr_cke,
                o_ddr_reset_n, o_ddr_cke,
                o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
                o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
                o_ddr_dqs, o_ddr_dm, o_ddr_odt, o_ddr_bus_oe,
                o_ddr_dqs, o_ddr_dm, o_ddr_odt, o_ddr_bus_oe,
                o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data,
                o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data);
                o_cmd_accepted);
 
        parameter       CKREFI4 = 13'd6240, // 4 * 7.8us at 200 MHz clock
        parameter       CKREFI4 = 13'd6240, // 4 * 7.8us at 200 MHz clock
                        CKRFC = 320,
                        CKRFC = 320,
                        CKXPR = CKRFC+5+2; // Clocks per tXPR timeout
                        CKXPR = CKRFC+5+2; // Clocks per tXPR timeout
        input                   i_clk, i_reset;
        input                   i_clk, i_reset;
        // Wishbone inputs
        // Wishbone inputs
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
        input           [25:0]   i_wb_addr;
        input           [25:0]   i_wb_addr;
        input           [31:0]   i_wb_data;
        input           [31:0]   i_wb_data;
        // Wishbone outputs
        // Wishbone outputs
        output  reg             o_wb_ack;
        output  reg             o_wb_ack;
        output  reg             o_wb_stall;
        output  reg             o_wb_stall;
        output  reg     [31:0]   o_wb_data;
        output  reg     [31:0]   o_wb_data;
        // DDR3 RAM Controller
        // DDR3 RAM Controller
        output  wire            o_ddr_reset_n, o_ddr_cke;
        output  wire            o_ddr_reset_n, o_ddr_cke;
        // Control outputs
        // Control outputs
        output  reg             o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n,o_ddr_we_n;
        output  reg             o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n,o_ddr_we_n;
        // DQS outputs:set to 3'b010 when data is active, 3'b100 (i.e. 2'bzz) ow
        // DQS outputs:set to 3'b010 when data is active, 3'b100 (i.e. 2'bzz) ow
        output  wire            o_ddr_dqs;
        output  wire            o_ddr_dqs;
        output  reg             o_ddr_dm, o_ddr_odt, o_ddr_bus_oe;
        output  reg             o_ddr_dm, o_ddr_odt, o_ddr_bus_oe;
        // Address outputs
        // Address outputs
        output  reg     [13:0]   o_ddr_addr;
        output  reg     [13:0]   o_ddr_addr;
        output  reg     [2:0]    o_ddr_ba;
        output  reg     [2:0]    o_ddr_ba;
        // And the data inputs and outputs
        // And the data inputs and outputs
        output  reg     [31:0]   o_ddr_data;
        output  reg     [31:0]   o_ddr_data;
        input           [31:0]   i_ddr_data;
        input           [31:0]   i_ddr_data;
        // And just for the test bench
 
        output  reg             o_cmd_accepted;
 
 
 
        always @(posedge i_clk)
 
                o_cmd_accepted <= (i_wb_stb)&&(~o_wb_stall);
 
 
 
        reg             drive_dqs;
        reg             drive_dqs;
 
 
        // The pending transaction
        // The pending transaction
        reg     [31:0]   r_data;
        reg     [31:0]   r_data;
        reg             r_pending, r_we;
        reg             r_pending, r_we;
        reg     [25:0]   r_addr;
        reg     [25:0]   r_addr;
        reg     [13:0]   r_row;
        reg     [13:0]   r_row;
        reg     [2:0]    r_bank;
        reg     [2:0]    r_bank;
        reg     [9:0]    r_col;
        reg     [9:0]    r_col;
        reg     [1:0]    r_sub;
        reg     [1:0]    r_sub;
        reg             r_move; // It was accepted, and can move to next stage
        reg             r_move; // It was accepted, and can move to next stage
 
 
        // The pending transaction, one further into the pipeline.  This is
        // The pending transaction, one further into the pipeline.  This is
        // the stage where the read/write command is actually given to the
        // the stage where the read/write command is actually given to the
        // interface if we haven't stalled.
        // interface if we haven't stalled.
        reg     [31:0]   s_data;
        reg     [31:0]   s_data;
        reg             s_pending, s_we, s_match;
        reg             s_pending, s_we; // , s_match;
        reg     [25:0]   s_addr;
        reg     [25:0]   s_addr;
        reg     [13:0]   s_row, s_nxt_row;
        reg     [13:0]   s_row, s_nxt_row;
        reg     [2:0]    s_bank, s_nxt_bank;
        reg     [2:0]    s_bank, s_nxt_bank;
        reg     [9:0]    s_col;
        reg     [9:0]    s_col;
        reg     [1:0]    s_sub;
        reg     [1:0]    s_sub;
 
 
        // Can the pending transaction be satisfied with the current (ongoing)
        // Can the pending transaction be satisfied with the current (ongoing)
        // transaction?
        // transaction?
        reg             m_move, m_match, m_pending, m_we;
        reg             m_move, m_match, m_pending, m_we;
        reg     [25:0]   m_addr;
        reg     [25:0]   m_addr;
        reg     [13:0]   m_row;
        reg     [13:0]   m_row;
        reg     [2:0]    m_bank;
        reg     [2:0]    m_bank;
        reg     [9:0]    m_col;
        reg     [9:0]    m_col;
        reg     [1:0]    m_sub;
        reg     [1:0]    m_sub;
 
 
        // Can we preload the next bank?
        // Can we preload the next bank?
        reg     [13:0]   r_nxt_row;
        reg     [13:0]   r_nxt_row;
        reg     [2:0]    r_nxt_bank;
        reg     [2:0]    r_nxt_bank;
 
 
        reg     need_close_bank, need_close_this_bank,
        reg     need_close_bank, need_close_this_bank,
                        last_close_bank, maybe_close_next_bank,
                        last_close_bank, maybe_close_next_bank,
                        last_maybe_close,
                        last_maybe_close,
                need_open_bank, last_open_bank, maybe_open_next_bank,
                need_open_bank, last_open_bank, maybe_open_next_bank,
                        last_maybe_open,
                        last_maybe_open,
                valid_bank, last_valid_bank;
                valid_bank, last_valid_bank;
        reg     [(`DDR_CMDLEN-1):0]      close_bank_cmd, activate_bank_cmd,
        reg     [(`DDR_CMDLEN-1):0]      close_bank_cmd, activate_bank_cmd,
                                        maybe_close_cmd, maybe_open_cmd, rw_cmd;
                                        maybe_close_cmd, maybe_open_cmd, rw_cmd;
        reg     [1:0]    rw_sub;
        reg     [1:0]    rw_sub;
        reg             rw_we;
        reg             rw_we;
 
 
        wire    w_this_closing_bank, w_this_opening_bank,
        wire    w_this_closing_bank, w_this_opening_bank,
                w_this_maybe_close, w_this_maybe_open,
                w_this_maybe_close, w_this_maybe_open,
                w_this_rw_move;
                w_this_rw_move;
        reg     last_closing_bank, last_opening_bank;
        reg     last_closing_bank, last_opening_bank;
//
//
// tWTR = 7.5
// tWTR = 7.5
// tRRD = 7.5
// tRRD = 7.5
// tREFI= 7.8
// tREFI= 7.8
// tFAW = 45
// tFAW = 45
// tRTP = 7.5
// tRTP = 7.5
// tCKE = 5.625
// tCKE = 5.625
// tRFC = 160
// tRFC = 160
// tRP  = 13.5
// tRP  = 13.5
// tRAS = 36
// tRAS = 36
// tRCD = 13.5
// tRCD = 13.5
//
//
// RESET:
// RESET:
//      1. Hold o_reset_n = 1'b0; for 200 us, or 40,000 clocks (65536 perhaps?)
//      1. Hold o_reset_n = 1'b0; for 200 us, or 40,000 clocks (65536 perhaps?)
//              Hold cke low during this time as well
//              Hold cke low during this time as well
//              The clock should be free running into the chip during this time
//              The clock should be free running into the chip during this time
//              Leave command in NOOP state: {cs,ras,cas,we} = 4'h7;
//              Leave command in NOOP state: {cs,ras,cas,we} = 4'h7;
//              ODT must be held low
//              ODT must be held low
//      2. Hold cke low for another 500us, or 100,000 clocks
//      2. Hold cke low for another 500us, or 100,000 clocks
//      3. Raise CKE, continue outputting a NOOP for
//      3. Raise CKE, continue outputting a NOOP for
//              tXPR, tDLLk, and tZQInit
//              tXPR, tDLLk, and tZQInit
//      4. Load MRS2, wait tMRD
//      4. Load MRS2, wait tMRD
//      4. Load MRS3, wait tMRD
//      4. Load MRS3, wait tMRD
//      4. Load MRS1, wait tMOD
//      4. Load MRS1, wait tMOD
// Before using the SDRAM, we'll need to program at least 3 of the mode
// Before using the SDRAM, we'll need to program at least 3 of the mode
//      registers, if not all 4. 
//      registers, if not all 4. 
//   tMOD clocks are required to program the mode registers, during which
//   tMOD clocks are required to program the mode registers, during which
//      time the RAM must be idle.
//      time the RAM must be idle.
//
//
// NOOP: CS low, RAS, CAS, and WE high
// NOOP: CS low, RAS, CAS, and WE high
 
 
//
//
// Reset logic should be simple, and is given as follows:
// Reset logic should be simple, and is given as follows:
// note that it depends upon a ROM memory, reset_mem, and an address into that
// note that it depends upon a ROM memory, reset_mem, and an address into that
// memory: reset_address.  Each memory location provides either a "command" to
// memory: reset_address.  Each memory location provides either a "command" to
// the DDR3 SDRAM, or a timer to wait until the next command.  Further, the
// the DDR3 SDRAM, or a timer to wait until the next command.  Further, the
// timer commands indicate whether or not the command during the timer is to
// timer commands indicate whether or not the command during the timer is to
// be set to idle, or whether the command is instead left as it was.
// be set to idle, or whether the command is instead left as it was.
        reg             reset_override, reset_ztimer, maintenance_override;
        reg             reset_override, reset_ztimer, maintenance_override;
        reg     [4:0]    reset_address;
        reg     [4:0]    reset_address;
        reg     [(`DDR_CMDLEN-1):0]      reset_cmd, cmd, refresh_cmd,
        reg     [(`DDR_CMDLEN-1):0]      reset_cmd, cmd, refresh_cmd,
                                        maintenance_cmd;
                                        maintenance_cmd;
        reg     [24:0]   reset_instruction;
        reg     [24:0]   reset_instruction;
        reg     [16:0]   reset_timer;
        reg     [16:0]   reset_timer;
        initial reset_override = 1'b1;
        initial reset_override = 1'b1;
        initial reset_address  = 5'h0;
        initial reset_address  = 5'h0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                begin
                begin
                        reset_override <= 1'b1;
                        reset_override <= 1'b1;
                        reset_cmd <= { `DDR_NOOP, reset_instruction[16:0]};
                        reset_cmd <= { `DDR_NOOP, reset_instruction[16:0]};
                end else if (reset_ztimer)
                end else if (reset_ztimer)
                begin
                begin
                        if (reset_instruction[`DDR_RSTDONE])
                        if (reset_instruction[`DDR_RSTDONE])
                                reset_override <= 1'b0;
                                reset_override <= 1'b0;
                        reset_cmd <= reset_instruction[20:0];
                        reset_cmd <= reset_instruction[20:0];
                end
                end
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        o_ddr_cke <= 1'b0;
                        o_ddr_cke <= 1'b0;
                else if ((reset_override)&&(reset_ztimer))
                else if ((reset_override)&&(reset_ztimer))
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
 
 
        initial reset_ztimer = 1'b0;    // Is the timer zero?
        initial reset_ztimer = 1'b0;    // Is the timer zero?
        initial reset_timer = 17'h02;
        initial reset_timer = 17'h02;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                begin
                begin
                        reset_ztimer <= 1'b0;
                        reset_ztimer <= 1'b0;
                        reset_timer <= 17'd2;
                        reset_timer <= 17'd2;
                end else if (!reset_ztimer)
                end else if (!reset_ztimer)
                begin
                begin
                        reset_ztimer <= (reset_timer == 17'h01);
                        reset_ztimer <= (reset_timer == 17'h01);
                        reset_timer <= reset_timer - 17'h01;
                        reset_timer <= reset_timer - 17'h01;
                end else if (reset_instruction[`DDR_RSTTIMER])
                end else if (reset_instruction[`DDR_RSTTIMER])
                begin
                begin
                        reset_ztimer <= 1'b0;
                        reset_ztimer <= 1'b0;
                        reset_timer <= reset_instruction[16:0];
                        reset_timer <= reset_instruction[16:0];
                end
                end
 
 
        wire    [16:0]   w_ckXPR = CKXPR, w_ckRST = 4, w_ckRP = 3,
        wire    [16:0]   w_ckXPR = CKXPR, w_ckRST = 4, w_ckRP = 3,
                        w_ckRFC = CKRFC;
                        w_ckRFC = CKRFC;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
                        reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
                else if (reset_ztimer) case(reset_address) // RSTDONE, TIMER, CKE, ??
                else if (reset_ztimer) case(reset_address) // RSTDONE, TIMER, CKE, ??
                // 1. Reset asserted (active low) for 200 us. (@200MHz)
                // 1. Reset asserted (active low) for 200 us. (@200MHz)
                5'h0: reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
                5'h0: reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
                // 2. Reset de-asserted, wait 500 us before asserting CKE
                // 2. Reset de-asserted, wait 500 us before asserting CKE
                5'h1: reset_instruction <= { 4'h6, `DDR_NOOP, 17'd100_000 };
                5'h1: reset_instruction <= { 4'h6, `DDR_NOOP, 17'd100_000 };
                // 3. Assert CKE, wait minimum of Reset CKE Exit time
                // 3. Assert CKE, wait minimum of Reset CKE Exit time
                5'h2: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckXPR };
                5'h2: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckXPR };
                // 4. Look MR2.  (1CK, no TIMER)
                // 4. Look MR2.  (1CK, no TIMER)
                5'h3: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h2,
                5'h3: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h2,
                        3'h0, 2'b00, 1'b0, 1'b0, 1'b1, 3'b0, 3'b0 }; // MRS2
                        3'h0, 2'b00, 1'b0, 1'b0, 1'b1, 3'b0, 3'b0 }; // MRS2
                // 3. Wait 4 clocks (tMRD)
                // 3. Wait 4 clocks (tMRD)
                5'h4: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
                5'h4: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
                // 5. Set MR1
                // 5. Set MR1
                5'h5: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h1,
                5'h5: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h1,
                        1'h0, // Reserved for Future Use (RFU)
                        1'h0, // Reserved for Future Use (RFU)
                        1'b0, // Qoff - output buffer enabled
                        1'b0, // Qoff - output buffer enabled
                        1'b1, // TDQS ... enabled
                        1'b1, // TDQS ... enabled
                        1'b0, // RFU
                        1'b0, // RFU
                        1'b0, // High order bit, Rtt_Nom (3'b011)
                        1'b0, // High order bit, Rtt_Nom (3'b011)
                        1'b0, // RFU
                        1'b0, // RFU
                        //
                        //
                        1'b0, // Disable write-leveling
                        1'b0, // Disable write-leveling
                        1'b1, // Mid order bit of Rtt_Nom
                        1'b1, // Mid order bit of Rtt_Nom
                        1'b0, // High order bit of Output Drvr Impedence Ctrl
                        1'b0, // High order bit of Output Drvr Impedence Ctrl
                        2'b0, // Additive latency = 0
                        2'b0, // Additive latency = 0
                        1'b1, // Low order bit of Rtt_Nom
                        1'b1, // Low order bit of Rtt_Nom
                        1'b1, // DIC set to 2'b01
                        1'b1, // DIC set to 2'b01
                        1'b1 }; // MRS1, DLL enable
                        1'b1 }; // MRS1, DLL enable
                // 7. Wait another 4 clocks
                // 7. Wait another 4 clocks
                5'h6: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
                5'h6: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
                // 8. Send MRS0
                // 8. Send MRS0
                5'h7: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h0,
                5'h7: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h0,
                        1'b0, // Reserved for future use
                        1'b0, // Reserved for future use
                        1'b0, // PPD control, (slow exit(DLL off))
                        1'b0, // PPD control, (slow exit(DLL off))
                        3'b1, // Write recovery for auto precharge
                        3'b1, // Write recovery for auto precharge
                        1'b0, // DLL Reset (No)
                        1'b0, // DLL Reset (No)
                        //
                        //
                        1'b0, // TM mode normal
                        1'b0, // TM mode normal
                        3'b01, // High 3-bits, CAS latency (=4'b0010 = 4'd5)
                        3'b01, // High 3-bits, CAS latency (=4'b0010 = 4'd5)
                        1'b0, // Read burst type = nibble sequential
                        1'b0, // Read burst type = nibble sequential
                        1'b0, // Low bit of cas latency
                        1'b0, // Low bit of cas latency
                        2'b0 }; // Burst length = 8 (Fixed)
                        2'b0 }; // Burst length = 8 (Fixed)
                // 9. Wait tMOD, is max(12 clocks, 15ns)
                // 9. Wait tMOD, is max(12 clocks, 15ns)
                5'h8: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h0a };
                5'h8: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h0a };
                // 10. Issue a ZQCL command to start ZQ calibration, A10 is high
                // 10. Issue a ZQCL command to start ZQ calibration, A10 is high
                5'h9: reset_instruction <= { 4'h3, `DDR_ZQS, 6'h0, 1'b1, 10'h0};
                5'h9: reset_instruction <= { 4'h3, `DDR_ZQS, 6'h0, 1'b1, 10'h0};
                //11.Wait for both tDLLK and tZQinit completed, both are 512 cks
                //11.Wait for both tDLLK and tZQinit completed, both are 512 cks
                5'ha: reset_instruction <= { 4'h7, `DDR_NOOP, 17'd512 };
                5'ha: reset_instruction <= { 4'h7, `DDR_NOOP, 17'd512 };
                // 12. Precharge all command
                // 12. Precharge all command
                5'hb: reset_instruction <= { 4'h3, `DDR_PRECHARGE, 6'h0, 1'b1, 10'h0 };
                5'hb: reset_instruction <= { 4'h3, `DDR_PRECHARGE, 6'h0, 1'b1, 10'h0 };
                // 13. Wait for the precharge to complete
                // 13. Wait for the precharge to complete
                5'hc: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRP };
                5'hc: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRP };
                // 14. A single Auto Refresh commands
                // 14. A single Auto Refresh commands
                5'hd: reset_instruction <= { 4'h3, `DDR_REFRESH, 17'h00 };
                5'hd: reset_instruction <= { 4'h3, `DDR_REFRESH, 17'h00 };
                // 15. Wait for the auto refresh to complete
                // 15. Wait for the auto refresh to complete
                5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
                5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
                // Two Auto Refresh commands
                // Two Auto Refresh commands
                default:
                default:
                        reset_instruction <={4'hb, `DDR_NOOP, 17'd00_000 };
                        reset_instruction <={4'hb, `DDR_NOOP, 17'd00_000 };
                endcase
                endcase
                // reset_instruction <= reset_mem[reset_address];
                // reset_instruction <= reset_mem[reset_address];
 
 
        initial reset_address = 5'h0;
        initial reset_address = 5'h0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        reset_address <= 5'h1;
                        reset_address <= 5'h1;
                else if ((reset_ztimer)&&(reset_override))
                else if ((reset_ztimer)&&(reset_override))
                        reset_address <= reset_address + 5'h1;
                        reset_address <= reset_address + 5'h1;
//
//
// initial reset_mem =
// initial reset_mem =
//       0.     !DONE, TIMER,RESET_N=0, CKE=0, CMD = NOOP, TIMER = 200us ( 40,000)
//       0.     !DONE, TIMER,RESET_N=0, CKE=0, CMD = NOOP, TIMER = 200us ( 40,000)
//       1.     !DONE, TIMER,RESET_N=1, CKE=0, CMD = NOOP, TIMER = 500us (100,000)
//       1.     !DONE, TIMER,RESET_N=1, CKE=0, CMD = NOOP, TIMER = 500us (100,000)
//       2.     !DONE, TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = (Look me up)
//       2.     !DONE, TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = (Look me up)
//       3.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS
//       3.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS
//       4.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       4.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       5.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS3
//       5.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS3
//       6.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       6.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       7.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
//       7.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
//       8.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       8.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
//       9.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
//       9.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
//      10.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMOD
//      10.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMOD
//      11.     !DONE,!TIMER,RESET_N=1, CKE=1, (Pre-charge all)
//      11.     !DONE,!TIMER,RESET_N=1, CKE=1, (Pre-charge all)
//      12.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
//      12.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
//      13.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
//      13.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
//      14.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
//      14.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
//      15.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
//      15.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
 
 
 
 
//
//
//
//
// Let's keep track of any open banks.  There are 8 of them to keep track of.
// Let's keep track of any open banks.  There are 8 of them to keep track of.
//
//
//      A precharge requires 3 clocks at 200MHz to complete, 2 clocks at 100MHz.
//      A precharge requires 3 clocks at 200MHz to complete, 2 clocks at 100MHz.
//      
//      
//
//
//
//
        reg     need_refresh;
        reg     need_refresh;
 
 
        wire    w_precharge_all;
        wire    w_precharge_all;
        reg     banks_are_closing, all_banks_closed;
        reg     banks_are_closing, all_banks_closed;
        reg     [3:0]    bank_status     [0:7];
        reg     [3:0]    bank_status     [0:7];
        reg     [13:0]   bank_address    [0:7];
        reg     [13:0]   bank_address    [0:7];
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
                bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
                bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
                bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
                bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
                bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
                bank_status[3] <= { bank_status[3][2:0], bank_status[3][0] };
                bank_status[3] <= { bank_status[3][2:0], bank_status[3][0] };
                bank_status[4] <= { bank_status[4][2:0], bank_status[4][0] };
                bank_status[4] <= { bank_status[4][2:0], bank_status[4][0] };
                bank_status[5] <= { bank_status[5][2:0], bank_status[5][0] };
                bank_status[5] <= { bank_status[5][2:0], bank_status[5][0] };
                bank_status[6] <= { bank_status[6][2:0], bank_status[6][0] };
                bank_status[6] <= { bank_status[6][2:0], bank_status[6][0] };
                bank_status[7] <= { bank_status[7][2:0], bank_status[7][0] };
                bank_status[7] <= { bank_status[7][2:0], bank_status[7][0] };
                all_banks_closed <= (bank_status[0][2:0] == 3'b00)
                all_banks_closed <= (bank_status[0][2:0] == 3'b00)
                                        &&(bank_status[1][2:0] == 3'b00)
                                        &&(bank_status[1][2:0] == 3'b00)
                                        &&(bank_status[2][2:0] == 3'b00)
                                        &&(bank_status[2][2:0] == 3'b00)
                                        &&(bank_status[3][2:0] == 3'b00)
                                        &&(bank_status[3][2:0] == 3'b00)
                                        &&(bank_status[4][2:0] == 3'b00)
                                        &&(bank_status[4][2:0] == 3'b00)
                                        &&(bank_status[5][2:0] == 3'b00)
                                        &&(bank_status[5][2:0] == 3'b00)
                                        &&(bank_status[6][2:0] == 3'b00)
                                        &&(bank_status[6][2:0] == 3'b00)
                                        &&(bank_status[7][2:0] == 3'b00);
                                        &&(bank_status[7][2:0] == 3'b00);
                if (reset_override)
                if (reset_override)
                begin
                begin
                        bank_status[0][0] <= 1'b0;
                        bank_status[0][0] <= 1'b0;
                        bank_status[1][0] <= 1'b0;
                        bank_status[1][0] <= 1'b0;
                        bank_status[2][0] <= 1'b0;
                        bank_status[2][0] <= 1'b0;
                        bank_status[3][0] <= 1'b0;
                        bank_status[3][0] <= 1'b0;
                        bank_status[4][0] <= 1'b0;
                        bank_status[4][0] <= 1'b0;
                        bank_status[5][0] <= 1'b0;
                        bank_status[5][0] <= 1'b0;
                        bank_status[6][0] <= 1'b0;
                        bank_status[6][0] <= 1'b0;
                        bank_status[7][0] <= 1'b0;
                        bank_status[7][0] <= 1'b0;
                        banks_are_closing <= 1'b1;
                        banks_are_closing <= 1'b1;
                end else if ((need_refresh)||(w_precharge_all))
                end else if ((need_refresh)||(w_precharge_all))
                begin
                begin
                        bank_status[0][0] <= 1'b0;
                        bank_status[0][0] <= 1'b0;
                        bank_status[1][0] <= 1'b0;
                        bank_status[1][0] <= 1'b0;
                        bank_status[2][0] <= 1'b0;
                        bank_status[2][0] <= 1'b0;
                        bank_status[3][0] <= 1'b0;
                        bank_status[3][0] <= 1'b0;
                        bank_status[4][0] <= 1'b0;
                        bank_status[4][0] <= 1'b0;
                        bank_status[5][0] <= 1'b0;
                        bank_status[5][0] <= 1'b0;
                        bank_status[6][0] <= 1'b0;
                        bank_status[6][0] <= 1'b0;
                        bank_status[7][0] <= 1'b0;
                        bank_status[7][0] <= 1'b0;
                        banks_are_closing <= 1'b1;
                        banks_are_closing <= 1'b1;
                end else if (need_close_bank)
                end else if (need_close_bank)
                begin
                begin
                        bank_status[close_bank_cmd[16:14]]
                        bank_status[close_bank_cmd[16:14]]
                                <= { bank_status[close_bank_cmd[16:14]][2:0], 1'b0 };
                                <= { bank_status[close_bank_cmd[16:14]][2:0], 1'b0 };
                        // bank_status[close_bank_cmd[16:14]][0] <= 1'b0;
                        // bank_status[close_bank_cmd[16:14]][0] <= 1'b0;
                end else if (need_open_bank)
                end else if (need_open_bank)
                begin
                begin
                        bank_status[activate_bank_cmd[16:14]]
                        bank_status[activate_bank_cmd[16:14]]
                                <= { bank_status[activate_bank_cmd[16:14]][2:0], 1'b1 };
                                <= { bank_status[activate_bank_cmd[16:14]][2:0], 1'b1 };
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
                        all_banks_closed <= 1'b0;
                        all_banks_closed <= 1'b0;
                        banks_are_closing <= 1'b0;
                        banks_are_closing <= 1'b0;
                end else if ((valid_bank)&&(!r_move))
                end else if ((valid_bank)&&(!r_move))
                        ;
                        ;
                else if (maybe_close_next_bank)
                else if (maybe_close_next_bank)
                begin
                begin
                        bank_status[maybe_close_cmd[16:14]]
                        bank_status[maybe_close_cmd[16:14]]
                                <= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b0 };
                                <= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b0 };
                end else if (maybe_open_next_bank)
                end else if (maybe_open_next_bank)
                begin
                begin
                        bank_status[maybe_open_cmd[16:14]]
                        bank_status[maybe_open_cmd[16:14]]
                                <= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
                                <= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
                        all_banks_closed <= 1'b0;
                        all_banks_closed <= 1'b0;
                        banks_are_closing <= 1'b0;
                        banks_are_closing <= 1'b0;
                end
                end
        end
        end
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                // if (cmd[22:19] == `DDR_ACTIVATE)
                // if (cmd[22:19] == `DDR_ACTIVATE)
                if (w_this_opening_bank)
                if (w_this_opening_bank)
                        bank_address[activate_bank_cmd[16:14]]
                        bank_address[activate_bank_cmd[16:14]]
                                <= activate_bank_cmd[13:0];
                                <= activate_bank_cmd[13:0];
                else if (!w_this_maybe_open)
                else if (!w_this_maybe_open)
                        bank_address[maybe_open_cmd[16:14]]
                        bank_address[maybe_open_cmd[16:14]]
                                <= maybe_open_cmd[13:0];
                                <= maybe_open_cmd[13:0];
 
 
//
//
//
//
// Okay, let's investigate when we need to do a refresh.  Our plan will be to
// Okay, let's investigate when we need to do a refresh.  Our plan will be to
// do 4 refreshes every tREFI*4 seconds.  tREFI = 7.8us, but its a parameter
// do 4 refreshes every tREFI*4 seconds.  tREFI = 7.8us, but its a parameter
// in the number of clocks so that we can handle both 100MHz and 200MHz clocks.
// in the number of clocks so that we can handle both 100MHz and 200MHz clocks.
//
//
// Note that 160ns are needed between refresh commands (JEDEC, p172), or
// Note that 160ns are needed between refresh commands (JEDEC, p172), or
// 320 clocks @200MHz, or equivalently 160 clocks @100MHz.  Thus to issue 4
// 320 clocks @200MHz, or equivalently 160 clocks @100MHz.  Thus to issue 4
// of these refresh cycles will require 4*320=1280 clocks@200 MHz.  After this
// of these refresh cycles will require 4*320=1280 clocks@200 MHz.  After this
// time, no more refreshes will be needed for 6240 clocks.
// time, no more refreshes will be needed for 6240 clocks.
//
//
// Let's think this through:
// Let's think this through:
//      REFRESH_COST = (n*(320)+24)/(n*1560)
//      REFRESH_COST = (n*(320)+24)/(n*1560)
// 
// 
//
//
//
//
        reg             refresh_ztimer;
        reg             refresh_ztimer;
        reg     [16:0]   refresh_counter;
        reg     [16:0]   refresh_counter;
        reg     [3:0]    refresh_addr;
        reg     [3:0]    refresh_addr;
        reg     [23:0]   refresh_instruction;
        reg     [23:0]   refresh_instruction;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (reset_override)
                if (reset_override)
                        refresh_addr <= 4'hf;
                        refresh_addr <= 4'hf;
                else if (refresh_ztimer)
                else if (refresh_ztimer)
                        refresh_addr <= refresh_addr + 1;
                        refresh_addr <= refresh_addr + 1;
                else if (refresh_instruction[`DDR_RFBEGIN])
                else if (refresh_instruction[`DDR_RFBEGIN])
                        refresh_addr <= 4'h0;
                        refresh_addr <= 4'h0;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (reset_override)
                if (reset_override)
                begin
                begin
                        refresh_ztimer <= 1'b1;
                        refresh_ztimer <= 1'b1;
                        refresh_counter <= 17'd0;
                        refresh_counter <= 17'd0;
                end else if (!refresh_ztimer)
                end else if (!refresh_ztimer)
                begin
                begin
                        refresh_ztimer <= (refresh_counter == 17'h1);
                        refresh_ztimer <= (refresh_counter == 17'h1);
                        refresh_counter <= (refresh_counter - 17'h1);
                        refresh_counter <= (refresh_counter - 17'h1);
                end else if (refresh_instruction[`DDR_RFTIMER])
                end else if (refresh_instruction[`DDR_RFTIMER])
                begin
                begin
                        refresh_ztimer <= 1'b0;
                        refresh_ztimer <= 1'b0;
                        refresh_counter <= refresh_instruction[16:0];
                        refresh_counter <= refresh_instruction[16:0];
                end
                end
 
 
        wire    [16:0]   w_ckREFIn, w_ckREFRst;
        wire    [16:0]   w_ckREFIn, w_ckREFRst;
        assign  w_ckREFIn[ 12: 0] = CKREFI4-5*CKRFC-2-10;
        assign  w_ckREFIn[ 12: 0] = CKREFI4-5*CKRFC-2-10;
        assign  w_ckREFIn[ 16:13] = 4'h0;
        assign  w_ckREFIn[ 16:13] = 4'h0;
        assign  w_ckREFRst[12: 0] = CKRFC-2-12;
        assign  w_ckREFRst[12: 0] = CKRFC-2-12;
        assign  w_ckREFRst[16:13] = 4'h0;
        assign  w_ckREFRst[16:13] = 4'h0;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (reset_override)
                if (reset_override)
                        refresh_instruction <= { 3'h0, `DDR_NOOP, w_ckREFIn };
                        refresh_instruction <= { 3'h0, `DDR_NOOP, w_ckREFIn };
                else if (refresh_ztimer)
                else if (refresh_ztimer)
                        refresh_cmd <= refresh_instruction[20:0];
                        refresh_cmd <= refresh_instruction[20:0];
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (reset_override)
                if (reset_override)
                        need_refresh <= 1'b0;
                        need_refresh <= 1'b0;
                else if (refresh_ztimer)
                else if (refresh_ztimer)
                        need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
                        need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
        if (refresh_ztimer)
        if (refresh_ztimer)
                case(refresh_addr)//NEED-RFC, HAVE-TIMER, 
                case(refresh_addr)//NEED-RFC, HAVE-TIMER, 
                4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
                4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
                // 17'd10 = time to complete write, plus write recovery time
                // 17'd10 = time to complete write, plus write recovery time
                //              minus two (cause we can't count zero or one)
                //              minus two (cause we can't count zero or one)
                //      = WL+4+tWR-2 = 10
                //      = WL+4+tWR-2 = 10
                //      = 5+4+3-2 = 10
                //      = 5+4+3-2 = 10
                4'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 };
                4'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 };
                4'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 };
                4'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 };
                4'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 };
                4'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 };
                4'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'h6: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h6: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h7: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'h7: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'h8: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h8: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'h9: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'h9: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'ha: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'ha: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
                4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
                4'hc: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFRst };
                4'hc: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFRst };
                default:
                default:
                        refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
                        refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
                endcase
                endcase
 
 
 
 
//
//
//
//
//      Let's track: when will our bus be active?  When will we be reading or
//      Let's track: when will our bus be active?  When will we be reading or
//      writing?
//      writing?
//
//
//
//
        reg     [`BUSNOW:0]      bus_active, bus_read, bus_new;
        reg     [`BUSNOW:0]      bus_active, bus_read, bus_new;
        reg     [1:0]    bus_subaddr     [`BUSNOW:0];
        reg     [1:0]    bus_subaddr     [`BUSNOW:0];
        initial bus_active = 0;
        initial bus_active = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 };
                bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 };
                bus_read[`BUSNOW:0]   <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
                bus_read[`BUSNOW:0]   <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
                // Is this a new command?  i.e., the start of a transaction?
                // Is this a new command?  i.e., the start of a transaction?
                bus_new[`BUSNOW:0]   <= { bus_new[(`BUSNOW-1):0], 1'b0 };
                bus_new[`BUSNOW:0]   <= { bus_new[(`BUSNOW-1):0], 1'b0 };
                //bus_mask[8:0] <= { bus_mask[7:0], 1'b1 }; // Write this value?
                //bus_mask[8:0] <= { bus_mask[7:0], 1'b1 }; // Write this value?
                bus_subaddr[8]  <= bus_subaddr[7];
                bus_subaddr[8]  <= bus_subaddr[7];
                bus_subaddr[7]  <= bus_subaddr[6];
                bus_subaddr[7]  <= bus_subaddr[6];
                bus_subaddr[6]  <= bus_subaddr[5];
                bus_subaddr[6]  <= bus_subaddr[5];
                bus_subaddr[5]  <= bus_subaddr[4];
                bus_subaddr[5]  <= bus_subaddr[4];
                bus_subaddr[4]  <= bus_subaddr[3];
                bus_subaddr[4]  <= bus_subaddr[3];
                bus_subaddr[3]  <= bus_subaddr[2];
                bus_subaddr[3]  <= bus_subaddr[2];
                bus_subaddr[2]  <= bus_subaddr[1];
                bus_subaddr[2]  <= bus_subaddr[1];
                bus_subaddr[1]  <= bus_subaddr[0];
                bus_subaddr[1]  <= bus_subaddr[0];
                bus_subaddr[0]  <= 2'h3;
                bus_subaddr[0]  <= 2'h3;
                if (w_this_rw_move)
                if (w_this_rw_move)
                begin
                begin
                        bus_active[3:0]<= 4'hf; // Once per clock
                        bus_active[3:0]<= 4'hf; // Once per clock
                        bus_read[3:0]  <= 4'hf; // These will be reads
                        bus_read[3:0]  <= 4'hf; // These will be reads
                        bus_subaddr[3] <= 2'h0;
                        bus_subaddr[3] <= 2'h0;
                        bus_subaddr[2] <= 2'h1;
                        bus_subaddr[2] <= 2'h1;
                        bus_subaddr[1] <= 2'h2;
                        bus_subaddr[1] <= 2'h2;
                        bus_new[{ 2'b0, rw_sub }] <= 1'b1;
                        bus_new[{ 2'b0, rw_sub }] <= 1'b1;
 
 
                        bus_read[3:0] <= (rw_we)? 4'h0:4'hf;
                        bus_read[3:0] <= (rw_we)? 4'h0:4'hf;
                end
                end
        end
        end
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                drive_dqs <= (~bus_read[`BUSREG])&&(|bus_active[`BUSREG]);
                drive_dqs <= (~bus_read[`BUSREG])&&(|bus_active[`BUSREG]);
 
 
//
//
//
//
// Now, let's see, can we issue a read command?
// Now, let's see, can we issue a read command?
//
//
//
//
        wire    w_s_match;
        wire    w_s_match;
        assign  w_s_match = (s_pending)&&(r_pending)&&(r_we == s_we)
        assign  w_s_match = (s_pending)&&(r_pending)&&(r_we == s_we)
                                &&(r_row == s_row)&&(r_bank == s_bank)
                                &&(r_row == s_row)&&(r_bank == s_bank)
                                &&(r_col == s_col)
                                &&(r_col == s_col)
                                &&(r_sub > s_sub);
                                &&(r_sub > s_sub);
        reg     pipe_stall;
        reg     pipe_stall;
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                r_pending <= (i_wb_stb)&&(~o_wb_stall)
                r_pending <= (i_wb_stb)&&(~o_wb_stall)
                                ||(r_pending)&&(pipe_stall);
                                ||(r_pending)&&(pipe_stall);
                if (~pipe_stall)
                if (~pipe_stall)
                        s_pending <= r_pending;
                        s_pending <= r_pending;
                if (~pipe_stall)
                if (~pipe_stall)
                begin
                begin
                        pipe_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
                        pipe_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
                        o_wb_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
                        o_wb_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
                end else begin // if (pipe_stall)
                end else begin // if (pipe_stall)
                        pipe_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
                        pipe_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
                        o_wb_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
                        o_wb_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
                end
                end
                if (need_refresh)
                if (need_refresh)
                        o_wb_stall <= 1'b1;
                        o_wb_stall <= 1'b1;
 
 
                if (~pipe_stall)
                if (~pipe_stall)
                begin
                begin
                        r_we   <= i_wb_we;
                        r_we   <= i_wb_we;
                        r_addr <= i_wb_addr;
                        r_addr <= i_wb_addr;
                        r_data <= i_wb_data;
                        r_data <= i_wb_data;
                        r_row  <= i_wb_addr[25:12];
                        r_row  <= i_wb_addr[25:12];
                        r_bank <= i_wb_addr[11:9];
                        r_bank <= i_wb_addr[11:9];
                        r_col  <= { i_wb_addr[8:2], 3'b000 }; // 9:2
                        r_col  <= { i_wb_addr[8:2], 3'b000 }; // 9:2
                        r_sub  <= i_wb_addr[1:0];
                        r_sub  <= i_wb_addr[1:0];
 
 
                        // pre-emptive work
                        // pre-emptive work
                        r_nxt_row  <= (i_wb_addr[11:9]==3'h7)?i_wb_addr[25:12]+14'h1:i_wb_addr[25:12];
                        r_nxt_row  <= (i_wb_addr[11:9]==3'h7)?i_wb_addr[25:12]+14'h1:i_wb_addr[25:12];
                        r_nxt_bank <= i_wb_addr[11:9]+3'h1;
                        r_nxt_bank <= i_wb_addr[11:9]+3'h1;
                end
                end
 
 
                if (~pipe_stall)
                if (~pipe_stall)
                begin
                begin
                        // Moving one down the pipeline
                        // Moving one down the pipeline
                        s_we   <= r_we;
                        s_we   <= r_we;
                        s_addr <= r_addr;
                        s_addr <= r_addr;
                        s_data <= r_data;
                        s_data <= r_data;
                        s_row  <= r_row;
                        s_row  <= r_row;
                        s_bank <= r_bank;
                        s_bank <= r_bank;
                        s_col  <= r_col;
                        s_col  <= r_col;
                        s_sub  <= r_sub;
                        s_sub  <= r_sub;
 
 
                        // pre-emptive work
                        // pre-emptive work
                        s_nxt_row  <= r_nxt_row;
                        s_nxt_row  <= r_nxt_row;
                        s_nxt_bank <= r_nxt_bank;
                        s_nxt_bank <= r_nxt_bank;
 
 
                        s_match <= w_s_match;
                        // s_match <= w_s_match;
                end
                end
        end
        end
 
 
        wire    w_need_close_this_bank, w_need_open_bank,
        wire    w_need_close_this_bank, w_need_open_bank,
                w_r_valid, w_s_valid;
                w_r_valid, w_s_valid;
        assign  w_need_close_this_bank = (r_pending)&&(bank_status[r_bank][0])
        assign  w_need_close_this_bank = (r_pending)&&(bank_status[r_bank][0])
                        &&(r_row != bank_address[r_bank])
                        &&(r_row != bank_address[r_bank])
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][0])
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][0])
                                &&(s_row != bank_address[s_bank]);
                                &&(s_row != bank_address[s_bank]);
        assign  w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00)
        assign  w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00)
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][1:0]==2'b00);
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][1:0]==2'b00);
        assign  w_r_valid = (!need_refresh)&&(r_pending)
        assign  w_r_valid = (!need_refresh)&&(r_pending)
                        &&(bank_status[r_bank][3])
                        &&(bank_status[r_bank][3])
                        &&(bank_address[r_bank]==r_row)
                        &&(bank_address[r_bank]==r_row)
                        &&(!bus_active[0]);
                        &&(!bus_active[0]);
        assign  w_s_valid = (!need_refresh)&&(s_pending)
        assign  w_s_valid = (!need_refresh)&&(s_pending)
                        &&(bank_status[s_bank][3])
                        &&(bank_status[s_bank][3])
                        &&(bank_address[s_bank]==s_row)
                        &&(bank_address[s_bank]==s_row)
                        &&(!bus_active[0]);
                        &&(!bus_active[0]);
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                need_close_bank <= (w_need_close_this_bank)
                need_close_bank <= (w_need_close_this_bank)
 
                                &&(!need_open_bank)
 
                                &&(!need_close_bank)
                                &&(!w_this_closing_bank)&&(!last_closing_bank);
                                &&(!w_this_closing_bank)&&(!last_closing_bank);
 
 
                maybe_close_next_bank <= (r_pending)
                maybe_close_next_bank <= (r_pending)
                        &&(bank_status[r_nxt_bank][0])
                        &&(bank_status[r_nxt_bank][0])
                        &&(r_nxt_row != bank_address[r_nxt_bank])
                        &&(r_nxt_row != bank_address[r_nxt_bank])
                        &&(!w_this_maybe_close)&&(!last_maybe_close);
                        &&(!w_this_maybe_close)&&(!last_maybe_close);
 
 
                close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
                close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
                maybe_close_cmd <= { `DDR_PRECHARGE, r_nxt_bank, r_nxt_row[13:11], 1'b0, r_nxt_row[9:0] };
                maybe_close_cmd <= { `DDR_PRECHARGE, r_nxt_bank, r_nxt_row[13:11], 1'b0, r_nxt_row[9:0] };
 
 
 
 
                need_open_bank <= (w_need_open_bank)
                need_open_bank <= (w_need_open_bank)
                                &&(!w_this_opening_bank)&&(!last_opening_bank);
                                &&(!w_this_opening_bank)&&(!last_opening_bank);
                last_open_bank <= (w_this_opening_bank);
                last_open_bank <= (w_this_opening_bank);
 
 
                maybe_open_next_bank <= (r_pending)
                maybe_open_next_bank <= (r_pending)
                        &&(bank_status[r_bank][0] == 1'b1)
                        &&(bank_status[r_bank][0] == 1'b1)
                        &&(bank_status[r_nxt_bank][1:0] == 2'b00)
                        &&(bank_status[r_nxt_bank][1:0] == 2'b00)
                        &&(!w_this_maybe_open)&&(!last_maybe_open);
                        &&(!w_this_maybe_open)&&(!last_maybe_open);
                last_maybe_open <= (w_this_maybe_open);
                last_maybe_open <= (w_this_maybe_open);
 
 
                activate_bank_cmd<= { `DDR_ACTIVATE,  r_bank,     r_row[13:0] };
                activate_bank_cmd<= { `DDR_ACTIVATE,  r_bank,     r_row[13:0] };
                maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
                maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
 
 
 
 
 
 
                valid_bank <= ((w_r_valid)||(pipe_stall)&&(w_s_valid))
                valid_bank <= ((w_r_valid)||(pipe_stall)&&(w_s_valid))
                                &&(!last_valid_bank)&&(!r_move);
                                &&(!last_valid_bank)&&(!r_move);
                last_valid_bank <= r_move;
                last_valid_bank <= r_move;
 
 
                if ((s_pending)&&(pipe_stall))
                if ((s_pending)&&(pipe_stall))
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (s_we)?`DDR_WRITE:`DDR_READ;
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (s_we)?`DDR_WRITE:`DDR_READ;
                else if (r_pending)
                else if (r_pending)
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (r_we)?`DDR_WRITE:`DDR_READ;
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (r_we)?`DDR_WRITE:`DDR_READ;
                else
                else
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= `DDR_NOOP;
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= `DDR_NOOP;
                if ((s_pending)&&(pipe_stall))
                if ((s_pending)&&(pipe_stall))
                        rw_cmd[`DDR_WEBIT-1:0] <= { s_bank, 3'h0, 1'b0, s_col };
                        rw_cmd[`DDR_WEBIT-1:0] <= { s_bank, 3'h0, 1'b0, s_col };
                else
                else
                        rw_cmd[`DDR_WEBIT-1:0] <= { r_bank, 3'h0, 1'b0, r_col };
                        rw_cmd[`DDR_WEBIT-1:0] <= { r_bank, 3'h0, 1'b0, r_col };
                if ((s_pending)&&(pipe_stall))
                if ((s_pending)&&(pipe_stall))
                        rw_sub <= 2'b11 - s_sub;
                        rw_sub <= 2'b11 - s_sub;
                else
                else
                        rw_sub <= 2'b11 - r_sub;
                        rw_sub <= 2'b11 - r_sub;
                if ((s_pending)&&(pipe_stall))
                if ((s_pending)&&(pipe_stall))
                        rw_we <= s_we;
                        rw_we <= s_we;
                else
                else
                        rw_we <= r_we;
                        rw_we <= r_we;
 
 
        end
        end
 
 
//
//
//
//
// Okay, let's look at the last assignment in our chain.  It should look
// Okay, let's look at the last assignment in our chain.  It should look
// something like:
// something like:
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        o_ddr_reset_n <= 1'b0;
                        o_ddr_reset_n <= 1'b0;
                else if (reset_ztimer)
                else if (reset_ztimer)
                        o_ddr_reset_n <= reset_instruction[`DDR_RSTBIT];
                        o_ddr_reset_n <= reset_instruction[`DDR_RSTBIT];
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        o_ddr_cke <= 1'b0;
                        o_ddr_cke <= 1'b0;
                else if (reset_ztimer)
                else if (reset_ztimer)
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        maintenance_override <= 1'b1;
                        maintenance_override <= 1'b1;
                else
                else
                        maintenance_override <= (reset_override)||(need_refresh);
                        maintenance_override <= (reset_override)||(need_refresh);
 
 
        initial maintenance_cmd = { `DDR_NOOP, 17'h00 };
        initial maintenance_cmd = { `DDR_NOOP, 17'h00 };
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
                        maintenance_cmd <= { `DDR_NOOP, 17'h00 };
                        maintenance_cmd <= { `DDR_NOOP, 17'h00 };
                else
                else
                        maintenance_cmd <= (reset_override)?reset_cmd:refresh_cmd;
                        maintenance_cmd <= (reset_override)?reset_cmd:refresh_cmd;
 
 
        assign  w_this_closing_bank = (!maintenance_override)
        assign  w_this_closing_bank = (!maintenance_override)
                                &&(need_close_bank);
                                &&(need_close_bank);
        assign  w_this_opening_bank = (!maintenance_override)
        assign  w_this_opening_bank = (!maintenance_override)
                                &&(!need_close_bank)&&(need_open_bank);
                                &&(!need_close_bank)&&(need_open_bank);
        assign  w_this_rw_move = (!maintenance_override)
        assign  w_this_rw_move = (!maintenance_override)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&(valid_bank)&&(!r_move);
                                &&(valid_bank)&&(!r_move);
        assign  w_this_maybe_close = (!maintenance_override)
        assign  w_this_maybe_close = (!maintenance_override)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&((!valid_bank)||(r_move))
                                &&((!valid_bank)||(r_move))
                                &&(maybe_close_next_bank);
                                &&(maybe_close_next_bank);
        assign  w_this_maybe_open = (!maintenance_override)
        assign  w_this_maybe_open = (!maintenance_override)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&(!need_close_bank)&&(!need_open_bank)
                                &&((!valid_bank)||(r_move))
                                &&((!valid_bank)||(r_move))
                                &&(!maybe_close_next_bank)
                                &&(!maybe_close_next_bank)
                                &&(maybe_open_next_bank);
                                &&(maybe_open_next_bank);
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                last_opening_bank <= 1'b0;
                last_opening_bank <= 1'b0;
                last_closing_bank <= 1'b0;
                last_closing_bank <= 1'b0;
                last_maybe_open   <= 1'b0;
                last_maybe_open   <= 1'b0;
                last_maybe_close  <= 1'b0;
                last_maybe_close  <= 1'b0;
                r_move <= 1'b0;
                r_move <= 1'b0;
                if (maintenance_override) // Command from either reset or
                if (maintenance_override) // Command from either reset or
                        cmd <= maintenance_cmd; // refresh logic
                        cmd <= maintenance_cmd; // refresh logic
                else if (need_close_bank)
                else if (need_close_bank)
                begin
                begin
                        cmd <= close_bank_cmd;
                        cmd <= close_bank_cmd;
                        last_closing_bank <= 1'b1;
                        last_closing_bank <= 1'b1;
                end else if (need_open_bank)
                end else if (need_open_bank)
                begin
                begin
                        cmd <= activate_bank_cmd;
                        cmd <= activate_bank_cmd;
                        last_opening_bank <= 1'b1;
                        last_opening_bank <= 1'b1;
                end else if ((valid_bank)&&(!r_move))
                end else if ((valid_bank)&&(!r_move))
                begin
                begin
                        cmd <= rw_cmd;
                        cmd <= rw_cmd;
                        r_move <= 1'b1;
                        r_move <= 1'b1;
                end else if (maybe_close_next_bank)
                end else if (maybe_close_next_bank)
                begin
                begin
                        cmd <= maybe_close_cmd;
                        cmd <= maybe_close_cmd;
                        last_maybe_close <= 1'b1;
                        last_maybe_close <= 1'b1;
                end else if (maybe_open_next_bank)
                end else if (maybe_open_next_bank)
                begin
                begin
                        cmd <= maybe_open_cmd;
                        cmd <= maybe_open_cmd;
                        last_maybe_open <= 1'b1;
                        last_maybe_open <= 1'b1;
                end else
                end else
                        cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] };
                        cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] };
        end
        end
 
 
`define LGFIFOLN        4
`define LGFIFOLN        4
`define FIFOLEN         16
`define FIFOLEN         16
        reg     [(`LGFIFOLN-1):0]        bus_fifo_head, bus_fifo_tail;
        reg     [(`LGFIFOLN-1):0]        bus_fifo_head, bus_fifo_tail;
        reg     [31:0]   bus_fifo_data   [0:(`FIFOLEN-1)];
        reg     [31:0]   bus_fifo_data   [0:(`FIFOLEN-1)];
        reg     [1:0]    bus_fifo_sub    [0:(`FIFOLEN-1)];
        reg     [1:0]    bus_fifo_sub    [0:(`FIFOLEN-1)];
        reg             bus_fifo_new    [0:(`FIFOLEN-1)];
        reg             bus_fifo_new    [0:(`FIFOLEN-1)];
        reg             pre_ack;
        reg             pre_ack;
 
 
        // The bus R/W FIFO
        // The bus R/W FIFO
        wire    w_bus_fifo_read_next_transaction;
        wire    w_bus_fifo_read_next_transaction;
        assign  w_bus_fifo_read_next_transaction =
        assign  w_bus_fifo_read_next_transaction =
                (bus_fifo_sub[bus_fifo_tail]==bus_subaddr[`BUSREG])
                (bus_fifo_sub[bus_fifo_tail]==bus_subaddr[`BUSREG])
                &&(bus_fifo_tail != bus_fifo_head)
                &&(bus_fifo_tail != bus_fifo_head)
                &&(bus_active[`BUSREG])
                &&(bus_active[`BUSREG])
                &&(bus_new[`BUSREG] == bus_fifo_new[bus_fifo_tail]);
                &&(bus_new[`BUSREG] == bus_fifo_new[bus_fifo_tail]);
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                pre_ack <= 1'b0;
                pre_ack <= 1'b0;
                o_ddr_dm <= 1'b0;
                o_ddr_dm <= 1'b0;
                if ((i_reset)||(reset_override))
                if ((i_reset)||(reset_override))
                begin
                begin
                        bus_fifo_head <= 4'h0;
                        bus_fifo_head <= 4'h0;
                        bus_fifo_tail <= 4'h0;
                        bus_fifo_tail <= 4'h0;
                        o_ddr_dm <= 1'b0;
                        o_ddr_dm <= 1'b0;
                end else begin
                end else begin
                        if ((w_this_rw_move)||((s_pending)&&(s_match)&&(!pipe_stall)))
                        if
 
        //((w_this_rw_move)||((s_pending)&&(s_match)&&(!pipe_stall)))
 
                                ((s_pending)&&(!pipe_stall))
                                bus_fifo_head <= bus_fifo_head + 4'h1;
                                bus_fifo_head <= bus_fifo_head + 4'h1;
 
 
                        o_ddr_dm <= (bus_active[`BUSREG])&&(!bus_read[`BUSREG]);
                        o_ddr_dm <= (bus_active[`BUSREG])&&(!bus_read[`BUSREG]);
                        if (w_bus_fifo_read_next_transaction)
                        if (w_bus_fifo_read_next_transaction)
                        begin
                        begin
                                bus_fifo_tail <= bus_fifo_tail + 4'h1;
                                bus_fifo_tail <= bus_fifo_tail + 4'h1;
                                pre_ack <= 1'b1;
                                pre_ack <= 1'b1;
                                o_ddr_dm <= 1'b0;
                                o_ddr_dm <= 1'b0;
                        end
                        end
                end
                end
                bus_fifo_data[bus_fifo_head] <= s_data;
                bus_fifo_data[bus_fifo_head] <= s_data;
                bus_fifo_sub[bus_fifo_head] <= s_sub;
                bus_fifo_sub[bus_fifo_head] <= s_sub;
                bus_fifo_new[bus_fifo_head] <= w_this_rw_move;
                bus_fifo_new[bus_fifo_head] <= w_this_rw_move;
        end
        end
 
 
 
 
        assign  o_ddr_cs_n  = cmd[`DDR_CSBIT];
        assign  o_ddr_cs_n  = cmd[`DDR_CSBIT];
        assign  o_ddr_ras_n = cmd[`DDR_RASBIT];
        assign  o_ddr_ras_n = cmd[`DDR_RASBIT];
        assign  o_ddr_cas_n = cmd[`DDR_CASBIT];
        assign  o_ddr_cas_n = cmd[`DDR_CASBIT];
        assign  o_ddr_we_n  = cmd[`DDR_WEBIT];
        assign  o_ddr_we_n  = cmd[`DDR_WEBIT];
        assign  o_ddr_dqs   = drive_dqs;
        assign  o_ddr_dqs   = drive_dqs;
        assign  o_ddr_addr  = cmd[(`DDR_ADDR_BITS-1):0];
        assign  o_ddr_addr  = cmd[(`DDR_ADDR_BITS-1):0];
        assign  o_ddr_ba    = cmd[(`DDR_BABITS+`DDR_ADDR_BITS-1):`DDR_ADDR_BITS];
        assign  o_ddr_ba    = cmd[(`DDR_BABITS+`DDR_ADDR_BITS-1):`DDR_ADDR_BITS];
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_ddr_data  <= bus_fifo_data[bus_fifo_tail];
                o_ddr_data  <= bus_fifo_data[bus_fifo_tail];
        assign  w_precharge_all = (cmd[`DDR_CSBIT:`DDR_WEBIT]==`DDR_PRECHARGE)
        assign  w_precharge_all = (cmd[`DDR_CSBIT:`DDR_WEBIT]==`DDR_PRECHARGE)
                                &&(o_ddr_addr[10]); // 5 bits
                                &&(o_ddr_addr[10]); // 5 bits
 
 
        // Need to set o_wb_dqs high one clock prior to any read.
        // Need to set o_wb_dqs high one clock prior to any read.
        // As per spec, ODT = 0 during reads
        // As per spec, ODT = 0 during reads
        assign  o_ddr_bus_oe = ~bus_read[`BUSNOW];
        assign  o_ddr_bus_oe = ~bus_read[`BUSNOW];
 
 
        // ODT must be in high impedence while reset_n=0, then it can be set
        // ODT must be in high impedence while reset_n=0, then it can be set
        // to low or high.
        // to low or high.
        assign  o_ddr_odt = o_ddr_bus_oe;
        assign  o_ddr_odt = o_ddr_bus_oe;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_wb_ack <= pre_ack;
                o_wb_ack <= pre_ack;
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_wb_data <= i_ddr_data;
                o_wb_data <= i_ddr_data;
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.