It’s Saturday night and I have been cleaning up my github repos. And I found this old defunct project I wrote few years ago. So, I thought to write this post about it.

This is a quick prototype for Python Hardware Description Language(Ironically, Named PHDL). Basically, I wanted to figure out semantics to specify verilog design programmatically. I started with defining components I need to generate a module. The snippet below shows Port and Parameter. I am using python templates to generate fragments of texts after full tree is build.

I used the most confusing variable names. Don’t mind me. That’s just me committing python war crimes.


class Port(Signal):
    def __init__(self,direction, *args):
        Signal.__init__(self, *args)      
        self.direction      = direction

    def render(self):
        pdims = "".join([f"[{p.MSB}:{p.LSB}]" for p in self.pdims])
        updims = "".join([f"[{p.MSB}:{p.LSB}]" for p in self.updims])
        txt = f"{self.direction} {self.type_} {pdims} {self.name} {updims}"
        return txt

class Parameter():
    def __init__(self, name="", type_ = "", value=None, **kargs):
        self.name       = name
        self.type_      = type_
        self.value      = value

    def render(self):
        txt = f"parameter {self.name} {self.type_}" + (f"= {self.value}" if self.value else "")
        return txt

400 lines later, I had the infra done to specify simple modules and instance as follows


import  verilog as verilog

m = verilog.Module(name="top")
m.ports.append(verilog.Port("input","p1", "logic",[verilog.Dimension(0,3)]))
m.ports.append(verilog.Port("input","p2", "logic",[verilog.Dimension(0,3)]))
m.params.append(verilog.Parameter("pr1",value=3))
m.items.append(verilog.Instance(name="u_controller", 
        module="controller",
        params_override=[("ff",3)],
        ports_conn=[("ff",3)]
        ))
print(m.render())

And the output generated as follows. I know. Not great but not terrible.

        module #(parameter pr1 = 3) top (input logic [0:3] p1 ,input logic [0:3] p2 );
        controller #( .ff(3) ) u_controller(.ff(3));
        endmodule