diff --git a/.gitignore b/.gitignore index bdf1e1b..a63d836 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ .bender scripts/compile.tcl -models/s27ks0641 \ No newline at end of file +axi_log/ +work/ +transcript +modelsim.ini +vsim.wlf +models/s27ks0641 diff --git a/Bender.yml b/Bender.yml index 905e54d..e5a6717 100644 --- a/Bender.yml +++ b/Bender.yml @@ -47,5 +47,6 @@ sources: - test/fixture_hyperbus.sv - test/hyperbus_tb.sv - test/dut_if.sv + - test/hyperbus_tb_pkg.sv - test/axi_hyper_tb.sv - src/hyperbus.sv diff --git a/src/hyperbus.sv b/src/hyperbus.sv index cf7212d..7b4a005 100644 --- a/src/hyperbus.sv +++ b/src/hyperbus.sv @@ -28,13 +28,12 @@ module hyperbus #( parameter type reg_rsp_t = logic, parameter type axi_rule_t = logic, // The below have sensible defaults, but should be set on integration! - parameter int unsigned RxFifoLogDepth = 2, - parameter int unsigned TxFifoLogDepth = 2, + parameter int unsigned RxFifoLogDepth = 3, + parameter int unsigned TxFifoLogDepth = 3, parameter logic [RegDataWidth-1:0] RstChipBase = 'h0, // Base address for all chips parameter logic [RegDataWidth-1:0] RstChipSpace = 'h1_0000, // 64 KiB: Current maximum HyperBus device size parameter hyperbus_pkg::hyper_cfg_t RstCfg = hyperbus_pkg::gen_RstCfg(NumPhys,MinFreqMHz), parameter int unsigned PhyStartupCycles = 300 * 200, /* us*MHz */ // Conservative maximum frequency estimate - parameter int unsigned AxiLogDepth = 3, parameter int unsigned SyncStages = 2 ) ( input logic clk_phy_i, diff --git a/src/hyperbus_axi.sv b/src/hyperbus_axi.sv index ca78ed2..a54012b 100644 --- a/src/hyperbus_axi.sv +++ b/src/hyperbus_axi.sv @@ -170,7 +170,7 @@ module hyperbus_axi #( // ============================ axi_fifo #( - .Depth ( 4 ), + .Depth ( 8 ), .FallThrough ( 1'b0 ), .aw_chan_t ( axi_fifo_aw_chan_t ), .w_chan_t ( axi_fifo_w_chan_t ), @@ -420,7 +420,7 @@ module hyperbus_axi #( stream_fifo #( .FALL_THROUGH ( 1'b0 ), .T ( axi_w_chan_t ), - .DEPTH ( 8 ) + .DEPTH ( 16 ) ) wchan_stream_fifo ( .clk_i, .rst_ni, diff --git a/src/hyperbus_cfg_regs.sv b/src/hyperbus_cfg_regs.sv index d438007..70ac78e 100644 --- a/src/hyperbus_cfg_regs.sv +++ b/src/hyperbus_cfg_regs.sv @@ -30,10 +30,10 @@ module hyperbus_cfg_regs #( `include "common_cells/registers.svh" // Internal Parameters - localparam int unsigned NumBaseRegs = 11; + localparam int unsigned NumBaseRegs = 12; localparam int unsigned NumRegs = 2*NumChips + NumBaseRegs; localparam int unsigned RegsBits = cf_math_pkg::idx_width(NumRegs); - localparam int unsigned RegStrbWidth = RegDataWidth/8; // TODO ASSERT: Must be power of two >= 16!! + localparam int unsigned RegStrbWidth = RegDataWidth/8; // Data and index types typedef logic [RegsBits-1:0] reg_idx_t; @@ -59,6 +59,7 @@ module hyperbus_cfg_regs #( if (sel_reg_mapped) begin rfield = { crange_q, + reg_data_t'(cfg_q.csn_to_ck_cycles), reg_data_t'(cfg_q.t_csh_cycles), reg_data_t'(cfg_q.which_phy), reg_data_t'(cfg_q.phys_in_use), @@ -99,6 +100,7 @@ module hyperbus_cfg_regs #( 'h8: cfg_d.phys_in_use = (NumPhys==1) ? 0 : ( (~wmask & cfg_q.phys_in_use ) | (wmask & reg_req_i.wdata) ); 'h9: cfg_d.which_phy = (NumPhys==1) ? 0 : ( (~wmask & cfg_q.which_phy ) | (wmask & reg_req_i.wdata) ); 'ha: cfg_d.t_csh_cycles = (~wmask & cfg_q.t_csh_cycles ) | (wmask & reg_req_i.wdata); + 'hb: cfg_d.csn_to_ck_cycles = (~wmask & cfg_q.csn_to_ck_cycles ) | (wmask & reg_req_i.wdata); default: begin {sel_chip, chip_reg} = sel_reg - NumBaseRegs; crange_d[sel_chip][chip_reg] = (~wmask & crange_q[sel_chip][chip_reg]) | (wmask & reg_req_i.wdata); diff --git a/src/hyperbus_phy.sv b/src/hyperbus_phy.sv index 78ed27d..e9229fe 100644 --- a/src/hyperbus_phy.sv +++ b/src/hyperbus_phy.sv @@ -269,15 +269,32 @@ module hyperbus_phy import hyperbus_pkg::*; #( if (trans_valid_i & ~b_pending_q & r_outstand_q == '0) begin tf_d = trans_i; cs_d = trans_cs_i; - // Send 3 CA words (t_CSS respected through clock delay) - timer_d = 2; - state_d = SendCA; - // Enable output driver (needs to be enabled one cycle - // earlier since tri-state enables of IO pads are quite - // slow compared to the data pins) + + if(cfg_i.csn_to_ck_cycles != 0) begin + // asser CS but delay hyper_ck to allow more time + // for memory to drive RWDS (to satisfy t_DSV) + state_d = DelayCK; + timer_d = cfg_i.csn_to_ck_cycles -1; + end else begin + // max throughput when memory RWDS signal arrives early + state_d = SendCA; + // Send 3 CA words (t_CSS respected through clock delay) + timer_d = 2; + end + + // Enable output driver (needs to be enabled at least + // one cycle earlier since tri-state enables of IO pads + // are quite slow compared to the data pins) trx_tx_data_oe = 1'b1; end end + DelayCK: begin + trx_clk_ena = 1'b0; + if (ctl_timer_zero) begin + timer_d = 2; // Send 3 CA words + state_d = SendCA; + end + end SendCA: begin // Dataflow handled outside FSM trx_clk_ena = 1'b1; diff --git a/src/hyperbus_phy_if.sv b/src/hyperbus_phy_if.sv index 3203b63..55b395f 100644 --- a/src/hyperbus_phy_if.sv +++ b/src/hyperbus_phy_if.sv @@ -8,10 +8,8 @@ module hyperbus_phy_if import hyperbus_pkg::*; #( parameter int unsigned IsClockODelayed = 1, parameter int unsigned NumChips = 2, parameter int unsigned NumPhys = 2, - parameter int unsigned TimerWidth = 16, - parameter int unsigned RxFifoLogDepth = 3, parameter int unsigned StartupCycles = 60000, /*MHz*/ // Conservative maximum frequency estimate - parameter int unsigned SyncStages = 2, + parameter int unsigned SyncStages = 2, parameter type hyper_tx_t = logic, parameter type hyper_rx_t = logic )( @@ -52,20 +50,20 @@ module hyperbus_phy_if import hyperbus_pkg::*; #( output logic [NumPhys-1:0] hyper_reset_no ); - phy_rx_t [NumPhys-1:0] phy_fifo_rx; - phy_rx_t [NumPhys-1:0] fifo_axi_rx; - logic [NumPhys-1:0] phy_fifo_valid; - logic [NumPhys-1:0] phy_fifo_ready; - logic [NumPhys-1:0] fifo_axi_valid; - logic fifo_axi_ready; + phy_rx_t [NumPhys-1:0] phy_fifo_rx; + phy_rx_t [NumPhys-1:0] fifo_axi_rx; + logic [NumPhys-1:0] phy_fifo_valid; + logic [NumPhys-1:0] phy_fifo_ready; + logic [NumPhys-1:0] fifo_axi_valid; + logic fifo_axi_ready; logic [NumPhys-1:0][1:0] fifo_axi_usage; - logic tx_both_ready, ts_both_ready; - logic rx_both_valid, b_both_valid; + logic tx_both_ready, ts_both_ready; + logic rx_both_valid, b_both_valid; - logic [NumPhys-1:0] phy_tx_ready; - logic phy_tx_valid; + logic [NumPhys-1:0] phy_tx_ready; + logic phy_tx_valid; logic [NumPhys-1:0] phy_trans_ready; logic [NumPhys-1:0] phy_trans_valid; @@ -77,7 +75,7 @@ module hyperbus_phy_if import hyperbus_pkg::*; #( genvar i; generate - if (NumPhys==2) begin : phy_wrap + if (NumPhys==2) begin : phy_wrap logic [NumPhys-1:0] phy_enable; logic [NumPhys-1:0] phy_busy; @@ -152,45 +150,45 @@ module hyperbus_phy_if import hyperbus_pkg::*; #( .rst_ni ( rst_ni ), .test_mode_i ( test_mode_i ), - .cfg_i ( cfg_i ), + .cfg_i ( cfg_i ), .busy_o ( phy_busy[i] ), - .rx_data_o ( phy_fifo_rx[i].data ), - .rx_last_o ( phy_fifo_rx[i].last ), - .rx_error_o ( phy_fifo_rx[i].error ), - .rx_valid_o ( phy_fifo_valid[i] ), - .rx_ready_i ( phy_fifo_ready[i] ), + .rx_data_o ( phy_fifo_rx[i].data ), + .rx_last_o ( phy_fifo_rx[i].last ), + .rx_error_o ( phy_fifo_rx[i].error ), + .rx_valid_o ( phy_fifo_valid[i] ), + .rx_ready_i ( phy_fifo_ready[i] ), - .tx_data_i ( tx_i.data[16*i +:16] ), - .tx_strb_i ( tx_i.strb[2*i +:2] ), - .tx_last_i ( tx_i.last ), - .tx_valid_i ( phy_tx_valid ), - .tx_ready_o ( phy_tx_ready[i] ), + .tx_data_i ( tx_i.data[16*i +:16] ), + .tx_strb_i ( tx_i.strb[2*i +:2] ), + .tx_last_i ( tx_i.last ), + .tx_valid_i ( phy_tx_valid ), + .tx_ready_o ( phy_tx_ready[i] ), - .b_error_o ( phy_b_error[i] ), - .b_valid_o ( phy_b_valid[i] ), - .b_ready_i ( phy_b_ready ), + .b_error_o ( phy_b_error[i] ), + .b_valid_o ( phy_b_valid[i] ), + .b_ready_i ( phy_b_ready ), .trans_i ( trans_i ), .trans_cs_i ( trans_cs_i ), .trans_valid_i ( phy_trans_valid[i] ), .trans_ready_o ( phy_trans_ready[i] ), - .hyper_cs_no ( hyper_cs_no[i] ), - .hyper_ck_o ( hyper_ck_o[i] ), - .hyper_ck_no ( hyper_ck_no[i] ), - .hyper_rwds_o ( hyper_rwds_o[i] ), - .hyper_rwds_i ( hyper_rwds_i[i] ), - .hyper_rwds_oe_o( hyper_rwds_oe_o[i] ), - .hyper_dq_i ( hyper_dq_i[i] ), - .hyper_dq_o ( hyper_dq_o[i] ), - .hyper_dq_oe_o ( hyper_dq_oe_o[i] ), - .hyper_reset_no ( hyper_reset_no[i] ) - ); + .hyper_cs_no ( hyper_cs_no[i] ), + .hyper_ck_o ( hyper_ck_o[i] ), + .hyper_ck_no ( hyper_ck_no[i] ), + .hyper_rwds_o ( hyper_rwds_o[i] ), + .hyper_rwds_i ( hyper_rwds_i[i] ), + .hyper_rwds_oe_o( hyper_rwds_oe_o[i] ), + .hyper_dq_i ( hyper_dq_i[i] ), + .hyper_dq_o ( hyper_dq_o[i] ), + .hyper_dq_oe_o ( hyper_dq_oe_o[i] ), + .hyper_reset_no ( hyper_reset_no[i] ) + ); - end // for ( i=0; i