#include #include #include #include #include #include #include #include #include #include #include using namespace sc_core; using namespace scc; class testbench: public sc_module, public scc::traceable { public: enum { WIDTH=64}; tlm::scc::initiator_mixin> isck{"isck"}; ahb::pin::initiator intor{"intor"}; sc_core::sc_clock HCLK{"HCLK", 10_ns}; sc_core::sc_signal HRESETn{"HRESETn"}; sc_core::sc_signal> HADDR{"HADDR"}; sc_core::sc_signal> HBURST{"HBURST"}; sc_core::sc_signal HMASTLOCK{"HMASTLOCK"}; sc_core::sc_signal> HPROT{"HPROT"}; sc_core::sc_signal> HSIZE{"HSIZE"}; sc_core::sc_signal> HTRANS{"HTRANS"}; sc_core::sc_signal> HWDATA{"HWDATA"}; sc_core::sc_signal HWRITE{"HWRITE"}; sc_core::sc_signal> HRDATA{"HRDATA"}; sc_core::sc_signal HREADY{"HREADY"}; sc_core::sc_signal HRESP{"HRESP"}; sc_core::sc_signal HSEL{"HSEL"}; ahb::pin::target target{"target"}; tlm::scc::target_mixin> tsck{"tsck"}; testbench(sc_module_name nm):sc_module(nm){ SC_HAS_PROCESS(testbench); isck(intor.tsckt); intor.HCLK_i(HCLK); intor.HRESETn_i(HRESETn); intor.HADDR_o(HADDR); intor.HBURST_o(HBURST); intor.HMASTLOCK_o(HMASTLOCK); intor.HPROT_o(HPROT); intor.HSIZE_o(HSIZE); intor.HTRANS_o(HTRANS); intor.HWDATA_o(HWDATA); intor.HWRITE_o(HWRITE); intor.HRDATA_i(HRDATA); intor.HREADY_i(HREADY); intor.HRESP_i(HRESP); target.HCLK_i(HCLK); target.HRESETn_i(HRESETn); target.HADDR_i(HADDR); target.HBURST_i(HBURST); target.HMASTLOCK_i(HMASTLOCK); target.HPROT_i(HPROT); target.HSIZE_i(HSIZE); target.HTRANS_i(HTRANS); target.HWDATA_i(HWDATA); target.HWRITE_i(HWRITE); target.HSEL_i(HSEL); target.HRDATA_o(HRDATA); target.HREADY_o(HREADY); target.HRESP_o(HRESP); target.isckt(tsck); SC_THREAD(run); tsck.register_b_transport([this](tlm::tlm_generic_payload& gp, sc_time& delay){ gp.set_response_status(tlm::TLM_OK_RESPONSE); if(gp.is_write()){ SCCINFO(SCMOD)<<"Received write access to addr 0x"< data; data[0]=2; data[1]=4; gp.set_address(0x1000); gp.set_data_length(8); gp.set_data_ptr(data.data()); gp.set_streaming_width(8); gp.set_command(tlm::TLM_WRITE_COMMAND); sc_time delay; isck->b_transport(gp, delay); gp.set_address(0x1020); gp.set_data_length(8); gp.set_data_ptr(data.data()); gp.set_streaming_width(8); gp.set_command(tlm::TLM_READ_COMMAND); delay=SC_ZERO_TIME; isck->b_transport(gp, delay); for(size_t i=0; i<10; ++i) wait(HCLK.posedge_event()); sc_stop(); } }; int sc_main (int argc , char *argv[]){ sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING ); sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); /////////////////////////////////////////////////////////////////////////// // configure logging /////////////////////////////////////////////////////////////////////////// scc::init_logging(scc::log::DEBUG); /////////////////////////////////////////////////////////////////////////// // set up configuration and tracing /////////////////////////////////////////////////////////////////////////// scc::configurer cfg("ahb_bfm.json"); scc::configurable_tracer trace("ahb_bfm", tracer::TEXT, true, true); /////////////////////////////////////////////////////////////////////////// // create modules/channels and trace /////////////////////////////////////////////////////////////////////////// testbench tb("tb"); trace.add_control(); { std::ofstream of{"ahb_test.default.json"}; if (of.is_open()) cfg.dump_configuration(of); } cfg.configure(); /////////////////////////////////////////////////////////////////////////// // run the simulation /////////////////////////////////////////////////////////////////////////// try { sc_core::sc_start(1_us); if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop(); } catch (sc_core::sc_report &rep) { sc_core::sc_report_handler::get_handler()(rep, sc_core::SC_DISPLAY | sc_core::SC_STOP); } return 0; }