diff --git a/unoptimized_lr/simple_lr_automaton.py b/unoptimized_lr/simple_lr_automaton.py
index a3d964568e721f7e92359de40e654db98561ea76..77c486ef509bf11f791842b76e02618f4269ac73 100644
--- a/unoptimized_lr/simple_lr_automaton.py
+++ b/unoptimized_lr/simple_lr_automaton.py
@@ -26,6 +26,7 @@ from functools import reduce
 #        * NNonterminal: Number of nonterminals
 #        * NStates:      Number of states in the LR automaton
 #        * NRules:       Number of rules
+#        * NLongestRule: Maximum number of right-hand-side items in a language rule
 #
 # From those, we derive these widths for internal buses and registers,
 # where log_2 determines the numbers of bits necessary to represent all possible
@@ -35,6 +36,7 @@ from functools import reduce
 # log_2(NNonterminal) = WNonterminal
 # log_2(NStates)=       WStates
 # log_2(NRules)=        WRules
+# log_2(NLongestRule)=  WLongestRule
 # and WItem = max(WTerminal, WNonterminal); since there are locations where
 # nonterminals and terminals alike must be processed/stored by the same mechanisms
 #
@@ -43,6 +45,9 @@ from functools import reduce
 #        * NStackItems:   Parse stack depth.
 #        * NLongestParse: The length of the longest possible parse tree
 #
+# log_2(NStackItems)   =    WStackItems
+# log_2(NLongestParse) =    WLongestParse
+#
 # In the general case, it is impossible to determine these for a given language.
 # Even with a simple expression-term-factor grammar, it's possible to reach arbitrary
 # depth of parse stack with arbitrary numbers of OPENPARENs, and likewise for the
@@ -60,14 +65,121 @@ from functools import reduce
 #        * Parse Stack
 #        * Sideband/index stack
 #        * Serialization memory
+#
+#
+# The top-level parser state machine ingests tokens from the input (with a bit width of
+# WTerminal):
+#
+#           INPUT STREAM
+#                |
+#                | bitwidth = WTerminal
+#                |
+#                V
+#   /----------------------\
+#   | Parse State Machine  |
+#   \----------------------/
+#
+# And the Parse State Machine is interfaced with multiple subcomponents. None of the
+# subcomponents are connected to each other so we list them here without needing to
+# include them in a single block diagram
+#
+#
+# Shift/Reduce table:
+#
+#                  (current state number, current terminal)
+#                       WStates             WTerminal
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        | Shift/reduce lookup |
+#   \----------------------/                        \---------------------/
+#               \                                            /
+#                <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#         (Parser action: {shift terminal, accept, error, reduce with rule k})
+#
+#
+#
+# GOTO table:
+#
+#           (current state number, nonterminal created by reduce rule)
+#                       WStates         WNonterminal
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        |      GOTO Table     |
+#   \----------------------/                        \---------------------/
+#               \                                            /
+#                <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#                     (validity bit, next state number)
+#
+#
+#
+# Reduce rule table:
+#
+#                           (reduce rule number)
+#                                WRules
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        | Reduce Rule Table   |
+#   \----------------------/                        \---------------------/
+#               \                                            /
+#                <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#              (nonterminal created, number of stack items to pop)
+#
+#
+#
+# Parse item stack:
+#
+#             (stack operation type, index for multipop, state number to push)
+#                3 bits                WStackItems        WStates
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        | Parse item stack    |
+#   \----------------------/                        \---------------------/
+#               \                                            /
+#                <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#                    (index out, data out, stack pointer)
+#
+#
+#
+# Parse index stack. Note that this is only needed if we're outputting a
+# serialized parse tree (regardless if to memory or to a stream):
+#
+#             (stack operation type, index for multipop, serialization index to push)
+#                3 bits                WStackItems         WLongestParse
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        | Parse index stack   |
+#   \----------------------/                        \---------------------/
+#               \                                            /
+#                <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#                    (index out, data out, stack pointer)
+#
+#
+# Serialization memory (or stream):
+#
+#               max(WLongestRule, 1 + WNonterminal, 1 + WTerminal)
+#                 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+#                /                                           \
+#   /----------------------\                        /---------------------\
+#   | Parse State Machine  |                        | Serialization memory|
+#   \----------------------/                        \---------------------/
+#
+# Note that there is no read connection, this allows the serialization memory
+# interface to be used without any change for a stream interface
+#
+
+
 
 
 
 
 
-class LRAutomaton(Elaboratable):
+class SimpleLRAutomaton(Elaboratable):
     def __init__(self):
-        
         # Stack
         self.mem = Memory(width=self.table_width, depth=self.table_depth, init=rasterized)