From 5abd73c570fd0ea5a86cceb46f5293be4ebbce58 Mon Sep 17 00:00:00 2001
From: Kia <kia@special-circumstanc.es>
Date: Sat, 23 May 2020 18:27:51 -0600
Subject: [PATCH] introspection of serialized parse tree!

---
 combinatorial_LR_parser.py |  16 +-
 python_arborist.py         | 298 +++++++++++++++++++++++++++++++++++++
 2 files changed, 307 insertions(+), 7 deletions(-)
 create mode 100644 python_arborist.py

diff --git a/combinatorial_LR_parser.py b/combinatorial_LR_parser.py
index 25ea3ef..7e801f4 100644
--- a/combinatorial_LR_parser.py
+++ b/combinatorial_LR_parser.py
@@ -409,7 +409,6 @@ class HitOrMiss(Elaboratable):
 
                     new_item_in_shiftset = Signal(1)
                     shift_item_predicates   = []
-                    print(forceshift_rule)
                     if (forceshift_rule == []):
                         m.d.comb += new_item_in_shiftset.eq(0)
                     else:
@@ -555,6 +554,7 @@ class TreeSerializer(Elaboratable):
         self.memory_address_port         = Signal(self.mem_address_width)
         self.memory_write_enable         = Signal(1)
 
+        self.mem = Memory(width=(self.item_width + 1), depth=64)
 
     def elaborate(self, platform):
         m = Module()
@@ -562,8 +562,7 @@ class TreeSerializer(Elaboratable):
         start_of_record = Signal(self.mem_address_width) # start of next/yet-unwritten node record, advanced only
                                                          # after each reduce
 
-        self.memory_introspection = mem = Memory(width=(self.item_width + 1), depth=64)
-        m.submodules.parse_tree = wport = mem.write_port()
+        m.submodules.parse_tree = wport = (self.mem).write_port()
 
 
 
@@ -649,10 +648,8 @@ class TreeSerializer(Elaboratable):
 
 
 
-
         return m
 
-
 # This is the master state machine -- it interfaces with the outside
 # and feeds data to the above subcomponents as appropriate. For
 # multi-cycle operations (popping multiple items off the InspectableStack)
@@ -688,6 +685,9 @@ class MasterStateMachine(Elaboratable):
         self.parse_complete_out = Signal(1)
         self.parse_success_out  = Signal(1)
         self.internal_fault     = Signal(1)
+        self.serializer = TreeSerializer(item_width=self.item_width, indices_width=(self.indices_width+1), stack_depth=self.stack_depth, serializing_ruleset=[])
+        self.tapir = self.serializer.mem
+
 
     def elaborate(self, platform):
         m = Module()
@@ -701,14 +701,16 @@ class MasterStateMachine(Elaboratable):
             reduction_rule_count=len(self.execute_rules), stack_state_descriptions = self.stack_state_descriptions, endofparse_marker = self.endofparse_marker)
         rex = RuleExecutor(item_width=self.item_width, stack_depth=self.stack_depth, execution_ruleset=self.execute_rules)
         skbuffer = RegisteredSkidBuffer(width = self.item_width)
-        serializer = TreeSerializer(item_width=self.item_width, indices_width=(self.indices_width+1), stack_depth=self.stack_depth, serializing_ruleset=[])
+#        serializer = TreeSerializer(item_width=self.item_width, indices_width=(self.indices_width+1), stack_depth=self.stack_depth, serializing_ruleset=[])
         #m.submodules.Stack = stack
         m.submodules.Stacks = doublestacks
         m.submodules.RuleMatcher = rule_matcher
         m.submodules.RuleExecute = rex
         m.submodules.skidbuffer = skbuffer
 
-        m.submodules.Serializer = serializer
+        serializer = m.submodules.Serializer = self.serializer
+
+
         # Skid buffer
         fsm_ready = Signal(1)
         new_item_valid = Signal(1)
