summaryrefslogtreecommitdiff
path: root/tb/models/ring.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tb/models/ring.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/tb/models/ring.py b/tb/models/ring.py
new file mode 100644
index 0000000..45305e6
--- /dev/null
+++ b/tb/models/ring.py
@@ -0,0 +1,54 @@
+def _shift_out(val, n):
+ rhs = val & ((1 << n) - 1)
+ lhs = val >> n
+ return (lhs, rhs)
+
+def _shift_in(val, n, req=0):
+ return req << n | (val & ((1 << n) - 1))
+
+def _out(*, ttl, read, inval, reply, tag, index, data):
+ req = _shift_in(read, 1, ttl)
+ req = _shift_in(inval, 1, req)
+ req = _shift_in(reply, 1, req)
+ req = _shift_in(tag, 13, req)
+ req = _shift_in(index, 12, req)
+ req = _shift_in(data, 128, req)
+ return req.to_bytes(20, 'big')
+
+class RingSegmentModel:
+ def __init__(self):
+ self.queue = []
+
+ def recv(self, req):
+ req = int.from_bytes(req, 'big')
+ req, data = _shift_out(req, 128)
+ req, index = _shift_out(req, 12)
+ req, tag = _shift_out(req, 13)
+ req, reply = _shift_out(req, 1)
+ req, inval = _shift_out(req, 1)
+ ttl, read = _shift_out(req, 1)
+
+ if ttl > 0:
+ req = _out(ttl=(ttl - 1), read=read, inval=inval, reply=reply,
+ tag=tag, index=index, data=data)
+
+ # Recvs de bus tienen prioridad
+ self.queue.insert(0, req)
+
+ def send(self, *, ty, tag, index, data):
+ read = 0
+ inval = 0
+
+ match ty:
+ case 'read':
+ read = 1
+ case 'inval':
+ inval = 1
+ case 'read-inval':
+ read = inval = 1
+
+ #FIXME: Bug en VPI
+ data = 0
+
+ req = _out(ttl=3, read=read, inval=inval, reply=0, tag=tag, index=index, data=data)
+ self.queue.append(req)