Line 53... |
Line 53... |
// 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
|
|
`define DDR_NEEDREFRESH 23
|
|
`define DDR_RFTIMER 22
|
|
`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 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);
|
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 = 140,
|
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;
|
Line 94... |
Line 103... |
// 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 i_ddr_data;
|
input [31:0] i_ddr_data;
|
// And just for the test bench
|
// And just for the test bench
|
output reg o_cmd_accepted;
|
output reg o_cmd_accepted;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
o_cmd_accepted <= (i_wb_stb)&&(~o_wb_stall);
|
o_cmd_accepted <= (i_wb_stb)&&(~o_wb_stall);
|
Line 134... |
Line 143... |
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;
|
|
|
|
wire w_this_closing_bank, w_this_opening_bank,
|
|
w_this_maybe_close, w_this_maybe_open,
|
|
w_this_rw_move, w_this_refresh;
|
|
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
|
Line 339... |
Line 353... |
&&(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)&&(need_refresh)||(w_precharge_all))
|
if (reset_override)
|
|
begin
|
|
bank_status[0][0] <= 1'b0;
|
|
bank_status[1][0] <= 1'b0;
|
|
bank_status[2][0] <= 1'b0;
|
|
bank_status[3][0] <= 1'b0;
|
|
bank_status[4][0] <= 1'b0;
|
|
bank_status[5][0] <= 1'b0;
|
|
bank_status[6][0] <= 1'b0;
|
|
bank_status[7][0] <= 1'b0;
|
|
banks_are_closing <= 1'b1;
|
|
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;
|
Line 400... |
Line 425... |
// 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 midrefresh, refresh_clear, endrefresh;
|
reg refresh_ztimer;
|
reg [12:0] refresh_clk;
|
reg [16:0] refresh_counter;
|
reg [2:0] midrefresh_hctr; // How many refresh cycles?
|
reg [3:0] refresh_addr;
|
reg [8:0] midrefresh_lctr; // How many clks in this refresh cycle
|
reg [23:0] refresh_instruction;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((reset_override)||(refresh_clear))
|
if (reset_override)
|
refresh_clk <= CKREFI4;
|
refresh_addr <= 4'hf;
|
else if (|refresh_clk)
|
else if (refresh_ztimer)
|
refresh_clk <= refresh_clk-1;
|
refresh_addr <= refresh_addr + 1;
|
always @(posedge i_clk)
|
else if (refresh_instruction[`DDR_RFBEGIN])
|
if (refresh_clk == 0)
|
refresh_addr <= 4'h0;
|
need_refresh <= 1'b1;
|
|
else if (endrefresh)
|
|
need_refresh <= 1'b0;
|
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (!need_refresh)
|
if (reset_override)
|
refresh_cmd <= { `DDR_NOOP, 17'h00 };
|
begin
|
else if (~banks_are_closing)
|
refresh_ztimer <= 1'b1;
|
refresh_cmd <= { `DDR_PRECHARGE, 3'h0, 3'h0, 1'b1, 10'h00 };
|
refresh_counter <= 17'd0;
|
else if (~all_banks_closed)
|
end else if (!refresh_ztimer)
|
refresh_cmd <= { `DDR_NOOP, 17'h00 };
|
begin
|
else
|
refresh_ztimer <= (refresh_counter == 17'h1);
|
refresh_cmd <= { `DDR_REFRESH, 17'h00 };
|
refresh_counter <= (refresh_counter - 17'h1);
|
always @(posedge i_clk)
|
end else if (refresh_instruction[`DDR_RFTIMER])
|
midrefresh <= (need_refresh)&&(all_banks_closed)&&(~refresh_clear);
|
begin
|
|
refresh_ztimer <= 1'b0;
|
always @(posedge i_clk)
|
refresh_counter <= refresh_instruction[16:0];
|
if (!need_refresh)
|
end
|
midrefresh_hctr <= 3'h0;
|
|
else if ((midrefresh_lctr == 0)&&(!midrefresh_hctr[2]))
|
wire [16:0] w_ckREFIn, w_ckREFRst;
|
midrefresh_hctr <= midrefresh_hctr + 3'h1;
|
assign w_ckREFIn[ 12: 0] = CKREFI4-5*CKRFC-2-10;
|
always @(posedge i_clk)
|
assign w_ckREFIn[ 16:13] = 4'h0;
|
if ((!need_refresh)||(!midrefresh))
|
assign w_ckREFRst[12: 0] = CKRFC-2-6;
|
endrefresh <= 1'b0;
|
assign w_ckREFRst[16:13] = 4'h0;
|
else if (midrefresh_hctr == 3'h0)
|
|
endrefresh <= 1'b1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (reset_override)
|
if (!need_refresh)
|
refresh_instruction <= { 3'h0, `DDR_NOOP, w_ckREFIn };
|
midrefresh_lctr <= CKRFC;
|
else if (refresh_ztimer)
|
else if (midrefresh_lctr == 0)
|
refresh_cmd <= refresh_instruction[20:0];
|
midrefresh_lctr <= CKRFC;
|
always @(posedge i_clk)
|
else
|
if (reset_override)
|
midrefresh_lctr <= midrefresh_lctr-1;
|
need_refresh <= 1'b0;
|
|
else if (refresh_ztimer)
|
|
need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
refresh_clear <= (need_refresh)&&(endrefresh)&&(midrefresh_lctr == 0);
|
if (refresh_ztimer)
|
|
case(refresh_addr)//NEED-RFC, HAVE-TIMER,
|
|
4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
|
|
// 17'd10 = time to complete write, plus write recovery time
|
|
// minus two (cause we can't count zero or one)
|
|
// = WL+4+tWR-2 = 10
|
|
// = 5+4+3-2 = 10
|
|
4'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 };
|
|
4'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 };
|
|
4'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 };
|
|
4'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
|
|
4'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
|
4'h6: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
|
|
4'h7: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
|
4'h8: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
|
|
4'h9: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
|
4'ha: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
|
|
4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
|
4'hc: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
|
default:
|
|
refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
|
|
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 [8:0] bus_active, bus_read;
|
reg [`BUSNOW:0] bus_active, bus_read, bus_new;
|
reg [1:0] bus_subaddr [8: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[8:0] <= { bus_active[7:0], 1'b0 };
|
bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 };
|
bus_read[8:0] <= { bus_read[7:0], 1'b0 }; // Drive the d-bus?
|
bus_read[`BUSNOW:0] <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
|
|
bus_new[`BUSNOW:0] <= { bus_new[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
|
//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 ((!reset_override)&&(!need_refresh)&&(!need_close_bank)
|
if (w_this_rw_move)
|
&&(!need_open_bank)&&(valid_bank))
|
|
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, (2'h3-r_sub) }] <= 1'b1;
|
|
|
bus_read[3:0] <= (r_we)? 4'h0:4'hf;
|
bus_read[3:0] <= (r_we)? 4'h0:4'hf;
|
end
|
end
|
end
|
end
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
drive_dqs <= (~bus_read[8])&&(|bus_active[8:7]);
|
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?
|
//
|
//
|
Line 499... |
Line 545... |
begin
|
begin
|
if ((i_wb_stb)&&(~o_wb_stall))
|
if ((i_wb_stb)&&(~o_wb_stall))
|
begin
|
begin
|
r_pending <= 1'b1;
|
r_pending <= 1'b1;
|
o_wb_stall <= 1'b1;
|
o_wb_stall <= 1'b1;
|
end else if ((r_move)||(m_move))
|
end else if ((m_move)||(w_this_rw_move))
|
begin
|
begin
|
r_pending <= 1'b0;
|
r_pending <= 1'b0;
|
o_wb_stall <= 1'b0;
|
o_wb_stall <= 1'b0;
|
end
|
end
|
|
|
Line 526... |
Line 572... |
wire w_need_close_this_bank, w_need_open_bank;
|
wire w_need_close_this_bank, w_need_open_bank;
|
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]);
|
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);
|
|
|
wire w_this_closing_bank, w_this_opening_bank,
|
|
w_this_maybe_close, w_this_maybe_open;
|
|
reg last_closing_bank, last_opening_bank;
|
|
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)
|
&&(!w_this_closing_bank)&&(!last_closing_bank);
|
&&(!w_this_closing_bank)&&(!last_closing_bank);
|
|
|
Line 571... |
Line 614... |
end
|
end
|
|
|
|
|
// Match registers, to see if we can move forward without sending a
|
// Match registers, to see if we can move forward without sending a
|
// new command
|
// new command
|
|
reg [2:0] m_clock;
|
|
reg m_timeout;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if (r_move)
|
if (|m_clock)
|
|
m_clock <= m_clock - 3'h1;
|
|
if (!m_timeout)
|
|
m_timeout <= (m_clock[2:1] == 2'b00);
|
|
if (w_this_rw_move)
|
begin
|
begin
|
m_pending <= r_pending;
|
m_pending <= r_pending;
|
m_we <= r_we;
|
m_we <= r_we;
|
m_addr <= r_addr;
|
m_addr <= r_addr;
|
m_row <= r_row;
|
m_row <= r_row;
|
m_bank <= r_bank;
|
m_bank <= r_bank;
|
m_col <= r_col;
|
m_col <= r_col;
|
m_sub <= r_sub;
|
m_sub <= r_sub;
|
end else if (m_match)
|
m_clock<= 3'h7;
|
|
m_timeout <= 1'b0;
|
|
end else if ((m_match)&&(!m_timeout))
|
m_sub <= r_sub;
|
m_sub <= r_sub;
|
|
|
m_match <= (m_pending)&&(r_pending)&&(r_we == m_we)
|
m_match <= (m_pending)&&(r_pending)&&(r_we == m_we)
|
&&(r_row == m_row)&&(r_bank == m_bank)
|
&&(r_row == m_row)&&(r_bank == m_bank)
|
&&(r_col == m_col)
|
&&(r_col == m_col)
|
Line 611... |
Line 662... |
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];
|
|
|
|
assign w_this_refresh = (!reset_override)&&(need_refresh)
|
|
&&(refresh_cmd[`DDR_CSBIT:`DDR_WEBIT] == `DDR_REFRESH);
|
|
|
assign w_this_closing_bank = (!reset_override)&&(!need_refresh)
|
assign w_this_closing_bank = (!reset_override)&&(!need_refresh)
|
&&(need_close_bank);
|
&&(need_close_bank);
|
assign w_this_opening_bank = (!reset_override)&&(!need_refresh)
|
assign w_this_opening_bank = (!reset_override)&&(!need_refresh)
|
&&(!need_close_bank)&&(need_open_bank);
|
&&(!need_close_bank)&&(need_open_bank);
|
|
assign w_this_rw_move = (!reset_override)&&(!need_refresh)
|
|
&&(!need_close_bank)&&(!need_open_bank)
|
|
&&(valid_bank)&&(!r_move);
|
assign w_this_maybe_close = (!reset_override)&&(!need_refresh)
|
assign w_this_maybe_close = (!reset_override)&&(!need_refresh)
|
&&(!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 = (!reset_override)&&(!need_refresh)
|
assign w_this_maybe_open = (!reset_override)&&(!need_refresh)
|
Line 660... |
Line 717... |
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
|
|
|
reg [31:0] bus_data[8:0];
|
`define LGFIFOLN 4
|
|
`define FIFOLEN 16
|
|
reg [(`LGFIFOLN-1):0] bus_fifo_head, bus_fifo_tail;
|
|
reg [31:0] bus_fifo_data [0:(`FIFOLEN-1)];
|
|
reg [1:0] bus_fifo_sub [0:(`FIFOLEN-1)];
|
|
reg bus_fifo_new [0:(`FIFOLEN-1)];
|
|
reg pre_ack;
|
|
|
|
// The bus R/W FIFO
|
|
wire w_bus_fifo_read_next_transaction;
|
|
assign w_bus_fifo_read_next_transaction = (bus_fifo_sub[bus_fifo_tail]==bus_subaddr[`BUSREG])&&(bus_active[`BUSREG])&&(bus_new[`BUSREG] == bus_fifo_new[bus_fifo_tail]);
|
|
always @(posedge i_clk)
|
|
begin
|
|
pre_ack <= 1'b0;
|
|
o_ddr_dm <= 1'b0;
|
|
if ((i_reset)||(reset_override))
|
|
begin
|
|
bus_fifo_head <= 4'h0;
|
|
bus_fifo_tail <= 4'h0;
|
|
o_ddr_dm <= 1'b0;
|
|
end else begin
|
|
if ((w_this_rw_move)||(m_move))
|
|
bus_fifo_head <= bus_fifo_head + 4'h1;
|
|
|
|
o_ddr_dm <= (bus_active[`BUSREG])&&(!bus_read[`BUSREG]);
|
|
if (w_bus_fifo_read_next_transaction)
|
|
begin
|
|
bus_fifo_tail <= bus_fifo_tail + 4'h1;
|
|
pre_ack <= 1'b1;
|
|
o_ddr_dm <= 1'b0;
|
|
end
|
|
end
|
|
bus_fifo_data[bus_fifo_head] <= r_data;
|
|
bus_fifo_sub[bus_fifo_head] <= r_sub;
|
|
bus_fifo_new[bus_fifo_head] <= w_this_rw_move;
|
|
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];
|
assign o_ddr_data = bus_data[8];
|
always @(posedge i_clk)
|
|
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[8];
|
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)
|
|
o_wb_ack <= pre_ack;
|
|
always @(posedge i_clk)
|
|
o_wb_data <= i_ddr_data;
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|