├── .gitignore ├── LICENSE ├── README.md ├── build-sc-tb.py ├── chisel-to-systemc-tb.sh └── testbench-template ├── InputFIFOAdapter.h ├── Makefile ├── OutputFIFOAdapter.h └── testbench.cpptmpl /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Yaman Umuroglu 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # systemc-chisel-tools 2 | A collection of tools for working with Chisel-generated hardware in SystemC. 3 | 4 | chisel-to-systemc.sh 5 | ===================== 6 | This script translates a Chisel hardware design into SystemC (via Verilator), 7 | then generates a simple SystemC testbench skeleton that instantiates the module and 8 | binds signals to the inputs and outputs. 9 | There is also some preliminary support for working with Decoupled interfaces in Chisel: 10 | interfaces with _ready/_valid/_bits naming are extracted and treated separately, 11 | generating simple adapters that support bridging the SystemC-style FIFO interfaces 12 | (sc_fifo) and the signal-level interface. This enables creating independent SystemC 13 | threads that feed the FIFOs with data. 14 | 15 | Writing complicated testbenches in SystemC is may sometimes be easier compared to Chisel, since it is 16 | possible to spawn threads executing in parallel and the entire C++ language is also at your 17 | disposal for modelling the signal driver/tester behavior. 18 | 19 | Usage: chisel-to-systemc-tb.sh verilog_module target_dir [-t] 20 | 21 | If -t is specified, a testbench skeleton will also be generated. 22 | 23 | 24 | Requirements 25 | ============= 26 | 27 | - working Chisel setup (sbt etc. -- see chisel.eecs.berkeley.edu) 28 | - Verilator 29 | - SystemC (SYSTEMC_ROOT, SYSTEMC_INCLUDE and SYSTEMC_LIBDIR env vars must be set) 30 | - Python 31 | 32 | -------------------------------------------------------------------------------- /build-sc-tb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # A simple Python script for extracting input and output ports from a SystemC 4 | # module definition. 5 | # The intended use case for the script is to be part of an automated testbench 6 | # skeleton generator for testing Chisel components in SystemC. 7 | # Since there currently is no Chisel SystemC backend, Verilog is generated via 8 | # the Chisel Verilog backend, which is then passed through Verilator to 9 | # generate SystemC code. The module header file (VSomething.h) is the target 10 | # for this particular script. 11 | 12 | # There is also some preliminary support for extracting Decoupled interfaces, 13 | # e.g those that consist of ready-valid-bits signals. These can be connected 14 | # to SystemC FIFO types (sc_fifo) through simple adapters. 15 | 16 | # Contact: Yaman Umuroglu 17 | 18 | import re, sys 19 | 20 | def getSignals(templateType, headerData): 21 | signals = [] 22 | signalMatches = re.findall( templateType + r'<.*>.*;', headerData, re.M) 23 | for s in signalMatches: 24 | match = re.match( templateType + r'<(.*)>\s(.*);', s) 25 | signals += [(match.group(2), match.group(1))] 26 | signals = dict(signals) 27 | return signals 28 | 29 | def getInputSignals(headerData): 30 | return getSignals(r'sc_in', headerData) 31 | 32 | def getOutputSignals(headerData): 33 | return getSignals(r'sc_out', headerData) 34 | 35 | def getInputFIFONames(headerData): 36 | inputValidMatches = re.findall( r'sc_in.*valid;', headerData, re.M) 37 | inputFIFONames = [] 38 | inputSignals=getInputSignals(headerData) 39 | outputSignals=getOutputSignals(headerData) 40 | for s in inputValidMatches: 41 | match = re.match( r'sc_in\s(.*)_valid;', s) 42 | fifoName = match.group(1) 43 | if fifoName+"_bits" in inputSignals and fifoName+"_ready" in outputSignals: 44 | inputFIFONames += [(fifoName, inputSignals[fifoName+"_bits"])] 45 | else: 46 | print >> sys.stderr, "some FIFO signals for " + fifoName + " not found!" 47 | return dict(inputFIFONames) 48 | 49 | def getOutputFIFONames(headerData): 50 | outputValidMatches = re.findall( r'sc_out.*valid;', headerData, re.M) 51 | outputFIFONames = [] 52 | inputSignals=getInputSignals(headerData) 53 | outputSignals=getOutputSignals(headerData) 54 | for s in outputValidMatches: 55 | match = re.match( r'sc_out\s(.*)_valid;', s) 56 | fifoName = match.group(1) 57 | if fifoName+"_bits" in outputSignals and fifoName+"_ready" in inputSignals: 58 | outputFIFONames += [(fifoName, outputSignals[fifoName+"_bits"])] 59 | else: 60 | print >> sys.stderr, "some FIFO signals for " + fifoName + " not found!" 61 | return dict(outputFIFONames) 62 | 63 | 64 | if len(sys.argv) == 2: 65 | headerFileName = str(sys.argv[1]) 66 | else: 67 | print >> sys.stderr, "Please specify input header file name." 68 | sys.exit() 69 | 70 | with open(headerFileName, "r") as myfile: 71 | data=myfile.read() 72 | 73 | moduleName = re.findall(r'SC_MODULE\((.*)\)', data, re.M)[0] 74 | inputSignals = getInputSignals(data) 75 | outputSignals = getOutputSignals(data) 76 | inputFIFOs = getInputFIFONames(data) 77 | outputFIFOs = getOutputFIFONames(data) 78 | 79 | inputSignalDecls = "" 80 | inputSignalConns = "" 81 | inputSignalInits = "" # initializers for the input drivers 82 | 83 | outputSignalDecls = "" 84 | outputSignalConns = "" 85 | 86 | resetCode = "" 87 | 88 | inputFIFODecls = "" 89 | outputFIFODecls = "" 90 | inputFIFOAdps = "" 91 | outputFIFOAdps = "" 92 | inputFIFOInit = "" 93 | outputFIFOInit = "" 94 | inputFIFOSetup = "" 95 | outputFIFOSetup = "" 96 | 97 | # - remove FIFO signals from regular I/O since we handle them separately 98 | # - build sc_fifo<> declarations 99 | # - build commands for initialization 100 | for f in inputFIFOs: 101 | del inputSignals[f+"_valid"] 102 | del inputSignals[f+"_bits"] 103 | del outputSignals[f+"_ready"] 104 | fifoDataType = inputFIFOs[f] 105 | inputFIFODecls += " sc_fifo<" + fifoDataType + "> fifo_"+f+";\n" 106 | inputFIFOAdps += " InputFIFOAdapter<" + fifoDataType + "> adp_"+f+";\n" 107 | inputFIFOInit += ", adp_" + f + "(\"adp_" + f + "\")" 108 | inputFIFOSetup += " adp_" + f + ".clk(clk);\n" 109 | inputFIFOSetup += " adp_" + f + ".fifoInput(fifo_" + f + ");\n" 110 | inputFIFOSetup += " adp_" + f + ".bindSignalInterface(uut."+f+"_valid, uut." +f+"_ready, uut."+f+"_bits);\n" 111 | 112 | for f in outputFIFOs: 113 | del outputSignals[f+"_valid"] 114 | del outputSignals[f+"_bits"] 115 | del inputSignals[f+"_ready"] 116 | fifoDataType = outputFIFOs[f] 117 | outputFIFODecls += " sc_fifo<" + fifoDataType + "> fifo_"+f+";\n" 118 | outputFIFOAdps += " OutputFIFOAdapter<" + fifoDataType + "> adp_"+f+";\n" 119 | outputFIFOInit += ", adp_" + f + "(\"adp_" + f + "\")" 120 | outputFIFOSetup += " adp_" + f + ".clk(clk);\n" 121 | outputFIFOSetup += " adp_" + f + ".fifoOutput(fifo_" + f + ");\n" 122 | outputFIFOSetup += " adp_" + f + ".bindSignalInterface(uut."+f+"_valid, uut." +f+"_ready, uut."+f+"_bits);\n" 123 | 124 | # Handle clock driver manually if there is a clk input 125 | if "clk" in inputSignals: 126 | del inputSignals["clk"] 127 | inputSignalConns += " uut.clk(clk);\n" 128 | resetCode += " sig_reset = true;\n" 129 | resetCode += " wait(10*CLOCK_CYCLE);\n" 130 | resetCode += " sig_reset = false;\n" 131 | 132 | # Build signal declarations and conns for input and outputs 133 | for sigName in inputSignals: 134 | sigType = inputSignals[sigName] 135 | inputSignalDecls += " sc_signal<" + sigType + "> sig_"+sigName+";\n" 136 | inputSignalConns += " uut." + sigName + "(sig_" + sigName + ");\n" 137 | inputSignalInits += " sig_" + sigName + " = 0;\n" 138 | 139 | for sigName in outputSignals: 140 | sigType = outputSignals[sigName] 141 | outputSignalDecls += " sc_signal<" + sigType + "> sig_"+sigName+";\n" 142 | outputSignalConns += " uut." + sigName + "(sig_" + sigName + ");\n" 143 | 144 | 145 | # Load the template 146 | with open("testbench-template/testbench.cpptmpl", "r") as templateFile: 147 | templateData = str(templateFile.read()) 148 | 149 | # Add module header #include 150 | templateData=templateData.replace("${MODULE_HEADER}", moduleName+".h") 151 | 152 | # Module name 153 | templateData=templateData.replace("${MODULE_NAME}", moduleName) 154 | 155 | # Testbench name 156 | templateData=templateData.replace("${TESTBENCH_NAME}", "Test"+moduleName) 157 | 158 | # Signal declarations 159 | templateData=templateData.replace("${INPUT_DRIVERS}", inputSignalDecls) 160 | templateData=templateData.replace("${OUTPUT_MONITORS}", outputSignalDecls) 161 | 162 | # Signal connections 163 | templateData=templateData.replace("${CONNECT_INPUT_DRIVERS}", inputSignalConns) 164 | templateData=templateData.replace("${CONNECT_OUTPUT_MONITORS}", outputSignalConns) 165 | 166 | # Init input drivers 167 | templateData=templateData.replace("${INIT_INPUT_DRIVERS}", inputSignalInits) 168 | 169 | # Reset code 170 | templateData=templateData.replace("${RESET_CODE}", resetCode) 171 | 172 | # FIFO declarations and adapter declarations 173 | templateData=templateData.replace("${INPUT_FIFO_ADAPTERS}", inputFIFOAdps) 174 | templateData=templateData.replace("${INPUT_FIFOS}", inputFIFODecls) 175 | templateData=templateData.replace("${OUTPUT_FIFO_ADAPTERS}", outputFIFOAdps) 176 | templateData=templateData.replace("${OUTPUT_FIFOS}", outputFIFODecls) 177 | 178 | # FIFO setup in constructor 179 | templateData=templateData.replace("${INPUT_FIFO_INIT}", inputFIFOInit) 180 | templateData=templateData.replace("${OUTPUT_FIFO_INIT}", outputFIFOInit) 181 | templateData=templateData.replace("${INPUT_FIFO_SETUP}", inputFIFOSetup) 182 | templateData=templateData.replace("${OUTPUT_FIFO_SETUP}", outputFIFOSetup) 183 | 184 | print templateData 185 | 186 | # TODO fill in SystemC testbench code that instantiates sc_fifo's and 187 | # appropriate adapters for connecting to a ready/valid/bits interface 188 | -------------------------------------------------------------------------------- /chisel-to-systemc-tb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -lt 2 ]; then 4 | echo "Usage:" 5 | echo "chisel-to-systemc-tb.sh verilog_module target_dir [-t]" 6 | echo "If -t is specified, a testbench skeleton will also be generated." 7 | exit 8 | fi 9 | 10 | get_abs_filename() { 11 | # $1 : relative filename 12 | echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" 13 | } 14 | 15 | WORK_DIR="/tmp/verilog-to-sc" 16 | MODULE_NAME=$1 17 | TARGET_DIR=$(get_abs_filename $2) 18 | VERILATOR_DIR="/usr/share/verilator/include" 19 | TOOL_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 20 | SRC_DIR=$(pwd) 21 | 22 | cd $SRC_DIR 23 | mkdir -p $WORK_DIR 24 | mkdir -p $TARGET_DIR 25 | echo "Invoking Chisel to generate Verilog..." 26 | sbt "run --targetDir $WORK_DIR --backend v" 27 | 28 | echo "Converting Verilog module $1 into SystemC at $2..." 29 | cd $WORK_DIR 30 | verilator --sc $MODULE_NAME.v +define+SYNTHESIS+1 -Wno-lint 31 | cp -f obj_dir/*.cpp $TARGET_DIR/ 32 | cp -f obj_dir/*.h $TARGET_DIR/ 33 | cp -f $VERILATOR_DIR/verilated.cpp $TARGET_DIR 34 | 35 | if [ "$3" = "-t" ]; then 36 | echo "Creating SystemC testbench skeleton for module V$MODULE_NAME..." 37 | cd $TOOL_DIR 38 | cp -f testbench-template/Makefile $TARGET_DIR 39 | cp -f testbench-template/*.h $TARGET_DIR 40 | ./build-sc-tb.py $WORK_DIR/obj_dir/V$MODULE_NAME.h > $TARGET_DIR/main.cpp 41 | fi 42 | 43 | cd $SRC_DIR 44 | rm -rf $WORK_DIR 45 | 46 | echo "Done!" 47 | 48 | -------------------------------------------------------------------------------- /testbench-template/InputFIFOAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUTFIFOADAPTER_H 2 | #define INPUTFIFOADAPTER_H 3 | 4 | #include 5 | 6 | // a wrapper/adapter for bridging a SystemC FIFO to a signal-level 7 | // read/valid enqueue interface 8 | 9 | template 10 | class InputFIFOAdapter : public sc_module 11 | { 12 | SC_HAS_PROCESS(InputFIFOAdapter); 13 | 14 | public: 15 | sc_in_clk clk; 16 | sc_fifo_in fifoInput; 17 | 18 | InputFIFOAdapter(sc_module_name nm) : sc_module(nm) 19 | { 20 | m_transferCount = 0; 21 | 22 | SC_THREAD(transferMonitor); 23 | sensitive << clk.pos(); 24 | 25 | SC_THREAD(fifoInputAdapt); 26 | sensitive << clk.pos(); 27 | 28 | m_reset = false; 29 | } 30 | 31 | void resetCounters() 32 | { 33 | m_transferCount = 0; 34 | } 35 | 36 | void resetContent() 37 | { 38 | // read all content from the attached FIFO IF 39 | while(fifoInput.num_available()) 40 | fifoInput.read(); 41 | 42 | 43 | m_reset = true; 44 | for(int i = 0; i < 10; i++) 45 | wait(clk.posedge_event()); 46 | m_reset = false; 47 | } 48 | 49 | void bindSignalInterface(sc_in & valid, sc_out & ready, sc_in & data) 50 | { 51 | valid.bind(m_valid); 52 | ready.bind(m_ready); 53 | data.bind(m_data); 54 | } 55 | 56 | unsigned long int getTransferCount() 57 | { 58 | return m_transferCount; 59 | } 60 | 61 | void transferMonitor() 62 | { 63 | while(1) 64 | { 65 | if( m_valid && m_ready) 66 | m_transferCount++; 67 | wait(1); 68 | } 69 | } 70 | 71 | void fifoInputAdapt() 72 | { 73 | m_valid = false; 74 | m_data = 0xdeadbeef; 75 | 76 | while(1) 77 | { 78 | m_valid = false; 79 | 80 | // add delays here for testing the latency insensitivity of the 81 | // target components 82 | //wait(15); 83 | 84 | T data; 85 | if(fifoInput.nb_read(data)) 86 | { 87 | m_valid = true; 88 | m_data = data; 89 | //cout << "**************************************************FIFO " << this->name() << " read value " << data << endl; 90 | 91 | do { 92 | wait(1); 93 | // include reset for enabling FIFO flush 94 | if(m_reset) 95 | break; 96 | } while(m_ready != true); 97 | 98 | } else 99 | wait(1); 100 | } 101 | } 102 | 103 | public: 104 | sc_signal m_valid; 105 | sc_signal m_ready; 106 | sc_signal m_data; 107 | 108 | bool m_reset; 109 | 110 | unsigned long int m_transferCount; 111 | 112 | }; 113 | 114 | #endif // INPUTFIFOADAPTER_H 115 | -------------------------------------------------------------------------------- /testbench-template/Makefile: -------------------------------------------------------------------------------- 1 | TARGET := testbench 2 | SRCS := $(wildcard *.cpp) 3 | OBJS := ${SRCS:.cpp=.o} 4 | DEPS := ${SRCS:.cpp=.dep} 5 | XDEPS := $(wildcard ${DEPS}) 6 | 7 | CXXFLAGS = -std=c++11 8 | LDFLAGS = -L$(SYSTEMC_ROOT)/lib-linux64 9 | LIBS = -lsystemc -lpthread 10 | INCLUDE = -I$(SYSTEMC_ROOT)/include -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd 11 | 12 | .PHONY: all clean distclean 13 | all:: ${TARGET} 14 | 15 | ifneq (${XDEPS},) 16 | include ${XDEPS} 17 | endif 18 | 19 | ${TARGET}: ${OBJS} 20 | ${CXX} ${LDFLAGS} -o $@ $^ ${LIBS} 21 | 22 | ${OBJS}: %.o: %.cpp %.dep 23 | ${CXX} ${CXXFLAGS} ${INCLUDE} -o $@ -c $< 24 | 25 | ${DEPS}: %.dep: %.cpp Makefile 26 | ${CXX} ${CXXFLAGS} ${INCLUDE} -MM $< > $@ 27 | 28 | clean:: 29 | -rm -f *~ *.o *.dep ${TARGET} 30 | 31 | distclean:: clean 32 | -------------------------------------------------------------------------------- /testbench-template/OutputFIFOAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef OUTPUTFIFOADAPTER_H 2 | #define OUTPUTFIFOADAPTER_H 3 | 4 | #include 5 | 6 | 7 | // a wrapper/adapter for bridging a SystemC FIFO to a signal-level 8 | // read/valid dequeue interface 9 | 10 | template 11 | class OutputFIFOAdapter : public sc_module 12 | { 13 | SC_HAS_PROCESS(OutputFIFOAdapter); 14 | 15 | public: 16 | sc_in_clk clk; 17 | sc_fifo_out fifoOutput; 18 | 19 | OutputFIFOAdapter(sc_module_name nm) : sc_module(nm) 20 | { 21 | m_transferCount = 0; 22 | 23 | SC_THREAD(transferMonitor); 24 | sensitive << clk.pos(); 25 | 26 | SC_CTHREAD(fifoOutputAdapt, clk.pos()); 27 | } 28 | 29 | void resetCounters() 30 | { 31 | m_transferCount = 0; 32 | } 33 | 34 | void bindSignalInterface(sc_out & valid, sc_in & ready, sc_out & data) 35 | { 36 | valid.bind(m_valid); 37 | ready.bind(m_ready); 38 | data.bind(m_data); 39 | } 40 | 41 | unsigned long int getTransferCount() 42 | { 43 | return m_transferCount; 44 | } 45 | 46 | void transferMonitor() 47 | { 48 | while(1) 49 | { 50 | if( m_valid && m_ready) 51 | m_transferCount++; 52 | wait(1); 53 | } 54 | } 55 | 56 | void fifoOutputAdapt() 57 | { 58 | while(1) 59 | { 60 | wait(1); 61 | 62 | m_ready = (fifoOutput.num_free() > 0); 63 | 64 | if(fifoOutput.num_free() && m_valid) 65 | { 66 | fifoOutput.write(m_data); 67 | } 68 | } 69 | } 70 | 71 | protected: 72 | sc_signal m_valid; 73 | sc_signal m_ready; 74 | sc_signal m_data; 75 | 76 | unsigned long int m_transferCount; 77 | 78 | }; 79 | 80 | #endif // OUTPUTFIFOADAPTER_H 81 | -------------------------------------------------------------------------------- /testbench-template/testbench.cpptmpl: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "InputFIFOAdapter.h" 5 | #include "OutputFIFOAdapter.h" 6 | #include "${MODULE_HEADER}" 7 | 8 | using namespace std; 9 | 10 | // clock period for the test clock 11 | #define CLOCK_CYCLE sc_time(10, SC_NS) 12 | 13 | class ${TESTBENCH_NAME} : public sc_module 14 | { 15 | SC_HAS_PROCESS(${TESTBENCH_NAME}); 16 | 17 | public: 18 | ${TESTBENCH_NAME}(sc_module_name name) : 19 | sc_module(name), uut("uut"), clk("clk", CLOCK_CYCLE) 20 | ${INPUT_FIFO_INIT} 21 | ${OUTPUT_FIFO_INIT} 22 | { 23 | // TODO handle FIFOs 24 | 25 | // connect input drivers 26 | ${CONNECT_INPUT_DRIVERS} 27 | // connect output monitors 28 | ${CONNECT_OUTPUT_MONITORS} 29 | 30 | // FIFO setup 31 | ${INPUT_FIFO_SETUP} 32 | ${OUTPUT_FIFO_SETUP} 33 | 34 | // declare run_tests as SystemC thread 35 | SC_THREAD(run_tests); 36 | } 37 | 38 | // initialize the driving signals for the uut inputs 39 | void init_drivers() 40 | { 41 | ${INIT_INPUT_DRIVERS} 42 | } 43 | 44 | // reset system if needed 45 | void reset_system() 46 | { 47 | ${RESET_CODE} 48 | } 49 | 50 | void run_tests() 51 | { 52 | // initialize input drivers 53 | init_drivers(); 54 | reset_system(); 55 | cout << "Reset completed at " << sc_time_stamp() << ", starting tests..." << endl; 56 | // TODO insert test code here 57 | 58 | } 59 | 60 | sc_clock clk; 61 | 62 | // instance for the module being tested 63 | ${MODULE_NAME} uut; 64 | 65 | // signals for manipulating the module 66 | ${INPUT_DRIVERS} 67 | ${OUTPUT_MONITORS} 68 | 69 | // FIFO adapters for bridging SystemC FIFOs with signal-level decoupled interfaces 70 | ${INPUT_FIFO_ADAPTERS} 71 | ${OUTPUT_FIFO_ADAPTERS} 72 | 73 | // SystemC FIFO declarations for talking to decoupled interfaces 74 | ${INPUT_FIFOS} 75 | ${OUTPUT_FIFOS} 76 | 77 | }; 78 | 79 | int sc_main(int argc, char *argv[]) 80 | { 81 | ${TESTBENCH_NAME} tb("tb"); 82 | 83 | sc_start(); 84 | 85 | return 0; 86 | } 87 | --------------------------------------------------------------------------------