[otbn,python] Wrap code to 79 columns

Our Python style guide claims that we wrap code at 79 columns but our
flake8 configuration is set to allow 100 (presumably because it's too
much work to squeeze existing code into shape!).

I wrote the OTBN Python code intending it to stay at 79. Put in a
local .flake8 file to set the expected width correctly and then (lots
of lines...) re-format comments and break strings to get everything
sorted.

This stricter formatting won't be checked by CI (which runs at
top-level, so won't see the new .flake8 config file) but it *will* be
checked by people's text editors if they've got the usual Python
setup.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/.flake8 b/hw/ip/otbn/.flake8
new file mode 100644
index 0000000..bfead2c
--- /dev/null
+++ b/hw/ip/otbn/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+max-line-length = 79
diff --git a/hw/ip/otbn/dv/otbnsim/sim/gpr.py b/hw/ip/otbn/dv/otbnsim/sim/gpr.py
index 9cd081a..26aff11 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/gpr.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/gpr.py
@@ -77,7 +77,8 @@
     def get_reg(self, idx: int) -> Reg:
         if idx == 0:
             # If idx == 0, this is a zeros register that should ignore writes.
-            # Return a fresh Reg with no parent, so writes to it have no effect.
+            # Return a fresh Reg with no parent, so writes to it have no
+            # effect.
             return Reg(None, 0, 32, 0)
         elif idx == 1:
             # If idx == 1, we return self._x1: element 1 of the underlying
diff --git a/hw/ip/otbn/dv/otbnsim/sim/state.py b/hw/ip/otbn/dv/otbnsim/sim/state.py
index d8ec83a..fc58c7e 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/state.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/state.py
@@ -155,8 +155,9 @@
         assert not self.rnd_cdc_pending
 
         # Collect 32b packages in a 256b variable
-        shift_num = 32 * self.rnd_256b_counter
-        self.rnd_256b = (self.rnd_256b | (rnd_data << shift_num)) & ((1 << 256) - 1)
+        new_word = rnd_data << (32 * self.rnd_256b_counter)
+        assert new_word < (1 << 256)
+        self.rnd_256b = self.rnd_256b | new_word
 
         if self.rnd_256b_counter == 7:
             # Reset the 32b package counter and wait until receiving done
@@ -245,7 +246,8 @@
         c = []  # type: List[Trace]
         c += self.gprs.changes()
         if self._pc_next_override is not None:
-            # Only append the next program counter to the trace if it is special
+            # Only append the next program counter to the trace if it has
+            # been set explicitly.
             c.append(TracePC(self.get_next_pc()))
         c += self.dmem.changes()
         c += self.loop_stack.changes()
@@ -400,7 +402,8 @@
         '''
 
         if self._err_bits:
-            # Abort all pending changes, including changes to external registers.
+            # Abort all pending changes, including changes to external
+            # registers.
             self._abort()
 
         # INTR_STATE is the interrupt state register. Bit 0 (which is being
diff --git a/hw/ip/otbn/dv/otbnsim/sim/stats.py b/hw/ip/otbn/dv/otbnsim/sim/stats.py
index bc8bc4d..a9bc9be 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/stats.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/stats.py
@@ -91,33 +91,36 @@
                 'iterations': iterations,
             })
 
-        is_last_insn_in_loop_body = state_bc.loop_stack.is_last_insn_in_loop_body(pc)
+        last_in_loop_body = state_bc.loop_stack.is_last_insn_in_loop_body(pc)
 
         # Basic blocks
+        #
         # A basic block is a linear sequence of code ending with an instruction
         # that can potentially change the control flow: a jump, a branch, the
         # last instruction in a loop (LOOP or LOOPI) body, or an ECALL. The
-        # length of the basic block equals the number of instructions within the
-        # basic block.
+        # length of the basic block equals the number of instructions within
+        # the basic block.
         self._current_basic_block_len += 1
-        if (is_jump or is_branch or is_last_insn_in_loop_body or
+        if (is_jump or is_branch or last_in_loop_body or
                 isinstance(insn, ECALL)):
 
             self.basic_block_histo[self._current_basic_block_len] += 1
             self._current_basic_block_len = 0
 
         # Extended basic blocks
+        #
         # An extended basic block is a sequence of one or more basic blocks
-        # which can be statically determined at compile time.
-        # Extended basic blocks end with a branch, the last instruction in a
-        # LOOP body, or an ECALL instruction.
+        # which can be statically determined at compile time. Extended basic
+        # blocks end with a branch, the last instruction in a LOOP body, or an
+        # ECALL instruction.
 
-        # Determine if the current instruction is the last instruction in a LOOP
-        # body (only LOOP, not LOOPI!).
+        # Determine if the current instruction is the last instruction in a
+        # LOOP body (only LOOP, not LOOPI!).
         finishing_loop = False
-        if is_last_insn_in_loop_body:
+        if last_in_loop_body:
             loop_insn_addr = state_bc.loop_stack.stack[-1].get_loop_insn_addr()
-            finishing_loop = isinstance(self._insn_at_addr(loop_insn_addr), LOOP)
+            last_insn = self._insn_at_addr(loop_insn_addr)
+            finishing_loop = isinstance(last_insn, LOOP)
 
         self._current_ext_basic_block_len += 1
         if is_branch or finishing_loop or isinstance(insn, ECALL):
@@ -143,8 +146,10 @@
                 continue
             # Looking for a range of addresses in two consecutive states that
             # contain the required address.
-            if prevstate and prevstate.address <= address < entry.state.address:
-                filename = lineprog['file_entry'][prevstate.file - 1].name.decode('utf-8')
+            if ((prevstate and
+                 prevstate.address <= address < entry.state.address)):
+                raw_name = lineprog['file_entry'][prevstate.file - 1].name
+                filename = raw_name.decode('utf-8')
                 line = prevstate.line
                 return filename, line
             prevstate = entry.state
@@ -180,7 +185,8 @@
             for sym_addr in self._addr_symbol_map.keys():
                 if sym_addr <= address and sym_addr > func_addr:
                     func_addr = sym_addr
-            symbol_name = self._addr_symbol_map[func_addr] + f"+{address - func_addr:#x}"
+            func_name = self._addr_symbol_map[func_addr]
+            symbol_name = func_name + f"+{address - func_addr:#x}"
 
         file_line = None
         if self._elf_file.has_dwarf_info():
@@ -267,8 +273,10 @@
 
         # Build function call graphs and a call site index
         # caller-indexed == forward, callee-indexed == reverse
-        # The call graphs are on function granularity; the call sites dictionary
-        # is indexed by the called function, but uses the call site as value.
+        #
+        # The call graphs are on function granularity; the call sites
+        # dictionary is indexed by the called function, but uses the call site
+        # as value.
         callgraph = {}  # type: Dict[int, typing.Counter[int]]
         rev_callgraph = {}  # type: Dict[int, typing.Counter[int]]
         rev_callsites = {}  # type: Dict[int, typing.Counter[int]]
@@ -297,8 +305,8 @@
                 func = self._describe_imem_addr(rev_caller_func)
                 out += f"    * {cnt} times by function {func}\n"
             out += "  from the following call sites\n"
-            for rev_callsite, cnt in rev_callsites[rev_callee_func].most_common():
-                func = self._describe_imem_addr(rev_callsite)
+            for rc, cnt in rev_callsites[rev_callee_func].most_common():
+                func = self._describe_imem_addr(rc)
                 out += f"    * {cnt} times from {func}\n"
 
             has_one_callsite = len(rev_callsites[rev_callee_func]) == 1
@@ -308,9 +316,9 @@
                 out += "    no other function (leaf function).\n"
 
                 if not has_one_callsite:
-                    # We don't count it as leaf function call if it has only one
-                    # call site to prevent double-counting these as optimization
-                    # opportunity.
+                    # We don't count it as leaf function call if it has only
+                    # one call site to prevent double-counting these as
+                    # optimization opportunity.
                     total_leaf_calls += sum(rev_caller_funcs.values())
             else:
                 caller_funcs = callgraph[rev_callee_func]
diff --git a/hw/ip/otbn/dv/otbnsim/sim/wsr.py b/hw/ip/otbn/dv/otbnsim/sim/wsr.py
index 2b00ab5..b20e474 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/wsr.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/wsr.py
@@ -90,9 +90,10 @@
 
     RND is special as OTBN can stall on reads to it. A read from RND either
     immediately returns data from a cache of a previous EDN request (triggered
-    by writing to the RND_PREFETCH CSR) or waits for data from the EDN. To model
-    this anything reading from RND must first call `request_value` which returns
-    True if the value is available.
+    by writing to the RND_PREFETCH CSR) or waits for data from the EDN. To
+    model this, anything reading from RND must first call `request_value` which
+    returns True if the value is available.
+
     '''
     def __init__(self, name: str):
         super().__init__(name)
