[myhdl-list] MyHDL 0.4 preview
Brought to you by:
jandecaluwe
|
From: Jan D. <ja...@ja...> - 2004-01-27 12:57:30
|
Hi:
MyHDL 0.4 preview
-----------------
I'm preparing a new release of MyHDL. With this release, I will have
implemented all functionality on my personal must-have list.
Therefore, this will be an important release for the future of
MyHDL. With the new functionality, I hope that the interest will
increase substantially, including developer interest.
To maximize the release quality, I would like to give a preview
through this channel, and I welcome any feedback, suggestions, or
questions. The implementation is basically ready, so I feel confident
to do this now as I'm working on the documentation. I will try to
explain the new functionality clearly and concisely.
New functionality description and rationale
-------------------------------------------
Basically, MyHDL 0.4 provides a path to automatic implementation
(synthesis) through conversion to Verilog. In the following, I will
refer to the corresponding source code as "synthesizable code".
In a typical design project, the amount of synthesizable code is
only a small fraction all source code: the larger part will consist of
high-level models, project maintenance and automation code, and
verification related code such as test benches.
Still, synthesizable code is of special importance in several
ways. First, the implementation is what counts in the end. Secondly,
synthesizable code has important restrictions and a different concept
of Quality of Results. Finally, synthesizable code is what many
designers like to do most and first (regardless of whether this is a
good idea from a methodology viewpoint).
MyHDL aims to be a complete solution, but at this point a MyHDL user
would have to translate "synthesizable" code manually to Verilog or
VHDL. Needless to say, this is very inconvenient, and probably
unacceptable to most designers.
In summary: even though the true advantages of MyHDL are to be found
in the high-level and verification-related tasks of a design project,
I believe that a path to automated implementation is essential to
convince more designers to give it a try.
Solution description
--------------------
The conversion does not start from source files, but from a design
that has been "elaborated" by the Python interpreter. This has
important advantages. First, there are no restrictions on how to
describe structure, as all "structural" constructs and parameters are
processed before the conversion starts. Second, the work of the Python
interpreter is "reused". The converter uses the Python profiler to
track the interpreter's operation and to infer the design structure
and name spaces. It then selectively compiles pieces of source code
for additional analysis and for conversion. This is done using the
Python compiler package.
The converter infers the Verilog module interface and bit widths from
the constructors and usage of the Signals. The design hierarchy can
be arbitrarily deep, but the converted Verilog design will be a flat
"net list of blocks". The converter maps generators to initial or
always blocks. To support function calls with various parameters, it
generates a unique Verilog function or task per call.
Unsurprisingly, not all Python code can be converted into Verilog. In
fact, there are very important restrictions. As the goal of the
conversion functionality is implementation, this should not be a big
issue: anyone familiar with synthesis is used to similar restrictions
in the "synthesizable subset" of Verilog and VHDL. The implementation
attempts to issue clear error messages when it encounters a construct
that cannot be converted. Details about the convertible subset follow
further.
The convertible "subset"
------------------------
In practice, the "synthesizable subset" usually refers to RTL
synthesis, which is by far the most popular type of synthesis
today. There are industry standards that define the RTL synthesis
subset. However, those were not used as a model for the restrictions
of the MyHDL converter, but as a minimal starting point. On that
basis, whenever it was judged easy or useful to support an additional
feature, this was done. For example, it is actually easier to convert
while loops than for loops even though they are not RTL-synthesizable.
As another example, 'print' is supported because it's so useful for
debugging, even though it's not synthesizable. In summary, the
convertible subset is a superset of the standard RTL synthesis subset,
and supports synthesis tools with more advanced capabilities, such as
behavioral synthesis.
A natural restriction on convertible code is that it should be
written in MyHDL style: cooperating generators, communicating through
signals, and with yield statements specifying wait points and resume
conditions. Supported resume conditions are a signal edge, a signal
change, or a tuple of such conditions.
The most important restriction regards object types. Verilog is an
almost typeless language, while Python is strongly (albeit
dynamically) typed. The converter needs to infer the types of
variables and map them to Verilog types. Therefore, it does type
inferencing of object constructors and expressions. Python int/long's
are mapped to Verilog integers. All other supported types are mapped
to Verilog regs (or wires), and therefore need to have a defined bit
width. The supported types are the Python bool type, the MyHDL intbv
type, and MyHDL enumeration types returned by function enum. The
latter types can also be used as the base value type of a
signal. intbv instances need to be constructed so that a bit width can
be inferred.
Recall that any restrictions only apply to the design post
elaboration. In practice, this means that they apply only to the code
of the generators, that are the "leaf" functional blocks in a MyHDL
design.
Optimizations
-------------
To make the conversion solution more attractive, some optimizations
were put in.
In Verilog and VHDL, case statements are often used to describe finite
state machines efficiently. Python doesn't have a case statement, but
the converter recognizes particular if-then-else structures and maps
them to case statements. This optimization occurs when a variable
whose type is an enumerated type is sequentially tested against
enumeration items in an if-then-else structure. Also, the appropriate
synthesis pragmas for efficient synthesis are generated in the Verilog
code.
As a further optimization, function enum was enhanced to support
alternative encoding schemes elegantly, using an additional parameter
'encoding'. For example:
t_State = enum("START", "RUN", "STOP", encoding='one_hot')
The default encoding is binary; other possibilities are one_hot and
one_cold. This parameter only affects the conversion output, not the
behavior of the type. Verilog case statements are optimized for an
efficient implementation according to the encoding. Note that in
contrast, a Verilog designer needs to make nontrivial code changes to
implement a different encoding scheme.
Usage example
-------------
We will illustrate the conversion usage with a small example with no
hierarchy. (As pointed out, the design hierarchy can in fact be
arbitrarily deep).
Consider the following MyHDL model of an incrementer:
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
"""
while 1:
yield posedge(clock), negedge(reset)
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = (count + 1) % n
Normally, to simulate it, we would "elaborate" an instance
as follows:
m = 8
n = 2 ** m
count = Signal(intbv(0)[m:])
enable, clock, reset = [Signal(bool()) for i in range(3)]
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 a Verilog module that is supposed to have
identical behavior. In addition, a test bench is generated, so that
the MyHDL cosimulation interface can be used to verify the Verilog
model against the MyHDL model. This is, of course, how I have been
verifying the Verilog converter.
For the example, the generated Verilog module is 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
Conclusion
----------
With release 0,4, MyHDL users will have a path to automated
implementation, by code conversion to Verilog.
--
Jan Decaluwe - Resources bvba - http://jandecaluwe.com
Losbergenlaan 16, B-3010 Leuven, Belgium
Bored with EDA the way it is? Check this:
http://jandecaluwe.com/Tools/MyHDL/Overview.html
|