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