diff --git a/hw/ip/otbn/dv/otbnsim/stepped.py b/hw/ip/otbn/dv/otbnsim/stepped.py
index 6e52369..5e8f0c3 100755
--- a/hw/ip/otbn/dv/otbnsim/stepped.py
+++ b/hw/ip/otbn/dv/otbnsim/stepped.py
@@ -74,7 +74,8 @@
                          .format(word_data, arg_name)) from None
 
     if value < 0 or value >> bits:
-        raise ValueError('<{}> argument is {!r}: not representable in {!r} bits.'
+        raise ValueError('<{}> argument is {!r}: '
+                         'not representable in {!r} bits.'
                          .format(arg_name, word_data, bits))
 
     return value
diff --git a/hw/ip/otbn/dv/otbnsim/test/simple_test.py b/hw/ip/otbn/dv/otbnsim/test/simple_test.py
index aacf363..d600227 100644
--- a/hw/ip/otbn/dv/otbnsim/test/simple_test.py
+++ b/hw/ip/otbn/dv/otbnsim/test/simple_test.py
@@ -108,7 +108,7 @@
         else:
             m = _REG_RE.match(line)
             if not m:
-                raise RuntimeError('Failed to parse line after dump_regs ({!r}).'
+                raise RuntimeError('Failed to parse dump_regs line ({!r}).'
                                    .format(line))
 
             ret[m.group(1)] = int(m.group(2), 0)
@@ -138,7 +138,7 @@
 
             m = _REG_RE.match(line)
             if m is None:
-                raise RuntimeError('{}:{}: Bad format for line in expected.txt.'
+                raise RuntimeError('{}:{}: Bad format for line.'
                                    .format(exp_path, idx + 1))
             ret[m.group(1)] = int(m.group(2), 0)
 
@@ -153,8 +153,9 @@
 
     # Run the simulation. We can just pass a list of commands to stdin, and
     # don't need to do anything clever to track what's going on.
-    standalone_py = os.path.join(SIM_DIR, 'standalone.py')
-    sim_proc = subprocess.run([standalone_py, '--dump-regs', '-', '-v', elf_file], check=True,
+    cmd = [os.path.join(SIM_DIR, 'standalone.py'),
+           '--dump-regs', '-', '-v', elf_file]
+    sim_proc = subprocess.run(cmd, check=True,
                               stdout=subprocess.PIPE, universal_newlines=True)
 
     regs_seen = get_reg_dump(sim_proc.stdout)
diff --git a/hw/ip/otbn/dv/otbnsim/test/stats_test.py b/hw/ip/otbn/dv/otbnsim/test/stats_test.py
index 9b169bb..9982c9c 100644
--- a/hw/ip/otbn/dv/otbnsim/test/stats_test.py
+++ b/hw/ip/otbn/dv/otbnsim/test/stats_test.py
@@ -100,11 +100,12 @@
         1: 1   # 1 basic block with 1 instruction (ecall)
     })
 
-    assert sorted(stats.ext_basic_block_histo) == sorted(stats.basic_block_histo)
+    assert (sorted(stats.ext_basic_block_histo) ==
+            sorted(stats.basic_block_histo))
 
 
 def test_basic_block_stats_loopi(tmpdir: py.path.local) -> None:
-    '''Check if statistics for basic blocks in LOOPIs are calculated properly'''
+    '''Check statistics for basic blocks in LOOPIs are calculated properly'''
 
     asm = """
     /* Loop 3 times over a body of 2 instructions. */
diff --git a/hw/ip/otbn/dv/rig/rig/config.py b/hw/ip/otbn/dv/rig/rig/config.py
index 326c995..fd4962b 100644
--- a/hw/ip/otbn/dv/rig/rig/config.py
+++ b/hw/ip/otbn/dv/rig/rig/config.py
@@ -84,11 +84,15 @@
             else:
                 self.max_values[key[4:]] = ival
 
-    def get_min(self, key: str, default: Optional[int] = None) -> Optional[int]:
+    def get_min(self,
+                key: str,
+                default: Optional[int] = None) -> Optional[int]:
         '''Get a minimum from the dictionary'''
         return self.min_values.get(key, default)
 
-    def get_max(self, key: str, default: Optional[int] = None) -> Optional[int]:
+    def get_max(self,
+                key: str,
+                default: Optional[int] = None) -> Optional[int]:
         '''Get a maximum from the dictionary'''
         return self.max_values.get(key, default)
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/bad_deep_loop.py b/hw/ip/otbn/dv/rig/rig/gens/bad_deep_loop.py
index c726dfd..c9d98cb 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/bad_deep_loop.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/bad_deep_loop.py
@@ -143,11 +143,11 @@
             # above)
             prog_insn, _ = self._gen_loop_head(model, program)
 
-            # Note that we generate a ProgSnippet, not a LoopSnippet here: while
-            # we've got a loop instruction, we happen to know that it will fault,
-            # so it's going to behave more like a straight line instruction. Also,
-            # we don't have a snippet for the body so the types don't really work
-            # for LoopSnippet.
+            # Note that we generate a ProgSnippet, not a LoopSnippet here:
+            # while we've got a loop instruction, we happen to know that it
+            # will fault, so it's going to behave more like a straight line
+            # instruction. Also, we don't have a snippet for the body so the
+            # types don't really work for LoopSnippet.
             snippet = ProgSnippet(model.pc, [prog_insn])
             snippet.insert_into_program(program)
 
@@ -161,7 +161,8 @@
         # space calculations into account (maybe thread them through as
         # arguments?)
 
-        # Our space calculations in gen() should have ensured that this is true.
+        # Our space calculations in gen() should have ensured that this is
+        # true.
         assert space_here >= 2
 
         hd_pc = model.pc
@@ -195,7 +196,8 @@
         if body_snippet is None:
             body_snippet = real_body_snippet
         else:
-            body_snippet = Snippet.merge_list([body_snippet, real_body_snippet])
+            body_snippet = Snippet.merge_list([body_snippet,
+                                               real_body_snippet])
 
         return (LoopSnippet(hd_pc, hd_insn, body_snippet, None), model)
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/bad_ispr.py b/hw/ip/otbn/dv/rig/rig/gens/bad_ispr.py
index 3aaaa39..92d0f62 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/bad_ispr.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/bad_ispr.py
@@ -17,7 +17,7 @@
 
 
 class BadIspr(SnippetGen):
-    ''' A snippet to generate load and store instructions to bad CSR/ WSR adresses '''
+    '''A snippet to generate accesses to invalid CSRs/WSRs'''
 
     ends_program = True
 
@@ -72,8 +72,9 @@
         while prog_insn is None:
             idx = random.choices(range(len(self.insns)), weights=weights)[0]
 
-            # weights[idx] will be positive so long as at least one instruction has positive weight.
-            # If it's zero, it means that every weight is zero and we should give up.
+            # weights[idx] will be positive so long as at least one instruction
+            # has positive weight. If it's zero, it means that every weight is
+            # zero and we should give up.
             if weights[idx] < 0:
                 return None
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/bad_load_store.py b/hw/ip/otbn/dv/rig/rig/gens/bad_load_store.py
index 342d9a2..cb1ba17 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/bad_load_store.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/bad_load_store.py
@@ -70,16 +70,17 @@
         if len(self.bnlid.operands) != 5:
             raise RuntimeError('Unexpected number of operands for bn.lid')
 
-        if not (isinstance(self.bnlid.operands[0].op_type, RegOperandType) and
-                (self.bnlid.operands[0].op_type.reg_type == 'gpr' and
-                not self.bnlid.operands[0].op_type.is_dest() and
-                isinstance(self.bnlid.operands[1].op_type, RegOperandType) and
-                self.bnlid.operands[1].op_type.reg_type == 'gpr' and
-                not self.bnlid.operands[1].op_type.is_dest() and
-                isinstance(self.bnlid.operands[2].op_type, ImmOperandType) and
-                self.bnlid.operands[2].op_type.signed and
-                isinstance(self.bnlid.operands[3].op_type, OptionOperandType) and
-                isinstance(self.bnlid.operands[4].op_type, OptionOperandType))):
+        ops = self.bnlid.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                (ops[0].op_type.reg_type == 'gpr' and
+                not ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'gpr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, ImmOperandType) and
+                ops[2].op_type.signed and
+                isinstance(ops[3].op_type, OptionOperandType) and
+                isinstance(ops[4].op_type, OptionOperandType))):
             raise RuntimeError('BN.LID instruction from instructions file is '
                                'not the shape expected by the BadLoadStore'
                                'generator.')
@@ -92,16 +93,17 @@
         if len(self.bnsid.operands) != 5:
             raise RuntimeError('Unexpected number of operands for bn.sid')
 
-        if not (isinstance(self.bnsid.operands[0].op_type, RegOperandType) and
-                self.bnsid.operands[0].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[0].op_type.is_dest() and
-                isinstance(self.bnsid.operands[1].op_type, RegOperandType) and
-                self.bnsid.operands[1].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[1].op_type.is_dest() and
-                isinstance(self.bnsid.operands[2].op_type, ImmOperandType) and
-                self.bnsid.operands[2].op_type.signed and
-                isinstance(self.bnsid.operands[3].op_type, OptionOperandType) and
-                isinstance(self.bnsid.operands[4].op_type, OptionOperandType)):
+        ops = self.bnsid.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                ops[0].op_type.reg_type == 'gpr' and
+                not ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'gpr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, ImmOperandType) and
+                ops[2].op_type.signed and
+                isinstance(ops[3].op_type, OptionOperandType) and
+                isinstance(ops[4].op_type, OptionOperandType)):
             raise RuntimeError('BN.LID instruction from instructions file is '
                                'not the shape expected by the BadLoadStore'
                                'generator.')
@@ -256,8 +258,9 @@
 
         elif insn.mnemonic == 'sw':
             # Any known register is okay for grs2 operand since it will be
-            # guaranteed to have an out of bounds address to store the value from
-            # We definitely have a known register (x0), so this should never fail
+            # guaranteed to have an out of bounds address to store the value
+            # from We definitely have a known register (x0), so this should
+            # never fail
             op_val_grs2 = random.choice(known_regs)[0]
 
             op_val = [op_val_grs2, offset_val, op_val_grs1]
@@ -305,15 +308,16 @@
         if insn.mnemonic == 'bn.lid':
             # Pick grd randomly. Since we can write to any register
             # (including x0) this should always succeed.
-            op_val_grd = model.pick_operand_value(self.bnlid.operands[0].op_type)
+            op_val_grd = model.pick_operand_value(insn.operands[0].op_type)
             assert op_val_grd is not None
 
             op_val = [op_val_grd, op_val_grs1, bn_offset_val, 0, 0]
 
         elif insn.mnemonic == 'bn.sid':
             # Any known register is okay for grs2 operand since it will be
-            # guaranteed to have an out of bounds address to store the value from.
-            # We definitely have a known register (x0), so this should never fail
+            # guaranteed to have an out of bounds address to store the value
+            # from. We definitely have a known register (x0), so this should
+            # never fail
             op_val_grs2 = random.choice(known_regs)[0]
 
             op_val = [op_val_grs1, op_val_grs2, bn_offset_val, 0, 0]
diff --git a/hw/ip/otbn/dv/rig/rig/gens/branch.py b/hw/ip/otbn/dv/rig/rig/gens/branch.py
index 115b5c1..45bb13c 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/branch.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/branch.py
@@ -36,8 +36,9 @@
                     not insn.operands[1].op_type.is_dest() and
                     isinstance(insn.operands[2].op_type, ImmOperandType) and
                     insn.operands[2].op_type.signed):
-                raise RuntimeError('{} instruction from instructions file is not '
-                                   'the shape expected by the Branch generator.'
+                raise RuntimeError('{} instruction from instructions file is '
+                                   'not the shape expected by the Branch '
+                                   'generator.'
                                    .format(insn.mnemonic))
 
         self.beq_prob = 0.5
diff --git a/hw/ip/otbn/dv/rig/rig/gens/branch_gen.py b/hw/ip/otbn/dv/rig/rig/gens/branch_gen.py
index 0a21467..2093338 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/branch_gen.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/branch_gen.py
@@ -16,7 +16,7 @@
 
 
 class BranchGen(SnippetGen):
-    ''' A snippet generator base class to generate bad or unbtaken BEQ and BNE.
+    ''' A snippet generator base class to generate bad or untaken BEQ and BNE.
 
     BadBranch and UntakenBranch inherit this class.
 
@@ -42,8 +42,9 @@
                     not insn.operands[1].op_type.is_dest() and
                     isinstance(insn.operands[2].op_type, ImmOperandType) and
                     insn.operands[2].op_type.signed):
-                raise RuntimeError('{} instruction from instructions file is not '
-                                   'the shape expected by the Branch generator.'
+                raise RuntimeError('{} instruction from instructions file is '
+                                   'not the shape expected by the BranchGen '
+                                   'generator.'
                                    .format(insn.mnemonic))
 
         self.imm_op_type = self.bne.operands[2].op_type
@@ -55,7 +56,7 @@
                     self.weights.append(weight)
                     self.insns.append(insn)
 
-        # Disable this generator if no branch instruction has a positive weigh
+        # Disable this generator if no branch instruction has a positive weight
         assert len(self.insns) == len(self.weights)
         if not self.weights:
             self.disabled = True
diff --git a/hw/ip/otbn/dv/rig/rig/gens/call_stack_rw.py b/hw/ip/otbn/dv/rig/rig/gens/call_stack_rw.py
index afd6cbd..b3e376f 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/call_stack_rw.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/call_stack_rw.py
@@ -54,7 +54,8 @@
                 weight = cfg.insn_weights.get(insn.mnemonic)
                 if weight > 0:
                     self.insns.append(insn)
-                    self.indices.append((gpr_dsts[0], gpr_srcs[0], gpr_srcs[1]))
+                    self.indices.append((gpr_dsts[0],
+                                         gpr_srcs[0], gpr_srcs[1]))
                     self.weights.append(weight)
 
         if not self.insns:
@@ -81,7 +82,8 @@
         '''
 
         # Pick an instruction
-        insn_idx = random.choices(range(len(self.weights)), weights=self.weights)[0]
+        insn_idx = random.choices(range(len(self.weights)),
+                                  weights=self.weights)[0]
 
         grd_idx, grs1_idx, grs2_idx = self.indices[insn_idx]
         insn = self.insns[insn_idx]
diff --git a/hw/ip/otbn/dv/rig/rig/gens/edge_load_store.py b/hw/ip/otbn/dv/rig/rig/gens/edge_load_store.py
index 195dd82..e854ec2 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/edge_load_store.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/edge_load_store.py
@@ -51,17 +51,18 @@
         if len(self.bnsid.operands) != 5:
             raise RuntimeError('Unexpected number of operands for bn.sid')
 
-        if not (isinstance(self.bnsid.operands[0].op_type, RegOperandType) and
-                self.bnsid.operands[0].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[0].op_type.is_dest() and
-                isinstance(self.bnsid.operands[1].op_type, RegOperandType) and
-                self.bnsid.operands[1].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[1].op_type.is_dest() and
-                isinstance(self.bnsid.operands[2].op_type, ImmOperandType) and
-                self.bnsid.operands[2].op_type.signed and
-                isinstance(self.bnsid.operands[3].op_type, OptionOperandType) and
-                isinstance(self.bnsid.operands[4].op_type, OptionOperandType)):
-            raise RuntimeError('BN.LID instruction from instructions file is '
+        ops = self.bnsid.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                ops[0].op_type.reg_type == 'gpr' and
+                not ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'gpr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, ImmOperandType) and
+                ops[2].op_type.signed and
+                isinstance(ops[3].op_type, OptionOperandType) and
+                isinstance(ops[4].op_type, OptionOperandType)):
+            raise RuntimeError('BN.SID instruction from instructions file is '
                                'not the shape expected by the BadLoadStore'
                                'generator.')
 
@@ -132,13 +133,14 @@
 
         for reg_idx, u_reg_val in known_regs:
             reg_val = u_reg_val - (1 << 32) if u_reg_val >> 31 else u_reg_val
-            if model.dmem_size - reg_val - 4 in range(min_offset, max_offset + 1):
+            off_to_top = model.dmem_size - reg_val - 4
+            if off_to_top in range(min_offset, max_offset + 1):
                 base.append((reg_idx, reg_val))
 
         if not base:
             return None
 
-        # Pick a random register among known registers that are constrained above
+        # Pick a random known register that can reach the top of memory
         idx, value = random.choice(base)
 
         imm_val = model.dmem_size - 4 - value
diff --git a/hw/ip/otbn/dv/rig/rig/gens/known_wdr.py b/hw/ip/otbn/dv/rig/rig/gens/known_wdr.py
index 9cdffd7..625a8db 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/known_wdr.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/known_wdr.py
@@ -29,43 +29,47 @@
 
         # BN.XOR has six operands: wrd, wrs1, wrs2, shift_type, shift_value
         # and flag_group
-        if not (len(self.bn_xor.operands) == 6 and
-                isinstance(self.bn_xor.operands[0].op_type, RegOperandType) and
-                self.bn_xor.operands[0].op_type.reg_type == 'wdr' and
-                self.bn_xor.operands[0].op_type.is_dest() and
-                isinstance(self.bn_xor.operands[1].op_type, RegOperandType) and
-                self.bn_xor.operands[1].op_type.reg_type == 'wdr' and
-                not self.bn_xor.operands[1].op_type.is_dest() and
-                isinstance(self.bn_xor.operands[2].op_type, RegOperandType) and
-                self.bn_xor.operands[2].op_type.reg_type == 'wdr' and
-                not self.bn_xor.operands[2].op_type.is_dest() and
-                isinstance(self.bn_xor.operands[4].op_type, ImmOperandType)):
+        ops = self.bn_xor.operands
+        if not (len(ops) == 6 and
+                isinstance(ops[0].op_type, RegOperandType) and
+                ops[0].op_type.reg_type == 'wdr' and
+                ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'wdr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, RegOperandType) and
+                ops[2].op_type.reg_type == 'wdr' and
+                not ops[2].op_type.is_dest() and
+                isinstance(ops[4].op_type, ImmOperandType)):
             raise RuntimeError('BN.XOR instruction from instructions file is '
-                               'not the shape expected by the KnownWDR generator.')
+                               'not the shape expected by the KnownWDR '
+                               'generator.')
 
-        self.wrd_op_type = self.bn_xor.operands[0].op_type
-        self.wrs_op_type = self.bn_xor.operands[1].op_type
-        self.imm_op_type = self.bn_xor.operands[4].op_type
+        self.wrd_op_type = ops[0].op_type
+        self.wrs_op_type = ops[1].op_type
+        self.imm_op_type = ops[4].op_type
         assert self.imm_op_type.shift == 3
 
-        if not (isinstance(self.bn_not.operands[0].op_type, RegOperandType) and
-                self.bn_not.operands[0].op_type.reg_type == 'wdr' and
-                self.bn_not.operands[0].op_type.is_dest() and
-                isinstance(self.bn_not.operands[1].op_type, RegOperandType) and
-                self.bn_not.operands[1].op_type.reg_type == 'wdr' and
-                not self.bn_not.operands[1].op_type.is_dest() and
-                isinstance(self.bn_not.operands[2].op_type, EnumOperandType) and
-                isinstance(self.bn_not.operands[3].op_type, ImmOperandType)):
+        ops = self.bn_not.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                ops[0].op_type.reg_type == 'wdr' and
+                ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'wdr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, EnumOperandType) and
+                isinstance(ops[3].op_type, ImmOperandType)):
             raise RuntimeError('BN.NOT instruction from instructions file is '
-                               'not the shape expected by KnownWDR generator. ')
+                               'not the shape expected by the KnownWDR '
+                               'generator.')
 
     def gen(self,
             cont: GenCont,
             model: Model,
             program: Program) -> Optional[GenRet]:
-        # Return None if this one of the last two instructions in the current gap
-        # because we need to either jump or do an ECALL to avoid getting stuck
-        # after executing both bn.xor and bn.not
+        # Return None if this one of the last two instructions in the current
+        # gap because we need to either jump or do an ECALL to avoid getting
+        # stuck after executing both bn.xor and bn.not
         if program.get_insn_space_at(model.pc) <= 3:
             return None
 
@@ -92,7 +96,8 @@
         shift_bits = self.imm_op_type.op_val_to_enc_val(0, model.pc)
         assert shift_bits is not None
 
-        # Value of shift_type does not matter since shift_bits are hardcoded to 0
+        # Value of shift_type does not matter since shift_bits are hardcoded to
+        # 0
         shift_type = model.pick_operand_value(self.bn_xor.operands[3].op_type)
         assert shift_type is not None
 
@@ -108,7 +113,8 @@
         op_vals_xor = [wrd_val_xor, wrs_val_xor, wrs_val_xor, shift_type,
                        shift_bits, flg_group]
 
-        op_vals_not = [wrd_val_not, wrd_val_xor, shift_type, shift_bits, flg_group]
+        op_vals_not = [wrd_val_not, wrd_val_xor,
+                       shift_type, shift_bits, flg_group]
 
         prog_bn_xor = ProgInsn(self.bn_xor, op_vals_xor, None)
         prog_bn_not = ProgInsn(self.bn_not, op_vals_not, None)
diff --git a/hw/ip/otbn/dv/rig/rig/gens/loop.py b/hw/ip/otbn/dv/rig/rig/gens/loop.py
index af1f6ae..622a7b5 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/loop.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/loop.py
@@ -46,8 +46,8 @@
                 self.loop.operands[0].op_type.reg_type == 'gpr' and
                 isinstance(self.loop.operands[1].op_type, ImmOperandType) and
                 not self.loop.operands[1].op_type.signed):
-            raise RuntimeError('LOOP instruction from instructions file is not '
-                               'the shape expected by the Loop generator.')
+            raise RuntimeError('LOOP instruction from instructions file is '
+                               'not the shape expected by the Loop generator.')
 
         # loopi expects operands: iterations, bodysize
         if not (len(self.loopi.operands) == 2 and
@@ -55,8 +55,8 @@
                 not self.loopi.operands[0].op_type.signed and
                 isinstance(self.loopi.operands[1].op_type, ImmOperandType) and
                 not self.loopi.operands[1].op_type.signed):
-            raise RuntimeError('LOOPI instruction from instructions file is not '
-                               'the shape expected by the Loop generator.')
+            raise RuntimeError('LOOPI instruction from instructions file is '
+                               'not the shape expected by the Loop generator.')
 
         self.loopi_prob = 0.5
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/misaligned_load_store.py b/hw/ip/otbn/dv/rig/rig/gens/misaligned_load_store.py
index 642928a..dadf74b 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/misaligned_load_store.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/misaligned_load_store.py
@@ -69,16 +69,17 @@
         if len(self.bnlid.operands) != 5:
             raise RuntimeError('Unexpected number of operands for bn.lid')
 
-        if not (isinstance(self.bnlid.operands[0].op_type, RegOperandType) and
-                (self.bnlid.operands[0].op_type.reg_type == 'gpr' and
-                not self.bnlid.operands[0].op_type.is_dest() and
-                isinstance(self.bnlid.operands[1].op_type, RegOperandType) and
-                self.bnlid.operands[1].op_type.reg_type == 'gpr' and
-                not self.bnlid.operands[1].op_type.is_dest() and
-                isinstance(self.bnlid.operands[2].op_type, ImmOperandType) and
-                self.bnlid.operands[2].op_type.signed and
-                isinstance(self.bnlid.operands[3].op_type, OptionOperandType) and
-                isinstance(self.bnlid.operands[4].op_type, OptionOperandType))):
+        ops = self.bnlid.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                (ops[0].op_type.reg_type == 'gpr' and
+                not ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'gpr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, ImmOperandType) and
+                ops[2].op_type.signed and
+                isinstance(ops[3].op_type, OptionOperandType) and
+                isinstance(ops[4].op_type, OptionOperandType))):
             raise RuntimeError('BN.LID instruction from instructions file is '
                                'not the shape expected by the BadLoadStore'
                                'generator.')
@@ -91,17 +92,18 @@
         if len(self.bnsid.operands) != 5:
             raise RuntimeError('Unexpected number of operands for bn.sid')
 
-        if not (isinstance(self.bnsid.operands[0].op_type, RegOperandType) and
-                self.bnsid.operands[0].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[0].op_type.is_dest() and
-                isinstance(self.bnsid.operands[1].op_type, RegOperandType) and
-                self.bnsid.operands[1].op_type.reg_type == 'gpr' and
-                not self.bnsid.operands[1].op_type.is_dest() and
-                isinstance(self.bnsid.operands[2].op_type, ImmOperandType) and
-                self.bnsid.operands[2].op_type.signed and
-                isinstance(self.bnsid.operands[3].op_type, OptionOperandType) and
-                isinstance(self.bnsid.operands[4].op_type, OptionOperandType)):
-            raise RuntimeError('BN.LID instruction from instructions file is '
+        ops = self.bnsid.operands
+        if not (isinstance(ops[0].op_type, RegOperandType) and
+                ops[0].op_type.reg_type == 'gpr' and
+                not ops[0].op_type.is_dest() and
+                isinstance(ops[1].op_type, RegOperandType) and
+                ops[1].op_type.reg_type == 'gpr' and
+                not ops[1].op_type.is_dest() and
+                isinstance(ops[2].op_type, ImmOperandType) and
+                ops[2].op_type.signed and
+                isinstance(ops[3].op_type, OptionOperandType) and
+                isinstance(ops[4].op_type, OptionOperandType)):
+            raise RuntimeError('BN.SID instruction from instructions file is '
                                'not the shape expected by the BadLoadStore'
                                'generator.')
 
@@ -182,7 +184,8 @@
         # We always have x0 as an eligible register for misaligned load/stores
         assert base
 
-        # Pick a random register among known registers that is constrained above
+        # Pick a random register among known registers that is constrained
+        # above
         idx, value = random.choice(base)
 
         op_val_grs1 = idx
@@ -204,8 +207,8 @@
         assert offset_val is not None
 
         if insn.mnemonic == 'lw':
-            # Pick grd randomly. Since we can write to any register (including x0)
-            # this should always succeed.
+            # Pick grd randomly. Since we can write to any register (including
+            # x0) this should always succeed.
             op_val_grd = model.pick_operand_value(grd_op_type)
             assert op_val_grd is not None
 
@@ -266,16 +269,17 @@
         assert op_val_grs1 is not None
 
         if insn.mnemonic == 'bn.lid':
-            # Pick grd randomly. Since we can write to any register (including x0)
-            # this should always succeed.
-            op_val_grd = model.pick_operand_value(self.bnlid.operands[0].op_type)
+            # Pick grd randomly. Since we can write to any register (including
+            # x0) this should always succeed.
+            op_val_grd = model.pick_operand_value(insn.operands[0].op_type)
             assert op_val_grd is not None
 
             op_val = [op_val_grd, op_val_grs1, bn_offset_val, 0, 0]
 
         elif insn.mnemonic == 'bn.sid':
             # Any known register is okay for grs2 operand since it will be
-            # guaranteed to have an out of bounds address to store the value from.
+            # guaranteed to have an out of bounds address to store the value
+            # from.
             op_val_grs2 = random.choice(known_regs)[0]
             assert op_val_grs2 is not None
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/small_val.py b/hw/ip/otbn/dv/rig/rig/gens/small_val.py
index 732337c..210ccd7 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/small_val.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/small_val.py
@@ -39,7 +39,7 @@
                 self.insn.operands[1].op_type.reg_type == 'gpr' and
                 isinstance(self.insn.operands[2].op_type, ImmOperandType) and
                 self.insn.operands[2].op_type.signed):
-            raise RuntimeError('ADDI instruction from instructions file is not '
+            raise RuntimeError('ADDI instruction from instructions file not '
                                'the shape expected by the SmallVal generator.')
 
         self.grd_op_type = self.insn.operands[0].op_type
diff --git a/hw/ip/otbn/dv/rig/rig/gens/straight_line_insn.py b/hw/ip/otbn/dv/rig/rig/gens/straight_line_insn.py
index 22864e8..36ccd72 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/straight_line_insn.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/straight_line_insn.py
@@ -424,7 +424,8 @@
                                        type(tgt_op.op_type).__name__))
 
         # We have a list of register operands, together with their types. Get a
-        # list of registers with known values for each register type we've seen.
+        # list of registers with known values for each register type we've
+        # seen.
         known_regs_by_type = {rtype: model.regs_with_known_vals(rtype)
                               for rtype in lsu_reg_types}
 
diff --git a/hw/ip/otbn/dv/rig/rig/gens/untaken_branch.py b/hw/ip/otbn/dv/rig/rig/gens/untaken_branch.py
index eaedb01..a4e4a9f 100644
--- a/hw/ip/otbn/dv/rig/rig/gens/untaken_branch.py
+++ b/hw/ip/otbn/dv/rig/rig/gens/untaken_branch.py
@@ -49,8 +49,8 @@
             if not bne_weight:
                 return None
 
-        # Generates instructions having registers with unequal values for beq and
-        # registers with equal values for bne.
+        # Generates instructions having registers with unequal values for beq
+        # and registers with equal values for bne.
         grs2_choices = not_equals if chosen_insn.mnemonic == 'beq' else equals
         assert grs2_choices
 
@@ -63,4 +63,3 @@
                         prog_insn: ProgInsn) -> None:
         model.update_for_insn(prog_insn)
         model.pc += 4
-
diff --git a/hw/ip/otbn/dv/rig/rig/init_data.py b/hw/ip/otbn/dv/rig/rig/init_data.py
index f77e9a4..4088420 100644
--- a/hw/ip/otbn/dv/rig/rig/init_data.py
+++ b/hw/ip/otbn/dv/rig/rig/init_data.py
@@ -89,8 +89,9 @@
     def gen(dmem_size: int) -> 'InitData':
         '''Generate some initialised data
 
-        This will be inserted into the program as initialised data (pre-loaded).
-        The dictionary maps (word-aligned) byte addresses to u32 values.
+        This will be inserted into the program as initialised data
+        (pre-loaded). The dictionary maps (word-aligned) byte addresses to u32
+        values.
 
         '''
         assert dmem_size > 0
diff --git a/hw/ip/otbn/dv/rig/rig/known_mem.py b/hw/ip/otbn/dv/rig/rig/known_mem.py
index c0338c3..31d46d8 100644
--- a/hw/ip/otbn/dv/rig/rig/known_mem.py
+++ b/hw/ip/otbn/dv/rig/rig/known_mem.py
@@ -123,7 +123,8 @@
 
         # Are we just above it?
         if addr == left_hi:
-            # If there is no range above, we can just extend the last range by one.
+            # If there is no range above, we can just extend the last range by
+            # one.
             if first_idx_above is None:
                 self.known_ranges = left + [(left_lo, left_hi + 1)]
                 return
@@ -239,8 +240,9 @@
         if ibase_addr % gcd:
             return None
 
-        # If gcd divides ibase_addr, we convert x0 and y0 to an initial solution
-        # (i0, j0) as described above by multiplying up by ibase_addr / gcd.
+        # If gcd divides ibase_addr, we convert x0 and y0 to an initial
+        # solution (i0, j0) as described above by multiplying up by ibase_addr
+        # / gcd.
         #
         # Note: the floor divisions below for scale_factor, minus_u and v are
         # actually exact
diff --git a/hw/ip/otbn/dv/rig/rig/model.py b/hw/ip/otbn/dv/rig/rig/model.py
index f6b6cd4..f2ee23e 100644
--- a/hw/ip/otbn/dv/rig/rig/model.py
+++ b/hw/ip/otbn/dv/rig/rig/model.py
@@ -674,7 +674,8 @@
                             for idx, value in indices
                             if value % base_align == 0]
 
-            # If there are no known aligned indices for this operand, give up now.
+            # If there are no known aligned indices for this operand, give up
+            # now.
             if not aligned_regs:
                 return None
 
@@ -758,8 +759,9 @@
         if src_val is None:
             result = None
         else:
-            # op_vals[2] is the immediate, but is already "encoded" as an unsigned
-            # value. Turn it back into the signed operand that actually gets added.
+            # op_vals[2] is the immediate, but is already "encoded" as an
+            # unsigned value. Turn it back into the signed operand that
+            # actually gets added.
             imm_op = insn.operands[2]
             imm_val = imm_op.op_type.enc_val_to_op_val(op_vals[2], self.pc)
             assert imm_val is not None
diff --git a/hw/ip/otbn/dv/rig/rig/program.py b/hw/ip/otbn/dv/rig/rig/program.py
index 2d27267..870eddc 100644
--- a/hw/ip/otbn/dv/rig/rig/program.py
+++ b/hw/ip/otbn/dv/rig/rig/program.py
@@ -340,12 +340,13 @@
 
         seg_descs = []
         for idx, (addr, values) in enumerate(sorted(dsegs.items())):
+            top_addr = addr + 4 * len(values) - 1
             seg_descs.append(('dseg{:04}'.format(idx),
                               addr,
                               addr + self.dmem_lma,
                               '.data.sec{:04}'.format(idx),
                               ('/* Data section {} ({:#06x}-{:#06x}) */'
-                               .format(idx, addr, addr + 4 * len(values) - 1))))
+                               .format(idx, addr, top_addr))))
         for idx, (addr, insns) in enumerate(sorted(self._sections.items())):
             seg_descs.append(('iseg{:04}'.format(idx),
                               addr,
diff --git a/hw/ip/otbn/dv/verilator/run-some.py b/hw/ip/otbn/dv/verilator/run-some.py
index 923a341..13e79dd 100755
--- a/hw/ip/otbn/dv/verilator/run-some.py
+++ b/hw/ip/otbn/dv/verilator/run-some.py
@@ -91,7 +91,8 @@
                  f'  command = fusesoc --cores-root={projdir_from_destdir} '
                  'run --target=sim --setup --build lowrisc:ip:otbn_top_sim '
                  '>fusesoc.log 2>&1\n\n')
-    handle.write('tb = build/lowrisc_ip_otbn_top_sim_0.1/sim-verilator/Votbn_top_sim\n\n')
+    handle.write('tb = build/lowrisc_ip_otbn_top_sim_0.1/'
+                 'sim-verilator/Votbn_top_sim\n\n')
     handle.write('build $tb: fusesoc\n\n')
 
     # Collect up all the generated files
diff --git a/hw/ip/otbn/util/shared/encoding.py b/hw/ip/otbn/util/shared/encoding.py
index 8df48b4..076738e 100644
--- a/hw/ip/otbn/util/shared/encoding.py
+++ b/hw/ip/otbn/util/shared/encoding.py
@@ -66,7 +66,8 @@
         what = 'encoding mapping for instruction {!r}'.format(mnemonic)
 
         # Check we've got exactly the right fields for the scheme
-        ydm = check_keys(yd['mapping'], what, list(scheme_fields.op_fields), [])
+        ydm = check_keys(yd['mapping'], what,
+                         list(scheme_fields.op_fields), [])
 
         # Build a map from operand name to the name of a field that uses it.
         self.op_to_field_name = {}  # type: Dict[str, str]
@@ -80,9 +81,9 @@
                               'encoding for instruction {!r}'
                               .format(field_name, mnemonic))
                 ef_val = check_str(ydm[field_name], field_what)
+                scheme_field = scheme_fields.fields[field_name]
                 field = EncodingField.from_yaml(ef_val,
-                                                scheme_fields.fields[field_name],
-                                                field_what)
+                                                scheme_field, field_what)
 
                 # If the field's value has type str, the field uses an operand
                 # rather than a literal. Check for linearity and store the
@@ -186,8 +187,8 @@
         '''Extract the encoded operand values from an encoded instruction'''
         ret = {}
         for field in self.fields.values():
-            # The operand fields (rather than fixed ones) have the operand name as
-            # their value.
+            # The operand fields (rather than fixed ones) have the operand name
+            # as their value.
             if not isinstance(field.value, str):
                 continue
 
diff --git a/hw/ip/otbn/util/shared/encoding_scheme.py b/hw/ip/otbn/util/shared/encoding_scheme.py
index 7b83c7d..ed2ce7a 100644
--- a/hw/ip/otbn/util/shared/encoding_scheme.py
+++ b/hw/ip/otbn/util/shared/encoding_scheme.py
@@ -7,7 +7,8 @@
 import re
 from typing import Dict, List, Optional, Set
 
-from serialize.parse_helpers import check_keys, check_str, check_list, index_list
+from serialize.parse_helpers import (check_keys,
+                                     check_str, check_list, index_list)
 
 from .bit_ranges import BitRanges
 from .bool_literal import BoolLiteral
@@ -118,7 +119,8 @@
                 field_name = arg_parts[0]
                 field_what = ('literal value for field {!r} when inheriting '
                               'from {!r} in encoding scheme {!r}'
-                              .format(arg_parts[0], self.parent, importer_name))
+                              .format(arg_parts[0],
+                                      self.parent, importer_name))
                 field_value = BoolLiteral.from_string(arg_parts[1], field_what)
 
                 if field_name in self.settings:
diff --git a/hw/ip/otbn/util/shared/lsu_desc.py b/hw/ip/otbn/util/shared/lsu_desc.py
index c9bb7da..b1f5923 100644
--- a/hw/ip/otbn/util/shared/lsu_desc.py
+++ b/hw/ip/otbn/util/shared/lsu_desc.py
@@ -62,7 +62,8 @@
         if lsu_type.startswith('mem-'):
             if 'bytes' not in yd:
                 raise ValueError('{} defines a memory operation, so requires '
-                                 'a bytes field (how many bytes does this touch?)'
+                                 'a bytes field (how many bytes does this '
+                                 'operation touch?)'
                                  .format(what))
             idx_width = check_int(yd['bytes'], 'bytes field for ' + what)
         else:
diff --git a/hw/ip/otbn/util/shared/operand.py b/hw/ip/otbn/util/shared/operand.py
index 1aa085c..e95e1fe 100644
--- a/hw/ip/otbn/util/shared/operand.py
+++ b/hw/ip/otbn/util/shared/operand.py
@@ -358,8 +358,8 @@
         if self.enc_offset:
             acc = '{} + {}'.format(acc, self.enc_offset)
             if shift:
-                # Although a + b << c is logically the same as (a + b) << c, we add
-                # the parentheses to make it easier to read.
+                # Although a + b << c is logically the same as (a + b) << c, we
+                # add the parentheses to make it easier to read.
                 acc = '({}) << {}'.format(acc, self.shift)
                 acc_prec = 0
         else:
@@ -447,7 +447,8 @@
                                      doc_lo, doc_hi))
 
         if self.signed:
-            encoded = (1 << self.width) + offset_val if offset_val < 0 else offset_val
+            encoded = ((1 << self.width) + offset_val
+                       if offset_val < 0 else offset_val)
         else:
             assert offset_val >= 0
             encoded = offset_val
@@ -657,7 +658,8 @@
                              'set, which is only allowed for immediates.'
                              .format(what, fmt))
         reg_type, is_src, is_dest = reg_match
-        return RegOperandType.make(reg_type, is_src, is_dest, what, scheme_field)
+        return RegOperandType.make(reg_type, is_src, is_dest,
+                                   what, scheme_field)
 
     # CSR and WSR indices. These are treated like unsigned immediates, with
     # width 12 and 8, respectively.
@@ -680,13 +682,14 @@
         # where BASE is 'simm' or 'uimm', WIDTH is a positive integer and
         # ENC_OFFSET and SHIFT are non-negative integers. The regex below
         # captures WIDTH as group 1, OFFSET as group 2 and SHIFT as group 3.
-        m = re.match(base + r'([1-9][0-9]*)?(?:\+([0-9]+))?(?:<<([0-9]+))?$', fmt)
+        m = re.match(base + r'([1-9][0-9]*)?(?:\+([0-9]+))?(?:<<([0-9]+))?$',
+                     fmt)
         if m is not None:
             width = int(m.group(1)) if m.group(1) is not None else None
             enc_offset = int(m.group(2)) if m.group(2) is not None else 0
             shift = int(m.group(3)) if m.group(3) is not None else 0
-            return ImmOperandType.make(width, enc_offset, shift, signed, pc_rel,
-                                       what, scheme_field)
+            return ImmOperandType.make(width, enc_offset, shift,
+                                       signed, pc_rel, what, scheme_field)
 
     m = re.match(r'enum\(([^\)]+)\)$', fmt)
     if m:
diff --git a/hw/ip/otbn/util/shared/toolchain.py b/hw/ip/otbn/util/shared/toolchain.py
index 2da21c9..1aeb550 100644
--- a/hw/ip/otbn/util/shared/toolchain.py
+++ b/hw/ip/otbn/util/shared/toolchain.py
@@ -37,8 +37,8 @@
         tool_path = os.path.join(toolchain_path, 'bin', expanded)
         if not os.path.exists(tool_path):
             raise RuntimeError('No such file: {!r} (derived from the '
-                               'TOOLCHAIN_PATH environment variable when trying '
-                               'to find the {!r} tool).'
+                               'TOOLCHAIN_PATH environment variable when '
+                               'trying to find the {!r} tool).'
                                .format(tool_path, tool_name))
         return tool_path
 
diff --git a/hw/ip/otbn/util/yaml_to_doc.py b/hw/ip/otbn/util/yaml_to_doc.py
index 6ef8bd3..860706e 100755
--- a/hw/ip/otbn/util/yaml_to_doc.py
+++ b/hw/ip/otbn/util/yaml_to_doc.py
@@ -269,7 +269,8 @@
 
     # If this came from the RV32I instruction set, say so.
     if insn.rv32i:
-        parts.append('This instruction is defined in the RV32I instruction set.\n\n')
+        parts.append('This instruction is defined in the '
+                     'RV32I instruction set.\n\n')
 
     # A list of errors that the instruction might cause.
     if insn.errs is not None:
diff --git a/hw/ip/rom_ctrl/dv/env/rom_ctrl_scoreboard.sv b/hw/ip/rom_ctrl/dv/env/rom_ctrl_scoreboard.sv
index abcfd36..2ec9f5d 100644
--- a/hw/ip/rom_ctrl/dv/env/rom_ctrl_scoreboard.sv
+++ b/hw/ip/rom_ctrl/dv/env/rom_ctrl_scoreboard.sv
@@ -166,10 +166,12 @@
   endfunction
 
   virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name);
-    uvm_reg csr;
+    dv_base_reg_block ral_model = cfg.ral_models[ral_name];
+    uvm_reg_addr_t    csr_addr = ral_model.get_word_aligned_addr(item.a_addr);
+    uvm_reg           csr = ral_model.default_map.get_reg_by_offset(csr_addr);
+
     bit     do_read_check   = 1'b1;
     bit     write           = item.is_write();
-    uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr);
 
     bit addr_phase_read   = (!write && channel == AddrChannel);
     bit addr_phase_write  = (write && channel == AddrChannel);
@@ -181,14 +183,13 @@
         check_rom_access(item);
       end
       return;
-    // if access was to a valid csr, get the csr handle
-    end else if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin
-      csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr);
-      `DV_CHECK_NE_FATAL(csr, null)
-    end else begin
-      `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
     end
 
+    // If we get here, then the access was on the register channel. If it was to an invalid CSR,
+    // there's nothing more to do. The base classes should already predict an error response.
+    if (csr == null)
+      return;
+
     // if incoming access is a write to a valid csr, then make updates right away
     if (addr_phase_write) begin
       void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));