feat: add xfer ctrl logic

This commit is contained in:
maksyuki committed 2025-02-15 20:39:18 +08:00
1 parent ea21aa9da7
commit 7d49b8ce9c
2 files changed
+66 -7

No files matched your search

+60 -2
View File
@@ -8,6 +8,7 @@ module psram_top (
input we_i,
input rd_i,
output ready_o,
output reg xfer_end_o,
input cfg_wr_en_i,
input [ 3:0] cfg_wait_i,
output [ 3:0] cfg_wait_o,
@@ -110,7 +111,9 @@ module psram_top (
r_fsm_state <= FSM_IDLE;
r_core_ready <= 1'b0;
r_byte_xfer_cnt <= 4'd0;
xfer_end_o <= 1'b0;
end else begin
xfer_end_o <= 1'b0;
case (r_fsm_state)
// go FSM_IDLE right after reset, but first memory operation will
// hang until the psram is ready_o
@@ -118,7 +121,7 @@ module psram_top (
if (we_i) begin
r_fsm_state <= FSM_WE_ST;
r_core_ready <= 1'b0;
r_byte_xfer_cnt <= 4'd4;
r_byte_xfer_cnt <= 4'd4; // TODO: support wstrb
end else if (rd_i) begin
r_fsm_state <= FSM_RD_ST;
r_core_ready <= 1'b0;
@@ -148,6 +151,7 @@ module psram_top (
if (r_byte_xfer_cnt == 4'd0) begin
r_fsm_state <= FSM_IDLE;
r_we_end <= 1'b1;
xfer_end_o <= 1'b1;
end
end
FSM_RD_ST: begin
@@ -168,6 +172,7 @@ module psram_top (
if (r_byte_xfer_cnt == 4'd0) begin
rdata_o <= {r_data_buf[3], r_data_buf[2], r_data_buf[1], r_data_buf[0]};
r_fsm_state <= FSM_IDLE;
xfer_end_o <= 1'b1;
end
end
endcase
@@ -176,6 +181,59 @@ module psram_top (
endmodule
module align_wdata (
input [ 3:0] wstrb,
input [31:0] wdata,
output reg [ 1:0] byte_offset,
output reg [ 2:0] wr_bytes,
output reg [31:0] wr_buffer
);
always @(*) begin
wr_buffer = wdata;
case (wstrb)
4'b0001: begin
byte_offset = 2'd0;
wr_buffer[31:24] = wdata[7:0];
wr_bytes = 3'd1;
end
4'b0010: begin
byte_offset = 2'd1;
wr_buffer[31:24] = wdata[15:8];
wr_bytes = 3'd1;
end
4'b0100: begin
byte_offset = 2'd2;
wr_buffer[31:24] = wdata[23:16];
wr_bytes = 3'd1;
end
4'b1000: begin
byte_offset = 2'd3;
wr_buffer[31:24] = wdata[31:24];
wr_bytes = 3'd1;
end
4'b0011: begin
byte_offset = 2'd0;
wr_buffer[31:16] = wdata[15:0];
wr_bytes = 3'd2;
end
4'b1100: begin
byte_offset = 2'd2;
wr_buffer[31:16] = wdata[31:16];
wr_bytes = 3'd2;
end
4'b1111: begin
byte_offset = 2'd0;
wr_buffer[31:0] = wdata[31:0];
wr_bytes = 3'd4;
end
default: begin
byte_offset = 2'd0;
wr_buffer = wdata;
wr_bytes = 3'd4;
end
endcase
end
endmodule
module psram_core (
input clk_i,
@@ -247,7 +305,7 @@ module psram_core (
else if (cfg_wr_en_i) cfg_wait_o <= cfg_wait_i;
end
assign ready_o = r_fsm_state == FSM_IDLE; // BUG:
assign ready_o = r_fsm_state == FSM_IDLE; // BUG:
assign psram_sio_oen_o = (r_fsm_state == FSM_RD_PRE_QUAD) | (r_fsm_state == FSM_RD_QUAD);
always @(*) begin
+6 -5
View File
@@ -144,7 +144,7 @@ module retrosoc #(
wire s_psram_valid;
wire s_psram_ready;
wire [ 3:0] s_psram_wstrb;
wire [29:0] s_psram_addr;
wire [31:0] s_psram_addr;
wire [31:0] s_psram_wdata;
wire [31:0] s_psram_rdata;
// mmio ctrl regs
@@ -444,20 +444,21 @@ module retrosoc #(
.irq_out (s_irq_tim1)
);
assign s_psram_addr = s_mem_addr[31:2];
assign s_psram_addr = s_mem_addr;
assign s_psram_wdata = s_mem_wdata;
assign s_psram_wstrb = s_mem_wstrb;
assign s_psram_valid = s_mem_valid && (s_mem_addr[31:24] == 8'h04);
psram_top u_psram_top (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.addr_i (s_psram_addr), // TODO:
.addr_i ({1'b0, s_psram_addr[22:0]}),
.wstrb_i (s_psram_wstrb),
.wdata_i (s_psram_wdata),
.rdata_o (s_psram_rdata),
.we_i (s_psram_valid && (|s_psram_wstrb)),
.rd_i (s_psram_valid && (~(|s_psram_wstrb))),
.ready_o (s_psram_ready),
.ready_o (),
.xfer_end_o (s_psram_ready),
.cfg_wr_en_i (s_psram_cfg_sel ? s_iomem_wstrb[0] : 1'b0),
.cfg_wait_i (r_psram_cfg_wait_din),
.cfg_wait_o (s_psram_cfg_wait_dout),
@@ -647,7 +648,7 @@ module retrosoc #(
// data mux
assign s_mem_ready = (s_iomem_valid && r_iomem_ready) ||
s_spimem_ready || r_ram_ready ||
s_spimemio_cfgreg_sel || (s_psram_ready & 0);
s_spimemio_cfgreg_sel || s_psram_ready;
assign s_mem_rdata = (s_iomem_valid && r_iomem_ready) ? r_iomem_rdata :
s_spimem_ready ? s_spimem_rdata :