Skip to content
Draft
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
16 changes: 8 additions & 8 deletions docs/regs/hyperbus_cfg_regs.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -440,7 +440,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -546,7 +546,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -652,7 +652,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -758,7 +758,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -864,7 +864,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -970,7 +970,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down Expand Up @@ -1076,7 +1076,7 @@ Don't override. Generated from: hyperbus_cfg_regs
- Base Offset: 0xC
- Size: 0x4

<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most 15 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>
<p>Chip latency configuration. t_latency_access must be 3 through 15; rwds_sample_delay must be at most t_latency_access minus 2 and is active when capability.rwds_sample_timing is set. Chip 0 is shared when capability.per_chip_cfg is clear.</p>

|Bits| Identifier |Access|Reset|Name|
|----|---------------------|------|-----|----|
Expand Down
30 changes: 17 additions & 13 deletions src/backend/hyperbus_backend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module hyperbus_backend #(
hyperbus_pkg::phy_cfg_t cfg_q;
logic cfg_apply_accepted;
logic phy_busy_any;
logic clk_tx;
logic [NumPhys-1:0] clk_tx;

`ASSERT_INIT(NumPhysValid, NumPhys == 1 || NumPhys == 2)
`ASSERT_INIT(SyncStagesValid, SyncStages >= 2)
Expand All @@ -60,16 +60,18 @@ module hyperbus_backend #(

`FFLARN(cfg_q, cfg_apply_i, cfg_apply_accepted, '0, clk_i, rst_ni)

hyperbus_tx_clk_delay i_tx_clk_delay (
.rst_ni,
for (genvar i = 0; i < NumPhys; i++) begin : gen_tx_clk_delay
hyperbus_tx_clk_delay i_tx_clk_delay (
.rst_ni,
`ifdef TARGET_XILINX
.clk_ref200_i,
.clk_ref200_i,
`endif
.clk_i,
.in_i ( clk_i ),
.delay_i ( cfg_q.t_tx_clk_delay ),
.out_o ( clk_tx )
);
.clk_i,
.in_i ( clk_i ),
.delay_i ( cfg_q.phy[i].tx_delay ),
.out_o ( clk_tx[i] )
);
end

/////////////////////
// Physical lanes //
Expand Down Expand Up @@ -177,10 +179,11 @@ module hyperbus_backend #(
hyperbus_phy #(
.StartupCycles ( StartupCycles ),
.NumPhys ( NumPhys ),
.SyncStages ( SyncStages )
.SyncStages ( SyncStages ),
.PhyIndex ( i )
) i_phy (
.clk_i,
.clk_tx_i ( clk_tx ),
.clk_tx_i ( clk_tx[i] ),
.rst_ni,
.test_mode_i,
.cfg_i ( cfg_q ),
Expand Down Expand Up @@ -218,10 +221,11 @@ module hyperbus_backend #(
hyperbus_phy #(
.StartupCycles ( StartupCycles ),
.NumPhys ( NumPhys ),
.SyncStages ( SyncStages )
.SyncStages ( SyncStages ),
.PhyIndex ( 0 )
) i_phy (
.clk_i,
.clk_tx_i ( clk_tx ),
.clk_tx_i ( clk_tx[0] ),
.rst_ni,
.test_mode_i,
.cfg_i ( cfg_q ),
Expand Down
55 changes: 37 additions & 18 deletions src/backend/hyperbus_phy.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
parameter int unsigned TimerWidth = 16,
parameter int unsigned RxFifoLogDepth = 3,
parameter int unsigned SyncStages = 2,
parameter int unsigned PhyIndex = 0,
// Conservative startup delay: 300 us at 200 MHz.
parameter int unsigned StartupCycles = 300 * 200
)(
Expand Down Expand Up @@ -67,9 +68,9 @@ module hyperbus_phy import hyperbus_pkg::*; #(
localparam int unsigned RxOutstandingLimit = (RxFifoDepth > RxFifoStopMargin) ?
(RxFifoDepth - RxFifoStopMargin) : 1;

logic [1:0] words_per_beat;
`ASSERT_INIT(PhyIndexValid, PhyIndex < 2)

