Browse Source

sdram: improve initialization timing

Timing would fail due to st_init counters, but initialization is
absolutely not timing critical. Add some registration to avoid timing
issues.
H. Peter Anvin 3 years ago
parent
commit
9b1134ea5b

File diff suppressed because it is too large
+ 401 - 1227
fpga/output_files/max80.jam


BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


+ 1 - 1
fpga/output_files/max80.map

@@ -10,7 +10,7 @@ Quad-Serial configuration device dummy clock cycle: 8
 
 Notes:
 
-- Data checksum for this conversion is 0xF76CC72A
+- Data checksum for this conversion is 0xF77DA63B
 
 - All the addresses in this file are byte addresses
 

BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


+ 35 - 25
fpga/sdram.sv

@@ -194,13 +194,12 @@ module sdram
 					 // Bit 0 - refresh if opportune
 					 // Bit 1 - refresh urgent
 
-   reg [3:0]		      op_cycle;	// Cycles into the current operation
-
    // The actual values are unimportant; the compiler will optimize
    // the state machine implementation.
    typedef enum logic [2:0] {
 	 st_reset,		// Reset until init timer expires
-	 st_init,		// 1st refresh during initialization
+	 st_init_rfsh,		// Refresh cycles during initialization
+ 	 st_init_mrd,		// MRD register write during initialization
 	 st_idle,		// Idle state: all banks precharged
 	 st_rfsh,
 	 st_rd,
@@ -212,13 +211,13 @@ module sdram
      if (~rst_n)
        begin
 	  rfsh_ctr  <= 1'b0;
-	  init_ctr  <= 1'b0;
 	  rfsh_prio <= 2'b00;
+	  init_ctr  <= 1'b0;
        end
      else
        begin
-	  rfsh_ctr          <= rfsh_ctr + 1'b1;
-	  rfsh_ctr_last_msb <= rfsh_ctr_msb;
+	  rfsh_ctr           <= rfsh_ctr + 1'b1;
+	  rfsh_ctr_last_msb  <= rfsh_ctr_msb;
 
 	  // Refresh priority management
 	  if (is_rfsh)
@@ -233,6 +232,10 @@ module sdram
 	  init_ctr <= init_ctr + rfsh_tick;
        end // else: !if(~rst_n)
 
+   reg [3:0] op_cycle;		// Cycle into the current operation
+   reg 	     op_zero;		// op_cycle wrap around
+   reg [1:0] init_op_ctr;	// op_cycle extension for init states
+   
    // Handle bank wraparound
    reg			    last_dword; // This is the last dword in this bank
    reg [14:0]		    next_bank;  // Row:bank for the next bank
@@ -266,7 +269,9 @@ module sdram
 	  dram_d        <= 16'hxxxx;
 	  dram_d_en     <= 1'b1; // Don't float except during read
 
-	  op_cycle      <= 1'b0;
+	  op_cycle      <= 4'h0;
+	  op_zero       <= 1'b0;
+	  init_op_ctr   <= 2'b00;
 	  state         <= st_reset;
 
 	  rack0         <= 1'b0;
@@ -302,33 +307,38 @@ module sdram
 	  else
 	    op_cycle <= op_cycle + 1'b1;
 
+	  op_zero <= |op_cycle;
+	  if (|op_cycle)
+	    init_op_ctr <= init_op_ctr + 1'b1;
+	  
 	  case (state)
 	    st_reset:
 	      begin
 		 dram_cmd  <= cmd_desl;
 		 if (init_ctr[t_p_lg2])
-		   begin
-		      dram_cmd   <= cmd_pre;
-		      dram_a[10] <= 1'b1; // Precharge All Banks
-		      state      <= st_init;
-		   end
+		      state      <= st_init_rfsh;
 	      end
-	    st_init:
+	    st_init_rfsh:
 	      begin
-		 // Add 3 to the count to account for skew between rfsh_ctr
-		 // and init_ctr
-		 if ( rfsh_ctr[4:0] == t_rp+3 || rfsh_ctr[4:0] == t_rp+t_rfc+3 )
-		   begin
-		      dram_cmd   <= cmd_ref;
-		   end
-		 if ( rfsh_ctr[4:0] == t_rp+t_rfc*2+3 )
+		 dram_a[10] <= 1'b1; // Refresh all banks
+
+		 if (op_zero)
 		   begin
-		      dram_cmd   <= cmd_mrd;
-		      dram_a     <= mrd_val;
+		      dram_cmd <= cmd_ref;
+
+		      if (init_op_ctr == 2'b11)
+			state <= st_init_mrd;
 		   end
-		 if ( rfsh_ctr[4:0] >= t_rp+t_rfc*2+t_mrd-1+3 )
-		   state <= st_idle;
-	      end // case: st_init
+	      end
+	    st_init_mrd:			       
+	      begin
+		 dram_a <= mrd_val;
+		 if (op_zero)
+		   if (init_op_ctr[0])
+		     state <= st_idle;
+		   else
+		     dram_cmd <= cmd_mrd;
+	      end
 	    st_idle:
 	      begin
 		 // A data transaction starts with ACTIVE command;

Some files were not shown because too many files changed in this diff