├── .github └── workflows │ └── python-package-ci.yml ├── .gitignore ├── .isort.cfg ├── .readthedocs.yml ├── .travis.yml ├── LICENSE ├── README.md ├── codecov.yml ├── docs ├── Makefile ├── conf.py ├── index.rst ├── intro │ ├── installation.rst │ └── quickstart.rst ├── ref │ ├── datatypes.rst │ ├── dsl.rst │ ├── passes-import-intro.rst │ ├── passes-import-meta.rst │ ├── passes-placeholder-meta.rst │ ├── passes-sim-api.rst │ ├── passes-trans-import-meta.rst │ ├── passes-translation-intro.rst │ ├── passes-translation-meta.rst │ ├── passes.rst │ ├── primitives.rst │ └── stdlib.rst └── tut │ ├── tut1-gl.rst │ └── tut2-rtl.rst ├── examples ├── __init__.py ├── ex01_basics │ ├── IncrMethodModular_test.py │ ├── IncrMethodPorts_test.py │ ├── IncrPyObjs_test.py │ ├── IncrPyVars_test.py │ ├── IncrValueModular_test.py │ ├── IncrWires_test.py │ ├── __init__.py │ └── incr_test.py ├── ex02_cksum │ ├── ChecksumCL.py │ ├── ChecksumFL.py │ ├── ChecksumRTL.py │ ├── __init__.py │ ├── cksum-translate │ ├── test │ │ ├── ChecksumCL_test.py │ │ ├── ChecksumFL_test.py │ │ ├── ChecksumRTL_test.py │ │ ├── ChecksumVRTL_test.py │ │ ├── __init__.py │ │ └── utils_test.py │ └── utils.py ├── ex03_proc │ ├── MiscRTL.py │ ├── NullXcel.py │ ├── ProcCL.py │ ├── ProcCtrlRTL.py │ ├── ProcDpathRTL.py │ ├── ProcFL.py │ ├── ProcRTL.py │ ├── SparseMemoryImage.py │ ├── TinyRV0InstRTL.py │ ├── __init__.py │ ├── proc-sim │ ├── proc-translate │ ├── test │ │ ├── ProcCL_test.py │ │ ├── ProcFL_test.py │ │ ├── ProcRTL_test.py │ │ ├── ProcVRTL_test.py │ │ ├── __init__.py │ │ ├── harness.py │ │ ├── inst_add.py │ │ ├── inst_addi.py │ │ ├── inst_and.py │ │ ├── inst_bne.py │ │ ├── inst_csr.py │ │ ├── inst_lw.py │ │ ├── inst_sll.py │ │ ├── inst_srl.py │ │ ├── inst_sw.py │ │ ├── inst_utils.py │ │ └── inst_xcel.py │ ├── tinyrv0-isa.md │ ├── tinyrv0_encoding.py │ └── ubmark │ │ ├── __init__.py │ │ ├── proc_ubmark_cksum_blk.py │ │ ├── proc_ubmark_cksum_blk_data.py │ │ ├── proc_ubmark_cksum_roll.py │ │ ├── proc_ubmark_cksum_roll_data.py │ │ ├── proc_ubmark_vvadd_data.py │ │ ├── proc_ubmark_vvadd_opt.py │ │ └── proc_ubmark_vvadd_unopt.py └── ex04_xcel │ ├── ChecksumXcelCL.py │ ├── ChecksumXcelFL.py │ ├── ChecksumXcelRTL.py │ ├── ProcXcel.py │ ├── __init__.py │ ├── proc-xcel-sim │ ├── proc-xcel-translate │ ├── test │ ├── ChecksumXcelCL_test.py │ ├── ChecksumXcelFL_test.py │ ├── ChecksumXcelRTL_test.py │ ├── ChecksumXcelVRTL_test.py │ └── __init__.py │ └── ubmark │ ├── __init__.py │ ├── proc_ubmark_checksum_xcel_single.py │ └── proc_ubmark_cksum_xcel_roll.py ├── pymtl3 ├── __init__.py ├── datatypes │ ├── PythonBits.py │ ├── __init__.py │ ├── bits_import.py │ ├── bitstructs.py │ ├── helpers.py │ ├── strategies.py │ └── test │ │ ├── __init__.py │ │ ├── bits_test.py │ │ ├── bitstructs_test.py │ │ ├── helpers_test.py │ │ └── strategies_test.py ├── dsl │ ├── AstHelper.py │ ├── Component.py │ ├── ComponentLevel1.py │ ├── ComponentLevel2.py │ ├── ComponentLevel3.py │ ├── ComponentLevel4.py │ ├── ComponentLevel5.py │ ├── ComponentLevel6.py │ ├── ComponentLevel7.py │ ├── Connectable.py │ ├── ConstraintTypes.py │ ├── MetadataKey.py │ ├── NamedObject.py │ ├── Placeholder.py │ ├── __init__.py │ ├── errors.py │ └── test │ │ ├── ComponentAPI_test.py │ │ ├── ComponentLevel1_test.py │ │ ├── ComponentLevel2_test.py │ │ ├── ComponentLevel3_test.py │ │ ├── ComponentLevel4_test.py │ │ ├── ComponentLevel5_test.py │ │ ├── ComponentLevel6_test.py │ │ ├── DataStruct_test.py │ │ ├── Interface_test.py │ │ ├── NamedObject_test.py │ │ ├── Placeholder_test.py │ │ ├── PortCheck_test.py │ │ ├── Slicing_test.py │ │ ├── __init__.py │ │ ├── set_param_test.py │ │ └── sim_utils.py ├── examples │ ├── __init__.py │ └── ex00_quickstart │ │ ├── FullAdder.py │ │ ├── RegIncr.py │ │ └── __init__.py ├── extra │ ├── __init__.py │ ├── clone_deepcopy.py │ └── pypy │ │ ├── __init__.py │ │ ├── custom_exec.py │ │ └── fast_bytearray_funcs.py ├── passes │ ├── BasePass.py │ ├── PassConfigs.py │ ├── PassGroups.py │ ├── PlaceholderConfigs.py │ ├── PlaceholderPass.py │ ├── __init__.py │ ├── adhoc_transform │ │ ├── AddDebugSignalPass.py │ │ ├── __init__.py │ │ └── test │ │ │ ├── AddDebugSignalPass_test.py │ │ │ └── __init__.py │ ├── autotick │ │ ├── OpenLoopCLPass.py │ │ ├── __init__.py │ │ └── test │ │ │ ├── OpenLoopCLPass_test.py │ │ │ └── __init__.py │ ├── backends │ │ ├── __init__.py │ │ ├── generic │ │ │ ├── BaseRTLIRTranslator.py │ │ │ ├── README.md │ │ │ ├── RTLIRTranslator.py │ │ │ ├── __init__.py │ │ │ ├── behavioral │ │ │ │ ├── BehavioralTranslatorL0.py │ │ │ │ ├── BehavioralTranslatorL1.py │ │ │ │ ├── BehavioralTranslatorL2.py │ │ │ │ ├── BehavioralTranslatorL3.py │ │ │ │ ├── BehavioralTranslatorL4.py │ │ │ │ ├── BehavioralTranslatorL5.py │ │ │ │ ├── __init__.py │ │ │ │ └── test │ │ │ │ │ ├── BehavioralTranslatorL1_test.py │ │ │ │ │ ├── BehavioralTranslatorL2_test.py │ │ │ │ │ ├── BehavioralTranslatorL3_test.py │ │ │ │ │ ├── BehavioralTranslatorL4_test.py │ │ │ │ │ ├── BehavioralTranslatorL5_test.py │ │ │ │ │ ├── TestBehavioralTranslator.py │ │ │ │ │ └── __init__.py │ │ │ ├── errors.py │ │ │ ├── structural │ │ │ │ ├── StructuralTranslatorL1.py │ │ │ │ ├── StructuralTranslatorL2.py │ │ │ │ ├── StructuralTranslatorL3.py │ │ │ │ ├── StructuralTranslatorL4.py │ │ │ │ ├── __init__.py │ │ │ │ └── test │ │ │ │ │ ├── StructuralTranslatorL1_test.py │ │ │ │ │ ├── StructuralTranslatorL2_test.py │ │ │ │ │ ├── StructuralTranslatorL3_test.py │ │ │ │ │ ├── StructuralTranslatorL4_test.py │ │ │ │ │ ├── TestStructuralTranslator.py │ │ │ │ │ └── __init__.py │ │ │ ├── test │ │ │ │ ├── RTLIRTranslator_L1_cases_test.py │ │ │ │ ├── RTLIRTranslator_L2_cases_test.py │ │ │ │ ├── RTLIRTranslator_L3_cases_test.py │ │ │ │ ├── RTLIRTranslator_L4_cases_test.py │ │ │ │ ├── RTLIRTranslator_L5_cases_test.py │ │ │ │ ├── TestRTLIRTranslator.py │ │ │ │ └── __init__.py │ │ │ └── testcases │ │ │ │ ├── __init__.py │ │ │ │ └── test_cases.py │ │ ├── verilog │ │ │ ├── VerilogPlaceholder.py │ │ │ ├── VerilogPlaceholderConfigs.py │ │ │ ├── VerilogPlaceholderPass.py │ │ │ ├── VerilogTranslationImportPass.py │ │ │ ├── __init__.py │ │ │ ├── errors.py │ │ │ ├── import_ │ │ │ │ ├── VerilogVerilatorImportConfigs.py │ │ │ │ ├── VerilogVerilatorImportPass.py │ │ │ │ ├── __init__.py │ │ │ │ ├── test │ │ │ │ │ ├── ImportedObject_test.py │ │ │ │ │ ├── VAdder.v │ │ │ │ │ ├── VImportSignalGen_test.py │ │ │ │ │ ├── VIncr.v │ │ │ │ │ ├── VNameMangle_test.py │ │ │ │ │ ├── VPassThrough.v │ │ │ │ │ ├── VQueue.v │ │ │ │ │ ├── VReg.v │ │ │ │ │ ├── VRegTrace.v │ │ │ │ │ ├── VUninit.v │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── pymtl.ini │ │ │ │ │ └── trace.v │ │ │ │ ├── verilator_wrapper_c_template.py │ │ │ │ └── verilator_wrapper_py_template.py │ │ │ ├── tbgen │ │ │ │ ├── VerilogTBGenPass.py │ │ │ │ ├── __init__.py │ │ │ │ ├── test │ │ │ │ │ ├── VQueue.v │ │ │ │ │ ├── VerilogTBGenPass_test.py │ │ │ │ │ └── __init__.py │ │ │ │ └── verilog_tbgen_v_template.py │ │ │ ├── test │ │ │ │ ├── TranslationImport_adhoc_gc_test.py │ │ │ │ ├── TranslationImport_adhoc_test.py │ │ │ │ ├── TranslationImport_closed_loop_component_input_test.py │ │ │ │ ├── TranslationImport_closed_loop_component_test.py │ │ │ │ ├── TranslationImport_closed_loop_directed_test.py │ │ │ │ ├── TranslationImport_dynlib_close_test.py │ │ │ │ ├── TranslationImport_stdlib_test.py │ │ │ │ └── __init__.py │ │ │ ├── testcases │ │ │ │ ├── VReg.v │ │ │ │ ├── VRegPassThrough.v │ │ │ │ ├── __init__.py │ │ │ │ └── test_cases.py │ │ │ ├── translation │ │ │ │ ├── VTranslator.py │ │ │ │ ├── VerilogTranslationConfigs.py │ │ │ │ ├── VerilogTranslationPass.py │ │ │ │ ├── __init__.py │ │ │ │ ├── behavioral │ │ │ │ │ ├── VBehavioralTranslatorL0.py │ │ │ │ │ ├── VBehavioralTranslatorL1.py │ │ │ │ │ ├── VBehavioralTranslatorL2.py │ │ │ │ │ ├── VBehavioralTranslatorL3.py │ │ │ │ │ ├── VBehavioralTranslatorL4.py │ │ │ │ │ ├── VBehavioralTranslatorL5.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── test │ │ │ │ │ │ ├── VBehavioralTranslatorL1_test.py │ │ │ │ │ │ ├── VBehavioralTranslatorL2_test.py │ │ │ │ │ │ ├── VBehavioralTranslatorL3_test.py │ │ │ │ │ │ ├── VBehavioralTranslatorL4_test.py │ │ │ │ │ │ ├── VBehavioralTranslatorL5_test.py │ │ │ │ │ │ └── __init__.py │ │ │ │ ├── structural │ │ │ │ │ ├── VStructuralTranslatorL1.py │ │ │ │ │ ├── VStructuralTranslatorL2.py │ │ │ │ │ ├── VStructuralTranslatorL3.py │ │ │ │ │ ├── VStructuralTranslatorL4.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── test │ │ │ │ │ │ ├── VStructuralTranslatorL1_test.py │ │ │ │ │ │ ├── VStructuralTranslatorL2_test.py │ │ │ │ │ │ ├── VStructuralTranslatorL3_test.py │ │ │ │ │ │ ├── VStructuralTranslatorL4_test.py │ │ │ │ │ │ └── __init__.py │ │ │ │ └── test │ │ │ │ │ ├── VTranslator_L1_cases_test.py │ │ │ │ │ ├── VTranslator_L2_cases_test.py │ │ │ │ │ ├── VTranslator_L3_cases_test.py │ │ │ │ │ ├── VTranslator_L4_cases_test.py │ │ │ │ │ └── __init__.py │ │ │ └── util │ │ │ │ ├── __init__.py │ │ │ │ ├── test_utility.py │ │ │ │ └── utility.py │ │ └── yosys │ │ │ ├── YosysTranslationImportPass.py │ │ │ ├── __init__.py │ │ │ ├── import_ │ │ │ ├── YosysVerilatorImportPass.py │ │ │ ├── __init__.py │ │ │ └── test │ │ │ │ ├── ImportedObject_test.py │ │ │ │ ├── VNameMangle_test.py │ │ │ │ └── __init__.py │ │ │ ├── test │ │ │ ├── TranslationImport_adhoc_test.py │ │ │ ├── TranslationImport_closed_loop_component_input_test.py │ │ │ ├── TranslationImport_closed_loop_component_test.py │ │ │ ├── TranslationImport_closed_loop_directed_test.py │ │ │ ├── TranslationImport_stdlib_test.py │ │ │ └── __init__.py │ │ │ ├── testcases │ │ │ ├── __init__.py │ │ │ └── test_cases.py │ │ │ ├── translation │ │ │ ├── YosysTranslationPass.py │ │ │ ├── YosysTranslator.py │ │ │ ├── __init__.py │ │ │ ├── behavioral │ │ │ │ ├── YosysBehavioralTranslatorL1.py │ │ │ │ ├── YosysBehavioralTranslatorL2.py │ │ │ │ ├── YosysBehavioralTranslatorL3.py │ │ │ │ ├── YosysBehavioralTranslatorL4.py │ │ │ │ ├── YosysBehavioralTranslatorL5.py │ │ │ │ ├── __init__.py │ │ │ │ └── test │ │ │ │ │ ├── YosysBehavioralTranslatorL1_test.py │ │ │ │ │ ├── YosysBehavioralTranslatorL2_test.py │ │ │ │ │ ├── YosysBehavioralTranslatorL3_test.py │ │ │ │ │ ├── YosysBehavioralTranslatorL4_test.py │ │ │ │ │ ├── YosysBehavioralTranslatorL5_test.py │ │ │ │ │ └── __init__.py │ │ │ ├── structural │ │ │ │ ├── YosysStructuralTranslatorL1.py │ │ │ │ ├── YosysStructuralTranslatorL2.py │ │ │ │ ├── YosysStructuralTranslatorL3.py │ │ │ │ ├── YosysStructuralTranslatorL4.py │ │ │ │ ├── __init__.py │ │ │ │ └── test │ │ │ │ │ ├── YosysStructuralTranslatorL1_test.py │ │ │ │ │ ├── YosysStructuralTranslatorL2_test.py │ │ │ │ │ ├── YosysStructuralTranslatorL3_test.py │ │ │ │ │ ├── YosysStructuralTranslatorL4_test.py │ │ │ │ │ └── __init__.py │ │ │ └── test │ │ │ │ ├── YosysTranslator_L1_cases_test.py │ │ │ │ ├── YosysTranslator_L2_cases_test.py │ │ │ │ ├── YosysTranslator_L3_cases_test.py │ │ │ │ ├── YosysTranslator_L4_cases_test.py │ │ │ │ └── __init__.py │ │ │ └── util │ │ │ ├── __init__.py │ │ │ └── utility.py │ ├── errors.py │ ├── mamba │ │ ├── HeuristicTopoPass.py │ │ ├── Mamba2020Pass.py │ │ ├── PassGroups.py │ │ ├── UnrollSimPass.py │ │ ├── __init__.py │ │ └── test │ │ │ ├── HeuTopoUnrollSim_test.py │ │ │ ├── Mamba2020Pass_test.py │ │ │ ├── UnrollSim_test.py │ │ │ └── __init__.py │ ├── rtlir │ │ ├── README.md │ │ ├── RTLIRPass.py │ │ ├── __init__.py │ │ ├── behavioral │ │ │ ├── BehavioralRTLIR.asdl │ │ │ ├── BehavioralRTLIR.py │ │ │ ├── BehavioralRTLIRGenL1Pass.py │ │ │ ├── BehavioralRTLIRGenL2Pass.py │ │ │ ├── BehavioralRTLIRGenL3Pass.py │ │ │ ├── BehavioralRTLIRGenL4Pass.py │ │ │ ├── BehavioralRTLIRGenL5Pass.py │ │ │ ├── BehavioralRTLIRImplGen.py │ │ │ ├── BehavioralRTLIRTypeCheckL1Pass.py │ │ │ ├── BehavioralRTLIRTypeCheckL2Pass.py │ │ │ ├── BehavioralRTLIRTypeCheckL3Pass.py │ │ │ ├── BehavioralRTLIRTypeCheckL4Pass.py │ │ │ ├── BehavioralRTLIRTypeCheckL5Pass.py │ │ │ ├── BehavioralRTLIRVisualizationPass.py │ │ │ ├── __init__.py │ │ │ └── test │ │ │ │ ├── BehavioralRTLIRFreeVar_test.py │ │ │ │ ├── BehavioralRTLIRL1Pass_test.py │ │ │ │ ├── BehavioralRTLIRL2Pass_test.py │ │ │ │ ├── BehavioralRTLIRL3Pass_test.py │ │ │ │ ├── BehavioralRTLIRL4Pass_test.py │ │ │ │ ├── BehavioralRTLIRL5Pass_test.py │ │ │ │ ├── BehavioralRTLIRPass_test.py │ │ │ │ ├── BehavioralRTLIRTmpVar_test.py │ │ │ │ └── __init__.py │ │ ├── errors.py │ │ ├── rtype │ │ │ ├── RTLIRDataType.py │ │ │ ├── RTLIRType.py │ │ │ ├── __init__.py │ │ │ └── test │ │ │ │ ├── RTLIRDataType_test.py │ │ │ │ └── RTLIRType_test.py │ │ ├── structural │ │ │ ├── StructuralRTLIRGenL0Pass.py │ │ │ ├── StructuralRTLIRGenL1Pass.py │ │ │ ├── StructuralRTLIRGenL2Pass.py │ │ │ ├── StructuralRTLIRGenL3Pass.py │ │ │ ├── StructuralRTLIRGenL4Pass.py │ │ │ ├── StructuralRTLIRSignalExpr.py │ │ │ ├── __init__.py │ │ │ └── test │ │ │ │ ├── StructuralRTLIRGenL1Pass_test.py │ │ │ │ ├── StructuralRTLIRGenL2Pass_test.py │ │ │ │ ├── StructuralRTLIRGenL3Pass_test.py │ │ │ │ ├── StructuralRTLIRGenL4Pass_test.py │ │ │ │ └── __init__.py │ │ └── util │ │ │ ├── __init__.py │ │ │ ├── test_utility.py │ │ │ └── utility.py │ ├── sim │ │ ├── DynamicSchedulePass.py │ │ ├── GenDAGPass.py │ │ ├── PrepareSimPass.py │ │ ├── SimpleSchedulePass.py │ │ ├── SimpleTickPass.py │ │ ├── WrapGreenletPass.py │ │ ├── __init__.py │ │ └── test │ │ │ ├── DynamicSchedulePass_test.py │ │ │ ├── SimpleSchedulePass_test.py │ │ │ └── __init__.py │ ├── testcases │ │ ├── TestCase.py │ │ ├── __init__.py │ │ └── test_cases.py │ └── tracing │ │ ├── CLLineTracePass.py │ │ ├── LineTraceParamPass.py │ │ ├── PrintTextWavePass.py │ │ ├── VcdGenerationPass.py │ │ ├── __init__.py │ │ └── test │ │ ├── LineTraceParamPass_test.py │ │ ├── PrintTextWavePass_test.py │ │ ├── VcdGenerationPass_test.py │ │ └── __init__.py ├── stdlib │ ├── __init__.py │ ├── basic_rtl │ │ ├── __init__.py │ │ ├── arbiters.py │ │ ├── arithmetics.py │ │ ├── crossbars.py │ │ ├── encoders.py │ │ ├── register_files.py │ │ ├── registers.py │ │ └── test │ │ │ ├── __init__.py │ │ │ ├── arbiters_test.py │ │ │ ├── crossbars_test.py │ │ │ └── encoders_test.py │ ├── connects │ │ ├── __init__.py │ │ ├── connect_bits2bitstruct.py │ │ ├── connect_pairs.py │ │ └── test │ │ │ ├── __init__.py │ │ │ └── connect_bits2bitstruct_test.py │ ├── delays │ │ ├── DelayPipeCL.py │ │ ├── StallCL.py │ │ ├── __init__.py │ │ └── test │ │ │ ├── DelayPipeCL_test.py │ │ │ └── __init__.py │ ├── ifcs │ │ ├── XcelMsg.py │ │ ├── __init__.py │ │ ├── get_give_ifcs.py │ │ ├── master_minion_ifcs.py │ │ ├── send_recv_ifcs.py │ │ ├── test │ │ │ ├── XcelMsg_test.py │ │ │ ├── __init__.py │ │ │ └── xcel_ifcs_test.py │ │ └── xcel_ifcs.py │ ├── mem │ │ ├── MagicMemoryCL.py │ │ ├── MagicMemoryFL.py │ │ ├── MemMsg.py │ │ ├── ROMRTL.py │ │ ├── __init__.py │ │ ├── mem_ifcs.py │ │ └── test │ │ │ ├── MagicMemoryCL_test.py │ │ │ ├── MemMsg_test.py │ │ │ ├── ROMRTL_test.py │ │ │ ├── __init__.py │ │ │ └── mem_ifcs_test.py │ ├── net │ │ ├── __init__.py │ │ └── test │ │ │ └── __init__.py │ ├── proc │ │ ├── SparseMemoryImage.py │ │ ├── __init__.py │ │ ├── elf.py │ │ └── test │ │ │ ├── SparseMemoryImage_test.py │ │ │ ├── __init__.py │ │ │ └── elf_test.py │ ├── queues │ │ ├── __init__.py │ │ ├── cl_queues.py │ │ ├── enq_deq_ifcs.py │ │ ├── enrdy_queues.py │ │ ├── queues.py │ │ ├── test │ │ │ ├── __init__.py │ │ │ ├── cl_queues_test.py │ │ │ ├── enrdy_queues_test.py │ │ │ └── queues_test.py │ │ └── valrdy_queues.py │ ├── stream │ │ ├── SinkRTL.py │ │ ├── SourceRTL.py │ │ ├── __init__.py │ │ ├── fl.py │ │ ├── ifcs.py │ │ ├── magic_memory.py │ │ ├── queue_adapters.py │ │ ├── queues.py │ │ ├── test │ │ │ ├── __init__.py │ │ │ ├── magic_memory_test.py │ │ │ └── queues_test.py │ │ ├── valrdy_master_minion_ifcs.py │ │ └── valrdy_test_masters.py │ └── test_utils │ │ ├── __init__.py │ │ ├── test │ │ ├── __init__.py │ │ ├── run_test_vector_sim_test.py │ │ └── src_sink_test.py │ │ ├── test_helpers.py │ │ ├── test_masters.py │ │ ├── test_sinks.py │ │ ├── test_srcs.py │ │ └── valrdy_test_srcs.py └── version.py ├── pytest.ini ├── pytest_plugin ├── __init__.py └── pytest_pymtl3.py ├── requirements.txt ├── requirements ├── CI-pypy.txt ├── CI.txt ├── constraints.txt ├── dev.txt ├── docs.txt ├── pypy-constraints.txt └── release.txt ├── scripts ├── common.py ├── pymtl-tutorial-isca2019.yml └── release └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # Git Ignore Files 3 | #========================================================================= 4 | # We explicitly ignore a default build directory, the autoconf generated 5 | # autom4te.cache directory, and automatically generated python files. 6 | # This makes it easy to do a clean build under the source directory and 7 | # still have it appear clean to git. 8 | 9 | build*/ 10 | autom4te.cache/ 11 | .pytest_cache/ 12 | *__pycache__ 13 | *.pyc 14 | *.pyo 15 | */.DS_Store 16 | .cache/ 17 | *.sw* 18 | *.tmp 19 | rast-viz/ 20 | scripts/work 21 | 22 | pymtl3.egg-info/ 23 | 24 | .hypothesis 25 | 26 | htmlcov/ 27 | .coverage 28 | coverage.xml 29 | 30 | *.vcd 31 | -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | known_third_party = greenlet 3 | multi_line_output=3 4 | include_trailing_comma=True 5 | force_grid_wrap=0 6 | use_parentheses=True 7 | line_length=88 8 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Build documentation in `docs` with Sphinx 8 | sphinx: 9 | configuration: docs/conf.py 10 | 11 | # Optionally build your docs in additional formats such as PDF and ePub 12 | formats: all 13 | 14 | # Optionally set the version of Python and requirements required to build your docs 15 | python: 16 | version: 3.6 17 | install: 18 | - requirements: requirements/docs.txt 19 | - requirements: requirements/release.txt 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2019, Batten Research Group, Cornell University 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "pymtl3/passes/rtlir/behavioral/BehavioralRTLIRImplGen.py" 3 | - "*_test.py" 4 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. PyMTL3 documentation master file, created by 2 | sphinx-quickstart on Fri Jan 17 14:51:00 2020. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to PyMTL3 documentation! 7 | ================================ 8 | PyMTL3 is the latest version of PyMTL, an open-source Python-based hardware 9 | generation, simulation, and verification framework with multi-level hardware 10 | modeling support. 11 | 12 | First Steps 13 | ----------- 14 | 15 | Installation and quick start in a Python REPL. 16 | 17 | * **Installing PyMTL3 and Verilator**: 18 | :doc:`Installation guide ` 19 | 20 | * **Using PyMTL3 in a Python REPL**: 21 | :doc:`Quick start ` 22 | 23 | .. toctree:: 24 | :maxdepth: 2 25 | :hidden: 26 | :caption: First Steps 27 | 28 | intro/installation 29 | intro/quickstart 30 | 31 | 32 | Tutorial 33 | -------- 34 | 35 | Tutorials for register-transfer-level and gate-level modeling. 36 | 37 | * **Hardware modeling**: 38 | :doc:`Gate-level modeling ` | 39 | :doc:`Register-transfer-level modeling ` 40 | 41 | .. toctree:: 42 | :maxdepth: 2 43 | :hidden: 44 | :caption: Tutorial 45 | 46 | tut/tut1-gl 47 | tut/tut2-rtl 48 | 49 | 50 | Reference 51 | --------- 52 | 53 | .. toctree:: 54 | :maxdepth: 2 55 | :hidden: 56 | :caption: Reference 57 | 58 | ref/datatypes 59 | ref/dsl 60 | ref/primitives 61 | ref/passes 62 | ref/stdlib 63 | 64 | 65 | Developer Manual 66 | ---------------- 67 | 68 | To be added... 69 | 70 | 71 | About PyMTL3 72 | ------------ 73 | 74 | Visit the PyMTL `website `_. 75 | 76 | 77 | Indices and tables 78 | ================== 79 | 80 | * :ref:`genindex` 81 | * :ref:`modindex` 82 | * :ref:`search` 83 | -------------------------------------------------------------------------------- /docs/ref/dsl.rst: -------------------------------------------------------------------------------- 1 | Domain-Specific Language APIs 2 | ============================= 3 | 4 | .. autoclass:: pymtl3.dsl.Component.Component 5 | :members: 6 | :special-members: 7 | :undoc-members: 8 | -------------------------------------------------------------------------------- /docs/ref/passes-import-meta.rst: -------------------------------------------------------------------------------- 1 | Import Pass Metadata Reference 2 | ============================== 3 | 4 | Verilog import pass 5 | ------------------- 6 | 7 | .. autoclass:: pymtl3.passes.backends.verilog.import_.VerilogVerilatorImportPass.VerilogVerilatorImportPass 8 | 9 | .. automethod:: __init__ 10 | .. automethod:: __call__ 11 | 12 | Here are the available input and output metadata of the Verilog import pass: 13 | 14 | .. autoclass:: pymtl3.passes.backends.verilog.import_.VerilogVerilatorImportPass.VerilogVerilatorImportPass 15 | :members: 16 | 17 | Yosys import pass 18 | ----------------- 19 | 20 | .. autoclass:: pymtl3.passes.backends.yosys.import_.YosysVerilatorImportPass.YosysVerilatorImportPass 21 | 22 | .. automethod:: __init__ 23 | .. automethod:: __call__ 24 | 25 | The available input and output metadata of the Yosys import pass are the same 26 | as those of the :ref:`Verilog import pass `. 27 | -------------------------------------------------------------------------------- /docs/ref/passes-placeholder-meta.rst: -------------------------------------------------------------------------------- 1 | Placeholder Pass Metadata Reference 2 | =================================== 3 | 4 | Verilog placeholder pass 5 | ------------------------ 6 | 7 | .. autoclass:: pymtl3.passes.backends.verilog.VerilogPlaceholderPass.VerilogPlaceholderPass 8 | 9 | .. automethod:: __init__ 10 | .. automethod:: __call__ 11 | 12 | Here are the available input metadata of the Verilog translation-import pass: 13 | 14 | .. autoclass:: pymtl3.passes.backends.verilog.VerilogPlaceholderPass.VerilogPlaceholderPass 15 | :members: 16 | -------------------------------------------------------------------------------- /docs/ref/passes-sim-api.rst: -------------------------------------------------------------------------------- 1 | Simulation Pass API Reference 2 | ============================= 3 | 4 | .. autoclass:: pymtl3.passes.PassGroups.DefaultPassGroup 5 | :members: 6 | :special-members: 7 | :private-members: 8 | :undoc-members: 9 | 10 | .. autoclass:: pymtl3.passes.PassGroups.SimpleSimPass 11 | :members: 12 | :special-members: 13 | :private-members: 14 | :undoc-members: 15 | 16 | .. autoclass:: pymtl3.passes.PassGroups.AutoTickSimPass 17 | :members: 18 | :special-members: 19 | :private-members: 20 | :undoc-members: 21 | -------------------------------------------------------------------------------- /docs/ref/passes-trans-import-meta.rst: -------------------------------------------------------------------------------- 1 | Translation-Import Pass Metadata Reference 2 | ========================================== 3 | 4 | Verilog translation-import pass 5 | ------------------------------- 6 | 7 | .. autoclass:: pymtl3.passes.backends.verilog.VerilogTranslationImportPass.VerilogTranslationImportPass 8 | 9 | .. automethod:: __init__ 10 | .. automethod:: __call__ 11 | 12 | Here are the available input metadata of the Verilog translation-import pass: 13 | 14 | .. autoclass:: pymtl3.passes.backends.verilog.VerilogTranslationImportPass.VerilogTranslationImportPass 15 | :members: 16 | 17 | Yosys translation-import pass 18 | ----------------------------- 19 | 20 | .. autoclass:: pymtl3.passes.backends.yosys.YosysTranslationImportPass.YosysTranslationImportPass 21 | 22 | .. automethod:: __init__ 23 | .. automethod:: __call__ 24 | 25 | The available input metadata of the Yosys translation-import pass are the same 26 | as those of the :ref:`Verilog translation-import pass `. 27 | -------------------------------------------------------------------------------- /docs/ref/passes-translation-meta.rst: -------------------------------------------------------------------------------- 1 | Translation Pass Metadata Reference 2 | =================================== 3 | 4 | Verilog translation pass 5 | ------------------------ 6 | 7 | .. autoclass:: pymtl3.passes.backends.verilog.translation.VerilogTranslationPass.VerilogTranslationPass 8 | 9 | .. automethod:: __init__ 10 | .. automethod:: __call__ 11 | 12 | Here are the available input and output metadata of the Verilog translation pass: 13 | 14 | .. autoclass:: pymtl3.passes.backends.verilog.translation.VerilogTranslationPass.VerilogTranslationPass 15 | :members: 16 | 17 | Yosys translation pass 18 | ---------------------- 19 | 20 | .. autoclass:: pymtl3.passes.backends.yosys.translation.YosysTranslationPass.YosysTranslationPass 21 | 22 | .. automethod:: __init__ 23 | .. automethod:: __call__ 24 | 25 | The available input and output metadata of the Yosys translation pass are the same 26 | as those of the :ref:`Verilog translation pass `. 27 | -------------------------------------------------------------------------------- /docs/ref/primitives.rst: -------------------------------------------------------------------------------- 1 | Hardware Modeling Primitives 2 | ============================ 3 | -------------------------------------------------------------------------------- /docs/ref/stdlib.rst: -------------------------------------------------------------------------------- 1 | Standard Library 2 | ================ 3 | -------------------------------------------------------------------------------- /docs/tut/tut1-gl.rst: -------------------------------------------------------------------------------- 1 | Gate-Level Modeling 2 | =================== 3 | -------------------------------------------------------------------------------- /docs/tut/tut2-rtl.rst: -------------------------------------------------------------------------------- 1 | Register-Transfer-Level Modeling 2 | ================================ 3 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/__init__.py -------------------------------------------------------------------------------- /examples/ex01_basics/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex01_basics/__init__.py -------------------------------------------------------------------------------- /examples/ex01_basics/incr_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | incr_test.py 4 | ========================================================================== 5 | An increment python function that uses PyMTL bits. 6 | 7 | Author : Yanghui Ou 8 | Date : June 17, 2019 9 | """ 10 | from pymtl3 import * 11 | 12 | # ''' TUTORIAL TASK '''''''''''''''''''''''''''''''''''''''''''''''''''''' 13 | # Implement the incr_8bit function and a corresponding unit test 14 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/ 15 | #; The incr_8bit function should take as input an 8-bit value, increment 16 | #; it by one, and return the result. Try writing two unit tests. The 17 | #; first unit test should verify basic functionality, and the second unit 18 | #; test should verify overflow. 19 | 20 | #------------------------------------------------------------------------- 21 | # An 8-bit increment function 22 | #------------------------------------------------------------------------- 23 | 24 | def incr_8bit( x ): 25 | return b8(x) + b8(1) 26 | 27 | #------------------------------------------------------------------------- 28 | # Directed tests for the incr_8bit function 29 | #------------------------------------------------------------------------- 30 | 31 | def test_incr_8bit_simple(): 32 | assert incr_8bit( b8(2) ) == b8(3) 33 | 34 | def test_incr_8bit_overflow(): 35 | assert incr_8bit( b8(0xff) ) == b8(0) 36 | -------------------------------------------------------------------------------- /examples/ex02_cksum/ChecksumFL.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | ChecksumFL.py 4 | ========================================================================== 5 | Functional-level implementation of a checksum unit which implements a 6 | simplified version of Fletcher's algorithm. Here is a straightforward C 7 | implementation for the classic version: 8 | 9 | uint32_t Fletcher32( uint16_t* data, int count ) 10 | { 11 | uint32_t sum1 = 0; 12 | uint32_t sum2 = 0; 13 | 14 | for( int index = 0; index < count; index++ ) { 15 | sum1 = ( sum1 + data[index] ) % 65535; 16 | sum2 = ( sum2 + sum1 ) % 65535; 17 | } 18 | 19 | return ( sum2 << 16 ) | sum1; 20 | } 21 | 22 | In our simplified version, we will use 65536 as the modulus which means 23 | we can implement the modulus with a mask. 24 | 25 | Author : Yanghui Ou, Christopher Batten 26 | Date : June 6, 2019 27 | """ 28 | from pymtl3 import * 29 | 30 | #------------------------------------------------------------------------- 31 | # Checksum FL 32 | #------------------------------------------------------------------------- 33 | 34 | # ''' TUTORIAL TASK '''''''''''''''''''''''''''''''''''''''''''''''''''''' 35 | # Implement the functional-level checksum here 36 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/ 37 | #; Use the pseudocode above for inspiration. Use Bits to implement 38 | #; fixed bitwidth types (e.g., Bits32 for uint32_t). Modulus 65536 is the 39 | #; same as anding with 0xffff. 40 | 41 | def checksum( words ): 42 | 43 | sum1 = b16(0) 44 | sum2 = b16(0) 45 | for word in words: 46 | sum1 = ( sum1 + word ) & 0xffff 47 | sum2 = ( sum2 + sum1 ) & 0xffff 48 | 49 | return concat( sum2, sum1 ) 50 | -------------------------------------------------------------------------------- /examples/ex02_cksum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex02_cksum/__init__.py -------------------------------------------------------------------------------- /examples/ex02_cksum/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex02_cksum/test/__init__.py -------------------------------------------------------------------------------- /examples/ex02_cksum/test/utils_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | utils.py 4 | ========================================================================== 5 | Helper functions for the checksum unit to convert a list of 16b words to 6 | a single Bits object and to convert a single Bits object to a list of 16b 7 | words. 8 | 9 | Author : Yanghui Ou 10 | Date : June 6, 2019 11 | 12 | """ 13 | import hypothesis 14 | from hypothesis import strategies as st 15 | 16 | import pymtl3.datatypes.strategies as pst 17 | from pymtl3 import * 18 | 19 | from ..utils import b128_to_words, words_to_b128 20 | 21 | #------------------------------------------------------------------------- 22 | # Directed Tests 23 | #------------------------------------------------------------------------- 24 | 25 | def test_bits2words(): 26 | bits = b128(0x00010002000300040005000600070008) 27 | words = [ b16(x) for x in [ 8, 7, 6, 5, 4, 3, 2, 1 ]] 28 | assert b128_to_words( bits ) == words 29 | 30 | def test_words2bits(): 31 | bits = b128(0x00010002000300040005000600070008) 32 | words = [ b16(x) for x in [ 8, 7, 6, 5, 4, 3, 2, 1 ]] 33 | assert words_to_b128( words ) == bits 34 | 35 | #------------------------------------------------------------------------- 36 | # Hypothesis Tests 37 | #------------------------------------------------------------------------- 38 | 39 | # ''' TUTORIAL TASK '''''''''''''''''''''''''''''''''''''''''''''''''''''' 40 | # Add Hypothesis test 41 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/ 42 | #; Add a Hypothesis tests to verify that converting words to bits and 43 | #; then bits to words always returns the original words. 44 | 45 | @hypothesis.given( words=st.lists( pst.bits(16), min_size=8, max_size=8 ) ) 46 | def test_hypothesis( words ): 47 | print(words) 48 | assert b128_to_words( words_to_b128( words ) ) == words 49 | -------------------------------------------------------------------------------- /examples/ex02_cksum/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | utils.py 4 | ========================================================================== 5 | Helper functions for the checksum unit. 6 | 7 | Author : Yanghui Ou 8 | Date : June 6, 2019 9 | """ 10 | 11 | from functools import reduce 12 | 13 | from pymtl3 import * 14 | 15 | #------------------------------------------------------------------------- 16 | # words_to_b128 converts a list of Bits16 to Bits128 17 | #------------------------------------------------------------------------- 18 | 19 | def words_to_b128( words ): 20 | assert len( words ) == 8 21 | bits = reduce( lambda x, y: concat( y, x ), words ) 22 | return bits 23 | 24 | #------------------------------------------------------------------------- 25 | # Helper function that converts Bits128 to a list of Bits16 26 | #------------------------------------------------------------------------- 27 | 28 | def b128_to_words( bits ): 29 | assert bits.nbits == 128 30 | words = [ bits[i*16:(i+1)*16] for i in range( 8 ) ] 31 | return words 32 | -------------------------------------------------------------------------------- /examples/ex03_proc/NullXcel.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | NullXcel.py 4 | ========================================================================== 5 | 6 | Author : Shunning Jiang 7 | Date : June 14, 2019 8 | """ 9 | from pymtl3 import * 10 | from pymtl3.stdlib.ifcs.xcel_ifcs import XcelMinionIfcRTL 11 | from pymtl3.stdlib.ifcs.XcelMsg import XcelMsgType, mk_xcel_msg 12 | from pymtl3.stdlib.basic_rtl import RegEn 13 | from pymtl3.stdlib.queues import NormalQueueRTL 14 | 15 | 16 | class NullXcelRTL(Component): 17 | 18 | def construct( s, nbits=32 ): 19 | 20 | dtype = mk_bits(32) 21 | xreq_class, xresp_class = mk_xcel_msg( 5,nbits ) 22 | 23 | s.xcel = XcelMinionIfcRTL( xreq_class, xresp_class ) 24 | 25 | s.xcelreq_q = NormalQueueRTL( xreq_class, 2 ) 26 | s.xcelreq_q.enq //= s.xcel.req 27 | 28 | s.xr0 = RegEn( dtype ) 29 | s.xr0.in_ //= s.xcelreq_q.deq.ret.data 30 | 31 | @update 32 | def up_null_xcel(): 33 | 34 | if s.xcelreq_q.deq.rdy & s.xcel.resp.rdy: 35 | s.xcelreq_q.deq.en @= 1 36 | s.xcel.resp.en @= 1 37 | s.xcel.resp.msg.type_ @= s.xcelreq_q.deq.ret.type_ 38 | 39 | if s.xcelreq_q.deq.ret.type_ == XcelMsgType.WRITE: 40 | s.xr0.en @= 1 41 | s.xcel.resp.msg.data @= 0 42 | else: 43 | s.xr0.en @= 0 44 | s.xcel.resp.msg.data @= s.xr0.out 45 | else: 46 | s.xcelreq_q.deq.en @= 0 47 | s.xcel.resp.en @= 0 48 | s.xr0.en @= 0 49 | s.xcel.resp.msg.data @= 0 50 | s.xcel.resp.msg.type_ @= 0 51 | 52 | def line_trace( s ): 53 | return str(s.xcel) 54 | -------------------------------------------------------------------------------- /examples/ex03_proc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex03_proc/__init__.py -------------------------------------------------------------------------------- /examples/ex03_proc/test/ProcCL_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================= 3 | ProcCL_test.py 4 | ========================================================================= 5 | Includes test cases for the cycle level TinyRV0 processor. 6 | 7 | Author : Shunning Jiang, Yanghui Ou 8 | Date : June 12, 2019 9 | """ 10 | import random 11 | 12 | import pytest 13 | 14 | from examples.ex03_proc.ProcCL import ProcCL 15 | from pymtl3 import * 16 | 17 | random.seed(0xdeadbeef) 18 | 19 | 20 | #------------------------------------------------------------------------- 21 | # ProcCL_Tests 22 | #------------------------------------------------------------------------- 23 | # It is as simple as inheriting from FL tests and change the ProcType to 24 | # ProcCL. 25 | 26 | from .ProcFL_test import ProcFL_Tests as BaseTests 27 | 28 | class ProcCL_Tests( BaseTests ): 29 | 30 | @classmethod 31 | def setup_class( cls ): 32 | cls.ProcType = ProcCL 33 | -------------------------------------------------------------------------------- /examples/ex03_proc/test/ProcRTL_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================= 3 | ProcRTL_test.py 4 | ========================================================================= 5 | Includes test cases for the register transfer level TinyRV0 processor. 6 | 7 | Author : Shunning Jiang, Yanghui Ou 8 | Date : June 15, 2019 9 | """ 10 | import random 11 | 12 | import pytest 13 | 14 | from examples.ex03_proc.ProcRTL import ProcRTL 15 | from pymtl3 import * 16 | 17 | random.seed(0xdeadbeef) 18 | 19 | 20 | #------------------------------------------------------------------------- 21 | # ProcRTL_Tests 22 | #------------------------------------------------------------------------- 23 | # It is as simple as inheriting from CL tests and change the ProcType to 24 | # ProcRTL. 25 | 26 | from .ProcCL_test import ProcCL_Tests as BaseTests 27 | 28 | class ProcRTL_Tests( BaseTests ): 29 | 30 | @classmethod 31 | def setup_class( cls ): 32 | cls.ProcType = ProcRTL 33 | -------------------------------------------------------------------------------- /examples/ex03_proc/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex03_proc/test/__init__.py -------------------------------------------------------------------------------- /examples/ex03_proc/test/inst_and.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # and 3 | #========================================================================= 4 | 5 | 6 | from pymtl3 import * 7 | 8 | from .inst_utils import * 9 | 10 | #------------------------------------------------------------------------- 11 | # gen_and_basic_test 12 | #------------------------------------------------------------------------- 13 | 14 | def gen_and_basic_test(): 15 | # ''' TUTORIAL TASK '''''''''''''''''''''''''''''''''''''''''''''''''''''' 16 | # Implement your own test for AND instruction 17 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/ 18 | #; Define a function named gen_and_basic_test that tests AND instruction 19 | #: return """ 20 | #: """ 21 | return """ 22 | csrr x1, mngr2proc < 0x0f0f0f0f 23 | csrr x2, mngr2proc < 0x00ff00ff 24 | and x3, x1, x2 25 | csrw proc2mngr, x3 > 0x000f000f 26 | """ 27 | 28 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''/\ 29 | -------------------------------------------------------------------------------- /examples/ex03_proc/test/inst_sll.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # sll 3 | #========================================================================= 4 | 5 | import random 6 | 7 | from pymtl3 import * 8 | 9 | from .inst_utils import * 10 | 11 | #------------------------------------------------------------------------- 12 | # gen_basic_test 13 | #------------------------------------------------------------------------- 14 | 15 | def gen_basic_test(): 16 | return """ 17 | csrr x1, mngr2proc < 0x80008000 18 | csrr x2, mngr2proc < 0x00000003 19 | nop 20 | nop 21 | nop 22 | nop 23 | nop 24 | nop 25 | nop 26 | nop 27 | sll x3, x1, x2 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | csrw proc2mngr, x3 > 0x00040000 37 | nop 38 | nop 39 | nop 40 | nop 41 | nop 42 | nop 43 | nop 44 | nop 45 | """ 46 | 47 | #------------------------------------------------------------------------- 48 | # gen_random_test 49 | #------------------------------------------------------------------------- 50 | 51 | def gen_random_test(): 52 | asm_code = [] 53 | for i in range(50): 54 | src0 = Bits32( random.randint(0,0xffffffff) ) 55 | src1 = Bits32( random.randint(0,31) ) 56 | dest = src0 << src1 57 | asm_code.append( gen_rr_value_test( "sll", src0.uint(), src1.uint(), dest.uint() ) ) 58 | return asm_code 59 | -------------------------------------------------------------------------------- /examples/ex03_proc/test/inst_srl.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # srl 3 | #========================================================================= 4 | 5 | import random 6 | 7 | from pymtl3 import * 8 | 9 | from .inst_utils import * 10 | 11 | #------------------------------------------------------------------------- 12 | # gen_basic_test 13 | #------------------------------------------------------------------------- 14 | 15 | def gen_basic_test(): 16 | return """ 17 | csrr x1, mngr2proc < 0x00008000 18 | csrr x2, mngr2proc < 0x00000003 19 | nop 20 | nop 21 | nop 22 | nop 23 | nop 24 | nop 25 | nop 26 | nop 27 | srl x3, x1, x2 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | csrw proc2mngr, x3 > 0x00001000 37 | nop 38 | nop 39 | nop 40 | nop 41 | nop 42 | nop 43 | nop 44 | nop 45 | """ 46 | 47 | #------------------------------------------------------------------------- 48 | # gen_random_test 49 | #------------------------------------------------------------------------- 50 | 51 | def gen_random_test(): 52 | asm_code = [] 53 | for i in range(50): 54 | src0 = Bits32( random.randint(0,0xffffffff) ) 55 | src1 = Bits32( random.randint(0,31) ) 56 | dest = src0 >> src1 57 | asm_code.append( gen_rr_value_test( "srl", src0.uint(), src1.uint(), dest.uint() ) ) 58 | return asm_code 59 | -------------------------------------------------------------------------------- /examples/ex03_proc/test/inst_xcel.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # xcel 3 | #========================================================================= 4 | 5 | 6 | from pymtl3 import * 7 | 8 | from .inst_utils import * 9 | 10 | #------------------------------------------------------------------------- 11 | # gen_basic_test 12 | #------------------------------------------------------------------------- 13 | 14 | def gen_basic_test(): 15 | return """ 16 | csrr x1, mngr2proc < 0xdeadbeef 17 | csrw 0x7E9, x1 18 | csrr x2, 0x7FF 19 | csrw proc2mngr, x2 > 0xdeadbeef 20 | """ 21 | 22 | def gen_multiple_test(): 23 | return """ 24 | csrr x1, mngr2proc < 0xdeadbee0 25 | csrw 0x7E0, x1 26 | csrr x2, 0x7FF 27 | csrw proc2mngr, x2 > 0xdeadbee0 28 | 29 | csrr x1, mngr2proc < 0xdeadbee1 30 | csrw 0x7E0, x1 31 | csrr x2, 0x7FF 32 | csrw proc2mngr, x2 > 0xdeadbee1 33 | 34 | csrr x1, mngr2proc < 0xdeadbee2 35 | csrw 0x7E0, x1 36 | csrr x2, 0x7FF 37 | csrw proc2mngr, x2 > 0xdeadbee2 38 | 39 | csrr x1, mngr2proc < 0xdeadbee2 40 | csrw 0x7E0, x1 41 | csrr x2, 0x7FF 42 | csrw proc2mngr, x2 > 0xdeadbee2 43 | 44 | csrr x1, mngr2proc < 0xdeadbee3 45 | csrw 0x7E0, x1 46 | csrr x2, 0x7FF 47 | csrw proc2mngr, x2 > 0xdeadbee3 48 | 49 | csrr x1, mngr2proc < 0xdeadbee4 50 | csrw 0x7E0, x1 51 | csrr x2, 0x7FF 52 | csrw proc2mngr, x2 > 0xdeadbee4 53 | 54 | csrr x1, mngr2proc < 0xdeadbee5 55 | csrw 0x7E0, x1 56 | csrr x2, 0x7FF 57 | csrw proc2mngr, x2 > 0xdeadbee5 58 | 59 | csrr x1, mngr2proc < 0xdeadbee6 60 | csrw 0x7E0, x1 61 | csrr x2, 0x7FF 62 | csrw proc2mngr, x2 > 0xdeadbee6 63 | """ 64 | -------------------------------------------------------------------------------- /examples/ex03_proc/ubmark/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex03_proc/ubmark/__init__.py -------------------------------------------------------------------------------- /examples/ex03_proc/ubmark/proc_ubmark_cksum_blk_data.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # proc_ubmark_cksum_blk_data.py 3 | #========================================================================= 4 | 5 | dataset_size = 3 6 | 7 | mask = [ 0x0000ffff ] 8 | 9 | ref = [ 10 | 0x00780024, 11 | 0x00820024, 12 | 0x3900bf00, 13 | ] 14 | 15 | src = [ 16 | 0x00020001, 0x00040003, 0x00060005, 0x00080007, 17 | 0x00020001, 0x00040003, 0x00070008, 0x00050006, 18 | 0xff00f000, 0x20001000, 0x60005000, 0x80007000, 19 | ] 20 | -------------------------------------------------------------------------------- /examples/ex03_proc/ubmark/proc_ubmark_cksum_roll_data.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # proc_ubmark_cksum_roll_data.py 3 | #========================================================================= 4 | 5 | dataset_size = 150 6 | 7 | mask = [ 0x0000ffff ] 8 | 9 | ref = [ 0x9f6b0de5 ] 10 | 11 | src = [ 12 | 0x01510248, 0x02cb03f5, 0x001c0387, 13 | 0x00010264, 0x000e0090, 0x02880210, 14 | 0x0376002c, 0x0106032c, 0x02470142, 15 | 0x007400ed, 0x037e0199, 0x018702b6, 16 | 0x03da018e, 0x004b0082, 0x0238039b, 17 | 0x02f50350, 0x02ed0358, 0x02d202e8, 18 | 0x02ad000b, 0x027a0178, 0x03e502bb, 19 | 0x0085028d, 0x00ee00f9, 0x036702ad, 20 | 0x001a0141, 0x00fd032d, 0x02cf027a, 21 | 0x02450151, 0x02550200, 0x029100b5, 22 | 0x03670135, 0x01cb015d, 0x01bc031d, 23 | 0x038e036b, 0x0006034a, 0x006e03ce, 24 | 0x00ef00a2, 0x03f802a2, 0x00e700b5, 25 | 0x030303df, 0x038701d6, 0x00d00329, 26 | 0x029001eb, 0x01030259, 0x007b03aa, 27 | 0x0358028b, 0x03420157, 0x01bd0112, 28 | 0x018e0010, 0x009c001c, 0x017d03fc, 29 | 0x01df03ee, 0x014f0079, 0x01f7023e, 30 | 0x0221039d, 0x03de0363, 0x0113031a, 31 | 0x021002a1, 0x00a5010f, 0x01c703f6, 32 | 0x039b0073, 0x025c0038, 0x007a03d5, 33 | 0x00a901da, 0x0374016b, 0x02520070, 34 | 0x01de02ee, 0x005002ad, 0x01a80378, 35 | 0x02d103bd, 0x01bc038b, 0x01980078, 36 | 0x000a006b, 0x03950258, 0x028f020e, 37 | ] 38 | -------------------------------------------------------------------------------- /examples/ex04_xcel/ChecksumXcelFL.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | ChecksumXcelFL.py 4 | ========================================================================== 5 | Functional level implementation of a checksum accelerator. 6 | 7 | Author : Yanghui Ou 8 | Date : June 14, 2019 9 | """ 10 | from examples.ex02_cksum.ChecksumFL import checksum 11 | from pymtl3 import * 12 | from pymtl3.stdlib.ifcs import mk_xcel_msg, XcelMinionIfcFL 13 | 14 | 15 | # Address space: 0~3: checksum input, 4: go bit, 5: result 16 | class ChecksumXcelFL( Component ): 17 | 18 | def construct( s ): 19 | 20 | # Interface 21 | 22 | ReqType, RespType = mk_xcel_msg( 5, 32 ) 23 | 24 | s.xcel = XcelMinionIfcFL( read=s.read, write=s.write ) 25 | 26 | # Components 27 | 28 | s.reg_file = [ b32(0) for _ in range(6) ] 29 | 30 | s.trace = " " 31 | @update 32 | def up_clear_trace(): 33 | s.trace = " " 34 | 35 | s.add_constraints( U(up_clear_trace) < M(s.read) ) 36 | s.add_constraints( U(up_clear_trace) < M(s.write) ) 37 | 38 | def read( s, addr ): 39 | s.trace = "fl:".format(int(addr)) 40 | return s.reg_file[ int(addr) ] 41 | 42 | def write( s, addr, data ): 43 | s.trace = "fl:".format(int(addr)) 44 | s.reg_file[ int(addr) ] = b32(data) 45 | 46 | # If go bit is written 47 | if s.reg_file[4]: 48 | words = [] 49 | for i in range( 4 ): 50 | words.append( s.reg_file[i][0 :16] ) 51 | words.append( s.reg_file[i][16:32] ) 52 | s.reg_file[5] = checksum( words ) 53 | 54 | def line_trace( s ): 55 | return s.trace 56 | -------------------------------------------------------------------------------- /examples/ex04_xcel/ProcXcel.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | ProcXcel.py 4 | ========================================================================== 5 | Processor-accelerator compostion. 6 | 7 | Author : Shunning Jiang 8 | Date : June 12, 2019 9 | """ 10 | 11 | from pymtl3 import * 12 | from pymtl3.stdlib.connects import connect_pairs 13 | from pymtl3.stdlib.ifcs import RecvIfcRTL, SendIfcRTL, SendIfcFL, GetIfcFL 14 | from pymtl3.stdlib.mem import MemMasterIfcCL, MemMasterIfcFL, MemMasterIfcRTL, mk_mem_msg 15 | 16 | 17 | class ProcXcel( Component ): 18 | 19 | def construct( s, ProcClass, XcelClass ): 20 | 21 | req_class, resp_class = mk_mem_msg( 8, 32, 32 ) 22 | 23 | s.commit_inst = OutPort( Bits1 ) 24 | 25 | # Instruction Memory Request/Response Interface 26 | 27 | s.proc = ProcClass() 28 | s.proc.commit_inst //= s.commit_inst 29 | 30 | s.xcel = XcelClass() 31 | s.xcel.xcel //= s.proc.xcel 32 | 33 | if isinstance( s.proc.imem, MemMasterIfcRTL ): # RTL proc 34 | s.mngr2proc = RecvIfcRTL( Bits32 ) 35 | s.proc2mngr = SendIfcRTL( Bits32 ) 36 | s.imem = MemMasterIfcRTL( req_class, resp_class ) 37 | s.dmem = MemMasterIfcRTL( req_class, resp_class ) 38 | 39 | elif isinstance( s.proc.imem, MemMasterIfcCL ): # CL proc 40 | s.mngr2proc = CalleeIfcCL( Type=Bits32 ) 41 | s.proc2mngr = CallerIfcCL( Type=Bits32 ) 42 | s.imem = MemMasterIfcCL( req_class, resp_class ) 43 | s.dmem = MemMasterIfcCL( req_class, resp_class ) 44 | 45 | elif isinstance( s.proc.imem, MemMasterIfcFL ): # FL proc 46 | s.mngr2proc = GetIfcFL( Type=Bits32 ) 47 | s.proc2mngr = SendIfcFL( Type=Bits32 ) 48 | s.imem = MemMasterIfcFL() 49 | s.dmem = MemMasterIfcFL() 50 | 51 | 52 | s.mngr2proc //= s.proc.mngr2proc 53 | s.proc2mngr //= s.proc.proc2mngr 54 | s.imem //= s.proc.imem 55 | s.dmem //= s.proc.dmem 56 | 57 | def line_trace( s ): 58 | return "{}|{}".format( s.proc.line_trace(), s.xcel.line_trace() ) 59 | -------------------------------------------------------------------------------- /examples/ex04_xcel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex04_xcel/__init__.py -------------------------------------------------------------------------------- /examples/ex04_xcel/test/ChecksumXcelFL_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | ChecksumXcelFL_test.py 4 | ========================================================================== 5 | Tests for the functional level checksum accelerator. 6 | 7 | Author : Yanghui Ou 8 | Date : June 14, 2019 9 | """ 10 | from examples.ex02_cksum.test.ChecksumCL_test import ChecksumCL_Tests as BaseTests 11 | from pymtl3 import * 12 | from pymtl3.stdlib.ifcs import mk_xcel_msg 13 | 14 | from ..ChecksumXcelFL import ChecksumXcelFL 15 | 16 | #------------------------------------------------------------------------- 17 | # Wrap Xcel into a function 18 | #------------------------------------------------------------------------- 19 | 20 | Req, Resp = mk_xcel_msg( 3, 32 ) 21 | 22 | def checksum_xcel_fl( words ): 23 | assert len( words ) == 8 24 | 25 | # Create a simulator using ChecksumXcelFL 26 | dut = ChecksumXcelFL() 27 | dut.elaborate() 28 | dut.apply( DefaultPassGroup() ) 29 | 30 | # Transfer checksum input 31 | for i in range( 4 ): 32 | data = concat( words[i*2+1], words[i*2] ) 33 | dut.xcel.write( i, data ) 34 | 35 | # Set the go bit 36 | dut.xcel.write( 4, b32(1) ) 37 | 38 | # get result 39 | return dut.xcel.read( 5 ) 40 | 41 | #------------------------------------------------------------------------- 42 | # Test checksum as a function 43 | #------------------------------------------------------------------------- 44 | # We reuse the extened function tests in ex02_cksum.test.ChecksumCL_test. 45 | 46 | 47 | # ''' TUTORIAL TASK '''''''''''''''''''''''''''''''''''''''''''''''''''''' 48 | # Implement the tests for ChecksumXcelFL 49 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/ 50 | #; Write a ChecksumXcelFL_Tests class that inherits from BaseTests which 51 | #; is basically ChecksumCL_Tests. ChecksumCL_Tests is developed in Task 2 52 | #; for the checksum unit. 53 | 54 | class ChecksumXcelFL_Tests( BaseTests ): 55 | 56 | def cksum_func( s, words ): 57 | return checksum_xcel_fl( words ) 58 | 59 | # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''/\ 60 | -------------------------------------------------------------------------------- /examples/ex04_xcel/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex04_xcel/test/__init__.py -------------------------------------------------------------------------------- /examples/ex04_xcel/ubmark/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/examples/ex04_xcel/ubmark/__init__.py -------------------------------------------------------------------------------- /examples/ex04_xcel/ubmark/proc_ubmark_checksum_xcel_single.py: -------------------------------------------------------------------------------- 1 | #======================================================================== 2 | # ubmark-checksum-xcel single iteration 3 | #======================================================================== 4 | 5 | 6 | from examples.ex03_proc.SparseMemoryImage import SparseMemoryImage, mk_section 7 | from examples.ex03_proc.tinyrv0_encoding import assemble 8 | from pymtl3 import * 9 | 10 | 11 | class ubmark_cksum_xcel_single: 12 | 13 | # verification function, argument is a bytearray from TestMemory instance 14 | 15 | @staticmethod 16 | def gen_mem_image(): 17 | 18 | # text section 19 | 20 | text = """ 21 | # load array pointers 22 | csrr x1, mngr2proc < 0xff00f000 23 | csrr x2, mngr2proc < 0x20001000 24 | csrr x3, mngr2proc < 0x60005000 25 | csrr x4, mngr2proc < 0x80007000 26 | addi x5, x0, 1 27 | 28 | csrw 0x7E0, x1 29 | csrw 0x7E1, x2 30 | csrw 0x7E2, x3 31 | csrw 0x7E3, x4 32 | csrw 0x7E4, x5 33 | 34 | csrr x1, 0x7E5 35 | csrw proc2mngr, x1 > 0x3900bf00 36 | 37 | """ 38 | 39 | mem_image = assemble( text ) 40 | 41 | return mem_image 42 | -------------------------------------------------------------------------------- /pymtl3/__init__.py: -------------------------------------------------------------------------------- 1 | from .datatypes import * 2 | from .datatypes import _bitwidths 3 | from .dsl.Component import Component 4 | from .dsl.ComponentLevel1 import update 5 | from .dsl.ComponentLevel2 import update_ff 6 | from .dsl.ComponentLevel3 import connect 7 | from .dsl.ComponentLevel4 import update_once 8 | from .dsl.ComponentLevel5 import method_port 9 | from .dsl.ComponentLevel6 import non_blocking 10 | from .dsl.ComponentLevel7 import blocking 11 | from .dsl.Connectable import ( 12 | CalleeIfcCL, 13 | CalleeIfcFL, 14 | CalleeIfcRTL, 15 | CalleePort, 16 | CallerIfcCL, 17 | CallerIfcFL, 18 | CallerIfcRTL, 19 | CallerPort, 20 | InPort, 21 | Interface, 22 | OutPort, 23 | Wire, 24 | ) 25 | from .dsl.ConstraintTypes import RD, WR, M, U 26 | from .dsl.MetadataKey import MetadataKey 27 | from .dsl.Placeholder import Placeholder 28 | from .passes.PassGroups import DefaultPassGroup 29 | 30 | __all__ = [ 31 | 'U','M','RD','WR', 32 | 'Wire', 'InPort', 'OutPort', 'Interface', 'CallerPort', 'CalleePort', 33 | 'update', 'update_ff', 'update_once', 'connect', 'method_port', 34 | 'CalleeIfcRTL', 'CallerIfcRTL', 35 | 'non_blocking', 'CalleeIfcCL', 'CallerIfcCL', 36 | 'blocking', 'CalleeIfcFL', 'CallerIfcFL', 37 | 38 | 'DefaultPassGroup', 39 | 'Component', 'Placeholder', 'MetadataKey', 40 | 41 | 'trunc', 'sext', 'zext', 'clog2', 'concat', 'reduce_and', 'reduce_or', 'reduce_xor', 42 | 'mk_bits', 'Bits', 43 | 'mk_bitstruct', 'bitstruct', 44 | ] + [ "Bits{}".format(x) for x in _bitwidths ] \ 45 | + [ "b{}".format(x) for x in _bitwidths ] 46 | -------------------------------------------------------------------------------- /pymtl3/datatypes/__init__.py: -------------------------------------------------------------------------------- 1 | from .bits_import import * 2 | from .bits_import import _bitwidths 3 | from .bitstructs import bitstruct, is_bitstruct_class, is_bitstruct_inst, mk_bitstruct 4 | from .helpers import clog2, concat, reduce_and, reduce_or, reduce_xor, sext, trunc, zext 5 | -------------------------------------------------------------------------------- /pymtl3/datatypes/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/datatypes/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/datatypes/test/helpers_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | helpers_test.py 4 | ========================================================================== 5 | Test cases for helper functions 6 | 7 | Author : Shunning Jiang 8 | Date : Nov 30, 2019 9 | """ 10 | 11 | from pymtl3.datatypes import * 12 | 13 | 14 | def test_concat(): 15 | x = concat( Bits128(0x1234567890abcdef1234567890abcdef), 16 | Bits252(0xfffffffff22222222222222222444441234567890abcdef1234567890abcdef) ) 17 | assert x.nbits == 380 18 | assert x == mk_bits(380)(0x1234567890abcdef1234567890abcdeffffffffff22222222222222222444441234567890abcdef1234567890abcdef) 19 | 20 | def test_zext(): 21 | assert zext( Bits8(0xe), 24 ) == Bits24(0xe) 22 | 23 | def test_sext(): 24 | assert zext( Bits8(0xe), 24 ) == Bits24(0xe) 25 | 26 | def test_clog2(): 27 | assert clog2(7) == 3 28 | assert clog2(8) == 3 29 | assert clog2(9) == 4 30 | 31 | def test_reduce_and(): 32 | for i in range(255): 33 | assert not reduce_and( b8(i) ) 34 | assert reduce_and( b8(255) ) 35 | assert reduce_and( b512((2**512)-1) ) 36 | 37 | def test_reduce_or(): 38 | for i in range(1, 256): 39 | assert reduce_or(i) 40 | assert not reduce_or( b8(0) ) 41 | assert reduce_or( b512((2**512)-1) ) 42 | 43 | def test_reduce_xor(): 44 | assert reduce_xor( b8(0b10101011) ) == 1 45 | assert reduce_xor( b8(0b10101010) ) == 0 46 | -------------------------------------------------------------------------------- /pymtl3/dsl/ComponentLevel6.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | ComponentLevel6.py 4 | ======================================================================== 5 | Add method port decorator. 6 | 7 | Author : Yanghui Ou, Shunning Jiang 8 | Date : Jan 24, 2020 9 | """ 10 | from .ComponentLevel5 import ComponentLevel5 11 | from .Connectable import CalleeIfcCL, CalleePort 12 | 13 | #------------------------------------------------------------------------- 14 | # non blocking decorator 15 | #------------------------------------------------------------------------- 16 | 17 | def non_blocking( rdy, Type=None ): 18 | def real_decorator( method ): 19 | method._non_blocking_rdy = rdy 20 | method._non_blocking_type = Type 21 | return method 22 | return real_decorator 23 | 24 | #------------------------------------------------------------------------- 25 | # ComponentLevel6 26 | #------------------------------------------------------------------------- 27 | 28 | class ComponentLevel6( ComponentLevel5 ): 29 | 30 | # Override 31 | def _handle_decorated_methods( s ): 32 | 33 | # The following code handles non-blocking methods 34 | def bind_method( method ): 35 | def _bound_method( *args, **kwargs ): 36 | return method( s, *args, **kwargs ) 37 | return _bound_method 38 | 39 | for x in s.__class__.__dict__: 40 | method = getattr( s, x ) 41 | 42 | # We identify decorated method port here 43 | if hasattr( method, "_callee_port" ): 44 | setattr( s, x, CalleePort( method=method ) ) 45 | 46 | # We identify non_blocking methods here 47 | elif hasattr( method, "_non_blocking_rdy" ): 48 | rdy = method._non_blocking_rdy 49 | Type = method._non_blocking_type 50 | setattr( s, x, CalleeIfcCL( Type=Type, method=method, rdy=bind_method( rdy ) ) ) 51 | -------------------------------------------------------------------------------- /pymtl3/dsl/ComponentLevel7.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | ComponentLevel7.py 4 | ======================================================================== 5 | Add functional-level blocking method decorator. 6 | 7 | Author : Shunning Jiang 8 | Date : Jan 23, 2020 9 | """ 10 | from .ComponentLevel6 import ComponentLevel6 11 | from .Connectable import CalleeIfcCL, CalleeIfcFL, CalleePort 12 | 13 | #------------------------------------------------------------------------- 14 | # method_port decorator 15 | #------------------------------------------------------------------------- 16 | 17 | def blocking( method ): 18 | method._blocking = True 19 | return method 20 | 21 | #------------------------------------------------------------------------- 22 | # ComponentLevel7 23 | #------------------------------------------------------------------------- 24 | 25 | class ComponentLevel7( ComponentLevel6 ): 26 | 27 | # override 28 | def _handle_decorated_methods( s ): 29 | 30 | # The following code handles non-blocking methods 31 | def bind_method( method ): 32 | def _bound_method( *args, **kwargs ): 33 | return method( s, *args, **kwargs ) 34 | return _bound_method 35 | 36 | for x in s.__class__.__dict__: 37 | method = getattr( s, x ) 38 | 39 | # We identify decorated method port here 40 | if hasattr( method, "_callee_port" ): 41 | setattr( s, x, CalleePort( method=method ) ) 42 | 43 | # We identify non_blocking methods here 44 | elif hasattr( method, "_non_blocking_rdy" ): 45 | rdy = method._non_blocking_rdy 46 | Type = method._non_blocking_type 47 | setattr( s, x, CalleeIfcCL( Type=Type, method=method, rdy=bind_method( rdy ) ) ) 48 | 49 | # We identify blocking methods here 50 | elif hasattr( method, "_blocking" ): 51 | setattr( s, x, CalleeIfcFL( method=method ) ) 52 | -------------------------------------------------------------------------------- /pymtl3/dsl/ConstraintTypes.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | ConstraintType.py 4 | ======================================================================== 5 | Explicit constraint class types. 6 | 7 | Author : Shunning Jiang 8 | Date : July 7, 2017 9 | """ 10 | 11 | class FuncConstraint: 12 | def __init__( self, func ): self.func = func 13 | def __lt__( self, other ): return (self, other, False) 14 | def __gt__( self, other ): return (other, self, False) 15 | def __eq__( self, other ): return (self, other, True) 16 | 17 | class ValueConstraint: 18 | def __init__( self, var ): self.var = var 19 | def __lt__( self, other ): return (self, other, False) 20 | def __gt__( self, other ): return (other, self, False) 21 | 22 | class U(FuncConstraint): pass 23 | class M(FuncConstraint): pass 24 | 25 | class RD(ValueConstraint): pass 26 | class WR(ValueConstraint): pass 27 | -------------------------------------------------------------------------------- /pymtl3/dsl/MetadataKey.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # MetadataKey.py 3 | #========================================================================= 4 | # Provides MetadataKey class. 5 | # 6 | # Author : Peitian Pan 7 | # Date : Mar 16, 2020 8 | 9 | class MetadataKey: 10 | def __init__( self, T=None ): 11 | assert T is None or isinstance( T, type ), f"The given parameter {T} is not a type." 12 | self.type = T 13 | 14 | def check_value( self, value ): 15 | if self.type is not None and not isinstance( value, self.type ): 16 | raise TypeError( f"Value {value} is of type {type(value)} and cannot be assigned " 17 | f"to this MetadataKey that enforces type {self.type}." ) 18 | -------------------------------------------------------------------------------- /pymtl3/dsl/Placeholder.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | Placeholder.py 4 | ======================================================================== 5 | 6 | Author : Shunning Jiang 7 | Date : June 1, 2019 8 | """ 9 | 10 | class Placeholder: 11 | pass 12 | -------------------------------------------------------------------------------- /pymtl3/dsl/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | These objects are only for developers to use. Other objects are exposed 3 | to users in pymtl/__init__.py 4 | """ 5 | from .Component import Component 6 | from .ComponentLevel1 import update 7 | from .ComponentLevel2 import update_ff 8 | from .ComponentLevel3 import connect 9 | from .ComponentLevel4 import update_once 10 | from .ComponentLevel5 import method_port 11 | from .ComponentLevel6 import non_blocking 12 | from .ComponentLevel7 import blocking 13 | from .Connectable import ( 14 | BlockingIfc, 15 | CalleeIfcCL, 16 | CalleeIfcFL, 17 | CalleeIfcRTL, 18 | CalleePort, 19 | CallerIfcCL, 20 | CallerIfcFL, 21 | CallerIfcRTL, 22 | CallerPort, 23 | CallIfcRTL, 24 | Const, 25 | InPort, 26 | Interface, 27 | MethodPort, 28 | NonBlockingIfc, 29 | OutPort, 30 | Signal, 31 | Wire, 32 | ) 33 | from .ConstraintTypes import RD, WR, M, U 34 | from .MetadataKey import MetadataKey 35 | from .Placeholder import Placeholder 36 | -------------------------------------------------------------------------------- /pymtl3/dsl/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/dsl/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/examples/__init__.py -------------------------------------------------------------------------------- /pymtl3/examples/ex00_quickstart/FullAdder.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # FullAdder.py 3 | #========================================================================= 4 | 5 | from pymtl3 import * 6 | 7 | 8 | class FullAdder( Component ): 9 | def construct( s ): 10 | s.a = InPort() 11 | s.b = InPort() 12 | s.cin = InPort() 13 | s.sum = OutPort() 14 | s.cout = OutPort() 15 | 16 | @update 17 | def upblk(): 18 | s.sum @= s.cin ^ s.a ^ s.b 19 | s.cout @= ( ( s.a ^ s.b ) & s.cin ) | ( s.a & s.b ) 20 | -------------------------------------------------------------------------------- /pymtl3/examples/ex00_quickstart/RegIncr.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RegIncr.py 3 | #========================================================================= 4 | 5 | from pymtl3 import * 6 | 7 | 8 | class RegIncr( Component ): 9 | def construct( s, nbits ): 10 | s.in_ = InPort( nbits ) 11 | s.out = OutPort( nbits ) 12 | 13 | s.reg_out = Wire( nbits ) 14 | 15 | @update_ff 16 | def upblk_ff(): 17 | if s.reset: 18 | s.reg_out <<= 0 19 | else: 20 | s.reg_out <<= s.in_ 21 | 22 | @update 23 | def upblk_comb(): 24 | s.out @= s.reg_out + 1 25 | -------------------------------------------------------------------------------- /pymtl3/examples/ex00_quickstart/__init__.py: -------------------------------------------------------------------------------- 1 | from .FullAdder import FullAdder 2 | from .RegIncr import RegIncr 3 | -------------------------------------------------------------------------------- /pymtl3/extra/__init__.py: -------------------------------------------------------------------------------- 1 | from .clone_deepcopy import clone_deepcopy 2 | -------------------------------------------------------------------------------- /pymtl3/extra/clone_deepcopy.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | clone_deepcopy.py 4 | ======================================================================== 5 | 6 | Author: Shunning Jiang 7 | Date: June 9, 2020 8 | """ 9 | from copy import deepcopy 10 | 11 | 12 | def clone_deepcopy( x ): 13 | try: 14 | return x.clone() 15 | except AttributeError: 16 | return deepcopy(x) 17 | -------------------------------------------------------------------------------- /pymtl3/extra/pypy/__init__.py: -------------------------------------------------------------------------------- 1 | from .custom_exec import custom_exec 2 | -------------------------------------------------------------------------------- /pymtl3/extra/pypy/custom_exec.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # custom_exec.py 3 | #========================================================================= 4 | # The purpose of this custom_exec function is to turn dictionaries into 5 | # ModuleDicts that results in much better JIT behavior under PyPy. 6 | # 7 | # Author : Shunning Jiang 8 | # Date : Feb 12, 2020 9 | 10 | try: 11 | import __pypy__ 12 | 13 | def _normalize_dict( _dict ): 14 | # Credit: Lin Cheng 15 | # return the original dictionary if not running on PyPy 16 | try: 17 | from __pypy__ import newdict, strategy 18 | except Exception: 19 | return _dict 20 | 21 | # return the original dictionary if already using ModuleDictStrategy 22 | if strategy( _dict ) == "ModuleDictStrategy": 23 | return _dict 24 | # create a new module dict 25 | new_dict = newdict("module") 26 | # copy over entries 27 | for key, value in _dict.items(): 28 | new_dict[key] = value 29 | return new_dict 30 | 31 | def custom_exec( prog, _globals, _locals ): 32 | assert _globals is not None 33 | assert _locals is not None 34 | 35 | norm_globals = _globals 36 | norm_locals = _locals 37 | if _globals is not None: 38 | norm_globals = _normalize_dict( _globals ) 39 | if _locals is not None: 40 | norm_locals = _normalize_dict( _locals ) 41 | 42 | exec( prog, norm_globals, norm_locals ) 43 | # Local may have more stuff generated by the code. 44 | # We need to put this back to the original _locals 45 | if _locals is not None: 46 | _locals.update( norm_locals ) 47 | 48 | except Exception: 49 | custom_exec = exec 50 | -------------------------------------------------------------------------------- /pymtl3/extra/pypy/fast_bytearray_funcs.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # fast_bytearray_funcs.py 3 | #========================================================================= 4 | # 5 | # Author : Shunning Jiang 6 | # Date : Feb 25, 2020 7 | 8 | try: 9 | from mamba import read_bytearray_bits 10 | except: 11 | from pymtl3.datatypes import Bits 12 | 13 | def read_bytearray_bits( arr, addr, nbytes ): 14 | ret = 0 15 | begin = int(addr) 16 | addr = begin + nbytes - 1 17 | 18 | while addr >= begin: 19 | ret = (ret << 8) + arr[addr] 20 | addr -= 1 21 | 22 | return Bits( nbytes << 3, ret ) 23 | 24 | try: 25 | from mamba import write_bytearray_bits 26 | except: 27 | from pymtl3.datatypes import Bits 28 | 29 | def write_bytearray_bits( arr, addr, nbytes, data ): 30 | addr = int(addr) 31 | end = addr + nbytes 32 | 33 | while addr < end: 34 | arr[addr] = data & 255 35 | data >>= 8 36 | addr += 1 37 | -------------------------------------------------------------------------------- /pymtl3/passes/BasePass.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | BasePass.py 4 | ======================================================================== 5 | An "abstract" base class for all passes. 6 | 7 | Author : Shunning Jiang 8 | Date : Dec 17, 2017 9 | """ 10 | class PassMetadata: 11 | pass 12 | 13 | class BasePass: 14 | def __init__( self, debug=False ): # initialize parameters 15 | self.debug = debug 16 | 17 | def __call__( self, m ): # execute pass on model m 18 | pass 19 | -------------------------------------------------------------------------------- /pymtl3/passes/PlaceholderConfigs.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # PlaceholderConfigs.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Jul 28, 2019 6 | """Configuration of Placeholders.""" 7 | 8 | import os 9 | 10 | from pymtl3.passes.PassConfigs import BasePassConfigs, Checker 11 | from pymtl3.passes.PlaceholderPass import PlaceholderPass 12 | 13 | 14 | def expand( path ): 15 | return os.path.expanduser(os.path.expandvars(path)) 16 | 17 | class PlaceholderConfigs( BasePassConfigs ): 18 | 19 | Options = { 20 | # Should placeholder passes handle this instance? 21 | "enable" : True, 22 | 23 | # Does the module to be imported has `clk` port? 24 | "has_clk" : True, 25 | 26 | # Does the module to be imported has `reset` port? 27 | "has_reset" : True, 28 | } 29 | 30 | Checkers = { 31 | ("enable", "has_clk", "has_reset") : 32 | Checker( lambda v: isinstance(v, bool), "expects a boolean" ), 33 | } 34 | 35 | Pass = PlaceholderPass 36 | -------------------------------------------------------------------------------- /pymtl3/passes/PlaceholderPass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # PlaceholderPass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Jan 27, 2020 6 | 7 | from pymtl3 import MetadataKey, Placeholder 8 | 9 | from .BasePass import BasePass 10 | from .errors import PlaceholderConfigError 11 | 12 | 13 | class PlaceholderPass( BasePass ): 14 | 15 | # Placeholder pass input pass data 16 | 17 | #: Enable pickling on the placeholder component. 18 | #: 19 | #: Type: ``bool``; input 20 | #: 21 | #: Default value: ``False`` 22 | enable = MetadataKey(bool) 23 | 24 | #: Does the module of external source have clk pin? 25 | #: 26 | #: Type: ``bool``; input 27 | #: 28 | #: Default value: ``False`` 29 | has_clk = MetadataKey(bool) 30 | 31 | #: Does the module of external source have reset pin? 32 | #: 33 | #: Type: ``bool``; input 34 | #: 35 | #: Default value: ``False`` 36 | has_reset = MetadataKey(bool) 37 | 38 | # Placeholder pass output pass data 39 | 40 | #: An instance of :class:`PlaceholderConfigs` that contains the parsed options. 41 | #: 42 | #: Type: ``PlaceholderConfigs``; output 43 | placeholder_config = MetadataKey() 44 | 45 | def __call__( s, m ): 46 | """Pickle every ``Placeholder`` in the component hierarchy rooted at ``m``.""" 47 | if isinstance( m, Placeholder ): 48 | s.visit_placeholder( m ) 49 | for child in m.get_child_components(repr): 50 | s.__call__( child ) 51 | 52 | def visit_placeholder( s, m ): 53 | s.setup_configs( m ) 54 | 55 | def setup_configs( s, m ): 56 | c = s.__class__ 57 | ph_config = c.get_placeholder_config()( m ) 58 | m.set_metadata( c.placeholder_config, ph_config ) 59 | 60 | @staticmethod 61 | def get_placeholder_config(): 62 | from pymtl3.passes.PlaceholderConfigs import PlaceholderConfigs 63 | return PlaceholderConfigs 64 | -------------------------------------------------------------------------------- /pymtl3/passes/__init__.py: -------------------------------------------------------------------------------- 1 | from .PassGroups import * 2 | -------------------------------------------------------------------------------- /pymtl3/passes/adhoc_transform/AddDebugSignalPass.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | AddDebugSignalPass.py 4 | ======================================================================== 5 | TODO currently doesn't support array of components because the uniquification 6 | of added signal names of an array of components is very convoluted. 7 | The verilog translation support is limited for two components of the 8 | same class that have different names of debug signals. 9 | 10 | Author : Shunning Jiang 11 | Date : Jul 5, 2020 12 | """ 13 | 14 | from pymtl3.dsl import Component, InPort, MetadataKey, OutPort 15 | from pymtl3.passes.BasePass import BasePass 16 | 17 | 18 | class AddDebugSignalPass( BasePass ): 19 | 20 | debug_pins = MetadataKey(set) 21 | 22 | def __call__( self, top, signal_names ): 23 | 24 | s_signal_names = [] 25 | for name in signal_names: 26 | assert name.startswith("top.") 27 | assert '[' not in name, "Currently don't support any array of components" 28 | s_signal_names.append( f"s{name[3:]}") 29 | 30 | signals = sorted( top.get_all_object_filter( lambda x: repr(x) in s_signal_names ), 31 | key=repr ) 32 | 33 | for i, signal in enumerate( signals ): 34 | debug_pin_name = f"debug_{i}" 35 | last_port = signal 36 | host = signal.get_host_component() 37 | while host is not None: 38 | this_port = OutPort( last_port.get_type() ) 39 | top.add_value_port( host, debug_pin_name, this_port ) 40 | top.add_connection( this_port, last_port ) 41 | last_port = this_port 42 | host = host.get_parent_object() 43 | -------------------------------------------------------------------------------- /pymtl3/passes/adhoc_transform/__init__.py: -------------------------------------------------------------------------------- 1 | from .AddDebugSignalPass import AddDebugSignalPass 2 | -------------------------------------------------------------------------------- /pymtl3/passes/adhoc_transform/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/adhoc_transform/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/autotick/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/autotick/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/autotick/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/autotick/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/BaseRTLIRTranslator.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BaseRTLIRTranslator.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 11, 2019 6 | """Provide base class and metadata namespace for RTLIR translators.""" 7 | 8 | 9 | class BaseRTLIRTranslator: 10 | """Base class of RTLIR translators.""" 11 | 12 | def __init__( s, top ): 13 | s.top = top 14 | 15 | def clear( s, tr_top ): 16 | s.tr_top = tr_top 17 | s.component = {} 18 | s.hierarchy = TranslatorMetadata() 19 | s.gen_base_rtlir_trans_metadata( s.tr_top ) 20 | 21 | def gen_base_rtlir_trans_metadata( s, m ): 22 | s.component[m] = TranslatorMetadata() 23 | for child in m.get_child_components(repr): 24 | s.gen_base_rtlir_trans_metadata( child ) 25 | 26 | #------------------------------------------------------------------------- 27 | # TranslatorMetadata 28 | #------------------------------------------------------------------------- 29 | 30 | class TranslatorMetadata: 31 | """Metadata namespace used by RTLIR translators.""" 32 | def __init__( s ): 33 | pass 34 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/__init__.py: -------------------------------------------------------------------------------- 1 | from .RTLIRTranslator import RTLIRTranslator 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/BehavioralTranslatorL0.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL0.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 22, 2019 6 | """Provide L0 behavioral translator.""" 7 | 8 | from ..BaseRTLIRTranslator import BaseRTLIRTranslator, TranslatorMetadata 9 | 10 | 11 | class BehavioralTranslatorL0( BaseRTLIRTranslator ): 12 | 13 | def clear( s, tr_top ): 14 | super().clear( tr_top ) 15 | s.behavioral = TranslatorMetadata() 16 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/BehavioralTranslatorL3.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL3.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 22, 2019 6 | """Provide L3 behavioral translator.""" 7 | 8 | from pymtl3.passes.rtlir import RTLIRDataType as rdt 9 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRGenL3Pass import ( 10 | BehavioralRTLIRGenL3Pass, 11 | ) 12 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRTypeCheckL3Pass import ( 13 | BehavioralRTLIRTypeCheckL3Pass, 14 | ) 15 | 16 | from .BehavioralTranslatorL2 import BehavioralTranslatorL2 17 | 18 | 19 | class BehavioralTranslatorL3( BehavioralTranslatorL2 ): 20 | 21 | #----------------------------------------------------------------------- 22 | # _gen_behavioral_trans_metadata 23 | #----------------------------------------------------------------------- 24 | 25 | # Override 26 | def _gen_behavioral_trans_metadata( s, m ): 27 | m.apply( BehavioralRTLIRGenL3Pass( s.tr_top ) ) 28 | m.apply( BehavioralRTLIRTypeCheckL3Pass( s.tr_top ) ) 29 | s.behavioral.rtlir[m] = \ 30 | m.get_metadata( BehavioralRTLIRGenL3Pass.rtlir_upblks ) 31 | s.behavioral.freevars[m] =\ 32 | m.get_metadata( BehavioralRTLIRTypeCheckL3Pass.rtlir_freevars ) 33 | s.behavioral.tmpvars[m] =\ 34 | m.get_metadata( BehavioralRTLIRTypeCheckL3Pass.rtlir_tmpvars ) 35 | 36 | #----------------------------------------------------------------------- 37 | # Freevar datatype dispatch 38 | #----------------------------------------------------------------------- 39 | 40 | def dispatch_freevar_datatype( s, dtype ): 41 | if isinstance( dtype, rdt.Struct ): 42 | return s.rtlir_tr_struct_dtype( dtype ) 43 | else: 44 | return super().dispatch_freevar_datatype( dtype ) 45 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/BehavioralTranslatorL4.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL4.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 22, 2019 6 | """Provide L4 behavioral translator.""" 7 | 8 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRGenL4Pass import ( 9 | BehavioralRTLIRGenL4Pass, 10 | ) 11 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRTypeCheckL4Pass import ( 12 | BehavioralRTLIRTypeCheckL4Pass, 13 | ) 14 | 15 | from .BehavioralTranslatorL3 import BehavioralTranslatorL3 16 | 17 | 18 | class BehavioralTranslatorL4( BehavioralTranslatorL3 ): 19 | 20 | #----------------------------------------------------------------------- 21 | # _gen_behavioral_trans_metadata 22 | #----------------------------------------------------------------------- 23 | 24 | # Override 25 | def _gen_behavioral_trans_metadata( s, m ): 26 | m.apply( BehavioralRTLIRGenL4Pass( s.tr_top ) ) 27 | m.apply( BehavioralRTLIRTypeCheckL4Pass( s.tr_top ) ) 28 | s.behavioral.rtlir[m] = \ 29 | m.get_metadata( BehavioralRTLIRGenL4Pass.rtlir_upblks ) 30 | s.behavioral.freevars[m] =\ 31 | m.get_metadata( BehavioralRTLIRTypeCheckL4Pass.rtlir_freevars ) 32 | s.behavioral.tmpvars[m] =\ 33 | m.get_metadata( BehavioralRTLIRTypeCheckL4Pass.rtlir_tmpvars ) 34 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/BehavioralTranslatorL5.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL5.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 22, 2019 6 | """Provide L5 behavioral translator.""" 7 | 8 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRGenL5Pass import ( 9 | BehavioralRTLIRGenL5Pass, 10 | ) 11 | from pymtl3.passes.rtlir.behavioral.BehavioralRTLIRTypeCheckL5Pass import ( 12 | BehavioralRTLIRTypeCheckL5Pass, 13 | ) 14 | 15 | from .BehavioralTranslatorL4 import BehavioralTranslatorL4 16 | 17 | 18 | class BehavioralTranslatorL5( BehavioralTranslatorL4 ): 19 | def __init__( s, top ): 20 | super().__init__( top ) 21 | 22 | def clear( s, tr_top ): 23 | super().clear( tr_top ) 24 | 25 | #----------------------------------------------------------------------- 26 | # _gen_behavioral_trans_metadata 27 | #----------------------------------------------------------------------- 28 | 29 | # Override 30 | def _gen_behavioral_trans_metadata( s, m ): 31 | m.apply( BehavioralRTLIRGenL5Pass( s.tr_top ) ) 32 | m.apply( BehavioralRTLIRTypeCheckL5Pass( s.tr_top ) ) 33 | s.behavioral.rtlir[m] = \ 34 | m.get_metadata( BehavioralRTLIRGenL5Pass.rtlir_upblks ) 35 | s.behavioral.freevars[m] =\ 36 | m.get_metadata( BehavioralRTLIRTypeCheckL5Pass.rtlir_freevars ) 37 | s.behavioral.tmpvars[m] =\ 38 | m.get_metadata( BehavioralRTLIRTypeCheckL5Pass.rtlir_tmpvars ) 39 | 40 | # Visit the whole component hierarchy because now we have subcomponents 41 | for child in m.get_child_components(repr): 42 | s._gen_behavioral_trans_metadata( child ) 43 | 44 | #----------------------------------------------------------------------- 45 | # translate_behavioral 46 | #----------------------------------------------------------------------- 47 | 48 | # Override 49 | def translate_behavioral( s, m ): 50 | super().translate_behavioral( m ) 51 | for child in m.get_child_components(repr): 52 | s.translate_behavioral( child ) 53 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/__init__.py: -------------------------------------------------------------------------------- 1 | from .BehavioralTranslatorL5 import BehavioralTranslatorL5 as BehavioralTranslator 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/BehavioralTranslatorL1_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL1_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Test the level 1 behavioral translator.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import ( 11 | CaseBits32ArrayClosureConstruct, 12 | CaseBits32ClosureConstruct, 13 | CaseTwoUpblksFreevarsComp, 14 | CaseTwoUpblksSliceComp, 15 | ) 16 | from ..BehavioralTranslatorL1 import BehavioralTranslatorL1 17 | from .TestBehavioralTranslator import mk_TestBehavioralTranslator 18 | 19 | 20 | @pytest.mark.parametrize( 21 | 'case', [ 22 | CaseBits32ClosureConstruct, 23 | CaseBits32ArrayClosureConstruct, 24 | CaseTwoUpblksSliceComp, 25 | CaseTwoUpblksFreevarsComp, 26 | ] 27 | ) 28 | def test_generic_behavioral_L1( case ): 29 | m = case.DUT() 30 | m.elaborate() 31 | tr = mk_TestBehavioralTranslator(BehavioralTranslatorL1)(m) 32 | tr.clear( m ) 33 | tr.translate_behavioral( m ) 34 | upblk_src = tr.behavioral.upblk_srcs[m] 35 | decl_freevars = tr.behavioral.decl_freevars[m] 36 | assert upblk_src == case.REF_UPBLK 37 | assert decl_freevars == case.REF_FREEVAR 38 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/BehavioralTranslatorL2_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL2_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Test the level 2 behavioral translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.dsl.errors import UpdateBlockWriteError 11 | from pymtl3.passes.rtlir.util.test_utility import expected_failure 12 | 13 | from ...testcases import ( 14 | CaseBits32ConstBitsToTmpVarComp, 15 | CaseBits32ConstIntToTmpVarComp, 16 | CaseBits32FreeVarToTmpVarComp, 17 | CaseBits32MultiTmpWireComp, 18 | CaseBits32TmpWireAliasComp, 19 | CaseBits32TmpWireComp, 20 | CaseUpdateffMixAssignComp, 21 | ) 22 | from ..BehavioralTranslatorL2 import BehavioralTranslatorL2 23 | from .TestBehavioralTranslator import mk_TestBehavioralTranslator 24 | 25 | 26 | def run_test( case ): 27 | m = case.DUT() 28 | m.elaborate() 29 | tr = mk_TestBehavioralTranslator(BehavioralTranslatorL2)(m) 30 | tr.clear( m ) 31 | tr.translate_behavioral( m ) 32 | upblk_src = tr.behavioral.upblk_srcs[m] 33 | decl_freevars = tr.behavioral.decl_freevars[m] 34 | decl_tmpvars = tr.behavioral.decl_tmpvars[m] 35 | assert upblk_src == case.REF_UPBLK 36 | assert decl_freevars == case.REF_FREEVAR 37 | assert decl_tmpvars == case.REF_TMPVAR 38 | 39 | @pytest.mark.parametrize( 40 | 'case', [ 41 | CaseBits32TmpWireComp, 42 | CaseBits32TmpWireAliasComp, 43 | CaseBits32MultiTmpWireComp, 44 | CaseBits32FreeVarToTmpVarComp, 45 | CaseBits32ConstBitsToTmpVarComp, 46 | CaseBits32ConstIntToTmpVarComp, 47 | ] 48 | ) 49 | def test_generic_behavioral_L2( case ): 50 | run_test( case ) 51 | 52 | def test_generic_behavioral_L2_updateff_mix_assign(): 53 | with expected_failure( UpdateBlockWriteError ): 54 | run_test( CaseUpdateffMixAssignComp ) 55 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/BehavioralTranslatorL3_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL3_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Test the level 3 behavioral translator.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import CaseStructTmpWireComp, CaseTwoUpblksStructTmpWireComp 11 | from ..BehavioralTranslatorL3 import BehavioralTranslatorL3 12 | from .TestBehavioralTranslator import mk_TestBehavioralTranslator 13 | 14 | 15 | @pytest.mark.parametrize( 16 | 'case', [ 17 | CaseStructTmpWireComp, 18 | CaseTwoUpblksStructTmpWireComp, 19 | ] 20 | ) 21 | def test_generic_behavioral_L3( case ): 22 | m = case.DUT() 23 | m.elaborate() 24 | tr = mk_TestBehavioralTranslator(BehavioralTranslatorL3)(m) 25 | tr.clear( m ) 26 | tr.translate_behavioral( m ) 27 | upblk_src = tr.behavioral.upblk_srcs[m] 28 | decl_freevars = tr.behavioral.decl_freevars[m] 29 | decl_tmpvars = tr.behavioral.decl_tmpvars[m] 30 | assert upblk_src == case.REF_UPBLK 31 | assert decl_freevars == case.REF_FREEVAR 32 | assert decl_tmpvars == case.REF_TMPVAR 33 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/BehavioralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Test the level 4 behavioral translator.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import CaseBits32IfcTmpVarOutComp, CaseStructIfcTmpVarOutComp 11 | from ..BehavioralTranslatorL4 import BehavioralTranslatorL4 12 | from .TestBehavioralTranslator import mk_TestBehavioralTranslator 13 | 14 | 15 | @pytest.mark.parametrize( 16 | 'case', [ 17 | CaseBits32IfcTmpVarOutComp, 18 | CaseStructIfcTmpVarOutComp, 19 | ] 20 | ) 21 | def test_generic_behavioral_L4( case ): 22 | m = case.DUT() 23 | m.elaborate() 24 | tr = mk_TestBehavioralTranslator(BehavioralTranslatorL4)(m) 25 | tr.clear( m ) 26 | tr.translate_behavioral( m ) 27 | upblk_src = tr.behavioral.upblk_srcs[m] 28 | decl_freevars = tr.behavioral.decl_freevars[m] 29 | decl_tmpvars = tr.behavioral.decl_tmpvars[m] 30 | assert upblk_src == case.REF_UPBLK 31 | assert decl_freevars == case.REF_FREEVAR 32 | assert decl_tmpvars == case.REF_TMPVAR 33 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/BehavioralTranslatorL5_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralTranslatorL5_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Test the level 5 ehavioral translator.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import CaseSubCompFreeVarDrivenComp, CaseSubCompTmpDrivenComp 11 | from ..BehavioralTranslatorL5 import BehavioralTranslatorL5 12 | from .TestBehavioralTranslator import mk_TestBehavioralTranslator 13 | 14 | 15 | @pytest.mark.parametrize( 16 | 'case', [ 17 | CaseSubCompTmpDrivenComp, 18 | CaseSubCompFreeVarDrivenComp, 19 | ] 20 | ) 21 | def test_generic_behavioral_L5( case ): 22 | m = case.DUT() 23 | m.elaborate() 24 | tr = mk_TestBehavioralTranslator(BehavioralTranslatorL5)(m) 25 | tr.clear( m ) 26 | tr.translate_behavioral( m ) 27 | upblk_src = tr.behavioral.upblk_srcs[m.subcomp] 28 | decl_freevars = tr.behavioral.decl_freevars[m.subcomp] 29 | decl_tmpvars = tr.behavioral.decl_tmpvars[m.subcomp] 30 | assert upblk_src == case.REF_UPBLK 31 | assert decl_freevars == case.REF_FREEVAR 32 | assert decl_tmpvars == case.REF_TMPVAR 33 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/behavioral/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/generic/behavioral/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/errors.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # errors.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 20, 2019 6 | """Provide exception types for translation errors.""" 7 | 8 | import sys 9 | import traceback 10 | 11 | 12 | class RTLIRTranslationError( Exception ): 13 | """Exception type for errors happening during translation of RTLIR.""" 14 | def __init__( self, obj, msg ): 15 | obj = str(obj) 16 | _, _, tb = sys.exc_info() 17 | tb_info = traceback.extract_tb(tb) 18 | fname, line, func, text = tb_info[-1] 19 | return super().__init__( 20 | f"\nIn file {fname}, Line {line}, Method {func}:" 21 | f"\nError trying to translate top component {obj}:\n- {msg}" 22 | f"\n {text}" ) 23 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/structural/__init__.py: -------------------------------------------------------------------------------- 1 | from .StructuralTranslatorL4 import StructuralTranslatorL4 as StructuralTranslator 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/structural/test/StructuralTranslatorL2_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralTranslatorL2_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 21, 2019 6 | """Test the level 2 structural translators.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import ( 11 | CaseNestedPackedArrayStructComp, 12 | CaseNestedStructPortOnly, 13 | CaseStructConstComp, 14 | CaseStructPortOnly, 15 | CaseStructWireDrivenComp, 16 | CaseStructx5PortOnly, 17 | ) 18 | from ..StructuralTranslatorL2 import StructuralTranslatorL2 19 | from .TestStructuralTranslator import mk_TestStructuralTranslator 20 | 21 | 22 | def run_test( case, m ): 23 | m.elaborate() 24 | tr = mk_TestStructuralTranslator(StructuralTranslatorL2)(m) 25 | tr.clear( m ) 26 | tr.translate_structural(m) 27 | try: 28 | name = tr.structural.component_unique_name[m] 29 | assert name == case.REF_NAME 30 | decl_ports = tr.structural.decl_ports[m] 31 | assert decl_ports == case.REF_PORT 32 | decl_wires = tr.structural.decl_wires[m] 33 | assert decl_wires == case.REF_WIRE 34 | decl_consts = tr.structural.decl_consts[m] 35 | assert decl_consts == case.REF_CONST 36 | connections = tr.structural.connections[m] 37 | assert connections == case.REF_CONN 38 | struct_types = tr.structural.decl_type_struct 39 | 40 | assert sorted(struct_types.items(), key=lambda x: str(x[1])) == case.REF_STRUCT 41 | except AttributeError: 42 | pass 43 | 44 | @pytest.mark.parametrize( 45 | 'case', [ 46 | CaseStructPortOnly, 47 | CaseStructWireDrivenComp, 48 | CaseStructConstComp, 49 | CaseStructx5PortOnly, 50 | CaseNestedStructPortOnly, 51 | CaseNestedPackedArrayStructComp, 52 | ] 53 | ) 54 | def test_generic_structural_L2( case ): 55 | run_test( case, case.DUT() ) 56 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/structural/test/StructuralTranslatorL3_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralTranslatorL3_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 21, 2019 6 | """Test the level 3 structural translators.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import ( 11 | CaseArrayBits32IfcInComp, 12 | CaseConnectArrayNestedIfcComp, 13 | CaseConnectValRdyIfcComp, 14 | ) 15 | from ..StructuralTranslatorL3 import StructuralTranslatorL3 16 | from .TestStructuralTranslator import mk_TestStructuralTranslator 17 | 18 | 19 | def run_test( case, m ): 20 | m.elaborate() 21 | tr = mk_TestStructuralTranslator(StructuralTranslatorL3)(m) 22 | tr.clear( m ) 23 | tr.translate_structural(m) 24 | try: 25 | decl_ifcs = tr.structural.decl_ifcs[m] 26 | assert decl_ifcs == case.REF_IFC 27 | connections = tr.structural.connections[m] 28 | assert connections == case.REF_CONN 29 | except AttributeError: 30 | pass 31 | 32 | @pytest.mark.parametrize( 33 | 'case', [ 34 | CaseConnectValRdyIfcComp, 35 | CaseArrayBits32IfcInComp, 36 | CaseConnectArrayNestedIfcComp, 37 | ] 38 | ) 39 | def test_generic_structural_L3( case ): 40 | run_test( case, case.DUT() ) 41 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/structural/test/StructuralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 21, 2019 6 | """Test the level 3 structural translators.""" 7 | 8 | import pytest 9 | 10 | from ...testcases import ( 11 | CaseBits32ConnectSubCompAttrComp, 12 | CaseConnectSubCompIfcHierarchyComp, 13 | ) 14 | from ..StructuralTranslatorL4 import StructuralTranslatorL4 15 | from .TestStructuralTranslator import mk_TestStructuralTranslator 16 | 17 | 18 | def run_test( case, m ): 19 | m.elaborate() 20 | tr = mk_TestStructuralTranslator(StructuralTranslatorL4)(m) 21 | tr.clear( m ) 22 | tr.translate_structural(m) 23 | connections = tr.structural.connections[m] 24 | assert connections == case.REF_CONN 25 | decl_comp = tr.structural.decl_subcomps[m] 26 | assert decl_comp == case.REF_COMP 27 | 28 | @pytest.mark.parametrize( 29 | 'case', [ 30 | CaseBits32ConnectSubCompAttrComp, 31 | CaseConnectSubCompIfcHierarchyComp, 32 | ] 33 | ) 34 | def test_generic_structural_L4( case ): 35 | run_test( case, case.DUT() ) 36 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/structural/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/generic/structural/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/RTLIRTranslator_L1_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRTranslator_L1_cases_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 23, 2019 6 | """Test the RTLIR translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.rtlir.util.test_utility import expected_failure, get_parameter 11 | 12 | from ..behavioral.test.BehavioralTranslatorL1_test import test_generic_behavioral_L1 13 | from ..errors import RTLIRTranslationError 14 | from ..structural.test.StructuralTranslatorL1_test import test_generic_structural_L1 15 | from .TestRTLIRTranslator import TestRTLIRTranslator 16 | 17 | 18 | def run_test( case, m ): 19 | if not m._dsl.constructed: 20 | m.elaborate() 21 | tr = TestRTLIRTranslator(m) 22 | tr.translate( m ) 23 | src = tr.hierarchy.src 24 | assert src == case.REF_SRC 25 | 26 | @pytest.mark.parametrize( 27 | 'case', get_parameter('case', test_generic_behavioral_L1) + \ 28 | get_parameter('case', test_generic_structural_L1) 29 | ) 30 | def test_generic_L1( case ): 31 | run_test( case, case.DUT() ) 32 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/RTLIRTranslator_L2_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRTranslator_L2_cases_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 23, 2019 6 | """Test the RTLIR translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 11 | 12 | from ..behavioral.test.BehavioralTranslatorL2_test import test_generic_behavioral_L2 13 | from ..structural.test.StructuralTranslatorL2_test import test_generic_structural_L2 14 | from .TestRTLIRTranslator import TestRTLIRTranslator 15 | 16 | 17 | def run_test( case, m ): 18 | if not m._dsl.constructed: 19 | m.elaborate() 20 | tr = TestRTLIRTranslator(m) 21 | tr.translate( m ) 22 | src = tr.hierarchy.src 23 | assert src == case.REF_SRC 24 | 25 | @pytest.mark.parametrize( 26 | 'case', get_parameter('case', test_generic_behavioral_L2) + \ 27 | get_parameter('case', test_generic_structural_L2) 28 | ) 29 | def test_generic_L2( case ): 30 | run_test( case, case.DUT() ) 31 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/RTLIRTranslator_L3_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRTranslator_L3_cases_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 23, 2019 6 | """Test the RTLIR translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 11 | 12 | from ..behavioral.test.BehavioralTranslatorL3_test import test_generic_behavioral_L3 13 | from ..structural.test.StructuralTranslatorL3_test import test_generic_structural_L3 14 | from .TestRTLIRTranslator import TestRTLIRTranslator 15 | 16 | 17 | def run_test( case, m ): 18 | if not m._dsl.constructed: 19 | m.elaborate() 20 | tr = TestRTLIRTranslator(m) 21 | tr.translate( m ) 22 | src = tr.hierarchy.src 23 | assert src == case.REF_SRC 24 | 25 | @pytest.mark.parametrize( 26 | 'case', get_parameter('case', test_generic_behavioral_L3) + \ 27 | get_parameter('case', test_generic_structural_L3) 28 | ) 29 | def test_generic_L3( case ): 30 | run_test( case, case.DUT() ) 31 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/RTLIRTranslator_L4_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRTranslator_L4_cases_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 23, 2019 6 | """Test the RTLIR translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 11 | 12 | from ..behavioral.test.BehavioralTranslatorL4_test import test_generic_behavioral_L4 13 | from ..structural.test.StructuralTranslatorL4_test import test_generic_structural_L4 14 | from .TestRTLIRTranslator import TestRTLIRTranslator 15 | 16 | 17 | def run_test( case, m ): 18 | if not m._dsl.constructed: 19 | m.elaborate() 20 | tr = TestRTLIRTranslator(m) 21 | tr.translate( m ) 22 | src = tr.hierarchy.src 23 | assert src == case.REF_SRC 24 | 25 | @pytest.mark.parametrize( 26 | 'case', get_parameter('case', test_generic_behavioral_L4) + \ 27 | get_parameter('case', test_generic_structural_L4) 28 | ) 29 | def test_generic_L4( case ): 30 | run_test( case, case.DUT() ) 31 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/RTLIRTranslator_L5_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRTranslator_L5_cases_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 23, 2019 6 | """Test the RTLIR translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 11 | 12 | from ..behavioral.test.BehavioralTranslatorL5_test import test_generic_behavioral_L5 13 | from .TestRTLIRTranslator import TestRTLIRTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | if not m._dsl.constructed: 18 | m.elaborate() 19 | tr = TestRTLIRTranslator(m) 20 | tr.translate( m ) 21 | src = tr.hierarchy.src 22 | assert src == case.REF_SRC 23 | 24 | @pytest.mark.parametrize( 25 | 'case', get_parameter('case', test_generic_behavioral_L5) 26 | ) 27 | def test_generic_L5( case ): 28 | run_test( case, case.DUT() ) 29 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/generic/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/generic/testcases/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_cases import * 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/VerilogPlaceholder.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VerilogPlaceholder.py 3 | #========================================================================= 4 | # A placeholder backed by an external Verilog module. 5 | # 6 | # Author : Peitian Pan 7 | # Date : May 11, 2020 8 | 9 | from pymtl3 import Placeholder 10 | 11 | 12 | class VerilogPlaceholder( Placeholder ): 13 | pass 14 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/__init__.py: -------------------------------------------------------------------------------- 1 | from .import_.VerilogVerilatorImportPass import VerilogVerilatorImportPass 2 | from .tbgen.VerilogTBGenPass import VerilogTBGenPass 3 | from .translation.VerilogTranslationPass import VerilogTranslationPass 4 | from .VerilogPlaceholder import VerilogPlaceholder 5 | from .VerilogPlaceholderPass import VerilogPlaceholderPass 6 | from .VerilogTranslationImportPass import VerilogTranslationImportPass 7 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/import_/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VAdder.v: -------------------------------------------------------------------------------- 1 | module VAdder #( parameter nbits = 32 ) 2 | ( 3 | input logic clk, 4 | input logic reset, 5 | input logic [nbits-1:0] in0, 6 | input logic [nbits-1:0] in1, 7 | input logic cin, 8 | output logic [nbits-1:0] out, 9 | output logic cout 10 | ); 11 | 12 | logic [nbits:0] temp; 13 | 14 | always_comb begin 15 | temp = ( in0 + in1 ) + 32'(cin); 16 | end 17 | 18 | assign cout = temp[nbits]; 19 | assign out = temp[nbits-1:0]; 20 | 21 | endmodule 22 | 23 | module test_VAdder #( parameter nbits = 32 ) 24 | ( 25 | input logic clk, 26 | input logic reset, 27 | input logic [nbits-1:0] in0, 28 | input logic [nbits-1:0] in1, 29 | input logic cin, 30 | output logic [nbits-1:0] out, 31 | output logic cout 32 | ); 33 | 34 | logic [nbits:0] temp; 35 | 36 | always_comb begin 37 | temp = ( in0 + in1 ) + 32'(cin); 38 | end 39 | 40 | assign cout = temp[nbits]; 41 | assign out = temp[nbits-1:0]; 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VIncr.v: -------------------------------------------------------------------------------- 1 | module child ( 2 | input [9:0] in_, 3 | output logic [9:0] out 4 | ); 5 | assign out = in_ + 1; 6 | endmodule 7 | 8 | module test_VIncr ( 9 | input [9:0] in_, 10 | output logic [9:0] out, 11 | output logic vcd_en 12 | ); 13 | logic [9:0] child_out; 14 | 15 | child c ( 16 | .in_(in_), 17 | .out(child_out) 18 | ); 19 | 20 | assign out = child_out; 21 | 22 | assign vcd_en = (in_[2:0] >= 4); 23 | endmodule 24 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VPassThrough.v: -------------------------------------------------------------------------------- 1 | module test_VPassThrough 2 | #( 3 | parameter num_ports = 2, 4 | parameter bitwidth = 32 5 | ) 6 | ( 7 | input logic [bitwidth-1:0] in_ [0:num_ports-1], 8 | output logic [bitwidth-1:0] out [0:num_ports-1] 9 | ); 10 | 11 | genvar i; 12 | 13 | generate 14 | for(i = 0; i < num_ports; i= i+1) begin 15 | assign out[i] = in_[i]; 16 | end 17 | endgenerate 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VReg.v: -------------------------------------------------------------------------------- 1 | module test_VReg( 2 | input logic clk, 3 | input logic reset, 4 | output logic [32-1:0] q, 5 | input logic [32-1:0] d 6 | ); 7 | always_ff @(posedge clk) begin 8 | q <= d; 9 | end 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VRegTrace.v: -------------------------------------------------------------------------------- 1 | `include "trace.v" 2 | 3 | module test_VRegTrace( 4 | input logic clk, 5 | input logic reset, 6 | output logic [32-1:0] q, 7 | input logic [32-1:0] d 8 | ); 9 | always_ff @(posedge clk) begin 10 | q <= d; 11 | end 12 | 13 | logic [`VC_TRACE_NBITS-1:0] str; 14 | logic [512*8-1:0] q_str; 15 | `VC_TRACE_BEGIN 16 | begin 17 | /* $display("q = %d\n", q); */ 18 | $sformat(q_str, "%d", q); 19 | vc_trace.append_str( trace_str, "q = " ); 20 | vc_trace.append_str( trace_str, q_str ); 21 | end 22 | `VC_TRACE_END 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/VUninit.v: -------------------------------------------------------------------------------- 1 | module test_VUninit( 2 | input logic clk, 3 | input logic reset, 4 | output logic [32-1:0] q, 5 | input logic [32-1:0] d 6 | ); 7 | 8 | always_comb begin 9 | if (d == 32'd42) 10 | q = 32'd42; 11 | end 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/import_/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/import_/test/pymtl.ini: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # pymtl.ini 3 | #========================================================================= 4 | # This is a PyMTL configuration ini file for testing purposes. This file 5 | # will be used to indicate the simulation root directory and provide some 6 | # helpful project-wide PyMTL configurations. 7 | 8 | #------------------------------------------------------------------------- 9 | # Placeholder configurations 10 | #------------------------------------------------------------------------- 11 | 12 | [placeholder] 13 | 14 | # Should PyMTL assume that every placeholder top module name is prefixed 15 | # with the parent directory name? 16 | auto_prefix = yes 17 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/tbgen/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/tbgen/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/tbgen/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/tbgen/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/test/TranslationImport_adhoc_gc_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # TranslationImport_adhoc_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Jun 5, 2019 6 | """Test ad-hoc components with SystemVerilog translation and import.""" 7 | 8 | import gc 9 | import resource 10 | 11 | import pytest 12 | 13 | from pymtl3 import * 14 | from pymtl3.passes.backends.verilog import VerilogPlaceholderPass 15 | 16 | from .. import VerilogTranslationImportPass 17 | 18 | 19 | def _run_case(): 20 | 21 | class DUT( Component ): 22 | def construct( s ): 23 | s.mem = bytearray(1<<29) 24 | s.mem[-1]=1 25 | s.mem[-2]=123 26 | s.mem[1] =12 27 | s.in_ = InPort( Bits32 ) 28 | s.out = OutPort( Bits32 ) 29 | @update 30 | def upblk(): 31 | s.out @= s.in_ + 1 32 | def line_trace( s ): 33 | return f"{s.in_} > {s.out}" 34 | 35 | m = DUT() 36 | m.elaborate() 37 | m.set_metadata( VerilogTranslationImportPass.enable, True ) 38 | m.apply( VerilogPlaceholderPass() ) 39 | m = VerilogTranslationImportPass()( m ) 40 | 41 | m.apply( DefaultPassGroup() ) 42 | m.sim_reset() 43 | 44 | m.in_ @= Bits32(123) 45 | m.sim_tick() 46 | assert m.out == 124 47 | 48 | m.finalize() 49 | gc.collect() 50 | print("python process memory usage:", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss//1024," MB") 51 | 52 | def test_verilog_translation_import_adhoc(): 53 | for i in range(10): 54 | _run_case() 55 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/testcases/VReg.v: -------------------------------------------------------------------------------- 1 | module VReg( 2 | input logic clk, 3 | input logic reset, 4 | output logic [32-1:0] q, 5 | input logic [32-1:0] d 6 | ); 7 | always_ff @(posedge clk) begin 8 | q <= d; 9 | end 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/testcases/VRegPassThrough.v: -------------------------------------------------------------------------------- 1 | // We do not explicitly include VReg here. Instead we assume the include 2 | // directory or the v_lib is correctly passed to Verilator. 3 | 4 | module VRegPassThrough( 5 | input logic clk, 6 | input logic reset, 7 | output logic [32-1:0] q, 8 | input logic [32-1:0] d 9 | ); 10 | 11 | VReg inner_reg( 12 | .clk(clk), 13 | .reset(reset), 14 | .q(q), 15 | .d(d) 16 | ); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/testcases/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_cases import * 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/VerilogTranslationConfigs.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VerilogTranslationConfigs.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Jan 28, 2020 6 | 7 | from pymtl3.passes.backends.verilog import VerilogTranslationPass 8 | from pymtl3.passes.PassConfigs import BasePassConfigs, Checker 9 | 10 | 11 | class VerilogTranslationConfigs( BasePassConfigs ): 12 | 13 | Options = { 14 | # Translate the current instance? 15 | "enable" : False, 16 | 17 | # Give an explicit file name to the translated source 18 | "explicit_file_name" : "", 19 | 20 | # Give an explicit module name to the translated component 21 | "explicit_module_name" : "", 22 | 23 | # Remove module definition during synthesis 24 | # Note that this could be applied to non-top modules 25 | "no_synthesis" : False, 26 | 27 | # This module does not have clk pin during synthesis 28 | # Note that this could be applied to non-top modules 29 | # This option can only be enabled if no_synthesis is True 30 | "no_synthesis_no_clk" : False, 31 | 32 | # This module does not have reset pin during synthesis 33 | # Note that this could be applied to non-top modules 34 | # This option can only be enabled if no_synthesis is True 35 | "no_synthesis_no_reset" : False, 36 | } 37 | 38 | Checkers = { 39 | ("enable", "no_synthesis", "no_synthesis_no_clk", "no_synthesis_no_reset") : 40 | Checker( lambda v: isinstance( v, bool ), "expects a boolean" ), 41 | 42 | ("explicit_file_name", "explicit_module_name") : 43 | Checker( lambda v: isinstance(v, str), "expects a string" ) 44 | } 45 | 46 | Pass = VerilogTranslationPass 47 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/translation/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/behavioral/VBehavioralTranslatorL0.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VBehavioralTranslatorL0.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : March 18, 2019 6 | """Provide the level 0 SystemVerilog translator implementation.""" 7 | 8 | from pymtl3.passes.backends.generic.behavioral.BehavioralTranslatorL0 import ( 9 | BehavioralTranslatorL0, 10 | ) 11 | 12 | 13 | class VBehavioralTranslatorL0( BehavioralTranslatorL0 ): 14 | pass 15 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/behavioral/__init__.py: -------------------------------------------------------------------------------- 1 | from .VBehavioralTranslatorL5 import VBehavioralTranslatorL5 as VBehavioralTranslator 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/behavioral/test/VBehavioralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VBehavioralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 28, 2019 6 | """Test the SystemVerilog translator implementation.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 11 | from pymtl3.passes.rtlir import BehavioralRTLIRGenPass, BehavioralRTLIRTypeCheckPass 12 | from pymtl3.passes.rtlir.util.test_utility import expected_failure 13 | 14 | from ....errors import VerilogTranslationError 15 | from ....testcases import ( 16 | CaseArrayBits32IfcInUpblkComp, 17 | CaseConnectValRdyIfcUpblkComp, 18 | CaseInterfaceArrayNonStaticIndexComp, 19 | ) 20 | from ..VBehavioralTranslatorL4 import BehavioralRTLIRToVVisitorL4 21 | 22 | 23 | def run_test( case, m ): 24 | m.elaborate() 25 | m.apply( BehavioralRTLIRGenPass( m ) ) 26 | m.apply( BehavioralRTLIRTypeCheckPass( m ) ) 27 | 28 | visitor = BehavioralRTLIRToVVisitorL4(lambda x: x in verilog_reserved) 29 | upblks = m.get_metadata( BehavioralRTLIRGenPass.rtlir_upblks ) 30 | m_all_upblks = m.get_update_blocks() 31 | assert len(m_all_upblks) == 1 32 | 33 | for blk in m_all_upblks: 34 | upblk_src = visitor.enter( blk, upblks[blk] ) 35 | upblk_src = "\n".join( upblk_src ) 36 | assert upblk_src + '\n' == case.REF_UPBLK 37 | 38 | @pytest.mark.parametrize( 39 | 'case', [ 40 | CaseConnectValRdyIfcUpblkComp, 41 | CaseArrayBits32IfcInUpblkComp, 42 | CaseInterfaceArrayNonStaticIndexComp, 43 | ] 44 | ) 45 | def test_verilog_behavioral_L4( case ): 46 | run_test( case, case.DUT() ) 47 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/behavioral/test/VBehavioralTranslatorL5_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VBehavioralTranslatorL5_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 28, 2019 6 | """Test the SystemVerilog translator implementation.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 11 | from pymtl3.passes.rtlir import BehavioralRTLIRGenPass, BehavioralRTLIRTypeCheckPass 12 | 13 | from ....testcases import ( 14 | CaseBehavioralArraySubCompArrayStructIfcComp, 15 | CaseBits32ArraySubCompAttrUpblkComp, 16 | CaseBits32SubCompAttrUpblkComp, 17 | ) 18 | from ..VBehavioralTranslatorL5 import BehavioralRTLIRToVVisitorL5 19 | 20 | 21 | def run_test( case, m ): 22 | m.elaborate() 23 | visitor = BehavioralRTLIRToVVisitorL5(lambda x: x in verilog_reserved) 24 | 25 | m.apply( BehavioralRTLIRGenPass( m ) ) 26 | m.apply( BehavioralRTLIRTypeCheckPass( m ) ) 27 | upblks = m.get_metadata( BehavioralRTLIRGenPass.rtlir_upblks ) 28 | m_all_upblks = m.get_update_blocks() 29 | assert len(m_all_upblks) == 1 30 | 31 | for blk in m_all_upblks: 32 | upblk_src = visitor.enter( blk, upblks[blk] ) 33 | upblk_src = "\n".join( upblk_src ) 34 | assert upblk_src + '\n' == case.REF_UPBLK 35 | 36 | @pytest.mark.parametrize( 37 | 'case', [ 38 | CaseBits32SubCompAttrUpblkComp, 39 | CaseBits32ArraySubCompAttrUpblkComp, 40 | CaseBehavioralArraySubCompArrayStructIfcComp, 41 | ] 42 | ) 43 | def test_verilog_behavioral_L5( case ): 44 | run_test( case, case.DUT() ) 45 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/behavioral/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/translation/behavioral/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/structural/__init__.py: -------------------------------------------------------------------------------- 1 | from .VStructuralTranslatorL4 import VStructuralTranslatorL4 as VStructuralTranslator 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/structural/test/VStructuralTranslatorL2_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VStructuralTranslatorL2_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 29, 2019 6 | """Test the level 2 SystemVerilog structural translator.""" 7 | 8 | from collections import deque 9 | 10 | import pytest 11 | 12 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 13 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 14 | 15 | from ....testcases import ( 16 | CaseConnectArrayStructAttrToOutComp, 17 | CaseConnectConstStructAttrToOutComp, 18 | CaseConnectLiteralStructComp, 19 | CaseConnectNestedStructPackedArrayComp, 20 | ) 21 | from ..VStructuralTranslatorL2 import VStructuralTranslatorL2 22 | 23 | 24 | def run_test( case, m ): 25 | m.elaborate() 26 | VStructuralTranslatorL2.is_verilog_reserved = lambda s, x: x in verilog_reserved 27 | tr = VStructuralTranslatorL2( m ) 28 | tr.clear( m ) 29 | tr._rtlir_tr_unpacked_q = deque() 30 | tr.translate_structural( m ) 31 | 32 | ports = tr.structural.decl_ports[m] 33 | wires = tr.structural.decl_wires[m] 34 | structs = tr.structural.decl_type_struct 35 | conns = tr.structural.connections[m] 36 | 37 | check_eq( ports, case.REF_PORT ) 38 | check_eq( wires, case.REF_WIRE ) 39 | check_eq( conns, case.REF_CONN ) 40 | 41 | assert list(structs.keys())[-1] == case.REF_STRUCT[0] 42 | check_eq( list(structs.values())[-1]['def'], case.REF_STRUCT[1] ) 43 | 44 | @pytest.mark.parametrize( 45 | 'case', [ 46 | CaseConnectConstStructAttrToOutComp, 47 | CaseConnectLiteralStructComp, 48 | CaseConnectArrayStructAttrToOutComp, 49 | CaseConnectNestedStructPackedArrayComp, 50 | ] 51 | ) 52 | def test_verilog_structural_L2( case ): 53 | run_test( case, case.DUT() ) 54 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/structural/test/VStructuralTranslatorL3_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VStructuralTranslatorL3_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 29, 2019 6 | """Test the level 3 SystemVerilog structural translator.""" 7 | 8 | from collections import deque 9 | 10 | import pytest 11 | 12 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 13 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 14 | 15 | from ....testcases import ( 16 | CaseConnectArrayBits32FooIfcComp, 17 | CaseConnectArrayNestedIfcComp, 18 | CaseConnectValRdyIfcComp, 19 | ) 20 | from ..VStructuralTranslatorL3 import VStructuralTranslatorL3 21 | 22 | 23 | def run_test( case, m ): 24 | m.elaborate() 25 | VStructuralTranslatorL3.is_verilog_reserved = lambda s, x: x in verilog_reserved 26 | tr = VStructuralTranslatorL3( m ) 27 | tr.clear( m ) 28 | tr._rtlir_tr_unpacked_q = deque() 29 | tr.translate_structural( m ) 30 | 31 | ifcs = tr.structural.decl_ifcs[m] 32 | conns = tr.structural.connections[m] 33 | 34 | check_eq( ifcs, case.REF_IFC ) 35 | check_eq( conns, case.REF_CONN ) 36 | 37 | @pytest.mark.parametrize( 38 | 'case', [ 39 | CaseConnectValRdyIfcComp, 40 | CaseConnectArrayBits32FooIfcComp, 41 | CaseConnectArrayNestedIfcComp, 42 | ] 43 | ) 44 | def test_verilog_structural_L3( case ): 45 | run_test( case, case.DUT() ) 46 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/structural/test/VStructuralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VStructuralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 29, 2019 6 | """Test the level 4 SystemVerilog structural translator.""" 7 | 8 | from collections import deque 9 | 10 | import pytest 11 | 12 | from pymtl3.passes.backends.verilog import VerilogPlaceholderPass 13 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 14 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 15 | 16 | from ....testcases import ( 17 | CaseBits32ArrayConnectSubCompAttrComp, 18 | CaseBits32ConnectSubCompAttrComp, 19 | CaseChildExplicitModuleName, 20 | CaseConnectArraySubCompArrayStructIfcComp, 21 | CaseHeteroCompArrayComp, 22 | ) 23 | from ..VStructuralTranslatorL4 import VStructuralTranslatorL4 24 | 25 | 26 | def run_test( case, m ): 27 | m.elaborate() 28 | VStructuralTranslatorL4.is_verilog_reserved = lambda s, x: x in verilog_reserved 29 | tr = VStructuralTranslatorL4( m ) 30 | tr._placeholder_pass = VerilogPlaceholderPass 31 | tr.clear( m ) 32 | tr._rtlir_tr_unpacked_q = deque() 33 | tr.translate_structural( m ) 34 | subcomps = tr.structural.decl_subcomps 35 | 36 | check_eq( subcomps[m], case.REF_COMP ) 37 | 38 | @pytest.mark.parametrize( 39 | 'case', [ 40 | CaseBits32ConnectSubCompAttrComp, 41 | CaseConnectArraySubCompArrayStructIfcComp, 42 | CaseBits32ArrayConnectSubCompAttrComp, 43 | CaseHeteroCompArrayComp, 44 | ] 45 | ) 46 | def test_verilog_structural_L4( case ): 47 | run_test( case, case.DUT() ) 48 | 49 | def test_verilog_structural_L4_child_explicit_module_name(): 50 | run_test( CaseChildExplicitModuleName, CaseChildExplicitModuleName.DUT() ) 51 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/structural/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/translation/structural/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/test/VTranslator_L1_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VTranslator_L1_cases_test.py 3 | #========================================================================= 4 | """Test the SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.VBehavioralTranslatorL1_test import test_verilog_behavioral_L1 12 | from ..structural.test.VStructuralTranslatorL1_test import test_verilog_structural_L1 13 | from ..VTranslator import VTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = VTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_verilog_structural_L1) + \ 24 | get_parameter('case', test_verilog_behavioral_L1) 25 | ) 26 | def test_verilog_L1( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/test/VTranslator_L3_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VTranslator_L3_cases_test.py 3 | #========================================================================= 4 | """Test the SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.VBehavioralTranslatorL4_test import test_verilog_behavioral_L4 12 | from ..structural.test.VStructuralTranslatorL3_test import test_verilog_structural_L3 13 | from ..VTranslator import VTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = VTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_verilog_behavioral_L4) + \ 24 | get_parameter('case', test_verilog_structural_L3) 25 | ) 26 | def test_verilog_L3( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/test/VTranslator_L4_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VTranslator_L4_cases_test.py 3 | #========================================================================= 4 | """Test the SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.VBehavioralTranslatorL5_test import test_verilog_behavioral_L5 12 | from ..structural.test.VStructuralTranslatorL4_test import test_verilog_structural_L4 13 | from ..VTranslator import VTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = VTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_verilog_behavioral_L5) + \ 24 | get_parameter('case', test_verilog_structural_L4) 25 | ) 26 | def test_verilog_L4( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/translation/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/translation/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/verilog/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/verilog/util/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/YosysTranslationImportPass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysTranslationImportPass.py 3 | #========================================================================= 4 | # Translate and import components in the given hierarchy. 5 | # 6 | # Author : Peitian Pan 7 | # Date : Aug 6, 2019 8 | 9 | from pymtl3.passes.backends.verilog.VerilogTranslationImportPass import ( 10 | VerilogTranslationImportPass, 11 | ) 12 | 13 | from .import_.YosysVerilatorImportPass import YosysVerilatorImportPass 14 | from .translation.YosysTranslationPass import YosysTranslationPass 15 | 16 | 17 | class YosysTranslationImportPass( VerilogTranslationImportPass ): 18 | 19 | @staticmethod 20 | def get_translation_pass(): 21 | return YosysTranslationPass 22 | 23 | @staticmethod 24 | def get_import_pass(): 25 | return YosysVerilatorImportPass 26 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/__init__.py: -------------------------------------------------------------------------------- 1 | from ..verilog.VerilogPlaceholder import VerilogPlaceholder as YosysPlaceholder 2 | from ..verilog.VerilogPlaceholderPass import ( 3 | VerilogPlaceholderPass as YosysPlaceholderPass, 4 | ) 5 | from .import_.YosysVerilatorImportPass import YosysVerilatorImportPass 6 | from .translation.YosysTranslationPass import YosysTranslationPass 7 | from .YosysTranslationImportPass import YosysTranslationImportPass 8 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/import_/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/import_/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/import_/test/ImportedObject_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # ImportedObject_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Jun 2, 2019 6 | """Test if the imported object works correctly.""" 7 | 8 | from pymtl3.passes.backends.verilog import VerilogPlaceholderPass 9 | from pymtl3.passes.backends.verilog.import_.test.ImportedObject_test import ( 10 | test_adder, 11 | test_normal_queue_implicit_top_module, 12 | test_normal_queue_interface, 13 | test_normal_queue_params, 14 | test_reg, 15 | test_reg_external_trace, 16 | test_reg_incomplete_portmap, 17 | test_reg_infer_external_trace, 18 | test_vl_uninit, 19 | ) 20 | from pymtl3.passes.backends.yosys import YosysTranslationImportPass 21 | from pymtl3.passes.rtlir.util.test_utility import do_test 22 | from pymtl3.stdlib.test_utils import TestVectorSimulator 23 | 24 | 25 | def local_do_test( _m ): 26 | _m.elaborate() 27 | if not hasattr( _m, "_no_trans_import" ): 28 | _m.set_metadata( YosysTranslationImportPass.enable, True ) 29 | _m.apply( VerilogPlaceholderPass() ) 30 | m = YosysTranslationImportPass()( _m ) 31 | sim = TestVectorSimulator( m, _m._tvs, _m._tv_in, _m._tv_out ) 32 | sim.run_test() 33 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/import_/test/VNameMangle_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # VNameMangle_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 15, 2019 6 | """Test the SystemVerilog name mangling.""" 7 | 8 | from pymtl3.passes.backends.verilog.import_.test.VNameMangle_test import ( 9 | test_interface, 10 | test_interface_array, 11 | test_nested_interface, 12 | test_nested_interface_port_array, 13 | test_nested_struct, 14 | test_packed_array_port_array, 15 | test_port_2d_array, 16 | test_port_array, 17 | test_port_single, 18 | test_struct_port_array, 19 | test_struct_port_single, 20 | ) 21 | from pymtl3.passes.backends.yosys.util.utility import gen_mapped_ports 22 | from pymtl3.passes.rtlir.util.test_utility import do_test 23 | 24 | 25 | def local_do_test( m ): 26 | m.elaborate() 27 | result = gen_mapped_ports( m, {} ) 28 | assert result == m._ref_ports_yosys 29 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/import_/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/import_/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/test/TranslationImport_closed_loop_component_input_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # TranslationImport_closed_loop_component_input_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 6, 2019 6 | """Closed-loop test cases for translation-import with component and input.""" 7 | 8 | from random import seed 9 | 10 | from pymtl3.passes.backends.verilog.test.TranslationImport_closed_loop_component_input_test import ( 11 | test_adder, 12 | test_mux, 13 | ) 14 | from pymtl3.passes.backends.verilog.util.test_utility import ( 15 | closed_loop_component_input_test, 16 | ) 17 | from pymtl3.passes.rtlir.util.test_utility import do_test 18 | 19 | seed( 0xdeadebeef ) 20 | 21 | def local_do_test( m ): 22 | closed_loop_component_input_test( m, m._tvs, m._tv_in, "yosys" ) 23 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/testcases/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_cases import * 2 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/YosysTranslationPass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysTranslationPass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 8, 2019 6 | """Translate a PyMTL component hierarhcy into yosys-verilog source code.""" 7 | 8 | from pymtl3.passes.backends.verilog import VerilogTranslationPass 9 | 10 | from .YosysTranslator import YosysTranslator 11 | 12 | 13 | class YosysTranslationPass( VerilogTranslationPass ): 14 | 15 | def __call__( s, top ): 16 | s.top = top 17 | s.translator = YosysTranslator( s.top ) 18 | s.traverse_hierarchy( top ) 19 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/translation/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/YosysBehavioralTranslatorL4.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysBehavioralTranslatorL4.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 9, 2019 6 | """Provide the yosys-compatible SystemVerilog L4 behavioral translator.""" 7 | 8 | from pymtl3.passes.backends.verilog.translation.behavioral.VBehavioralTranslatorL4 import ( 9 | BehavioralRTLIRToVVisitorL4, 10 | VBehavioralTranslatorL4, 11 | ) 12 | from pymtl3.passes.rtlir import RTLIRType as rt 13 | 14 | from .YosysBehavioralTranslatorL3 import ( 15 | YosysBehavioralRTLIRToVVisitorL3, 16 | YosysBehavioralTranslatorL3, 17 | ) 18 | 19 | 20 | class YosysBehavioralTranslatorL4( 21 | YosysBehavioralTranslatorL3, VBehavioralTranslatorL4 ): 22 | 23 | def _get_rtlir2v_visitor( s ): 24 | return YosysBehavioralRTLIRToVVisitorL4 25 | 26 | class YosysBehavioralRTLIRToVVisitorL4( 27 | YosysBehavioralRTLIRToVVisitorL3, BehavioralRTLIRToVVisitorL4 ): 28 | 29 | def visit_Attribute( s, node ): 30 | """Return the SystemVerilog representation of an attribute. 31 | 32 | Add support for accessing interface attribute in L4. 33 | """ 34 | if isinstance( node.value.Type, rt.InterfaceView ): 35 | value = s.visit( node.value ) 36 | s.signal_expr_prologue( node ) 37 | attr = node.attr 38 | s.check_res( node, attr ) 39 | node.sexpr['s_attr'] += "__{}" 40 | node.sexpr['attr'].append( attr ) 41 | return s.signal_expr_epilogue(node, f"{value}.{attr}") 42 | 43 | else: 44 | return super().visit_Attribute( node ) 45 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/YosysBehavioralTranslatorL5.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysBehavioralTranslatorL5.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 9, 2019 6 | """Provide the yosys-compatible SystemVerilog L5 behavioral translator.""" 7 | 8 | from pymtl3.passes.backends.verilog.translation.behavioral.VBehavioralTranslatorL5 import ( 9 | BehavioralRTLIRToVVisitorL5, 10 | VBehavioralTranslatorL5, 11 | ) 12 | from pymtl3.passes.rtlir import BehavioralRTLIR as bir 13 | from pymtl3.passes.rtlir import RTLIRType as rt 14 | 15 | from .YosysBehavioralTranslatorL4 import ( 16 | YosysBehavioralRTLIRToVVisitorL4, 17 | YosysBehavioralTranslatorL4, 18 | ) 19 | 20 | 21 | class YosysBehavioralTranslatorL5( 22 | YosysBehavioralTranslatorL4, VBehavioralTranslatorL5 ): 23 | 24 | def _get_rtlir2v_visitor( s ): 25 | return YosysBehavioralRTLIRToVVisitorL5 26 | 27 | class YosysBehavioralRTLIRToVVisitorL5( 28 | YosysBehavioralRTLIRToVVisitorL4, BehavioralRTLIRToVVisitorL5 ): 29 | 30 | def visit_Attribute( s, node ): 31 | """Return the SystemVerilog representation of an attribute. 32 | 33 | Add support for subcomponent attributes in L5. 34 | """ 35 | # Generate subcomponent attribute 36 | if isinstance( node.value.Type, rt.Component ) and\ 37 | not isinstance( node.value, bir.Base ): 38 | 39 | value = s.visit( node.value ) 40 | s.signal_expr_prologue( node ) 41 | attr = node.attr 42 | s.check_res( node, attr ) 43 | node.sexpr['s_attr'] += "__{}" 44 | node.sexpr['attr'].append( attr ) 45 | return s.signal_expr_epilogue(node, f"{value}.{attr}") 46 | 47 | return super().visit_Attribute( node ) 48 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/__init__.py: -------------------------------------------------------------------------------- 1 | from .YosysBehavioralTranslatorL5 import ( 2 | YosysBehavioralTranslatorL5 as YosysBehavioralTranslator, 3 | ) 4 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/test/YosysBehavioralTranslatorL3_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysBehavioralTranslatorL3_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 9, 2019 6 | """Test the YosysVerilog translator implementation.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.errors import VerilogTranslationError 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | from pymtl3.passes.rtlir import BehavioralRTLIRGenPass, BehavioralRTLIRTypeCheckPass 13 | 14 | from ....testcases import ( 15 | CaseBits32FooInBits32OutComp, 16 | CaseBits32FooToBits32Comp, 17 | CaseBits32ToBits32FooComp, 18 | CaseConstStructInstComp, 19 | CaseIntToBits32FooComp, 20 | CaseNestedStructPackedArrayUpblkComp, 21 | CaseSizeCastPaddingStructPort, 22 | CaseStructPackedArrayUpblkComp, 23 | CaseTypeBundle, 24 | ) 25 | from ..YosysBehavioralTranslatorL3 import YosysBehavioralRTLIRToVVisitorL3 26 | 27 | 28 | def run_test( case, m ): 29 | m.elaborate() 30 | m.apply( BehavioralRTLIRGenPass( m ) ) 31 | m.apply( BehavioralRTLIRTypeCheckPass( m ) ) 32 | 33 | visitor = YosysBehavioralRTLIRToVVisitorL3(lambda x: x in verilog_reserved) 34 | upblks = m.get_metadata( BehavioralRTLIRGenPass.rtlir_upblks ) 35 | m_all_upblks = m.get_update_blocks() 36 | assert len(m_all_upblks) == 1 37 | 38 | for blk in m_all_upblks: 39 | upblk_src = visitor.enter( blk, upblks[blk] ) 40 | upblk_src = "\n".join( upblk_src ) 41 | assert upblk_src + '\n' == case.REF_UPBLK 42 | 43 | @pytest.mark.parametrize( 44 | 'case', [ 45 | CaseBits32FooInBits32OutComp, 46 | CaseConstStructInstComp, 47 | CaseStructPackedArrayUpblkComp, 48 | CaseNestedStructPackedArrayUpblkComp, 49 | CaseSizeCastPaddingStructPort, 50 | CaseTypeBundle, 51 | CaseBits32FooToBits32Comp, 52 | CaseBits32ToBits32FooComp, 53 | CaseIntToBits32FooComp, 54 | ] 55 | ) 56 | def test_yosys_behavioral_L3( case ): 57 | run_test( case, case.DUT() ) 58 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/test/YosysBehavioralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysBehavioralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 9, 2019 6 | """Test the SystemVerilog translator implementation.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.errors import VerilogTranslationError 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | from pymtl3.passes.rtlir import BehavioralRTLIRGenPass, BehavioralRTLIRTypeCheckPass 13 | from pymtl3.passes.rtlir.util.test_utility import expected_failure 14 | 15 | from ....testcases import ( 16 | CaseArrayBits32IfcInUpblkComp, 17 | CaseConnectValRdyIfcUpblkComp, 18 | CaseInterfaceArrayNonStaticIndexComp, 19 | ) 20 | from ..YosysBehavioralTranslatorL4 import YosysBehavioralRTLIRToVVisitorL4 21 | 22 | 23 | def run_test( case, m ): 24 | m.elaborate() 25 | m.apply( BehavioralRTLIRGenPass( m ) ) 26 | m.apply( BehavioralRTLIRTypeCheckPass( m ) ) 27 | 28 | visitor = YosysBehavioralRTLIRToVVisitorL4(lambda x: x in verilog_reserved) 29 | upblks = m.get_metadata( BehavioralRTLIRGenPass.rtlir_upblks ) 30 | m_all_upblks = m.get_update_blocks() 31 | assert len(m_all_upblks) == 1 32 | 33 | for blk in m_all_upblks: 34 | upblk_src = visitor.enter( blk, upblks[blk] ) 35 | upblk_src = "\n".join( upblk_src ) 36 | assert upblk_src + '\n' == case.REF_UPBLK 37 | 38 | @pytest.mark.parametrize( 39 | 'case', [ 40 | CaseConnectValRdyIfcUpblkComp, 41 | CaseArrayBits32IfcInUpblkComp, 42 | CaseInterfaceArrayNonStaticIndexComp, 43 | ] 44 | ) 45 | def test_yosys_behavioral_L4( case ): 46 | run_test( case, case.DUT() ) 47 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/test/YosysBehavioralTranslatorL5_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysBehavioralTranslatorL5_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 9, 2019 6 | """Test the YosysVerilog translator implementation.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 11 | from pymtl3.passes.rtlir import BehavioralRTLIRGenPass, BehavioralRTLIRTypeCheckPass 12 | 13 | from ....testcases import ( 14 | CaseBehavioralArraySubCompArrayStructIfcComp, 15 | CaseBits32ArraySubCompAttrUpblkComp, 16 | CaseBits32SubCompAttrUpblkComp, 17 | ) 18 | from ..YosysBehavioralTranslatorL5 import YosysBehavioralRTLIRToVVisitorL5 19 | 20 | 21 | def run_test( case, m ): 22 | m.elaborate() 23 | visitor = YosysBehavioralRTLIRToVVisitorL5(lambda x: x in verilog_reserved) 24 | 25 | m.apply( BehavioralRTLIRGenPass( m ) ) 26 | m.apply( BehavioralRTLIRTypeCheckPass( m ) ) 27 | upblks = m.get_metadata( BehavioralRTLIRGenPass.rtlir_upblks ) 28 | m_all_upblks = m.get_update_blocks() 29 | assert len(m_all_upblks) == 1 30 | 31 | for blk in m_all_upblks: 32 | upblk_src = visitor.enter( blk, upblks[blk] ) 33 | upblk_src = "\n".join( upblk_src ) 34 | assert upblk_src + '\n' == case.REF_UPBLK 35 | 36 | @pytest.mark.parametrize( 37 | 'case', [ 38 | CaseBits32SubCompAttrUpblkComp, 39 | CaseBits32ArraySubCompAttrUpblkComp, 40 | CaseBehavioralArraySubCompArrayStructIfcComp, 41 | ] 42 | ) 43 | def test_yosys_behavioral_L5( case ): 44 | run_test( case, case.DUT() ) 45 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/behavioral/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/translation/behavioral/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/__init__.py: -------------------------------------------------------------------------------- 1 | from .YosysStructuralTranslatorL4 import ( 2 | YosysStructuralTranslatorL4 as YosysStructuralTranslator, 3 | ) 4 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/test/YosysStructuralTranslatorL1_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysStructuralTranslatorL1_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 13, 2019 6 | """Test the level 1 yosys-SystemVerilog structural translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | 13 | from ....testcases import ( 14 | CaseBitSelOverBitSelComp, 15 | CaseBitSelOverPartSelComp, 16 | CaseConnectBitsConstToOutComp, 17 | CaseConnectBitSelToOutComp, 18 | CaseConnectConstToOutComp, 19 | CaseConnectInToWireComp, 20 | CaseConnectSliceToOutComp, 21 | CasePartSelOverBitSelComp, 22 | CasePartSelOverPartSelComp, 23 | ) 24 | from ..YosysStructuralTranslatorL1 import YosysStructuralTranslatorL1 25 | 26 | 27 | def run_test( case, m ): 28 | m.elaborate() 29 | YosysStructuralTranslatorL1.is_verilog_reserved = lambda s, x: x in verilog_reserved 30 | tr = YosysStructuralTranslatorL1( m ) 31 | tr.clear( m ) 32 | tr.translate_structural( m ) 33 | 34 | ports = tr.structural.decl_ports[m] 35 | wires = tr.structural.decl_wires[m] 36 | conns = tr.structural.connections[m] 37 | 38 | check_eq( ports["port_decls"], case.REF_PORTS_PORT ) 39 | check_eq( ports["wire_decls"], case.REF_PORTS_WIRE ) 40 | check_eq( ports["connections"], case.REF_PORTS_CONN ) 41 | check_eq( wires, case.REF_WIRE ) 42 | check_eq( conns, case.REF_CONN ) 43 | 44 | @pytest.mark.parametrize( 45 | 'case', [ 46 | CaseConnectInToWireComp, 47 | CaseConnectBitsConstToOutComp, 48 | CaseConnectConstToOutComp, 49 | CaseConnectBitSelToOutComp, 50 | CaseConnectSliceToOutComp, 51 | CaseBitSelOverBitSelComp, 52 | CaseBitSelOverPartSelComp, 53 | CasePartSelOverBitSelComp, 54 | CasePartSelOverPartSelComp, 55 | ] 56 | ) 57 | def test_yosys_structural_L1( case ): 58 | run_test( case, case.DUT() ) 59 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/test/YosysStructuralTranslatorL2_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysStructuralTranslatorL2_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 13, 2019 6 | """Test the level 2 yosys-SystemVerilog structural translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | 13 | from ....testcases import ( 14 | CaseConnectArrayStructAttrToOutComp, 15 | CaseConnectConstStructAttrToOutComp, 16 | CaseConnectLiteralStructComp, 17 | CaseConnectNestedStructPackedArrayComp, 18 | ) 19 | from ..YosysStructuralTranslatorL2 import YosysStructuralTranslatorL2 20 | 21 | 22 | def run_test( case, m ): 23 | m.elaborate() 24 | YosysStructuralTranslatorL2.is_verilog_reserved = lambda s, x: x in verilog_reserved 25 | tr = YosysStructuralTranslatorL2( m ) 26 | tr.clear( m ) 27 | tr.translate_structural( m ) 28 | 29 | ports = tr.structural.decl_ports[m] 30 | wires = tr.structural.decl_wires[m] 31 | conns = tr.structural.connections[m] 32 | 33 | check_eq( ports["port_decls"], case.REF_PORTS_PORT ) 34 | check_eq( ports["wire_decls"], case.REF_PORTS_WIRE ) 35 | check_eq( ports["connections"], case.REF_PORTS_CONN ) 36 | check_eq( wires, case.REF_WIRE ) 37 | check_eq( conns, case.REF_CONN ) 38 | 39 | @pytest.mark.parametrize( 40 | 'case', [ 41 | CaseConnectConstStructAttrToOutComp, 42 | CaseConnectLiteralStructComp, 43 | CaseConnectArrayStructAttrToOutComp, 44 | CaseConnectNestedStructPackedArrayComp, 45 | ] 46 | ) 47 | def test_yosys_structural_L2( case ): 48 | run_test( case, case.DUT() ) 49 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/test/YosysStructuralTranslatorL3_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysStructuralTranslatorL3_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 13, 2019 6 | """Test the level 3 yosys-SystemVerilog structural translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | 13 | from ....testcases import ( 14 | CaseConnectArrayBits32FooIfcComp, 15 | CaseConnectArrayNestedIfcComp, 16 | CaseConnectValRdyIfcComp, 17 | ) 18 | from ..YosysStructuralTranslatorL3 import YosysStructuralTranslatorL3 19 | 20 | 21 | def run_test( case, m ): 22 | m.elaborate() 23 | YosysStructuralTranslatorL3.is_verilog_reserved = lambda s, x: x in verilog_reserved 24 | tr = YosysStructuralTranslatorL3( m ) 25 | tr.clear( m ) 26 | tr.translate_structural( m ) 27 | 28 | ports = tr.structural.decl_ifcs[m] 29 | conns = tr.structural.connections[m] 30 | 31 | check_eq( ports["port_decls"], case.REF_IFC_PORT ) 32 | check_eq( ports["wire_decls"], case.REF_IFC_WIRE ) 33 | check_eq( ports["connections"], case.REF_IFC_CONN ) 34 | check_eq( conns, case.REF_CONN ) 35 | 36 | @pytest.mark.parametrize( 37 | 'case', [ 38 | CaseConnectValRdyIfcComp, 39 | CaseConnectArrayBits32FooIfcComp, 40 | CaseConnectArrayNestedIfcComp, 41 | ] 42 | ) 43 | def test_yosys_structural_L3( case ): 44 | run_test( case, case.DUT() ) 45 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/test/YosysStructuralTranslatorL4_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysStructuralTranslatorL4_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : June 13, 2019 6 | """Test the level 4 yosys-SystemVerilog structural translator.""" 7 | 8 | import pytest 9 | 10 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 11 | from pymtl3.passes.backends.verilog.util.utility import verilog_reserved 12 | 13 | from ....testcases import ( 14 | CaseBits32ArrayConnectSubCompAttrComp, 15 | CaseBits32ConnectSubCompAttrComp, 16 | CaseConnectArraySubCompArrayStructIfcComp, 17 | ) 18 | from ..YosysStructuralTranslatorL4 import YosysStructuralTranslatorL4 19 | 20 | 21 | def run_test( case, m ): 22 | m.elaborate() 23 | YosysStructuralTranslatorL4.is_verilog_reserved = lambda s, x: x in verilog_reserved 24 | tr = YosysStructuralTranslatorL4( m ) 25 | tr.clear( m ) 26 | tr.translate_structural( m ) 27 | 28 | comps = tr.structural.decl_subcomps[m] 29 | 30 | check_eq( comps["port_decls"], case.REF_COMP_PORT ) 31 | check_eq( comps["wire_decls"], case.REF_COMP_WIRE ) 32 | check_eq( comps["connections"], case.REF_COMP_CONN ) 33 | 34 | @pytest.mark.parametrize( 35 | 'case', [ 36 | CaseBits32ConnectSubCompAttrComp, 37 | CaseConnectArraySubCompArrayStructIfcComp, 38 | CaseBits32ArrayConnectSubCompAttrComp, 39 | ] 40 | ) 41 | def test_yosys_structural_L4( case ): 42 | run_test( case, case.DUT() ) 43 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/structural/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/translation/structural/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/test/YosysTranslator_L1_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysTranslator_L1_cases_test.py 3 | #========================================================================= 4 | """Test the yosys-SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.YosysBehavioralTranslatorL1_test import test_yosys_behavioral_L1 12 | from ..structural.test.YosysStructuralTranslatorL1_test import test_yosys_structural_L1 13 | from ..YosysTranslator import YosysTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = YosysTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_yosys_behavioral_L1) + \ 24 | get_parameter('case', test_yosys_structural_L1) 25 | ) 26 | def test_yosys_L1( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/test/YosysTranslator_L3_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysTranslator_L3_cases_test.py 3 | #========================================================================= 4 | """Test the yosys-SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.YosysBehavioralTranslatorL4_test import test_yosys_behavioral_L4 12 | from ..structural.test.YosysStructuralTranslatorL3_test import test_yosys_structural_L3 13 | from ..YosysTranslator import YosysTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = YosysTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_yosys_behavioral_L4) + \ 24 | get_parameter('case', test_yosys_structural_L3) 25 | ) 26 | def test_yosys_L3( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/test/YosysTranslator_L4_cases_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # YosysTranslator_L4_cases_test.py 3 | #========================================================================= 4 | """Test the yosys-SystemVerilog translator.""" 5 | 6 | import pytest 7 | 8 | from pymtl3.passes.backends.verilog.util.test_utility import check_eq 9 | from pymtl3.passes.rtlir.util.test_utility import get_parameter 10 | 11 | from ..behavioral.test.YosysBehavioralTranslatorL5_test import test_yosys_behavioral_L5 12 | from ..structural.test.YosysStructuralTranslatorL4_test import test_yosys_structural_L4 13 | from ..YosysTranslator import YosysTranslator 14 | 15 | 16 | def run_test( case, m ): 17 | m.elaborate() 18 | tr = YosysTranslator( m ) 19 | tr.translate( m ) 20 | check_eq( tr.hierarchy.src, case.REF_SRC ) 21 | 22 | @pytest.mark.parametrize( 23 | 'case', get_parameter('case', test_yosys_behavioral_L5) + \ 24 | get_parameter('case', test_yosys_structural_L4) 25 | ) 26 | def test_yosys_L4( case ): 27 | run_test( case, case.DUT() ) 28 | -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/translation/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/translation/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/backends/yosys/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/backends/yosys/util/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/errors.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | errors.py 4 | ======================================================================== 5 | 6 | Author : Shunning Jiang 7 | Date : Jul 4, 2017 8 | """ 9 | class PassOrderError( Exception ): 10 | """ Raise when applying a pass to a component and some required variable 11 | generated by other passes is missing """ 12 | def __init__( self, var ): 13 | return super().__init__( f"Please first apply other passes to generate model.{var}" ) 14 | 15 | class ModelTypeError( Exception ): 16 | """ Raise when a pass cannot be applied to some component type """ 17 | def __init__( self, typename ): 18 | return super().__init__( f"This pass can only be applied to {typename}" ) 19 | 20 | class TranslationError( Exception ): 21 | """ Raise when translation goes wrong """ 22 | def __init__( self, blk, x ): 23 | return super().__init__( f"{blk.__name__} {x}" ) 24 | 25 | class InvalidPassOption( Exception ): 26 | """ Raised when the given pass option is not valid. """ 27 | def __init__( self, opt, pas ): 28 | return super().__init__(f"\n{opt} is not a valid option of pass {pas}!") 29 | 30 | class InvalidPassOptionValue( Exception ): 31 | """ Raised when the given pass option value is not valid. """ 32 | def __init__( self, opt, val, pas, msg ): 33 | return super().__init__(f"\n{val} is not a valid value for option {opt}" 34 | f" of pass {pas} because {msg}.") 35 | 36 | class PlaceholderConfigError( Exception ): 37 | """ Raised when a placeholder is incorrectly configured. """ 38 | def __init__( self, obj, msg ): 39 | return super().__init__(f"Error while configuring {obj}:\n - {msg}") 40 | -------------------------------------------------------------------------------- /pymtl3/passes/mamba/PassGroups.py: -------------------------------------------------------------------------------- 1 | from ..BasePass import BasePass 2 | from ..sim.GenDAGPass import GenDAGPass 3 | from ..sim.PrepareSimPass import PrepareSimPass 4 | from ..sim.SimpleSchedulePass import SimpleSchedulePass 5 | from ..sim.WrapGreenletPass import WrapGreenletPass 6 | from ..tracing.CLLineTracePass import CLLineTracePass 7 | from ..tracing.LineTraceParamPass import LineTraceParamPass 8 | from .HeuristicTopoPass import HeuristicTopoPass 9 | from .Mamba2020Pass import Mamba2020Pass 10 | from .UnrollSimPass import UnrollSimPass 11 | 12 | 13 | class UnrollSim( BasePass ): 14 | def __init__( s, *, waveform=None, print_line_trace=True, reset_active_high=True ): 15 | s.waveform = waveform 16 | s.print_line_trace = print_line_trace 17 | s.reset_active_high = reset_active_high 18 | 19 | def __call__( s, top ): 20 | top.elaborate() 21 | GenDAGPass()( top ) 22 | WrapGreenletPass()( top ) 23 | SimpleSchedulePass()( top ) 24 | UnrollSimPass(print_line_trace=s.print_line_trace, 25 | reset_active_high=s.reset_active_high)( top ) 26 | 27 | class HeuTopoUnrollSim( BasePass ): 28 | def __init__( s, *, waveform=None, print_line_trace=True, reset_active_high=True ): 29 | s.waveform = waveform 30 | s.print_line_trace = print_line_trace 31 | s.reset_active_high = reset_active_high 32 | 33 | def __call__( s, top ): 34 | top.elaborate() 35 | GenDAGPass()( top ) 36 | WrapGreenletPass()( top ) 37 | HeuristicTopoPass(print_line_trace=s.print_line_trace, 38 | reset_active_high=s.reset_active_high)( top ) 39 | 40 | class Mamba2020( BasePass ): 41 | def __init__( s, *, waveform=None, print_line_trace=True, reset_active_high=True ): 42 | s.waveform = waveform 43 | s.print_line_trace = print_line_trace 44 | s.reset_active_high = reset_active_high 45 | 46 | def __call__( s, top ): 47 | top.elaborate() 48 | GenDAGPass()( top ) 49 | WrapGreenletPass()( top ) 50 | if s.print_line_trace: 51 | CLLineTracePass()( top ) 52 | LineTraceParamPass()( top ) 53 | Mamba2020Pass(print_line_trace=s.print_line_trace, 54 | reset_active_high=s.reset_active_high)( top ) 55 | -------------------------------------------------------------------------------- /pymtl3/passes/mamba/__init__.py: -------------------------------------------------------------------------------- 1 | from .PassGroups import HeuTopoUnrollSim, Mamba2020, UnrollSim 2 | -------------------------------------------------------------------------------- /pymtl3/passes/mamba/test/HeuTopoUnrollSim_test.py: -------------------------------------------------------------------------------- 1 | from pymtl3.datatypes import Bits32 2 | from pymtl3.dsl import * 3 | 4 | from ..PassGroups import HeuTopoUnrollSim 5 | 6 | 7 | def test_very_deep_dag(): 8 | 9 | class Inner(Component): 10 | def construct( s ): 11 | s.in_ = InPort(Bits32) 12 | s.out = OutPort(Bits32) 13 | 14 | @update 15 | def up(): 16 | s.out @= s.in_ + 1 17 | 18 | def done( s ): 19 | return True 20 | 21 | def line_trace( s ): 22 | return "{} > {}".format( s.a, s.b ) 23 | 24 | class Top(Component): 25 | def construct( s, N=2000 ): 26 | s.inners = [ Inner() for i in range(N) ] 27 | for i in range(N-1): 28 | s.inners[i].out //= s.inners[i+1].in_ 29 | 30 | s.out = OutPort(Bits32) 31 | @update_ff 32 | def ff(): 33 | if s.reset: 34 | s.out <<= 0 35 | else: 36 | s.out <<= s.out + s.inners[N-1].out 37 | 38 | def line_trace( s ): 39 | return str(s.inners[-1].out) + " " + str(s.out) 40 | 41 | N = 2000 42 | A = Top( N ) 43 | 44 | A.apply( HeuTopoUnrollSim() ) 45 | A.sim_reset() 46 | 47 | T = 0 48 | while T < 5: 49 | assert A.out == T * N 50 | A.sim_tick() 51 | T += 1 52 | return A 53 | 54 | def test_equal_top_level(): 55 | class A(Component): 56 | def construct( s ): 57 | @update 58 | def up(): 59 | print(1) 60 | 61 | a = A() 62 | a.apply( HeuTopoUnrollSim() ) 63 | a.sim_reset() 64 | 65 | try: 66 | a.reset = 0 67 | a.sim_tick() 68 | except AssertionError as e: 69 | print(e) 70 | assert str(e).startswith("Please use @= to assign top level InPort") 71 | return 72 | -------------------------------------------------------------------------------- /pymtl3/passes/mamba/test/UnrollSim_test.py: -------------------------------------------------------------------------------- 1 | from pymtl3.datatypes import Bits32 2 | from pymtl3.dsl import * 3 | 4 | from ..PassGroups import UnrollSim 5 | 6 | 7 | def test_very_deep_dag(): 8 | 9 | class Inner(Component): 10 | def construct( s ): 11 | s.in_ = InPort(Bits32) 12 | s.out = OutPort(Bits32) 13 | 14 | @update 15 | def up(): 16 | s.out @= s.in_ + 1 17 | 18 | def done( s ): 19 | return True 20 | 21 | def line_trace( s ): 22 | return "{} > {}".format( s.a, s.b ) 23 | 24 | class Top(Component): 25 | def construct( s, N=2000 ): 26 | s.inners = [ Inner() for i in range(N) ] 27 | for i in range(N-1): 28 | s.inners[i].out //= s.inners[i+1].in_ 29 | 30 | s.out = OutPort(Bits32) 31 | @update_ff 32 | def ff(): 33 | if s.reset: 34 | s.out <<= 0 35 | else: 36 | s.out <<= s.out + s.inners[N-1].out 37 | 38 | def line_trace( s ): 39 | return str(s.inners[-1].out) + " " + str(s.out) 40 | 41 | N = 2000 42 | A = Top( N ) 43 | 44 | A.apply( UnrollSim() ) 45 | A.sim_reset() 46 | 47 | T = 0 48 | while T < 5: 49 | assert A.out == T * N 50 | A.sim_tick() 51 | T += 1 52 | return A 53 | 54 | def test_equal_top_level(): 55 | class A(Component): 56 | def construct( s ): 57 | @update 58 | def up(): 59 | print(1) 60 | 61 | a = A() 62 | a.apply( UnrollSim() ) 63 | a.sim_reset() 64 | 65 | try: 66 | a.reset = 0 67 | a.sim_tick() 68 | except AssertionError as e: 69 | print(e) 70 | assert str(e).startswith("Please use @= to assign top level InPort") 71 | return 72 | -------------------------------------------------------------------------------- /pymtl3/passes/mamba/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/mamba/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/RTLIRPass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # RTLIRPass.py 3 | #========================================================================= 4 | # Provides the rtlir_getter metadata key. 5 | # 6 | # Author : Peitian Pan 7 | # Date : May 17, 2020 8 | 9 | from pymtl3 import MetadataKey 10 | from pymtl3.passes.BasePass import BasePass 11 | 12 | 13 | class RTLIRPass( BasePass ): 14 | 15 | #: An RTLIR getter 16 | #: 17 | #: Type: ``RTLIRGetter``; output 18 | rtlir_getter = MetadataKey() 19 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/__init__.py: -------------------------------------------------------------------------------- 1 | """Expose method that returns RTLIR. 2 | 3 | This module exposes get_rtlir method that converts PyMTL components 4 | to RTLIR representation. 5 | """ 6 | from .behavioral import ( 7 | BehavioralRTLIR, 8 | BehavioralRTLIRGenPass, 9 | BehavioralRTLIRTypeCheckPass, 10 | BehavioralRTLIRVisualizationPass, 11 | ) 12 | from .rtype import RTLIRDataType, RTLIRType 13 | from .rtype.RTLIRDataType import get_rtlir_dtype 14 | from .rtype.RTLIRType import RTLIRGetter 15 | from .structural import StructuralRTLIRGenPass, StructuralRTLIRSignalExpr 16 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/behavioral/BehavioralRTLIRGenL4Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralRTLIRGenL4Pass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Oct 20, 2018 6 | """Provide L4 behavioral RTLIR generation pass.""" 7 | 8 | from .BehavioralRTLIRGenL3Pass import ( 9 | BehavioralRTLIRGeneratorL3, 10 | BehavioralRTLIRGenL3Pass, 11 | ) 12 | 13 | 14 | class BehavioralRTLIRGenL4Pass( BehavioralRTLIRGenL3Pass ): 15 | # Override 16 | def get_rtlir_generator_class( s ): 17 | return BehavioralRTLIRGeneratorL4 18 | 19 | class BehavioralRTLIRGeneratorL4( BehavioralRTLIRGeneratorL3 ): 20 | """Behavioral RTLIR generator level 4. 21 | 22 | Do nothing here because attributes have been handled in previous 23 | levels. 24 | """ 25 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/behavioral/BehavioralRTLIRGenL5Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # BehavioralRTLIRGenL5Pass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Oct 20, 2018 6 | """Provide L5 behavioral RTLIR generation pass.""" 7 | 8 | from .BehavioralRTLIRGenL4Pass import ( 9 | BehavioralRTLIRGeneratorL4, 10 | BehavioralRTLIRGenL4Pass, 11 | ) 12 | 13 | 14 | class BehavioralRTLIRGenL5Pass( BehavioralRTLIRGenL4Pass ): 15 | # Override 16 | def get_rtlir_generator_class( s ): 17 | return BehavioralRTLIRGeneratorL5 18 | 19 | class BehavioralRTLIRGeneratorL5( BehavioralRTLIRGeneratorL4 ): 20 | """Behavioral RTLIR generator level 5. 21 | 22 | Do nothing here because attributes have been handled in previous 23 | levels. 24 | """ 25 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/behavioral/__init__.py: -------------------------------------------------------------------------------- 1 | """Expose behavioral RTLIR generation and type check passes. 2 | 3 | PyMTL user should only interact with passes exposed here. 4 | """ 5 | 6 | from .BehavioralRTLIRGenL5Pass import BehavioralRTLIRGenL5Pass as BehavioralRTLIRGenPass 7 | from .BehavioralRTLIRTypeCheckL5Pass import ( 8 | BehavioralRTLIRTypeCheckL5Pass as BehavioralRTLIRTypeCheckPass, 9 | ) 10 | from .BehavioralRTLIRVisualizationPass import BehavioralRTLIRVisualizationPass 11 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/behavioral/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/rtlir/behavioral/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/rtype/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/rtlir/rtype/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/StructuralRTLIRGenL0Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL0Pass.py 3 | #========================================================================= 4 | 5 | from pymtl3 import MetadataKey 6 | from pymtl3.passes.rtlir.RTLIRPass import RTLIRPass 7 | 8 | 9 | class StructuralRTLIRGenL0Pass( RTLIRPass ): 10 | 11 | # Pass metadata 12 | 13 | #: RTLIR type of the component 14 | #: 15 | #: Type: ``RTLIRType.Component``; output 16 | rtlir_type = MetadataKey() 17 | 18 | #: RTLIR of all constants that belong to the component 19 | #: 20 | #: Type: ``list``; output 21 | consts = MetadataKey() 22 | 23 | #: RTLIR of all connections in component 24 | #: 25 | #: Type: ``list``; output 26 | connections = MetadataKey() 27 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/StructuralRTLIRGenL2Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL2Pass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Apr 3, 2019 6 | """Provide L2 structural RTLIR generation pass.""" 7 | 8 | from .StructuralRTLIRGenL1Pass import StructuralRTLIRGenL1Pass 9 | 10 | 11 | class StructuralRTLIRGenL2Pass( StructuralRTLIRGenL1Pass ): 12 | pass 13 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/StructuralRTLIRGenL3Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL3Pass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Apr 3, 2019 6 | """Provide L3 structural RTLIR generation pass.""" 7 | 8 | from .StructuralRTLIRGenL2Pass import StructuralRTLIRGenL2Pass 9 | from .StructuralRTLIRSignalExpr import CurComp 10 | 11 | 12 | class StructuralRTLIRGenL3Pass( StructuralRTLIRGenL2Pass ): 13 | pass 14 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/StructuralRTLIRGenL4Pass.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL4Pass.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Apr 3, 2019 6 | """Provide L4 structural RTLIR generation pass.""" 7 | 8 | from .StructuralRTLIRGenL3Pass import StructuralRTLIRGenL3Pass 9 | 10 | 11 | class StructuralRTLIRGenL4Pass( StructuralRTLIRGenL3Pass ): 12 | """At L4 we need to recursively generate metadata for every component""" 13 | 14 | # Override 15 | def _gen_metadata( s, m ): 16 | super()._gen_metadata( m ) 17 | for child in m.get_child_components(repr): 18 | s._gen_metadata( child ) 19 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/__init__.py: -------------------------------------------------------------------------------- 1 | """Expose structural RTLIR generation pass. 2 | 3 | PyMTL user should only interact with the passes exposed here. 4 | """ 5 | from .StructuralRTLIRGenL4Pass import StructuralRTLIRGenL4Pass as StructuralRTLIRGenPass 6 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/test/StructuralRTLIRGenL2Pass_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL2Pass_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 19, 2019 6 | """Test the generation of level 2 structural RTLIR.""" 7 | 8 | from pymtl3.passes.rtlir.structural.StructuralRTLIRGenL2Pass import ( 9 | StructuralRTLIRGenL2Pass, 10 | ) 11 | from pymtl3.passes.rtlir.structural.StructuralRTLIRSignalExpr import * 12 | from pymtl3.passes.testcases import ( 13 | CaseConnectArrayStructAttrToOutComp, 14 | CaseConnectStructAttrToOutComp, 15 | ) 16 | 17 | from .StructuralRTLIRGenL1Pass_test import gen_connections 18 | 19 | 20 | def test_L2_struct_attr(): 21 | a = CaseConnectStructAttrToOutComp.DUT() 22 | a.elaborate() 23 | a.apply( StructuralRTLIRGenL2Pass( gen_connections( a ) ) ) 24 | connections = a.get_metadata( StructuralRTLIRGenL2Pass.connections ) 25 | comp = CurComp(a, 's') 26 | assert connections == \ 27 | [(StructAttr(CurCompAttr(comp, 'in_'), 'foo'), CurCompAttr(comp, 'out'))] 28 | 29 | def test_L2_packed_index(): 30 | a = CaseConnectArrayStructAttrToOutComp.DUT() 31 | a.elaborate() 32 | a.apply( StructuralRTLIRGenL2Pass( gen_connections( a ) ) ) 33 | connections = a.get_metadata( StructuralRTLIRGenL2Pass.connections ) 34 | comp = CurComp(a, 's') 35 | assert connections == \ 36 | [(PackedIndex(StructAttr(CurCompAttr(comp, 'in_'), 'foo'), 1), 37 | CurCompAttr(comp, 'out'))] 38 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/test/StructuralRTLIRGenL4Pass_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # StructuralRTLIRGenL4Pass_test.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : May 19, 2019 6 | """Test the generation of level 1 structural RTLIR.""" 7 | 8 | from pymtl3.passes.rtlir.structural.StructuralRTLIRGenL4Pass import ( 9 | StructuralRTLIRGenL4Pass, 10 | ) 11 | from pymtl3.passes.rtlir.structural.StructuralRTLIRSignalExpr import * 12 | from pymtl3.passes.testcases import ( 13 | CaseBits32ArrayConnectSubCompAttrComp, 14 | CaseBits32ConnectSubCompAttrComp, 15 | ) 16 | 17 | from ..StructuralRTLIRGenL2Pass import StructuralRTLIRGenL2Pass 18 | from .StructuralRTLIRGenL1Pass_test import gen_connections 19 | 20 | 21 | def test_L4_subcomp_attr(): 22 | a = CaseBits32ConnectSubCompAttrComp.DUT() 23 | a.elaborate() 24 | a.apply( StructuralRTLIRGenL4Pass( gen_connections( a ) ) ) 25 | connections = a.get_metadata( StructuralRTLIRGenL2Pass.connections ) 26 | comp = CurComp(a, 's') 27 | # The first two signals are clk and reset 28 | assert connections[2] == \ 29 | (SubCompAttr(CurCompAttr(comp, 'b'), 'out'), CurCompAttr(comp, 'out')) 30 | 31 | def test_L4_subcomp_index(): 32 | a = CaseBits32ArrayConnectSubCompAttrComp.DUT() 33 | a.elaborate() 34 | a.apply( StructuralRTLIRGenL4Pass( gen_connections( a ) ) ) 35 | connections = a.get_metadata( StructuralRTLIRGenL2Pass.connections ) 36 | comp = CurComp(a, 's') 37 | # The first ten signals are clks and resets 38 | assert connections[10] == \ 39 | (SubCompAttr(ComponentIndex(CurCompAttr(comp, 'b'), 1), 'out'), 40 | CurCompAttr(comp, 'out')) 41 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/structural/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/rtlir/structural/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/rtlir/util/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/util/test_utility.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # test_utility.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Feb 21, 2019 6 | """Test utilities used by RTLIR tests.""" 7 | 8 | from contextlib import contextmanager 9 | 10 | import pytest 11 | 12 | 13 | @pytest.fixture 14 | def do_test( request ): 15 | """Call `local_do_test` of the requesting module.""" 16 | return request.module.local_do_test 17 | 18 | @contextmanager 19 | def expected_failure( exception = Exception, msg = None ): 20 | """Mark one test case as should-fail. 21 | 22 | Not to be confused with pytest.xfail, which is commonly used to mark 23 | tests related to unimplemented functionality. This test only passes when 24 | it throws an expected exception. 25 | """ 26 | try: 27 | yield 28 | except exception as e: 29 | if msg is None or e.args[0].find( msg ) != -1: 30 | return 31 | else: 32 | raise 33 | raise Exception( 'expected-to-fail test unexpectedly passed!' ) 34 | 35 | def get_parameter( name, func ): 36 | """Return the parameter for `name` arg of `func`""" 37 | try: 38 | for mark in func.pytestmark: 39 | if mark.name == 'parametrize': 40 | # Find the position of the given name 41 | pos = -1 42 | for i, arg in enumerate( mark.args[0].split() ): 43 | if arg == name: 44 | pos = i 45 | break 46 | if pos == -1: 47 | raise Exception( f'{func} does not have parameter named {name}!' ) 48 | if len(mark.args[0].split()) == 1: 49 | return mark.args[1] 50 | return list(map(lambda x: x[pos], mark.args[1])) 51 | except AttributeError: 52 | raise Exception( f'given function {func} does not have pytest marks!' ) 53 | -------------------------------------------------------------------------------- /pymtl3/passes/rtlir/util/utility.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # utility.py 3 | #========================================================================= 4 | # Author : Peitian Pan 5 | # Date : Feb 13, 2019 6 | """Helper methods for RTLIR.""" 7 | 8 | from pymtl3.datatypes import is_bitstruct_class 9 | 10 | from ..rtype.RTLIRDataType import get_rtlir_dtype 11 | 12 | 13 | def collect_objs( m, Type ): 14 | """Return a list of members of `m` that are of type `Type`.""" 15 | 16 | def _is_of_type( obj, Type ): 17 | if isinstance(obj, Type): 18 | return True 19 | if isinstance(obj, list): 20 | return all( _is_of_type( x, Type ) for x in obj ) 21 | return False 22 | 23 | ret = [] 24 | for name, obj in vars(m).items(): 25 | if isinstance( name, str ) and name[0] != '_': 26 | if _is_of_type( obj, Type ): 27 | ret.append( ( name, obj ) ) 28 | return ret 29 | 30 | def get_component_full_name( c_rtype ): 31 | 32 | def get_string( obj ): 33 | """Return the string that identifies `obj`""" 34 | if isinstance(obj, type): 35 | if is_bitstruct_class(obj): 36 | return get_rtlir_dtype( obj() ).get_name() 37 | return obj.__name__ 38 | return str( obj ) 39 | 40 | comp_name = c_rtype.get_name() 41 | comp_params = c_rtype.get_params() 42 | assert comp_name 43 | for arg_name, arg_value in comp_params: 44 | assert arg_name != '' 45 | comp_name += '__' + arg_name + '_' + get_string(arg_value) 46 | if not comp_params: 47 | comp_name += '_noparam' 48 | return comp_name 49 | 50 | def get_ordered_upblks( m ): 51 | """Return a list of non-update-ff update blocks that have deterministic order""" 52 | 53 | upblks = m.get_update_blocks() - m.get_update_ff() 54 | return [ x for x in m.get_update_block_order() if x in upblks ] 55 | 56 | def get_ordered_update_ff( m ): 57 | """Return a list of update-ff update blocks that have deterministic order""" 58 | 59 | return [ x for x in m.get_update_block_order() if x in m.get_update_ff() ] 60 | -------------------------------------------------------------------------------- /pymtl3/passes/sim/SimpleTickPass.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | SimpleTickPass.py 4 | ======================================================================== 5 | Generate a simple tick function (no Mamba techniques here) 6 | 7 | Author : Shunning Jiang 8 | Date : Dec 26, 2018 9 | """ 10 | from pymtl3.dsl import MethodPort 11 | from pymtl3.dsl.errors import UpblkCyclicError 12 | from pymtl3.passes.BasePass import BasePass 13 | from pymtl3.passes.errors import PassOrderError 14 | 15 | # Shunning: We are aware of the problem that there may be multiple places 16 | # that assembles the function for the user to tick the simulator. 17 | # I think LLVM applies passes based on the order they are inserted to the 18 | # pass manager. LLVM also has some local ordering mechanism to figure out 19 | # the dependencies between passes. Currently we haven't got to the point 20 | # where we have enough passes to manage, but we should keep this in mind. 21 | 22 | class SimpleTickPass( BasePass ): 23 | 24 | @staticmethod 25 | def gen_tick_function( schedule ): 26 | def iterative(): 27 | for blk in schedule: 28 | blk() 29 | return iterative 30 | -------------------------------------------------------------------------------- /pymtl3/passes/sim/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/sim/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/sim/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/sim/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/passes/testcases/TestCase.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================= 3 | TestCase.py 4 | ========================================================================= 5 | Implement the base TestCase class. 6 | 7 | Author : Peitian Pan 8 | Date : Dec 12, 2019 9 | """ 10 | 11 | from textwrap import dedent 12 | 13 | 14 | class AliasOf: 15 | def __init__( s, alias_name = 'A' ): 16 | s.alias_name = alias_name 17 | 18 | def __get__( s, instance, owner ): 19 | return getattr( owner, s.alias_name ) 20 | 21 | def __set__( s, instance, value ): 22 | # Overwriting an existing alias is not supported yet 23 | raise NotImplementedError 24 | 25 | def set_attributes( _cls, *args ): 26 | assert len( args ) % 2 == 0 27 | # Correctly "copy" a Python class 28 | # https://stackoverflow.com/questions/9541025/how-to-copy-a-python-class 29 | cls = type(_cls.__name__, (_cls,), dict(_cls.__dict__)) 30 | for attr, obj in zip( args[::2], args[1::2] ): 31 | setattr( cls, attr, dedent(obj) if isinstance(obj, str) else obj ) 32 | return cls 33 | -------------------------------------------------------------------------------- /pymtl3/passes/testcases/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_cases import * 2 | from .TestCase import set_attributes 3 | -------------------------------------------------------------------------------- /pymtl3/passes/tracing/LineTraceParamPass.py: -------------------------------------------------------------------------------- 1 | #======================================================================== 2 | # LineTraceParamPass.py 3 | #======================================================================== 4 | # Enable multi-level line trace. 5 | # 6 | # Author : Yanghui Ou 7 | # Date : May 29, 2019 8 | 9 | from pymtl3.dsl import * 10 | from pymtl3.passes.BasePass import BasePass, PassMetadata 11 | 12 | 13 | class LineTraceParamPass( BasePass ): 14 | 15 | def __call__( self, top ): 16 | 17 | def wrap_line_trace( obj ): 18 | if not hasattr( obj, '_ml_trace' ): 19 | obj._ml_trace = PassMetadata() 20 | obj._ml_trace.line_trace = obj.line_trace 21 | 22 | def wrapped_line_trace( self, *args, **kwargs ): 23 | if self._dsl.param_tree is not None: 24 | if self._dsl.param_tree.leaf is not None: 25 | if 'line_trace' in self._dsl.param_tree.leaf: 26 | # TODO: figure out whether it is necessary to enforce no 27 | # positional args. 28 | assert len( args ) == 0 29 | more_args = self._dsl.param_tree.leaf['line_trace'].items() 30 | kwargs.update({ x:y for x, y in more_args }) 31 | try: 32 | return self._ml_trace.line_trace( *args, **kwargs ) 33 | except TypeError: 34 | return self._ml_trace.line_trace() 35 | 36 | obj.line_trace = lambda *args, **kwargs : wrapped_line_trace( obj, *args, **kwargs ) 37 | 38 | all_objects = top.get_all_object_filter( lambda x: True ) 39 | for obj in all_objects: 40 | if hasattr( obj, 'line_trace' ): 41 | wrap_line_trace( obj ) 42 | -------------------------------------------------------------------------------- /pymtl3/passes/tracing/__init__.py: -------------------------------------------------------------------------------- 1 | from .PrintTextWavePass import PrintTextWavePass 2 | from .VcdGenerationPass import VcdGenerationPass 3 | -------------------------------------------------------------------------------- /pymtl3/passes/tracing/test/LineTraceParamPass_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | #========================================================================= 3 | # LineTraceParamPass_test.py 4 | #========================================================================= 5 | # Test for multi-level line trace pass. 6 | # 7 | # Author : Yanghui Ou 8 | # Date : 29 May, 2019 9 | """ 10 | from pymtl3.dsl import * 11 | 12 | from ..LineTraceParamPass import LineTraceParamPass 13 | 14 | 15 | def test_multi_level_trace(): 16 | 17 | class Top( Component ): 18 | def construct( s ): 19 | s.simple_trace = 'simple' 20 | s.verbose_trace = 'verbose' 21 | 22 | def line_trace( s, level='simple' ): 23 | if level == 'simple': 24 | return f"{s.simple_trace}" 25 | elif level == 'verbose': 26 | return f"{s.verbose_trace}" 27 | else: 28 | return "default" 29 | 30 | A = Top() 31 | A.set_param( 'top.line_trace', level='verbose' ) 32 | A.elaborate() 33 | A.apply( LineTraceParamPass() ) 34 | print( A.line_trace() ) 35 | assert A.line_trace() == "verbose" 36 | -------------------------------------------------------------------------------- /pymtl3/passes/tracing/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/passes/tracing/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/__init__.py: -------------------------------------------------------------------------------- 1 | from .arbiters import RoundRobinArbiter, RoundRobinArbiterEn 2 | from .arithmetics import ( 3 | Adder, 4 | And, 5 | Demux, 6 | EqComparator, 7 | Incrementer, 8 | LEComparator, 9 | LeftLogicalShifter, 10 | LTComparator, 11 | Mux, 12 | RightLogicalShifter, 13 | Subtractor, 14 | ZeroComparator, 15 | ) 16 | from .crossbars import Crossbar 17 | from .encoders import Encoder 18 | from .register_files import RegisterFile, RegisterFileRst 19 | from .registers import Reg, RegEn, RegEnRst, RegRst 20 | -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/crossbars.py: -------------------------------------------------------------------------------- 1 | """ 2 | ====================================================================== 3 | Crossbar.py 4 | ====================================================================== 5 | """ 6 | 7 | from pymtl3 import * 8 | 9 | 10 | class Crossbar( Component ): 11 | 12 | def construct( s, nports, dtype ): 13 | 14 | s.in_ = [ InPort ( dtype ) for _ in range( nports ) ] 15 | s.out = [ OutPort ( dtype ) for _ in range( nports ) ] 16 | s.sel = [ InPort ( clog2( nports ) ) for _ in range( nports ) ] 17 | 18 | @update 19 | def comb_logic(): 20 | for i in range( nports ): 21 | s.out[i] @= s.in_[ s.sel[ i ] ] 22 | 23 | def line_trace( s ): 24 | in_str = ' '.join( [ str(x) for x in s.in_ ] ) 25 | sel_str = ' '.join( [ str(x) for x in s.sel ] ) 26 | out_str = ' '.join( [ str(x) for x in s.out ] ) 27 | return f"{in_str} ( {sel_str} ) {out_str}" 28 | -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/encoders.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | Encoder.py 4 | ======================================================================== 5 | A priority encoder for arbitration 6 | 7 | Author : Yanghui Ou, Cheng Tan 8 | Date : Mar 1, 2019 9 | """ 10 | from pymtl3 import * 11 | 12 | 13 | class Encoder( Component ): 14 | def construct( s, in_nbits, out_nbits ): 15 | 16 | # Interface 17 | 18 | s.in_ = InPort( in_nbits ) 19 | s.out = OutPort( out_nbits ) 20 | 21 | # Constants 22 | 23 | s.in_nbits = in_nbits 24 | s.out_nbits = out_nbits 25 | 26 | # Logic 27 | 28 | @update 29 | def encode(): 30 | s.out @= 0 31 | for i in range( s.in_nbits ): 32 | if s.in_[i]: 33 | s.out @= i 34 | 35 | def line_trace( s ): 36 | return "in:{:0>{n}b} | out:{}".format( 37 | int( s.in_ ), s.out, n=s.in_nbits 38 | ) 39 | -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/registers.py: -------------------------------------------------------------------------------- 1 | from pymtl3 import * 2 | 3 | 4 | class Reg( Component ): 5 | 6 | def construct( s, Type ): 7 | s.out = OutPort( Type ) 8 | s.in_ = InPort( Type ) 9 | 10 | @update_ff 11 | def up_reg(): 12 | s.out <<= s.in_ 13 | 14 | def line_trace( s ): 15 | return f"[{s.in_} > {s.out}]" 16 | 17 | class RegEn( Component ): 18 | 19 | def construct( s, Type ): 20 | s.out = OutPort( Type ) 21 | s.in_ = InPort( Type ) 22 | 23 | s.en = InPort() 24 | 25 | @update_ff 26 | def up_regen(): 27 | if s.en: 28 | s.out <<= s.in_ 29 | 30 | def line_trace( s ): 31 | return f"[{'en' if s.en else ' '}|{s.in_} > {s.out}]" 32 | 33 | class RegRst( Component ): 34 | 35 | def construct( s, Type, reset_value=0 ): 36 | s.out = OutPort( Type ) 37 | s.in_ = InPort( Type ) 38 | 39 | @update_ff 40 | def up_regrst(): 41 | if s.reset: s.out <<= reset_value 42 | else: s.out <<= s.in_ 43 | 44 | def line_trace( s ): 45 | return f"[{'rst' if s.reset else ' '}|{s.in_} > {s.out}]" 46 | 47 | class RegEnRst( Component ): 48 | 49 | def construct( s, Type, reset_value=0 ): 50 | s.out = OutPort( Type ) 51 | s.in_ = InPort( Type ) 52 | 53 | s.en = InPort() 54 | 55 | @update_ff 56 | def up_regenrst(): 57 | if s.reset: s.out <<= reset_value 58 | elif s.en: s.out <<= s.in_ 59 | 60 | def line_trace( s ): 61 | return f"[{'en' if s.en else ' '}|{s.in_} > {s.out}]" 62 | -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/basic_rtl/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/test/crossbars_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ====================================================================== 3 | Crossbar_test.py 4 | ====================================================================== 5 | """ 6 | from pymtl3 import * 7 | from pymtl3.stdlib.test_utils import TestVectorSimulator 8 | 9 | from ..crossbars import Crossbar 10 | 11 | 12 | #----------------------------------------------------------------------- 13 | # run_test_crossbar 14 | #----------------------------------------------------------------------- 15 | def run_test_crossbar( model, test_vectors ): 16 | 17 | # Define functions mapping the test vector to ports in model 18 | 19 | def tv_in( model, test_vector ): 20 | n = len( model.in_ ) 21 | 22 | for i in range(n): 23 | model.in_[i] @= test_vector[i] 24 | model.sel[i] @= test_vector[n+i] 25 | 26 | def tv_out( model, test_vector ): 27 | n = len( model.in_ ) 28 | 29 | for i in range(n): 30 | assert model.out[i] == test_vector[n*2+i] 31 | 32 | # Run the test 33 | 34 | sim = TestVectorSimulator( model, test_vectors, tv_in, tv_out ) 35 | sim.run_test() 36 | 37 | #----------------------------------------------------------------------- 38 | # test_crossbar3 39 | #----------------------------------------------------------------------- 40 | 41 | def test_crossbar3(): 42 | run_test_crossbar( Crossbar( 3, Bits16 ), [ 43 | [ 0xdead, 0xbeef, 0xcafe, 0, 1, 2, 0xdead, 0xbeef, 0xcafe ], 44 | [ 0xdead, 0xbeef, 0xcafe, 0, 2, 1, 0xdead, 0xcafe, 0xbeef ], 45 | [ 0xdead, 0xbeef, 0xcafe, 1, 2, 0, 0xbeef, 0xcafe, 0xdead ], 46 | [ 0xdead, 0xbeef, 0xcafe, 1, 0, 2, 0xbeef, 0xdead, 0xcafe ], 47 | [ 0xdead, 0xbeef, 0xcafe, 2, 1, 0, 0xcafe, 0xbeef, 0xdead ], 48 | [ 0xdead, 0xbeef, 0xcafe, 2, 0, 1, 0xcafe, 0xdead, 0xbeef ], 49 | ]) 50 | -------------------------------------------------------------------------------- /pymtl3/stdlib/basic_rtl/test/encoders_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | Encoder_test 4 | ======================================================================== 5 | Test for RTL priority encoder. 6 | 7 | Author : Yanghui Ou 8 | Date : Apr 5, 2019 9 | """ 10 | from pymtl3 import * 11 | from pymtl3.stdlib.test_utils import TestVectorSimulator 12 | 13 | from ..encoders import Encoder 14 | 15 | 16 | def run_test( model, test_vectors ): 17 | 18 | def tv_in( model, test_vector ): 19 | model.in_ @= test_vector[0] 20 | 21 | def tv_out( model, test_vector ): 22 | assert model.out == test_vector[1] 23 | 24 | sim = TestVectorSimulator( model, test_vectors, tv_in, tv_out ) 25 | sim.run_test() 26 | 27 | def test_encoder_5_directed(): 28 | 29 | model = Encoder( 5, 3 ) 30 | run_test( model, [ 31 | # in out 32 | [ 0b00000, 0 ], 33 | [ 0b00001, 0 ], 34 | [ 0b00010, 1 ], 35 | [ 0b00100, 2 ], 36 | [ 0b01100, 3 ], 37 | [ 0b10000, 4 ] 38 | ] ) 39 | -------------------------------------------------------------------------------- /pymtl3/stdlib/connects/__init__.py: -------------------------------------------------------------------------------- 1 | from .connect_bits2bitstruct import connect_bits2bitstruct 2 | from .connect_pairs import connect_pairs 3 | -------------------------------------------------------------------------------- /pymtl3/stdlib/connects/connect_pairs.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | connect_pairs.py 4 | ========================================================================== 5 | Advanced connect functions for different patterns 6 | 7 | Author: Shunning 8 | Date: July 13, 2019 9 | """ 10 | 11 | from pymtl3 import * 12 | 13 | 14 | def connect_pairs( *args ): 15 | 16 | if len(args) & 1 != 0: 17 | raise InvalidConnectionError( "Odd number ({}) of objects provided.".format( len(args) ) ) 18 | 19 | for i in range(len(args)>>1) : 20 | try: 21 | connect( args[ i<<1 ], args[ (i<<1)+1 ] ) 22 | except Exception as e: 23 | args = list(e.args[::]) 24 | args[0] = "[connect_pair] connecting {}-th argument to {}-th argument\n" \ 25 | .format( i<<1, (i<<1)+1 ) + \ 26 | "--------------------\n" + args[0] 27 | e.args = tuple(args) 28 | raise 29 | -------------------------------------------------------------------------------- /pymtl3/stdlib/connects/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/connects/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/delays/StallCL.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================= 3 | StallCL.py 4 | ========================================================================= 5 | Models random stall 6 | 7 | Author : Shunning Jiang 8 | Date : Feb 6, 2020 9 | """ 10 | 11 | from random import Random 12 | 13 | from pymtl3 import * 14 | 15 | # This stall is for testing purpose 16 | # Recv side has a random stall 17 | 18 | class StallCL( Component ): 19 | 20 | # ready <==> stall_rand > stall_prob 21 | @non_blocking( lambda s: s.stall_rgen.random() > s.stall_prob and s.send.rdy() ) 22 | def recv( s, msg ): 23 | s.send( msg ) 24 | 25 | def construct( s, stall_prob=0.5, stall_seed=0x1 ): 26 | 27 | s.send = CallerIfcCL() 28 | 29 | s.stall_prob = stall_prob 30 | s.stall_rgen = Random( stall_seed ) # Separate randgen for each injector 31 | 32 | s.add_constraints( 33 | M(s.recv) == M(s.send), # pass_through 34 | M(s.recv.rdy) == M(s.send.rdy), # pass_through 35 | ) 36 | 37 | 38 | def line_trace( s ): 39 | return f"{s.recv}" 40 | -------------------------------------------------------------------------------- /pymtl3/stdlib/delays/__init__.py: -------------------------------------------------------------------------------- 1 | from .DelayPipeCL import DelayPipeDeqCL, DelayPipeSendCL 2 | from .StallCL import StallCL 3 | -------------------------------------------------------------------------------- /pymtl3/stdlib/delays/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/delays/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/ifcs/XcelMsg.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | XcelMsg.py 4 | ======================================================================== 5 | Accelerator message type implementation. 6 | 7 | Author : Yanghui Ou 8 | Date : June 3, 2019 9 | """ 10 | from pymtl3 import * 11 | 12 | 13 | class XcelMsgType: 14 | # TODO: figure out whether we want to use Bits1 here. 15 | READ = 0 16 | WRITE = 1 17 | 18 | str = { 19 | READ : "rd", 20 | WRITE : "wr", 21 | } 22 | 23 | def mk_xcel_msg( addr, data ): 24 | return mk_xcel_req_msg( addr, data ), mk_xcel_resp_msg( data ) 25 | 26 | def mk_xcel_req_msg( a, d ): 27 | @bitstruct 28 | class XcelReqMsg: 29 | type_ : Bits1 30 | addr : mk_bits( a ) 31 | data : mk_bits( d ) 32 | 33 | def __str__( self ): 34 | return "{}:{}:{}".format( 35 | XcelMsgType.str[ int(self.type_) ], 36 | self.addr, 37 | self.data if self.type_ != XcelMsgType.READ else " " * ( d//4 ), 38 | ) 39 | 40 | return XcelReqMsg 41 | 42 | def mk_xcel_resp_msg( d ): 43 | @bitstruct 44 | class XcelRespMsg: 45 | type_ : Bits1 46 | data : mk_bits( d ) 47 | 48 | def __str__( self ): 49 | return "{}:{}".format( 50 | XcelMsgType.str[ int(self.type_) ], 51 | self.data if self.type_ != XcelMsgType.WRITE else " " * ( d//4 ), 52 | ) 53 | 54 | return XcelRespMsg 55 | -------------------------------------------------------------------------------- /pymtl3/stdlib/ifcs/__init__.py: -------------------------------------------------------------------------------- 1 | # from .EnqDeqIfc import DeqIfcFL, DeqIfcRTL, EnqIfcFL, EnqIfcRTL 2 | from .get_give_ifcs import GetIfcFL, GetIfcRTL, GiveIfcFL, GiveIfcRTL 3 | from .master_minion_ifcs import MasterIfcCL, MasterIfcRTL, MinionIfcCL, MinionIfcRTL 4 | from .send_recv_ifcs import ( 5 | RecvCL2SendRTL, 6 | RecvIfcFL, 7 | RecvIfcRTL, 8 | RecvRTL2SendCL, 9 | SendIfcFL, 10 | SendIfcRTL, 11 | ) 12 | from .xcel_ifcs import ( 13 | XcelMasterIfcCL, 14 | XcelMasterIfcFL, 15 | XcelMasterIfcRTL, 16 | XcelMinionIfcCL, 17 | XcelMinionIfcFL, 18 | XcelMinionIfcRTL, 19 | ) 20 | from .XcelMsg import XcelMsgType, mk_xcel_msg, mk_xcel_req_msg, mk_xcel_resp_msg 21 | -------------------------------------------------------------------------------- /pymtl3/stdlib/ifcs/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/ifcs/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/mem/MagicMemoryFL.py: -------------------------------------------------------------------------------- 1 | from pymtl3 import * 2 | from pymtl3.extra.pypy.fast_bytearray_funcs import ( 3 | read_bytearray_bits, 4 | write_bytearray_bits, 5 | ) 6 | 7 | from .mem_ifcs import MemMinionIfcFL 8 | from .MemMsg import MemMsgType 9 | 10 | AMO_FUNS = { MemMsgType.AMO_ADD : lambda m,a : m+a, 11 | MemMsgType.AMO_AND : lambda m,a : m&a, 12 | MemMsgType.AMO_OR : lambda m,a : m|a, 13 | MemMsgType.AMO_SWAP : lambda m,a : a, 14 | MemMsgType.AMO_MIN : lambda m,a : m if m.int() < a.int() else a, 15 | MemMsgType.AMO_MINU : min, 16 | MemMsgType.AMO_MAX : lambda m,a : m if m.int() > a.int() else a, 17 | MemMsgType.AMO_MAXU : max, 18 | MemMsgType.AMO_XOR : lambda m,a : m^a, 19 | } 20 | 21 | class MagicMemoryFL( Component ): 22 | 23 | def construct( s, mem_nbytes=1<<20 ): 24 | s.mem = bytearray( mem_nbytes ) 25 | 26 | s.ifc = MemMinionIfcFL( s.read, s.write, s.amo ) 27 | 28 | s.trace = " " 29 | @update_once 30 | def up_clear_trace(): 31 | s.trace = " " 32 | 33 | def read( s, addr, nbytes ): 34 | s.trace = "[rd ]" 35 | return read_bytearray_bits( s.mem, addr, nbytes ) 36 | 37 | def write( s, addr, nbytes, data ): 38 | s.trace = "[wr ]" 39 | write_bytearray_bits( s.mem, addr, nbytes, data ) 40 | 41 | # addr = int(addr) 42 | # end = addr + nbytes 43 | 44 | # while addr < end: 45 | # s.mem[addr] = data & 255 46 | # data >>= 8 47 | # addr += 1 48 | # s.trace = "[wr ]" 49 | 50 | def amo( s, amo, addr, nbytes, data ): 51 | ret = s.read( addr, nbytes ) 52 | s.write( addr, nbytes, AMO_FUNS[ int(amo) ]( ret, data ) ) 53 | s.trace = "[amo]" 54 | return ret 55 | 56 | def read_mem( s, addr, size ): 57 | assert len(s.mem) > (addr + size) 58 | return s.mem[ addr : addr + size ] 59 | 60 | def write_mem( s, addr, data ): 61 | assert len(s.mem) > (addr + len(data)) 62 | s.mem[ addr : addr + len(data) ] = data 63 | 64 | def line_trace( s ): 65 | return s.trace 66 | -------------------------------------------------------------------------------- /pymtl3/stdlib/mem/ROMRTL.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | ROMRTL.py 4 | ======================================================================== 5 | Multiported ROM 6 | 7 | Author : Shunning Jiang 8 | Date : June 18, 2020 9 | """ 10 | 11 | from pymtl3 import * 12 | 13 | 14 | class CombinationalROMRTL( Component ): 15 | 16 | def construct( s, Type, num_entries, data, num_ports=1 ): 17 | assert len(data) == num_entries 18 | 19 | s.raddr = [ InPort( clog2(num_entries) ) for _ in range(num_ports) ] 20 | s.rdata = [ OutPort( Type ) for _ in range(num_ports) ] 21 | 22 | s.mem = [ Wire(Type) for _ in range(num_entries) ] 23 | for i in range(num_entries): 24 | s.mem[i] //= data[i] 25 | 26 | @update 27 | def up_read_rom(): 28 | for i in range(num_ports): 29 | s.rdata[i] @= s.mem[ s.raddr[i] ] 30 | 31 | class SequentialROMRTL( Component ): 32 | 33 | def construct( s, Type, num_entries, data, num_ports=1 ): 34 | assert len(data) == num_entries 35 | 36 | s.raddr = [ InPort( clog2(num_entries) ) for _ in range(num_ports) ] 37 | s.rdata = [ OutPort( Type ) for _ in range(num_ports) ] 38 | 39 | s.mem = [ Wire(Type) for _ in range(num_entries) ] 40 | for i in range(num_entries): 41 | s.mem[i] //= data[i] 42 | 43 | @update_ff 44 | def up_read_rom(): 45 | for i in range(num_ports): 46 | s.rdata[i] <<= s.mem[ s.raddr[i] ] 47 | #----------------------------------------------------------------------- 48 | # line_trace 49 | #----------------------------------------------------------------------- 50 | 51 | def line_trace( s ): 52 | return "|".join( [ f"[{s.raddr[i]}]->{s.rdata[i]}" for i in range(len(s.raddr)) ] ) 53 | -------------------------------------------------------------------------------- /pymtl3/stdlib/mem/__init__.py: -------------------------------------------------------------------------------- 1 | from .MagicMemoryCL import MagicMemoryCL 2 | from .MagicMemoryFL import MagicMemoryFL 3 | from .mem_ifcs import ( 4 | MemMasterIfcCL, 5 | MemMasterIfcFL, 6 | MemMasterIfcRTL, 7 | MemMinionIfcCL, 8 | MemMinionIfcFL, 9 | MemMinionIfcRTL, 10 | ) 11 | from .MemMsg import MemMsgType, mk_mem_msg, mk_mem_req_msg, mk_mem_resp_msg 12 | from .ROMRTL import CombinationalROMRTL, SequentialROMRTL 13 | -------------------------------------------------------------------------------- /pymtl3/stdlib/mem/test/ROMRTL_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # ROMRTL_test.py 3 | #========================================================================= 4 | 5 | from pymtl3 import * 6 | from pymtl3.stdlib.test_utils import run_test_vector_sim 7 | 8 | from ..ROMRTL import CombinationalROMRTL, SequentialROMRTL 9 | 10 | 11 | def test_combinational_rom_rtl(): 12 | run_test_vector_sim( CombinationalROMRTL(Bits32, 8, [8,7,6,5,4,3,2,1], num_ports=2), [ 13 | ('raddr[0]', 'rdata[0]*', 'raddr[1]', 'rdata[1]*'), 14 | [ 1, 7, 5, 3 ], 15 | [ 2, 6, 7, 1 ], 16 | ]) 17 | 18 | run_test_vector_sim( CombinationalROMRTL(Bits32, 8, [8,7,6,5,4,3,2,1], num_ports=2), [ 19 | ('raddr[0]', 'rdata[0]*', 'raddr[1]', 'rdata[1]*'), 20 | [ 1, 7, 5, 3 ], 21 | [ 2, 6, 7, 1 ], 22 | ], {'dump_textwave':False, 'dump_vcd': 'test_rom', 'test_verilog': 'ones', 23 | 'test_yosys_verilog': '', 'dump_vtb': ''} ) 24 | 25 | 26 | def test_sequential_rom_rtl(): 27 | run_test_vector_sim( SequentialROMRTL(Bits32, 8, [8,7,6,5,4,3,2,1], num_ports=2), [ 28 | ('raddr[0]', 'rdata[0]*', 'raddr[1]', 'rdata[1]*'), 29 | [ 1, '?', 5, '?' ], 30 | [ 2, 7, 7, 3 ], 31 | [ 0, 6, 0, 1 ], 32 | ]) 33 | 34 | run_test_vector_sim( SequentialROMRTL(Bits32, 8, [8,7,6,5,4,3,2,1], num_ports=2), [ 35 | ('raddr[0]', 'rdata[0]*', 'raddr[1]', 'rdata[1]*'), 36 | [ 1, '?', 5, '?' ], 37 | [ 2, 7, 7, 3 ], 38 | [ 0, 6, 0, 1 ], 39 | ], {'dump_textwave':False, 'dump_vcd': 'test_rom', 'test_verilog': 'ones', 40 | 'test_yosys_verilog': '', 'dump_vtb': ''} ) 41 | -------------------------------------------------------------------------------- /pymtl3/stdlib/mem/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/mem/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/net/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/net/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/net/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/net/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/proc/__init__.py: -------------------------------------------------------------------------------- 1 | from .elf import elf_reader, elf_writer 2 | from .SparseMemoryImage import SparseMemoryImage 3 | -------------------------------------------------------------------------------- /pymtl3/stdlib/proc/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/proc/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/proc/test/elf_test.py: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # elf_test.py 3 | #========================================================================= 4 | 5 | import random 6 | import struct 7 | 8 | from .. import elf 9 | from ..SparseMemoryImage import SparseMemoryImage 10 | 11 | #------------------------------------------------------------------------- 12 | # test_basic 13 | #------------------------------------------------------------------------- 14 | 15 | def test_basic( tmpdir ): 16 | 17 | # Create a sparse memory image 18 | 19 | mem_image = SparseMemoryImage() 20 | 21 | section_names = [ ".text", ".data" ] 22 | 23 | for i in range(4): 24 | 25 | section = SparseMemoryImage.Section() 26 | section.name = section_names[ random.randint(0,1) ] 27 | section.addr = i * 0x00000200 28 | 29 | data_ints = [ random.randint(0,1000) for r in range(10) ] 30 | data_bytes = bytearray() 31 | for data_int in data_ints: 32 | data_bytes.extend(struct.pack(" 0: 46 | s.count -= 1 47 | s.send.val <<= 0 48 | 49 | else: # s.count == 0 50 | if s.idx < len(s.msgs): 51 | s.send.val <<= 1 52 | s.send.msg <<= s.msgs[s.idx] 53 | else: 54 | s.send.val <<= 0 55 | 56 | 57 | def done( s ): 58 | return s.idx >= len(s.msgs) 59 | 60 | # Line trace 61 | 62 | def line_trace( s ): 63 | return f"{s.send}" 64 | -------------------------------------------------------------------------------- /pymtl3/stdlib/stream/__init__.py: -------------------------------------------------------------------------------- 1 | from .SinkRTL import SinkRTL 2 | from .SourceRTL import SourceRTL 3 | from . import ifcs 4 | from .queue_adapters import RecvQueueAdapter, SendQueueAdapter 5 | from .queues import NormalQueueRTL, PipeQueueRTL, BypassQueueRTL 6 | from .magic_memory import MagicMemoryRTL 7 | from . import fl 8 | -------------------------------------------------------------------------------- /pymtl3/stdlib/stream/ifcs.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | ValRdyIfc 4 | ======================================================================== 5 | RTL val/rdy interface. 6 | 7 | Author : Shunning Jiang 8 | Date : Apr 5, 2019 9 | """ 10 | from pymtl3 import * 11 | 12 | 13 | def valrdy_to_str( msg, val, rdy, trace_len=15 ): 14 | if val and not rdy: return "#".ljust( trace_len ) 15 | if not val and rdy: return " ".ljust( trace_len ) 16 | if not val and not rdy: return ".".ljust( trace_len ) 17 | return f"{msg}".ljust( trace_len ) # val and rdy 18 | 19 | class RecvIfcRTL( Interface ): 20 | 21 | def construct( s, Type ): 22 | 23 | s.msg = InPort( Type ) 24 | s.val = InPort() 25 | s.rdy = OutPort() 26 | 27 | s.trace_len = len(str(Type())) 28 | 29 | def __str__( s ): 30 | return valrdy_to_str( s.msg, s.val, s.rdy, s.trace_len ) 31 | 32 | class SendIfcRTL( Interface ): 33 | 34 | def construct( s, Type ): 35 | 36 | s.msg = OutPort( Type ) 37 | s.val = OutPort() 38 | s.rdy = InPort() 39 | 40 | s.trace_len = len(str(Type())) 41 | 42 | def __str__( s ): 43 | return valrdy_to_str( s.msg, s.val, s.rdy, s.trace_len ) 44 | 45 | class MasterIfcRTL( Interface ): 46 | def construct( s, ReqType, RespType ): 47 | s.ReqType = ReqType 48 | s.RespType = RespType 49 | s.req = SendIfcRTL( Type=ReqType ) 50 | s.resp = RecvIfcRTL( Type=RespType ) 51 | def __str__( s ): 52 | return f"{s.req}|{s.resp}" 53 | 54 | class MinionIfcRTL( Interface ): 55 | def construct( s, ReqType, RespType ): 56 | s.ReqType = ReqType 57 | s.RespType = RespType 58 | s.req = RecvIfcRTL( Type=ReqType ) 59 | s.resp = SendIfcRTL( Type=RespType ) 60 | def __str__( s ): 61 | return f"{s.req}|{s.resp}" 62 | -------------------------------------------------------------------------------- /pymtl3/stdlib/stream/queue_adapters.py: -------------------------------------------------------------------------------- 1 | from pymtl3 import * 2 | from pymtl3.extra import clone_deepcopy 3 | from .ifcs import RecvIfcRTL, SendIfcRTL 4 | 5 | class RecvQueueAdapter( Component ): 6 | 7 | @non_blocking( lambda s: s.entry is not None ) 8 | def deq( s ): 9 | ret = s.entry 10 | s.entry = None 11 | return ret 12 | 13 | def construct( s, Type ): 14 | s.recv = RecvIfcRTL( Type ) 15 | s.entry = None 16 | 17 | @update_once 18 | def up_recv_rdy(): 19 | s.recv.rdy @= (s.entry is None) 20 | 21 | @update_once 22 | def up_recv_msg(): 23 | if (s.entry is None) & s.recv.val: 24 | s.entry = clone_deepcopy( s.recv.msg ) 25 | 26 | s.add_constraints( M( s.deq ) < U( up_recv_rdy ), # deq before recv in a cycle -- pipe behavior 27 | M( s.deq.rdy ) < U( up_recv_rdy ), 28 | U( up_recv_rdy ) < U( up_recv_msg ) ) 29 | 30 | 31 | class SendQueueAdapter( Component ): 32 | 33 | @non_blocking( lambda s: s.entry is None ) 34 | def enq( s, msg ): 35 | s.entry = clone_deepcopy( msg ) 36 | 37 | def construct( s, Type ): 38 | s.send = SendIfcRTL( Type ) 39 | 40 | s.entry = None 41 | s.sent = Wire() 42 | 43 | @update_once 44 | def up_send(): 45 | if s.entry is None: 46 | s.send.val @= 0 47 | else: 48 | s.send.val @= 1 49 | s.send.msg @= s.entry 50 | 51 | @update_ff 52 | def up_sent(): 53 | s.sent <<= s.send.val & s.send.rdy 54 | 55 | @update_once 56 | def up_clear(): 57 | if s.sent: # constraints reverse this 58 | s.entry = None 59 | 60 | s.add_constraints( 61 | U( up_clear ) < M( s.enq ), 62 | U( up_clear ) < M( s.enq.rdy ), 63 | M( s.enq ) < U( up_send ), 64 | M( s.enq.rdy ) < U( up_send ) 65 | ) 66 | -------------------------------------------------------------------------------- /pymtl3/stdlib/stream/test/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pymtl3/stdlib/stream/valrdy_test_masters.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | test_masters.py 4 | ========================================================================== 5 | 6 | Author: Shunning Jiang 7 | Date: May 27, 2020 8 | """ 9 | from pymtl3 import * 10 | from pymtl3.stdlib.ifcs.valrdy_master_minion_ifcs import MasterIfcRTL 11 | 12 | from .valrdy_test_sinks import TestSinkRTL 13 | from .valrdy_test_srcs import TestSrcRTL 14 | 15 | 16 | class TestMasterRTL( Component ): 17 | 18 | def construct( s, ReqType, RespType, MasterIfc=MasterIfcRTL ): 19 | s.master = MasterIfc( ReqType, RespType ) 20 | s.src = TestSrcRTL( ReqType ) 21 | s.sink = TestSinkRTL( RespType ) 22 | 23 | s.src.out //= s.master.req 24 | s.sink.in_ //= s.master.resp 25 | 26 | def done( s ): 27 | return s.src.done() and s.sink.done() 28 | 29 | def line_trace( s ): 30 | return str(s.master) 31 | -------------------------------------------------------------------------------- /pymtl3/stdlib/test_utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_helpers import ( 2 | RunTestVectorSimError, 3 | TestVectorSimulator, 4 | config_model_with_cmdline_opts, 5 | mk_test_case_table, 6 | run_sim, 7 | run_test_vector_sim, 8 | ) 9 | from .test_masters import TestMasterCL 10 | from .test_sinks import TestSinkCL 11 | from .test_srcs import TestSrcCL 12 | -------------------------------------------------------------------------------- /pymtl3/stdlib/test_utils/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pymtl3/stdlib/test_utils/test/__init__.py -------------------------------------------------------------------------------- /pymtl3/stdlib/test_utils/test_masters.py: -------------------------------------------------------------------------------- 1 | """ 2 | ========================================================================== 3 | test_masters.py 4 | ========================================================================== 5 | 6 | Author: Shunning Jiang 7 | Date: May 27, 2020 8 | """ 9 | from pymtl3 import * 10 | from pymtl3.stdlib.ifcs import MasterIfcCL 11 | 12 | from .test_sinks import TestSinkCL 13 | from .test_srcs import TestSrcCL 14 | 15 | 16 | class TestMasterCL( Component ): 17 | 18 | def construct( s, ReqType, RespType, MasterIfc=MasterIfcCL ): 19 | s.master = MasterIfc( ReqType, RespType ) 20 | s.src = TestSrcCL( ReqType ) 21 | s.sink = TestSinkCL( RespType ) 22 | 23 | s.src.send //= s.master.req 24 | s.sink.recv //= s.master.resp 25 | 26 | def done( s ): 27 | return s.src.done() and s.sink.done() 28 | 29 | def line_trace( s ): 30 | return str(s.master) 31 | -------------------------------------------------------------------------------- /pymtl3/stdlib/test_utils/test_srcs.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | SrcRTL 4 | ======================================================================== 5 | Test sources with CL or RTL interfaces. 6 | 7 | Author : Yanghui Ou 8 | Date : Mar 11, 2019 9 | """ 10 | from collections import deque 11 | 12 | from pymtl3 import * 13 | from pymtl3.stdlib.ifcs import RecvCL2SendRTL, SendIfcRTL 14 | 15 | #------------------------------------------------------------------------- 16 | # TestSrcCL 17 | #------------------------------------------------------------------------- 18 | 19 | class TestSrcCL( Component ): 20 | 21 | def construct( s, Type, msgs, initial_delay=0, interval_delay=0 ): 22 | 23 | s.send = CallerIfcCL( Type=Type ) 24 | s.msgs = deque( msgs ) 25 | 26 | s.count = initial_delay 27 | s.delay = interval_delay 28 | 29 | @update_once 30 | def up_src_send(): 31 | if s.count > 0: 32 | s.count -= 1 33 | elif not s.reset: 34 | if s.send.rdy() and s.msgs: 35 | s.send( s.msgs.popleft() ) 36 | s.count = s.delay # reset count after a message is sent 37 | 38 | def done( s ): 39 | return not s.msgs 40 | 41 | # Line trace 42 | 43 | def line_trace( s ): 44 | return "{}".format( s.send ) 45 | 46 | #------------------------------------------------------------------------- 47 | # TestSrcRTL 48 | #------------------------------------------------------------------------- 49 | # TODO: deprecating TestSrcRTL. 50 | 51 | class TestSrcRTL( Component ): 52 | 53 | def construct( s, Type, msgs, initial_delay=0, interval_delay=0 ): 54 | 55 | # Interface 56 | 57 | s.send = SendIfcRTL( Type ) 58 | 59 | # Components 60 | 61 | s.src = TestSrcCL( Type, msgs, initial_delay, interval_delay ) 62 | s.adapter = RecvCL2SendRTL( Type ) 63 | 64 | connect( s.src.send, s.adapter.recv ) 65 | connect( s.adapter.send, s.send ) 66 | 67 | def done( s ): 68 | return s.src.done() 69 | 70 | # Line trace 71 | 72 | def line_trace( s ): 73 | return "{}".format( s.send ) 74 | -------------------------------------------------------------------------------- /pymtl3/stdlib/test_utils/valrdy_test_srcs.py: -------------------------------------------------------------------------------- 1 | """ 2 | ======================================================================== 3 | Test sources 4 | ======================================================================== 5 | Test sources with CL or RTL interfaces. 6 | 7 | Author : Yanghui Ou 8 | Date : Mar 11, 2019 9 | """ 10 | from collections import deque 11 | from copy import deepcopy 12 | 13 | from pymtl3 import * 14 | from pymtl3.stdlib.ifcs import OutValRdyIfc 15 | 16 | 17 | class TestSrcRTL( Component ): 18 | 19 | def construct( s, Type, msgs, initial_delay=0, interval_delay=0 ): 20 | 21 | # Interface 22 | 23 | s.out = OutValRdyIfc( Type ) 24 | 25 | # Data 26 | 27 | s.msgs = deepcopy(msgs) 28 | 29 | # TODO: use wires and ROM to make it translatable 30 | s.idx = 0 31 | s.num_msgs = len(s.msgs) 32 | s.count = 0 33 | 34 | @update_ff 35 | def up_src(): 36 | if s.reset: 37 | s.idx = 0 38 | s.count = initial_delay 39 | s.out.val <<= 0 40 | 41 | else: 42 | if s.out.val & s.out.rdy: 43 | s.idx += 1 44 | s.count = interval_delay 45 | 46 | if s.count > 0: 47 | s.count -= 1 48 | s.out.val <<= 0 49 | 50 | else: # s.count == 0 51 | if s.idx < s.num_msgs: 52 | s.out.val <<= 1 53 | s.out.msg <<= s.msgs[s.idx] 54 | else: 55 | s.out.val <<= 0 56 | 57 | 58 | def done( s ): 59 | return s.idx >= s.num_msgs 60 | 61 | # Line trace 62 | 63 | def line_trace( s ): 64 | return f"{s.out}" 65 | -------------------------------------------------------------------------------- /pymtl3/version.py: -------------------------------------------------------------------------------- 1 | __version__ = "3.1.16" 2 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # pytest.ini 3 | #========================================================================= 4 | # Configuration file for pytest 5 | 6 | [pytest] 7 | 8 | #------------------------------------------------------------------------- 9 | # configure test collection 10 | #------------------------------------------------------------------------- 11 | # We explicitly do not set a pattern for collecting python classes 12 | # yet. This avoids collecting TestHarness which we use in many of our 13 | # PyMTL unit tests, but eventually we will need to decide on a 14 | # replacement. 15 | 16 | python_files = *_test.py 17 | python_classes = *_Tests 18 | python_functions = test test_* 19 | 20 | #------------------------------------------------------------------------- 21 | # default commandline arguments 22 | #------------------------------------------------------------------------- 23 | # By default do not show any traceback. This means by deafult pytest 24 | # gives an overview of the results but not any details. Users can use 25 | # --tb=long to get more information on a failing test. We also display 26 | # error/warnings at the end; otherwise syntax errors won't really show 27 | # up. 28 | 29 | addopts = --tb=no -r Ew 30 | -------------------------------------------------------------------------------- /pytest_plugin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pymtl/pymtl3/eea5ff49e06b303123097dc4d9e163790c0f58d6/pytest_plugin/__init__.py -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # This file specifies the dependencies needed for developing PyMTL 2 | -r requirements/dev.txt 3 | -------------------------------------------------------------------------------- /requirements/CI-pypy.txt: -------------------------------------------------------------------------------- 1 | -r dev.txt 2 | -c constraints.txt 3 | -c pypy-constraints.txt 4 | 5 | # CI dependencies 6 | pytest-cov 7 | codecov 8 | -------------------------------------------------------------------------------- /requirements/CI.txt: -------------------------------------------------------------------------------- 1 | -r dev.txt 2 | -c constraints.txt 3 | 4 | # CI dependencies 5 | pytest-cov 6 | codecov 7 | -------------------------------------------------------------------------------- /requirements/constraints.txt: -------------------------------------------------------------------------------- 1 | # Explicit constraints to workaround dependency resolution of pip 2 | # Currently only required for CI 3 | attrs>=19.2.0 4 | -------------------------------------------------------------------------------- /requirements/dev.txt: -------------------------------------------------------------------------------- 1 | -r release.txt 2 | -r docs.txt 3 | 4 | # Extra development dependencies 5 | autoflake 6 | flake8 7 | isort 8 | pyupgrade 9 | graphviz 10 | -------------------------------------------------------------------------------- /requirements/docs.txt: -------------------------------------------------------------------------------- 1 | # Documentation dependencies 2 | sphinx 3 | sphinx-prompt 4 | sphinx-rtd-theme 5 | -------------------------------------------------------------------------------- /requirements/pypy-constraints.txt: -------------------------------------------------------------------------------- 1 | # Workaround the PyPy PEP 517 issue related to cryptography and the typing module 2 | hypothesis==5.29.0 3 | cryptography==41.0.6 4 | -------------------------------------------------------------------------------- /requirements/release.txt: -------------------------------------------------------------------------------- 1 | # Minimal dependencies required for using pip-installed PyMTL 2 | py 3 | pytest 4 | hypothesis 5 | cffi 6 | greenlet 7 | --------------------------------------------------------------------------------