I felt inspired and started working on the memory controller. I've
reviewed the specs on a few DDR memory chips and have started work on
a controller design. It's not 100% fully formed, but in the spirit of
releasing early, here it is. I know that this two stage design is
going to require more stages to meet timing goals, but I want to start
with a functionally-correct design and work my way towards a fast
functionally-correct design. I don't have access to SVN from this
computer, so I'm just going to post my code inline to the list.
This email contains the first stage, and the second email contains the
last stage. The first stage interprets commands and rewrites them as
necessary to keep the second stage simple. Some of the notes on the
second stage are useful for understanding the first. I intend to
clean up the sloppiness as I go along. Also, there are some
significant things missing.
Here we go....
// This is the second to last stage. It computes state information
// for the last stage.
module memctl_cs(
clock,
reset,
// Command to process
cmd_in,
bank_in,
row_in,
col_in,
wdata_in,
wbytes_in,
// Command to next stage
cmd_out,
next_state_out,
bank_out,
row_out,
col_out,
wdata_out,
wbytes_out,
row_miss,
busy_in
);
input clock, reset;
input busy_in;
input [2:0] cmd_in;
input [1:0] bank_in;
input [12:0] row_in, col_in;
input [63:0] wdata_in;
input [7:0] wbytes_in;
output [1:0] cmd_out;
output [2:0] next_state_out;
output [1:0] bank_out;
output [12:0] row_out, col_out;
output [63:0] wdata_out;
output [7:0] wbytes_out;
output row_miss;
// Valid commands
parameter cmd_none = 0;
parameter cmd_read = 1;
parameter cmd_write = 2;
parameter cmd_refresh = 3;
parameter cmd_preall = 4;
parameter cmd_lmr = 5;
reg [3:0] open;
reg [12:0] last_row [0:3];
wire row_open = open[bank_in];
wire row_hit = last_row[bank_in] == row_in;
always @(posedge clock or negedge reset) begin
if (!reset) begin
end else begin
if (!busy_in) begin
cmd_out <= cmd_in;
next_state_out <= s_none;
bank_out <= bank_in;
row_out <= row_in;
col_out <= col_in;
col_out[10] <= 0; // No auto precharge, no all bank
wdata_out <= wdata_in;
wbytes_out <= wbytes_in;
row_miss <= 0;
case (cmd_in) // synthesis full_case
cmd_none: ;
cmd_read, cmd_write: begin
row_miss <= !row_hit || !row_open;
if (!row_open) begin
next_state_out <= s_activate;
end else if (!row_hit) begin
next_state_out <= s_precharge;
end
end
cmd_refresh: begin
col_out[10] <= 1; // precharge all
next_state_out <= s_refresh0;
end
cmd_preall: begin
col_out[10] <= 1; // precharge all
cmd_out <= cmd_none;
next_state_out <= s_precharge_all;
end
cmd_lmr: begin
cmd_out <= cmd_none;
col_out <= wdata_in; // Somehow, get the data there
next_state_out <= s_lmr;
end
endcase
end
end
end
endmodule
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)