From 5220984df82edad47f2c20ee8aa60ba2a50b3919 Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Wed, 27 Apr 2022 17:39:48 +0200 Subject: [PATCH 1/2] hyperbus: add a timeout for long bursts --- litex/soc/cores/hyperbus.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/hyperbus.py b/litex/soc/cores/hyperbus.py index 1c20553a4..325d5cb84 100644 --- a/litex/soc/cores/hyperbus.py +++ b/litex/soc/cores/hyperbus.py @@ -24,7 +24,7 @@ class HyperRAM(Module): This core favors portability and ease of use over performance. """ - def __init__(self, pads, latency=6): + def __init__(self, frequency, pads, latency=6, Tcsm=4e-6): self.pads = pads self.bus = bus = wishbone.Interface() @@ -61,6 +61,25 @@ class HyperRAM(Module): else: self.specials += DifferentialOutput(clk, pads.clk_p, pads.clk_n) + # Timeout counter -------------------------------------------------------------------------- + timeout_value = int(Tcsm * frequency) + timeout_cnt = Signal(32) + timeout_rst = Signal() + timeout = Signal() + + self.sync += [ + If(timeout_rst, + timeout_cnt.eq(0), + timeout.eq(0) + ).Else( + If(timeout_cnt < timeout_value, + timeout_cnt.eq(timeout_cnt + 1) + ).Else( + timeout.eq(1) + ) + ), + ] + # Clock Generation (sys_clk/4) ------------------------------------------------------------- self.sync += clk_phase.eq(clk_phase + 1) cases = {} @@ -122,6 +141,7 @@ class HyperRAM(Module): first = Signal() self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", + timeout_rst.eq(1), NextValue(first, 1), If(bus.cyc & bus.stb, If(clk_phase == 0, @@ -172,7 +192,7 @@ class HyperRAM(Module): If(n == (states - 1), NextValue(first, 0), # Continue burst when a consecutive access is ready. - If(bus.stb & bus.cyc & (bus.we == bus_we) & (bus.adr == (bus_adr + 1)), + If(bus.stb & bus.cyc & (bus.we == bus_we) & (bus.adr == (bus_adr + 1)) & ~timeout, # Latch Bus. bus_latch.eq(1), # Early Write Ack (to allow bursting). From a66af6343e98a93dc3779b078428045742c305db Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Thu, 28 Apr 2022 10:42:07 +0200 Subject: [PATCH 2/2] hyperbus: check if cyc is active during every state --- litex/soc/cores/hyperbus.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/hyperbus.py b/litex/soc/cores/hyperbus.py index 325d5cb84..ade68d2b1 100644 --- a/litex/soc/cores/hyperbus.py +++ b/litex/soc/cores/hyperbus.py @@ -159,7 +159,9 @@ class HyperRAM(Module): # Wait for 6*2 cycles... If(cycles == (6*2 - 1), NextState("WAIT-LATENCY") - ) + ), + # Always check if bus cycle is still active + If(~bus.cyc, NextState("IDLE")) ) fsm.act("WAIT-LATENCY", # Set CSn. @@ -171,7 +173,9 @@ class HyperRAM(Module): # Early Write Ack (to allow bursting). bus.ack.eq(bus.we), NextState("READ-WRITE-DATA0") - ) + ), + # Always check if bus cycle is still active + If(~bus.cyc, NextState("IDLE")) ) states = {8:4, 16:2}[dw] for n in range(states):