MyHDL provides a way to include user-defined Verilog code during the conversion process.
MyHDL defines a hook that is understood by the converter but ignored by
the simulator. The hook is called __verilog__. It operates
like a special return value. When a MyHDL function defines
__verilog__, the Verilog converter will use its value instead of the
regular return value.
The value of __verilog__ should be a format string that uses keys in
its format specifiers. The keys refer to the variable names in the
context of the string.
Example:
def inc_comb(nextCount, count, n):
@always_comb
def logic():
# note: '-' instead of '+'
nextCount.next = (count - 1) % n
nextCount.driven = "wire"
__verilog__ =\
"""
assign %(nextCount)s = (%(count)s + 1) %% %(n)s;
"""
return logic
The converted code looks as follows:
module inc_comb (
nextCount,
count
);
output [7:0] nextCount;
wire [7:0] nextCount;
input [7:0] count;
assign nextCount = (count + 1) % 128;
endmodule
In this example, conversion of the inc_comb function is bypassed and the user-defined Verilog code is inserted instead. Note that the user-defined code refers to signals and parameters in the MyHDL context by using format specifiers. During conversion, the appropriate hierarchical names and parameter values will be filled in. Note also that the format specifier indicator % needs to be escaped (by doubling it) if it is required in the user-defined code.
There is one more issue that needs user attention. Normally, the
Verilog converter infers inputs, internal signals, and outputs. It
also detects undriven and multiple driven signals. To do this, it
assumes that signals are not driven by default. It then processes the
code to find out which signals are driven from where. However, it
cannot do this for user-defined code. Without additional help, this
will result in warnings or errors during the inference process, or in
compilation errors from invalid Verilog code. The user should solve
this by setting the driven attribute for signals that are driven from
the user-defined code. In the example code above, note the following
assignment:
nextCount.driven = "wire"
This specifies that the nextCount signal is driven as a Verilog wire
from this module. The allowed values of the driven attribute are
'wire' and 'reg'. The value specifies how the
user-defined Verilog code drives the signal in Verilog. To decide
which value to use, consider how the signal should be declared in
Verilog after the user-defined code is inserted.
About this document