From 96c021c73197e09b39d367030c37ec404df56ed3 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 4 Oct 2015 15:33:44 -0400 Subject: More toys. --- verilog-integer.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 verilog-integer.py (limited to 'verilog-integer.py') diff --git a/verilog-integer.py b/verilog-integer.py new file mode 100644 index 0000000..e9a1ba5 --- /dev/null +++ b/verilog-integer.py @@ -0,0 +1,86 @@ +# Code to parse Verilog's integer constant syntax so that we can +# generate C headers from Verilog constants. +# +# Doesn't attempt to handle the analogue states ("x", "z", "?"). +# +# Reference: http://verilog.renerta.com/source/vrg00020.htm + +class VerilogInteger(object): + + radix = dict(b = 2, o = 8, d = 10, h = 16) + + def __init__(self, input): + head, sep, tail = input.lower().translate(None, " \t_").partition("'") + self.input = input + self.code = tail[0] if tail else None + + if not sep: + self.width = 32 + self.value = int(head) + + elif self.code in self.radix: + self.width = int(head) if head else 32 + self.value = int(tail[1:], self.radix[self.code]) + if self.width <= 0 or self.value < 0: + raise ValueError + + else: + raise ValueError + + if self.width is not None: + mask = (1L << self.width) - 1 + if self.value > mask: + self.value &= mask + elif self.value < -mask: + self.value = -( -self.value & mask) + + @property + def C(self): + if self.code is None: + return str(self.value) + elif self.code == "d": + return "{0:d}".format(self.value) + elif self.code == "o": + return "0{0:0{1}o}".format(self.value, (self.width + 2) / 3) + else: + return "0x{0:0{1}x}".format(self.value, (self.width + 3) / 4) + + @property + def Verilog(self): + if self.code is None: + return str(self.value) + else: + fmt = "x" if self.code == "h" else self.code + return "{0.width}'{0.code}{0.value:{1}}".format(self, fmt) + + +if __name__ == "__main__": + + def show(*args): + print "{:20} | {:20} | {:20}".format(*args) + + show("C", "Verilog", "Input") + show("-" * 20, "-" * 20, "-" * 20) + + def test(x): + v = VerilogInteger(x) + show(v.C, v.Verilog, v.input) + + test("15") + test("'h f") + test("'o 17") + test("'d 15") + test("'b 1111") + test("'b 1_1_1_1") + test("10 'd 20") + test("6'o 71") + test("8'b0") + test("8'b00000000") + test("8'b1") + test("8'b00000001") + + try: + for line in open("/tmp/sample-verilog-numbers"): + test(line.strip()) + except IOError: + pass -- cgit v1.2.3