[tlgen] Various fixes to tlgen behavior.
- De-couples unode / dnode dependencies. In the existing design
sometimes the downstream node may overwrite properties of upstream.
- When s1n connects to sm1, always fully passthrough, FIFOs can be
instantiated at the beginning of s1n, or the end of sm1
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/util/tlgen/elaborate.py b/util/tlgen/elaborate.py
index 09a32ac..7a2f52a 100644
--- a/util/tlgen/elaborate.py
+++ b/util/tlgen/elaborate.py
@@ -83,9 +83,12 @@
node_type=NodeType.SOCKET_M1,
clock=xbar.clock,
reset=xbar.reset)
- new_node.hdepth = 2
+
+ # By default, assume connecting to SOCKET_1N upstream and bypass all FIFOs
+ # If upstream requires pipelining, it will be added through process pipeline
+ new_node.hdepth = 0
new_node.hpass = 2**len(node.us) - 1
- new_node.ddepth = 2
+ new_node.ddepth = 0
new_node.dpass = 1
xbar.insert_node(new_node, node)
process_node(new_node, xbar)
@@ -97,9 +100,12 @@
node_type=NodeType.SOCKET_1N,
clock=xbar.clock,
reset=xbar.reset)
- new_node.hdepth = 2
+
+ # By default, assume connecting to SOCKET_M1 downstream and bypass all FIFOs
+ # If upstream requires pipelining, it will be added through process pipeline
+ new_node.hdepth = 0
new_node.hpass = 1
- new_node.ddepth = 2
+ new_node.ddepth = 0
new_node.dpass = 2**len(node.ds) - 1
xbar.insert_node(new_node, node)
@@ -122,29 +128,59 @@
# If Socket M1, find position of the host and follow procedure above
# If it is device, it means host and device are directly connected. Ignore now.
- # After process node is done, always only one downstream exists in any host node
- if host.pipeline is True and host.pipeline_byp is True:
- # No need to process, same as default
- continue
+ log.info("Processing pipeline for host {}".format(host.name))
- no_bypass = (host.pipeline is True and host.pipeline_byp is False)
+ # FIFO present with no passthrough option
+ # FIFO present with passthrough option
+ # FIFO not present and full passthrough
+ full_fifo = False
+ fifo_passthru = False
+ full_passthru = True
+ if host.pipeline is True and host.pipeline_byp is False:
+ full_fifo = True
+
+ elif host.pipeline is True and host.pipeline_byp is True:
+ fifo_passthru = True
+
+ elif host.pipeline is False:
+ full_passthru = True
+
dnode = host.ds[0].ds
if dnode.node_type == NodeType.ASYNC_FIFO:
continue
if dnode.node_type == NodeType.SOCKET_1N:
- dnode.hpass = 0 if no_bypass else dnode.hpass
+ if full_fifo:
+ dnode.hpass = 0
+ dnode.hdepth = 2
+ elif fifo_passthru:
+ dnode.hpass = 0
+ dnode.hdepth = 2
+ elif full_passthru:
+ dnode.hpass = 1
+ dnode.hdepth = 0
+
+ log.info("Finished processing socket1n {}, pass={}, depth={}"
+ .format(dnode.name, dnode.hpass, dnode.hdepth))
elif dnode.node_type == NodeType.SOCKET_M1:
idx = dnode.us.index(host.ds)
- dnode.hpass = dnode.hpass ^ (
- 1 << idx) if no_bypass else dnode.hpass
+ if full_fifo:
+ log.info("fifo present no bypass")
+ dnode.hpass = dnode.hpass & ~(1 << idx)
+ dnode.hdepth = dnode.hdepth | (2 << idx * 4)
+ elif fifo_passthru:
+ log.info("fifo present with bypass")
+ dnode.hpass = dnode.hpass | (1 << idx)
+ dnode.hdepth = dnode.hdepth | (2 << idx * 4)
+ elif full_passthru:
+ log.info("fifo not present")
+ dnode.hpass = dnode.hpass | (1 << idx)
+ dnode.hdepth = dnode.hdepth & ~(0xF << idx * 4)
- # keep variables separate in case we ever need to differentiate
- dnode.dpass = 0 if no_bypass else dnode.dpass
- dnode.hdepth = 0 if host.pipeline is False else dnode.hdepth
- dnode.ddepth = dnode.hdepth
+ log.info("Finished processing socketm1 {}, pass={}, depth={}"
+ .format(dnode.name, dnode.hpass, dnode.hdepth))
for device in xbar.devices:
# go upstream and set DReq/RspPass at the first instance.
@@ -155,10 +191,24 @@
# If Socket 1N, find position of the device and follow procedure above
# If it is host, ignore
- if device.pipeline is True and device.pipeline_byp is True:
- continue
+ log.info("Processing pipeline for device {}".format(device.name))
- no_bypass = (device.pipeline is True and device.pipeline_byp is False)
+ # FIFO present with no passthrough option
+ # FIFO present with passthrough option
+ # FIFO not present and full passthrough
+
+ full_fifo = False
+ fifo_passthru = False
+ full_passthru = True
+ if device.pipeline is True and device.pipeline_byp is False:
+ full_fifo = True
+
+ elif device.pipeline is True and device.pipeline_byp is True:
+ fifo_passthru = True
+
+ elif device.pipeline is False:
+ full_passthru = True
+
unode = device.us[0].us
if unode.node_type == NodeType.ASYNC_FIFO:
@@ -166,15 +216,35 @@
if unode.node_type == NodeType.SOCKET_1N:
idx = unode.ds.index(device.us[0])
- unode.dpass = unode.dpass ^ (
- 1 << idx) if no_bypass else unode.dpass
+
+ if full_fifo:
+ unode.dpass = unode.dpass & ~(1 << idx)
+ unode.ddepth = unode.ddepth | (2 << idx * 4)
+ elif fifo_passthru:
+ unode.dpass = unode.dpass | (1 << idx)
+ unode.ddepth = unode.ddepth | (2 << idx * 4)
+ elif full_passthru:
+ unode.dpass = unode.dpass | (1 << idx)
+ unode.ddepth = unode.ddepth & ~(0xF << idx * 4)
+
+ log.info("Finished processing socket1n {}, pass={:x}, depth={:x}"
+ .format(unode.name, unode.dpass, unode.ddepth))
elif unode.node_type == NodeType.SOCKET_M1:
- unode.dpass = 0 if no_bypass else unode.dpass
+ if full_fifo:
+ log.info("Fifo present with no passthrough")
+ unode.dpass = 0
+ unode.ddepth = 2
+ elif fifo_passthru:
+ log.info("Fifo present with passthrough")
+ unode.dpass = 0
+ unode.ddepth = 2
+ elif full_passthru:
+ log.info("No Fifo")
+ unode.dpass = 1
+ unode.ddepth = 0
- # keep variables separate in case we ever need to differentiate
- unode.hpass = 0 if no_bypass else unode.hpass
- unode.ddepth = 0 if device.pipeline is False else unode.ddepth
- unode.hdepth = unode.ddepth
+ log.info("Finished processing socketm1 {}, pass={:x}, depth={:x}"
+ .format(unode.name, unode.dpass, unode.ddepth))
return xbar