assign words_per_beat = (NumPhys == 2 && cfg_i.dual_phy) ? 2 : 1;
logic [1:0] words_per_beat;

//////////////////////
// Persistent state //
Expand All @@ -80,6 +81,22 @@ module hyperbus_phy import hyperbus_pkg::*; #(
hyper_tf_t tf_d, tf_q;
logic [HyperNumChips-1:0] cs_d, cs_q;
logic add_latency_d, add_latency_q;
logic [HyperNumChips-1:0] cfg_select_cs;
logic [2:0] cfg_chip_idx;
chip_phy_cfg_t cfg_chip;

// During Idle the incoming command CS is authoritative. Once accepted,
// retain the registered CS for every subsequent phase of the transfer.
assign cfg_select_cs = (state_q == Idle) ? trans_cs_i : cs_q;
onehot_to_bin #(
.ONEHOT_WIDTH ( HyperNumChips )
) i_cfg_chip_idx (
.onehot ( cfg_select_cs ),
.bin ( cfg_chip_idx )
);
assign cfg_chip = cfg_i.chip[cfg_chip_idx];

assign words_per_beat = (NumPhys == 2 && cfg_i.dual_phy) ? 2 : 1;

// Whether B response is pending
logic b_pending_q;
Expand Down Expand Up @@ -144,7 +161,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
.tx_data_oe_i ( trx_tx_data_oe ),
.tx_rwds_i ( trx_tx_rwds ),
.tx_rwds_oe_i ( trx_tx_rwds_oe ),
.rx_clk_delay_i ( cfg_i.chip.t_rx_clk_delay ),
.rx_clk_delay_i ( cfg_chip.t_rx_clk_delay ),
.rx_clk_set_i ( trx_rx_clk_set ),
.rx_clk_reset_i ( trx_rx_clk_reset ),
.rx_data_o ( trx_rx_data ),
Expand Down Expand Up @@ -189,7 +206,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
trx_tx_data = tx_data_i;
trx_tx_rwds = ~tx_strb_i;
tx_ready_o = 1'b1; // Memory always ready within HyperBus burst
ctl_wclk_ena = tx_valid_i;
ctl_wclk_ena = tx_valid_i;
end
end

Expand Down Expand Up @@ -234,8 +251,8 @@ module hyperbus_phy import hyperbus_pkg::*; #(

// Auxiliary control signals
assign ctl_write_zero_lat = tf_q.address_space & tf_q.write;
// cfg_i.chip.en_latency_additional overwrites the sampled RWDS value.
assign ctl_add_latency = trx_rwds_sample | cfg_i.chip.en_latency_additional;
// The selected chip configuration overwrites the sampled RWDS value.
assign ctl_add_latency = trx_rwds_sample | cfg_chip.en_latency_additional;

assign ctl_tf_burst_last = (tf_q.burst == 1) || (tf_q.burst == words_per_beat);
assign ctl_tf_burst_done = (tf_q.burst == 0);
Expand Down Expand Up @@ -288,11 +305,11 @@ module hyperbus_phy import hyperbus_pkg::*; #(
cs_d = trans_cs_i;
add_latency_d = 1'b0;

