interconnect/axi/axi_full/AXIDownConverter: Fix len/addr conversion and add latency to r.resp/user/dest/id.

This commit is contained in:
Florent Kermarrec 2022-12-08 18:52:29 +01:00
parent a54d5180ba
commit fd12b6b0b7
1 changed files with 13 additions and 7 deletions

View File

@ -259,10 +259,13 @@ class AXIDownConverter(Module):
# AW Channel. # AW Channel.
self.comb += [ self.comb += [
axi_from.aw.connect(axi_to.aw, omit={"len", "size"}), axi_from.aw.connect(axi_to.aw, omit={"len", "size"}),
axi_to.aw.len.eq( axi_from.aw.len << log2_int(ratio)), axi_to.aw.len.eq(((axi_from.aw.len + 1) << log2_int(ratio)) - 1),
axi_to.aw.size.eq(axi_from.aw.size - log2_int(ratio)), axi_to.aw.size.eq(axi_from.aw.size - log2_int(ratio)),
] ]
# Upstream uses strb for unaligned accesses, so align Downstream address to Upstream.
self.comb += axi_to.aw.addr[:log2_int(dw_from//8)].eq(0),
# W Channel. # W Channel.
w_converter = stream.StrideConverter( w_converter = stream.StrideConverter(
description_from = [("data", dw_from), ("strb", dw_from//8)], description_from = [("data", dw_from), ("strb", dw_from//8)],
@ -271,6 +274,7 @@ class AXIDownConverter(Module):
self.submodules += w_converter self.submodules += w_converter
self.comb += axi_from.w.connect(w_converter.sink, omit={"id", "dest", "user"}) self.comb += axi_from.w.connect(w_converter.sink, omit={"id", "dest", "user"})
self.comb += w_converter.source.connect(axi_to.w) self.comb += w_converter.source.connect(axi_to.w)
# ID/Dest/User (self.comb since no latency in StrideConverter).
self.comb += axi_to.w.id.eq(axi_from.w.id) self.comb += axi_to.w.id.eq(axi_from.w.id)
self.comb += axi_to.w.dest.eq(axi_from.w.dest) self.comb += axi_to.w.dest.eq(axi_from.w.dest)
self.comb += axi_to.w.user.eq(axi_from.w.user) self.comb += axi_to.w.user.eq(axi_from.w.user)
@ -283,9 +287,11 @@ class AXIDownConverter(Module):
# AR Channel. # AR Channel.
self.comb += [ self.comb += [
axi_from.ar.connect(axi_to.ar, omit={"len", "size"}), axi_from.ar.connect(axi_to.ar, omit={"len", "size"}),
axi_to.ar.len.eq( axi_from.ar.len << log2_int(ratio)), axi_to.ar.len.eq(((axi_from.ar.len + 1) << log2_int(ratio)) - 1),
axi_to.ar.size.eq(axi_from.ar.size - log2_int(ratio)), axi_to.ar.size.eq(axi_from.ar.size - log2_int(ratio)),
] ]
# Upstream uses strb for unaligned accesses, so align Downstream address to Upstream.
self.comb += axi_to.ar.addr[:log2_int(dw_from//8)].eq(0),
# R Channel. # R Channel.
r_converter = stream.StrideConverter( r_converter = stream.StrideConverter(
@ -295,11 +301,11 @@ class AXIDownConverter(Module):
self.submodules += r_converter self.submodules += r_converter
self.comb += axi_to.r.connect(r_converter.sink, omit={"id", "dest", "user", "resp"}) self.comb += axi_to.r.connect(r_converter.sink, omit={"id", "dest", "user", "resp"})
self.comb += r_converter.source.connect(axi_from.r) self.comb += r_converter.source.connect(axi_from.r)
self.comb += axi_from.r.resp.eq(axi_to.r.resp) # ID/Dest/User (self.sync since +1 cycle latency in StrideConverter).
self.comb += axi_from.r.user.eq(axi_to.r.user) self.sync += axi_from.r.resp.eq(axi_to.r.resp)
self.comb += axi_from.r.dest.eq(axi_to.r.dest) self.sync += axi_from.r.user.eq(axi_to.r.user)
self.comb += axi_from.r.id.eq(axi_to.r.id) self.sync += axi_from.r.dest.eq(axi_to.r.dest)
self.sync += axi_from.r.id.eq(axi_to.r.id)
class AXIConverter(Module): class AXIConverter(Module):
"""AXI data width converter""" """AXI data width converter"""