Line 97... |
Line 97... |
// 92 MHz 718
|
// 92 MHz 718
|
// 88 MHz 687
|
// 88 MHz 687
|
// 84 MHz 656
|
// 84 MHz 656
|
// 80 MHz 625
|
// 80 MHz 625
|
//
|
//
|
|
// However, since we do two refresh cycles everytime we need a refresh,
|
|
// this standard is close to overkill--but we'll use it anyway. At
|
|
// some later time we should address this, once we are entirely
|
|
// convinced that the memory is otherwise working without failure. Of
|
|
// course, at that time, it may no longer be a priority ...
|
|
//
|
reg need_refresh;
|
reg need_refresh;
|
reg [9:0] refresh_clk;
|
reg [9:0] refresh_clk;
|
wire refresh_cmd;
|
wire refresh_cmd;
|
assign refresh_cmd = (~o_ram_cs_n)&&(~o_ram_ras_n)&&(~o_ram_cas_n)&&(o_ram_we_n);
|
assign refresh_cmd = (~o_ram_cs_n)&&(~o_ram_ras_n)&&(~o_ram_cas_n)&&(o_ram_we_n);
|
initial refresh_clk = 0;
|
initial refresh_clk = 0;
|
Line 140... |
Line 146... |
// Second, do we *need* a precharge now --- must be break out of
|
// Second, do we *need* a precharge now --- must be break out of
|
// whatever we are doing to issue a precharge command?
|
// whatever we are doing to issue a precharge command?
|
//
|
//
|
// Keep in mind, the number of clocks to wait has to be reduced by
|
// Keep in mind, the number of clocks to wait has to be reduced by
|
// the amount of time it may take us to go into a precharge state.
|
// the amount of time it may take us to go into a precharge state.
|
|
// You may also notice that the precharge requirement is tighter
|
|
// than this one, so ... perhaps this isn't as required?
|
//
|
//
|
|
`ifdef PRECHARGE_COUNTERS
|
|
/*
|
|
*
|
|
* I'm commenting this out. As long as we are doing one refresh
|
|
* cycle every 625 (or even 1250) clocks, and as long as that refresh
|
|
* cycle requires that all banks be precharged, then we will never run
|
|
* out of the maximum active to precharge command period.
|
|
*
|
|
* If the logic isn't needed, then, let's get rid of it.
|
|
*
|
|
*/
|
reg [3:0] need_precharge;
|
reg [3:0] need_precharge;
|
genvar k;
|
genvar k;
|
generate
|
generate
|
for(k=0; k<4; k=k+1)
|
for(k=0; k<4; k=k+1)
|
begin : precharge_genvar_loop
|
begin : precharge_genvar_loop
|
Line 157... |
Line 176... |
reg [9:0] precharge_clk;
|
reg [9:0] precharge_clk;
|
initial precharge_clk = 0;
|
initial precharge_clk = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if ((precharge_cmd)||(bank_active[k] == 0))
|
if ((precharge_cmd)||(bank_active[k] == 0))
|
|
// This needs to be 100_000 ns, or 10_000
|
|
// clocks. A value of 1000 is *highly*
|
|
// conservative.
|
precharge_clk <= 10'd1000;
|
precharge_clk <= 10'd1000;
|
else if (|precharge_clk)
|
else if (|precharge_clk)
|
precharge_clk <= precharge_clk - 10'h1;
|
precharge_clk <= precharge_clk - 10'h1;
|
end
|
end
|
initial need_precharge[k] = 1'b0;
|
initial need_precharge[k] = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
need_precharge[k] <= ~(|precharge_clk);
|
need_precharge[k] <= ~(|precharge_clk);
|
end // precharge_genvar_loop
|
end // precharge_genvar_loop
|
endgenerate
|
endgenerate
|
|
`else
|
|
wire [3:0] need_precharge;
|
|
assign need_precharge = 4'h0;
|
|
`endif
|
|
|
|
|
|
|
reg [15:0] clocks_til_idle;
|
reg [15:0] clocks_til_idle;
|
reg [1:0] r_state;
|
reg [1:0] r_state;
|
Line 242... |
Line 268... |
r_barrell_ack <= r_barrell_ack >> 1;
|
r_barrell_ack <= r_barrell_ack >> 1;
|
nxt_dmod <= `DMOD_GETINPUT;
|
nxt_dmod <= `DMOD_GETINPUT;
|
o_ram_dmod <= nxt_dmod;
|
o_ram_dmod <= nxt_dmod;
|
|
|
//
|
//
|
|
// We assume that, whatever state the bank is in, that it
|
|
// continues in that state and set up a series of shift
|
|
// registers to contain that information. If it will not
|
|
// continue in that state, all that therefore needs to be
|
|
// done is to set bank_active[?][2] below.
|
|
//
|
bank_active[0] <= { bank_active[0][2], bank_active[0][2:1] };
|
bank_active[0] <= { bank_active[0][2], bank_active[0][2:1] };
|
bank_active[1] <= { bank_active[1][2], bank_active[1][2:1] };
|
bank_active[1] <= { bank_active[1][2], bank_active[1][2:1] };
|
bank_active[2] <= { bank_active[2][2], bank_active[2][2:1] };
|
bank_active[2] <= { bank_active[2][2], bank_active[2][2:1] };
|
bank_active[3] <= { bank_active[3][2], bank_active[3][2:1] };
|
bank_active[3] <= { bank_active[3][2], bank_active[3][2:1] };
|
//
|
//
|
Line 261... |
Line 293... |
// o_ram_cs_n <= (~i_wb_cyc) above, NOOP
|
// o_ram_cs_n <= (~i_wb_cyc) above, NOOP
|
o_ram_ras_n <= 1'b1;
|
o_ram_ras_n <= 1'b1;
|
o_ram_cas_n <= 1'b1;
|
o_ram_cas_n <= 1'b1;
|
o_ram_we_n <= 1'b1;
|
o_ram_we_n <= 1'b1;
|
|
|
// Don't drive the bus normally, let it float unless we wish
|
// o_ram_data <= r_data[15:0];
|
// to give it a command
|
|
o_ram_data <= r_data[15:0];
|
|
|
|
|
if (nxt_dmod)
|
|
;
|
|
else
|
if ((~i_wb_cyc)||(|need_precharge)||(need_refresh))
|
if ((~i_wb_cyc)||(|need_precharge)||(need_refresh))
|
begin // Issue a precharge all command (if any banks are open),
|
begin // Issue a precharge all command (if any banks are open),
|
// otherwise an autorefresh command
|
// otherwise an autorefresh command
|
if ((bank_active[0][2:1]==2'b10)
|
if ((bank_active[0][2:1]==2'b10)
|
||(bank_active[1][2:1]==2'b10)
|
||(bank_active[1][2:1]==2'b10)
|
||(bank_active[2][2:1]==2'b10)
|
||(bank_active[2][2:1]==2'b10)
|
||(bank_active[3][2:1]==2'b10))
|
||(bank_active[3][2:1]==2'b10)
|
|
||(|clocks_til_idle[2:0]))
|
begin
|
begin
|
// Do nothing this clock
|
// Do nothing this clock
|
// Can't precharge a bank immediately after
|
// Can't precharge a bank immediately after
|
// activating it
|
// activating it
|
end else if (bank_active[0][2]
|
end else if (bank_active[0][2]
|
Line 302... |
Line 336... |
o_ram_cs_n <= 1'b0;
|
o_ram_cs_n <= 1'b0;
|
o_ram_ras_n <= 1'b0;
|
o_ram_ras_n <= 1'b0;
|
o_ram_cas_n <= 1'b0;
|
o_ram_cas_n <= 1'b0;
|
o_ram_we_n <= 1'b1;
|
o_ram_we_n <= 1'b1;
|
end // Else just send NOOP's, the default command
|
end // Else just send NOOP's, the default command
|
end else if (nxt_dmod)
|
// end else if (nxt_dmod)
|
begin
|
// begin
|
// Last half of a two cycle write
|
// Last half of a two cycle write
|
o_ram_data <= r_data[15:0];
|
// o_ram_data <= r_data[15:0];
|
|
//
|
|
// While this does need to take precedence over all
|
|
// other commands, it doesn't need to take precedence
|
|
// over the the deactivate/precharge commands from
|
|
// above.
|
|
//
|
|
// We could probably even speed ourselves up a touch
|
|
// by moving this condition down below activating
|
|
// and closing active banks. ... only problem is when I
|
|
// last tried that I broke everything so ... that's not
|
|
// my problem.
|
end else if (in_refresh)
|
end else if (in_refresh)
|
begin
|
begin
|
// NOOPS only here, until we are out of refresh
|
// NOOPS only here, until we are out of refresh
|
end else if ((pending)&&(~r_bank_valid)&&(bank_active[r_addr[9:8]]==3'h0))
|
end else if ((pending)&&(~r_bank_valid)&&(bank_active[r_addr[9:8]]==3'h0))
|
begin // Need to activate the requested bank
|
begin // Need to activate the requested bank
|
Line 364... |
Line 409... |
o_ram_bs <= r_addr[9:8];
|
o_ram_bs <= r_addr[9:8];
|
clocks_til_idle[2:0] <= 3'h1;
|
clocks_til_idle[2:0] <= 3'h1;
|
|
|
o_wb_stall <= 1'b0;
|
o_wb_stall <= 1'b0;
|
r_barrell_ack[1] <= 1'b1;
|
r_barrell_ack[1] <= 1'b1;
|
o_ram_data <= r_data[31:16];
|
// o_ram_data <= r_data[31:16];
|
//
|
//
|
o_ram_dmod <= `DMOD_PUTOUTPUT;
|
o_ram_dmod <= `DMOD_PUTOUTPUT;
|
nxt_dmod <= `DMOD_PUTOUTPUT;
|
nxt_dmod <= `DMOD_PUTOUTPUT;
|
end else if ((r_pending)&&(r_addr[7:0] >= 8'hf0)
|
end else if ((r_pending)&&(r_addr[7:0] >= 8'hf0)
|
&&(~fwd_bank_valid))
|
&&(~fwd_bank_valid))
|
Line 456... |
Line 501... |
|
|
o_wb_stall <= 1'b1;
|
o_wb_stall <= 1'b1;
|
r_barrell_ack[(RDLY-1):0] <= 0;
|
r_barrell_ack[(RDLY-1):0] <= 0;
|
end
|
end
|
|
|
|
always @(posedge i_clk)
|
|
if (nxt_dmod)
|
|
o_ram_data <= r_data[15:0];
|
|
else
|
|
o_ram_data <= r_data[31:16];
|
|
|
`ifdef VERILATOR
|
`ifdef VERILATOR
|
// While I hate to build something that works one way under Verilator
|
// While I hate to build something that works one way under Verilator
|
// and another way in practice, this really isn't that. The problem
|
// and another way in practice, this really isn't that. The problem
|
// \/erilator is having is resolved in toplevel.v---one file that
|
// \/erilator is having is resolved in toplevel.v---one file that
|
// \/erilator doesn't implement. In toplevel.v, there's not only a
|
// \/erilator doesn't implement. In toplevel.v, there's not only a
|
Line 489... |
Line 540... |
// If you want to capture the first value "written" to the device,
|
// If you want to capture the first value "written" to the device,
|
// you'll need to write a nothing value to the device to set r_we.
|
// you'll need to write a nothing value to the device to set r_we.
|
// The first value "written" to the device can be caught in the next
|
// The first value "written" to the device can be caught in the next
|
// interaction after that.
|
// interaction after that.
|
//
|
//
|
assign o_debug = { i_wb_cyc, i_wb_stb, i_wb_we, o_wb_ack, o_wb_stall,
|
reg trigger;
|
o_ram_cs_n, o_ram_ras_n, o_ram_cas_n, o_ram_we_n, o_ram_bs,
|
always @(posedge i_clk)
|
o_ram_dmod, r_pending,
|
trigger <= ((o_wb_data[15:0]==o_wb_data[31:16])
|
// 13 of 32
|
&&(o_wb_ack)&&(~i_wb_we));
|
o_ram_addr[10:0], // 11 more
|
|
(r_we) ? { i_wb_data[23:20], i_wb_data[3:0] }
|
|
|
assign o_debug = { i_wb_cyc, i_wb_stb, i_wb_we, o_wb_ack, o_wb_stall, // 5
|
|
o_ram_cs_n, o_ram_ras_n, o_ram_cas_n, o_ram_we_n, o_ram_bs,//6
|
|
o_ram_dmod, r_pending, // 2
|
|
trigger, // 1
|
|
o_ram_addr[9:0], // 10 more
|
|
(r_we) ? { o_ram_data[7:0] } // 8 values
|
: { o_wb_data[23:20], o_wb_data[3:0] }
|
: { o_wb_data[23:20], o_wb_data[3:0] }
|
// i_ram_data[7:0]
|
// i_ram_data[7:0]
|
};
|
};
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|