- Every verilog line should follow a magic comment:
#/
.- Warning: The verilog line must be consistent with python indent
- Warning: No blank spaces are allowed between
#
and/
. Some IDEs (such as pycharm) automatically adds a blank space after#
- Inside a magic comment, the content enclosed by 2 apostrophes are intepreted as python variables. For instance:
#/ LLR_RECV[`h_bit`:`l_bit`] <= 12'b`llr_1`;
- Idealy, PyTV supports all sorts of python expressions between 2 apostrophes. But for safety considerations, we do recommand doing operations outside the apostrophes and write only single python variable between the apostrophes.
- Every definition of a verilog module is written in magic comments and embodied in the definition of a python function.
- The name of the python function must start with
Module
. The function name is formulated asModule_abstract_module_name
. In the current PyTV version, please do not define a normal function whose name start withModule
. Also, the module function definition should be written in a single line. (We prepare to solve these 2 issues in future releases) - Every module function should be decorated with pytv using
@convert
. Please write@convert
only in the line above each module function definition. - The parameters of the python function can be of any data type.
- The function must not have any return value (We will support module functions with return values in future releases).
- -Below is a very short definition of a verilog module using PyTV
@convert def ModuleBasic(p1, p2): #/ module BASIC( if p1 > 0: #/ portBA1, pass if p2 > 0: #/ portBA2, pass #/ ); #/ start of BASIC #/ middle of BASIC #/ end of BASIC #/ endmodule
- The name of the python function must start with
- Module Instantiation with PyTV is done by directly calling the defined module function with the original parameters and extra parameters for ports and inst name (This parameter can be left out with auto-naming).
- Grammar for instantiation:
ModuleYOUR_MODULE_TO_INSTANTIATE (param1 = p1, param2 = p2, paramN = pN, PORTS = PORTS_DICT, INST_NAME = MY_INST_NAME)
. - An example for instantiation:
ModuleMUL(param1 = 1, param2 = 1, paramN = 1, PORTS = ["my_mul_port1", "my_mul_port2", "my_mul_port3"], INST_NAME = "mymul_inst") inst_ports_dict = {'PORT1':'name_port1', 'PORT2':'name_port2'} for i in range (1,5): ModuleBasic(p1=1, p2=1, PORTS=inst_ports_dict) ModuleBasic(p1=rst1, p2=-10, PORTS=["PORTA"]) ModuleBasic(p1=1, p2=1, PORTS=inst_ports_dict)
- Instantiation Constraints:
PORTS
: The function paramPORTS
does not appear in the user's definition of the python function. It's a parameter added to the function by the decoratorpytv
. Unless you are instantiating a top module, you should assign value to this parameter (otherwise you will see warning message). Value assigned to this param can either be a pythonlist
ordict
. It is NOT allowed to assignPORTS
with a string.INST_NAME
: The function paramINST_NAME
is not compulsory. Actually, we recommend the users to uuse automatic inst naming. (If thisINST_NAME
is not assigned a value, pytv will automatically name the instance the module)MODULE_NAME
: The function paramMODULE_NAME
is supported but we strongly recommend the users to avoid using it because its usage may potentially corrupt the naming space in pytv.OUTMODE
: DO NOT pass this argument in normal instantiation. If you want to directly print the module code in the upstream module (rather than save it in a module file), setOUTMODE='PRINT'
.- Before generating instantiation code in the upper module, pytv will check whether the number of ports in the list/dict assigned to
PORTS
matches the ports in the module to be instantiated. If mismatch is found, pytv will throw an exception and terminate code generation. So make sure you have passed correct value toPORTS
. - All parameters should be passed in the keyword argument format, but the order in which you pass the arguments can be switched.
- Default Parameters: verithon 0.3 and later supports default arguments. But you are still required to pass default arguments in keyword argument format if you want to modify their values in a module function call. Again, the order in which you pass the arguments do not matter.
PyTV enables auto naming of modules, module files and instances. Auto-naming is done whenever a module function is called without the argument MODULE_NAME
or INST_NAME
. There are 3 naming modes to choose from (HASH
, MD5_SHORT
, SEQUENTIAL
). SEQUENTIAL
is the most recommended naming mode.
- PyTV provides an api for specifying naming mode:
moduleloader.set_naming_mode("SEQUENTIAL")
- You can also set naming mode by passing args in command line:
--naming_mode "SEQUENTIAL"
- Naming of modules or module files
- Whether to generate new module: Every time a module function is called, pytv reads the python level params and inspects whether the params overlap with some earlier calls. If overlap is found, pytv will not generate a new module file.
- Naming newly generated module: The module name in pytv is formulated as
abstract_module_name + module_identifier
.abstract_module_name
is read from the name of the module function.module_identifier
is auto-generated according to certain rules to distinguish between different modules. InSEQUENTIAL
naming mode,module_identifier
is a 10-digit hexadecimal number. InHASH
mode,module_identifier
is a hash value of the python layer params the module function received. InMD5_SHORT
mode,module_identifier
is a cut MD5 value of the python layer params.
- Naming of instances
- Instances are named according to the module they belong to. To avoid naming conflict across different instances, there is also an instance sequence number included in the instance names.
- The instance name is formulated as:
u_sequence_number_module_name
.
- An example for naming of module and instance.
- pytv line:
ModuleBasic(p1=1, p2=1, PORTS=inst_ports_dict)
- generated module name:
Basic0000000001
- generated module file name:
Basic0000000001.v
- generated instance name:
Basic0000000001 u_0000000002_Basic0000000001
(This is 2nd time that the module function ModuleBasic is called with the same python layer params)
- pytv line:
- Verithon 0.3 and later enable directly outputing your code to the upstream module (rather than only outputing the instantiation code and save the module code in an independent file). The grammar is:
ModuleYOUR_MODULE_TO_PRINT (param1 = p1, param2 = p2, paramN = pN, PORTS = PORTS_DICT, INST_NAME = MY_INST_NAME, OUTMODE='PRINT')
. The grammar for printing the code is identical to the grammar for instantiation, except that you should pass an additionalOUTMODE
argument and set its value to be'PRINT'
. However, this is a recently developed feature and there is some constraints. - Constraints:
- We are not sure whether you can include instantiation in the code that you want to output. This may potentially corrupt the naming space.
- In verithon v0.3, when passing the argument
OUTMODE
, you have to writeOUTMODE
='PRINT'
orOUTMODE="PRINT"
. But you should not write like:flag='PRINT' OUTMODE=flag
.
- An example for verilog code direct output:
ModuleBasic(p1=1, p2=1, PORTS=inst_ports_dict)
ModuleBasic(p1=rst1, p2=-10, PORTS=["PORTA"])
ModuleBasic(p1=1, p2=15, PORTS=inst_ports_dict)
# Direct Output
ModuleMyPrint(p=500,q=600,i=i,OUTMODE = 'PRINT')
In the code above, the call of ModuleMyPrint
is used to directly output the code generated within ModuleMyPrint
. ModuleMyPrint
is a module function decorated with @convert
. Here is its definition:
@convert
def ModuleMyPrint(p,q,i,myQu = QuType(100,200)):
#/ reg [`p`:0] print_port1_`i`;
#/ reg [`q`:0] print_port2_`i`;
#/ reg [`myQu.DWT`:0] print_port_qu_`i`;
pass
The generated verilog code is:
Basic0000000001 u_0000000002_Basic0000000001(.PORT1(name_port1), .PORT2(name_port2));
Basic0000000003 u_0000000001_Basic0000000003(.portBA1(PORTA));
Basic0000000004 u_0000000001_Basic0000000004(.PORT1(name_port1), .PORT2(name_port2));
reg [500:0] print_port1_1;
reg [600:0] print_port2_1;
reg [100:0] print_port_qu_1;
The first 3 lines are from normal instantiation, while the later 3 lines are from direct output.
Verithon provides various api functions for users to manually set naming mode, disenable warning, set save path and view arguments of module functions (params). The api functions are hereby explained in detail:
-
moduleloader.set_naming_mode(YOUR_NAMING_MODE)
- Function: sets the naming mode of instances & modules & module files.
- Argument Type:
string
- Argument Value:
'HASH'
: Uses a hash value as part of the filename (default).'MD5_SHORT'
: Uses a shortened MD5 value as part of the filename.'SEQUENTIAL'
: Uses a sequential number as part of the filename.
'SEQUENTIAL'
naming is recommended.
-
moduleloader.set_root_dir(YOUR_ROOT_DIR)
- Function: sets the path to save the generated RTL files.
- Argument Type:
string
.
-
moduleloader.getParams(YOUR_MODULE_NAME)
- Function: returns the python layer params of a specified module or abstract module
- Argument Type:
string
- Return value: returns a dict if the argument
YOUR_MODULE_NAME
is a specific module name (such asTOP0000000001
), or a list of dict ifYOUR_MODULE_NAME
is an abstract module name (such asTOP
). - Call this function only after the specified module is generated.
- An example for calling
getParams
:The extracted params would be:params_of_basic = moduleloader.getParams("Basic") params_of_mul1 = moduleloader.getParams("MUL0000000001")
Observe that the function returns a list of dict for argumentparams_of_basic = [{'Basic0000000001': {'p1': 1, 'p2': 1}}, {'Basic0000000002': {'p1': 5, 'p2': 6}}, {'Basic0000000003': {'p1': 1, 'p2': -10}}, {'Basic0000000004': {'p1': 1, 'p2': 15}}] params_of_mul1 = {'param1': 29, 'param2': 1, 'paramN': 1, 'Qu_inst': <mycls.QuType object at 0x000001CDE55D0A00>, 'defaultp': 99}
Basic
(an abstract module name) and a dict for argumentMUL0000000001
(a real module name).
-
moduleloader.disEnableWarning()
- Function: Disenable warning messages.
- Argument Type: This function takes no arguments.
- Some critical warnings cannot be disenabled.
We have renamed this package as verithon
. Run the following command to install the latest version:
pip install verithon --upgrade
You should import moduleloader
and convert
when you want to use pytv. You should write:
import pytv
from pytv import convert
from pytv import moduleloader
You can run pytv with the following shell script:
cd "C:\your\path"
python your_pytv_file.py --naming_mode HASH --root_dir "C:\your\root_dir" --disable_warning
Meaning of each command line argument is presented below:
-
--naming_mode
- Meaning: Sets the naming mode for the RTL files.
- Possible Values:
HASH
: Uses a hash value as part of the filename (default).MD5_SHORT
: Uses a shortened MD5 value as part of the filename.SEQUENTIAL
: Uses a sequential number as part of the filename.
-
--root_dir
- Meaning: Specifies the path where RTL files will be saved.
- Possible Values: Any valid folder path. The user must either pass this argument in command line or set moduleloader.root_dir with api functions. Otherwise, exceptions will be raised and RTL code generation will not start.
-
--disable_warning
- Meaning: Indicates whether to disable warnings (if true, pytv will display no warnings).
- Possible Values:
store_true
: If this parameter is present, the warnings will be dis-enabled.- Default is
False
if this parameter is not provided.
If you want to run your pytv file without command line, you can configure root directory, naming, saving and warning settings with api functions of pytv. Examples of usage are presented below:
moduleloader.set_naming_mode("SEQUENTIAL")
moduleloader.set_root_dir("C:\信道编码\SummerSchool\提交")
moduleloader.disEnableWarning()
moduleloader.getParams("MUL0000000001")
Note that these api functions must be called before you call a pytv module function.
- You can find the generated module files in the folder
your_root_dir\\RTL_GEN
. - You can extract param directly in the python level by calling
moduleloader.getParams(YOUR_MODULE_NAME)
. This will return a dict if the argumentYOUR_MODULE_NAME
is a specific module name (such asTOP0000000001
), or return a list of dict ifYOUR_MODULE_NAME
is an abstract module name (such asTOP
). - You can view info and warning messages in the terminal.