Skip to content

Commit 5c79efb

Browse files
committed
Sample RWDS relative to CS edge not clock start
1 parent 4d157b1 commit 5c79efb

File tree

5 files changed

+59
-72
lines changed

5 files changed

+59
-72
lines changed

src/hyperbus_cfg_regs.sv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ module hyperbus_cfg_regs #(
5858
if (sel_reg_mapped) begin
5959
rfield = {
6060
crange_q,
61-
reg_data_t'(cfg_q.rwds_sample_edge),
61+
reg_data_t'(cfg_q.rwds_sample),
6262
reg_data_t'(cfg_q.csn_to_ck_cycles),
6363
reg_data_t'(cfg_q.t_csh_cycles),
6464
reg_data_t'(cfg_q.which_phy),
@@ -101,7 +101,7 @@ module hyperbus_cfg_regs #(
101101
'h9: cfg_d.which_phy = (NumPhys==1) ? 0 : ( (~wmask & cfg_q.which_phy ) | (wmask & reg_req_i.wdata) );
102102
'ha: cfg_d.t_csh_cycles = (~wmask & cfg_q.t_csh_cycles ) | (wmask & reg_req_i.wdata);
103103
'hb: cfg_d.csn_to_ck_cycles = (~wmask & cfg_q.csn_to_ck_cycles ) | (wmask & reg_req_i.wdata);
104-
'hc: cfg_d.rwds_sample_edge = (~wmask & cfg_q.rwds_sample_edge ) | (wmask & reg_req_i.wdata);
104+
'hc: cfg_d.rwds_sample = (~wmask & cfg_q.rwds_sample ) | (wmask & reg_req_i.wdata);
105105
default: begin
106106
{sel_chip, chip_reg} = sel_reg - NumBaseRegs;
107107
crange_d[sel_chip][chip_reg] = (~wmask & crange_q[sel_chip][chip_reg]) | (wmask & reg_req_i.wdata);

src/hyperbus_phy.sv

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -121,24 +121,24 @@ module hyperbus_phy import hyperbus_pkg::*; #(
121121
.clk_i_90,
122122
.rst_ni,
123123
.test_mode_i,
124-
.cfg_edge_idx_i ( cfg_i.rwds_sample_edge.cylce_idx ),
125-
.cfg_edge_pol_i ( cfg_i.rwds_sample_edge.polarity ),
126-
.cs_i ( cs_q ),
127-
.cs_ena_i ( trx_cs_ena ),
128-
.rwds_sample_o ( trx_rwds_sample ),
129-
.rwds_sample_ena_i ( trx_rwds_sample_ena ),
130-
.tx_clk_delay_i ( cfg_i.t_tx_clk_delay ),
131-
.tx_clk_ena_i ( trx_clk_ena ),
132-
.tx_data_i ( trx_tx_data ),
133-
.tx_data_oe_i ( trx_tx_data_oe ),
134-
.tx_rwds_i ( trx_tx_rwds ),
135-
.tx_rwds_oe_i ( trx_tx_rwds_oe ),
136-
.rx_clk_delay_i ( cfg_i.t_rx_clk_delay ),
137-
.rx_clk_set_i ( trx_rx_clk_set ),
138-
.rx_clk_reset_i ( trx_rx_clk_reset ),
139-
.rx_data_o ( trx_rx_data ),
140-
.rx_valid_o ( trx_rx_valid ),
141-
.rx_ready_i ( trx_rx_ready ),
124+
.cfg_edge_idx_i ( cfg_i.rwds_sample.cylce_idx ),
125+
.cfg_edge_pol_i ( cfg_i.rwds_sample.polarity ),
126+
.cs_i ( cs_q ),
127+
.cs_ena_i ( trx_cs_ena ),
128+
.rwds_sample_o ( trx_rwds_sample ),
129+
.rwds_sample_ena_i ( trx_rwds_sample_ena ),
130+
.tx_clk_delay_i ( cfg_i.t_tx_clk_delay ),
131+
.tx_clk_ena_i ( trx_clk_ena ),
132+
.tx_data_i ( trx_tx_data ),
133+
.tx_data_oe_i ( trx_tx_data_oe ),
134+
.tx_rwds_i ( trx_tx_rwds ),
135+
.tx_rwds_oe_i ( trx_tx_rwds_oe ),
136+
.rx_clk_delay_i ( cfg_i.t_rx_clk_delay ),
137+
.rx_clk_set_i ( trx_rx_clk_set ),
138+
.rx_clk_reset_i ( trx_rx_clk_reset ),
139+
.rx_data_o ( trx_rx_data ),
140+
.rx_valid_o ( trx_rx_valid ),
141+
.rx_ready_i ( trx_rx_ready ),
142142
.hyper_cs_no,
143143
.hyper_ck_o,
144144
.hyper_ck_no,

src/hyperbus_pkg.sv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ package hyperbus_pkg;
1010

1111

1212
typedef struct packed {
13-
logic [1:0] cylce_idx;
14-
logic polarity;
13+
logic [3:0] cylce_idx; // number of cycles passed when sampling should occur
14+
logic polarity; // 1: rising, 0: falling
1515
} hyper_cfg_rwds_t;
1616

1717
// configuration type
@@ -28,7 +28,7 @@ package hyperbus_pkg;
2828
logic which_phy;
2929
logic [3:0] t_csh_cycles; // add an configurable Tcsh for high freq operation(200MHz Hyperram)
3030
logic [3:0] csn_to_ck_cycles; // delay hyper_ck after CS is asserted (more time for t_DSV)
31-
hyper_cfg_rwds_t rwds_sample_edge;
31+
hyper_cfg_rwds_t rwds_sample;
3232
} hyper_cfg_t;
3333

