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)

Reply via email to