diff --git a/python_arborist.py b/python_arborist.py
new file mode 100644
index 0000000..7e12bb4
--- /dev/null
+++ b/python_arborist.py
@@ -0,0 +1,298 @@
+from nmigen import *
+from nmigen.cli import main
+
+from nmigen.back.pysim import Simulator, Delay
+
+from functools import reduce
+
+
+from typing import List, Dict, Tuple, Optional
+
+
+from combinatorial_LR_parser import MasterStateMachine
+
+
+class Cirno(Elaboratable):
+    def __init__(self):
+        self.input_memory_addr = Signal(8)
+        self.input_memory_data = Signal(16)
+
+    def elaborate(self, platform):
+        cntr = Signal(8)
+        resetted = Signal(1)
+
+        valid_data_out = Signal(1)
+        romem_ready = Signal(1)
+        data_port = Signal(16)
+
+
+        BOTTOM      = 0x5a00
+        ENDOFPARSE  = 0x5500
+
+        EXPRESSION  = 0xEE00
+        TERM        = 0xE700
+        FACTOR      = 0xEF00
+        INTEGER     = 0xE100
+
+        OPENPAREN   = 0xCA00
+        CLOSEPAREN  = 0xCB00
+
+        ADDOP       = 0xAA00
+        MULTOP      = 0xAB00
+        STDMASK     = 0xff00
+
+        m = Module()
+        # BOTTOM = start of parse
+
+
+
+        common_stack_states = [
+        # State 0 in the paper
+        # Bottom of parse stack
+        [(0, STDMASK, BOTTOM)],
+
+        # State 1 in the paper
+        # Bottom of parse stack        Expression
+        [(1, STDMASK, BOTTOM),          (0, STDMASK, EXPRESSION)],
+
+        # state 2 in paper
+        # TERM
+        [(0, STDMASK, TERM)],
+
+        # state 3 in paper
+        # FACTOR
+        [(0, STDMASK, FACTOR)],
+
+        # State 4 in paper
+        # OPEN PAREN
+        [(0, STDMASK, OPENPAREN)],
+
+        # State 5 in paper
+        # INTEGER
+        [(0, STDMASK, INTEGER)],
+
+        # State 6 in paper
+        # EXPRESSION             PLUS
+        [(1, STDMASK, EXPRESSION), (0, STDMASK, ADDOP)],
+
+        # State 7 in paper
+        # TERM                     MULTIPLY
+        [(1, STDMASK, TERM), (0, STDMASK, MULTOP)],
+
+        # State 8 in paper
+        # OPEN PAREN             EXPRESSION
+        [(1, STDMASK, OPENPAREN), (0, STDMASK, EXPRESSION)],
+
+        # State 9 in paper
+        #  EXPRESSION             PLUS                 TERM
+        [(2, STDMASK, EXPRESSION), (1, STDMASK, ADDOP), (0, STDMASK, TERM)],
+
+        # State 10 in paper
+        # TERM                    MULTIPLY             FACTOR
+        [(2, STDMASK, TERM), (1, STDMASK, MULTOP), (0, STDMASK, FACTOR)],
+
+        # State 11 in paper
+        # OPEN PAREN             EXPRESSION             CLOSE PAREN
+        [(2, STDMASK, OPENPAREN), (1, STDMASK, EXPRESSION), (0, STDMASK, CLOSEPAREN)]
+        ]
+
+        pairwise_priority_ruleset = [(1,8),(2,9), (3,10)]
+
+
+
+        validitem_ruleset = [
+        # For state 0:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 1:
+        [(STDMASK, ADDOP),                                           (STDMASK, ENDOFPARSE)],
+        # For state 2:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        # For state 3:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        # For state 4:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 5:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        # For state 6:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 7:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 8:
+        [(STDMASK, ADDOP),                    (STDMASK, CLOSEPAREN)],
+        # For state 9:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        # For state 10:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        # For state 11:
+        [(STDMASK, ADDOP), (STDMASK, MULTOP), (STDMASK, CLOSEPAREN), (STDMASK, ENDOFPARSE)],
+        ]
+
+
+        forceshift_ruleset = [
+        # For state 0:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 1:
+        [(STDMASK, ADDOP),                                           (STDMASK, ENDOFPARSE)],
+        # For state 2:
+        [(STDMASK, MULTOP)],
+        # For state 3:
+        [],
+        # For state 4:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 5:
+        [],
+        # For state 6:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 7:
+        [(STDMASK, INTEGER),                  (STDMASK, OPENPAREN)],
+        # For state 8:
+        [(STDMASK, ADDOP),                    (STDMASK, CLOSEPAREN)],
+        # For state 9:
+        [(STDMASK, MULTOP)],
+        # For state 10:
+        [],
+        # For state 11:
+        []
+        ]
+
+
+        reduce_ruleset = [
+        # For state 0:
+        [],
+        # For state 1:
+        [],
+        # For state 2:
+        [((STDMASK, ADDOP),1), ((STDMASK, CLOSEPAREN),1), ((STDMASK, ENDOFPARSE),1)],
+        # For state 3:
+        [((STDMASK, ADDOP),3), ((STDMASK, MULTOP),3), ((STDMASK, CLOSEPAREN),3), ((STDMASK, ENDOFPARSE),3)],
+        # For state 4:
+        [],
+        # For state 5:
+        [((STDMASK, ADDOP),5), ((STDMASK, MULTOP),5), ((STDMASK, CLOSEPAREN),5), ((STDMASK, ENDOFPARSE),5)],
+        # For state 6:
+        [],
+        # For state 7:
+        [],
+        # For state 8:
+        [],
+        # For state 9:
+        [((STDMASK, ADDOP),0), ((STDMASK, CLOSEPAREN),0), ((STDMASK, ENDOFPARSE),0)],
+        # For state 10:
+        [((STDMASK, ADDOP),2), ((STDMASK, MULTOP),2), ((STDMASK, CLOSEPAREN),2), ((STDMASK, ENDOFPARSE),2)],
+        # For state 11:
+        [((STDMASK, ADDOP),4), ((STDMASK, MULTOP),4), ((STDMASK, CLOSEPAREN),4), ((STDMASK, ENDOFPARSE),4)],
+        ]
+
+        def extractor(x): return (x & 0x00ff)
+        execute_rules = [
+        (3, (lambda stackview: EXPRESSION + (extractor(stackview[0]) + extractor(stackview[2])))),
+
+        (1, (lambda stackview: EXPRESSION + extractor(stackview[0]))),
+
+        (3, (lambda stackview: TERM + (extractor(stackview[0]) * extractor(stackview[2])))),
+
+        (1, (lambda stackview: TERM + extractor(stackview[0]))),
+
+        (3, (lambda stackview: FACTOR + extractor(stackview[1]))),
+
+        (1, (lambda stackview: FACTOR + extractor(stackview[0])))
+        ]
+
+        msm = MasterStateMachine(item_width=16, indices_width=16, stack_depth=10,
+            validitem_ruleset = validitem_ruleset,
+            pairwise_priority_ruleset = pairwise_priority_ruleset,
+            forceshift_ruleset = forceshift_ruleset,
+            reduce_ruleset=reduce_ruleset,
+            execute_rules=execute_rules, stack_state_descriptions=common_stack_states, endofparse_marker=(0xffff, ENDOFPARSE))
+
+        m.submodules.StateMachine = msm
+
+        self.tapir = msm.tapir
+
+        with m.If(resetted == 0):
+            m.d.sync += resetted.eq(1)
+        with m.If(resetted == 1):
+            m.d.comb += msm.data_in_valid.eq(1)
+
+        stall_recovery = Signal(1)
+
+        cashew_register = Signal(16)
+        m.d.sync += stall_recovery.eq(msm.data_in_ready) # one-cycle-delayed
+
+        with m.If(msm.data_in_ready == 1):
+            m.d.sync += cntr.eq(cntr + 1)
+            m.d.comb += msm.data_in.eq(self.input_memory_data)
+
+        with m.If((msm.data_in_ready == 0) & (stall_recovery == 1)):
+            m.d.sync += cashew_register.eq(self.input_memory_data)
+            m.d.comb += msm.data_in.eq(self.input_memory_data)
+
+        with m.If(stall_recovery == 0):
+            m.d.comb += msm.data_in.eq(cashew_register)
+
+
+        m.d.comb += self.input_memory_addr.eq(cntr)
+
+
+
+        return m
+
+
+
+BOTTOM      = 0x5a00
+ENDOFPARSE  = 0x5500
+
+EXPRESSION  = 0xEE00
+TERM        = 0xE700
+FACTOR      = 0xEF00
+INTEGER     = 0xE100
+
+OPENPAREN   = 0xCA00
+CLOSEPAREN  = 0xCB00
+
+ADDOP       = 0xAA00
+MULTOP      = 0xAB00
+STDMASK     = 0xff00
+
+
+if __name__ == '__main__':
+    m = Module()
+    m.submodules.baka = nine = Cirno()
+
+    trace = []
+    def process():
+        for _ in range(16):
+            yield
+            array = []
+            for idx in range(16):
+                #print(idx)
+                x = yield nine.tapir[idx]
+                array.append(x)
+            trace.append(array)
+
+
+    init_data = [OPENPAREN, OPENPAREN, 0XE102, CLOSEPAREN, ADDOP, 0XE103, CLOSEPAREN, ADDOP, 0XE101, ENDOFPARSE]
+    
+    with m.Switch(nine.input_memory_addr):
+        for addr,data in enumerate(init_data):
+            with m.Case(addr):
+                #print(addr,data)
+                m.d.comb += nine.input_memory_data.eq(data)
+        with m.Default():
+                m.d.comb += nine.input_memory_data.eq(0xfe)
+
+
+    sim = Simulator(m)
+    sim.add_clock(1e-9)
+    sim.add_sync_process(process)
+    with sim.write_vcd("test.vcd", "test.gtkw"):
+        sim.run()
+
+    print(trace)
+
+
+
+
+
+
+
-- 
GitLab