soc/cores/hyperbus: Add automatic read burst detection.
This commit is contained in:
parent
3bde3e9848
commit
c554752e8a
|
@ -308,17 +308,18 @@ class HyperRAMCore(LiteXModule):
|
||||||
|
|
||||||
# Signals.
|
# Signals.
|
||||||
# --------
|
# --------
|
||||||
self.cmd = cmd = Signal(48)
|
self.cmd = cmd = Signal(48)
|
||||||
self.cycles = cycles = Signal(8)
|
self.cycles = cycles = Signal(8)
|
||||||
self.latency_x2 = latency_x2 = Signal()
|
self.latency_x2 = latency_x2 = Signal()
|
||||||
self.bus_latch = bus_latch = Signal()
|
self.bus_latch = bus_latch = Signal()
|
||||||
self.bus_cti = bus_cti = Signal(3)
|
self.bus_cti = bus_cti = Signal(3)
|
||||||
self.bus_we = bus_we = Signal()
|
self.bus_we = bus_we = Signal()
|
||||||
self.bus_sel = bus_sel = Signal(4)
|
self.bus_sel = bus_sel = Signal(4)
|
||||||
self.bus_adr = bus_adr = Signal(32)
|
self.bus_adr = bus_adr = Signal(32)
|
||||||
self.bus_dat_w = bus_dat_w = Signal(32)
|
self.bus_dat_w = bus_dat_w = Signal(32)
|
||||||
self.burst_w = burst_w = Signal()
|
self.burst_w = burst_w = Signal()
|
||||||
self.burst_r = burst_r = Signal()
|
self.burst_r = burst_r = Signal()
|
||||||
|
self.burst_r_first = burst_r_first = Signal()
|
||||||
|
|
||||||
# PHY.
|
# PHY.
|
||||||
# ----
|
# ----
|
||||||
|
@ -425,8 +426,9 @@ class HyperRAMCore(LiteXModule):
|
||||||
If(reg.stb & ~reg.we,
|
If(reg.stb & ~reg.we,
|
||||||
NextState("REG-READ")
|
NextState("REG-READ")
|
||||||
).Else(
|
).Else(
|
||||||
|
bus_latch.eq(1),
|
||||||
|
NextValue(burst_r_first, 1),
|
||||||
If(bus.we,
|
If(bus.we,
|
||||||
bus_latch.eq(1),
|
|
||||||
NextState("DAT-WRITE")
|
NextState("DAT-WRITE")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("DAT-READ")
|
NextState("DAT-READ")
|
||||||
|
@ -470,7 +472,7 @@ class HyperRAMCore(LiteXModule):
|
||||||
bus_dat_w.eq(bus.dat_w),
|
bus_dat_w.eq(bus.dat_w),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.comb += If(bus_latch, bus.ack.eq(1))
|
self.comb += If(bus_latch, bus.ack.eq(bus.we))
|
||||||
self.comb += burst_w.eq(
|
self.comb += burst_w.eq(
|
||||||
# Notified Incrementing Burst.
|
# Notified Incrementing Burst.
|
||||||
(bus_cti == 0b010) |
|
(bus_cti == 0b010) |
|
||||||
|
@ -500,16 +502,21 @@ class HyperRAMCore(LiteXModule):
|
||||||
# Data Read State.
|
# Data Read State.
|
||||||
self.comb += burst_r.eq(
|
self.comb += burst_r.eq(
|
||||||
# Notified Incrementing Burst.
|
# Notified Incrementing Burst.
|
||||||
(bus.cti == 0b10)
|
(bus_cti == 0b10) |
|
||||||
|
# Detected Incrementing Burst.
|
||||||
|
((bus.we == bus_we) & (bus.adr == (bus_adr + 1))),
|
||||||
)
|
)
|
||||||
fsm.act("DAT-READ",
|
fsm.act("DAT-READ",
|
||||||
source.valid.eq(bus.cyc & bus.stb),
|
source.valid.eq(1),
|
||||||
source.dat_r.eq(1),
|
source.dat_r.eq(1),
|
||||||
If(dat_rx_conv.source.valid,
|
If(dat_rx_conv.source.valid,
|
||||||
bus.ack.eq(1),
|
NextValue(burst_r_first, 0),
|
||||||
|
# Ack on first or while Incrementing Burst ongoing...
|
||||||
|
bus.ack.eq(burst_r_first | (with_bursting & bus.cyc & bus.stb & burst_r)),
|
||||||
bus.dat_r.eq(dat_rx_conv.source.dq),
|
bus.dat_r.eq(dat_rx_conv.source.dq),
|
||||||
# Stay in DAT-READ while Incrementing Burst ongoing...
|
# If Ack, stay in DAT-READ to anticipate next read...
|
||||||
If(with_bursting & bus.cyc & bus.stb & burst_r,
|
If(bus.ack,
|
||||||
|
bus_latch.eq(1),
|
||||||
NextState("DAT-READ")
|
NextState("DAT-READ")
|
||||||
# ..else exit.
|
# ..else exit.
|
||||||
).Else(
|
).Else(
|
||||||
|
|
|
@ -178,13 +178,13 @@ class TestHyperRAM(unittest.TestCase):
|
||||||
self.assertEqual(dat, 0xdeadbeef)
|
self.assertEqual(dat, 0xdeadbeef)
|
||||||
|
|
||||||
def hyperram_gen(dut):
|
def hyperram_gen(dut):
|
||||||
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
||||||
cs_n = "----______________________________________________________________________----"
|
cs_n = "----______________________________________________________________________________----"
|
||||||
dq_oe = "______------------____________________________________________________________"
|
dq_oe = "______------------____________________________________________________________________"
|
||||||
dq_o = "000000a000048d0000000000000000000000000000000000000000000000000000000000000000"
|
dq_o = "000000a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
dq_i = "000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
dq_i = "000000000000000000000000000000000000000000000000000000deadbeefcafefade0000000000000000"
|
||||||
rwds_oe = "______________________________________________________________________________"
|
rwds_oe = "______________________________________________________________________________________"
|
||||||
rwds_i = "______________________________________________________--__--__--__--__________"
|
rwds_i = "______________________________________________________--__--__--__--__________________"
|
||||||
yield
|
yield
|
||||||
for i in range(len(clk)):
|
for i in range(len(clk)):
|
||||||
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
||||||
|
@ -206,13 +206,13 @@ class TestHyperRAM(unittest.TestCase):
|
||||||
self.assertEqual(dat, 0xdeadbeef)
|
self.assertEqual(dat, 0xdeadbeef)
|
||||||
|
|
||||||
def hyperram_gen(dut):
|
def hyperram_gen(dut):
|
||||||
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
||||||
cs_n = "----______________________________________________________________________________----"
|
cs_n = "----______________________________________________________________________________________----"
|
||||||
dq_oe = "______------------____________________________________________________________________"
|
dq_oe = "______------------____________________________________________________________________________"
|
||||||
dq_o = "000000a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
|
dq_o = "000000a000048d00000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
dq_i = "00000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
dq_i = "00000000000000000000000000000000000000000000000000000000000000deadbeefcafefade0000000000000000"
|
||||||
rwds_oe = "______________________________________________________________________________________"
|
rwds_oe = "______________________________________________________________________________________________"
|
||||||
rwds_i = "______________________________________________________________--__--__--__--__________"
|
rwds_i = "______________________________________________________________--__--__--__--__________________"
|
||||||
yield
|
yield
|
||||||
for i in range(len(clk)):
|
for i in range(len(clk)):
|
||||||
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
||||||
|
@ -233,14 +233,15 @@ class TestHyperRAM(unittest.TestCase):
|
||||||
dat = yield from dut.bus.read(0x1234)
|
dat = yield from dut.bus.read(0x1234)
|
||||||
self.assertEqual(dat, 0xdeadbeef)
|
self.assertEqual(dat, 0xdeadbeef)
|
||||||
|
|
||||||
|
|
||||||
def hyperram_gen(dut):
|
def hyperram_gen(dut):
|
||||||
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
|
||||||
cs_n = "----______________________________________________________________________________________----"
|
cs_n = "----______________________________________________________________________________________________----"
|
||||||
dq_oe = "______------------____________________________________________________________________________"
|
dq_oe = "______------------____________________________________________________________________________________"
|
||||||
dq_o = "000000a000048d00000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
dq_o = "000000a000048d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
dq_i = "0000000000000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
dq_i = "0000000000000000000000000000000000000000000000000000000000000000000000deadbeefcafefade0000000000000000"
|
||||||
rwds_oe = "______________________________________________________________________________________________"
|
rwds_oe = "______________________________________________________________________________________________________"
|
||||||
rwds_i = "______________________________________________________________________--__--__--__--__________"
|
rwds_i = "______________________________________________________________________--__--__--__--__________________"
|
||||||
yield
|
yield
|
||||||
for i in range(len(clk)):
|
for i in range(len(clk)):
|
||||||
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
||||||
|
@ -262,13 +263,13 @@ class TestHyperRAM(unittest.TestCase):
|
||||||
self.assertEqual(dat, 0xdeadbeef)
|
self.assertEqual(dat, 0xdeadbeef)
|
||||||
|
|
||||||
def hyperram_gen(dut):
|
def hyperram_gen(dut):
|
||||||
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__-______"
|
clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__-______"
|
||||||
cs_n = "----________________________________________________________------"
|
cs_n = "----________________________________________________________________------"
|
||||||
dq_oe = "______------------________________________________________________"
|
dq_oe = "______------------________________________________________________________"
|
||||||
dq_o = "000000a000048d0000000000000000000000000000000000000000000000000000"
|
dq_o = "000000a000048d000000000000000000000000000000000000000000000000000000000000"
|
||||||
dq_i = "0000000000000000000000000000000000000000deadbeefcafefade0000000000"
|
dq_i = "0000000000000000000000000000000000000000deadbeefcafefade000000000000000000"
|
||||||
rwds_oe = "__________________________________________________________________"
|
rwds_oe = "__________________________________________________________________________"
|
||||||
rwds_i = "________________________________________--__--__--__--____________"
|
rwds_i = "________________________________________--__--__--__--____________________"
|
||||||
yield
|
yield
|
||||||
for i in range(len(clk)):
|
for i in range(len(clk)):
|
||||||
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
||||||
|
|
Loading…
Reference in New Issue