if(cfg_i.chip.csn_to_ck_cycles != 0) begin
if(cfg_chip.csn_to_ck_cycles != 0) begin
// assert 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.chip.csn_to_ck_cycles -1;
timer_d = cfg_chip.csn_to_ck_cycles -1;
end else begin
// max throughput when memory RWDS signal arrives early
state_d = SendCA;
Expand Down Expand Up @@ -323,10 +340,10 @@ module hyperbus_phy import hyperbus_pkg::*; #(
trx_rwds_sample_ena = ~ctl_write_zero_lat;
if (ctl_timer_zero) begin
if (ctl_write_zero_lat) begin
timer_d = cfg_i.chip.t_burst_max;
timer_d = cfg_chip.t_burst_max;
state_d = Write;
end else begin
timer_d = TimerWidth'(cfg_i.chip.t_latency_access);
timer_d = TimerWidth'(cfg_chip.t_latency_access);
add_latency_d = ctl_add_latency;
state_d = WaitLatAccess;
end
Expand All @@ -344,7 +361,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
if (~add_latency_q) begin
// Substract cycle for last CA and another for state delay
if(ctl_timer_two) begin
timer_d = cfg_i.chip.t_burst_max;
timer_d = cfg_chip.t_burst_max;
// Switch to write or read phase and already start
// turnaround of tri-state driver (depending on latency
// config and if read or write transaction).
Expand All @@ -364,7 +381,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
end else if (ctl_timer_one) begin
// instead of going to 0, add another latency count
state_d = WaitAddLatAccess;
timer_d = TimerWidth'(cfg_i.chip.t_latency_access);
timer_d = TimerWidth'(cfg_chip.t_latency_access);
add_latency_d = 1'b0;
end
end
Expand All @@ -375,7 +392,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
trx_clk_ena = 1'b1;
trx_tx_data_oe = 1'b1;
if (ctl_timer_two) begin
timer_d = cfg_i.chip.t_burst_max;
timer_d = cfg_chip.t_burst_max;
if (tf_q.write) begin
state_d = Write;
trx_tx_data_oe = 1'b1;
Expand All @@ -397,13 +414,13 @@ module hyperbus_phy import hyperbus_pkg::*; #(
tf_d.burst = tf_q.burst - words_per_beat;
tf_d.address = tf_q.address + 1;
if (ctl_tf_burst_last) begin
timer_d = cfg_i.chip.t_csh_cycles;
timer_d = cfg_chip.t_csh_cycles;
state_d = WaitXfer;
end
end
// Force-terminate access on burst time limit
if (ctl_timer_one) begin
timer_d = cfg_i.chip.t_csh_cycles;
timer_d = cfg_chip.t_csh_cycles;
state_d = WaitXfer;
end
end
Expand All @@ -420,13 +437,13 @@ module hyperbus_phy import hyperbus_pkg::*; #(
tf_d.address = tf_q.address + 1;
if (ctl_tf_burst_last) begin
b_pending_set = 1'b1;
timer_d = cfg_i.chip.t_csh_cycles;
timer_d = cfg_chip.t_csh_cycles;
state_d = WaitXfer;
end
end
// Force-terminate access on burst time limit
if (ctl_timer_one) begin
timer_d = cfg_i.chip.t_csh_cycles;
timer_d = cfg_chip.t_csh_cycles;
state_d = WaitXfer;
end
end
Expand All @@ -435,7 +452,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
// Wait for FFed Clock and output to stop
// May have to be prolonged for potential future devices with t_CSH > 0
if (ctl_timer_zero) begin
timer_d = cfg_i.chip.t_read_write_recovery;
timer_d = cfg_chip.t_read_write_recovery;
state_d = WaitRWR;
end
end
Expand Down Expand Up @@ -491,5 +508,7 @@ module hyperbus_phy import hyperbus_pkg::*; #(
`ASSERT(RxCaptureActiveDuringRead, state_q == Read |-> !trx_rx_clk_reset)
`ASSERT(RxCaptureResetAfterDrain,
(r_outstand_dec && r_outstand_q == 1 && state_q != Read) |=> trx_rx_clk_reset)
`ASSERT(OutputDriversDisabledDuringRecovery,
state_q == WaitRWR |-> (!hyper_dq_oe_o && !hyper_rwds_oe_o))

endmodule
4 changes: 3 additions & 1 deletion src/hyperbus_asynchronous.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module hyperbus_asynchronous #(
parameter type axi_req_t = logic,
parameter type axi_rsp_t = logic,
parameter int unsigned RegDataWidth = -1,
parameter int unsigned RegAddrWidth = 32,
parameter type reg_req_t = logic,
parameter type reg_rsp_t = logic,
parameter type axi_rule_t = logic,
Expand Down Expand Up @@ -127,7 +128,8 @@ module hyperbus_asynchronous #(
.reg_req_t ( reg_req_t ),
.reg_rsp_t ( reg_rsp_t ),
.host_rule_t ( axi_rule_t ),
.RegDataWidth ( RegDataWidth )
.RegDataWidth ( RegDataWidth ),
.RegAddrWidth ( RegAddrWidth )
) i_cfg_frontend (
.clk_i ( clk_sys_i ),
.rst_ni ( rst_sys_ni ),
Expand Down
Loading