Line 4... |
Line 4... |
//
|
//
|
// 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
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
Line 95... |
Line 77... |
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
|
Line 122... |
Line 103... |
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;
|
Line 144... |
Line 120... |
|
|
// 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;
|
Line 628... |
Line 604... |
|
|
// 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;
|
Line 652... |
Line 628... |
&&(!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])
|
Line 805... |
Line 783... |
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
|