Skip to content

Commit 141fca8

Browse files
committed
Implement Xilinx delay lines
Adds the Xilinx/Gensys2 delay lines for 200MHz operation.
1 parent 1983836 commit 141fca8

15 files changed

+304
-123
lines changed

Bender.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ sources:
4040
- src/hyperbus_phy.sv
4141
- src/hyperbus_phy_if.sv
4242
- src/hyperbus_axi.sv
43+
- target: xilinx
44+
files:
45+
- target/xilinx/hyperbus_clk_delay.sv
46+
- target/xilinx/hyperbus_rwds_delay.sv
4347
- target: hyper_test
4448
files:
4549
# Device models. TODO: extend

models/configurable_delay.behav.sv

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
// Automatically generated by the Generic Delay generator.
1414
`timescale 1ps/1ps
1515

16-
(* no_ungroup *)
17-
(* no_boundary_optimization *)
1816
module configurable_delay #(
1917
parameter int unsigned NUM_STEPS, // The desired number of delay taps. Must be
2018
// a power of 2. Don't use very large values
@@ -23,17 +21,18 @@ module configurable_delay #(
2321
// will not work.
2422
localparam DELAY_SEL_WIDTH = $clog2(NUM_STEPS)
2523
) (
26-
input logic clk_i,
27-
input logic enable_i,
24+
input logic clk_i,
2825
input logic [DELAY_SEL_WIDTH-1:0] delay_i,
2926
output logic clk_o
3027
);
3128

32-
logic enable_latched;
3329
logic clk;
3430

3531
assign clk = clk_i;
3632

37-
always @(clk) clk_o <= #(real'(delay_i)*3.750ns/15) clk;
33+
// The standard delay line is expected to have 32 taps with ~78ps per tap
34+
// This conforms to the Xilinx IDELAYE2 with a 200MHz reference clock
35+
// The total delay range is thus ~2.5ns
36+
always @(clk) clk_o <= #(real'(delay_i)*78ps + 10ps) clk;
3837

3938
endmodule

models/configurable_delay.fpga.sv

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
`timescale 1ps/1ps
1313

14-
(* no_ungroup *)
15-
(* no_boundary_optimization *)
1614
module configurable_delay #(
1715
parameter int unsigned NUM_STEPS, // The desired number of delay taps. Must be
1816
// a power of 2. Don't use very large values

src/hyperbus.sv

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,39 @@
77
// Luca Valente <luca.valente@unibo.it>
88

99
module hyperbus #(
10-
parameter int unsigned NumChips = -1,
11-
parameter int unsigned NumPhys = 2,
12-
parameter int unsigned IsClockODelayed = 0,
13-
parameter int unsigned AxiAddrWidth = -1,
14-
parameter int unsigned AxiDataWidth = -1,
15-
parameter int unsigned AxiIdWidth = -1,
16-
parameter int unsigned AxiUserWidth = -1,
17-
parameter type axi_req_t = logic,
18-
parameter type axi_rsp_t = logic,
19-
parameter type axi_w_chan_t = logic,
20-
parameter type axi_b_chan_t = logic,
21-
parameter type axi_ar_chan_t = logic,
22-
parameter type axi_r_chan_t = logic,
23-
parameter type axi_aw_chan_t = logic,
24-
parameter int unsigned RegAddrWidth = -1,
25-
parameter int unsigned RegDataWidth = -1,
10+
parameter int unsigned NumChips = -1,
11+
parameter int unsigned NumPhys = 2,
12+
parameter bit UsePhyClkDivider = 1,
13+
parameter int unsigned AxiAddrWidth = -1,
14+
parameter int unsigned AxiDataWidth = -1,
15+
parameter int unsigned AxiIdWidth = -1,
16+
parameter int unsigned AxiUserWidth = -1,
17+
parameter type axi_req_t = logic,
18+
parameter type axi_rsp_t = logic,
19+
parameter type axi_w_chan_t = logic,
20+
parameter type axi_b_chan_t = logic,
21+
parameter type axi_ar_chan_t = logic,
22+
parameter type axi_r_chan_t = logic,
23+
parameter type axi_aw_chan_t = logic,
24+
parameter int unsigned RegAddrWidth = -1,
25+
parameter int unsigned RegDataWidth = -1,
2626
parameter int unsigned MinFreqMHz = 100,
27-
parameter type reg_req_t = logic,
28-
parameter type reg_rsp_t = logic,
29-
parameter type axi_rule_t = logic,
27+
parameter type reg_req_t = logic,
28+
parameter type reg_rsp_t = logic,
29+
parameter type axi_rule_t = logic,
3030
// The below have sensible defaults, but should be set on integration!
31-
parameter int unsigned RxFifoLogDepth = 3,
32-
parameter int unsigned TxFifoLogDepth = 3,
31+
parameter int unsigned RxFifoLogDepth = 3,
32+
parameter int unsigned TxFifoLogDepth = 3,
3333
parameter logic [RegDataWidth-1:0] RstChipBase = 'h0, // Base address for all chips
3434
parameter logic [RegDataWidth-1:0] RstChipSpace = 'h1_0000, // 64 KiB: Current maximum HyperBus device size
3535
parameter hyperbus_pkg::hyper_cfg_t RstCfg = hyperbus_pkg::gen_RstCfg(NumPhys,MinFreqMHz),
3636
parameter int unsigned PhyStartupCycles = 300 * 200, /* us*MHz */ // Conservative maximum frequency estimate
3737
parameter int unsigned SyncStages = 2
3838
) (
3939
input logic clk_phy_i,
40+
`ifdef TARGET_XILINX
41+
input logic clk_ref200_i, // only used for Xilinx delay lines
42+
`endif
4043
input logic rst_phy_ni,
4144
input logic clk_sys_i,
4245
input logic rst_sys_ni,
@@ -79,7 +82,7 @@ module hyperbus #(
7982
} tf_cdc_t;
8083

