6.6.1 A small sequential design

Consider the following MyHDL code for an incrementer module:

ACTIVE_LOW, INACTIVE_HIGH = 0, 1

def inc(count, enable, clock, reset, n):
    
    """ Incrementer with enable.
    
    count -- output
    enable -- control input, increment when 1
    clock -- clock input
    reset -- asynchronous reset input
    n -- counter max value
    
    """
    
    @always(clock.posedge, reset.negedge)
    def incProcess():
        if reset == ACTIVE_LOW:
            count.next = 0
        else:
            if enable:
                count.next = (count + 1) % n
                
    return incProcess

In Verilog terminology, function inc corresponds to a module, while the decorated function incProcess roughly corresponds to an always block.

Normally, to simulate the design, we would "elaborate" an instance as follows:

m = 8
n = 2 ** m
 
count = Signal(intbv(0)[m:])
enable = Signal(bool(0))
clock, reset = [Signal(bool()) for i in range(2)]

inc_inst = inc(count, enable, clock, reset, n=n)

inc_inst is an elaborated design instance that can be simulated. To convert it to Verilog, we change the last line as follows:

inc_inst = toVerilog(inc, count, enable, clock, reset, n=n)

Again, this creates an instance that can be simulated, but as a side effect, it also generates an equivalent Verilog module in file inc.v. The Verilog code looks as follows:

module inc_inst (
    count,
    enable,
    clock,
    reset
);

output [7:0] count;
reg [7:0] count;
input enable;
input clock;
input reset;


always @(posedge clock or negedge reset) begin: _MYHDL1_BLOCK
    if ((reset == 0)) begin
        count <= 0;
    end
    else begin
        if (enable) begin
            count <= ((count + 1) % 256);
        end
    end
end

endmodule

You can see the module interface and the always block, as expected from the MyHDL design.

About this document