diff --git a/rtl/ip/cust/psram.v b/rtl/ip/cust/psram.v index 5b21f3c2..e5afc11a 100644 --- a/rtl/ip/cust/psram.v +++ b/rtl/ip/cust/psram.v @@ -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, diff --git a/rtl/ip/cust/psram_core.v b/rtl/ip/cust/psram_core.v index fc4f86a1..b7e53dff 100644 --- a/rtl/ip/cust/psram_core.v +++ b/rtl/ip/cust/psram_core.v @@ -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 diff --git a/rtl/retrosoc.v b/rtl/retrosoc.v index dd21d416..e198fe75 100644 --- a/rtl/retrosoc.v +++ b/rtl/retrosoc.v @@ -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