Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.bender
scripts/compile.tcl
models/s27ks0641
axi_log/
work/
transcript
modelsim.ini
vsim.wlf
models/s27ks0641
6 changes: 6 additions & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ sources:
- src/hyperbus_phy2r.sv
- src/hyperbus_ddr_out.sv
- src/hyperbus_delay.sv
- src/hyperbus_rwds_sampler.sv
- src/hyperbus_trx.sv
- src/hyperbus_cfg_regs.sv
- src/hyperbus_phy.sv
- src/hyperbus_phy_if.sv
- src/hyperbus_axi.sv
- target: xilinx
files:
- target/xilinx/hyperbus_clk_delay.sv
- target/xilinx/hyperbus_rwds_delay.sv
- target: hyper_test
files:
# Device models. TODO: extend
Expand All @@ -47,5 +52,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
11 changes: 5 additions & 6 deletions models/configurable_delay.behav.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
// Automatically generated by the Generic Delay generator.
`timescale 1ps/1ps

(* no_ungroup *)
(* no_boundary_optimization *)
module configurable_delay #(
parameter int unsigned NUM_STEPS, // The desired number of delay taps. Must be
// a power of 2. Don't use very large values
Expand All @@ -23,17 +21,18 @@ module configurable_delay #(
// will not work.
localparam DELAY_SEL_WIDTH = $clog2(NUM_STEPS)
) (
input logic clk_i,
input logic enable_i,
input logic clk_i,
input logic [DELAY_SEL_WIDTH-1:0] delay_i,
output logic clk_o
);

logic enable_latched;
logic clk;

assign clk = clk_i;

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

endmodule
2 changes: 0 additions & 2 deletions models/configurable_delay.fpga.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

`timescale 1ps/1ps

(* no_ungroup *)
(* no_boundary_optimization *)
module configurable_delay #(
parameter int unsigned NUM_STEPS, // The desired number of delay taps. Must be
// a power of 2. Don't use very large values
Expand Down
117 changes: 58 additions & 59 deletions src/hyperbus.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,39 @@
// Luca Valente <luca.valente@unibo.it>

module hyperbus #(
parameter int unsigned NumChips = -1,
parameter int unsigned NumPhys = 2,
parameter int unsigned IsClockODelayed = 0,
parameter int unsigned AxiAddrWidth = -1,
parameter int unsigned AxiDataWidth = -1,
parameter int unsigned AxiIdWidth = -1,
parameter int unsigned AxiUserWidth = -1,
parameter type axi_req_t = logic,
parameter type axi_rsp_t = logic,
parameter type axi_w_chan_t = logic,
parameter type axi_b_chan_t = logic,
parameter type axi_ar_chan_t = logic,
parameter type axi_r_chan_t = logic,
parameter type axi_aw_chan_t = logic,
parameter int unsigned RegAddrWidth = -1,
parameter int unsigned RegDataWidth = -1,
parameter int unsigned NumChips = -1,
parameter int unsigned NumPhys = 2,
parameter bit UsePhyClkDivider = 1,
parameter int unsigned AxiAddrWidth = -1,
parameter int unsigned AxiDataWidth = -1,
parameter int unsigned AxiIdWidth = -1,
parameter int unsigned AxiUserWidth = -1,
parameter type axi_req_t = logic,
parameter type axi_rsp_t = logic,
parameter type axi_w_chan_t = logic,
parameter type axi_b_chan_t = logic,
parameter type axi_ar_chan_t = logic,
parameter type axi_r_chan_t = logic,
parameter type axi_aw_chan_t = logic,
parameter int unsigned RegAddrWidth = -1,
parameter int unsigned RegDataWidth = -1,
parameter int unsigned MinFreqMHz = 100,
parameter type reg_req_t = logic,
parameter type reg_rsp_t = logic,
parameter type axi_rule_t = logic,
parameter type reg_req_t = logic,
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,
`ifdef TARGET_XILINX
input logic clk_ref200_i, // only used for Xilinx delay lines
`endif
input logic rst_phy_ni,
input logic clk_sys_i,
input logic rst_sys_ni,
Expand Down Expand Up @@ -80,7 +82,7 @@ module hyperbus #(
} tf_cdc_t;


