The log 5. Another method to create the wrapper has successfully implemented the automatic wrapper that I intended to design one year ago. This is a relief, even though for now it forces bit vectors to use the SLV package of wrapper types. This could be solved later and it's not a great problem because the units I test have a fixed size, genericity has gone out of the window since the netlists are synthesised.
Now this forces me to re-architect the whole code because now the wrapper is the top level. The previous choice has been discussed in the log 24. Hierarchy problems and solutions and we're back to the initial version:
The bash script now knows the size of the vectors and can also "plug" the generator or driver but the rest of the code must be turned upside down like a sock. I have to rewrite/restructure the code from scratch, but the modifications are minor.
The new structure has the wrapper containing the "driver" so the wrapper has no I/O ports, which are replaced by internal signals. Another change is that the driver is made of procedures and functions and it would be weird to encapsulate them in another entity. A main procedure with in and out arguments would work better and reduce the semantic complexity : in VHDL a procedure can work like an entity so let's exploit this trick :-) And the procedure can be nicely packaged in a separate library.
Some more typing and I get the following example out of the ALU:
-- Wrapper.vhdl -- Generated on 20200915-07:57 -- Do not modify Library ieee; use ieee.std_logic_1164.all; Library work; use work.all; Library LibreGates; use LibreGates.Gates_lib.all; use LibreGates.Netlist_lib.all; entity Wrapper is generic ( WrapperWidthIn : integer := 22; WrapperWidthOut: integer := 17; main_delay : time := 1 sec; filename : string := ""; -- file of exclude vectors verbose : string := "" ); end Wrapper; architecture Wrap of Wrapper is signal VectIn : std_logic_vector(WrapperWidthIn -1 downto 0); signal VectOut: std_logic_vector(WrapperWidthOut-1 downto 0); signal VectClk: std_logic := 'X'; begin -- force the registration of the gates. -- must be placed at the very beginning! update_select_gate( -- called only once at start 0, -- show gate listing when < 1 -1, -- no alteration 2, -- probe mode verbose, filename); Drive_DUT(VectIn, VectOut, VectClk, main_delay); -- Finally we "wire" the unit to the ports: tb: entity alu8 port map ( cin => VectIn(0), neg => VectIn(1), passmask => VectIn(2), orxor => VectIn(3), rop2mx => VectIn(4), cmps => VectIn(5), sri => VectIn(13 downto 6), snd => VectIn(21 downto 14), rop2 => VectOut(7 downto 0), sum => VectOut(15 downto 8), cout => VectOut(16)); end Wrap;
The line use LibreGates.Gates_lib.all; is required because update_select_gate() is used. Drive_DUT() is defined is defined in the new package Netlist_lib where all the netlist management functions are moved, from Vectgen.vhdl which will soon be obsolete.
So now all the "fun stuff" is going to happen in Netlist_lib.vhdl, in which the size of the vectors is very easy to get, with the 'LENGTH attribute:
package body Netlist_lib is procedure Drive_DUT( signal VectIn : out std_logic_vector; signal VectOut: in std_logic_vector; signal VectClk: inout std_logic; Interval: in time) is begin report "VectIn: " & integer'image(VectIn'length) & ", VectOut: " & integer'image(VectOut'length) & ", CLK: " & std_logic'image(VectClk) ; wait; end Drive_DUT; end Netlist_lib;
There, it's solved. And I can even sense if the clock signal is connected, by setting it to 'X' or 'U' in the wrapper.
Well no, it's not totally and definitively solved because it's a hack and it can't catch the std_logic_vectors. It works but it's not scalable.
Unai did some code at https://github.com/ghdl/ghdl/pull/1449 for his project https://umarcor.github.io/hwstudio/ and there is hope that libghdl will be more and better used in the future. I didn't want to add more languages (and my python version is obsolete) but it's not ruled out. I'm waiting for Unai to progress with his version while I progress on my own code :-)