mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-07 08:27:07 +00:00
Archie: 128 bit burst read for VIDC
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
*/
|
||||
|
||||
localparam RASCAS_DELAY = 3'd3; // tRCD=20ns -> 3 cycles@128MHz
|
||||
localparam BURST_LENGTH = 3'b010; // 000=1, 001=2, 010=4, 011=8, 111 = continuous.
|
||||
localparam BURST_LENGTH = 3'b011; // 000=1, 001=2, 010=4, 011=8, 111 = continuous.
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd3; // 2/3 allowed
|
||||
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
|
||||
|
||||
@@ -63,15 +63,15 @@ localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, B
|
||||
reg [3:0] t;
|
||||
reg [4:0] reset;
|
||||
|
||||
reg[31:0] sd_dat = 0; // data output to chipset/cpu
|
||||
reg[31:0] sd_dat_nxt = 0; // data output to chipset/cpu
|
||||
reg [31:0] sd_dat[4]; // data output to chipset/cpu
|
||||
reg [2:0] sd_word;
|
||||
|
||||
reg sd_stb = 1'b0; // copy of the wishbone bus signal.
|
||||
reg sd_we = 1'b0; // copy of the wishbone bus signal.
|
||||
reg sd_cyc = 1'b0; // copy of the wishbone bus signal.
|
||||
reg sd_burst = 1'b0;
|
||||
|
||||
reg [3:0] sd_cycle= 4'd0;
|
||||
reg [4:0] sd_cycle= 5'd0;
|
||||
reg sd_done = 1'b0;
|
||||
|
||||
reg [3:0] sd_cmd = 4'd0; // current command sent to sd ram
|
||||
@@ -91,21 +91,24 @@ initial begin
|
||||
sd_cmd = CMD_INHIBIT;
|
||||
end
|
||||
|
||||
localparam CYCLE_PRECHARGE = 4'd0;
|
||||
localparam CYCLE_RAS_START = 4'd3;
|
||||
localparam CYCLE_PRECHARGE = 5'd0;
|
||||
localparam CYCLE_RAS_START = 5'd3;
|
||||
localparam CYCLE_RFSH_START = CYCLE_RAS_START;
|
||||
localparam CYCLE_CAS0 = CYCLE_RAS_START + RASCAS_DELAY;
|
||||
localparam CYCLE_CAS1 = CYCLE_CAS0 + 4'd1;
|
||||
localparam CYCLE_CAS2 = CYCLE_CAS1 + 4'd1;
|
||||
localparam CYCLE_CAS3 = CYCLE_CAS2 + 4'd1;
|
||||
localparam CYCLE_READ0 = CYCLE_CAS0 + CAS_LATENCY + 4'd1;
|
||||
localparam CYCLE_CAS1 = CYCLE_CAS0 + 1'd1;
|
||||
localparam CYCLE_CAS2 = CYCLE_CAS1 + 1'd1;
|
||||
localparam CYCLE_READ0 = CYCLE_CAS0 + CAS_LATENCY + 1'd1;
|
||||
localparam CYCLE_READ1 = CYCLE_READ0+ 1'd1;
|
||||
localparam CYCLE_READ2 = CYCLE_READ1+ 1'd1;
|
||||
localparam CYCLE_READ3 = CYCLE_READ2+ 1'd1;
|
||||
localparam CYCLE_END = CYCLE_READ3+ 1'd1;
|
||||
localparam CYCLE_READ4 = CYCLE_READ3+ 1'd1;
|
||||
localparam CYCLE_READ5 = CYCLE_READ4+ 1'd1;
|
||||
localparam CYCLE_READ6 = CYCLE_READ5+ 1'd1;
|
||||
localparam CYCLE_READ7 = CYCLE_READ6+ 1'd1;
|
||||
localparam CYCLE_END = CYCLE_READ7+ 1'd1;
|
||||
localparam CYCLE_RFSH_END = CYCLE_RFSH_START + RFC_DELAY;
|
||||
|
||||
localparam RAM_CLK = 128000000;
|
||||
localparam RAM_CLK = 120000000;
|
||||
localparam REFRESH_PERIOD = (RAM_CLK / (16 * 8192)) - CYCLE_END;
|
||||
|
||||
`ifdef VERILATOR
|
||||
@@ -127,7 +130,8 @@ always @(posedge sd_clk) begin
|
||||
sd_ready <= 0;
|
||||
end else begin
|
||||
if (!sd_ready) begin
|
||||
t <= t + 4'd1;
|
||||
sd_word <= 0;
|
||||
t <= t + 1'd1;
|
||||
|
||||
if (t ==4'hF) begin
|
||||
reset <= reset - 5'd1;
|
||||
@@ -165,12 +169,15 @@ always @(posedge sd_clk) begin
|
||||
end
|
||||
|
||||
sd_refresh <= sd_refresh + 9'd1;
|
||||
|
||||
if(|sd_word) begin
|
||||
sd_word <= sd_word + 1'd1;
|
||||
sd_dat[sd_word[2:1]][{sd_word[0],4'b0000} +:16] <= sd_dq;
|
||||
end
|
||||
// this is the auto refresh code.
|
||||
// it kicks in so that 8192 auto refreshes are
|
||||
// issued in a 64ms period. Other bus operations
|
||||
// are stalled during this period.
|
||||
if ((sd_refresh > REFRESH_PERIOD) && (sd_cycle == 4'd0)) begin
|
||||
if ((sd_refresh > REFRESH_PERIOD) && (sd_cycle == 5'd0)) begin
|
||||
sd_auto_refresh <= 1'b1;
|
||||
sd_refresh <= 10'd0;
|
||||
sd_cmd <= CMD_PRECHARGE;
|
||||
@@ -178,7 +185,7 @@ always @(posedge sd_clk) begin
|
||||
sd_bank_active <= 0;
|
||||
end else if (sd_auto_refresh) begin
|
||||
// while the cycle is active count.
|
||||
sd_cycle <= sd_cycle + 3'd1;
|
||||
sd_cycle <= sd_cycle + 1'd1;
|
||||
case (sd_cycle)
|
||||
CYCLE_RFSH_START: begin
|
||||
sd_cmd <= CMD_AUTO_REFRESH;
|
||||
@@ -186,20 +193,20 @@ always @(posedge sd_clk) begin
|
||||
CYCLE_RFSH_END: begin
|
||||
// reset the count.
|
||||
sd_auto_refresh <= 1'b0;
|
||||
sd_cycle <= 4'd0;
|
||||
sd_cycle <= 5'd0;
|
||||
end
|
||||
endcase
|
||||
|
||||
end else if (sd_cyc | (sd_cycle != 0) | (sd_cycle == 0 && sd_req)) begin
|
||||
|
||||
// while the cycle is active count.
|
||||
sd_cycle <= sd_cycle + 3'd1;
|
||||
sd_cycle <= sd_cycle + 1'd1;
|
||||
case (sd_cycle)
|
||||
CYCLE_PRECHARGE: begin
|
||||
if (~sd_bank_active[sd_bank])
|
||||
sd_cycle <= CYCLE_RAS_START;
|
||||
else if (sd_active_row[sd_bank] == sd_row)
|
||||
sd_cycle <= CYCLE_CAS0 - 1'd1; // FIXME: Why doesn't work without -1?
|
||||
sd_cycle <= CYCLE_CAS0;
|
||||
else begin
|
||||
sd_cmd <= CMD_PRECHARGE;
|
||||
sd_addr[10] <= 0;
|
||||
@@ -213,25 +220,19 @@ always @(posedge sd_clk) begin
|
||||
sd_ba <= sd_bank;
|
||||
sd_active_row[sd_bank] <= sd_row;
|
||||
sd_bank_active[sd_bank] <= 1;
|
||||
|
||||
if(sd_reading) begin
|
||||
sd_dqm <= 2'b00;
|
||||
end else begin
|
||||
sd_dqm <= 2'b11;
|
||||
end
|
||||
end
|
||||
|
||||
// this is the first CAS cycle
|
||||
CYCLE_CAS0: begin
|
||||
// always, always read on a 32bit boundary and completely ignore the lsb of wb_adr.
|
||||
sd_addr <= { 4'b0000, wb_adr[23], wb_adr[8:2], 1'b0 }; // no auto precharge
|
||||
sd_dqm <= ~wb_sel[1:0];
|
||||
sd_ba <= sd_bank;
|
||||
|
||||
if (sd_reading) begin
|
||||
sd_cmd <= CMD_READ;
|
||||
end else if (sd_writing) begin
|
||||
sd_cmd <= CMD_WRITE;
|
||||
sd_dqm <= ~wb_sel[1:0];
|
||||
`ifdef VERILATOR
|
||||
sd_q <= wb_dat_i[15:0];
|
||||
`else
|
||||
@@ -243,12 +244,12 @@ always @(posedge sd_clk) begin
|
||||
CYCLE_CAS1: begin
|
||||
// now we access the second part of the 32 bit location.
|
||||
sd_addr <= { 4'b0000, wb_adr[23], wb_adr[8:2], 1'b1 }; // no auto precharge
|
||||
sd_dqm <= ~wb_sel[3:2];
|
||||
|
||||
if (sd_reading) sd_dqm <= ~wb_sel[1:0];
|
||||
if (sd_reading & burst_mode & can_burst) sd_burst <= 1'b1;
|
||||
|
||||
if (sd_writing) begin
|
||||
sd_cmd <= CMD_WRITE;
|
||||
sd_dqm <= ~wb_sel[3:2];
|
||||
sd_done <= ~sd_done;
|
||||
`ifdef VERILATOR
|
||||
sd_q <= wb_dat_i[31:16];
|
||||
@@ -258,41 +259,28 @@ always @(posedge sd_clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
CYCLE_CAS2: if (sd_reading) sd_dqm <= ~wb_sel[3:2];
|
||||
|
||||
CYCLE_READ0: begin
|
||||
if (sd_reading) begin
|
||||
sd_dat[15:0] <= sd_dq;
|
||||
sd_dat[0][15:0] <= sd_dq;
|
||||
sd_word <= 2'b01;
|
||||
end else begin
|
||||
if (sd_writing) sd_cycle <= CYCLE_END;
|
||||
end
|
||||
end
|
||||
|
||||
CYCLE_READ1: begin
|
||||
if (sd_reading) begin
|
||||
sd_dat[31:16] <= sd_dq;
|
||||
sd_done <= ~sd_done;
|
||||
end
|
||||
end
|
||||
|
||||
CYCLE_READ2: begin
|
||||
if (sd_reading) begin
|
||||
sd_dat_nxt[15:0] <= sd_dq;
|
||||
end
|
||||
end
|
||||
|
||||
CYCLE_READ3: begin
|
||||
if (sd_reading) begin
|
||||
sd_dat_nxt[31:16] <= sd_dq;
|
||||
end
|
||||
end
|
||||
CYCLE_READ1: if (sd_reading) sd_done <= ~sd_done;
|
||||
|
||||
CYCLE_END: begin
|
||||
sd_burst <= 1'b0;
|
||||
sd_cyc <= 1'b0;
|
||||
sd_stb <= 1'b0;
|
||||
sd_cycle <= 5'd0;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
sd_cycle <= 4'd0;
|
||||
sd_cycle <= 5'd0;
|
||||
sd_burst <= 1'b0;
|
||||
end
|
||||
end
|
||||
@@ -300,7 +288,7 @@ always @(posedge sd_clk) begin
|
||||
end
|
||||
|
||||
reg wb_burst;
|
||||
|
||||
reg [1:0] wb_word;
|
||||
always @(posedge wb_clk) begin
|
||||
reg sd_doneD;
|
||||
|
||||
@@ -311,16 +299,18 @@ always @(posedge wb_clk) begin
|
||||
|
||||
if ((sd_done ^ sd_doneD) & ~wb_ack) begin
|
||||
|
||||
wb_dat_o <= sd_dat;
|
||||
wb_dat_o <= sd_dat[0];
|
||||
wb_burst <= burst_mode;
|
||||
wb_word <= 2'b01;
|
||||
|
||||
end
|
||||
|
||||
if (wb_ack & wb_burst) begin
|
||||
|
||||
wb_ack <= 1'b1;
|
||||
wb_burst <= 1'b0;
|
||||
wb_dat_o <= sd_dat_nxt;
|
||||
wb_burst <= ~&wb_word;
|
||||
wb_word <= wb_word + 1'd1;
|
||||
wb_dat_o <= sd_dat[wb_word];
|
||||
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user