logic clk_phy_i_0, clk_phy_i_90, rst_phy;
logic clk_phy_0, clk_phy_90, rst_phy;

// Register file
hyperbus_pkg::hyper_cfg_t cfg;
Expand Down Expand Up @@ -179,18 +181,37 @@ module hyperbus #(
.trans_active_o ( trans_active )
);

if(UsePhyClkDivider == 1'b1) begin : clock_generator
hyperbus_clk_gen ddr_clk (
.clk_i ( clk_phy_i ),
.rst_ni ( rst_phy_ni ),
.clk0_o ( clk_phy_0 ),
.clk90_o ( clk_phy_90 ),
.clk180_o ( ),
.clk270_o ( ),
.rst_no ( rst_phy )
);
end else begin
assign clk_phy_0 = clk_phy_i;
assign clk_phy_90 = '0;
assign rst_phy = rst_phy_ni;
end

hyperbus_phy_if #(
.IsClockODelayed( IsClockODelayed ),
.NumChips ( NumChips ),
.StartupCycles ( PhyStartupCycles ),
.NumPhys ( NumPhys ),
.hyper_rx_t ( hyper_rx_t ),
.hyper_tx_t ( hyper_tx_t ),
.SyncStages ( SyncStages )
.UsePhyClkDivider ( UsePhyClkDivider ),
.NumChips ( NumChips ),
.NumPhys ( NumPhys ),
.StartupCycles ( PhyStartupCycles ),
.hyper_rx_t ( hyper_rx_t ),
.hyper_tx_t ( hyper_tx_t ),
.SyncStages ( SyncStages )
) i_phy (
.clk_i ( clk_phy_i_0 ),
.clk_i_90 ( clk_phy_i_90 ),
.rst_ni ( rst_phy ),
.clk_phy_i ( clk_phy_0 ),
.clk_phy_i_90 ( clk_phy_90 ),
`ifdef TARGET_XILINX
.clk_ref200_i ( clk_ref200_i ),
`endif
.rst_phy_ni ( rst_phy ),
.test_mode_i ( test_mode_i ),

.cfg_i ( cfg ),
Expand Down Expand Up @@ -231,7 +252,7 @@ module hyperbus #(
.src_ready_o ( axi_trans_ready ),

.dst_rst_ni ( rst_phy ),
.dst_clk_i ( clk_phy_i_0 ),
.dst_clk_i ( clk_phy_0 ),
.dst_data_o ( phy_tf_cdc ),
.dst_valid_o ( phy_trans_valid ),
.dst_ready_i ( phy_trans_ready )
Expand All @@ -241,7 +262,7 @@ module hyperbus #(
.T ( logic )
) i_cdc_2phase_b (
.src_rst_ni ( rst_phy ),
.src_clk_i ( clk_phy_i_0 ),
.src_clk_i ( clk_phy_0 ),
.src_data_i ( phy_b_error ),
.src_valid_i ( phy_b_valid ),
.src_ready_o ( phy_b_ready ),
Expand All @@ -265,7 +286,7 @@ module hyperbus #(
.src_ready_o ( axi_tx_ready ),

.dst_rst_ni ( rst_phy ),
.dst_clk_i ( clk_phy_i_0 ),
.dst_clk_i ( clk_phy_0 ),
.dst_data_o ( phy_tx ),
.dst_valid_o ( phy_tx_valid ),
.dst_ready_i ( phy_tx_ready )
Expand All @@ -277,7 +298,7 @@ module hyperbus #(
.LOG_DEPTH ( RxFifoLogDepth )
) i_cdc_fifo_rx (
.src_rst_ni ( rst_phy ),
.src_clk_i ( clk_phy_i_0 ),
.src_clk_i ( clk_phy_0 ),
.src_data_i ( phy_rx ),
.src_valid_i ( phy_rx_valid ),
.src_ready_o ( phy_rx_ready ),
Expand All @@ -289,27 +310,5 @@ module hyperbus #(
.dst_ready_i ( axi_rx_ready )
);

