diff --git a/unoptimized_lr/simple_lr_automaton.py b/unoptimized_lr/simple_lr_automaton.py
index 77c486ef509bf11f791842b76e02618f4269ac73..97b1c1b609768366751a0351dccc93457f9d467c 100644
--- a/unoptimized_lr/simple_lr_automaton.py
+++ b/unoptimized_lr/simple_lr_automaton.py
@@ -175,6 +175,42 @@ from functools import reduce
 
 
 
+class ParametrizationConstants():
+    def __init__(self, *, number_of_terminals, number_of_nonterminals,
+                          number_of_states, number_of_reduce_rules,
+                          length_of_longest_rule_RHS, maximum_number_of_stack_items,
+                          longest_serialized_parse_tree):
+        self.number_of_terminals           = number_of_terminals
+        self.number_of_nonterminals        = number_of_nonterminals
+        self.number_of_states              = number_of_states
+        self.number_of_reduce_rules        = number_of_reduce_rules
+        self.length_of_longest_rule_RHS    = length_of_longest_rule_RHS
+        self.maximum_number_of_stack_items = maximum_number_of_stack_items
+        self.longest_serialized_parse_tree = longest_serialized_parse_tree
+
+        # We calculate the ceil(log_2())'s here all in one go:
+
+        dummy_signal = Signal(range(number_of_terminals))
+        self.W_terminal = len(dummy_signal)
+
+        dummy_signal = Signal(range(number_of_nonterminals))
+        self.W_nonterminal = len(dummy_signal)
+
+        dummy_signal = Signal(range(number_of_states))
+        self.W_state = len(dummy_signal)
+
+        dummy_signal = Signal(range(number_of_reduce_rules))
+        self.W_rule = len(dummy_signal)
+
+        dummy_signal = Signal(range(length_of_longest_rule_RHS))
+        self.W_max_RHS = len(dummy_signal)
+
+        dummy_signal = Signal(range(maximum_number_of_stack_items))
+        self.W_stackdepth = len(dummy_signal)
+
+        dummy_signal = Signal(range(longest_serialized_parse_tree))
+        self.W_parsetree_index = len(dummy_signal)
+
 
 
 
diff --git a/unoptimized_lr/simple_lr_table.py b/unoptimized_lr/simple_lr_table.py
index 82a90e2b9c2d3912b086676c6b52064b88ccc8e1..e72ddf9c360c24ec78694688fc34fbad19021fea 100644
--- a/unoptimized_lr/simple_lr_table.py
+++ b/unoptimized_lr/simple_lr_table.py
@@ -7,6 +7,9 @@ import skidbuffer
 from functools import reduce
 
 
+# WARNING! NONE OF THESE ARE SYNTHESIZABLE! WE NEED TO FINISH THE ARBITRARYWIDTHMEMORY
+# MODULE BEFORE WE CAN REWRITE THESE TO USE FPGA BLOCK RAM!
+
 # We know this is not really likely to synthesize well, but we implement here so
 # we can get a gold-standard/reference implementation, against which we can test
 # our further optimizations, including compression and non-standard representations.
@@ -19,6 +22,8 @@ from functools import reduce
 
 
 