3434
typedef struct packed {
@@ -85,9 +85,9 @@ package hyperbus_pkg;
8585
phys_in_use: NumPhys-1,
8686
which_phy: NumPhys-1,
8787
t_csh_cycles: 'h1,
88-
csn_to_ck_cycles: 'h2,
89-
rwds_sample_edge: hyper_cfg_rwds_t'{ // third rising edge, see hyperbus_rwds_sampler
90-
cylce_idx: 'h1,
88+
csn_to_ck_cycles: 'h1,
89+
rwds_sample: hyper_cfg_rwds_t'{ // sampling edge for RWDS relative to CS_N going low
90+
cylce_idx: 'h2,
9191
polarity: 'b1 }
9292
};
9393

src/hyperbus_rwds_sampler.sv

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module hyperbus_rwds_sampler import hyperbus_pkg::*; #()
3131
input logic rst_ni,
3232
input logic test_mode_i,
3333

34-
input logic [1:0] cfg_edge_idx_i, // #edge where rwds is sampled
34+
input logic [3:0] cfg_edge_idx_i, // #edge where rwds is sampled
3535
input logic cfg_edge_pol_i, // 1: rising, 0: falling
3636

3737
// sampled value going to PHY-FSM
@@ -42,65 +42,54 @@ module hyperbus_rwds_sampler import hyperbus_pkg::*; #()
4242

4343
// physical HyperBus signals
4444
input logic hyper_cs_ni,
45-
input logic hyper_ck_i,
46-
input logic hyper_ck_ni,
4745
input logic hyper_rwds_i
4846
);
4947

5048
// used to time the sampling of RWDS to determine additional latency
51-
logic [2:0] cnt_edge_d, cnt_edge_q; // one bit larger than config
52-
logic start_of_tf_d, start_of_tf_q; // start of transfer indicator
53-
logic [2:0] cnt_target_value;
54-
logic cnt_at_target;
49+
logic tx_clk_270; // inverted 90deg clock
50+
logic [4:0] cnt_edge_d, cnt_edge_q; // one bit larger than config
5551
logic cnt_clk; // clock used for edge counting
5652
logic sampling_clk, sampling_clk_gated; // clock used for sampling
5753
logic enable_sampling; // sampling clock gate enable
5854
logic rwds_sample;
5955

