diff --git a/registers.py b/registers.py index 86d0bba1..0b41219a 100755 --- a/registers.py +++ b/registers.py @@ -213,19 +213,33 @@ def symbols( self ): def columnWidth( self ): """Return the width of the column in boxes.""" - charWidth = .33 + offsetCharWidth = .26 + nameCharWidth = .33 xlen_symbol = sympy.symbols('XLEN') + lengthCharWidth = .22 try: # Pretend XLEN=32. This makes 32-bit registers with just a single # field be wide, while registers with XLEN-32 width be narrow. length = int(self.length().subs(xlen_symbol, 32)) except TypeError: length = 20 + if self.length() == 1: + bitText = f"{self.lowBit}" + else: + # There is no dash in what we're displaying, but we want some space + # for separation between the two values. + bitText = f"{self.highBit} - {self.lowBit}" width = math.ceil(max( + # Minimum length 1, + # Make fields with more bits take up more space visually 1 + math.log(max(length, 0.1), 1.7), - len( str( self.length() )) * charWidth, - len( self.name ) * charWidth)) + # Wide enough to accommodate the string showing the field length + len( str( self.length() )) * lengthCharWidth, + # Wide enough to accommodate the high/low bit strings + len( bitText ) * offsetCharWidth, + # Wide enough to accommodate the name of the field + len( self.name ) * nameCharWidth)) # Make longer widths odd, so we can center the bit. if width > 1 and width % 2 == 0: width += 1 @@ -879,14 +893,26 @@ def write_bytefield_row( fd, fields ): else: headers.append(f.lowBit) else: - assert columnWidth >= 2 - headers.append(f.lowBit) - headers += [""] * (columnWidth - 2) - headers.append(f.highBit) + # If low/high bit need more than 2 characters, place them one in + # from the end so they don't overflow into the neighboring field. + # Really this should be done with right/left alignment, but + # bytefield doesn't seem to support that. + if len(f.lowBit) > 2: + start = ["", f.lowBit] + else: + start = [f.lowBit] + if len(f.highBit) > 2: + end = [f.highBit, ""] + else: + end = [f.highBit] + assert columnWidth >= len(start) + len(end) + headers += start + headers += [""] * (columnWidth - len(start) - len(end)) + headers += end columnOffset += columnWidth # remove whitespace to save space headers = [h.replace(" ", "") for h in headers] - fd.write('(draw-column-headers {:font-size 15 :height 16 :labels [%s]})\n' % " ".join(f'"{h}"' for h in reversed(headers))) + fd.write('(draw-column-headers {:font-size 15 :height 17 :labels [%s]})\n' % " ".join(f'"{h}"' for h in reversed(headers))) for f in fields: fd.write('(draw-box (text "%s" {:font-size 20}) {:span %s})\n' % ( f.name, f.columnWidth() ))