├── .gitignore ├── Adder ├── CMakeLists.txt ├── README.md ├── exercises_adder.cpp └── simple_adder.cpp ├── Doulos_Example5 ├── CMakeLists.txt ├── README.md ├── bus.h ├── initiator1.h ├── initiator2.h ├── target.h ├── testbench.cpp ├── top.h └── utilities.h ├── Doulos_Sockets ├── CMakeLists.txt ├── README.md ├── initiator.h ├── target.h ├── testbench.cpp └── top.h ├── Doulos_Tutorial2 ├── CMakeLists.txt ├── README.md ├── initiator.h ├── target.h ├── testbench.cpp └── top.h ├── Doulos_Tutorial3 ├── CMakeLists.txt ├── README.md ├── initiator.h ├── router.h ├── target.h ├── testbench.cpp └── top.h ├── README.md └── SimpleBus ├── CMakeLists.txt ├── ChangeLog ├── LEGAL ├── Makefile ├── README.md ├── golden.log ├── simple_bus.cpp ├── simple_bus.h ├── simple_bus.sln ├── simple_bus.vcxproj ├── simple_bus_arbiter.cpp ├── simple_bus_arbiter.h ├── simple_bus_arbiter_if.h ├── simple_bus_blocking_if.h ├── simple_bus_direct_if.h ├── simple_bus_fast_mem.h ├── simple_bus_main.cpp ├── simple_bus_master_blocking.cpp ├── simple_bus_master_blocking.h ├── simple_bus_master_direct.cpp ├── simple_bus_master_direct.h ├── simple_bus_master_non_blocking.cpp ├── simple_bus_master_non_blocking.h ├── simple_bus_non_blocking_if.h ├── simple_bus_request.h ├── simple_bus_slave_if.h ├── simple_bus_slow_mem.h ├── simple_bus_test.h ├── simple_bus_tools.cpp ├── simple_bus_types.cpp ├── simple_bus_types.h └── test.am /.gitignore: -------------------------------------------------------------------------------- 1 | /*/cmake-build-debug/* 2 | /*/.idea/* -------------------------------------------------------------------------------- /Adder/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Adder) 3 | 4 | # change your SystemC installation directory 5 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 6 | # if under linux OS 7 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 8 | message(STATUS "Current development environment is Linux,") 9 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 10 | message(STATUS "Current development environment is Windows,") 11 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 12 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 13 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 14 | 15 | include_directories(${CMAKE_PREFIX_PATH}/include) 16 | find_package(SystemCLanguage CONFIG REQUIRED) 17 | link_directories(${CMAKE_PREFIX_PATH}/lib) 18 | add_executable(Adder exercises_adder.cpp) 19 | #add_executable(Adder simple_adder.cpp) 20 | target_link_libraries(Adder SystemC::systemc) 21 | -------------------------------------------------------------------------------- /Adder/README.md: -------------------------------------------------------------------------------- 1 | # Adder 2 | 3 | ## Simple Adder 4 | 5 | This file is the original codes from the slides. 6 | 7 | ## Exercises Adder 8 | 9 | This file is the codes I modified for the exercises. 10 | 11 | ## CMakeLists 12 | 13 | This is used for current project. -------------------------------------------------------------------------------- /Adder/exercises_adder.cpp: -------------------------------------------------------------------------------- 1 | /** This file is based on the `simple_adder.cpp`, 2 | * and modified for the exercises. 3 | * (1) Dump the execution order of the different processes 4 | * (2) Set the sizes of all the FIFO channels to 5, 5 | * and compare the execution order of the processes with that in (1) 6 | * (3) Continue the experiment in (1) and modify the DF_fork module such that 7 | * it produces two values on each output for every data sample consumed. 8 | * Identify the step in which the simulation halts and state the reasons 9 | * (4) Continue the experiment in (3), break the feedback loop, remove the adder, 10 | * and state whether the system will halt or not? 11 | * Give the reasons behind your observations. 12 | * (5) Continue the experiment in (1), set the delay z^(-1) to z^(-3) 13 | * */ 14 | 15 | #include 16 | #include 17 | template SC_MODULE(DF_Adder){ 18 | sc_fifo_in input1, input2; 19 | sc_fifo_out output; 20 | void process(){ 21 | while(1) { 22 | T data = input1.read()+input2.read(); 23 | wait(200, SC_NS); 24 | output.write(data); 25 | std::string logInfo = "[" + sc_time_stamp().to_string() + "]" 26 | + name() + " now process"; 27 | cout << logInfo << endl; 28 | } 29 | 30 | } 31 | 32 | SC_CTOR(DF_Adder) 33 | { 34 | SC_THREAD(process); 35 | } 36 | }; 37 | 38 | template SC_MODULE(DF_Const) { 39 | sc_fifo_out output; 40 | void process() { 41 | while (1) { 42 | output.write(constant_); 43 | std::string logInfo = "[" + sc_time_stamp().to_string() + "]" 44 | + name() + " now process with a constant "; 45 | cout << logInfo << constant_ << endl; 46 | }; 47 | } 48 | SC_HAS_PROCESS(DF_Const); 49 | DF_Const(sc_module_name N, const T&C): 50 | sc_module(N), constant_(C) 51 | {SC_THREAD(process);} 52 | T constant_; 53 | }; 54 | 55 | template SC_MODULE(DF_Fork){ 56 | sc_fifo_in input; 57 | sc_fifo_out output1,output2; 58 | void process(){ 59 | while(1) { 60 | T value=input.read(); 61 | output1.write(value); 62 | output2.write(value); 63 | std::string logInfo = "[" + sc_time_stamp().to_string() + "]" 64 | + name() + " now process with a value "; 65 | cout << logInfo << value << endl; 66 | } } 67 | SC_CTOR(DF_Fork) { 68 | SC_THREAD(process) 69 | } 70 | }; 71 | 72 | template 73 | SC_MODULE(DF_Printer){ 74 | sc_fifo_in input; 75 | sc_out done; 76 | SC_CTOR(DF_Printer) { 77 | SC_THREAD(print_process); 78 | done.initialize(false); 79 | } 80 | void print_process(){ 81 | for(unsigned i=0;i, 0> inputs; 96 | SC_CTOR(Terminator) { 97 | SC_METHOD(arnold); 98 | sensitive << inputs; 99 | } 100 | 101 | void arnold() { 102 | for (unsigned i = 0; i < inputs.size(); i++) 103 | if (inputs[i]->read() == 0) 104 | return; 105 | std::string logInfo = "[" + sc_time_stamp().to_string() + "]" 106 | + name() + " now stop"; 107 | cout << logInfo << endl; 108 | sc_stop(); 109 | } 110 | }; 111 | 112 | int sc_main(int, char**) { 113 | int fifo_size = 5; // exercise 2 114 | DF_Const constant("constant",3); 115 | DF_Adder adder("adder"); 116 | DF_Fork fork("fork"); 117 | DF_Printer printer("printer"); 118 | Terminator terminator("terminator"); 119 | //fifo 120 | sc_fifo const_out("const_out",fifo_size); 121 | sc_fifo adder_out("adder_out",fifo_size); 122 | sc_fifo feedback("feedback",fifo_size); 123 | sc_fifo to_printer("to_printer",fifo_size); 124 | sc_signal to_terminator; 125 | feedback.write(42); 126 | constant.output(const_out); 127 | adder.input1(feedback); 128 | adder.input2(const_out); 129 | adder.output(adder_out); 130 | fork.input(adder_out); 131 | fork.output1(feedback); 132 | fork.output2(to_printer); 133 | printer.input(to_printer); 134 | printer.done(to_terminator); //output 135 | terminator.inputs(to_terminator); 136 | //sc_start(-1); 137 | sc_start(); 138 | //sc_start(200, SC_MS); 139 | return 0; 140 | } 141 | 142 | /** 143 | * The original output: 144 | * printer45 145 | * printer48 146 | * printer51 147 | * printer54 148 | * printer57 149 | * printer60 150 | * printer63 151 | * printer66 152 | * printer69 153 | * printer72 154 | * 155 | * The output of exercise (1): 156 | * [0 s]constant now process with a constant 3 157 | * [0 s]constant now process with a constant 3 158 | * [200 ns]adder now process 159 | * [200 ns]fork now process with a value 45 160 | * [200 ns]printer 45 161 | * [200 ns]constant now process with a constant 3 162 | * [400 ns]adder now process 163 | * [400 ns]fork now process with a value 48 164 | * [400 ns]printer 48 165 | * [400 ns]constant now process with a constant 3 166 | * [600 ns]adder now process 167 | * [600 ns]fork now process with a value 51 168 | * [600 ns]printer 51 169 | * [600 ns]constant now process with a constant 3 170 | * [800 ns]adder now process 171 | * [800 ns]fork now process with a value 54 172 | * [800 ns]printer 54 173 | * [800 ns]constant now process with a constant 3 174 | * [1 us]adder now process 175 | * [1 us]fork now process with a value 57 176 | * [1 us]printer 57 177 | * [1 us]constant now process with a constant 3 178 | * [1200 ns]adder now process 179 | * [1200 ns]fork now process with a value 60 180 | * [1200 ns]printer 60 181 | * [1200 ns]constant now process with a constant 3 182 | * [1400 ns]adder now process 183 | * [1400 ns]fork now process with a value 63 184 | * [1400 ns]printer 63 185 | * [1400 ns]constant now process with a constant 3 186 | * [1600 ns]adder now process 187 | * [1600 ns]fork now process with a value 66 188 | * [1600 ns]printer 66 189 | * [1600 ns]constant now process with a constant 3 190 | * [1800 ns]adder now process 191 | * [1800 ns]fork now process with a value 69 192 | * [1800 ns]printer 69 193 | * [1800 ns]constant now process with a constant 3 194 | * [2 us]adder now process 195 | * [2 us]fork now process with a value 72 196 | * [2 us]printer 72 197 | * [2 us]terminator now stop 198 | * [2 us]constant now process with a constant 3 199 | * 200 | * The output of exercise (2): 201 | * 202 | * The output of exercise (3): 203 | * */ -------------------------------------------------------------------------------- /Adder/simple_adder.cpp: -------------------------------------------------------------------------------- 1 | /** This file is copied from the slides. 2 | * */ 3 | #include 4 | #include 5 | template SC_MODULE(DF_Adder){ 6 | sc_fifo_in input1, input2; 7 | sc_fifo_out output; 8 | void process(){ 9 | while(1) 10 | output.write(input1.read()+input2.read()); 11 | } 12 | 13 | SC_CTOR(DF_Adder) 14 | { 15 | SC_THREAD(process); 16 | } 17 | }; 18 | 19 | template SC_MODULE(DF_Const) { 20 | sc_fifo_out output; 21 | void process() { 22 | while (1) output.write(constant_); 23 | } 24 | SC_HAS_PROCESS(DF_Const); 25 | DF_Const(sc_module_name N, const T&C): 26 | sc_module(N), constant_(C) 27 | {SC_THREAD(process);} 28 | T constant_; 29 | }; 30 | 31 | template SC_MODULE(DF_Fork){ 32 | sc_fifo_in input; 33 | sc_fifo_out output1,output2; 34 | void process(){ 35 | while(1) { 36 | T value=input.read(); 37 | output1.write(value); 38 | output2.write(value); 39 | } } 40 | SC_CTOR(DF_Fork) { 41 | SC_THREAD(process) 42 | } 43 | }; 44 | 45 | template SC_MODULE(DF_Printer){ 46 | sc_fifo_in input; 47 | SC_HAS_PROCESS(DF_Printer); 48 | DF_Printer(const sc_module_name& NAME, unsigned N_ITER): 49 | sc_module(NAME), n_iterations_(N_ITER), done_(false) 50 | {SC_THREAD(print_process)} 51 | void print_process(){ 52 | for(unsigned i=0;i constant("constant",3); 69 | DF_Adder adder("adder"); 70 | DF_Fork fork("fork"); 71 | DF_Printer printer("printer",10); 72 | //fifo 73 | sc_fifo const_out("const_out",1); 74 | sc_fifo adder_out("adder_out",1); 75 | sc_fifo feedback("feedback",1); 76 | sc_fifo to_printer("tc_printer",1); 77 | feedback.write(42); 78 | constant.output(const_out); 79 | adder.input1(feedback); 80 | adder.input2(const_out); 81 | adder.output(adder_out); 82 | fork.input(adder_out); 83 | fork.output1(feedback); 84 | fork.output2(to_printer); 85 | printer.input(to_printer); 86 | //sc_start(-1); 87 | sc_start(); 88 | return 0; 89 | } -------------------------------------------------------------------------------- /Doulos_Example5/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | project(Doulos_Example5) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | # change your SystemC installation directory 6 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 7 | # if under linux OS 8 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 9 | message(STATUS "Current development environment is Linux,") 10 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 11 | message(STATUS "Current development environment is Windows,") 12 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 13 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 14 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 15 | 16 | include_directories(${CMAKE_PREFIX_PATH}/include) 17 | find_package(SystemCLanguage CONFIG REQUIRED) 18 | link_directories(${CMAKE_PREFIX_PATH}/lib) 19 | 20 | add_executable(Doulos_Example5 testbench.cpp top.h initiator1.h utilities.h initiator2.h bus.h target.h) 21 | 22 | target_link_libraries (Doulos_Example5 SystemC::systemc) 23 | -------------------------------------------------------------------------------- /Doulos_Example5/README.md: -------------------------------------------------------------------------------- 1 | # Example 5 - Temporal Decoupling, Multiple Initiators and Targets 2 | 3 | This is a TLM demo developed by Doulos, 4 | you can find the original descriptions 5 | [here](https://www.doulos.com/knowhow/systemc/tlm2/example_5/index.php). 6 | 7 | In this project, it: 8 | + Shows two loosely-timed initiators both with temporal decoupling and quantum keeper 9 | + Shows a bus with multiple initiators and multiple targets (four memories) 10 | + Routes transactions to target and back using address decoding built into the bus 11 | + Uses tagged interfaces and sockets to implement multiple fw/bw interfaces in a single module 12 | + Propagates DMI calls on both forward and backward paths, 13 | with 'invalidate' being broadcast to every initiator 14 | + Shows transaction pooling using a memory manager -------------------------------------------------------------------------------- /Doulos_Example5/bus.h: -------------------------------------------------------------------------------- 1 | #ifndef BUS_H 2 | #define BUS_H 3 | 4 | #include "utilities.h" 5 | #include "tlm_utils/simple_initiator_socket.h" 6 | #include "tlm_utils/simple_target_socket.h" 7 | 8 | // ************************************************************************************ 9 | // Bus model supports multiple initiators and multiple targets 10 | // Supports b_ and nb_ transport interfaces, although only b_transport is actually used 11 | // It does no arbitration, but routes all transactions from initiators without blocking 12 | // It uses a simple built-in routing algorithm 13 | // ************************************************************************************ 14 | 15 | template 16 | struct Bus: sc_module 17 | { 18 | // Tagged sockets allow incoming transactions to be identified 19 | tlm_utils::simple_target_socket_tagged* targ_socket[N_INITIATORS]; 20 | tlm_utils::simple_initiator_socket_tagged* init_socket[N_TARGETS]; 21 | 22 | SC_CTOR(Bus) 23 | { 24 | for (unsigned int i = 0; i < N_INITIATORS; i++) 25 | { 26 | char txt[20]; 27 | sprintf(txt, "targ_socket_%d", i); 28 | targ_socket[i] = new tlm_utils::simple_target_socket_tagged(txt); 29 | 30 | targ_socket[i]->register_nb_transport_fw( this, &Bus::nb_transport_fw, i); 31 | targ_socket[i]->register_b_transport( this, &Bus::b_transport, i); 32 | targ_socket[i]->register_get_direct_mem_ptr(this, &Bus::get_direct_mem_ptr, i); 33 | targ_socket[i]->register_transport_dbg( this, &Bus::transport_dbg, i); 34 | } 35 | for (unsigned int i = 0; i < N_TARGETS; i++) 36 | { 37 | char txt[20]; 38 | sprintf(txt, "init_socket_%d", i); 39 | init_socket[i] = new tlm_utils::simple_initiator_socket_tagged(txt); 40 | 41 | init_socket[i]->register_nb_transport_bw( this, &Bus::nb_transport_bw, i); 42 | init_socket[i]->register_invalidate_direct_mem_ptr(this, &Bus::invalidate_direct_mem_ptr, i); 43 | } 44 | } 45 | 46 | 47 | // Tagged non-blocking transport forward method 48 | virtual tlm::tlm_sync_enum nb_transport_fw(int id, 49 | tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) 50 | { 51 | if (id < N_INITIATORS) 52 | { 53 | // Forward path 54 | m_id_map[ &trans ] = id; 55 | 56 | sc_dt::uint64 address = trans.get_address(); 57 | sc_dt::uint64 masked_address; 58 | unsigned int target_nr = decode_address( address, masked_address); 59 | 60 | if (target_nr < N_TARGETS) 61 | { 62 | // Modify address within transaction 63 | trans.set_address( masked_address ); 64 | 65 | // Forward transaction to appropriate target 66 | tlm::tlm_sync_enum status = (*init_socket[target_nr])->nb_transport_fw(trans, phase, delay); 67 | 68 | if (status == tlm::TLM_COMPLETED) 69 | // Put back original address 70 | trans.set_address( address ); 71 | return status; 72 | } 73 | else 74 | return tlm::TLM_COMPLETED; 75 | } 76 | else 77 | { 78 | SC_REPORT_FATAL("TLM-2", "Invalid tagged socket id in bus"); 79 | return tlm::TLM_COMPLETED; 80 | } 81 | } 82 | 83 | // Tagged non-blocking transport backward method 84 | virtual tlm::tlm_sync_enum nb_transport_bw(int id, 85 | tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) 86 | { 87 | if (id < N_TARGETS) 88 | { 89 | // Backward path 90 | 91 | // Replace original address 92 | sc_dt::uint64 address = trans.get_address(); 93 | trans.set_address( compose_address( id, address ) ); 94 | 95 | return ( *(targ_socket[ m_id_map[ &trans ] ]) )->nb_transport_bw(trans, phase, delay); 96 | } 97 | else 98 | { 99 | SC_REPORT_FATAL("TLM-2", "Invalid tagged socket id in bus"); 100 | return tlm::TLM_COMPLETED; 101 | } 102 | } 103 | 104 | // Tagged TLM-2 blocking transport method 105 | virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay ) 106 | { 107 | if (id < N_INITIATORS) 108 | { 109 | // Forward path 110 | sc_dt::uint64 address = trans.get_address(); 111 | sc_dt::uint64 masked_address; 112 | unsigned int target_nr = decode_address( address, masked_address); 113 | 114 | if (target_nr < N_TARGETS) 115 | { 116 | // Modify address within transaction 117 | trans.set_address( masked_address ); 118 | 119 | // Forward transaction to appropriate target 120 | (*init_socket[target_nr])->b_transport(trans, delay); 121 | 122 | // Replace original address 123 | trans.set_address( address ); 124 | } 125 | } 126 | else 127 | SC_REPORT_FATAL("TLM-2", "Invalid tagged socket id in bus"); 128 | } 129 | 130 | // Tagged TLM-2 forward DMI method 131 | virtual bool get_direct_mem_ptr(int id, 132 | tlm::tlm_generic_payload& trans, 133 | tlm::tlm_dmi& dmi_data) 134 | { 135 | sc_dt::uint64 masked_address; 136 | unsigned int target_nr = decode_address( trans.get_address(), masked_address ); 137 | if (target_nr >= N_TARGETS) 138 | return false; 139 | 140 | trans.set_address( masked_address ); 141 | 142 | bool status = ( *init_socket[target_nr] )->get_direct_mem_ptr( trans, dmi_data ); 143 | 144 | // Calculate DMI address of target in system address space 145 | dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() )); 146 | dmi_data.set_end_address ( compose_address( target_nr, dmi_data.get_end_address() )); 147 | 148 | return status; 149 | } 150 | 151 | 152 | // Tagged debug transaction method 153 | virtual unsigned int transport_dbg(int id, tlm::tlm_generic_payload& trans) 154 | { 155 | sc_dt::uint64 masked_address; 156 | unsigned int target_nr = decode_address( trans.get_address(), masked_address ); 157 | if (target_nr >= N_TARGETS) 158 | return 0; 159 | trans.set_address( masked_address ); 160 | 161 | // Forward debug transaction to appropriate target 162 | return ( *init_socket[target_nr] )->transport_dbg( trans ); 163 | } 164 | 165 | 166 | // Tagged backward DMI method 167 | virtual void invalidate_direct_mem_ptr(int id, 168 | sc_dt::uint64 start_range, 169 | sc_dt::uint64 end_range) 170 | { 171 | // Reconstruct address range in system memory map 172 | sc_dt::uint64 bw_start_range = compose_address( id, start_range ); 173 | sc_dt::uint64 bw_end_range = compose_address( id, end_range ); 174 | 175 | // Propagate call backward to all initiators 176 | for (unsigned int i = 0; i < N_INITIATORS; i++) 177 | (*targ_socket[i])->invalidate_direct_mem_ptr(bw_start_range, bw_end_range); 178 | } 179 | 180 | // Simple fixed address decoding 181 | inline unsigned int decode_address( sc_dt::uint64 address, sc_dt::uint64& masked_address ) 182 | { 183 | unsigned int target_nr = static_cast( (address >> 6) & 0x3 ); 184 | masked_address = address & 0x3F; 185 | return target_nr; 186 | } 187 | 188 | inline sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address) 189 | { 190 | return (target_nr << 6) | (address & 0x3F); 191 | } 192 | 193 | std::map m_id_map; 194 | }; 195 | 196 | #endif 197 | -------------------------------------------------------------------------------- /Doulos_Example5/initiator1.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIATOR1_H 2 | #define INITIATOR1_H 3 | 4 | #include "utilities.h" 5 | #include "tlm_utils/simple_initiator_socket.h" 6 | #include "tlm_utils/tlm_quantumkeeper.h" 7 | 8 | 9 | // ***************************************************************************************** 10 | // Initiator1 writes to all 4 memories, and demonstrates DMI and debug transport 11 | // Does not use an explicit memory manager 12 | // ***************************************************************************************** 13 | 14 | const int RUN_LENGTH = 256; 15 | 16 | struct Initiator1: sc_module 17 | { 18 | tlm_utils::simple_initiator_socket socket; 19 | 20 | SC_CTOR(Initiator1) : socket("socket"), dmi_ptr_valid(false) 21 | { 22 | socket.register_invalidate_direct_mem_ptr(this, &Initiator1::invalidate_direct_mem_ptr); 23 | 24 | SC_THREAD(thread_process); 25 | 26 | // ************************************************************************* 27 | // All initiators use a quantum of 1us, that is, they synchronize themselves 28 | // to simulation time every 1us using the quantum keeper 29 | // ************************************************************************* 30 | 31 | m_qk.set_global_quantum( sc_time(1, SC_US) ); 32 | m_qk.reset(); 33 | } 34 | 35 | void thread_process() { 36 | // Use debug transaction interface to dump entire memory contents 37 | dump(); 38 | 39 | tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; 40 | sc_time delay; 41 | 42 | for (int i = 0; i < RUN_LENGTH; i += 4) 43 | { 44 | data = i; 45 | delay = m_qk.get_local_time(); 46 | 47 | if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address() 48 | && sc_dt::uint64(i) <= dmi_data.get_end_address()) 49 | { 50 | // Bypass transport interface and use direct memory interface 51 | assert( dmi_data.is_write_allowed() ); 52 | memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4); 53 | 54 | // Accumulate memory latency into local time 55 | delay += dmi_data.get_write_latency(); 56 | 57 | cout << "WRITE/DMI addr = " << hex << i << ", data = " << data 58 | << " at " << sc_time_stamp() << " delay = " << delay << "\n"; 59 | } 60 | else 61 | { 62 | // No DMI, so use blocking transport interface 63 | trans->set_command( tlm::TLM_WRITE_COMMAND ); 64 | trans->set_address( i ); 65 | trans->set_data_ptr( reinterpret_cast(&data) ); 66 | trans->set_data_length( 4 ); 67 | trans->set_streaming_width( 4 ); // = data_length to indicate no streaming 68 | trans->set_byte_enable_ptr( 0 ); // 0 indicates unused 69 | trans->set_dmi_allowed( false ); // Mandatory initial value 70 | trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value 71 | 72 | socket->b_transport( *trans, delay ); 73 | 74 | cout << "WRITE addr = " << hex << i << ", data = " << data 75 | << " at " << sc_time_stamp() << " delay = " << delay << "\n"; 76 | 77 | // Initiator obliged to check response status 78 | if (trans->is_response_error()) 79 | SC_REPORT_ERROR("TLM-2", trans->get_response_string().c_str()); 80 | 81 | if ( trans->is_dmi_allowed() ) 82 | { 83 | dmi_data.init(); 84 | dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data ); 85 | } 86 | } 87 | 88 | // Accumulate local time and synchronize when quantum is reached 89 | m_qk.set( delay ); 90 | m_qk.inc( sc_time(100, SC_NS) ); // Model time used for additional processing 91 | if (m_qk.need_sync()) m_qk.sync(); 92 | } 93 | 94 | // Use debug transaction interface to dump entire memory contents 95 | dump(); 96 | } 97 | 98 | 99 | virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) 100 | { 101 | cout << "INVALIDATE DMI (" << start_range << ".." << end_range 102 | << ") for Initiator1 at " << sc_time_stamp() << "\n"; 103 | 104 | // Ignore range and invalidate all DMI pointers regardless 105 | dmi_ptr_valid = false; 106 | } 107 | 108 | void dump() 109 | { 110 | unsigned char buffer[64]; 111 | // Use debug transaction interface to dump memory contents 112 | 113 | cout << "\nDump memories at time " << sc_time_stamp() << "\n"; 114 | 115 | for (unsigned int k = 0; k < 4; k++) 116 | { 117 | tlm::tlm_generic_payload dbg; 118 | sc_dt::uint64 A = 64 * k; 119 | dbg.set_address(A); 120 | dbg.set_read(); 121 | dbg.set_data_length(64); 122 | dbg.set_data_ptr(buffer); 123 | 124 | unsigned int n_bytes = socket->transport_dbg( dbg ); 125 | 126 | for (unsigned int i = 0; i < n_bytes; i += 4) 127 | { 128 | cout << "mem[" << hex << (A + i) << "] = " 129 | << *(reinterpret_cast( &buffer[i] )) << endl; 130 | } 131 | } 132 | cout << "\n"; 133 | } 134 | 135 | int data; // Internal data buffer used by initiator with generic payload 136 | tlm_utils::tlm_quantumkeeper m_qk; // Quantum keeper for temporal decoupling 137 | bool dmi_ptr_valid; 138 | tlm::tlm_dmi dmi_data; 139 | }; 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /Doulos_Example5/initiator2.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIATOR2_H 2 | #define INITIATOR2_H 3 | 4 | #include "utilities.h" 5 | #include "tlm_utils/simple_initiator_socket.h" 6 | #include "tlm_utils/tlm_quantumkeeper.h" 7 | 8 | // ***************************************************************************************** 9 | // Initiator2 reads from all 4 memories, but does not use DMI or debug transport 10 | // Uses an explicit memory manager and transaction pool 11 | // ***************************************************************************************** 12 | 13 | struct Initiator2: sc_module 14 | { 15 | tlm_utils::simple_initiator_socket socket; 16 | 17 | SC_CTOR(Initiator2) : socket("socket") 18 | { 19 | // No callback methods registered with socket 20 | 21 | SC_THREAD(thread_process); 22 | } 23 | 24 | void thread_process() 25 | { 26 | tlm::tlm_generic_payload* trans; 27 | sc_time delay; 28 | 29 | // Reset the local quantum keeper 30 | m_qk.reset(); 31 | wait(1, SC_US); 32 | 33 | for (int i = 0; i < RUN_LENGTH; i += 4) 34 | { 35 | // Grab a new transaction from the memory manager 36 | trans = m_mm.allocate(); 37 | trans->acquire(); 38 | 39 | data = i; 40 | 41 | trans->set_command( tlm::TLM_READ_COMMAND ); 42 | trans->set_address( i ); 43 | trans->set_data_ptr( reinterpret_cast(&data) ); 44 | trans->set_data_length( 4 ); 45 | trans->set_streaming_width( 4 ); // = data_length to indicate no streaming 46 | trans->set_byte_enable_ptr( 0 ); // 0 indicates unused 47 | trans->set_dmi_allowed( false ); // Mandatory initial value 48 | trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value 49 | 50 | delay = m_qk.get_local_time(); 51 | 52 | socket->b_transport( *trans, delay ); 53 | 54 | // Initiator obliged to check response status 55 | if (trans->is_response_error()) 56 | SC_REPORT_ERROR("TLM-2", trans->get_response_string().c_str()); 57 | if (data != i) 58 | SC_REPORT_ERROR("TLM-2", "Mismatch in initiator when reading back data"); 59 | 60 | cout << "READ addr = " << hex << i << ", data = " << data 61 | << " at " << sc_time_stamp() << " delay = " << delay << "\n"; 62 | trans->release(); 63 | 64 | // Accumulate local time and synchronize when quantum is reached 65 | m_qk.set( delay ); 66 | m_qk.inc( sc_time(100, SC_NS) );// Model time used for additional processing 67 | if (m_qk.need_sync()) m_qk.sync(); 68 | } 69 | } 70 | 71 | int data; // Internal data buffer used by initiator with generic payload 72 | 73 | mm m_mm; // Memory manager 74 | tlm_utils::tlm_quantumkeeper m_qk; // Quantum keeper for temporal decoupling 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /Doulos_Example5/target.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_H 2 | #define TARGET_H 3 | 4 | // ***************************************************************************************** 5 | // Target memory implements b_transport, DMI and debug 6 | // ***************************************************************************************** 7 | 8 | #include 9 | #include "tlm.h" 10 | #include "tlm_utils/simple_target_socket.h" 11 | 12 | struct Memory: sc_module 13 | { 14 | tlm_utils::simple_target_socket socket; 15 | 16 | enum { SIZE = 64 }; 17 | const sc_time LATENCY; 18 | 19 | SC_CTOR(Memory) 20 | : socket("socket"), LATENCY(10, SC_NS) 21 | { 22 | socket.register_b_transport( this, &Memory::b_transport); 23 | socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); 24 | socket.register_transport_dbg( this, &Memory::transport_dbg); 25 | 26 | // Initialize memory with random data 27 | for (int i = 0; i < SIZE; i++) 28 | mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256); 29 | 30 | // Each instance is given identifiable contents to help debug 31 | ++mem_nr; 32 | 33 | SC_THREAD(invalidation_process); 34 | } 35 | 36 | virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 37 | { 38 | tlm::tlm_command cmd = trans.get_command(); 39 | sc_dt::uint64 adr = trans.get_address() / 4; 40 | unsigned char* ptr = trans.get_data_ptr(); 41 | unsigned int len = trans.get_data_length(); 42 | unsigned char* byt = trans.get_byte_enable_ptr(); 43 | unsigned int wid = trans.get_streaming_width(); 44 | 45 | if (adr > sc_dt::uint64(SIZE)) { 46 | trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); 47 | return; 48 | } 49 | if (byt != 0) { 50 | trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); 51 | return; 52 | } 53 | if (len > 4 || wid < len) { 54 | trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); 55 | return; 56 | } 57 | 58 | if (trans.get_command() == tlm::TLM_READ_COMMAND) 59 | memcpy(ptr, &mem[adr], len); 60 | else if (cmd == tlm::TLM_WRITE_COMMAND) 61 | memcpy(&mem[adr], ptr, len); 62 | 63 | // Use temporal decoupling: add memory latency to delay argument 64 | delay += LATENCY; 65 | 66 | trans.set_dmi_allowed(true); 67 | trans.set_response_status( tlm::TLM_OK_RESPONSE ); 68 | } 69 | 70 | 71 | // TLM-2 DMI method 72 | virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, 73 | tlm::tlm_dmi& dmi_data) 74 | { 75 | // Permit read and write access 76 | dmi_data.allow_read_write(); 77 | 78 | // Set other details of DMI region 79 | dmi_data.set_dmi_ptr( reinterpret_cast( &mem[0] ) ); 80 | dmi_data.set_start_address( 0 ); 81 | dmi_data.set_end_address( SIZE*4-1 ); 82 | dmi_data.set_read_latency( LATENCY ); 83 | dmi_data.set_write_latency( LATENCY ); 84 | 85 | return true; 86 | } 87 | 88 | 89 | // TLM-2 debug transaction method 90 | virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) 91 | { 92 | tlm::tlm_command cmd = trans.get_command(); 93 | sc_dt::uint64 adr = trans.get_address() / 4; 94 | unsigned char* ptr = trans.get_data_ptr(); 95 | unsigned int len = trans.get_data_length(); 96 | 97 | // Calculate the number of bytes to be actually copied 98 | unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4; 99 | 100 | if ( cmd == tlm::TLM_READ_COMMAND ) 101 | memcpy(ptr, &mem[adr], num_bytes); 102 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 103 | memcpy(&mem[adr], ptr, num_bytes); 104 | 105 | return num_bytes; 106 | } 107 | 108 | void invalidation_process() 109 | { 110 | // Invalidate DMI pointers once just as an example of routing a call back to initiators 111 | wait(3, SC_US); 112 | socket->invalidate_direct_mem_ptr(0, SIZE-1); 113 | } 114 | 115 | int mem[SIZE]; 116 | static unsigned int mem_nr; // Unique memory number to help debug 117 | }; 118 | 119 | unsigned int Memory::mem_nr = 0; 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /Doulos_Example5/testbench.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // Copyright (c) 2007-2008 by Doulos Ltd. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | //---------------------------------------------------------------------- 16 | 17 | // Version 1, 26-June-2008 18 | // Version 2, 3-July-2008 - fix bug: call dmi_data.init() 19 | // Version 3 12-Jan-2009 - fix bug in transport_dbg 20 | // Version 4 26-Sep-2009 - fix bug with set_end_address 21 | 22 | 23 | // Getting Started with TLM-2.0, Example 5 24 | 25 | // Shows two loosely-timed initiators both with temporal decoupling and quantum keeper 26 | 27 | // Shows a bus with multiple initiators and multiple targets (four memories) 28 | // Routes transactions to target and back using address decoding built into the bus 29 | // Uses tagged interfaces and sockets to implement multiple fw/bw interfaces in a single module 30 | // Propagates DMI calls on both forward and backward paths, 31 | // with 'invalidate' being broadcast to every initiator 32 | 33 | // Shows transaction pooling using a memory manager 34 | 35 | #include "top.h" 36 | 37 | int sc_main(int argc, char* argv[]) 38 | { 39 | Top top("top"); 40 | sc_start(); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Doulos_Example5/top.h: -------------------------------------------------------------------------------- 1 | #ifndef TOP_H 2 | #define TOP_H 3 | 4 | #include "initiator1.h" 5 | #include "initiator2.h" 6 | #include "bus.h" 7 | #include "target.h" 8 | 9 | // ***************************************************************************************** 10 | // Top-level module instantiates 2 initiators, a bus, and 4 memories 11 | // ***************************************************************************************** 12 | 13 | SC_MODULE(Top) 14 | { 15 | Initiator1* init1; 16 | Initiator2* init2; 17 | Bus<2,4>* bus; 18 | Memory* memory[4]; 19 | 20 | SC_CTOR(Top) 21 | { 22 | init1 = new Initiator1("init1"); 23 | init2 = new Initiator2("init2"); 24 | bus = new Bus<2,4> ("bus"); 25 | 26 | init1->socket.bind( *(bus->targ_socket[0]) ); 27 | init2->socket.bind( *(bus->targ_socket[1]) ); 28 | 29 | for (int i = 0; i < 4; i++) 30 | { 31 | char txt[20]; 32 | sprintf(txt, "memory_%d", i); 33 | memory[i] = new Memory(txt); 34 | 35 | ( *(bus->init_socket[i]) ).bind( memory[i]->socket ); 36 | } 37 | } 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Doulos_Example5/utilities.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITIES_H 2 | #define UTILITIES_H 3 | 4 | #include "systemc" 5 | using namespace sc_core; 6 | using namespace sc_dt; 7 | using namespace std; 8 | 9 | #include "tlm.h" 10 | 11 | // ************************************************************************************** 12 | // User-defined memory manager, which maintains a pool of transactions 13 | // ************************************************************************************** 14 | 15 | class mm: public tlm::tlm_mm_interface 16 | { 17 | typedef tlm::tlm_generic_payload gp_t; 18 | 19 | public: 20 | mm() : free_list(0), empties(0) {} 21 | 22 | gp_t* allocate(); 23 | void free(gp_t* trans); 24 | 25 | private: 26 | struct access 27 | { 28 | gp_t* trans; 29 | access* next; 30 | access* prev; 31 | }; 32 | 33 | access* free_list; 34 | access* empties; 35 | 36 | }; 37 | 38 | mm::gp_t* mm::allocate() 39 | { 40 | gp_t* ptr; 41 | if (free_list) 42 | { 43 | ptr = free_list->trans; 44 | empties = free_list; 45 | free_list = free_list->next; 46 | } 47 | else 48 | { 49 | ptr = new gp_t(this); 50 | } 51 | return ptr; 52 | } 53 | 54 | void mm::free(gp_t* trans) 55 | { 56 | if (!empties) 57 | { 58 | empties = new access; 59 | empties->next = free_list; 60 | empties->prev = 0; 61 | if (free_list) 62 | free_list->prev = empties; 63 | } 64 | free_list = empties; 65 | free_list->trans = trans; 66 | empties = free_list->prev; 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /Doulos_Sockets/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Doulos_Sockets) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | # change your SystemC installation directory 7 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 8 | # if under linux OS 9 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 10 | message(STATUS "Current development environment is Linux,") 11 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 12 | message(STATUS "Current development environment is Windows,") 13 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 14 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 15 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 16 | 17 | include_directories(${CMAKE_PREFIX_PATH}/include) 18 | find_package(SystemCLanguage CONFIG REQUIRED) 19 | link_directories(${CMAKE_PREFIX_PATH}/lib) 20 | 21 | add_executable(Doulos_Sockets testbench.cpp target.h initiator.h top.h) 22 | target_link_libraries (Doulos_Sockets SystemC::systemc) 23 | -------------------------------------------------------------------------------- /Doulos_Sockets/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial 1 - Sockets, Generic Payload, Blocking Transport 2 | 3 | This is a TLM demo developed by Doulos, you can find the original 4 | descriptions [here](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/). 5 | 6 | In this project, it: 7 | + Shows the generic payload, sockets, and blocking transport interface. 8 | + Shows the responsibilities of initiator and target with respect to the generic payload. 9 | + Has only dummy implementations of the direct memory and debug transaction interfaces. 10 | + Does not show the non-blocking transport interface. -------------------------------------------------------------------------------- /Doulos_Sockets/initiator.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIATOR_H 2 | #define INITIATOR_H 3 | 4 | #include "systemc" 5 | using namespace sc_core; 6 | using namespace sc_dt; 7 | using namespace std; 8 | 9 | #include "tlm.h" 10 | #include "tlm_utils/simple_initiator_socket.h" 11 | 12 | 13 | // Initiator module generating generic payload transactions 14 | 15 | struct Initiator: sc_module 16 | { 17 | // TLM-2 socket, defaults to 32-bits wide, base protocol 18 | tlm_utils::simple_initiator_socket socket; 19 | 20 | SC_CTOR(Initiator) 21 | : socket("socket") // Construct and name socket 22 | { 23 | SC_THREAD(thread_process); 24 | } 25 | 26 | void thread_process() 27 | { 28 | // TLM-2 generic payload transaction, reused across calls to b_transport 29 | tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; 30 | sc_time delay = sc_time(10, SC_NS); 31 | 32 | // Generate a random sequence of reads and writes 33 | for (int i = 32; i < 96; i += 4) 34 | { 35 | 36 | tlm::tlm_command cmd = static_cast(rand() % 2); 37 | if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i; 38 | 39 | // Initialize 8 out of the 10 attributes, byte_enable_length and extensions being unused 40 | trans->set_command( cmd ); 41 | trans->set_address( i ); 42 | trans->set_data_ptr( reinterpret_cast(&data) ); 43 | trans->set_data_length( 4 ); 44 | trans->set_streaming_width( 4 ); // = data_length to indicate no streaming 45 | trans->set_byte_enable_ptr( 0 ); // 0 indicates unused 46 | trans->set_dmi_allowed( false ); // Mandatory initial value 47 | trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value 48 | 49 | socket->b_transport( *trans, delay ); // Blocking transport call 50 | 51 | // Initiator obliged to check response status and delay 52 | if ( trans->is_response_error() ) 53 | SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); 54 | 55 | cout << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i 56 | << " } , data = " << hex << data << " at time " << sc_time_stamp() 57 | << " delay = " << delay << endl; 58 | 59 | // Realize the delay annotated onto the transport call 60 | wait(delay); 61 | } 62 | } 63 | 64 | // Internal data buffer used by initiator with generic payload 65 | int data; 66 | }; 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /Doulos_Sockets/target.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_H 2 | #define TARGET_H 3 | 4 | // Needed for the simple_target_socket 5 | #define SC_INCLUDE_DYNAMIC_PROCESSES 6 | 7 | #include "systemc" 8 | using namespace sc_core; 9 | using namespace sc_dt; 10 | using namespace std; 11 | 12 | #include "tlm.h" 13 | #include "tlm_utils/simple_target_socket.h" 14 | 15 | 16 | // Target module representing a simple memory 17 | 18 | struct Memory: sc_module 19 | { 20 | // TLM-2 socket, defaults to 32-bits wide, base protocol 21 | tlm_utils::simple_target_socket socket; 22 | 23 | enum { SIZE = 256 }; 24 | 25 | SC_CTOR(Memory) 26 | : socket("socket") 27 | { 28 | // Register callback for incoming b_transport interface method call 29 | socket.register_b_transport(this, &Memory::b_transport); 30 | 31 | // Initialize memory with random data 32 | for (int i = 0; i < SIZE; i++) 33 | mem[i] = 0xAA000000 | (rand() % 256); 34 | } 35 | 36 | // TLM-2 blocking transport method 37 | virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 38 | { 39 | tlm::tlm_command cmd = trans.get_command(); 40 | sc_dt::uint64 adr = trans.get_address() / 4; 41 | unsigned char* ptr = trans.get_data_ptr(); 42 | unsigned int len = trans.get_data_length(); 43 | unsigned char* byt = trans.get_byte_enable_ptr(); 44 | unsigned int wid = trans.get_streaming_width(); 45 | 46 | // Obliged to check address range and check for unsupported features, 47 | // i.e. byte enables, streaming, and bursts 48 | // Can ignore DMI hint and extensions 49 | // Using the SystemC report handler is an acceptable way of signalling an error 50 | 51 | if (adr >= sc_dt::uint64(SIZE) || byt != 0 || len > 4 || wid < len) 52 | SC_REPORT_ERROR("TLM-2", "Target does not support given generic payload transaction"); 53 | 54 | // Obliged to implement read and write commands 55 | if ( cmd == tlm::TLM_READ_COMMAND ) 56 | memcpy(ptr, &mem[adr], len); 57 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 58 | memcpy(&mem[adr], ptr, len); 59 | 60 | // Obliged to set response status to indicate successful completion 61 | trans.set_response_status( tlm::TLM_OK_RESPONSE ); 62 | } 63 | 64 | int mem[SIZE]; 65 | }; 66 | 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /Doulos_Sockets/testbench.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // Copyright (c) 2007-2008 by Doulos Ltd. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | //---------------------------------------------------------------------- 16 | 17 | // Version 2 16-June-2008 - updated for TLM-2.0 18 | 19 | // Getting Started with TLM-2.0, Tutorial Example 1 20 | 21 | // For a full description, see http://www.doulos.com/knowhow/systemc/tlm2 22 | 23 | // Shows the generic payload, sockets, and blocking transport interface. 24 | // Shows the responsibilities of initiator and target with respect to the generic payload. 25 | // Has only dummy implementations of the direct memory and debug transaction interfaces. 26 | // Does not show the non-blocking transport interface. 27 | 28 | #include "top.h" 29 | 30 | int sc_main(int argc, char* argv[]) 31 | { 32 | Top top("top"); 33 | sc_start(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Doulos_Sockets/top.h: -------------------------------------------------------------------------------- 1 | #ifndef TOP_H 2 | #define TOP_H 3 | 4 | #include "initiator.h" 5 | #include "target.h" 6 | 7 | SC_MODULE(Top) 8 | { 9 | Initiator *initiator; 10 | Memory *memory; 11 | 12 | SC_CTOR(Top) 13 | { 14 | // Instantiate components 15 | initiator = new Initiator("initiator"); 16 | memory = new Memory ("memory"); 17 | 18 | // One initiator is bound directly to one target with no intervening bus 19 | 20 | // Bind initiator socket to target socket 21 | initiator->socket.bind( memory->socket ); 22 | } 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Doulos_Tutorial2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Doulos_Tutorial2) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | # change your SystemC installation directory 7 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 8 | # if under linux OS 9 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 10 | message(STATUS "Current development environment is Linux,") 11 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 12 | message(STATUS "Current development environment is Windows,") 13 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 14 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 15 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 16 | 17 | include_directories(${CMAKE_PREFIX_PATH}/include) 18 | find_package(SystemCLanguage CONFIG REQUIRED) 19 | link_directories(${CMAKE_PREFIX_PATH}/lib) 20 | 21 | add_executable(Doulos_Tutorial2 testbench.cpp top.h initiator.h target.h) 22 | target_link_libraries (Doulos_Tutorial2 SystemC::systemc) 23 | -------------------------------------------------------------------------------- /Doulos_Tutorial2/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial 2 - Response Status, DMI, and Debug Transport 2 | 3 | This is a TLM demo developed by Doulos, you can find the original 4 | descriptions [here](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/). 5 | 6 | In this project, it: 7 | + Shows the direct memory interfaces and the DMI hint. 8 | + Shows the debug transaction interface 9 | + Shows the proper use of response status -------------------------------------------------------------------------------- /Doulos_Tutorial2/initiator.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIATOR_H 2 | #define INITIATOR_H 3 | 4 | #include "systemc" 5 | using namespace sc_core; 6 | using namespace sc_dt; 7 | using namespace std; 8 | 9 | #include "tlm.h" 10 | #include "tlm_utils/simple_initiator_socket.h" 11 | 12 | 13 | // Initiator module generating generic payload transactions 14 | 15 | struct Initiator: sc_module 16 | { 17 | // TLM-2 socket, defaults to 32-bits wide, base protocol 18 | tlm_utils::simple_initiator_socket socket; 19 | 20 | SC_CTOR(Initiator) 21 | : socket("socket"), // Construct and name socket 22 | dmi_ptr_valid(false) 23 | { 24 | // Register callbacks for incoming interface method calls 25 | socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidate_direct_mem_ptr); 26 | 27 | SC_THREAD(thread_process); 28 | } 29 | 30 | void thread_process() 31 | { 32 | // TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug 33 | tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; 34 | sc_time delay = sc_time(10, SC_NS); 35 | 36 | // Generate a random sequence of reads and writes 37 | for (int i = 0; i < 128; i += 4) 38 | { 39 | int data; 40 | tlm::tlm_command cmd = static_cast(rand() % 2); 41 | if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i; 42 | 43 | // ********************************************* 44 | // Use DMI if it is available, reusing same transaction object 45 | // ********************************************* 46 | 47 | if (dmi_ptr_valid) 48 | { 49 | // Bypass transport interface and use direct memory interface 50 | // Implement target latency 51 | if ( cmd == tlm::TLM_READ_COMMAND ) 52 | { 53 | assert( dmi_data.is_read_allowed() ); 54 | memcpy(&data, dmi_data.get_dmi_ptr() + i, 4); 55 | wait( dmi_data.get_read_latency() ); 56 | } 57 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 58 | { 59 | assert( dmi_data.is_write_allowed() ); 60 | memcpy(dmi_data.get_dmi_ptr() + i, &data, 4); 61 | wait( dmi_data.get_write_latency() ); 62 | } 63 | 64 | cout << "DMI = { " << (cmd ? 'W' : 'R') << ", " << hex << i 65 | << " } , data = " << hex << data << " at time " << sc_time_stamp() << endl; 66 | } 67 | else 68 | { 69 | trans->set_command( cmd ); 70 | trans->set_address( i ); 71 | trans->set_data_ptr( reinterpret_cast(&data) ); 72 | trans->set_data_length( 4 ); 73 | trans->set_streaming_width( 4 ); // = data_length to indicate no streaming 74 | trans->set_byte_enable_ptr( 0 ); // 0 indicates unused 75 | trans->set_dmi_allowed( false ); // Mandatory initial value 76 | trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value 77 | 78 | #ifdef INJECT_ERROR 79 | if (i > 90) trans->set_streaming_width(2); 80 | #endif 81 | 82 | // Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions 83 | 84 | socket->b_transport( *trans, delay ); // Blocking transport call 85 | 86 | // Initiator obliged to check response status 87 | if ( trans->is_response_error() ) 88 | { 89 | // ********************************************* 90 | // Print response string 91 | // ********************************************* 92 | 93 | char txt[100]; 94 | sprintf(txt, "Error from b_transport, response status = %s", 95 | trans->get_response_string().c_str()); 96 | SC_REPORT_ERROR("TLM-2", txt); 97 | 98 | } 99 | 100 | // ********************************************* 101 | // Check DMI hint 102 | // ********************************************* 103 | 104 | if ( trans->is_dmi_allowed() ) 105 | { 106 | // Re-user transaction object for DMI 107 | dmi_data.init(); 108 | dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data ); 109 | } 110 | 111 | cout << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i 112 | << " } , data = " << hex << data << " at time " << sc_time_stamp() 113 | << " delay = " << delay << endl; 114 | } 115 | } 116 | 117 | // ********************************************* 118 | // Use debug transaction interface to dump memory contents, reusing same transaction object 119 | // ********************************************* 120 | 121 | trans->set_address(0); 122 | trans->set_read(); 123 | trans->set_data_length(128); 124 | 125 | unsigned char* data = new unsigned char[128]; 126 | trans->set_data_ptr(data); 127 | 128 | unsigned int n_bytes = socket->transport_dbg( *trans ); 129 | 130 | for (unsigned int i = 0; i < n_bytes; i += 4) 131 | { 132 | cout << "mem[" << i << "] = " 133 | << *(reinterpret_cast( &data[i] )) << endl; 134 | } 135 | } 136 | 137 | // ********************************************* 138 | // TLM-2 backward DMI method 139 | // ********************************************* 140 | 141 | virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, 142 | sc_dt::uint64 end_range) 143 | { 144 | // Ignore range and invalidate all DMI pointers regardless 145 | dmi_ptr_valid = false; 146 | } 147 | 148 | bool dmi_ptr_valid; 149 | tlm::tlm_dmi dmi_data; 150 | }; 151 | 152 | #endif 153 | 154 | -------------------------------------------------------------------------------- /Doulos_Tutorial2/target.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_H 2 | #define TARGET_H 3 | 4 | // Needed for the simple_target_socket 5 | #define SC_INCLUDE_DYNAMIC_PROCESSES 6 | 7 | #include "systemc" 8 | using namespace sc_core; 9 | using namespace sc_dt; 10 | using namespace std; 11 | 12 | #include "tlm.h" 13 | #include "tlm_utils/simple_target_socket.h" 14 | 15 | 16 | // Target module representing a simple memory 17 | 18 | struct Memory: sc_module 19 | { 20 | // TLM-2 socket, defaults to 32-bits wide, base protocol 21 | tlm_utils::simple_target_socket socket; 22 | 23 | enum { SIZE = 256 }; 24 | const sc_time LATENCY; 25 | 26 | SC_CTOR(Memory) 27 | : socket("socket"), LATENCY(10, SC_NS) 28 | { 29 | // Register callbacks for incoming interface method calls 30 | socket.register_b_transport( this, &Memory::b_transport); 31 | socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); 32 | socket.register_transport_dbg( this, &Memory::transport_dbg); 33 | 34 | // Initialize memory with random data 35 | for (int i = 0; i < SIZE; i++) 36 | mem[i] = 0xAA000000 | (rand() % 256); 37 | 38 | SC_THREAD(invalidation_process); 39 | } 40 | 41 | // TLM-2 blocking transport method 42 | virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 43 | { 44 | tlm::tlm_command cmd = trans.get_command(); 45 | sc_dt::uint64 adr = trans.get_address() / 4; 46 | unsigned char* ptr = trans.get_data_ptr(); 47 | unsigned int len = trans.get_data_length(); 48 | unsigned char* byt = trans.get_byte_enable_ptr(); 49 | unsigned int wid = trans.get_streaming_width(); 50 | 51 | // Obliged to check address range and check for unsupported features, 52 | // i.e. byte enables, streaming, and bursts 53 | // Can ignore extensions 54 | 55 | // ********************************************* 56 | // Generate the appropriate error response 57 | // ********************************************* 58 | 59 | if (adr >= sc_dt::uint64(SIZE)) { 60 | trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); 61 | return; 62 | } 63 | if (byt != 0) { 64 | trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); 65 | return; 66 | } 67 | if (len > 4 || wid < len) { 68 | trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); 69 | return; 70 | } 71 | 72 | // Obliged to implement read and write commands 73 | if ( cmd == tlm::TLM_READ_COMMAND ) 74 | memcpy(ptr, &mem[adr], len); 75 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 76 | memcpy(&mem[adr], ptr, len); 77 | 78 | // Illustrates that b_transport may block 79 | wait(delay); 80 | 81 | // Reset timing annotation after waiting 82 | delay = SC_ZERO_TIME; 83 | 84 | // ********************************************* 85 | // Set DMI hint to indicated that DMI is supported 86 | // ********************************************* 87 | 88 | trans.set_dmi_allowed(true); 89 | 90 | // Obliged to set response status to indicate successful completion 91 | trans.set_response_status( tlm::TLM_OK_RESPONSE ); 92 | } 93 | 94 | // ********************************************* 95 | // TLM-2 forward DMI method 96 | // ********************************************* 97 | 98 | virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, 99 | tlm::tlm_dmi& dmi_data) 100 | { 101 | // Permit read and write access 102 | dmi_data.allow_read_write(); 103 | 104 | // Set other details of DMI region 105 | dmi_data.set_dmi_ptr( reinterpret_cast( &mem[0] ) ); 106 | dmi_data.set_start_address( 0 ); 107 | dmi_data.set_end_address( SIZE*4-1 ); 108 | dmi_data.set_read_latency( LATENCY ); 109 | dmi_data.set_write_latency( LATENCY ); 110 | 111 | return true; 112 | } 113 | 114 | void invalidation_process() 115 | { 116 | // Invalidate DMI pointers periodically 117 | for (int i = 0; i < 4; i++) 118 | { 119 | wait(LATENCY*8); 120 | socket->invalidate_direct_mem_ptr(0, SIZE-1); 121 | } 122 | } 123 | 124 | // ********************************************* 125 | // TLM-2 debug transport method 126 | // ********************************************* 127 | 128 | virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) 129 | { 130 | tlm::tlm_command cmd = trans.get_command(); 131 | sc_dt::uint64 adr = trans.get_address() / 4; 132 | unsigned char* ptr = trans.get_data_ptr(); 133 | unsigned int len = trans.get_data_length(); 134 | 135 | // Calculate the number of bytes to be actually copied 136 | unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4; 137 | 138 | if ( cmd == tlm::TLM_READ_COMMAND ) 139 | memcpy(ptr, &mem[adr], num_bytes); 140 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 141 | memcpy(&mem[adr], ptr, num_bytes); 142 | 143 | return num_bytes; 144 | } 145 | 146 | int mem[SIZE]; 147 | }; 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /Doulos_Tutorial2/testbench.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // Copyright (c) 2007-2008 by Doulos Ltd. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | //---------------------------------------------------------------------- 16 | 17 | // Version 2 18-June-2008 - updated for TLM-2.0 18 | // Version 3 3-July-2008 - bug fix: call dmi_data.init() 19 | // Version 4 12-Jan-2009 - fix bug in transport_dbg 20 | // Version 5 26-Sep-2009 - fix bug with set_end_address 21 | 22 | // Getting Started with TLM-2.0, Tutorial Example 2 23 | 24 | // For a full description, see http://www.doulos.com/knowhow/systemc/tlm2 25 | 26 | // Shows the direct memory interfaces and the DMI hint. 27 | // Shows the debug transaction interface 28 | // Shows the proper use of response status 29 | 30 | // Define the following macro to invoke an error response from the target 31 | // #define INJECT_ERROR 32 | 33 | #include "top.h" 34 | 35 | int sc_main(int argc, char* argv[]) 36 | { 37 | Top top("top"); 38 | sc_start(); 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Doulos_Tutorial2/top.h: -------------------------------------------------------------------------------- 1 | #ifndef TOP_H 2 | #define TOP_H 3 | 4 | #include "initiator.h" 5 | #include "target.h" 6 | 7 | SC_MODULE(Top) 8 | { 9 | Initiator *initiator; 10 | Memory *memory; 11 | 12 | SC_CTOR(Top) 13 | { 14 | // Instantiate components 15 | initiator = new Initiator("initiator"); 16 | memory = new Memory ("memory"); 17 | 18 | // One initiator is bound directly to one target with no intervening bus 19 | 20 | // Bind initiator socket to target socket 21 | initiator->socket.bind(memory->socket); 22 | } 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | project(Doulos_Tutorial3) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | # change your SystemC installation directory 6 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 7 | # if under linux OS 8 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 9 | message(STATUS "Current development environment is Linux,") 10 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 11 | message(STATUS "Current development environment is Windows,") 12 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 13 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 14 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 15 | 16 | include_directories(${CMAKE_PREFIX_PATH}/include) 17 | find_package(SystemCLanguage CONFIG REQUIRED) 18 | link_directories(${CMAKE_PREFIX_PATH}/lib) 19 | 20 | add_executable(Doulos_Tutorial3 testbench.cpp router.h target.h initiator.h top.h) 21 | target_link_libraries (Doulos_Tutorial3 SystemC::systemc) 22 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial 3 - Routing Methods through Interconnect Components 2 | 3 | This is a TLM demo developed by Doulos, 4 | you can find the original descriptions 5 | [here](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/). 6 | 7 | In this project, it: 8 | + Shows a router modeled as an interconnect component 9 | between the initiator and the target 10 | + The router decodes the address to select a target, 11 | and masks the address in the transaction 12 | + Shows the router passing transport, 13 | DMI and debug transactions along forward and backward paths 14 | and doing address translation in both directions 15 | 16 | The hierarchy is shown bellow: 17 | 18 | ![the module hierarchy](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/ex_3.gif) -------------------------------------------------------------------------------- /Doulos_Tutorial3/initiator.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIATOR_H 2 | #define INITIATOR_H 3 | 4 | #include "systemc" 5 | using namespace sc_core; 6 | using namespace sc_dt; 7 | using namespace std; 8 | 9 | #include "tlm.h" 10 | #include "tlm_utils/simple_initiator_socket.h" 11 | 12 | 13 | // Initiator module generating generic payload transactions 14 | 15 | struct Initiator: sc_module 16 | { 17 | // TLM-2 socket, defaults to 32-bits wide, base protocol 18 | tlm_utils::simple_initiator_socket socket; 19 | 20 | SC_CTOR(Initiator) 21 | : socket("socket"), // Construct and name socket 22 | dmi_ptr_valid(false) 23 | { 24 | // Register callbacks for incoming interface method calls 25 | socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidate_direct_mem_ptr); 26 | 27 | SC_THREAD(thread_process); 28 | } 29 | 30 | void thread_process() 31 | { 32 | // TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug 33 | tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; 34 | sc_time delay = sc_time(10, SC_NS); 35 | 36 | // Generate a random sequence of reads and writes 37 | for (int i = 256-64; i < 256+64; i += 4) 38 | { 39 | int data; 40 | tlm::tlm_command cmd = static_cast(rand() % 2); 41 | if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i; 42 | 43 | // Use DMI if it is available 44 | if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address() 45 | && sc_dt::uint64(i) <= dmi_data.get_end_address()) 46 | { 47 | // Bypass transport interface and use direct memory interface 48 | // Implement target latency 49 | if ( cmd == tlm::TLM_READ_COMMAND ) 50 | { 51 | assert( dmi_data.is_read_allowed() ); 52 | memcpy(&data, dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), 4); 53 | wait( dmi_data.get_read_latency() ); 54 | } 55 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 56 | { 57 | assert( dmi_data.is_write_allowed() ); 58 | memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4); 59 | wait( dmi_data.get_write_latency() ); 60 | } 61 | 62 | cout << "DMI = { " << (cmd ? 'W' : 'R') << ", " << hex << i 63 | << " } , data = " << hex << data << " at time " << sc_time_stamp() << endl; 64 | } 65 | else 66 | { 67 | trans->set_command( cmd ); 68 | trans->set_address( i ); 69 | trans->set_data_ptr( reinterpret_cast(&data) ); 70 | trans->set_data_length( 4 ); 71 | trans->set_streaming_width( 4 ); // = data_length to indicate no streaming 72 | trans->set_byte_enable_ptr( 0 ); // 0 indicates unused 73 | trans->set_dmi_allowed( false ); // Mandatory initial value 74 | trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value 75 | 76 | 77 | #ifdef INJECT_ERROR 78 | if (i > 90) trans->set_streaming_width(2); 79 | #endif 80 | 81 | // Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions 82 | 83 | socket->b_transport( *trans, delay ); // Blocking transport call 84 | 85 | // Initiator obliged to check response status 86 | if ( trans->is_response_error() ) 87 | { 88 | // Print response string 89 | char txt[100]; 90 | sprintf(txt, "Error from b_transport, response status = %s", 91 | trans->get_response_string().c_str()); 92 | SC_REPORT_ERROR("TLM-2", txt); 93 | 94 | } 95 | 96 | // Check DMI hint 97 | if ( trans->is_dmi_allowed() ) 98 | { 99 | // ********************************************* 100 | // Re-use transaction object for DMI. Reset the address because it could 101 | // have been modified by the interconnect on the previous transport call 102 | // ********************************************* 103 | 104 | trans->set_address( i ); 105 | dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data ); 106 | } 107 | 108 | cout << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i 109 | << " } , data = " << hex << data << " at time " << sc_time_stamp() << endl; 110 | } 111 | } 112 | 113 | // Use debug transaction interface to dump memory contents, reusing same transaction object 114 | sc_dt::uint64 A = 128; 115 | trans->set_address(A); 116 | trans->set_read(); 117 | trans->set_data_length(256); 118 | 119 | unsigned char* data = new unsigned char[256]; 120 | trans->set_data_ptr(data); 121 | 122 | unsigned int n_bytes = socket->transport_dbg( *trans ); 123 | 124 | for (unsigned int i = 0; i < n_bytes; i += 4) 125 | { 126 | cout << "mem[" << (A + i) << "] = " 127 | << *(reinterpret_cast( &data[i] )) << endl; 128 | } 129 | 130 | A = 256; 131 | trans->set_address(A); 132 | trans->set_data_length(128); 133 | 134 | n_bytes = socket->transport_dbg( *trans ); 135 | 136 | for (unsigned int i = 0; i < n_bytes; i += 4) 137 | { 138 | cout << "mem[" << (A + i) << "] = " 139 | << *(reinterpret_cast( &data[i] )) << endl; 140 | } 141 | } 142 | 143 | // TLM-2 backward DMI method 144 | virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, 145 | sc_dt::uint64 end_range) 146 | { 147 | // Ignore range and invalidate all DMI pointers regardless 148 | dmi_ptr_valid = false; 149 | } 150 | 151 | bool dmi_ptr_valid; 152 | tlm::tlm_dmi dmi_data; 153 | }; 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/router.h: -------------------------------------------------------------------------------- 1 | #ifndef ROUTER_H 2 | #define ROUTER_H 3 | 4 | #include "systemc" 5 | using namespace sc_core; 6 | using namespace sc_dt; 7 | using namespace std; 8 | 9 | #include "tlm.h" 10 | #include "tlm_utils/simple_initiator_socket.h" 11 | #include "tlm_utils/simple_target_socket.h" 12 | 13 | 14 | // ********************************************* 15 | // Generic payload blocking transport router 16 | // ********************************************* 17 | 18 | template 19 | struct Router: sc_module 20 | { 21 | // TLM-2 socket, defaults to 32-bits wide, base protocol 22 | tlm_utils::simple_target_socket target_socket; 23 | 24 | // ********************************************* 25 | // Use tagged sockets to be able to distinguish incoming backward path calls 26 | // ********************************************* 27 | 28 | tlm_utils::simple_initiator_socket_tagged* initiator_socket[N_TARGETS]; 29 | 30 | SC_CTOR(Router) 31 | : target_socket("target_socket") 32 | { 33 | // Register callbacks for incoming interface method calls 34 | target_socket.register_b_transport( this, &Router::b_transport); 35 | target_socket.register_get_direct_mem_ptr(this, &Router::get_direct_mem_ptr); 36 | target_socket.register_transport_dbg( this, &Router::transport_dbg); 37 | 38 | for (unsigned int i = 0; i < N_TARGETS; i++) 39 | { 40 | char txt[20]; 41 | sprintf(txt, "socket_%d", i); 42 | initiator_socket[i] = new tlm_utils::simple_initiator_socket_tagged(txt); 43 | 44 | // ********************************************* 45 | // Register callbacks for incoming interface method calls, including tags 46 | // ********************************************* 47 | initiator_socket[i]->register_invalidate_direct_mem_ptr(this, &Router::invalidate_direct_mem_ptr, i); 48 | } 49 | } 50 | 51 | // **************** 52 | // FORWARD PATH 53 | // **************** 54 | 55 | // TLM-2 blocking transport method 56 | virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 57 | { 58 | sc_dt::uint64 address = trans.get_address(); 59 | sc_dt::uint64 masked_address; 60 | unsigned int target_nr = decode_address( address, masked_address); 61 | 62 | // Modify address within transaction 63 | trans.set_address( masked_address ); 64 | 65 | // Forward transaction to appropriate target 66 | ( *initiator_socket[target_nr] )->b_transport( trans, delay ); 67 | } 68 | 69 | // TLM-2 forward DMI method 70 | virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, 71 | tlm::tlm_dmi& dmi_data) 72 | { 73 | sc_dt::uint64 masked_address; 74 | unsigned int target_nr = decode_address( trans.get_address(), masked_address ); 75 | trans.set_address( masked_address ); 76 | 77 | bool status = ( *initiator_socket[target_nr] )->get_direct_mem_ptr( trans, dmi_data ); 78 | 79 | // Calculate DMI address of target in system address space 80 | dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() )); 81 | dmi_data.set_end_address ( compose_address( target_nr, dmi_data.get_end_address() )); 82 | 83 | return status; 84 | } 85 | 86 | // TLM-2 debug transaction method 87 | virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) 88 | { 89 | sc_dt::uint64 masked_address; 90 | unsigned int target_nr = decode_address( trans.get_address(), masked_address ); 91 | trans.set_address( masked_address ); 92 | 93 | // Forward debug transaction to appropriate target 94 | return ( *initiator_socket[target_nr] )->transport_dbg( trans ); 95 | } 96 | 97 | // **************** 98 | // BACKWARD PATH 99 | // **************** 100 | 101 | // ************************** 102 | // Tagged backward DMI method 103 | // ************************** 104 | 105 | virtual void invalidate_direct_mem_ptr(int id, 106 | sc_dt::uint64 start_range, 107 | sc_dt::uint64 end_range) 108 | { 109 | // Reconstruct address range in system memory map 110 | sc_dt::uint64 bw_start_range = compose_address( id, start_range ); 111 | sc_dt::uint64 bw_end_range = compose_address( id, end_range ); 112 | target_socket->invalidate_direct_mem_ptr(bw_start_range, bw_end_range); 113 | } 114 | 115 | // **************** 116 | // ROUTER INTERNALS 117 | // **************** 118 | 119 | // Simple fixed address decoding 120 | inline unsigned int decode_address( sc_dt::uint64 address, sc_dt::uint64& masked_address ) 121 | { 122 | unsigned int target_nr = static_cast( (address >> 8) & 0x3 ); 123 | masked_address = address & 0xFF; 124 | return target_nr; 125 | } 126 | 127 | inline sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address) 128 | { 129 | return (target_nr << 8) | (address & 0xFF); 130 | } 131 | }; 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/target.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_H 2 | #define TARGET_H 3 | 4 | // Needed for the simple_target_socket 5 | #define SC_INCLUDE_DYNAMIC_PROCESSES 6 | 7 | #include "systemc" 8 | using namespace sc_core; 9 | using namespace sc_dt; 10 | using namespace std; 11 | 12 | #include "tlm.h" 13 | #include "tlm_utils/simple_target_socket.h" 14 | 15 | 16 | // Target module representing a simple memory 17 | 18 | struct Memory: sc_module 19 | { 20 | // TLM-2 socket, defaults to 32-bits wide, base protocol 21 | tlm_utils::simple_target_socket socket; 22 | 23 | enum { SIZE = 256 }; 24 | const sc_time LATENCY; 25 | 26 | SC_CTOR(Memory) 27 | : socket("socket"), LATENCY(10, SC_NS) 28 | { 29 | // Register callbacks for incoming interface method calls 30 | socket.register_b_transport( this, &Memory::b_transport); 31 | socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); 32 | socket.register_transport_dbg( this, &Memory::transport_dbg); 33 | 34 | // Initialize memory with random data 35 | for (int i = 0; i < SIZE; i++) 36 | mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256); 37 | 38 | ++mem_nr; 39 | } 40 | 41 | // TLM-2 blocking transport method 42 | virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 43 | { 44 | tlm::tlm_command cmd = trans.get_command(); 45 | sc_dt::uint64 adr = trans.get_address() / 4; 46 | unsigned char* ptr = trans.get_data_ptr(); 47 | unsigned int len = trans.get_data_length(); 48 | unsigned char* byt = trans.get_byte_enable_ptr(); 49 | unsigned int wid = trans.get_streaming_width(); 50 | 51 | // Obliged to check address range and check for unsupported features, 52 | // i.e. byte enables, streaming, and bursts 53 | // Can ignore extensions 54 | 55 | // Generate the appropriate error response 56 | if (adr >= SIZE) { 57 | trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); 58 | return; 59 | } 60 | if (byt != 0) { 61 | trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); 62 | return; 63 | } 64 | if (len > 4 || wid < len) { 65 | trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); 66 | return; 67 | } 68 | 69 | wait(delay); 70 | delay = SC_ZERO_TIME; 71 | 72 | // Obliged to implement read and write commands 73 | if ( cmd == tlm::TLM_READ_COMMAND ) 74 | memcpy(ptr, &mem[adr], len); 75 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 76 | memcpy(&mem[adr], ptr, len); 77 | 78 | // Set DMI hint to indicated that DMI is supported 79 | trans.set_dmi_allowed(true); 80 | 81 | // Obliged to set response status to indicate successful completion 82 | trans.set_response_status( tlm::TLM_OK_RESPONSE ); 83 | } 84 | 85 | // TLM-2 forward DMI method 86 | virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, 87 | tlm::tlm_dmi& dmi_data) 88 | { 89 | // Permit read and write access 90 | dmi_data.allow_read_write(); 91 | 92 | // Set other details of DMI region 93 | dmi_data.set_dmi_ptr( reinterpret_cast( &mem[0] ) ); 94 | dmi_data.set_start_address( 0 ); 95 | dmi_data.set_end_address( SIZE*4-1 ); 96 | dmi_data.set_read_latency( LATENCY ); 97 | dmi_data.set_write_latency( LATENCY ); 98 | 99 | return true; 100 | } 101 | 102 | // TLM-2 debug transaction method 103 | virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) 104 | { 105 | tlm::tlm_command cmd = trans.get_command(); 106 | sc_dt::uint64 adr = trans.get_address() / 4; 107 | unsigned char* ptr = trans.get_data_ptr(); 108 | unsigned int len = trans.get_data_length(); 109 | 110 | // Calculate the number of bytes to be actually copied 111 | unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4; 112 | 113 | if ( cmd == tlm::TLM_READ_COMMAND ) 114 | memcpy(ptr, &mem[adr], num_bytes); 115 | else if ( cmd == tlm::TLM_WRITE_COMMAND ) 116 | memcpy(&mem[adr], ptr, num_bytes); 117 | 118 | return num_bytes; 119 | } 120 | 121 | int mem[SIZE]; 122 | static unsigned int mem_nr; 123 | }; 124 | 125 | unsigned int Memory::mem_nr = 0; 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/testbench.cpp: -------------------------------------------------------------------------------- 1 | #//---------------------------------------------------------------------- 2 | // Copyright (c) 2007-2008 by Doulos Ltd. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | //---------------------------------------------------------------------- 16 | 17 | // Version 2 - fix warnings that only showed up using g++ 18 | // Version 3 18-June-2008 - updated for TLM-2.0 19 | // Version 4 12-Jan-2009 - fix bug in transport_dbg 20 | // Version 5 26-Sep-2009 - fix bug with set_end_address 21 | 22 | 23 | // Getting Started with TLM-2.0, Tutorial Example 3 24 | 25 | // For a full description, see http://www.doulos.com/knowhow/systemc/tlm2 26 | 27 | // Shows a router modeled as an interconnect component between the initiator and the target 28 | // The router decodes the address to select a target, and masks the address in the transaction 29 | // Shows the router passing transport, DMI and debug transactions along forward and backward paths 30 | // and doing address translation in both directions 31 | 32 | 33 | // Define the following macro to invoke an error response from the target 34 | // #define INJECT_ERROR 35 | 36 | #include "top.h" 37 | 38 | int sc_main(int argc, char* argv[]) 39 | { 40 | Top top("top"); 41 | sc_start(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Doulos_Tutorial3/top.h: -------------------------------------------------------------------------------- 1 | #ifndef TOP_H 2 | #define TOP_H 3 | 4 | #include "initiator.h" 5 | #include "target.h" 6 | #include "router.h" 7 | 8 | SC_MODULE(Top) 9 | { 10 | Initiator* initiator; 11 | Router<4>* router; 12 | Memory* memory[4]; 13 | 14 | SC_CTOR(Top) 15 | { 16 | // Instantiate components 17 | initiator = new Initiator("initiator"); 18 | router = new Router<4>("router"); 19 | for (int i = 0; i < 4; i++) 20 | { 21 | char txt[20]; 22 | sprintf(txt, "memory_%d", i); 23 | memory[i] = new Memory(txt); 24 | } 25 | 26 | // Bind sockets 27 | initiator->socket.bind( router->target_socket ); 28 | for (int i = 0; i < 4; i++) 29 | router->initiator_socket[i]->bind( memory[i]->socket ); 30 | } 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SystemC Training 2 | 3 | This project is used for me to learn SystemC TLM. 4 | 5 | ## Adder 6 | 7 | This is a simpe project from National Chiao-Tung University. 8 | 9 | ## [SimpleBus](./SimpleBus) 10 | 11 | This is a simple SystemC tutorial by Synopsys. 12 | 13 | In this project, it: 14 | + Shows the usage of ports, channels; 15 | + Block and non block require/response; 16 | 17 | ## [Doulos_Sockets: Sockets, Generic Payload, Blocking Transport](./Doulos_Sockets) 18 | 19 | This is the [first TLM tutorial](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/) by Doulos. 20 | 21 | In this project, it: 22 | + Shows the generic payload, sockets, and blocking transport interface. 23 | + Shows the responsibilities of initiator and target with respect to the generic payload. 24 | + Has only dummy implementations of the direct memory and debug transaction interfaces. 25 | + Does not show the non-blocking transport interface. 26 | 27 | ## [Doulos_Tutorial2: Response Status, DMI, and Debug Transport](./Doulos_Tutorial2) 28 | 29 | This is the [second TLM tutorial](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__2/) by Doulos. 30 | 31 | In this project, it: 32 | + Shows the direct memory interfaces and the DMI hint. 33 | + Shows the debug transaction interface 34 | + Shows the proper use of response status 35 | 36 | ## [Doulos_Tutorial3: Routing Methods through Interconnect Components ](./Doulos_Tutorial3) 37 | 38 | This is the [third TLM tutorial](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/) by Doulos. 39 | 40 | In this project, it: 41 | + Shows a router modeled as an interconnect component 42 | between the initiator and the target 43 | + The router decodes the address to select a target, 44 | and masks the address in the transaction 45 | + Shows the router passing transport, 46 | DMI and debug transactions along forward and backward paths 47 | and doing address translation in both directions 48 | 49 | The hierarchy is shown bellow: 50 | 51 | ![the module hierarchy](https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/ex_3.gif) 52 | 53 | ## [Doulos_Example5: Temporal Decoupling, Multiple Initiators and Targets](./Doulos_Example5) 54 | 55 | This is the [fifth TLM example](https://www.doulos.com/knowhow/systemc/tlm2/example_5/index.php) by Doulos. 56 | 57 | In this project, it: 58 | + Shows two loosely-timed initiators both with temporal decoupling and quantum keeper 59 | + Shows a bus with multiple initiators and multiple targets (four memories) 60 | + Routes transactions to target and back using address decoding built into the bus 61 | + Uses tagged interfaces and sockets to implement multiple fw/bw interfaces in a single module 62 | + Propagates DMI calls on both forward and backward paths, 63 | with 'invalidate' being broadcast to every initiator 64 | + Shows transaction pooling using a memory manager -------------------------------------------------------------------------------- /SimpleBus/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | # more contributor license agreements. See the NOTICE file distributed 5 | # with this work for additional information regarding copyright ownership. 6 | # Accellera licenses this file to you under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with the 8 | # License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. See the License for the specific language governing 16 | # permissions and limitations under the License. 17 | # 18 | ############################################################################### 19 | 20 | ############################################################################### 21 | # 22 | # examples/sysc/simple_bus/CMakeLists.txt -- 23 | # CMake script to configure the SystemC sources and to generate native 24 | # Makefiles and project workspaces for your compiler environment. 25 | # 26 | # Original Author: Torsten Maehne, Université Pierre et Marie Curie, Paris, 27 | # 2013-06-11 28 | # 29 | ############################################################################### 30 | 31 | ############################################################################### 32 | # 33 | # MODIFICATION LOG - modifiers, enter your name, affiliation, date and 34 | # changes you are making here. 35 | # 36 | # Name, Affiliation, Date: 37 | # Description of Modification: 38 | # 39 | ############################################################################### 40 | cmake_minimum_required(VERSION 3.16) 41 | project(simple_bus) 42 | 43 | # change your SystemC installation directory 44 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 45 | # if under linux OS 46 | set(CMAKE_PREFIX_PATH /home/singularity/systemc-2.3.3-install) 47 | message(STATUS "Current development environment is Linux,") 48 | else(CMAKE_SYSTEM_NAME STREQUAL "Linux") 49 | message(STATUS "Current development environment is Windows,") 50 | set(CMAKE_PREFIX_PATH E:/systemc-2.3.3/SystemC) 51 | endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 52 | message(STATUS "The SystemC installation directory is ${CMAKE_PREFIX_PATH}") 53 | 54 | include_directories(${CMAKE_PREFIX_PATH}/include) 55 | find_package(SystemCLanguage CONFIG REQUIRED) 56 | link_directories(${CMAKE_PREFIX_PATH}/lib) 57 | 58 | add_executable (simple_bus simple_bus_main.cpp 59 | simple_bus_test.h 60 | simple_bus_master_blocking.h 61 | simple_bus_master_blocking.cpp 62 | simple_bus_master_non_blocking.h 63 | simple_bus_master_non_blocking.cpp 64 | simple_bus_master_direct.h 65 | simple_bus_master_direct.cpp 66 | simple_bus_slow_mem.h 67 | simple_bus_types.h 68 | simple_bus_blocking_if.h 69 | simple_bus_direct_if.h 70 | simple_bus_non_blocking_if.h 71 | simple_bus_request.h 72 | simple_bus_slave_if.h 73 | simple_bus.h 74 | simple_bus.cpp 75 | simple_bus_fast_mem.h 76 | simple_bus_arbiter.h 77 | simple_bus_arbiter_if.h 78 | simple_bus_arbiter.cpp 79 | simple_bus_types.cpp 80 | simple_bus_tools.cpp) 81 | target_link_libraries (simple_bus SystemC::systemc) 82 | #configure_and_add_test (simple_bus) 83 | -------------------------------------------------------------------------------- /SimpleBus/ChangeLog: -------------------------------------------------------------------------------- 1 | 2001-10-19 Ric Hilderink 2 | 3 | * Simple bus version 2 released. 4 | 5 | This version is a drastic simplification of the first version, 6 | focussing on the most elementary features and capabilities of a 7 | bus modeled at the Transaction-Level with SystemC 2.0. 8 | 9 | 2001-11-09 Martin Janssen 10 | 11 | * Simple bus version 2.1 released. 12 | 13 | This version supports the Windows NT platform, in addition to 14 | the UNIX platforms already supported in the previous release. 15 | 16 | 2001-11-27 Martin Janssen 17 | 18 | * Simple bus version 2.2 released. 19 | 20 | This version includes improvements in the README file and in 21 | the verbose output of the bus arbiter model. 22 | 23 | 2002-01-28 Holger Keding 24 | 25 | * Simple bus version 2.3 released. 26 | 27 | This version uses byte addressing throughout all models. 28 | Also, before simulation starts this version is performing a 29 | one-time check for overlapping address spaces of the slaves 30 | attached to the bus. 31 | -------------------------------------------------------------------------------- /SimpleBus/LEGAL: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 23 | 24 | *****************************************************************************/ 25 | -------------------------------------------------------------------------------- /SimpleBus/Makefile: -------------------------------------------------------------------------------- 1 | include ../../build-unix/Makefile.config 2 | 3 | PROJECT := simple_bus 4 | SRCS := $(wildcard *.cpp) 5 | OBJS := $(SRCS:.cpp=.o) 6 | 7 | include ../../build-unix/Makefile.rules 8 | -------------------------------------------------------------------------------- /SimpleBus/golden.log: -------------------------------------------------------------------------------- 1 | 0 s top.master_d : mem[78:87] = (0, 0, 0, 0) 2 | 100 ns top.master_d : mem[78:87] = (b, c, d, e) 3 | 200 ns top.master_d : mem[78:87] = (b, c, d, e) 4 | 300 ns top.master_d : mem[78:87] = (b, c, d, e) 5 | 400 ns top.master_d : mem[78:87] = (1b, 1d, d, e) 6 | 500 ns top.master_d : mem[78:87] = (26, 18, 1a, 2f) 7 | 600 ns top.master_d : mem[78:87] = (26, 18, 1a, 2f) 8 | 700 ns top.master_d : mem[78:87] = (26, 18, 1a, 2f) 9 | 800 ns top.master_d : mem[78:87] = (31, 24, 27, 3d) 10 | 900 ns top.master_d : mem[78:87] = (31, 24, 27, 3d) 11 | 1 us top.master_d : mem[78:87] = (31, 24, 27, 3d) 12 | 1100 ns top.master_d : mem[78:87] = (31, 24, 27, 3d) 13 | 1200 ns top.master_d : mem[78:87] = (3c, 41, 46, 5e) 14 | 1300 ns top.master_d : mem[78:87] = (3c, 41, 46, 5e) 15 | 1400 ns top.master_d : mem[78:87] = (3c, 41, 46, 5e) 16 | 1500 ns top.master_d : mem[78:87] = (47, 4d, 53, 6c) 17 | 1600 ns top.master_d : mem[78:87] = (47, 4d, 53, 6c) 18 | 1700 ns top.master_d : mem[78:87] = (47, 4d, 53, 6c) 19 | 1800 ns top.master_d : mem[78:87] = (47, 4d, 53, 6c) 20 | 1900 ns top.master_d : mem[78:87] = (62, 6a, 60, 7a) 21 | 2 us top.master_d : mem[78:87] = (62, 6a, 72, 8d) 22 | 2100 ns top.master_d : mem[78:87] = (62, 6a, 72, 8d) 23 | 2200 ns top.master_d : mem[78:87] = (62, 6a, 72, 8d) 24 | 2300 ns top.master_d : mem[78:87] = (6d, 76, 7f, 9b) 25 | 2400 ns top.master_d : mem[78:87] = (6d, 76, 7f, 9b) 26 | 2500 ns top.master_d : mem[78:87] = (6d, 76, 7f, 9b) 27 | 2600 ns top.master_d : mem[78:87] = (78, 82, 8c, a9) 28 | 2700 ns top.master_d : mem[78:87] = (88, 93, 9e, bc) 29 | 2800 ns top.master_d : mem[78:87] = (88, 93, 9e, bc) 30 | 2900 ns top.master_d : mem[78:87] = (88, 93, 9e, bc) 31 | 3 us top.master_d : mem[78:87] = (93, 9f, ab, ca) 32 | 3100 ns top.master_d : mem[78:87] = (93, 9f, ab, ca) 33 | 3200 ns top.master_d : mem[78:87] = (93, 9f, ab, ca) 34 | 3300 ns top.master_d : mem[78:87] = (9e, ab, b8, d8) 35 | 3400 ns top.master_d : mem[78:87] = (ae, ab, b8, d8) 36 | 3500 ns top.master_d : mem[78:87] = (ae, bc, ca, eb) 37 | 3600 ns top.master_d : mem[78:87] = (ae, bc, ca, eb) 38 | 3700 ns top.master_d : mem[78:87] = (b9, c8, d7, f9) 39 | 3800 ns top.master_d : mem[78:87] = (b9, c8, d7, f9) 40 | 3900 ns top.master_d : mem[78:87] = (b9, c8, d7, f9) 41 | 4 us top.master_d : mem[78:87] = (c4, d4, d7, f9) 42 | 4100 ns top.master_d : mem[78:87] = (c4, d4, e4, 107) 43 | 4200 ns top.master_d : mem[78:87] = (d4, e5, f6, 107) 44 | 4300 ns top.master_d : mem[78:87] = (d4, e5, f6, 11a) 45 | 4400 ns top.master_d : mem[78:87] = (df, f1, 103, 128) 46 | 4500 ns top.master_d : mem[78:87] = (df, f1, 103, 128) 47 | 4600 ns top.master_d : mem[78:87] = (df, f1, 103, 128) 48 | 4700 ns top.master_d : mem[78:87] = (df, f1, 103, 128) 49 | 4800 ns top.master_d : mem[78:87] = (ea, fd, 110, 136) 50 | 4900 ns top.master_d : mem[78:87] = (fa, fd, 110, 136) 51 | 5 us top.master_d : mem[78:87] = (fa, 10e, 122, 149) 52 | 5100 ns top.master_d : mem[78:87] = (105, 11a, 12f, 157) 53 | 5200 ns top.master_d : mem[78:87] = (105, 11a, 12f, 157) 54 | 5300 ns top.master_d : mem[78:87] = (105, 11a, 12f, 157) 55 | 5400 ns top.master_d : mem[78:87] = (105, 11a, 12f, 157) 56 | 5500 ns top.master_d : mem[78:87] = (110, 126, 13c, 165) 57 | 5600 ns top.master_d : mem[78:87] = (110, 126, 13c, 165) 58 | 5700 ns top.master_d : mem[78:87] = (120, 137, 14e, 165) 59 | 5800 ns top.master_d : mem[78:87] = (12b, 143, 14e, 178) 60 | 5900 ns top.master_d : mem[78:87] = (12b, 143, 15b, 186) 61 | 6 us top.master_d : mem[78:87] = (12b, 143, 15b, 186) 62 | 6100 ns top.master_d : mem[78:87] = (12b, 143, 15b, 186) 63 | 6200 ns top.master_d : mem[78:87] = (136, 14f, 168, 194) 64 | 6300 ns top.master_d : mem[78:87] = (136, 14f, 168, 194) 65 | 6400 ns top.master_d : mem[78:87] = (136, 14f, 168, 194) 66 | 6500 ns top.master_d : mem[78:87] = (146, 160, 17a, 1a7) 67 | 6600 ns top.master_d : mem[78:87] = (151, 16c, 187, 1b5) 68 | 6700 ns top.master_d : mem[78:87] = (151, 16c, 187, 1b5) 69 | 6800 ns top.master_d : mem[78:87] = (151, 16c, 187, 1b5) 70 | 6900 ns top.master_d : mem[78:87] = (15c, 178, 194, 1c3) 71 | 7 us top.master_d : mem[78:87] = (15c, 178, 194, 1c3) 72 | 7100 ns top.master_d : mem[78:87] = (15c, 178, 194, 1c3) 73 | 7200 ns top.master_d : mem[78:87] = (16c, 189, 194, 1c3) 74 | 7300 ns top.master_d : mem[78:87] = (177, 195, 1a1, 1e4) 75 | 7400 ns top.master_d : mem[78:87] = (177, 195, 1a1, 1e4) 76 | 7500 ns top.master_d : mem[78:87] = (177, 195, 1a1, 1e4) 77 | 7600 ns top.master_d : mem[78:87] = (182, 1a1, 1ae, 1f2) 78 | 7700 ns top.master_d : mem[78:87] = (182, 1a1, 1ae, 1f2) 79 | 7800 ns top.master_d : mem[78:87] = (182, 1a1, 1ae, 1f2) 80 | 7900 ns top.master_d : mem[78:87] = (182, 1a1, 1ae, 1f2) 81 | 8 us top.master_d : mem[78:87] = (18d, 1ad, 1cd, 213) 82 | 8100 ns top.master_d : mem[78:87] = (18d, 1ad, 1cd, 213) 83 | 8200 ns top.master_d : mem[78:87] = (18d, 1ad, 1cd, 213) 84 | 8300 ns top.master_d : mem[78:87] = (18d, 1ad, 1cd, 213) 85 | 8400 ns top.master_d : mem[78:87] = (198, 1b9, 1da, 221) 86 | 8500 ns top.master_d : mem[78:87] = (198, 1b9, 1da, 221) 87 | 8600 ns top.master_d : mem[78:87] = (198, 1b9, 1da, 221) 88 | 8700 ns top.master_d : mem[78:87] = (1b3, 1c5, 1e7, 22f) 89 | 8800 ns top.master_d : mem[78:87] = (1b3, 1d6, 1f9, 242) 90 | 8900 ns top.master_d : mem[78:87] = (1b3, 1d6, 1f9, 242) 91 | 9 us top.master_d : mem[78:87] = (1b3, 1d6, 1f9, 242) 92 | 9100 ns top.master_d : mem[78:87] = (1be, 1e2, 206, 250) 93 | 9200 ns top.master_d : mem[78:87] = (1be, 1e2, 206, 250) 94 | 9300 ns top.master_d : mem[78:87] = (1be, 1e2, 206, 250) 95 | 9400 ns top.master_d : mem[78:87] = (1c9, 1ee, 213, 25e) 96 | 9500 ns top.master_d : mem[78:87] = (1d9, 1ff, 225, 25e) 97 | 9600 ns top.master_d : mem[78:87] = (1d9, 1ff, 225, 271) 98 | 9700 ns top.master_d : mem[78:87] = (1d9, 1ff, 225, 271) 99 | 9800 ns top.master_d : mem[78:87] = (1e4, 20b, 232, 27f) 100 | 9900 ns top.master_d : mem[78:87] = (1e4, 20b, 232, 27f) 101 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus.cpp : The bus. 23 | 24 | The main_action process is active at falling clock edge. 25 | 26 | Handling of the requests. A request can result in 27 | different requests to slaves. These are atomic requests 28 | and cannot be interrupted. A slave can take several 29 | cycles to complete: each time the request has to be 30 | re-issued to the slave. Once the slave transaction 31 | is completed, the m_current_request is cleared, and 32 | the request form is updated (address+=4, data++). 33 | 34 | When m_current_request is clear, the next request is 35 | selected. This can be the same one, if the transfer is 36 | not completed (burst-mode), or it can be a request with 37 | a higher priority. Intrusion to a non-locked burst-mode 38 | transaction is possible. 39 | 40 | When a transaction sets a lock, then the corresponding 41 | field in the request is set to SIMPLE_BUS_LOCK_SET. If 42 | the locked transaction is granted by the arbiter for the 43 | first time, the lock is set to SIMPLE_BUS_LOCK_GRANTED. 44 | At the end of the transaction, the lock is set to 45 | SIMPLE_BUS_LOCK_SET. If now a new locked request is made, 46 | with the same priority, the status of the lock is set 47 | to SIMPLE_BUS_LOCK_GRANTED, and the arbiter will pick 48 | this transaction to be the best. If the locked trans- 49 | action was not selected by the arbiter in the first 50 | round (request with higher priority preceeded), then the 51 | lock is not set. After the completion of the transaction, 52 | the lock is set from SIMPLE_BUS_LOCK_SET (set during the 53 | bus-interface function), to SIMPLE_BUS_LOCK_NO. 54 | 55 | The bus is derived from the following interfaces, and 56 | contains the implementation of these: 57 | - blocking : burst_read/burst_write 58 | - non-blocking : read/write/get_status 59 | - direct : direct_read/direct_write 60 | 61 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 62 | 63 | *****************************************************************************/ 64 | 65 | /***************************************************************************** 66 | 67 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 68 | changes you are making here. 69 | 70 | Name, Affiliation, Date: 71 | Description of Modification: 72 | 73 | *****************************************************************************/ 74 | 75 | #include "simple_bus.h" 76 | 77 | void simple_bus::end_of_elaboration() 78 | { 79 | // perform a static check for overlapping memory areas of the slaves 80 | bool no_overlap; 81 | for (int i = 1; i < slave_port.size(); ++i) { 82 | simple_bus_slave_if *slave1 = slave_port[i]; 83 | for (int j = 0; j < i; ++j) { 84 | simple_bus_slave_if *slave2 = slave_port[j]; 85 | no_overlap = ( slave1->end_address() < slave2->start_address() ) || 86 | ( slave1->start_address() > slave2->end_address() ); 87 | if ( !no_overlap ) { 88 | sb_fprintf(stdout,"Error: overlapping address spaces of 2 slaves : \n"); 89 | sb_fprintf(stdout,"slave %i : %0X..%0X\n",i,slave1->start_address(),slave1->end_address()); 90 | sb_fprintf(stdout,"slave %i : %0X..%0X\n",j,slave2->start_address(),slave2->end_address()); 91 | exit(0); 92 | } 93 | } 94 | } 95 | } 96 | 97 | //---------------------------------------------------------------------------- 98 | //-- process 99 | //---------------------------------------------------------------------------- 100 | 101 | void simple_bus::main_action() 102 | { 103 | // m_current_request is cleared after the slave is done with a 104 | // single data transfer. Burst requests require the arbiter to 105 | // select the request again. 106 | 107 | if (!m_current_request) 108 | m_current_request = get_next_request(); 109 | else 110 | // monitor slave wait states 111 | if (m_verbose) 112 | sb_fprintf(stdout, "%s SLV [%d]\n", sc_time_stamp().to_string().c_str(), 113 | m_current_request->address); 114 | if (m_current_request) 115 | handle_request(); 116 | if (!m_current_request) 117 | clear_locks(); 118 | } 119 | 120 | //---------------------------------------------------------------------------- 121 | //-- direct BUS interface 122 | //---------------------------------------------------------------------------- 123 | 124 | bool simple_bus::direct_read(int *data, unsigned int address) 125 | { 126 | if (address%4 != 0 ) {// address not word alligned 127 | sb_fprintf(stdout, " BUS ERROR --> address %04X not word alligned\n",address); 128 | return false; 129 | } 130 | simple_bus_slave_if *slave = get_slave(address); 131 | if (!slave) return false; 132 | return slave->direct_read(data, address); 133 | } 134 | 135 | bool simple_bus::direct_write(int *data, unsigned int address) 136 | { 137 | if (address%4 != 0 ) {// address not word alligned 138 | sb_fprintf(stdout, " BUS ERROR --> address %04X not word alligned\n",address); 139 | return false; 140 | } 141 | simple_bus_slave_if *slave = get_slave(address); 142 | if (!slave) return false; 143 | return slave->direct_write(data, address); 144 | } 145 | 146 | //---------------------------------------------------------------------------- 147 | //-- non-blocking BUS interface 148 | //---------------------------------------------------------------------------- 149 | 150 | void simple_bus::read(unsigned int unique_priority 151 | , int *data 152 | , unsigned int address 153 | , bool lock) 154 | { 155 | if (m_verbose) 156 | sb_fprintf(stdout, "%s %s : read(%d) @ %x\n", 157 | sc_time_stamp().to_string().c_str(), name(), unique_priority, address); 158 | 159 | simple_bus_request *request = get_request(unique_priority); 160 | 161 | // abort when the request is still not finished 162 | sc_assert((request->status == SIMPLE_BUS_OK) || 163 | (request->status == SIMPLE_BUS_ERROR)); 164 | 165 | request->do_write = false; // we are reading 166 | request->address = address; 167 | request->end_address = address; 168 | request->data = data; 169 | 170 | if (lock) 171 | request->lock = (request->lock == SIMPLE_BUS_LOCK_SET) ? 172 | SIMPLE_BUS_LOCK_GRANTED : SIMPLE_BUS_LOCK_SET; 173 | 174 | request->status = SIMPLE_BUS_REQUEST; 175 | } 176 | 177 | void simple_bus::write(unsigned int unique_priority 178 | , int *data 179 | , unsigned int address 180 | , bool lock) 181 | { 182 | if (m_verbose) 183 | sb_fprintf(stdout, "%s %s : write(%d) @ %x\n", 184 | sc_time_stamp().to_string().c_str(), name(), unique_priority, address); 185 | 186 | simple_bus_request *request = get_request(unique_priority); 187 | 188 | // abort when the request is still not finished 189 | sc_assert((request->status == SIMPLE_BUS_OK) || 190 | (request->status == SIMPLE_BUS_ERROR)); 191 | 192 | request->do_write = true; // we are writing 193 | request->address = address; 194 | request->end_address = address; 195 | request->data = data; 196 | 197 | if (lock) 198 | request->lock = (request->lock == SIMPLE_BUS_LOCK_SET) ? 199 | SIMPLE_BUS_LOCK_GRANTED : SIMPLE_BUS_LOCK_SET; 200 | 201 | request->status = SIMPLE_BUS_REQUEST; 202 | } 203 | 204 | simple_bus_status simple_bus::get_status(unsigned int unique_priority) 205 | { 206 | return get_request(unique_priority)->status; 207 | } 208 | 209 | //---------------------------------------------------------------------------- 210 | //-- blocking BUS interface 211 | //---------------------------------------------------------------------------- 212 | 213 | simple_bus_status simple_bus::burst_read(unsigned int unique_priority 214 | , int *data 215 | , unsigned int start_address 216 | , unsigned int length 217 | , bool lock) 218 | { 219 | if (m_verbose) 220 | { 221 | sb_fprintf(stdout, "%s %s : burst_read(%d) @ %x\n", 222 | sc_time_stamp().to_string().c_str(), name(), unique_priority, 223 | start_address); 224 | } 225 | 226 | simple_bus_request *request = get_request(unique_priority); 227 | 228 | request->do_write = false; // we are reading 229 | request->address = start_address; 230 | request->end_address = start_address + (length-1)*4; 231 | request->data = data; 232 | 233 | if (lock) 234 | request->lock = (request->lock == SIMPLE_BUS_LOCK_SET) ? 235 | SIMPLE_BUS_LOCK_GRANTED : SIMPLE_BUS_LOCK_SET; 236 | 237 | request->status = SIMPLE_BUS_REQUEST; 238 | 239 | wait(request->transfer_done); 240 | wait(clock->posedge_event()); 241 | return request->status; 242 | } 243 | 244 | simple_bus_status simple_bus::burst_write(unsigned int unique_priority 245 | , int *data 246 | , unsigned int start_address 247 | , unsigned int length 248 | , bool lock) 249 | { 250 | if (m_verbose) 251 | sb_fprintf(stdout, "%s %s : burst_write(%d) @ %x\n", 252 | sc_time_stamp().to_string().c_str(), name(), unique_priority, 253 | start_address); 254 | 255 | simple_bus_request *request = get_request(unique_priority); 256 | 257 | request->do_write = true; // we are writing 258 | request->address = start_address; 259 | request->end_address = start_address + (length-1)*4; 260 | request->data = data; 261 | 262 | if (lock) 263 | request->lock = (request->lock == SIMPLE_BUS_LOCK_SET) ? 264 | SIMPLE_BUS_LOCK_GRANTED : SIMPLE_BUS_LOCK_SET; 265 | 266 | request->status = SIMPLE_BUS_REQUEST; 267 | 268 | wait(request->transfer_done); 269 | wait(clock->posedge_event()); 270 | return request->status; 271 | } 272 | 273 | //---------------------------------------------------------------------------- 274 | //-- BUS methods: 275 | // 276 | // handle_request() : performs atomic bus-to-slave request 277 | // get_request() : BUS-interface: gets the request form of given 278 | // priority 279 | // get_next_request() : returns a valid request out of the list of 280 | // pending requests 281 | // clear_locks() : downgrade the lock status of the requests once 282 | // the transfer is done 283 | //---------------------------------------------------------------------------- 284 | 285 | void simple_bus::handle_request() 286 | { 287 | if (m_verbose) 288 | sb_fprintf(stdout, "%s %s Handle Slave(%d)\n", 289 | sc_time_stamp().to_string().c_str(), name(), 290 | m_current_request->priority); 291 | 292 | m_current_request->status = SIMPLE_BUS_WAIT; 293 | simple_bus_slave_if *slave = get_slave(m_current_request->address); 294 | 295 | if ((m_current_request->address)%4 != 0 ) {// address not word aligned 296 | sb_fprintf(stdout, " BUS ERROR --> address %04X not word aligned\n",m_current_request->address); 297 | m_current_request->status = SIMPLE_BUS_ERROR; 298 | m_current_request = (simple_bus_request *)0; 299 | return; 300 | } 301 | if (!slave) { 302 | sb_fprintf(stdout, " BUS ERROR --> no slave for address %04X \n",m_current_request->address); 303 | m_current_request->status = SIMPLE_BUS_ERROR; 304 | m_current_request = (simple_bus_request *)0; 305 | return; 306 | } 307 | 308 | simple_bus_status slave_status = SIMPLE_BUS_OK; 309 | if (m_current_request->do_write) 310 | slave_status = slave->write(m_current_request->data, 311 | m_current_request->address); 312 | else 313 | slave_status = slave->read(m_current_request->data, 314 | m_current_request->address); 315 | 316 | if (m_verbose) 317 | sb_fprintf(stdout, " --> status=(%s)\n", simple_bus_status_str[slave_status]); 318 | 319 | switch(slave_status) 320 | { 321 | case SIMPLE_BUS_ERROR: 322 | m_current_request->status = SIMPLE_BUS_ERROR; 323 | m_current_request->transfer_done.notify(); 324 | m_current_request = (simple_bus_request *)0; 325 | break; 326 | case SIMPLE_BUS_OK: 327 | m_current_request->address+=4; //next word (byte addressing) 328 | m_current_request->data++; 329 | if (m_current_request->address > m_current_request->end_address) 330 | { 331 | // burst-transfer (or single transfer) completed 332 | m_current_request->status = SIMPLE_BUS_OK; 333 | m_current_request->transfer_done.notify(); 334 | m_current_request = (simple_bus_request *)0; 335 | } 336 | else 337 | { // more data to transfer, but the (atomic) slave transfer is done 338 | m_current_request = (simple_bus_request *)0; 339 | } 340 | break; 341 | case SIMPLE_BUS_WAIT: 342 | // the slave is still processing: no clearance of the current request 343 | break; 344 | default: 345 | break; 346 | } 347 | } 348 | 349 | simple_bus_slave_if *simple_bus::get_slave(unsigned int address) 350 | { 351 | for (int i = 0; i < slave_port.size(); ++i) 352 | { 353 | simple_bus_slave_if *slave = slave_port[i]; 354 | if ((slave->start_address() <= address) && 355 | (address <= slave->end_address())) 356 | return slave; 357 | } 358 | return (simple_bus_slave_if *)0; 359 | } 360 | 361 | simple_bus_request * simple_bus::get_request(unsigned int priority) 362 | { 363 | simple_bus_request *request = (simple_bus_request *)0; 364 | for (unsigned int i = 0; i < m_requests.size(); ++i) 365 | { 366 | request = m_requests[i]; 367 | if ((request) && 368 | (request->priority == priority)) 369 | return request; 370 | } 371 | request = new simple_bus_request; 372 | request->priority = priority; 373 | m_requests.push_back(request); 374 | return request; 375 | } 376 | 377 | simple_bus_request * simple_bus::get_next_request() 378 | { 379 | // the slave is done with its action, m_current_request is 380 | // empty, so go over the bag of request-forms and compose 381 | // a set of likely requests. Pass it to the arbiter for the 382 | // final selection 383 | simple_bus_request_vec Q; 384 | for (unsigned int i = 0; i < m_requests.size(); ++i) 385 | { 386 | simple_bus_request *request = m_requests[i]; 387 | if ((request->status == SIMPLE_BUS_REQUEST) || 388 | (request->status == SIMPLE_BUS_WAIT)) 389 | { 390 | if (m_verbose) 391 | sb_fprintf(stdout, "%s %s : request (%d) [%s]\n", 392 | sc_time_stamp().to_string().c_str(), name(), 393 | request->priority, simple_bus_status_str[request->status]); 394 | Q.push_back(request); 395 | } 396 | } 397 | if (Q.size() > 0) 398 | return arbiter_port->arbitrate(Q); 399 | return (simple_bus_request *)0; 400 | } 401 | 402 | void simple_bus::clear_locks() 403 | { 404 | for (unsigned int i = 0; i < m_requests.size(); ++i) 405 | if (m_requests[i]->lock == SIMPLE_BUS_LOCK_GRANTED) 406 | m_requests[i]->lock = SIMPLE_BUS_LOCK_SET; 407 | else 408 | m_requests[i]->lock = SIMPLE_BUS_LOCK_NO; 409 | } 410 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus.h : The bus. 23 | 24 | The bus is derived from the following interfaces, and 25 | contains the implementation of these: 26 | - blocking : burst_read/burst_write 27 | - non-blocking : read/write/get_status 28 | - direct : direct_read/direct_write 29 | 30 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 31 | 32 | *****************************************************************************/ 33 | 34 | /***************************************************************************** 35 | 36 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 37 | changes you are making here. 38 | 39 | Name, Affiliation, Date: 40 | Description of Modification: 41 | 42 | *****************************************************************************/ 43 | 44 | #ifndef __simple_bus_h 45 | #define __simple_bus_h 46 | 47 | #include 48 | 49 | #include "simple_bus_types.h" 50 | #include "simple_bus_request.h" 51 | #include "simple_bus_direct_if.h" 52 | #include "simple_bus_non_blocking_if.h" 53 | #include "simple_bus_blocking_if.h" 54 | #include "simple_bus_arbiter_if.h" 55 | #include "simple_bus_slave_if.h" 56 | 57 | 58 | class simple_bus 59 | // the master interface is implemented in the bus, used by the masters 60 | : public simple_bus_direct_if 61 | , public simple_bus_non_blocking_if 62 | , public simple_bus_blocking_if 63 | , public sc_module 64 | { 65 | public: 66 | // ports 67 | sc_in_clk clock; 68 | sc_port arbiter_port; 69 | sc_port slave_port; 70 | 71 | SC_HAS_PROCESS(simple_bus); 72 | 73 | // constructor 74 | simple_bus(sc_module_name name_ 75 | , bool verbose = false) 76 | : sc_module(name_) 77 | , m_verbose(verbose) 78 | , m_current_request(0) 79 | { 80 | // process declaration 81 | SC_METHOD(main_action); 82 | dont_initialize(); 83 | sensitive << clock.neg(); 84 | } 85 | 86 | // process 87 | void main_action(); 88 | 89 | // direct BUS interface 90 | bool direct_read(int *data, unsigned int address); 91 | bool direct_write(int *data, unsigned int address); 92 | 93 | // non-blocking BUS interface 94 | void read(unsigned int unique_priority 95 | , int *data 96 | , unsigned int address 97 | , bool lock = false); 98 | void write(unsigned int unique_priority 99 | , int *data 100 | , unsigned int address 101 | , bool lock = false); 102 | simple_bus_status get_status(unsigned int unique_priority); 103 | 104 | // blocking BUS interface 105 | simple_bus_status burst_read(unsigned int unique_priority 106 | , int *data 107 | , unsigned int start_address 108 | , unsigned int length = 1 109 | , bool lock = false); 110 | simple_bus_status burst_write(unsigned int unique_priority 111 | , int *data 112 | , unsigned int start_address 113 | , unsigned int length = 1 114 | , bool lock = false); 115 | 116 | private: 117 | void handle_request(); 118 | void end_of_elaboration(); 119 | simple_bus_slave_if * get_slave(unsigned int address); 120 | simple_bus_request * get_request(unsigned int priority); 121 | simple_bus_request * get_next_request(); 122 | void clear_locks(); 123 | 124 | private: 125 | bool m_verbose; 126 | simple_bus_request_vec m_requests; 127 | simple_bus_request *m_current_request; 128 | 129 | }; // end class simple_bus 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_bus", "simple_bus.vcxproj", "{CE91C43D-8F06-4821-A84A-C561D9A19558}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Debug|Win32.Build.0 = Debug|Win32 16 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Debug|x64.ActiveCfg = Debug|x64 17 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Debug|x64.Build.0 = Debug|x64 18 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Release|Win32.ActiveCfg = Release|Win32 19 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Release|Win32.Build.0 = Release|Win32 20 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Release|x64.ActiveCfg = Release|x64 21 | {CE91C43D-8F06-4821-A84A-C561D9A19558}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {CE91C43D-8F06-4821-A84A-C561D9A19558} 23 | simple_bus 24 | Win32Proj 25 | 26 | 27 | 28 | Application 29 | 30 | 31 | Application 32 | 33 | 34 | Application 35 | 36 | 37 | Application 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | <_ProjectFileVersion>10.0.30319.1 61 | $(ProjectDir)$(IntDir) 62 | $(Configuration)\ 63 | true 64 | $(ProjectDir)$(IntDir) 65 | $(Configuration)\ 66 | false 67 | $(ProjectDir)$(IntDir) 68 | $(Platform)\$(Configuration)\ 69 | true 70 | $(ProjectDir)$(IntDir) 71 | $(Platform)\$(Configuration)\ 72 | false 73 | AllRules.ruleset 74 | 75 | 76 | AllRules.ruleset 77 | 78 | 79 | AllRules.ruleset 80 | 81 | 82 | AllRules.ruleset 83 | 84 | 85 | 86 | 87 | 88 | Disabled 89 | $(SYSTEMC_HOME)\src;%(AdditionalIncludeDirectories) 90 | WIN32;_DEBUG;_CONSOLE;NOGDI;%(PreprocessorDefinitions) 91 | true 92 | EnableFastChecks 93 | MultiThreadedDebugDLL 94 | true 95 | 96 | 97 | Level3 98 | EditAndContinue 99 | 4996;%(DisableSpecificWarnings) 100 | 101 | 102 | systemc.lib;%(AdditionalDependencies) 103 | $(OutDir)$(ProjectName).exe 104 | $(SYSTEMC_HOME)\$(MSVC)\SystemC\$(IntDir);%(AdditionalLibraryDirectories) 105 | true 106 | $(OutDir)$(ProjectName).pdb 107 | Console 108 | MachineX86 109 | false 110 | 111 | 112 | 113 | 114 | $(SYSTEMC_HOME)\src;%(AdditionalIncludeDirectories) 115 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 116 | true 117 | Default 118 | false 119 | true 120 | 121 | 122 | Level3 123 | ProgramDatabase 124 | 4996;%(DisableSpecificWarnings) 125 | 126 | 127 | systemc.lib;%(AdditionalDependencies) 128 | $(OutDir)$(ProjectName).exe 129 | $(SYSTEMC_HOME)\$(MSVC)\SystemC\$(IntDir);%(AdditionalLibraryDirectories) 130 | false 131 | Console 132 | true 133 | true 134 | MachineX86 135 | 136 | 137 | 138 | 139 | X64 140 | 141 | 142 | Disabled 143 | $(SYSTEMC_HOME)\src;%(AdditionalIncludeDirectories) 144 | WIN32;_DEBUG;_CONSOLE;NOGDI;%(PreprocessorDefinitions) 145 | true 146 | EnableFastChecks 147 | MultiThreadedDebugDLL 148 | true 149 | 150 | 151 | Level3 152 | ProgramDatabase 153 | 4267;4996;%(DisableSpecificWarnings) 154 | 155 | 156 | systemc.lib;%(AdditionalDependencies) 157 | $(OutDir)$(ProjectName).exe 158 | $(SYSTEMC_HOME)\$(MSVC)\SystemC\$(IntDir);%(AdditionalLibraryDirectories) 159 | true 160 | $(IntDir)$(ProjectName).pdb 161 | Console 162 | MachineX64 163 | 164 | 165 | 166 | 167 | X64 168 | 169 | 170 | $(SYSTEMC_HOME)\src;%(AdditionalIncludeDirectories) 171 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 172 | true 173 | Default 174 | false 175 | true 176 | 177 | 178 | Level3 179 | ProgramDatabase 180 | 4267;4996;%(DisableSpecificWarnings) 181 | 182 | 183 | systemc.lib;%(AdditionalDependencies) 184 | $(OutDir)$(ProjectName).exe 185 | $(SYSTEMC_HOME)\$(MSVC)\SystemC\$(IntDir);%(AdditionalLibraryDirectories) 186 | false 187 | $(IntDir)$(ProjectName).pdb 188 | Console 189 | true 190 | true 191 | MachineX64 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_arbiter.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_arbiter.cpp : The arbitration unit. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #include "simple_bus_arbiter.h" 39 | 40 | simple_bus_request * 41 | simple_bus_arbiter::arbitrate(const simple_bus_request_vec &requests) 42 | { 43 | unsigned int i; 44 | // at least one request is here 45 | simple_bus_request *best_request = requests[0]; 46 | 47 | if (m_verbose) 48 | { // shows the list of pending requests 49 | sb_fprintf(stdout, "%s %s :", sc_time_stamp().to_string().c_str(), name()); 50 | for (i = 0; i < requests.size(); ++i) 51 | { 52 | simple_bus_request *request = requests[i]; 53 | // simple_bus_lock_status encoding 54 | const char lock_chars[] = { '-', '=', '+' }; 55 | // simple_bus_status encoding 56 | sb_fprintf(stdout, "\n R[%d](%c%s@%x)", 57 | request->priority, 58 | lock_chars[request->lock], 59 | simple_bus_status_str[request->status], 60 | request->address); 61 | } 62 | } 63 | 64 | // highest priority: status==SIMPLE_BUS_WAIT and lock is set: 65 | // locked burst-action 66 | for (i = 0; i < requests.size(); ++i) 67 | { 68 | simple_bus_request *request = requests[i]; 69 | if ((request->status == SIMPLE_BUS_WAIT) && 70 | (request->lock == SIMPLE_BUS_LOCK_SET)) 71 | { 72 | // cannot break-in a locked burst 73 | if (m_verbose) 74 | sb_fprintf(stdout, " -> R[%d] (rule 1)\n", request->priority); 75 | return request; 76 | } 77 | } 78 | 79 | // second priority: lock is set at previous call, 80 | // i.e. SIMPLE_BUS_LOCK_GRANTED 81 | for (i = 0; i < requests.size(); ++i) 82 | if (requests[i]->lock == SIMPLE_BUS_LOCK_GRANTED) 83 | { 84 | if (m_verbose) 85 | sb_fprintf(stdout, " -> R[%d] (rule 2)\n", requests[i]->priority); 86 | return requests[i]; 87 | } 88 | 89 | // third priority: priority 90 | for (i = 1; i < requests.size(); ++i) 91 | { 92 | sc_assert(requests[i]->priority != best_request->priority); 93 | if (requests[i]->priority < best_request->priority) 94 | best_request = requests[i]; 95 | } 96 | 97 | if (best_request->lock != SIMPLE_BUS_LOCK_NO) 98 | best_request->lock = SIMPLE_BUS_LOCK_GRANTED; 99 | 100 | if (m_verbose) 101 | sb_fprintf(stdout, " -> R[%d] (rule 3)\n", best_request->priority); 102 | 103 | return best_request; 104 | } 105 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_arbiter.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_arbiter.h : The arbitration unit. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_arbiter_h 39 | #define __simple_bus_arbiter_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | #include "simple_bus_request.h" 45 | #include "simple_bus_arbiter_if.h" 46 | 47 | 48 | class simple_bus_arbiter 49 | : public simple_bus_arbiter_if // the arbiter interface is implemented in the arbiter, used by the bus 50 | , public sc_module 51 | { 52 | public: 53 | // constructor 54 | simple_bus_arbiter(sc_module_name name_ 55 | , bool verbose = false) 56 | : sc_module(name_) 57 | , m_verbose(verbose) 58 | {} 59 | 60 | simple_bus_request *arbitrate(const simple_bus_request_vec &requests); 61 | 62 | private: 63 | bool m_verbose; 64 | 65 | }; // end class simple_bus_arbiter 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_arbiter_if.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_arbiter_if.h : The arbiter interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_arbiter_if_h 39 | #define __simple_bus_arbiter_if_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | 45 | 46 | class simple_bus_arbiter_if 47 | : public virtual sc_interface 48 | { 49 | public: 50 | virtual simple_bus_request * 51 | arbitrate(const simple_bus_request_vec &requests) = 0; 52 | 53 | }; // end class simple_bus_arbiter_if 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_blocking_if.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_blocking_if.h : The blocking bus interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_blocking_if_h 39 | #define __simple_bus_blocking_if_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | 45 | class simple_bus_blocking_if 46 | : public virtual sc_interface 47 | { 48 | public: 49 | // blocking BUS interface 50 | virtual simple_bus_status burst_read(unsigned int unique_priority 51 | , int *data 52 | , unsigned int start_address 53 | , unsigned int length = 1 54 | , bool lock = false) = 0; 55 | virtual simple_bus_status burst_write(unsigned int unique_priority 56 | , int *data 57 | , unsigned int start_address 58 | , unsigned int length = 1 59 | , bool lock = false) = 0; 60 | 61 | }; // end class simple_bus_blocking_if 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_direct_if.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_direct_if.h : The direct BUS/Slave interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_direct_if_h 39 | #define __simple_bus_direct_if_h 40 | 41 | #include 42 | 43 | class simple_bus_direct_if 44 | : public virtual sc_interface 45 | { 46 | public: 47 | // direct BUS/Slave interface 48 | virtual bool direct_read(int *data, unsigned int address) = 0; 49 | virtual bool direct_write(int *data, unsigned int address) = 0; 50 | 51 | }; // end class simple_bus_direct_if 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_fast_mem.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_fast_mem.h : The memory (slave) without wait states. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_fast_mem_h 39 | #define __simple_bus_fast_mem_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | #include "simple_bus_slave_if.h" 45 | 46 | 47 | class simple_bus_fast_mem 48 | : public simple_bus_slave_if // the slave interface is implemented in the slave, used by the bus 49 | , public sc_module 50 | { 51 | public: 52 | // constructor 53 | simple_bus_fast_mem(sc_module_name name_ 54 | , unsigned int start_address 55 | , unsigned int end_address) 56 | : sc_module(name_) 57 | , m_start_address(start_address) 58 | , m_end_address(end_address) 59 | { 60 | sc_assert(m_start_address <= m_end_address); 61 | sc_assert((m_end_address-m_start_address+1)%4 == 0); 62 | unsigned int size = (m_end_address-m_start_address+1)/4; 63 | MEM = new int [size]; // allocate memory 64 | for (unsigned int i = 0; i < size; ++i) 65 | MEM[i] = 0; 66 | } 67 | 68 | // destructor 69 | ~simple_bus_fast_mem(); 70 | 71 | // direct Slave Interface 72 | bool direct_read(int *data, unsigned int address); 73 | bool direct_write(int *data, unsigned int address); 74 | 75 | // Slave Interface 76 | simple_bus_status read(int *data, unsigned int address); 77 | simple_bus_status write(int *data, unsigned int address); 78 | 79 | unsigned int start_address() const; 80 | unsigned int end_address() const; 81 | 82 | private: 83 | /**the pointer of the array, i.e., the start address of the array*/ 84 | int * MEM; 85 | unsigned int m_start_address; 86 | unsigned int m_end_address; 87 | 88 | }; // end class simple_bus_fast_mem 89 | 90 | inline bool simple_bus_fast_mem::direct_read(int *data, unsigned int address) 91 | { 92 | return (read(data, address) == SIMPLE_BUS_OK); 93 | } 94 | 95 | inline bool simple_bus_fast_mem::direct_write(int *data, unsigned int address) 96 | { 97 | return (write(data, address) == SIMPLE_BUS_OK); 98 | } 99 | 100 | inline simple_bus_status simple_bus_fast_mem::read(int *data 101 | , unsigned int address) 102 | { 103 | *data = MEM[(address - m_start_address)/4]; 104 | return SIMPLE_BUS_OK; 105 | } 106 | 107 | inline simple_bus_status simple_bus_fast_mem::write(int *data 108 | , unsigned int address) 109 | { 110 | MEM[(address - m_start_address)/4] = *data; 111 | return SIMPLE_BUS_OK; 112 | } 113 | 114 | inline simple_bus_fast_mem::~simple_bus_fast_mem() 115 | { 116 | if (MEM) delete [] MEM; 117 | MEM = (int *)0; 118 | } 119 | 120 | inline unsigned int simple_bus_fast_mem::start_address() const 121 | { 122 | return m_start_address; 123 | } 124 | 125 | inline unsigned int simple_bus_fast_mem::end_address() const 126 | { 127 | return m_end_address; 128 | } 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_main.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_main.cpp : sc_main 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #include "systemc.h" 39 | #include "simple_bus_test.h" 40 | 41 | int sc_main(int, char **) 42 | { 43 | simple_bus_test top("top"); 44 | 45 | sc_start(10000, SC_NS); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_blocking.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_blocking.cpp : The master using the blocking BUS interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #include "simple_bus_master_blocking.h" 39 | 40 | [[noreturn]] void simple_bus_master_blocking::main_action() 41 | { 42 | const unsigned int mylength = 0x10; // storage capacity/burst length in words 43 | int mydata[mylength]; 44 | unsigned int i; 45 | simple_bus_status status; 46 | 47 | while (true) 48 | { 49 | wait(); // ... for the next rising clock edge 50 | status = bus_port->burst_read(m_unique_priority, mydata, 51 | m_address, mylength, m_lock); 52 | if (status == SIMPLE_BUS_ERROR) 53 | sb_fprintf(stdout, "%s %s : blocking-read failed at address %x\n", 54 | sc_time_stamp().to_string().c_str(), name(), m_address); 55 | 56 | for (i = 0; i < mylength; ++i) 57 | { 58 | mydata[i] += i; 59 | wait(); 60 | } 61 | 62 | status = bus_port->burst_write(m_unique_priority, mydata, 63 | m_address, mylength, m_lock); 64 | if (status == SIMPLE_BUS_ERROR) 65 | sb_fprintf(stdout, "%s %s : blocking-write failed at address %x\n", 66 | sc_time_stamp().to_string().c_str(), name(), m_address); 67 | 68 | wait(m_timeout, SC_NS); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_blocking.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_blocking.h : The master using the blocking BUS interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: Singularity, 2020-07-02 34 | Description of Modification: use the c++ style sc_module 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_master_blocking_h 39 | #define __simple_bus_master_blocking_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | #include "simple_bus_blocking_if.h" 45 | 46 | 47 | class simple_bus_master_blocking: public sc_module 48 | { 49 | public: 50 | // ports 51 | sc_in_clk clock; 52 | sc_port bus_port; 53 | 54 | SC_HAS_PROCESS(simple_bus_master_blocking); 55 | 56 | // constructor 57 | simple_bus_master_blocking(sc_module_name name_ 58 | , unsigned int unique_priority 59 | , unsigned int address 60 | , bool lock 61 | , int timeout) 62 | : sc_module(name_) 63 | , m_unique_priority(unique_priority) 64 | , m_address(address) 65 | , m_lock(lock) 66 | , m_timeout(timeout) 67 | { 68 | // process declaration 69 | SC_THREAD(main_action); 70 | sensitive << clock.pos(); 71 | } 72 | 73 | // process 74 | [[noreturn]] void main_action(); 75 | 76 | private: 77 | unsigned int m_unique_priority; 78 | unsigned int m_address; 79 | bool m_lock; 80 | int m_timeout; 81 | 82 | }; // end class simple_bus_master_blocking 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_direct.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_direct.cpp : The monitor (master) using the direct BUS 23 | interface. 24 | 25 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 26 | 27 | *****************************************************************************/ 28 | 29 | /***************************************************************************** 30 | 31 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32 | changes you are making here. 33 | 34 | Name, Affiliation, Date: Singularity, 2020-07-01 35 | Description of Modification: 36 | *** utilize the for loop to call the 37 | * [[[bus_port->direct_read]]] function 38 | *****************************************************************************/ 39 | 40 | #include "simple_bus_master_direct.h" 41 | #include "simple_bus_types.h" 42 | 43 | [[noreturn]] void simple_bus_master_direct::main_action() 44 | { 45 | int mydata[4]; 46 | while (true) 47 | { 48 | for (int i = 0; i < sizeof(mydata); ++i) 49 | bus_port->direct_read(&mydata[i], m_address + 4*i); 50 | 51 | if (m_verbose) 52 | sb_fprintf(stdout, "%s %s : mem[%x:%x] = (%x, %x, %x, %x)\n", 53 | sc_time_stamp().to_string().c_str(), name(), m_address, 54 | m_address+15, 55 | mydata[0], mydata[1], mydata[2], mydata[3]); 56 | 57 | wait(m_timeout, SC_NS); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_direct.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_direct.h : The monitor (master) using the direct BUS 23 | interface. 24 | 25 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 26 | 27 | *****************************************************************************/ 28 | 29 | /***************************************************************************** 30 | 31 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32 | changes you are making here. 33 | 34 | Name, Affiliation, Date: 35 | Description of Modification: 36 | 37 | *****************************************************************************/ 38 | 39 | #ifndef __simple_bus_master_direct_h 40 | #define __simple_bus_master_direct_h 41 | 42 | #include 43 | 44 | #include "simple_bus_direct_if.h" 45 | 46 | 47 | SC_MODULE(simple_bus_master_direct) 48 | { 49 | // ports 50 | sc_in_clk clock; 51 | sc_port bus_port; 52 | 53 | SC_HAS_PROCESS(simple_bus_master_direct); 54 | 55 | // constructor 56 | simple_bus_master_direct(sc_module_name name_ 57 | , unsigned int address 58 | , int timeout 59 | , bool verbose = true) 60 | : sc_module(name_) 61 | , m_address(address) 62 | , m_timeout(timeout) 63 | , m_verbose(verbose) 64 | { 65 | // process declaration 66 | SC_THREAD(main_action); 67 | } 68 | 69 | // process 70 | [[noreturn]] void main_action(); 71 | 72 | private: 73 | unsigned int m_address; 74 | int m_timeout; 75 | bool m_verbose; 76 | 77 | }; // end class simple_bus_master_direct 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_non_blocking.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_non_blocking.cpp : The master using the non-blocking BUS 23 | interface. 24 | 25 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 26 | 27 | *****************************************************************************/ 28 | 29 | /***************************************************************************** 30 | 31 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32 | changes you are making here. 33 | 34 | Name, Affiliation, Date: 35 | Description of Modification: 36 | 37 | *****************************************************************************/ 38 | 39 | #include "simple_bus_master_non_blocking.h" 40 | 41 | [[noreturn]] void simple_bus_master_non_blocking::main_action() 42 | { 43 | int mydata; 44 | int cnt = 0; 45 | unsigned int addr = m_start_address; 46 | 47 | wait(); // ... for the next rising clock edge 48 | while (true) 49 | { 50 | bus_port->read(m_unique_priority, &mydata, addr, m_lock); 51 | while ((bus_port->get_status(m_unique_priority) != SIMPLE_BUS_OK) && 52 | (bus_port->get_status(m_unique_priority) != SIMPLE_BUS_ERROR)) 53 | wait(); 54 | if (bus_port->get_status(m_unique_priority) == SIMPLE_BUS_ERROR) 55 | sb_fprintf(stdout, "%s %s : ERROR cannot read from %x\n", 56 | sc_time_stamp().to_string().c_str(), name(), addr); 57 | 58 | mydata += cnt; 59 | cnt++; 60 | 61 | bus_port->write(m_unique_priority, &mydata, addr, m_lock); 62 | while ((bus_port->get_status(m_unique_priority) != SIMPLE_BUS_OK) && 63 | (bus_port->get_status(m_unique_priority) != SIMPLE_BUS_ERROR)) 64 | wait(); 65 | if (bus_port->get_status(m_unique_priority) == SIMPLE_BUS_ERROR) 66 | sb_fprintf(stdout, "%s %s : ERROR cannot write to %x\n", 67 | sc_time_stamp().to_string().c_str(), name(), addr); 68 | 69 | wait(m_timeout, SC_NS); 70 | wait(); // ... for the next rising clock edge 71 | 72 | addr+=4; // next word (byte addressing) 73 | if (addr > (m_start_address+0x80)) { 74 | addr = m_start_address; cnt = 0; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_master_non_blocking.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_master_non_blocking.h : The master using the non-blocking BUS 23 | interface. 24 | 25 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 26 | 27 | *****************************************************************************/ 28 | 29 | /***************************************************************************** 30 | 31 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32 | changes you are making here. 33 | 34 | Name, Affiliation, Date: 35 | Description of Modification: 36 | 37 | *****************************************************************************/ 38 | 39 | #ifndef __simple_bus_master_non_blocking_h 40 | #define __simple_bus_master_non_blocking_h 41 | 42 | #include 43 | 44 | #include "simple_bus_types.h" 45 | #include "simple_bus_non_blocking_if.h" 46 | 47 | 48 | SC_MODULE(simple_bus_master_non_blocking) 49 | { 50 | // ports 51 | sc_in_clk clock; 52 | sc_port bus_port; 53 | 54 | SC_HAS_PROCESS(simple_bus_master_non_blocking); 55 | 56 | // constructor 57 | simple_bus_master_non_blocking(sc_module_name _name 58 | , unsigned int unique_priority 59 | , unsigned int start_address 60 | , bool lock 61 | , int timeout) 62 | : sc_module(_name) 63 | , m_unique_priority(unique_priority) 64 | , m_start_address(start_address) 65 | , m_lock(lock) 66 | , m_timeout(timeout) 67 | { 68 | // process declaration 69 | SC_THREAD(main_action); 70 | sensitive << clock.pos(); 71 | } 72 | 73 | // process 74 | [[noreturn]] void main_action(); 75 | 76 | private: 77 | unsigned int m_unique_priority; 78 | unsigned int m_start_address; 79 | bool m_lock; 80 | int m_timeout; 81 | 82 | }; // end class simple_bus_master_non_blocking 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_non_blocking_if.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_non_blocking_if.h : The non-blocking BUS interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_non_blocking_if_h 39 | #define __simple_bus_non_blocking_if_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | 45 | class simple_bus_non_blocking_if 46 | : public virtual sc_interface 47 | { 48 | public: 49 | // non-blocking BUS interface 50 | virtual void read(unsigned int unique_priority 51 | , int *data 52 | , unsigned int address 53 | , bool lock = false) = 0; 54 | virtual void write(unsigned int unique_priority 55 | , int *data 56 | , unsigned int address 57 | , bool lock = false) = 0; 58 | 59 | virtual simple_bus_status get_status(unsigned int unique_priority) = 0; 60 | 61 | }; // end class simple_bus_non_blocking_if 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_request.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_request.h : The bus interface request form. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_request_h 39 | #define __simple_bus_request_h 40 | 41 | enum simple_bus_lock_status { SIMPLE_BUS_LOCK_NO = 0 42 | , SIMPLE_BUS_LOCK_SET 43 | , SIMPLE_BUS_LOCK_GRANTED 44 | }; 45 | 46 | struct simple_bus_request 47 | { 48 | // parameters 49 | unsigned int priority; 50 | 51 | // request parameters 52 | bool do_write; 53 | unsigned int address; 54 | unsigned int end_address; 55 | int *data; 56 | simple_bus_lock_status lock; 57 | 58 | // request status 59 | sc_event transfer_done; 60 | simple_bus_status status; 61 | 62 | // default constructor 63 | simple_bus_request(); 64 | }; 65 | 66 | inline simple_bus_request::simple_bus_request() 67 | : priority(0) 68 | , do_write(false) 69 | , address(0) 70 | , end_address(0) 71 | , data((int *)0) 72 | , lock(SIMPLE_BUS_LOCK_NO) 73 | , status(SIMPLE_BUS_OK) 74 | {} 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_slave_if.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_slave_if.h : The Slave interface. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_slave_if_h 39 | #define __simple_bus_slave_if_h 40 | 41 | #include 42 | 43 | #include "simple_bus_types.h" 44 | #include "simple_bus_direct_if.h" 45 | 46 | 47 | class simple_bus_slave_if 48 | : public simple_bus_direct_if 49 | { 50 | public: 51 | // Slave interface 52 | virtual simple_bus_status read(int *data, unsigned int address) = 0; 53 | virtual simple_bus_status write(int *data, unsigned int address) = 0; 54 | 55 | virtual unsigned int start_address() const = 0; 56 | virtual unsigned int end_address() const = 0; 57 | 58 | }; // end class simple_bus_slave_if 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_slow_mem.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_slow_mem.h : Slave : The memory (slave) with wait states. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: Singularity, 2020-07-01 34 | Description of Modification: 35 | 36 | + Add some comments 37 | 38 | *****************************************************************************/ 39 | 40 | #ifndef __simple_bus_slow_mem_h 41 | #define __simple_bus_slow_mem_h 42 | 43 | #include 44 | 45 | #include "simple_bus_types.h" 46 | #include "simple_bus_slave_if.h" 47 | 48 | 49 | class simple_bus_slow_mem 50 | : public simple_bus_slave_if // the slave interface is implemented in the slave, used by the bus 51 | , public sc_module 52 | { 53 | public: 54 | // ports 55 | sc_in_clk clock; 56 | 57 | SC_HAS_PROCESS(simple_bus_slow_mem); 58 | 59 | // constructor 60 | simple_bus_slow_mem(sc_module_name name_ 61 | , unsigned int start_address 62 | , unsigned int end_address 63 | , unsigned int nr_wait_states) 64 | : sc_module(name_) 65 | , m_start_address(start_address) 66 | , m_end_address(end_address) 67 | , m_nr_wait_states(nr_wait_states) 68 | , m_wait_count(-1) 69 | { 70 | // process declaration 71 | SC_METHOD(wait_loop); 72 | dont_initialize(); 73 | sensitive << clock.pos(); 74 | 75 | sc_assert(m_start_address <= m_end_address); 76 | sc_assert((m_end_address-m_start_address+1)%4 == 0); 77 | unsigned int size = (m_end_address-m_start_address+1)/4; 78 | MEM = new int [size]; // allocate memory 79 | for (unsigned int i = 0; i < size; ++i) 80 | MEM[i] = 0; 81 | } 82 | 83 | // destructor 84 | ~simple_bus_slow_mem(); 85 | 86 | // process 87 | void wait_loop(); 88 | 89 | // direct Slave Interface 90 | bool direct_read(int *data, unsigned int address); 91 | bool direct_write(int *data, unsigned int address); 92 | 93 | // Slave Interface 94 | simple_bus_status read(int *data, unsigned int address); 95 | simple_bus_status write(int *data, unsigned int address); 96 | 97 | unsigned int start_address() const; 98 | unsigned int end_address() const; 99 | 100 | private: 101 | /**the pointer of the array, i.e., the start address of the array*/ 102 | int *MEM; 103 | unsigned int m_start_address; 104 | unsigned int m_end_address; 105 | unsigned int m_nr_wait_states; 106 | /**The cycles needed to wait. 107 | * -1 means can receive a new requirement; 108 | * 0 means read finishes right now; 109 | * int > 0 means the cycle number left to finish*/ 110 | int m_wait_count; 111 | 112 | }; // end class simple_bus_slow_mem 113 | 114 | inline simple_bus_slow_mem::~simple_bus_slow_mem() 115 | { 116 | if (MEM) delete [] MEM; 117 | MEM = (int *)0; 118 | } 119 | 120 | inline void simple_bus_slow_mem::wait_loop() 121 | { 122 | if (m_wait_count >= 0) m_wait_count--; 123 | } 124 | 125 | inline bool simple_bus_slow_mem::direct_read(int *data, unsigned int address) 126 | { 127 | *data = MEM[(address - m_start_address)/4]; 128 | return true; 129 | } 130 | 131 | inline bool simple_bus_slow_mem::direct_write(int *data, unsigned int address) 132 | { 133 | MEM[(address - m_start_address)/4] = *data; 134 | return true; 135 | } 136 | 137 | inline simple_bus_status simple_bus_slow_mem::read(int *data 138 | , unsigned int address) 139 | { 140 | // accept a new call if m_wait_count < 0) 141 | if (m_wait_count < 0) 142 | { 143 | m_wait_count = m_nr_wait_states; 144 | return SIMPLE_BUS_WAIT; 145 | } 146 | if (m_wait_count == 0) 147 | { 148 | *data = MEM[(address - m_start_address)/4]; 149 | return SIMPLE_BUS_OK; 150 | } 151 | return SIMPLE_BUS_WAIT; 152 | } 153 | 154 | inline simple_bus_status simple_bus_slow_mem::write(int *data 155 | , unsigned int address) 156 | { 157 | // accept a new call if m_wait_count < 0) 158 | if (m_wait_count < 0) 159 | { 160 | m_wait_count = m_nr_wait_states; 161 | return SIMPLE_BUS_WAIT; 162 | } 163 | if (m_wait_count == 0) 164 | { 165 | MEM[(address - m_start_address)/4] = *data; 166 | return SIMPLE_BUS_OK; 167 | } 168 | return SIMPLE_BUS_WAIT; 169 | } 170 | 171 | 172 | inline unsigned int simple_bus_slow_mem::start_address() const 173 | { 174 | return m_start_address; 175 | } 176 | 177 | inline unsigned int simple_bus_slow_mem::end_address() const 178 | { 179 | return m_end_address; 180 | } 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_test.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_test.h : The test bench. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_test_h 39 | #define __simple_bus_test_h 40 | 41 | #include 42 | 43 | #include "simple_bus_master_blocking.h" 44 | #include "simple_bus_master_non_blocking.h" 45 | #include "simple_bus_master_direct.h" 46 | #include "simple_bus_slow_mem.h" 47 | #include "simple_bus.h" 48 | #include "simple_bus_fast_mem.h" 49 | #include "simple_bus_arbiter.h" 50 | 51 | SC_MODULE(simple_bus_test) 52 | { 53 | // channels 54 | sc_clock C1; 55 | 56 | // module instances 57 | simple_bus_master_blocking *master_b; 58 | simple_bus_master_non_blocking *master_nb; 59 | simple_bus_master_direct *master_d; 60 | simple_bus_slow_mem *mem_slow; 61 | simple_bus *bus; 62 | simple_bus_fast_mem *mem_fast; 63 | simple_bus_arbiter *arbiter; 64 | 65 | // constructor 66 | SC_CTOR(simple_bus_test) 67 | : C1("C1") 68 | { 69 | // create instances 70 | master_b = new simple_bus_master_blocking("master_b", 4, 0x4c, false, 300); 71 | master_nb = new simple_bus_master_non_blocking("master_nb", 3, 0x38, false, 20); 72 | master_d = new simple_bus_master_direct("master_d", 0x78, 100); 73 | mem_fast = new simple_bus_fast_mem("mem_fast", 0x00, 0x7f); 74 | mem_slow = new simple_bus_slow_mem("mem_slow", 0x80, 0xff, 1); 75 | // bus = new simple_bus("bus",true); // verbose output 76 | bus = new simple_bus("bus"); 77 | // arbiter = new simple_bus_arbiter("arbiter",true); // verbose output 78 | arbiter = new simple_bus_arbiter("arbiter"); 79 | 80 | // connect instances 81 | master_d->clock(C1); 82 | bus->clock(C1); 83 | master_b->clock(C1); 84 | master_nb->clock(C1); 85 | mem_slow->clock(C1); 86 | master_d->bus_port(*bus); 87 | master_b->bus_port(*bus); 88 | master_nb->bus_port(*bus); 89 | bus->arbiter_port(*arbiter); 90 | bus->slave_port(*mem_slow); 91 | bus->slave_port(*mem_fast); 92 | } 93 | 94 | // destructor 95 | ~simple_bus_test() 96 | { 97 | if (master_b) {delete master_b; master_b = 0;} 98 | if (master_nb) {delete master_nb; master_nb = 0;} 99 | if (master_d) {delete master_d; master_d = 0;} 100 | if (mem_slow) {delete mem_slow; mem_slow = 0;} 101 | if (bus) {delete bus; bus = 0;} 102 | if (mem_fast) {delete mem_fast; mem_fast = 0;} 103 | if (arbiter) {delete arbiter; arbiter = 0;} 104 | } 105 | 106 | }; // end class simple_bus_test 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_tools.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_tools.cpp : The signal-safe fprintf function (sb_fprintf). 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | int sb_fprintf(FILE *fp, const char *fmt, ...) 43 | { 44 | va_list ap; 45 | va_start(ap, fmt); 46 | int ret = 0; 47 | do { 48 | errno = 0; 49 | ret = vfprintf(fp, fmt, ap); 50 | } while (errno == EINTR); 51 | return ret; 52 | } 53 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_types.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_types.h : The common types. 23 | 24 | Original Author: Holger Keding, Synopsys, Inc., 2002-01-28 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | // only needed for more readable debug output 39 | char simple_bus_status_str[4][20] = {"SIMPLE_BUS_OK" 40 | , "SIMPLE_BUS_REQUEST" 41 | , "SIMPLE_BUS_WAIT" 42 | , "SIMPLE_BUS_ERROR"}; 43 | -------------------------------------------------------------------------------- /SimpleBus/simple_bus_types.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | 3 | Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | more contributor license agreements. See the NOTICE file distributed 5 | with this work for additional information regarding copyright ownership. 6 | Accellera licenses this file to you under the Apache License, Version 2.0 7 | (the "License"); you may not use this file except in compliance with the 8 | License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | implied. See the License for the specific language governing 16 | permissions and limitations under the License. 17 | 18 | *****************************************************************************/ 19 | 20 | /***************************************************************************** 21 | 22 | simple_bus_types.h : The common types. 23 | 24 | Original Author: Ric Hilderink, Synopsys, Inc., 2001-10-11 25 | 26 | *****************************************************************************/ 27 | 28 | /***************************************************************************** 29 | 30 | MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 | changes you are making here. 32 | 33 | Name, Affiliation, Date: 34 | Description of Modification: 35 | 36 | *****************************************************************************/ 37 | 38 | #ifndef __simple_bus_types_h 39 | #define __simple_bus_types_h 40 | 41 | #include 42 | #include 43 | 44 | enum simple_bus_status { SIMPLE_BUS_OK = 0 45 | , SIMPLE_BUS_REQUEST 46 | , SIMPLE_BUS_WAIT 47 | , SIMPLE_BUS_ERROR }; 48 | 49 | // needed for more readable debug output 50 | extern char simple_bus_status_str[4][20]; 51 | 52 | struct simple_bus_request; 53 | typedef std::vector simple_bus_request_vec; 54 | 55 | extern int sb_fprintf(FILE *, const char *, ...); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /SimpleBus/test.am: -------------------------------------------------------------------------------- 1 | ## **************************************************************************** 2 | ## 3 | ## Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 | ## more contributor license agreements. See the NOTICE file distributed 5 | ## with this work for additional information regarding copyright ownership. 6 | ## Accellera licenses this file to you under the Apache License, Version 2.0 7 | ## (the "License"); you may not use this file except in compliance with the 8 | ## License. You may obtain a copy of the License at 9 | ## 10 | ## http://www.apache.org/licenses/LICENSE-2.0 11 | ## 12 | ## Unless required by applicable law or agreed to in writing, software 13 | ## distributed under the License is distributed on an "AS IS" BASIS, 14 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | ## implied. See the License for the specific language governing 16 | ## permissions and limitations under the License. 17 | ## 18 | ## **************************************************************************** 19 | ## 20 | ## test.am -- 21 | ## Included from a Makefile.am to provide example-specific information 22 | ## 23 | ## Original Author: Philipp A. Hartmann, OFFIS, 2013-05-20 24 | ## 25 | ## **************************************************************************** 26 | ## 27 | ## MODIFICATION LOG - modifiers, enter your name, affiliation, date and 28 | ## changes you are making here. 29 | ## 30 | ## Name, Affiliation, Date: 31 | ## Description of Modification: 32 | ## 33 | ## *************************************************************************** 34 | 35 | ## Generic example setup 36 | ## (should be kept in sync among all test.am files) 37 | ## 38 | ## Note: Recent Automake versions (>1.13) support relative placeholders for 39 | ## included files (%D%,%C%). To support older versions, use explicit 40 | ## names for now. 41 | ## 42 | ## Local values: 43 | ## %D%: simple_bus 44 | ## %C%: simple_bus 45 | 46 | examples_TESTS += simple_bus/test 47 | 48 | simple_bus_test_CPPFLAGS = \ 49 | $(AM_CPPFLAGS) 50 | 51 | simple_bus_test_SOURCES = \ 52 | $(simple_bus_H_FILES) \ 53 | $(simple_bus_CXX_FILES) 54 | 55 | examples_BUILD += \ 56 | $(simple_bus_BUILD) 57 | 58 | examples_CLEAN += \ 59 | simple_bus/run.log \ 60 | simple_bus/expected_trimmed.log \ 61 | simple_bus/run_trimmed.log \ 62 | simple_bus/diff.log 63 | 64 | examples_FILES += \ 65 | $(simple_bus_H_FILES) \ 66 | $(simple_bus_CXX_FILES) \ 67 | $(simple_bus_BUILD) \ 68 | $(simple_bus_EXTRA) 69 | 70 | examples_DIRS += simple_bus 71 | 72 | ## example-specific details 73 | 74 | simple_bus_H_FILES = \ 75 | simple_bus/simple_bus.h \ 76 | simple_bus/simple_bus_arbiter.h \ 77 | simple_bus/simple_bus_arbiter_if.h \ 78 | simple_bus/simple_bus_blocking_if.h \ 79 | simple_bus/simple_bus_direct_if.h \ 80 | simple_bus/simple_bus_fast_mem.h \ 81 | simple_bus/simple_bus_master_blocking.h \ 82 | simple_bus/simple_bus_master_direct.h \ 83 | simple_bus/simple_bus_master_non_blocking.h \ 84 | simple_bus/simple_bus_non_blocking_if.h \ 85 | simple_bus/simple_bus_request.h \ 86 | simple_bus/simple_bus_slave_if.h \ 87 | simple_bus/simple_bus_slow_mem.h \ 88 | simple_bus/simple_bus_test.h \ 89 | simple_bus/simple_bus_types.h 90 | 91 | simple_bus_CXX_FILES = \ 92 | simple_bus/simple_bus.cpp \ 93 | simple_bus/simple_bus_arbiter.cpp \ 94 | simple_bus/simple_bus_main.cpp \ 95 | simple_bus/simple_bus_master_blocking.cpp \ 96 | simple_bus/simple_bus_master_direct.cpp \ 97 | simple_bus/simple_bus_master_non_blocking.cpp \ 98 | simple_bus/simple_bus_types.cpp \ 99 | simple_bus/simple_bus_tools.cpp 100 | 101 | simple_bus_BUILD = \ 102 | simple_bus/golden.log 103 | 104 | simple_bus_EXTRA = \ 105 | simple_bus/simple_bus.sln \ 106 | simple_bus/simple_bus.vcxproj \ 107 | simple_bus/CMakeLists.txt \ 108 | simple_bus/Makefile \ 109 | simple_bus/ChangeLog \ 110 | simple_bus/README \ 111 | simple_bus/SLIDES.pdf \ 112 | simple_bus/LEGAL 113 | 114 | #simple_bus_FILTER = 115 | 116 | ## Taf! 117 | ## :vim:ft=automake: 118 | --------------------------------------------------------------------------------