8184

82-
logic clk_phy_i_0, clk_phy_i_90, rst_phy;
85+
logic clk_phy_0, clk_phy_90, rst_phy;
8386

8487
// Register file
8588
hyperbus_pkg::hyper_cfg_t cfg;
@@ -178,18 +181,37 @@ module hyperbus #(
178181
.trans_active_o ( trans_active )
179182
);
180183

184+
if(UsePhyClkDivider == 1'b1) begin : clock_generator
185+
hyperbus_clk_gen ddr_clk (
186+
.clk_i ( clk_phy_i ),
187+
.rst_ni ( rst_phy_ni ),
188+
.clk0_o ( clk_phy_0 ),
189+
.clk90_o ( clk_phy_90 ),
190+
.clk180_o ( ),
191+
.clk270_o ( ),
192+
.rst_no ( rst_phy )
193+
);
194+
end else begin
195+
assign clk_phy_0 = clk_phy_i;
196+
assign clk_phy_90 = '0;
197+
assign rst_phy = rst_phy_ni;
198+
end
199+
181200
hyperbus_phy_if #(
182-
.IsClockODelayed( IsClockODelayed ),
183-
.NumChips ( NumChips ),
184-
.StartupCycles ( PhyStartupCycles ),
185-
.NumPhys ( NumPhys ),
186-
.hyper_rx_t ( hyper_rx_t ),
187-
.hyper_tx_t ( hyper_tx_t ),
188-
.SyncStages ( SyncStages )
201+
.UsePhyClkDivider ( UsePhyClkDivider ),
202+
.NumChips ( NumChips ),
203+
.NumPhys ( NumPhys ),
204+
.StartupCycles ( PhyStartupCycles ),
205+
.hyper_rx_t ( hyper_rx_t ),
206+
.hyper_tx_t ( hyper_tx_t ),
207+
.SyncStages ( SyncStages )
189208
) i_phy (
190-
.clk_i ( clk_phy_i_0 ),
191-
.clk_i_90 ( clk_phy_i_90 ),
192-
.rst_ni ( rst_phy ),
209+
.clk_phy_i ( clk_phy_0 ),
210+
.clk_phy_i_90 ( clk_phy_90 ),
211+
`ifdef TARGET_XILINX
212+
.clk_ref200_i ( clk_ref200_i ),
213+
`endif
214+
.rst_phy_ni ( rst_phy ),
193215
.test_mode_i ( test_mode_i ),
194216

195217
.cfg_i ( cfg ),
@@ -230,7 +252,7 @@ module hyperbus #(
230252
.src_ready_o ( axi_trans_ready ),
231253

232254
.dst_rst_ni ( rst_phy ),
233-
.dst_clk_i ( clk_phy_i_0 ),
255+
.dst_clk_i ( clk_phy_0 ),
234256
.dst_data_o ( phy_tf_cdc ),
235257
.dst_valid_o ( phy_trans_valid ),
236258
.dst_ready_i ( phy_trans_ready )
@@ -240,7 +262,7 @@ module hyperbus #(
240262
.T ( logic )
241263
) i_cdc_2phase_b (
242264
.src_rst_ni ( rst_phy ),
243-
.src_clk_i ( clk_phy_i_0 ),
265+
.src_clk_i ( clk_phy_0 ),
244266
.src_data_i ( phy_b_error ),
245267
.src_valid_i ( phy_b_valid ),
246268
.src_ready_o ( phy_b_ready ),
@@ -264,7 +286,7 @@ module hyperbus #(
264286
.src_ready_o ( axi_tx_ready ),
265287

266288
.dst_rst_ni ( rst_phy ),
267-
.dst_clk_i ( clk_phy_i_0 ),
289+
.dst_clk_i ( clk_phy_0 ),
268290
.dst_data_o ( phy_tx ),
269291
.dst_valid_o ( phy_tx_valid ),
270292
.dst_ready_i ( phy_tx_ready )
@@ -276,7 +298,7 @@ module hyperbus #(
276298
.LOG_DEPTH ( RxFifoLogDepth )
277299
) i_cdc_fifo_rx (
278300
.src_rst_ni ( rst_phy ),
279-
.src_clk_i ( clk_phy_i_0 ),
301+
.src_clk_i ( clk_phy_0 ),
280302
.src_data_i ( phy_rx ),
281303
.src_valid_i ( phy_rx_valid ),
282304
.src_ready_o ( phy_rx_ready ),
@@ -288,27 +310,5 @@ module hyperbus #(
288310
.dst_ready_i ( axi_rx_ready )
289311
);
290312