+
+
 class TableBusLayout(Layout):
     def __init__(self, *, row_input_width, column_input_width, output_width):
         super().__init__([
@@ -40,9 +45,28 @@ class TableBus(Record):
         super().__init__(TableBusLayout(row_input_width=row_input_width, column_input_width=column_input_width, output_width=output_width))
 
 
+class OneDimensionTableBusLayout(Layout):
+    def __init__(self, *, row_input_width, output_width):
+        super().__init__([
+            # INPUTS
+            ("row_idx",     unsigned(row_input_width)),    # FROM SOURCE
+            ("valid_in",    1),                            # FROM SOURCE
+            ("ready_in",    1),        # FROM DEST
+
+            # OUTPUTS
+            ("output_data", unsigned(output_width)), # TO DEST
+            ("valid_out",   1), # TO DEST
+            ("ready_out",   1), # TO SOURCE
+
+        ])
+
+class OneDimensionTableBus(Record):
+    def __init__(self, *, row_input_width, output_width):
+        super().__init__(OneDimensionTableBusLayout(row_input_width=row_input_width, output_width=output_width))
+
 
 class LRTable(Elaboratable):
-    def __init__(self, number_of_states, number_of_terminals, number_of_reduce_rules, input_array):
+    def __init__(self, *, lang_params, input_array):
         # Parameters
 
         # So the LR table is a two-dimensional array, where one of the dimensions (rows)
@@ -64,33 +88,26 @@ class LRTable(Elaboratable):
         # depth = number_of_states * number_of_terminals
 
         # We calculate these now:
+        self.lang_params = lang_params
 
-        reduce_rule_signal = Signal(range(number_of_reduce_rules))
-        reduce_rule_bits = len(reduce_rule_signal)
-        self.table_width = (reduce_rule_bits + 2)
-        self.table_depth = number_of_states * number_of_terminals
-
-        self.number_of_terminals = number_of_terminals
-
+        self.table_width = (lang_params.W_rule + 2)
+        self.table_depth = lang_params.number_of_states * lang_params.number_of_terminals
 
 
-        dummy_row    = Signal(range(number_of_states))
-        dummy_column = Signal(range(number_of_terminals))
-
         # Interfaces
-        self.bus = TableBus(row_input_width=len(dummy_row),
-                            column_input_width=len(dummy_column),
+        self.bus = TableBus(row_input_width=lang_params.W_state,
+                            column_input_width=lang_params.W_terminal,
                             output_width=self.table_width)
         # Interfaces
 
 
 
         # Prepare the table for consumption
-        assert(len(input_array) == number_of_states)
+        assert(len(input_array) == lang_params.number_of_states)
 
         rasterized = []
         for row in input_array:
-            assert(len(row) == number_of_terminals)
+            assert(len(row) == lang_params.number_of_terminals)
             rasterized.extend(row)
 
         # Memory
@@ -110,7 +127,7 @@ class LRTable(Elaboratable):
         # Now we calculate the address:
         tgt_address = Signal(self.table_depth)
         with m.If(self.bus.valid_in == 1):
-            m.d.comb += tgt_address.eq(self.bus.row_idx * self.number_of_terminals + self.bus.col_idx)
+            m.d.comb += tgt_address.eq(self.bus.row_idx * self.lang_params.number_of_terminals + self.bus.col_idx)
             m.d.comb += rport.addr.eq(tgt_address)
         with m.If(self.bus.valid_out == 1):
             m.d.comb += self.bus.output_data.eq((rport.data))
@@ -120,7 +137,7 @@ class LRTable(Elaboratable):
 
 
 class GOTOtable(Elaboratable):
-    def __init__(self, number_of_states, number_of_nonterminals, input_array):
+    def __init__(self, *,  lang_params, input_array):
         # Parameters
 
         # So the GOTO table is a two-dimensional array, where one of the dimensions (rows)
@@ -147,32 +164,26 @@ class GOTOtable(Elaboratable):
         # depth = number_of_states
 
         # We calculate these now:
+        self.lang_params = lang_params
 
-        nonterminal_signal = Signal(range(number_of_nonterminals))
-        nonterminal_bits = len(nonterminal_signal)
-        self.table_width = (nonterminal_bits + 1)
-        print(number_of_nonterminals)
-        self.table_depth = number_of_nonterminals * number_of_states
-
-        self.number_of_nonterminals = number_of_nonterminals
 
+        self.table_width = (lang_params.W_nonterminal + 1)
+        print(lang_params.number_of_nonterminals)
+        self.table_depth = lang_params.number_of_nonterminals * lang_params.number_of_states
 
 
-        dummy_row    = Signal(range(number_of_states))
-        dummy_column = Signal(range(number_of_nonterminals))
-
         # Interfaces
-        self.bus = TableBus(row_input_width=len(dummy_row),
-                            column_input_width=len(dummy_column),
+        self.bus = TableBus(row_input_width=lang_params.W_state,
+                            column_input_width=lang_params.W_nonterminal,
                             output_width=self.table_width)
 
 
         # Prepare the table for consumption
-        assert(len(input_array) == number_of_states)
+        assert(len(input_array) == lang_params.number_of_states)
 
         rasterized = []
         for row in input_array:
-            assert(len(row) == number_of_nonterminals)
+            assert(len(row) == lang_params.number_of_nonterminals)
             rasterized.extend(row)
 
         # Memory
@@ -192,7 +203,7 @@ class GOTOtable(Elaboratable):
         # Now we calculate the address:
         tgt_address = Signal(self.table_depth)
         with m.If(self.bus.valid_in == 1):
-            m.d.comb += tgt_address.eq(self.bus.row_idx * self.number_of_nonterminals + self.bus.col_idx)
+            m.d.comb += tgt_address.eq(self.bus.row_idx * self.lang_params.number_of_nonterminals + self.bus.col_idx)
             m.d.comb += rport.addr.eq(tgt_address)
         with m.If(self.bus.valid_out == 1):
             m.d.comb += self.bus.output_data.eq(rport.data)
@@ -204,6 +215,48 @@ class GOTOtable(Elaboratable):
 
 
 
+
+class ReduceRuleTable(Elaboratable):
+    def __init__(self, *, lang_params, input_array):
+        # Parameters
+
+        # So the Reduce Rule lookup table is a one-dimensional array, indexed by
+        # rule number:
+
+        # Each element of the array is of the form:
+
+        # [Number of items to pop] [Generated nonterminal]
+
+        # This means that the length of each element has to be:
+        # TIW = (WLongestRule + number of bits to index the nonterminals)
+
+    
+        self.table_width = (nonterminal_bits + 1)
+        print(number_of_nonterminals)
+        self.table_depth = number_of_nonterminals * number_of_states
+
+        self.number_of_nonterminals = number_of_nonterminals
+
+
+        # Interfaces
+        self.bus = OneDimensionTableBus(row_input_width=W_nonterminal,
+                            output_width=self.table_width)
+
+
+        self.mem = Memory(width=self.table_width, depth=self.table_depth, init=rasterized)
+
+
+    def elaborate(self, platform):
+        m = Module()
+        m.submodules.rport = rport = (self.mem).read_port()
+        m.submodules.wport = wport = (self.mem).write_port()
+
+
+        return m
+
+
+
+
 class DummyPlug(Elaboratable):
 
     #def __init__(self):
diff --git a/unoptimized_lr/skidbuffer.py b/unoptimized_lr/skidbuffer.py
old mode 100755
new mode 100644