MEP | 107 |
Author | Christopher Felton |
Status | Draft |
Created | 19-Jan-2012 |
MyHDL-version | 0.9 |
Introduction
An interface is an object passed as a port to a MyHDL module and has one or more Signal objects as attributes.
The following is a proposal to add conversion support for attributes that are a Signal type. In this MEP a collection of attributes that are a type Signal will be referred to as an interface. Attributes are anything to the right of the "dot" in an expression.
This proposal is to add unique name creation for attributes in the converted code (when the attribute is a convertible type). It is important to state that using attributes is fully support in MyHDL 0.7 for modeling and simulation except when used in the sensitivity list as discussed in the mailing-list.
For more information on Python classes and attributes see the following 1
The rest of this enhancement proposal will outline the addition of attributes to the MyHDL convertible subset of the Python programming language. Through the rest of this document the term "interface(s)" will be used to refer to attributes of a convertible type.
Name Expansion
The desired approach is to generate a unique name for a Signal that is part of an interface. If an expression includes an interface a unique net name will be generated for the Signal, example:
myobj.x.next = yourobj.y + silly.samsobj.z
The conversion utilities would determine if the type referenced is a Signal and then create a unique name for the Signal. The following is an example of the name expansion:
myobj_x = yourobj_y + silly_samsobj_z
The converter will simply use the interface's reference name as part of the net name. The same rules that apply to the hierarchy naming will be included. The above might be convert to something like the following to avoid name collision:
mod1i_mod2i_myobj_x = mod1i_mod2i_yourobj_y + mod1i_mod2i_silly_samsobj_z
In other cases a data structure might not contain a Signal but a constant (literal). In this case the conversion method will dig down to find the constant and use the constant value.
Required support:
- Expansion of Signal interface names
- Interfaces as ports, including top-level ports
- Interfaces as sensitivity lists
- Resolution of data in data structures
In general, interfaces can be used, as long as the final referenced object is a convertible type (Signal, int, long, bool, intbv). All of the above is supported for MyHDL modeling in MyHDL 0.7, except for the "interfaces as sensitivity lists" as discussed on the mailing-list.
This feature is similar to the VHDL record and SystemVerilog interfaces. The idea is that signals can be logically grouped. Logically grouping signals is extremely useful in large complex designs.
Conversion Guidelines
-
The attribute referenced is a convertible type
-
Left hand side : Signal of type intbv or bool
-
Right hand side : int, long, bool, intbv or a Signal of type int, long, bool, intbv
-
-
The object being referenced will be represented in the converted code as a long-net-name. Long-net-names are derived by object.attribute path
-
Class path name extension, the name will simply replace the "." in the Python source with an "_" in the target conversion HDL
-
Hierarchy name rules. The same rules that avoid name conflict for local Signals will be used in name extension
Examples
Example 1
from myhdl import * class MyObj(object): def __init__(self): self.x = Signal(intbv(0)[8:]) self.y = Signal(intbv(0)[4:]) self.z = Signal(intbv(0)[9:]) def m_ex1(clk, xyz): @always(clk.posedge) def hdl(): xyz.z.next = xyz.x + xyz.y return hdl clk = Signal(False) xyz = MyObj() toVerilog(m_ex1, clk, xyz) toVHDL(m_ex1, clk, xyz)
Verilog conversion for example 1
// File: m_ex1.v // Generated by MyHDL 0.9dev // Date: Mon Jan 20 20:12:41 2014 `timescale 1ns/10ps module m_ex1 ( clk, xyz_y, xyz_x, xyz_z ); input clk; input [3:0] xyz_y; input [7:0] xyz_x; output [8:0] xyz_z; reg [8:0] xyz_z; always @(posedge clk) begin: M_EX1_HDL xyz_z <= (xyz_x + xyz_y); end endmodule
VHDL conversion for the example 1
-- File: m_ex1.vhd -- Generated by MyHDL 0.9dev -- Date: Mon Jan 20 20:12:41 2014 library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use std.textio.all; use work.pck_myhdl_09.all; entity m_ex1 is port ( clk: in std_logic; xyz_y: in unsigned(3 downto 0); xyz_x: in unsigned(7 downto 0); xyz_z: out unsigned(8 downto 0) ); end entity m_ex1; architecture MyHDL of m_ex1 is begin M_EX1_HDL: process (clk) is begin if rising_edge(clk) then xyz_z <= (resize(xyz_x, 9) + xyz_y); end if; end process M_EX1_HDL; end architecture MyHDL;
Example 2
Embedded memory-mapped buses are common in designs. The following is a simple memory-mapped bus definition and an example of a conversion using the bus. The conversion code is only a snippet of the full converted code, relevant code with the name extension.
class BareBoneBus: def __init__(self): self.wr = Signal(False) self.rd = Signal(False) self.ack = Signal(False) self.rdat = Signal(intbv(0)[8:]) self.wdat = Signal(intbv(0)[8:]) self.addr = Signal(intbv(0)[16:])
Verilog conversion for example 2
always @(posedge clock) begin: M_SIMPLE_GL_RTL if (reset == 1) begin gl_bb_rdat <= 0; leds <= 0; gl_lled <= 0; gl_bb_ack <= 0; end else begin if ((gl_bb_rd && (gl_bb_addr == 0))) begin gl_bb_rdat <= gl_lled; gl_bb_ack <= 1'b1; end else if ((gl_bb_wr && (gl_bb_addr == 0))) begin gl_lled <= gl_bb_wdat; gl_bb_ack <= 1'b1; end else begin gl_bb_ack <= 1'b0; end leds <= gl_lled; end end
VHDL conversion for the example 2
M_SIMPLE_GL_RTL: process (clock) is begin if rising_edge(clock) then if (reset = '1') then gl_bb_rdat <= to_unsigned(0, 8); leds <= to_unsigned(0, 8); gl_lled <= to_unsigned(0, 8); gl_bb_ack <= '0'; else if (bool(gl_bb_rd) and (gl_bb_addr = 0)) then gl_bb_rdat <= gl_lled; gl_bb_ack <= '1'; elsif (bool(gl_bb_wr) and (gl_bb_addr = 0)) then gl_lled <= gl_bb_wdat; gl_bb_ack <= '1'; else gl_bb_ack <= '0'; end if; leds <= gl_lled; end if; end if; end process M_SIMPLE_GL_RTL;
Conclusion
Interfaces provide a powerful method to encapsulate signals and to group signals that are associated. The straight-forward net-name extraction creates a unique net in the lower-level HDLs that can be mapped back to the Signal in a data structure.
Acknowledgments
Keerthan Jaic implemented this MEP (interface conversion) in 0.9, this was no small task! Jan Decaluwe provided feedback that provided clarity and focus.