mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: add psram more perf tuning for tht 144MHz
This commit is contained in:
3 files changed
+41
-41
No files matched your search
+14
-14
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user