|
@@ -18,19 +18,15 @@
|
|
|
//
|
|
|
// Two ports are provided: port 0 is single byte per transaction,
|
|
|
// and has highest priority; it is intended for transactions from the
|
|
|
-// ABC-bus. Port 1 does 8-strobe burst transactions. If additional ports
|
|
|
-// are needed, the intent is to add an arbiter to port 1.
|
|
|
+// ABC-bus. Port 1 does 4-byte accesses with arbitrary alignment and
|
|
|
+// byte enables.
|
|
|
//
|
|
|
// All signals are in the sdram clock domain.
|
|
|
//
|
|
|
-// The ack signals are arrays that give (some) advance notification:
|
|
|
-// e.g. rack0[1] is asserted exactly one cycle before rack0[0].
|
|
|
-//
|
|
|
-// rack*[0] is asserted during the first cycle rd* is valid.
|
|
|
-// wack*[0] is asserted during the cycle after wd* was sampled.
|
|
|
-//
|
|
|
-// Thus, especially for bursts on port 1, generally rack1[0] and
|
|
|
-// wack1[1] are the relevant signals.
|
|
|
+// [rw]ack is asserted at the beginning of a read- or write cycle and
|
|
|
+// deasserted afterwards; rvalid is asserted once all data is read and
|
|
|
+// the read data (rdX port) is valid; it remains asserted after the
|
|
|
+// transaction is complete and rack is deasserted.
|
|
|
//
|
|
|
|
|
|
module sdram
|
|
@@ -71,43 +67,45 @@ module sdram
|
|
|
)
|
|
|
(
|
|
|
// Reset and clock
|
|
|
- input rst_n,
|
|
|
- input clk,
|
|
|
+ input rst_n,
|
|
|
+ input clk,
|
|
|
|
|
|
// SDRAM hardware interface
|
|
|
- output sr_clk, // SDRAM clock output buffer
|
|
|
- output sr_cke, // SDRAM clock enable
|
|
|
- output sr_cs_n, // SDRAM CS#
|
|
|
- output sr_ras_n, // SDRAM RAS#
|
|
|
- output sr_cas_n, // SDRAM CAS#
|
|
|
- output sr_we_n, // SDRAM WE#
|
|
|
- output [1:0] sr_dqm, // SDRAM DQM (per byte)
|
|
|
- output [1:0] sr_ba, // SDRAM bank selects
|
|
|
- output [12:0] sr_a, // SDRAM address bus
|
|
|
- inout [15:0] sr_dq, // SDRAM data bus
|
|
|
+ output sr_clk, // SDRAM clock output buffer
|
|
|
+ output sr_cke, // SDRAM clock enable
|
|
|
+ output sr_cs_n, // SDRAM CS#
|
|
|
+ output sr_ras_n, // SDRAM RAS#
|
|
|
+ output sr_cas_n, // SDRAM CAS#
|
|
|
+ output sr_we_n, // SDRAM WE#
|
|
|
+ output [1:0] sr_dqm, // SDRAM DQM (per byte)
|
|
|
+ output [1:0] sr_ba, // SDRAM bank selects
|
|
|
+ output [12:0] sr_a, // SDRAM address bus
|
|
|
+ inout [15:0] sr_dq, // SDRAM data bus
|
|
|
|
|
|
// Port 0: single byte, high priority
|
|
|
- input [24:0] a0, // Address, must be stable until ack
|
|
|
+ input [24:0] a0, // Address, must be stable until ack
|
|
|
|
|
|
- output reg [7:0] rd0, // Data from SDRAM
|
|
|
- input rrq0, // Read request
|
|
|
- output reg [t_rcd+t_cl+3:0] rack0, // Read ack
|
|
|
+ output reg [7:0] rd0, // Data from SDRAM
|
|
|
+ input rrq0, // Read request
|
|
|
+ output reg rack0, // Read ack (transaction started)
|
|
|
+ output reg rvalid0, // Read data valid
|
|
|
|
|
|
- input [7:0] wd0, // Data to SDRAM
|
|
|
- input wrq0, // Write request
|
|
|
- output reg wack0, // Write ack (data latched)
|
|
|
+ input [7:0] wd0, // Data to SDRAM
|
|
|
+ input wrq0, // Write request
|
|
|
+ output reg wack0, // Write ack (data latched)
|
|
|
|
|
|
// Port 1
|
|
|
- input [24:2] a1,
|
|
|
- input [7:0] be1, // Write byte enable
|
|
|
+ input [24:2] a1,
|
|
|
+ input [7:0] be1, // Write byte enable
|
|
|
|
|
|
- output reg [31:0] rd1,
|
|
|
- input rrq1,
|
|
|
- output reg [t_rcd+t_cl+3:0] rack1,
|
|
|
+ output reg [31:0] rd1,
|
|
|
+ input rrq1,
|
|
|
+ output reg rack1,
|
|
|
+ output reg rvalid1,
|
|
|
|
|
|
- input [31:0] wd1,
|
|
|
- input wrq1,
|
|
|
- output reg wack1
|
|
|
+ input [31:0] wd1,
|
|
|
+ input wrq1,
|
|
|
+ output reg wack1
|
|
|
);
|
|
|
|
|
|
// Mode register data
|
|
@@ -179,8 +177,10 @@ module sdram
|
|
|
reg dram_d_en; // Drive data out
|
|
|
assign sr_dq = dram_d_en ? dram_d : 16'hzzzz;
|
|
|
|
|
|
- // Input register for SDRAM data
|
|
|
+ // I/O cell input register for SDRAM data
|
|
|
reg [15:0] dram_q;
|
|
|
+ always @(posedge clk)
|
|
|
+ dram_q <= sr_dq;
|
|
|
|
|
|
// State machine and counters
|
|
|
reg [t_refi_lg2-2:0] rfsh_ctr; // Refresh timer
|
|
@@ -191,7 +191,6 @@ module sdram
|
|
|
reg [1:0] rfsh_prio; // Refresh priority
|
|
|
// Bit 0 - refresh if opportune
|
|
|
// Bit 1 - refresh urgent
|
|
|
- reg port; // Port being serviced
|
|
|
|
|
|
reg [3:0] op_cycle; // Cycles into the current operation
|
|
|
|
|
@@ -254,7 +253,7 @@ module sdram
|
|
|
end // else: !if(~rst_n)
|
|
|
|
|
|
reg [31:0] wdata_q;
|
|
|
- reg [ 6:0] be_q;
|
|
|
+ reg [ 7:0] be_q;
|
|
|
|
|
|
//
|
|
|
// Careful with the timing here... there is one cycle between
|
|
@@ -271,13 +270,20 @@ module sdram
|
|
|
dram_dqm <= 2'b00;
|
|
|
dram_d <= 16'hxxxx;
|
|
|
dram_d_en <= 1'b1; // Don't float except during read
|
|
|
+
|
|
|
op_cycle <= 1'b0;
|
|
|
state <= st_reset;
|
|
|
|
|
|
- rack0 <= 1'b0;
|
|
|
- wack0 <= 1'b0;
|
|
|
- rack1 <= 1'b0;
|
|
|
- wack1 <= 1'b0;
|
|
|
+ rack0 <= 1'b0;
|
|
|
+ rvalid0 <= 1'b0;
|
|
|
+ wack0 <= 1'b0;
|
|
|
+
|
|
|
+ rack1 <= 1'b0;
|
|
|
+ rvalid1 <= 1'b0;
|
|
|
+ wack1 <= 1'b0;
|
|
|
+
|
|
|
+ wdata_q <= 32'hxxxx_xxxx;
|
|
|
+ be_q <= 8'hxx;
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
@@ -285,17 +291,17 @@ module sdram
|
|
|
|
|
|
// Default values
|
|
|
dram_ba <= 2'bxx;
|
|
|
- dram_dqm <= 2'b11;
|
|
|
+ dram_dqm <= 2'b00;
|
|
|
dram_d <= 16'hxxxx;
|
|
|
dram_cmd <= cmd_nop;
|
|
|
|
|
|
- rack0 <= rack0 >> 1;
|
|
|
- wack0 <= 1'b0;
|
|
|
- rack1 <= rack1 >> 1;
|
|
|
- wack1 <= 1'b0;
|
|
|
-
|
|
|
dram_d_en <= 1'b1; // Don't float except during read
|
|
|
|
|
|
+ rack0 <= 1'b0;
|
|
|
+ wack0 <= 1'b0;
|
|
|
+ rack1 <= 1'b0;
|
|
|
+ wack1 <= 1'b0;
|
|
|
+
|
|
|
if (state == st_reset || state == st_idle)
|
|
|
op_cycle <= 1'b0;
|
|
|
else
|
|
@@ -341,12 +347,11 @@ module sdram
|
|
|
4'b1???:
|
|
|
begin
|
|
|
// Begin port 0 transaction
|
|
|
- dram_cmd <= cmd_act;
|
|
|
- dram_a <= a0[24:12];
|
|
|
- dram_ba <= a0[11:10];
|
|
|
- col_addr <= a0[11:2];
|
|
|
- be_q <= 1'b1 << a0[1:0];
|
|
|
- port <= 1'b0;
|
|
|
+ dram_cmd <= cmd_act;
|
|
|
+ dram_a <= a0[24:12];
|
|
|
+ dram_ba <= a0[11:10];
|
|
|
+ col_addr <= a0[11:2];
|
|
|
+ be_q <= 1'b1 << a0[1:0];
|
|
|
if ( wrq0 )
|
|
|
begin
|
|
|
state <= st_wr;
|
|
@@ -355,19 +360,19 @@ module sdram
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- state <= st_rd;
|
|
|
- rack0[t_rcd+t_cl+3] <= 1'b1;
|
|
|
+ state <= st_rd;
|
|
|
+ rack0 <= 1'b1;
|
|
|
+ rvalid0 <= 1'b0;
|
|
|
end
|
|
|
end
|
|
|
4'b010?:
|
|
|
begin
|
|
|
// Begin port 1 transaction
|
|
|
- dram_cmd <= cmd_act;
|
|
|
- dram_a <= a1[24:12];
|
|
|
- dram_ba <= a1[11:10];
|
|
|
- col_addr <= a1[11:2];
|
|
|
- be_q <= be1;
|
|
|
- port <= 1'b1;
|
|
|
+ dram_cmd <= cmd_act;
|
|
|
+ dram_a <= a1[24:12];
|
|
|
+ dram_ba <= a1[11:10];
|
|
|
+ col_addr <= a1[11:2];
|
|
|
+ be_q <= be1;
|
|
|
if ( wrq1 )
|
|
|
begin
|
|
|
state <= st_wr;
|
|
@@ -376,8 +381,9 @@ module sdram
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- state <= st_rd;
|
|
|
- rack1[t_rcd+t_cl+3] <= 1'b1;
|
|
|
+ state <= st_rd;
|
|
|
+ rack1 <= 1'b1;
|
|
|
+ rvalid1 <= 1'b0;
|
|
|
end
|
|
|
end
|
|
|
4'b0?1?, 4'b0001:
|
|
@@ -400,8 +406,10 @@ module sdram
|
|
|
end
|
|
|
st_rd:
|
|
|
begin
|
|
|
- dram_d_en <= 1'b0; // Tristate our output
|
|
|
- dram_dqm <= 2'b00;
|
|
|
+ rack0 <= rack0;
|
|
|
+ rack1 <= rack1;
|
|
|
+
|
|
|
+ dram_d_en <= 1'b0; // Tristate data bus
|
|
|
|
|
|
// Commands
|
|
|
//
|
|
@@ -430,41 +438,59 @@ module sdram
|
|
|
end
|
|
|
10: begin
|
|
|
state <= st_idle;
|
|
|
+ rack0 <= 1'b0;
|
|
|
+ rack1 <= 1'b0;
|
|
|
end
|
|
|
endcase // case (op_cycle)
|
|
|
|
|
|
// +2 for bus turnaround latencies
|
|
|
+ // Assert rvalid in the same cycle the last requested
|
|
|
+ // data byte (as given by byte enables) is latched.
|
|
|
+
|
|
|
if (op_cycle >= 2+t_cl+2)
|
|
|
begin
|
|
|
- if (port == 1'b0)
|
|
|
+ if (rack0)
|
|
|
begin
|
|
|
+ rvalid0 <= ~|be_q[7:2];
|
|
|
+
|
|
|
if (be_q[0])
|
|
|
rd0 <= dram_q[7:0];
|
|
|
if (be_q[1])
|
|
|
rd0 <= dram_q[15:8];
|
|
|
end
|
|
|
- else if (op_cycle[0] ^ ((2+t_cl+2) & 1'b1))
|
|
|
- begin
|
|
|
- // Odd word
|
|
|
- if (be_q[0])
|
|
|
- rd1[23:16] <= dram_q[ 7:0];
|
|
|
- if (be_q[1])
|
|
|
- rd1[31:24] <= dram_q[15:8];
|
|
|
- end
|
|
|
- else
|
|
|
+ if (rack1)
|
|
|
begin
|
|
|
- // Even word
|
|
|
- if (be_q[0])
|
|
|
- rd1[ 7:0] <= dram_q[ 7:0];
|
|
|
- if (be_q[1])
|
|
|
- rd1[15:8] <= dram_q[15:8];
|
|
|
- end // else: !if(op_cycle[0] ^ ((t_rcd-1+t_cl+2) & 1'b1))
|
|
|
+ rvalid1 <= ~|be_q[7:2];
|
|
|
+
|
|
|
+ if (op_cycle[0] ^ ((2+t_cl+2) & 1'b1))
|
|
|
+ begin
|
|
|
+ // Odd word
|
|
|
+ if (be_q[0])
|
|
|
+ rd1[23:16] <= dram_q[ 7:0];
|
|
|
+ if (be_q[1])
|
|
|
+ rd1[31:24] <= dram_q[15:8];
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ // Even word
|
|
|
+ if (be_q[0])
|
|
|
+ rd1[ 7:0] <= dram_q[ 7:0];
|
|
|
+ if (be_q[1])
|
|
|
+ rd1[15:8] <= dram_q[15:8];
|
|
|
+ end // else: !if(op_cycle[0] ^ ((t_rcd-1+t_cl+2) & 1'b1))
|
|
|
+ end // if (rack1)
|
|
|
+
|
|
|
be_q >>= 2;
|
|
|
end // if (op_cycle >= 2+t_cl+2)
|
|
|
end // case: st_rd
|
|
|
|
|
|
st_wr:
|
|
|
begin
|
|
|
+ wack0 <= wack0;
|
|
|
+ wack1 <= wack1;
|
|
|
+
|
|
|
+ dram_dqm <= 2'b11; // Mask data bytes unless we mean it
|
|
|
+
|
|
|
// Commands
|
|
|
//
|
|
|
// This assumes:
|
|
@@ -494,6 +520,8 @@ module sdram
|
|
|
end
|
|
|
10: begin
|
|
|
state <= st_idle;
|
|
|
+ wack0 <= 1'b0;
|
|
|
+ wack1 <= 1'b0;
|
|
|
end
|
|
|
endcase // case (op_cycle)
|
|
|
|