Skip to content

Commit b300a4d

Browse files
committed
Add configurable CS to clock-start delay
Acording to spec: t_DSV (data strobe valid) which is the time from CS# going low to the first hyperbus clock can be at most 2 clock periods long (12ns@166MHz). This shrinks the RWDS valid window down to one period centered on CA4 (5th data transaction). Meaning it is valid around the 3rd rising edge of CK. Problem: With additional routing delay this may cause the RWDS sample register (clocked by clk_i) to miss the stable period of RWDS. Solution: Delaying the clock is allowed and gives RWDS more time to arrive and creates a larger stable window. It is possible to set this to zero to increase throughput.
1 parent d00e4c5 commit b300a4d

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

src/hyperbus_cfg_regs.sv

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ module hyperbus_cfg_regs #(
3030
`include "common_cells/registers.svh"
3131

3232
// Internal Parameters
33-
localparam int unsigned NumBaseRegs = 11;
33+
localparam int unsigned NumBaseRegs = 12;
3434
localparam int unsigned NumRegs = 2*NumChips + NumBaseRegs;
3535
localparam int unsigned RegsBits = cf_math_pkg::idx_width(NumRegs);
36-
localparam int unsigned RegStrbWidth = RegDataWidth/8; // TODO ASSERT: Must be power of two >= 16!!
36+
localparam int unsigned RegStrbWidth = RegDataWidth/8;
3737

3838
// Data and index types
3939
typedef logic [RegsBits-1:0] reg_idx_t;
@@ -59,6 +59,7 @@ module hyperbus_cfg_regs #(
5959
if (sel_reg_mapped) begin
6060
rfield = {
6161
crange_q,
62+
reg_data_t'(cfg_q.csn_to_ck_cycles),
6263
reg_data_t'(cfg_q.t_csh_cycles),
6364
reg_data_t'(cfg_q.which_phy),
6465
reg_data_t'(cfg_q.phys_in_use),
@@ -99,6 +100,7 @@ module hyperbus_cfg_regs #(
99100
'h8: cfg_d.phys_in_use = (NumPhys==1) ? 0 : ( (~wmask & cfg_q.phys_in_use ) | (wmask & reg_req_i.wdata) );
100101
'h9: cfg_d.which_phy = (NumPhys==1) ? 0 : ( (~wmask & cfg_q.which_phy ) | (wmask & reg_req_i.wdata) );
101102
'ha: cfg_d.t_csh_cycles = (~wmask & cfg_q.t_csh_cycles ) | (wmask & reg_req_i.wdata);
103+
'hb: cfg_d.csn_to_ck_cycles = (~wmask & cfg_q.csn_to_ck_cycles ) | (wmask & reg_req_i.wdata);
102104
default: begin
103105
{sel_chip, chip_reg} = sel_reg - NumBaseRegs;
104106
crange_d[sel_chip][chip_reg] = (~wmask & crange_q[sel_chip][chip_reg]) | (wmask & reg_req_i.wdata);

src/hyperbus_phy.sv

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,32 @@ module hyperbus_phy import hyperbus_pkg::*; #(
269269
if (trans_valid_i & ~b_pending_q & r_outstand_q == '0) begin
270270
tf_d = trans_i;
271271
cs_d = trans_cs_i;
272-
// Send 3 CA words (t_CSS respected through clock delay)
273-
timer_d = 2;
274-
state_d = SendCA;
275-
// Enable output driver (needs to be enabled one cycle
276-
// earlier since tri-state enables of IO pads are quite
277-
// slow compared to the data pins)
272+
273+
if(cfg_i.csn_to_ck_cycles != 0) begin
274+
// asser CS but delay hyper_ck to allow more time
275+
// for memory to drive RWDS (to satisfy t_DSV)
276+
state_d = DelayCK;
277+
timer_d = cfg_i.csn_to_ck_cycles -1;
278+
end else begin
279+
// max throughput when memory RWDS signal arrives early
280+
state_d = SendCA;
281+
// Send 3 CA words (t_CSS respected through clock delay)
282+
timer_d = 2;
283+
end
284+
285+
// Enable output driver (needs to be enabled at least
286+
// one cycle earlier since tri-state enables of IO pads
287+
// are quite slow compared to the data pins)
278288
trx_tx_data_oe = 1'b1;
279289
end
280290
end
291+
DelayCK: begin
292+
trx_clk_ena = 1'b0;
293+
if (ctl_timer_zero) begin
294+
timer_d = 2; // Send 3 CA words
295+
state_d = SendCA;
296+
end
297+
end
281298
SendCA: begin
282299
// Dataflow handled outside FSM
283300
trx_clk_ena = 1'b1;

src/hyperbus_pkg.sv

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ package hyperbus_pkg;
2020
logic address_space;
2121
logic phys_in_use;
2222
logic which_phy;
23-
logic [3:0] t_csh_cycles; //add an configurable Tcsh for high freq operation(200MHz Hyperram)
23+
logic [3:0] t_csh_cycles; // add an configurable Tcsh for high freq operation(200MHz Hyperram)
24+
logic [3:0] csn_to_ck_cycles; // delay hyper_ck after CS is asserted (more time for t_DSV)
2425
} hyper_cfg_t;
2526

2627
typedef struct packed {
@@ -40,6 +41,7 @@ package hyperbus_pkg;
4041
typedef enum logic[3:0] {
4142
Startup,
4243
Idle,
44+
DelayCK,
4345
SendCA,
4446
WaitLatAccess,
4547
Read,
@@ -74,7 +76,8 @@ package hyperbus_pkg;
7476
address_space: 'b0,
7577
phys_in_use: NumPhys-1,
7678
which_phy: NumPhys-1,
77-
t_csh_cycles: 'h1
79+
t_csh_cycles: 'h1,
80+
csn_to_ck_cycles: 'h2
7881
};
7982

8083
return cfg;

0 commit comments

Comments
 (0)