Skip to content

Commit

Permalink
Merge pull request #1999 from FlyGoat/csr-re
Browse files Browse the repository at this point in the history
csr_bus: Honour re signal from the upstream bus
  • Loading branch information
enjoy-digital committed Jun 24, 2024
2 parents 8e4f878 + af3d2a2 commit a47dde6
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 12 deletions.
5 changes: 4 additions & 1 deletion litex/soc/interconnect/axi/axi_lite.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def __init__(self, master, slave, origin=0, size=None):

# AXI-Lite to Simple Bus ---------------------------------------------------------------------------

def axi_lite_to_simple(axi_lite, port_adr, port_dat_r, port_dat_w=None, port_we=None):
def axi_lite_to_simple(axi_lite, port_adr, port_dat_r, port_dat_w=None, port_re=None, port_we=None):
"""Connection of AXILite to simple bus with 1-cycle latency, such as CSR bus or Memory port"""
bus_data_width = axi_lite.data_width
adr_shift = log2_int(bus_data_width//8)
Expand All @@ -168,6 +168,9 @@ def axi_lite_to_simple(axi_lite, port_adr, port_dat_r, port_dat_w=None, port_we=
else:
comb.append(port_we.eq(axi_lite.w.valid & axi_lite.w.ready & (axi_lite.w.strb != 0)))

if port_re is not None:
comb.append(port_re.eq(axi_lite.ar.valid & axi_lite.ar.ready))

port_adr_reg = Signal(len(port_adr))

fsm = FSM()
Expand Down
1 change: 1 addition & 0 deletions litex/soc/interconnect/axi/axi_lite_to_csr.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self, axi_lite=None, bus_csr=None, register=False):
fsm, comb = axi_lite_to_simple(
axi_lite = self.axi_lite,
port_adr = self.csr.adr,
port_re = self.csr.re,
port_dat_r = self.csr.dat_r,
port_dat_w = self.csr.dat_w,
port_we = self.csr.we)
Expand Down
20 changes: 13 additions & 7 deletions litex/soc/interconnect/csr_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
┌───────────┐ Write in 1 cycle:
│ │ - adr/we/dat_w set by bridge.
│ ├───► adr
│ │ Read in 2 cycles:
Main SoC Bus ◄────► CSR ├───► we - adr set by bridge
│ Bridge │ - dat_r set returned by user logic.
| | Read in 2 cycles:
│ ├───► re - adr and re set by bridge.
Main SoC Bus ◄────► │ - User logic can ignore re if there is no reading side effect.
| CSR ├───► we - dat_r set returned by user logic.
│ Bridge │
│ ├───► dat_w
│ │
│ ◄──── dat_r
Expand All @@ -46,6 +48,7 @@

_layout = [
("adr", "address_width", DIR_M_TO_S),
("re", 1, DIR_M_TO_S),
("we", 1, DIR_M_TO_S),
("dat_w", "data_width", DIR_M_TO_S),
("dat_r", "data_width", DIR_S_TO_M)
Expand Down Expand Up @@ -81,9 +84,11 @@ def write(self, adr, dat):

def read(self, adr):
yield self.adr.eq(adr)
yield self.re.eq(1)
yield
yield
return (yield self.dat_r)
value = (yield self.dat_r)
yield self.re.eq(0)
return value

# CSR Interconnect ---------------------------------------------------------------------------------

Expand All @@ -97,6 +102,7 @@ def __init__(self, masters, slaves):
intermediate = Interface.like(masters[0])
self.comb += [
intermediate.adr.eq( Reduce("OR", [masters[i].adr for i in range(len(masters))])),
intermediate.re.eq( Reduce("OR", [masters[i].re for i in range(len(masters))])),
intermediate.we.eq( Reduce("OR", [masters[i].we for i in range(len(masters))])),
intermediate.dat_w.eq(Reduce("OR", [masters[i].dat_w for i in range(len(masters))]))
]
Expand Down Expand Up @@ -207,8 +213,8 @@ def __init__(self, description, address=0, bus=None, paging=0x800, ordering="big
self.comb += [
c.r.eq(self.bus.dat_w[:c.size]),
If(sel & (self.bus.adr[:log2_int(aligned_paging)] == i),
c.re.eq( self.bus.we),
c.we.eq(~self.bus.we)
c.re.eq(self.bus.we),
c.we.eq(self.bus.re)
)
]

Expand Down
7 changes: 5 additions & 2 deletions litex/soc/interconnect/wishbone.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,12 +602,14 @@ def __init__(self, bus_wishbone=None, bus_csr=None, register=True):
NextValue(self.csr.dat_w, self.wishbone.dat_w),
If(self.wishbone.cyc & self.wishbone.stb,
NextValue(self.csr.adr, self.wishbone.adr[wishbone_adr_shift:]),
NextValue(self.csr.we, self.wishbone.we & (self.wishbone.sel != 0)),
NextValue(self.csr.re, ~self.wishbone.we & (self.wishbone.sel != 0)),
NextValue(self.csr.we, self.wishbone.we & (self.wishbone.sel != 0)),
NextState("WRITE-READ")
)
)
fsm.act("WRITE-READ",
NextValue(self.csr.adr, 0),
NextValue(self.csr.re, 0),
NextValue(self.csr.we, 0),
NextState("ACK")
)
Expand All @@ -623,7 +625,8 @@ def __init__(self, bus_wishbone=None, bus_csr=None, register=True):
self.csr.dat_w.eq(self.wishbone.dat_w),
If(self.wishbone.cyc & self.wishbone.stb,
self.csr.adr.eq(self.wishbone.adr[wishbone_adr_shift:]),
self.csr.we.eq(self.wishbone.we & (self.wishbone.sel != 0)),
self.csr.re.eq(~self.wishbone.we & (self.wishbone.sel != 0)),
self.csr.we.eq( self.wishbone.we & (self.wishbone.sel != 0)),
NextState("ACK")
)
)
Expand Down
4 changes: 2 additions & 2 deletions test/test_csr.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ def csr32_write(dut, adr, dat):

def csr32_read(dut, adr):
dat = 0
for i in range(4):
for i in range(5):
dat |= ((yield from dut.csr.read(adr + 3 - i)) << 8*i)
return dat
return dat >> 8


class CSRModule(Module, csr.AutoCSR):
Expand Down

0 comments on commit a47dde6

Please sign in to comment.