// Shift clock by 90 degrees
generate
if(IsClockODelayed==0) begin : clock_generator
hyperbus_clk_gen ddr_clk (
.clk_i ( clk_phy_i ),
.rst_ni ( rst_phy_ni ),
.clk0_o ( clk_phy_i_0 ),
.clk90_o ( clk_phy_i_90 ),
.clk180_o ( ),
.clk270_o ( ),
.rst_no ( rst_phy )
);
end else if (IsClockODelayed==1) begin
assign clk_phy_i_0 = clk_phy_i;
assign rst_phy = rst_phy_ni;
hyperbus_delay i_delay_tx_clk_90 (
.in_i ( clk_phy_i_0 ),
.delay_i ( cfg.t_tx_clk_delay ),
.out_o ( clk_phy_i_90 )
);
end
endgenerate

endmodule : hyperbus
4 changes: 2 additions & 2 deletions src/hyperbus_axi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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 ),
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 6 additions & 2 deletions src/hyperbus_cfg_regs.sv
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ module hyperbus_cfg_regs #(
`include "common_cells/registers.svh"

// Internal Parameters
localparam int unsigned NumBaseRegs = 11;
localparam int unsigned NumBaseRegs = 13;
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;
Expand All @@ -59,6 +59,8 @@ module hyperbus_cfg_regs #(
if (sel_reg_mapped) begin
rfield = {
crange_q,
reg_data_t'(cfg_q.rwds_sample),
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),
Expand Down Expand Up @@ -99,6 +101,8 @@ 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);
'hc: cfg_d.rwds_sample = (~wmask & cfg_q.rwds_sample ) | (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);
Expand Down
3 changes: 3 additions & 0 deletions src/hyperbus_clk_gen.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// Hayate Okuhara <hayate.okuhara@unibo.it>

/// Generates 4 phase shifted clocks out of one faster clock
(* no_ungroup *)
(* no_boundary_optimization *)
(* keep_hierarchy = "yes" *)
module hyperbus_clk_gen (
input logic clk_i, // input clock
input logic rst_ni,
Expand Down
3 changes: 3 additions & 0 deletions src/hyperbus_clock_diff_out.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
// Stephan Keck <kecks@ethz.ch>

/// A Hyperbus differential clock output generator.
(* no_ungroup *)
(* no_boundary_optimization *)
(* keep_hierarchy = "yes" *)
module hyperbus_clock_diff_out
(
input logic in_i,
Expand Down
13 changes: 8 additions & 5 deletions src/hyperbus_delay.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
// Thomas Benz <paulsc@iis.ee.ethz.ch>
// Paul Scheffler <paulsc@iis.ee.ethz.ch>

(* no_ungroup *)
(* no_boundary_optimization *)
(* keep_hierarchy = "yes" *)
module hyperbus_delay (
input logic in_i,
input logic [3:0] delay_i,
input logic [4:0] delay_i,
output logic out_o
);

// The standard delay line is expected to have 32 taps with ~78ps per tap
// This conforms to the Xilinx IDELAYE2 with a 200MHz reference clock
// The total delay range is thus ~2.5ns
configurable_delay #(
.NUM_STEPS(16)
.NUM_STEPS(32)
) i_delay (
.clk_i ( in_i ),
`ifndef TARGET_ASIC
.enable_i ( 1'b1 ),
`endif
.delay_i ( delay_i ),
.clk_o ( out_o )
);
Expand Down
Loading