MyHDL converter nextgen
=======================
[josyb: I suggest to add your name in brackets or possibly your complete comment / addition between brackets - prefixed by your (nick)name and date.]
#### Author: hgomersall
Some thoughts:
##### Interfaces
The way top level interfaces are converted is simple and neat but rather constrained and has some interesting corner cases:
* Multi-level interfaces are not converted, but since they're just python objects, they can be passed in acceptably and then used internally.
* c.f. the above to lists of signals, which are explicitly banned.
* One might want an object to contain signals that are not part of the public interface but be passed in. There is no way of specifying this.
* The naming of top-level interface signals should be user defined, not created algorithmically.
I wonder if there should be an implicit wrapper around the top level entry point to deal with these issues. A munger from whatever is need for V* to whatever is allowed by MyHDL. This would allow a couple of things - much more flexibility in how the top level interface is defined as well as providing a nice route to hierarchical conversions.
Arguably we should be using annotations to add any extra level of capability to the interface stuff. Not sure how exactly to best do that.
#### Author: josyb
- Rewrite *_toVerilog.py* and *_toVHDL.py*
The actual process is too nervous and thus generates the output on the fly. The suggestion is to generate an interim representation first. A following pass will then process this interim representation and generate the actual converted code. Note: part of the refactored conversion code can be common for all current *and future* target languages. The idea is that a new *converter.py* code will only handle parsing the AST and on the second pass call on the target language process who on their turn will call upon the (*new*) objects to help produce the actual target output code (or something along those lines).
- Introduce a MyHDL base type class, to derive the actual new *signal* types from.
#### _**Challenge**_
Not breaking exsiting MyHDL designs. Or write a good _MyHDL1to2.py_?
[josyb 26-10-2019: not breaking existing MyHDL designs is a must-have]
#### Author: NicoPy
Date: 1 October 2019
Here are additional features I think are usefull (I currently use some of them in my version of MyHDL) :
- Ability to tell a signal/port is not used to remove warnings (I currently use a NotUsed() function).
This could allow a better design check when unused signals are propagated in the design.
- Ability to assign attributes to signals/entities (I currently use a Attribute() class for signals).
This is of importance for some attributes (keep, mem_type, async_reg...)
- Always generate the same code :
Today, when using Python 2 or Python 3 before 3.6 (?), each conversion run generates a different VHDL code (because of unsorted dicts ?).
This is a real problem when iterating to fix a conversion bug. Some lines of code you want to check might move in the file.
This is also a problem when using vcs. The file you commit will not be a *reference file*.
I currently alphabetically sort signal declarations, process sensitivity list... It seems to be enough to always get the same converted code.
**[edit 2, 3 October 2019]** This is not enough. Statements inserted in a process to reset signals when *reset* is asserted must be sorted.
- Remove *@always_comb* limitations :
The following constructs do not convert :
```python
@always_comb
def logic() :
sig.next = 12 # No sensitivity list
```
```python
@always_comb
def logic() :
sig2.next = sig1
sig3.next = sig2 # sig2 is input and output
```
- Simplify VHDL conversion by using *process(all)* :
Generated VHDL code is VHDL2008 compliant. This is fine. With VHDL2008 one can write *process(all)* instead of *process(sig1, sig2, sig3...)*
- **[Added on 10 oct 2019]** Add a conversion option to declare all top level signals with types which are declared in a pakage. This is useful when the MyHL code is configurable and the converted code is inserted in a VHDL design.
For example instead of generating this :
```vhdl
entity Example is
port (
i_Clk: in std_logic;
i_Data: in unsigned(10 downto 0);
o_Data: out unsigned(10 downto 0)
);
end entity Example;
```
generate this :
```vhdl
package pck_Example is
type t_i_Clk is std_logic;
type t_i_Data is unsigned (10 downto 0);
type t_o_Data is unsigned (10 downto 0);
end package pck_Example;
entity Example is
port (
i_Clk: in t_i_Clk;
i_Data: in t_i_Data;
o_Data: out t_o_Data
);
end entity Example;
```
This way, the VHDL code using the Example entity can automatically adapt its signals by using *t_i_Clk*, *t_i_Data* and *t_o_Data*.
[josyb 3-10-2019: (with all respect) These are features that are already applicable to the current *upcoming* MyHDL 1.0, as are some of mine.
I created an `Open()` class which comments out all assignments in the generated V\*.
The `Attributes()` class is interesting. I thought about that but didn't get round to try something.
I have switched to Python 3.7 *only*. I think we will no longer support 2.7 starting from MyHDL 1.0]
[josyb 18-10-2019: The optional package is certainly a good idea, however:
- creating new types for atomic types like std_logic doesn't look good IMHO
- It may create conflicts; in a design we will have two modules where one generates a package to define its output types and the second that generates another package that defines it input types. We would get two type definitions with either the same name and arguments which may throw an error, or two type definitions with different names, be it with the same argumenst, which would require extra code to cast the output into the input?]
[NicoPy 19-10-2019: No need to create additionnal modules. Packages can be embedded in the design module. Why two packages ? No need for one package for inputs and one for outputs. A single package is enough. I already do this for lists in top level ports.]
[josyb 20-10-2019: I can see your point in the case of *simple* lists, each module will generate the same type in its associated package, so you can resort to just using one package. I had the more general idea in mind where we create types for (future) structured types. Say we now have three MyHDL modules with the first transforming a certain input type into another output type, the second module transforming that output type into another output type and finally a third transforming that output further into another output type. We then end up with three packages, none of them having all type declarations, and if you use any two packages you will have a conflict of having a double declaration.
Currently *interfaces* have their elements spelled out; I feel that simply enumerating *list of Signals* would be a simpler approach; which incidently also works well for Verilog :)]