[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 |