291-
// Shift clock by 90 degrees
292-
generate
293-
if(IsClockODelayed==0) begin : clock_generator
294-
hyperbus_clk_gen ddr_clk (
295-
.clk_i ( clk_phy_i ),
296-
.rst_ni ( rst_phy_ni ),
297-
.clk0_o ( clk_phy_i_0 ),
298-
.clk90_o ( clk_phy_i_90 ),
299-
.clk180_o ( ),
300-
.clk270_o ( ),
301-
.rst_no ( rst_phy )
302-
);
303-
end else if (IsClockODelayed==1) begin
304-
assign clk_phy_i_0 = clk_phy_i;
305-
assign rst_phy = rst_phy_ni;
306-
hyperbus_delay i_delay_tx_clk_90 (
307-
.in_i ( clk_phy_i_0 ),
308-
.delay_i ( cfg.t_tx_clk_delay ),
309-
.out_o ( clk_phy_i_90 )
310-
);
311-
end
312-
endgenerate
313313

314314
endmodule : hyperbus

src/hyperbus_clk_gen.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// Hayate Okuhara <hayate.okuhara@unibo.it>
66

77
/// Generates 4 phase shifted clocks out of one faster clock
8+
(* no_ungroup *)
9+
(* no_boundary_optimization *)
10+
(* keep_hierarchy = "yes" *)
811
module hyperbus_clk_gen (
912
input logic clk_i, // input clock
1013
input logic rst_ni,

src/hyperbus_clock_diff_out.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
// Stephan Keck <kecks@ethz.ch>
77

88
/// A Hyperbus differential clock output generator.
9+
(* no_ungroup *)
10+
(* no_boundary_optimization *)
11+
(* keep_hierarchy = "yes" *)
912
module hyperbus_clock_diff_out
1013
(
1114
input logic in_i,

src/hyperbus_delay.sv

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@
55
// Thomas Benz <paulsc@iis.ee.ethz.ch>
66
// Paul Scheffler <paulsc@iis.ee.ethz.ch>
77

8+
(* no_ungroup *)
9+
(* no_boundary_optimization *)
10+
(* keep_hierarchy = "yes" *)
811
module hyperbus_delay (
912
input logic in_i,
10-
input logic [3:0] delay_i,
13+
input logic [4:0] delay_i,
1114
output logic out_o
1215
);
1316

17+
// The standard delay line is expected to have 32 taps with ~78ps per tap
18+
// This conforms to the Xilinx IDELAYE2 with a 200MHz reference clock
19+
// The total delay range is thus ~2.5ns
1420
configurable_delay #(
15-
.NUM_STEPS(16)
21+
.NUM_STEPS(32)
1622
) i_delay (
1723
.clk_i ( in_i ),
18-
`ifndef TARGET_ASIC
19-
.enable_i ( 1'b1 ),
20-
`endif
2124
.delay_i ( delay_i ),
2225
.clk_o ( out_o )
2326
);

src/hyperbus_phy.sv

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// Paul Scheffler <paulsc@iis.ee.ethz.ch>
99

1010
module hyperbus_phy import hyperbus_pkg::*; #(
11-
parameter int unsigned IsClockODelayed = -1,
1211
parameter int unsigned NumChips = 2,
1312
parameter int unsigned NumPhys = -1,
1413
parameter int unsigned TimerWidth = 16,
@@ -113,7 +112,6 @@ module hyperbus_phy import hyperbus_pkg::*; #(
113112
// =================
114113

115114
hyperbus_trx #(
116-
.IsClockODelayed( IsClockODelayed ),
117115
.NumChips ( NumChips ),
118116
.RxFifoLogDepth ( RxFifoLogDepth ),
119117
.SyncStages ( SyncStages )

0 commit comments

Comments
 (0)