litepcie: use new Migen modules from actorlib (avoid duplications between cores)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 27 Apr 2015 12:59:29 +0000 (14:59 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 27 Apr 2015 13:05:40 +0000 (15:05 +0200)
misoclib/com/litepcie/common.py
misoclib/com/litepcie/core/packet/common.py
misoclib/com/litepcie/core/packet/depacketizer.py
misoclib/com/litepcie/core/packet/packetizer.py
misoclib/com/litepcie/core/switch/arbiter.py [deleted file]
misoclib/com/litepcie/core/switch/crossbar.py
misoclib/com/litepcie/core/switch/dispatcher.py [deleted file]
misoclib/com/litepcie/test/model/host.py
misoclib/com/litepcie/test/model/tlp.py

index b3ac21b14f7af6586f1e69c208e70766c8415d1a..4f16c7e68f318fe7246444bee444a0200dfd6ffb 100644 (file)
@@ -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),
index da454347e8a3f4ae19c3bdcb3147d7ca1ba612b0..2b7dedf3c778a28c128130f3ec18f58f2ebbd901 100644 (file)
@@ -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)
index d81ba599f31ae9d615979c7711cd9be2a5400132..f04afe2c9acefc50e54821e35d62ddb68e4fe692 100644 (file)
@@ -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 += [
index 8133f0746ff3d125aec72eef27a05dd287c50b14..5807456d3815daa5871525f50c9d39de8efd737d 100644 (file)
@@ -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 (file)
index c2ed003..0000000
+++ /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)
index 9fa5070cec0a5a67eb08d0b0c8c073b9b68dc6d6..a5ee1af30bc88e17045a6bde52980db85c04b228 100644 (file)
@@ -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 (file)
index d9e87f3..0000000
+++ /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)
index d69ccb52e939013d41ff735755843de3bf167d74..b8207bc78283986e2809f91a86256af55275f347 100644 (file)
@@ -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
         ###
index fab7e1e60388b724ab302ca5b6567d6ef6f96b42..78185d022f34cfb74dcc9cccf3150e856c9910cd 100644 (file)
@@ -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]