From: Florent Kermarrec Date: Mon, 27 Apr 2015 12:59:29 +0000 (+0200) Subject: litepcie: use new Migen modules from actorlib (avoid duplications between cores) X-Git-Tag: 24jan2021_ls180~2294 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=20dd6d3047ba8bc576fbc9f4dc2c20202dd09683;p=litex.git litepcie: use new Migen modules from actorlib (avoid duplications between cores) --- diff --git a/misoclib/com/litepcie/common.py b/misoclib/com/litepcie/common.py index b3ac21b1..4f16c7e6 100644 --- a/misoclib/com/litepcie/common.py +++ b/misoclib/com/litepcie/common.py @@ -1,6 +1,8 @@ from migen.fhdl.std import * from migen.genlib.record import * +from migen.genlib.misc import reverse_bytes from migen.flow.actor import * +from migen.actorlib.packet import Arbiter, Dispatcher KB = 1024 MB = 1024*KB @@ -18,15 +20,6 @@ def get_bar_mask(size): size = size >> 1 return mask - -def reverse_bytes(v): - return Cat(v[24:32], v[16:24], v[8:16], v[0:8]) - - -def reverse_bits(v): - return Cat(v[3], v[2], v[1], v[0]) - - def phy_layout(dw): layout = [ ("dat", dw), diff --git a/misoclib/com/litepcie/core/packet/common.py b/misoclib/com/litepcie/core/packet/common.py index da454347..2b7dedf3 100644 --- a/misoclib/com/litepcie/core/packet/common.py +++ b/misoclib/com/litepcie/core/packet/common.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.genlib.record import * from migen.flow.actor import EndpointDescription, Sink, Source +from migen.actorlib.packet import HeaderField, Header from misoclib.com.litepcie.common import * @@ -26,92 +27,91 @@ max_request_size = 512 # headers -class HField(): - def __init__(self, word, offset, width): - self.word = word - self.offset = offset - self.width = width - -tlp_header_w = 128 - -tlp_common_header = { - "fmt": HField(0, 29, 2), - "type": HField(0, 24, 5), +tlp_common_header_length = 16 +tlp_common_header_fields = { + "fmt": HeaderField(0*4, 29, 2), + "type": HeaderField(0*4, 24, 5), } - -tlp_request_header = { - "fmt": HField(0, 29, 2), - "type": HField(0, 24, 5), - "tc": HField(0, 20, 3), - "td": HField(0, 15, 1), - "ep": HField(0, 14, 1), - "attr": HField(0, 12, 2), - "length": HField(0, 0, 10), - - "requester_id": HField(1, 16, 16), - "tag": HField(1, 8, 8), - "last_be": HField(1, 4, 4), - "first_be": HField(1, 0, 4), - - "address": HField(2, 2, 30), +tlp_common_header = Header(tlp_common_header_fields, + tlp_common_header_length, + swap_field_bytes=False) + + +tlp_request_header_length = 16 +tlp_request_header_fields = { + "fmt": HeaderField(0*4, 29, 2), + "type": HeaderField(0*4, 24, 5), + "tc": HeaderField(0*4, 20, 3), + "td": HeaderField(0*4, 15, 1), + "ep": HeaderField(0*4, 14, 1), + "attr": HeaderField(0*4, 12, 2), + "length": HeaderField(0*4, 0, 10), + + "requester_id": HeaderField(1*4, 16, 16), + "tag": HeaderField(1*4, 8, 8), + "last_be": HeaderField(1*4, 4, 4), + "first_be": HeaderField(1*4, 0, 4), + + "address": HeaderField(2*4, 2, 30), } - -tlp_completion_header = { - "fmt": HField(0, 29, 2), - "type": HField(0, 24, 5), - "tc": HField(0, 20, 3), - "td": HField(0, 15, 1), - "ep": HField(0, 14, 1), - "attr": HField(0, 12, 2), - "length": HField(0, 0, 10), - - "completer_id": HField(1, 16, 16), - "status": HField(1, 13, 3), - "bcm": HField(1, 12, 1), - "byte_count": HField(1, 0, 12), - - "requester_id": HField(2, 16, 16), - "tag": HField(2, 8, 8), - "lower_address": HField(2, 0, 7), +tlp_request_header = Header(tlp_request_header_fields, + tlp_request_header_length, + swap_field_bytes=False) + + +tlp_completion_header_length = 16 +tlp_completion_header_fields = { + "fmt": HeaderField(0*4, 29, 2), + "type": HeaderField(0*4, 24, 5), + "tc": HeaderField(0*4, 20, 3), + "td": HeaderField(0*4, 15, 1), + "ep": HeaderField(0*4, 14, 1), + "attr": HeaderField(0*4, 12, 2), + "length": HeaderField(0*4, 0, 10), + + "completer_id": HeaderField(1*4, 16, 16), + "status": HeaderField(1*4, 13, 3), + "bcm": HeaderField(1*4, 12, 1), + "byte_count": HeaderField(1*4, 0, 12), + + "requester_id": HeaderField(2*4, 16, 16), + "tag": HeaderField(2*4, 8, 8), + "lower_address": HeaderField(2*4, 0, 7), } +tlp_completion_header = Header(tlp_completion_header_fields, + tlp_completion_header_length, + swap_field_bytes=False) # layouts -def _layout_from_header(header): - _layout = [] - for k, v in sorted(header.items()): - _layout.append((k, v.width)) - return _layout - - def tlp_raw_layout(dw): layout = [ - ("header", tlp_header_w), - ("dat", dw), - ("be", dw//8) + ("header", 4*32), + ("dat", dw), + ("be", dw//8) ] return EndpointDescription(layout, packetized=True) def tlp_common_layout(dw): - layout = _layout_from_header(tlp_common_header) + [ - ("dat", dw), - ("be", dw//8) + layout = tlp_common_header.get_layout() + [ + ("dat", dw), + ("be", dw//8) ] return EndpointDescription(layout, packetized=True) def tlp_request_layout(dw): - layout = _layout_from_header(tlp_request_header) + [ - ("dat", dw), - ("be", dw//8) + layout = tlp_request_header.get_layout() + [ + ("dat", dw), + ("be", dw//8) ] return EndpointDescription(layout, packetized=True) def tlp_completion_layout(dw): - layout = _layout_from_header(tlp_completion_header) + [ - ("dat", dw), - ("be", dw//8) + layout = tlp_completion_header.get_layout() + [ + ("dat", dw), + ("be", dw//8) ] return EndpointDescription(layout, packetized=True) diff --git a/misoclib/com/litepcie/core/packet/depacketizer.py b/misoclib/com/litepcie/core/packet/depacketizer.py index d81ba599..f04afe2c 100644 --- a/misoclib/com/litepcie/core/packet/depacketizer.py +++ b/misoclib/com/litepcie/core/packet/depacketizer.py @@ -3,16 +3,6 @@ from migen.actorlib.structuring import * from migen.genlib.fsm import FSM, NextState from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.core.switch.dispatcher import Dispatcher - - -def _decode_header(h_dict, h_signal, obj): - r = [] - for k, v in sorted(h_dict.items()): - start = v.word*32+v.offset - end = start+v.width - r.append(getattr(obj, k).eq(h_signal[start:end])) - return r class HeaderExtracter(Module): @@ -65,7 +55,7 @@ class HeaderExtracter(Module): source.sop.eq(sop), source.eop.eq(sink.eop), source.dat.eq(Cat(reverse_bytes(sink_dat_r[32:]), reverse_bytes(sink.dat[:32]))), - source.be.eq(Cat(reverse_bits(sink_be_r[4:]), reverse_bits(sink.be[:4]))), + source.be.eq(Cat(freversed(sink_be_r[4:]), freversed(sink.be[:4]))), If(source.stb & source.ack & source.eop, NextState("HEADER1") ) @@ -82,7 +72,7 @@ class HeaderExtracter(Module): source.sop.eq(1), source.eop.eq(1), source.dat.eq(reverse_bytes(sink.dat[32:])), - source.be.eq(reverse_bits(sink.be[4:])), + source.be.eq(freversed(sink.be[4:])), If(source.stb & source.ack & source.eop, NextState("HEADER1") ) @@ -116,7 +106,7 @@ class Depacketizer(Module): dispatch_source.eop.eq(header_extracter.source.eop), dispatch_source.dat.eq(header_extracter.source.dat), dispatch_source.be.eq(header_extracter.source.be), - _decode_header(tlp_common_header, header, dispatch_source) + tlp_common_header.decode(header, dispatch_source) ] self.submodules.dispatcher = Dispatcher(dispatch_source, dispatch_sinks) @@ -132,7 +122,7 @@ class Depacketizer(Module): # decode TLP request and format local request tlp_req = Source(tlp_request_layout(dw)) self.comb += Record.connect(dispatch_sinks[0], tlp_req) - self.comb += _decode_header(tlp_request_header, header, tlp_req) + self.comb += tlp_request_header.decode(header, tlp_req) req_source = self.req_source self.comb += [ @@ -151,7 +141,7 @@ class Depacketizer(Module): # decode TLP completion and format local completion tlp_cmp = Source(tlp_completion_layout(dw)) self.comb += Record.connect(dispatch_sinks[1], tlp_cmp) - self.comb += _decode_header(tlp_completion_header, header, tlp_cmp) + self.comb += tlp_completion_header.decode(header, tlp_cmp) cmp_source = self.cmp_source self.comb += [ diff --git a/misoclib/com/litepcie/core/packet/packetizer.py b/misoclib/com/litepcie/core/packet/packetizer.py index 8133f074..5807456d 100644 --- a/misoclib/com/litepcie/core/packet/packetizer.py +++ b/misoclib/com/litepcie/core/packet/packetizer.py @@ -4,16 +4,6 @@ from migen.genlib.fsm import FSM, NextState from migen.genlib.misc import chooser from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.core.switch.arbiter import Arbiter - - -def _encode_header(h_dict, h_signal, obj): - r = [] - for k, v in sorted(h_dict.items()): - start = v.word*32+v.offset - end = start+v.width - r.append(h_signal[start:end].eq(getattr(obj, k))) - return r class HeaderInserter(Module): @@ -53,7 +43,7 @@ class HeaderInserter(Module): source.sop.eq(0), source.eop.eq(sink.eop), source.dat.eq(Cat(sink.header[64:96], reverse_bytes(sink.dat[:32]))), - source.be.eq(Cat(Signal(4, reset=0xf), reverse_bits(sink.be[:4]))), + source.be.eq(Cat(Signal(4, reset=0xf), freversed(sink.be[:4]))), If(source.stb & source.ack, sink.ack.eq(1), If(source.eop, @@ -135,7 +125,7 @@ class Packetizer(Module): tlp_req.ack.eq(tlp_raw_req.ack), tlp_raw_req.sop.eq(tlp_req.sop), tlp_raw_req.eop.eq(tlp_req.eop), - _encode_header(tlp_request_header, tlp_raw_req.header, tlp_req), + tlp_request_header.encode(tlp_req, tlp_raw_req.header), tlp_raw_req.dat.eq(tlp_req.dat), tlp_raw_req.be.eq(tlp_req.be), ] @@ -179,7 +169,7 @@ class Packetizer(Module): tlp_cmp.ack.eq(tlp_raw_cmp.ack), tlp_raw_cmp.sop.eq(tlp_cmp.sop), tlp_raw_cmp.eop.eq(tlp_cmp.eop), - _encode_header(tlp_completion_header, tlp_raw_cmp.header, tlp_cmp), + tlp_completion_header.encode(tlp_cmp, tlp_raw_cmp.header), tlp_raw_cmp.dat.eq(tlp_cmp.dat), tlp_raw_cmp.be.eq(tlp_cmp.be), ] diff --git a/misoclib/com/litepcie/core/switch/arbiter.py b/misoclib/com/litepcie/core/switch/arbiter.py deleted file mode 100644 index c2ed003b..00000000 --- a/misoclib/com/litepcie/core/switch/arbiter.py +++ /dev/null @@ -1,25 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.roundrobin import * -from migen.genlib.record import * - - -class Arbiter(Module): - def __init__(self, sources, sink): - if len(sources) == 0: - pass - else: - self.submodules.rr = RoundRobin(len(sources)) - self.grant = self.rr.grant - cases = {} - for i, source in enumerate(sources): - sop = Signal() - eop = Signal() - ongoing = Signal() - self.comb += [ - sop.eq(source.stb & source.sop), - eop.eq(source.stb & source.eop & source.ack), - ] - self.sync += ongoing.eq((sop | ongoing) & ~eop) - self.comb += self.rr.request[i].eq((sop | ongoing) & ~eop) - cases[i] = [Record.connect(source, sink)] - self.comb += Case(self.grant, cases) diff --git a/misoclib/com/litepcie/core/switch/crossbar.py b/misoclib/com/litepcie/core/switch/crossbar.py index 9fa5070c..a5ee1af3 100644 --- a/misoclib/com/litepcie/core/switch/crossbar.py +++ b/misoclib/com/litepcie/core/switch/crossbar.py @@ -3,8 +3,6 @@ from migen.bank.description import * from misoclib.com.litepcie.common import * from misoclib.com.litepcie.core.switch.common import * -from misoclib.com.litepcie.core.switch.arbiter import Arbiter -from misoclib.com.litepcie.core.switch.dispatcher import Dispatcher from misoclib.com.litepcie.core.switch.request_controller import RequestController diff --git a/misoclib/com/litepcie/core/switch/dispatcher.py b/misoclib/com/litepcie/core/switch/dispatcher.py deleted file mode 100644 index d9e87f3f..00000000 --- a/misoclib/com/litepcie/core/switch/dispatcher.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.record import * - - -class Dispatcher(Module): - def __init__(self, source, sinks, one_hot=False): - if len(sinks) == 0: - self.sel = Signal() - elif len(sinks) == 1: - self.comb += Record.connect(source, sinks[0]) - self.sel = Signal() - else: - if one_hot: - self.sel = Signal(len(sinks)) - else: - self.sel = Signal(max=len(sinks)) - ### - sop = Signal() - self.comb += sop.eq(source.stb & source.sop) - sel = Signal(flen(self.sel)) - sel_r = Signal(flen(self.sel)) - self.sync += \ - If(sop, - sel_r.eq(self.sel) - ) - self.comb += \ - If(sop, - sel.eq(self.sel) - ).Else( - sel.eq(sel_r) - ) - cases = {} - for i, sink in enumerate(sinks): - if one_hot: - idx = 2**i - else: - idx = i - cases[idx] = [Record.connect(source, sink)] - cases["default"] = [source.ack.eq(1)] - self.comb += Case(sel, cases) diff --git a/misoclib/com/litepcie/test/model/host.py b/misoclib/com/litepcie/test/model/host.py index d69ccb52..b8207bc7 100644 --- a/misoclib/com/litepcie/test/model/host.py +++ b/misoclib/com/litepcie/test/model/host.py @@ -13,9 +13,9 @@ def print_host(s): # Host model class Host(Module): def __init__(self, dw, root_id, endpoint_id, bar0_size=1*MB, - phy_debug=False, - chipset_debug=False, chipset_split=False, chipset_reordering=False, - host_debug=False): + phy_debug=False, + chipset_debug=False, chipset_split=False, chipset_reordering=False, + host_debug=False): self.debug = host_debug self.chipset_split = chipset_split ### diff --git a/misoclib/com/litepcie/test/model/tlp.py b/misoclib/com/litepcie/test/model/tlp.py index fab7e1e6..78185d02 100644 --- a/misoclib/com/litepcie/test/model/tlp.py +++ b/misoclib/com/litepcie/test/model/tlp.py @@ -4,7 +4,7 @@ from misoclib.com.litepcie.core.packet.common import * # TLP Layer model def get_field_data(field, dwords): - return (dwords[field.word] >> field.offset) & (2**field.width-1) + return (dwords[field.byte//4] >> field.offset) & (2**field.width-1) tlp_headers_dict = { "RD32": tlp_request_header, @@ -23,14 +23,14 @@ class TLP(): self.decode_dwords() def decode_dwords(self): - for k, v in tlp_headers_dict[self.name].items(): + for k, v in tlp_headers_dict[self.name].fields.items(): setattr(self, k, get_field_data(v, self.header)) def encode_dwords(self, data=[]): self.header = [0, 0, 0] - for k, v in tlp_headers_dict[self.name].items(): - field = tlp_headers_dict[self.name][k] - self.header[field.word] |= (getattr(self, k) << field.offset) + for k, v in tlp_headers_dict[self.name].fields.items(): + field = tlp_headers_dict[self.name].fields[k] + self.header[field.byte//4] |= (getattr(self, k) << field.offset) self.data = data self.dwords = self.header + self.data return self.dwords @@ -81,8 +81,8 @@ fmt_type_dict = { def parse_dwords(dwords): - f = get_field_data(tlp_common_header["fmt"], dwords) - t = get_field_data(tlp_common_header["type"], dwords) + f = get_field_data(tlp_common_header.fields["fmt"], dwords) + t = get_field_data(tlp_common_header.fields["type"], dwords) fmt_type = (f << 5) | t try: tlp, min_len = fmt_type_dict[fmt_type]