60-
assign cnt_target_value = cfg_edge_idx_i + 1;
61-
assign cnt_at_target = (cnt_target_value == cnt_edge_q);
62-
56+
// generate and select clocks
57+
// Sampling is either clocked by un-inverted or inverted 90deg hyperbus clock
58+
// Counter is clocked by the inverse as it controls the clock gate
59+
// which should be on for one cycle with sampling edge in the middle
60+
tc_clk_inverter i_tx_clk_inv (
61+
.clk_i ( tx_clk_90_i ),
62+
.clk_o ( tx_clk_270 )
63+
);
64+
65+
tc_clk_mux2 i_sampling_clk_mux (
66+
.clk0_i ( tx_clk_270 ),
67+
.clk1_i ( tx_clk_90_i ),
68+
.clk_sel_i ( cfg_edge_pol_i ),
69+
.clk_o ( sampling_clk )
70+
);
71+
72+
tc_clk_inverter i_edge_cnt_clk_inv (
73+
.clk_i ( sampling_clk ),
74+
.clk_o ( cnt_clk )
75+
);
76+
6377
always_comb begin : gen_edge_cnt
64-
// only count at the start of a transfer
65-
if(start_of_tf_q) begin
66-
cnt_edge_d = cnt_edge_q +1; // count hyper_ck(_n) edges
78+
// only count during transfers
79+
if(~hyper_cs_ni) begin
80+
cnt_edge_d = cnt_edge_q +1;
81+
if(cnt_edge_q == '1) begin
82+
cnt_edge_d = cnt_edge_q; // saturating counter
83+
end
6784
end else begin
68-
// reset counter for next start of transfer
85+
// reset counter for next transfer
6986
cnt_edge_d = 1'b0;
7087
end
7188
end
72-
// sampling on the rising edge requires counting on falling edges to create
73-
// a window where the clk-gate is transparent around rising edge and vice versa
74-
tc_clk_mux2 i_cnt_clk_mux (
75-
.clk0_i ( hyper_ck_ni ),
76-
.clk1_i ( hyper_ck_i ),
77-
.clk_sel_i ( ~cfg_edge_pol_i ),
78-
.clk_o ( cnt_clk )
79-
);
8089

8190
`FF(cnt_edge_q, cnt_edge_d, '0, cnt_clk);
8291

83-
// used to reset counter and ensure clock gate opens only once
84-
// clocked with ungated clock to detect cs_n going high
85-
always_comb begin : gen_start_of_transfer
86-
start_of_tf_d = start_of_tf_q;
87-
if(hyper_cs_ni) begin
88-
start_of_tf_d = 1'b1;
89-
end else if (cnt_at_target) begin
90-
start_of_tf_d = 1'b0;
91-
end
92-
end
93-
`FF(start_of_tf_q, start_of_tf_d, '0, tx_clk_90_i);
94-
95-
// TODO: Check proper sampling point in sim
96-
assign enable_sampling = (cnt_at_target && start_of_tf_q);
97-
98-
tc_clk_mux2 i_sampling_clk_mux (
99-
.clk0_i ( hyper_ck_ni ),
100-
.clk1_i ( hyper_ck_i ),
101-
.clk_sel_i ( cfg_edge_pol_i ),
102-
.clk_o ( sampling_clk )
103-
);
92+
assign enable_sampling = (cnt_edge_q == cfg_edge_idx_i);
10493

10594
// gate the sampling of rwds to the selected clock edge
10695
tc_clk_gating i_rwds_sample_rise_gate (

src/hyperbus_trx.sv

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module hyperbus_trx #(
1818
input logic rst_ni,
1919
input logic test_mode_i,
2020

21-
input logic [1:0] cfg_edge_idx_i,
21+
input logic [3:0] cfg_edge_idx_i,
2222
input logic cfg_edge_pol_i,
2323

2424
// Transceiver control: facing controller
@@ -150,8 +150,6 @@ module hyperbus_trx #(
150150
.rwds_sample_o,
151151
.tx_clk_90_i ( tx_clk_90 ),
152152
.hyper_cs_ni ( &hyper_cs_no ),
153-
.hyper_ck_i ( hyper_ck_o ),
154-
.hyper_ck_ni ( hyper_ck_no ),
155153
.hyper_rwds_i ( hyper_rwds_i )
156154
);
157155

0 commit comments

Comments
 (0)