Common Python API
Introduction
OpenFASoC generators have a Python script that runs the generator flow (See Generators for more information). Many of the steps in the Python script are common across generators.
A common Python module is exported in ``openfasoc/generators/common/``to reduce code duplication and simplify the creation of new generators. This module exports various functions and constants which may be used in generators.
Importing
Since the common Python module is in the openfasoc/generators/common/
directory, which is a parent directory, the path to this directory must be added using sys.path.append()
.
import sys
sys.path.append(
# This is the relative path to the `openfasoc/generators/common/` directory.
os.path.join(os.path.dirname(__file__), '..', '..')
)
Once the directory is added to the path, the exported modules can be imported using the standard Python import syntax.
from common.verilog_generation import generate_verilog
See Exported Modules for a list of exported modules and their respective functions and constants.
Exported Modules
The top level module common
exports the following submodules.
1. Verilog Generation (common.verilog_generation
)
This module exports functions and constants used in the Verilog generation step. See Temperature Sensor Generator for more about Verilog generation.
This module uses the Mako templating library to convert source Verilog templates into final Verilog files used in the OpenROAD flow.
Functions
generate_verilog(parameters: dict, src_dir: str, out_dir: str) -> None
Reads source Verilog files from
src_dir
and generates output Verilog files for synthesis in the OpenROAD flow. The source files are Mako templates.The
parameters
argument is a dictionary of all the parameters used in the source Verilog Mako templates. Use the${parameter}}
syntax in the source files to insert parameters. For example, the number of inverters in the Temperature Sensor Generator is a parameter.This function maintains the source directory (
src_dir
) structure in the output directory (out_dir
). i.e., source files from a subdirectory of thesrc_dir
will be generated in a subdirectory inout_dir
with the same name.- Arguments:
src_dir
(str): Path to the directory with the source Verilog templates. (default:src/
)out_dir
(str): Path to the directory in which the output will be generated. (default:flow/design/src/
)parameters
(dict): Dictionary of all the parameters used in the Mako templates.
- Example:
generate_verilog( # Generates the output in flow/design/src/ out_dir=os.path.join('flow', 'design', 'src', 'tempsense'), # Sets the parameters used in the design parameters={ "ninv": 6, "nhead": 3, "design_name": "tempsenseInst_error", } )
See the generators’ Python files in
tools/
for more examples.- This function also appends (can be directly used in the source Verilog files) the following Mako defs:
cell(name)
This def returns the name of a standard cell for a given platform. Currently, it only supports the sky130 platform. The naming scheme for sky130 is
${cell_prefix}${name}${cell_suffix}
.Here
name
is an argument passed to thecell()
def, andcell_prefix
andcell_suffix
are set in theparameters
argument passed to thegenerate_verilog()
function.For example, an inverter cell can be inserted using the syntax
${cell('inv')}
. If the prefix issky130_fd_sc_hd__
(sky130hd) and the suffix is_1
, the cell will be replaced withsky130_fd_sc_hd__inv_1
. The same statement will be replaced withsky130_fd_sc_hs__inv_1
for the sky130hs platform.Use the constant
COMMON_PLATFORMS_PREFIX_MAP
for mapping a sky130 platform to its platform.
Constants
COMMON_PLATFORMS_PREFIX_MAP
This is a dictionary of common platforms (currently sky130) and their cell naming prefixes. See the
cell()
def in thegenerate_verilog()
function for more information on how to use it.
2. Simulation (common.simulation
)
This module exports functions used to simulate SPICE testbenches with multiple parameters.
This module supports the use of Mako templating library to insert parameters into SPICE templates.
Functions
run_simulations(parameters: dict, platform: str, simulation_dir: str, template_path: str, runs_dir: str, sim_tool: str, num_concurrent_sims: int, netlist_path: str) -> int
Generates configurations of all combinations of the given
parameters
and runs simulations for each case. The testbench SPICE file, configuration parameters, and the ouptut for each run are generated in{simulation_dir}/{runs_dir}
.The testbench SPICE file given by
template_path
follows the Mako templating syntax. Use the${parameter}
syntax for inserting parameters in the file. The following parameters are automatically inserted during each run.run_number
(int): The number/index of the run/configuration.sim_tool
(str): Command for the simulation tool used.platform
(str): The platform/PDK.template
(str): Path to the SPICE testbench template.netlist_path
(str): Absolute path to the SPICE netlist of the design to be simulated.
- Example SPICE template: (From the Temperature Sensor Generator)
.lib '${model_file}' ${model_corner} .include '${netlist_path}' .param temp_var = ${temp} .param vvdd = 1.8 .param sim_end = '800m/exp(0.04*temp_var)'
Each configuration is run/simulated in a directory in the
runs_dir
. Each run directory contains the final SPICE testbench with the parameters inserted, aparameters.txt
file containing the values of each parameter, and the output log file.parameters
is a dict with keys corresponding to the parameter’s name and the values of one of the following types.1. A constant value. The value of this parameter will be the same for every configuration/run.
{'param': 'value'}
2. Array of integer/float/string constants. Each of the values in the array will be swept.
{'param': [1, 2, 3, 8]} # OR { 'param': { 'values': [1, 2, 3, 8] } }
3. Increments. All values starting from
start
(included) and ending atend
(included if it isstart + n * step
) will be swept with a step ofstep
. The default value forstep
is1
.{'param': { 'start': 10, 'end': 50, 'step': 10 }} # param will take values 10, 20, 30, 40, 50
- Example parameters:
# Runs 10 total simulations # Sweeps through all temperatures from 10 to 100 (both included) with increments of 10. example1 = { 'temp': {'start': 10, 'end': 100, 'step': 10} } # Runs 9 total simulations # Sweeps through all the 3 input voltages as well as all the 3 temperatures example2 = { 'input_voltage': [1, 2, 3], 'temp': [20, 30, 40] } # Runs 4 total simulations # Duty cycle and aux_spice_path remain the same in all simulations # input_voltage is swept example3 = { 'duty_cycle': 10, 'aux_spice_path': 'auxcell.cdl', 'input_voltage': [1, 2, 3] }
See the generators’ Python files in
tools/
for more examples.- Arguments:
parameters
(dict): Dictionary of parameters. Explained above.platform
(str): Platform/PDK. (eg:sky130hd`
)simulation_dir
(str): Path to the directory where the simulation source files are placed and the outputs will be generated. (Default:simulations
)template_path
(str): Path to the SPICE template file for the testbench. (Default:templates/template.sp
)runs_dir
(str): Path to a directory inside thesimulation_dir
directory where the outputs for the simulations will be generated. (Default:runs
)sim_tool
(str): Command for the simulation tool.ngspice
,xyce
, andfinesim
are supported. (Default:ngspice
)num_concurrent_sims
(int): The maximum number of concurrent simulations. (Default:4
)netlist_path
(str): Path to the SPICE netlist inside thesimulation_dir
of the design to be simulated. (Default:netlist.sp
)
Returns (int): The total number of simulations run.
- Overall example: (From the Temperature Sensor Generator)
run_simulations( parameters={ 'temp': {'start': tempStart, 'end': tempStop, 'step': tempStep}, 'model_file': model_file, 'model_corner': platformConfig['model_corner'], 'nominal_voltage': platformConfig['nominal_voltage'], 'design_name': designName }, platform="sky130hd", simulation_dir="simulations", template_path=os.path.join("templates", f"tempsenseInst_{simTool}.sp"), runs_dir=f"run/prePEX_inv{num_inv}_header{num_header}/", sim_tool=simTool, netlist_path=dstNetlist )