feat: add psram more perf tuning for tht 144MHz

This commit is contained in:
maksyuki committed 2025-02-19 12:32:06 +08:00
1 parent a571ce69c3
commit e42f56a668
3 files changed
+41 -41

No files matched your search

+14 -14
View File
@@ -1,41 +1,41 @@
// NOTE: for supporting cross page xfer, the max freq of 'sclk' is 84MHz
// when 'sclk' is 133MHz(max, ~7.52ns), according to TRM:
// when 'sclk' is 144MHz(max, ~6.94ns), according to TRM:
//
// tCLK(min: 7ns) is meet, dont have 8'h03 rd oper(min: 30.3ns)
// tCLK(min: 6.94ns) is meet, dont have 8'h03 rd oper(min: 30.3ns)
//
// tCH/tCL(min:0.45%, max: 0.55%) tCLK is meet
//
// tKHKL(max: 1.5ns) is meet
//
// tCPH(min: 50ns) -> 50 / 7.52 = ~6.6 so wait cycles need to >= ceil(6.6) = 7,
// so 'cfg_wait_o' = 7 * 2 >= 14 in default, reset value is 15
// tCPH(min: 50ns) -> 50 / 6.94 = ~7.2 so wait cycles need to >= ceil(7.2) = 8,
// so 'cfg_wait_o' = 8 * 2 >= 16 in default, reset value is '18'
// for lower freq, can modify this value for performance tuning
//
// tCEM(max: 8us) is enough long for just 32bits xfer:
// QPI mode: 32(cmd+addr) + 32(data) / 4 = 16 cycles
// for min sclk 12MHz, ~83ns * 16 = 1333ns = 1.333us
// QPI mode: (32(cmd+addr) + 32(data)) / 4 = 16 cycles + 6 wait cycles = 22 cycles
// for min sclk 12MHz, ~83ns * 22 = 1826ns = 1.826us
//
// tCSP(min: 2.5ns) is meet
// sclk keeps 7.52 / 2 = 3.76ns low at least after ce activing
// sclk keeps 6.94 / 2 = 3.47ns low at least after ce activing
//
// tCHD(min: 20ns) > tACLK + tCLK
// sclk keep 7.52 * 1.5 = 11.28 at least(no meet!)
// need to set 'cfg_chd_o' = ceil(ceil(20 / 7.52) - 1.5) * 2 = 2, reset value is 3
// sclk keep 6.94 * 1.5 = 10.41 at least(no meet!)
// need to set 'cfg_chd_o' = ceil(ceil(20 / 6.94) - 1.5) * 2 = 3, reset value is '4'
// for lower freq, can modify this value for performance tuning
//
// tSP(min: 2ns) is meet
// data keeps 7.52 / 2 = 3.76ns low at least befer sclk
// data keeps 6.94 / 2 = 3.47ns low at least befer sclk
module psram_top (
input clk_i,
input rst_n_i,
input cfg_wait_wr_en_i,
input [ 3:0] cfg_wait_i,
output [ 3:0] cfg_wait_o,
input [ 4:0] cfg_wait_i,
output [ 4:0] cfg_wait_o,
input cfg_chd_wr_en_i,
input [ 1:0] cfg_chd_i,
output [ 1:0] cfg_chd_o,
input [ 2:0] cfg_chd_i,
output [ 2:0] cfg_chd_o,
input mem_valid_i,
output mem_ready_o,
input [23:0] mem_addr_i,
+19 -19
View File
@@ -2,11 +2,11 @@ module psram_core (
input clk_i,
input rst_n_i,
input cfg_wait_wr_en_i,
input [ 3:0] cfg_wait_i,
output reg [ 3:0] cfg_wait_o,
input [ 4:0] cfg_wait_i,
output reg [ 4:0] cfg_wait_o,
input cfg_chd_wr_en_i,
input [ 1:0] cfg_chd_i,
output reg [ 1:0] cfg_chd_o,
input [ 2:0] cfg_chd_i,
output reg [ 2:0] cfg_chd_o,
output reg mem_ready_o,
input [23:0] mem_addr_i,
input [31:0] mem_wdata_i,
@@ -56,9 +56,9 @@ module psram_core (
reg [ 7:0] r_xfer_ca_bit_cnt;
reg [ 7:0] r_xfer_data_bit_cnt;
reg [ 7:0] r_xfer_byte_data;
reg [ 3:0] r_ce_cnt;
reg [ 4:0] r_ce_cnt;
reg [ 3:0] r_rd_wait_cnt;
reg [ 1:0] r_cfg_chd;
reg [ 2:0] r_cfg_chd;
reg r_dev_rst;
reg r_wr_st;
reg r_rd_st;
@@ -68,12 +68,12 @@ module psram_core (
// wait cycles(mmio)
always @(posedge clk_i or negedge rst_n_i) begin
if (~rst_n_i) cfg_wait_o <= 4'd15;
if (~rst_n_i) cfg_wait_o <= 5'd18;
else if (cfg_wait_wr_en_i) cfg_wait_o <= cfg_wait_i;
end
// extra cycle for tCHD(mmio)
always @(posedge clk_i or negedge rst_n_i) begin
if (~rst_n_i) cfg_chd_o <= 2'd3;
if (~rst_n_i) cfg_chd_o <= 3'd4;
else if (cfg_chd_wr_en_i) cfg_chd_o <= cfg_chd_i;
end
@@ -121,9 +121,9 @@ module psram_core (
r_xfer_ca_bit_cnt <= 8'd0;
r_xfer_data_bit_cnt <= 8'd0;
r_xfer_byte_data <= 8'd0;
r_ce_cnt <= 4'd0;
r_ce_cnt <= 5'd0;
r_rd_wait_cnt <= 4'd0;
r_cfg_chd <= 2'd0;
r_cfg_chd <= 3'd0;
r_dev_rst <= 1'b1;
mem_ready_o <= 1'b0;
psram_sclk_o <= 1'b0;
@@ -138,7 +138,7 @@ module psram_core (
FSM_RSTEN: begin
r_xfer_ca <= {8'h66, 24'd0};
r_xfer_ca_bit_cnt <= 8'd8;
r_cfg_chd <= 2'd0;
r_cfg_chd <= 3'd0;
psram_ce_o <= 1'b0;
r_ce_cnt <= cfg_wait_o;
r_fsm_state <= FSM_SEND;
@@ -147,7 +147,7 @@ module psram_core (
FSM_RSTEN2RST: begin // tCPH >= 50ns, when 192MHz, ce need keep high(>=10 cycles)
if (r_cfg_chd == cfg_chd_o) begin
if (r_ce_cnt != cfg_wait_o) psram_ce_o <= 1'b1;
if (r_ce_cnt == 4'd0) r_fsm_state <= FSM_RST;
if (r_ce_cnt == 5'd0) r_fsm_state <= FSM_RST;
r_ce_cnt <= r_ce_cnt - 1'b1;
end else begin
r_cfg_chd <= r_cfg_chd + 1'b1;
@@ -165,7 +165,7 @@ module psram_core (
FSM_RST2QE: begin
if (r_cfg_chd == cfg_chd_o) begin
if (r_ce_cnt != cfg_wait_o) psram_ce_o <= 1'b1;
if (r_ce_cnt == 4'd0) r_fsm_state <= FSM_QE;
if (r_ce_cnt == 5'd0) r_fsm_state <= FSM_QE;
r_ce_cnt <= r_ce_cnt - 1'b1;
end else begin
r_cfg_chd <= r_cfg_chd + 1'b1;
@@ -174,7 +174,7 @@ module psram_core (
FSM_QE: begin
r_xfer_ca <= {8'h35, 24'd0};
r_xfer_ca_bit_cnt <= 8'd8;
r_cfg_chd <= 2'd0;
r_cfg_chd <= 3'd0;
psram_ce_o <= 1'b0;
r_ce_cnt <= cfg_wait_o;
r_fsm_state <= FSM_SEND;
@@ -183,7 +183,7 @@ module psram_core (
FSM_QE2IDLE: begin
if (r_cfg_chd == cfg_chd_o) begin
if (r_ce_cnt != cfg_wait_o) psram_ce_o <= 1'b1;
if (r_ce_cnt == 4'd0) r_fsm_state <= FSM_IDLE;
if (r_ce_cnt == 5'd0) r_fsm_state <= FSM_IDLE;
r_ce_cnt <= r_ce_cnt - 1'b1;
end else begin
r_cfg_chd <= r_cfg_chd + 1'b1;
@@ -201,7 +201,7 @@ module psram_core (
r_fsm_state <= FSM_SEND_QPI;
r_fsm_state_tgt <= FSM_WR_QPI;
r_xfer_data_bit_cnt <= 8'd0;
r_cfg_chd <= 2'd0;
r_cfg_chd <= 3'd0;
psram_ce_o <= 1'b0;
end else if (r_rd_st) begin
r_xfer_ca <= {8'hEB, mem_addr_i[23:0]};
@@ -210,7 +210,7 @@ module psram_core (
r_fsm_state_tgt <= FSM_RD_PRE_QPI;
r_rd_wait_cnt <= 4'd12; // wait 6 cycle afer cmd+addr accrondig to TRM
r_xfer_data_bit_cnt <= 8'd0;
r_cfg_chd <= 2'd0;
r_cfg_chd <= 3'd0;
psram_ce_o <= 1'b0;
end else begin
psram_ce_o <= 1'b1;
@@ -281,7 +281,7 @@ module psram_core (
psram_ce_o <= 1'b1;
r_xfer_data[31:24] <= r_xfer_byte_data; // HACK:
end
if (r_ce_cnt == 4'd0) begin
if (r_ce_cnt == 5'd0) begin
r_fsm_state <= FSM_IDLE;
mem_ready_o <= 1'b1;
end
@@ -293,7 +293,7 @@ module psram_core (
FSM_WR2IDLE: begin
if (r_cfg_chd == cfg_chd_o) begin
if (r_ce_cnt != cfg_wait_o) psram_ce_o <= 1'b1;
if (r_ce_cnt == 4'd0) begin
if (r_ce_cnt == 5'd0) begin
r_fsm_state <= FSM_IDLE;
mem_ready_o <= 1'b1;
end
+8 -8
View File
@@ -363,10 +363,10 @@ module retrosoc #(
// psram
wire s_psram_cfg_wait_sel = s_iomem_valid && (s_iomem_addr == 32'h0300_0080);
wire s_psram_cfg_chd_sel = s_iomem_valid && (s_iomem_addr == 32'h0300_0084);
reg [ 3:0] r_psram_cfg_wait_din;
wire [ 3:0] s_psram_cfg_wait_dout;
reg [ 1:0] r_psram_cfg_chd_din;
wire [ 1:0] s_psram_cfg_chd_dout;
reg [ 4:0] r_psram_cfg_wait_din;
wire [ 4:0] s_psram_cfg_wait_dout;
reg [ 2:0] r_psram_cfg_chd_din;
wire [ 2:0] s_psram_cfg_chd_dout;
spimemio u_spimemio (
.clk (clk_i),
@@ -636,12 +636,12 @@ module retrosoc #(
8'h6c: r_iomem_rdata <= s_tim1_reg_val_dout;
8'h70: r_iomem_rdata <= s_tim1_reg_dat_dout;
8'h80: begin
r_iomem_rdata <= {28'd0, s_psram_cfg_wait_dout};
if (s_iomem_wstrb[0]) r_psram_cfg_wait_din <= s_iomem_wdata[3:0];
r_iomem_rdata <= {27'd0, s_psram_cfg_wait_dout};
if (s_iomem_wstrb[0]) r_psram_cfg_wait_din <= s_iomem_wdata[4:0];
end
8'h84: begin
r_iomem_rdata <= {30'd0, s_psram_cfg_chd_dout};
if (s_iomem_wstrb[0]) r_psram_cfg_chd_din <= s_iomem_wdata[1:0];
r_iomem_rdata <= {29'd0, s_psram_cfg_chd_dout};
if (s_iomem_wstrb[0]) r_psram_cfg_chd_din <= s_iomem_wdata[2:0];
end
endcase
end else if (s_iomem_valid && !r_iomem_ready && s_aximem_range) begin