diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 1de6284..eb68e46 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/examples/simple_system/gen/gpio_regs.h b/examples/simple_system/gen/gpio_regs.h index 2c5c079..541adf9 100644 --- a/examples/simple_system/gen/gpio_regs.h +++ b/examples/simple_system/gen/gpio_regs.h @@ -44,7 +44,7 @@ namespace sysc { class gpio_regs : public sc_core::sc_module, public scc::resetable { -protected: +public: // storage declarations uint32_t r_value; diff --git a/examples/simple_system/gpio.cpp b/examples/simple_system/gpio.cpp index 04e847e..a7e87d3 100644 --- a/examples/simple_system/gpio.cpp +++ b/examples/simple_system/gpio.cpp @@ -1,22 +1,44 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Contributors: +// eyck@minres.com - initial implementation // -// http://www.apache.org/licenses/LICENSE-2.0 // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. //////////////////////////////////////////////////////////////////////////////// #include "gpio.h" -#include "gen/gpio_regs.h" +#include "scc/report.h" #include "scc/utilities.h" +#include "gen/gpio_regs.h" +#include namespace sysc { @@ -25,25 +47,176 @@ gpio::gpio(sc_core::sc_module_name nm) , tlm_target<>(clk) , NAMED(clk_i) , NAMED(rst_i) -, NAMED(out, 32) -, NAMED(in, 32) -, NAMEDD(gpio_regs, regs) { +, NAMED(pins_o, 32) +, NAMED(pins_i, 32) +, NAMED(iof0_o, 32) +, NAMED(iof1_o, 32) +, NAMED(iof0_i, 32) +, NAMED(iof1_i, 32) +, NAMEDD(gpio_regs, regs) +{ regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; SC_METHOD(reset_cb); sensitive << rst_i; + dont_initialize(); + auto pins_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<>& gp, + tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ + this->pin_input(tag, gp, delay); + return tlm::TLM_COMPLETED; + }; + auto i=0U; + for(auto& s:pins_i){ + s.register_nb_transport(pins_i_cb, i); + ++i; + } + auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<>& gp, + tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ + last_iof0[tag]=gp.get_value(); + this->iof_input(tag, 0, gp, delay); + return tlm::TLM_COMPLETED; + }; + i=0; + for(auto& s:iof0_i){ + s.register_nb_transport(iof0_i_cb, i); + ++i; + } + auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<>& gp, + tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ + last_iof1[tag]=gp.get_value(); + this->iof_input(tag, 1, gp, delay); + return tlm::TLM_COMPLETED; + }; + i=0; + for(auto& s:iof1_i){ + s.register_nb_transport(iof1_i_cb, i); + ++i; + } + auto update_pins_cb = [this](scc::sc_register ®, uint32_t data, sc_core::sc_time d) -> bool { + if (!this->regs->in_reset()) { + auto changed_bits = (reg.get()^data); + reg.put(data); + update_pins(changed_bits); + } + return true; + }; + regs->port.set_write_cb(update_pins_cb); + regs->output_en.set_write_cb(update_pins_cb); + regs->out_xor.set_write_cb(update_pins_cb); + regs->iof_en.set_write_cb(update_pins_cb); + regs->iof_sel.set_write_cb(update_pins_cb); } gpio::~gpio() {} -void gpio::clock_cb() {} - void gpio::reset_cb() { - if (rst_i.read()) + if (rst_i.read()){ regs->reset_start(); - else + } else { regs->reset_stop(); + } + update_pins(std::numeric_limits::max()); +} + +void gpio::clock_cb() { + this->clk = clk_i.read(); +} + +tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp& gp, size_t i, bool val) { + sc_core::sc_time delay{SC_ZERO_TIME}; + tlm::tlm_phase phase{ tlm::BEGIN_REQ }; + gp.set_command(tlm::TLM_WRITE_COMMAND); + gp.set_response_status(tlm::TLM_OK_RESPONSE); + gp.set_value(val); + pins_o.at(i)->nb_transport_fw(gp, phase, delay); + return phase; +} + +void gpio::update_pins(uint32_t changed_bits) { + sc_core::sc_inout_rv<32>::data_type out_val; + tlm::tlm_signal_gp gp; + bool val; + for(size_t i=0, mask = 1; i<32; ++i, mask<<=1){ + if(changed_bits&mask){ + if((regs->r_iof_en&mask!=0) && (iof0_i[i].size()==0 || iof1_i[i].size()==0)){ + if((regs->r_iof_sel&mask)==0 && iof0_i[i].size()>0){ + val=last_iof0[i]?sc_dt::Log_1:sc_dt::Log_0; + } else if((regs->r_iof_sel&mask)==1 && iof1_i[i].size()>0) + val=last_iof1[i]?sc_dt::Log_1:sc_dt::Log_0; + } else { + if((regs->r_output_en&mask) && (regs->r_port&mask)) + val=true; + else + val=false; + if(regs->r_out_xor&mask) + val=~val; + } + tlm::tlm_phase phase = write_output(gp, i, val); + } + } +} + +void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp& gp, sc_core::sc_time& delay) { + if(delay>SC_ZERO_TIME){ + wait(delay); + delay=SC_ZERO_TIME; + } + auto mask = 1u<r_output_en&mask==0) + regs->r_value|=mask; + forward_pin_input(tag, gp); + break; + case false: + if(regs->r_output_en&mask==0) regs->r_value&=~mask; + forward_pin_input(tag, gp); + break; + } +} + +void gpio::forward_pin_input(unsigned int tag, tlm::tlm_signal_gp& gp) { + const auto mask = 1U<iof_en&mask){ + auto& socket = regs->iof_sel&mask?iof1_o[tag]:iof0_o[tag]; + tlm::tlm_signal_gp<> new_gp; + for(size_t i=0; inb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum + } + } +} + +void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay) { + if(delay>SC_ZERO_TIME){ + wait(delay); + delay=SC_ZERO_TIME; + } + const auto mask = 1U<r_iof_en&mask){ + const auto idx = regs->r_iof_sel&mask?1:0; + if(iof_idx == idx){ + auto& socket = pins_o[tag]; + for(size_t i=0; i new_gp; + new_gp.set_command(tlm::TLM_WRITE_COMMAND); + auto val = gp.get_value(); + new_gp.set_value(val); + new_gp.copy_extensions_from(gp); + socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum + gp.update_extensions_from(new_gp); + } + } + } } } /* namespace sysc */ + diff --git a/examples/simple_system/gpio.h b/examples/simple_system/gpio.h index 1e9b2d3..d61b9a6 100644 --- a/examples/simple_system/gpio.h +++ b/examples/simple_system/gpio.h @@ -1,44 +1,84 @@ -/******************************************************************************* - * Copyright 2017 eyck@minres.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Contributors: +// eyck@minres.com - initial implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _GPIO_H_ #define _GPIO_H_ -#include +#include "scc/tlm_target.h" +#include "scc/signal_target_mixin.h" +#include "scc/signal_initiator_mixin.h" #include namespace sysc { class gpio_regs; +class WsHandler; class gpio : public sc_core::sc_module, public scc::tlm_target<> { public: SC_HAS_PROCESS(gpio); sc_core::sc_in clk_i; sc_core::sc_in rst_i; - sc_core::sc_vector> out; - sc_core::sc_vector> in; + // sc_core::sc_inout_rv<32> pins_io; + + sc_core::sc_vector pins_o; + sc_core::sc_vector pins_i; + + sc_core::sc_vector iof0_o; + sc_core::sc_vector iof1_o; + sc_core::sc_vector iof0_i; + sc_core::sc_vector iof1_i; + gpio(sc_core::sc_module_name nm); - virtual ~gpio(); + virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs protected: void clock_cb(); void reset_cb(); + void update_pins(uint32_t changed_bits); + void pin_input(unsigned int tag, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay); + void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<>& gp); + void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay); sc_core::sc_time clk; + std::array last_iof0, last_iof1; std::unique_ptr regs; + std::shared_ptr handler; + +private: + tlm::tlm_phase write_output(tlm::tlm_signal_gp<>& gp, size_t i, bool val); }; } /* namespace sysc */ diff --git a/examples/simple_system/sc_main.cpp b/examples/simple_system/sc_main.cpp index 1bda3c6..d8e1f53 100644 --- a/examples/simple_system/sc_main.cpp +++ b/examples/simple_system/sc_main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace sysc; using namespace scc; @@ -40,8 +41,9 @@ const size_t ERROR_UNHANDLED_EXCEPTION = 2; int sc_main(int argc, char *argv[]) { /////////////////////////////////////////////////////////////////////////// // setup initial logging - /////////////////////////////////////////////////////////////////////////// - scc::Logger<>::reporting_level() = logging::INFO; + /////////////////////////////////////////////////////////////////////////// LOGGER(DEFAULT)::reporting_level() = l; + LOGGER(DEFAULT)::reporting_level() = logging::INFO; + LOGGER(SystemC)::reporting_level() = logging::INFO; /////////////////////////////////////////////////////////////////////////// // CLI argument parsing /////////////////////////////////////////////////////////////////////////// @@ -67,11 +69,10 @@ int sc_main(int argc, char *argv[]) { std::cerr << desc << std::endl; return ERROR_IN_COMMAND_LINE; } - if (vm.count("debug")) { - LOGGER(DEFAULT)::reporting_level() = log::DEBUG; - LOGGER(SystemC)::reporting_level() = log::DEBUG; - scc::Logger<>::reporting_level() = log::DEBUG; - } + /////////////////////////////////////////////////////////////////////////// + // configure logging + /////////////////////////////////////////////////////////////////////////// + scc::init_logging(vm.count("debug")?logging::DEBUG:logging::INFO); /////////////////////////////////////////////////////////////////////////// // set up tracing & transaction recording @@ -83,7 +84,6 @@ int sc_main(int argc, char *argv[]) { // instantiate top level /////////////////////////////////////////////////////////////////////////// simple_system i_simple_system("i_simple_system"); - // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, sc_core::SC_WARNING, sc_core::SC_MEDIUM); /////////////////////////////////////////////////////////////////////////// // run simulation @@ -92,7 +92,7 @@ int sc_main(int argc, char *argv[]) { // todo: provide end-of-simulation macros if (!sc_core::sc_end_of_simulation_invoked()) { - LOG(ERROR) << "simulation timed out"; + SCERR() << "simulation timed out"; sc_core::sc_stop(); } return SUCCESS; diff --git a/examples/simple_system/simple_system.cpp b/examples/simple_system/simple_system.cpp index 083b787..302f86f 100644 --- a/examples/simple_system/simple_system.cpp +++ b/examples/simple_system/simple_system.cpp @@ -35,7 +35,9 @@ simple_system::simple_system(sc_core::sc_module_name nm) , NAMED(s_clk) , NAMED(s_rst) , NAMED(s_global_interrupts, 256) -, NAMED(s_core_interrupt) { +, NAMED(s_core_interrupt) +, NAMED(s_gpio, 32) +{ // todo: discuss naming conventions (s_ vs. _i/_o) --> covnert into _s // bus connections @@ -66,7 +68,11 @@ simple_system::simple_system(sc_core::sc_module_name nm) i_master.global_interrupts_o(s_global_interrupts); i_master.core_interrupt_i(s_core_interrupt); - i_gpio.in(i_gpio.out); + for(auto i=0U; i s_rst; sc_core::sc_vector> s_global_interrupts; sc_core::sc_signal s_core_interrupt; + sc_core::sc_vector> s_gpio; simple_system(sc_core::sc_module_name nm); diff --git a/examples/transaction_recording/CMakeLists.txt b/examples/transaction_recording/CMakeLists.txt index aa1d8ba..2e13eeb 100644 --- a/examples/transaction_recording/CMakeLists.txt +++ b/examples/transaction_recording/CMakeLists.txt @@ -11,5 +11,6 @@ target_link_libraries (transaction_recording LINK_PUBLIC sc-components) target_link_libraries (transaction_recording LINK_PUBLIC ${SystemC_LIBRARIES}) target_link_libraries (transaction_recording LINK_PUBLIC ${SCV_LIBRARIES}) target_link_libraries (transaction_recording LINK_PUBLIC ${Boost_LIBRARIES} ) +target_link_libraries (transaction_recording LINK_PUBLIC ${ZLIB_LIBRARIES} ) target_link_libraries (transaction_recording LINK_PUBLIC ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (transaction_recording LINK_PUBLIC ${CMAKE_DL_LIBS}) diff --git a/examples/transaction_recording/scv_tr_recording_example.cpp b/examples/transaction_recording/scv_tr_recording_example.cpp index 6e2e571..9b5eece 100644 --- a/examples/transaction_recording/scv_tr_recording_example.cpp +++ b/examples/transaction_recording/scv_tr_recording_example.cpp @@ -16,6 +16,14 @@ *****************************************************************************/ #include "scv.h" +#include "scc/scv_tr_db.h" +#include "scc/report.h" + +//47ms #define SQLITE_DB +//27ms +#define CTXT_DB +//29ms #define BINARY_DB +//27ms TEXT_DB // hack to fake a true fifo_mutex #define fifo_mutex sc_mutex @@ -189,8 +197,7 @@ inline void test::main1() { for (int i = 0; i < 3; i++) { rw_task_if::addr_t addr = i; rw_task_if::data_t data = transactor->read(&addr); - cout << "at time " << sc_time_stamp() << ": "; - cout << "received data : " << data << endl; + SCINFO(sc_get_current_object()->name()) << "received data : " << data; } scv_smart_ptr addr; @@ -198,14 +205,14 @@ inline void test::main1() { addr->next(); rw_task_if::data_t data = transactor->read(addr->get_instance()); - cout << "data for address " << *addr << " is " << data << endl; + SCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data; } scv_smart_ptr write; for (int i = 0; i < 3; i++) { write->next(); transactor->write(write->get_instance()); - cout << "send data : " << write->data << endl; + SCINFO(sc_get_current_object()->name()) << "send data : " << write->data; } scv_smart_ptr data; @@ -224,8 +231,7 @@ inline void test::main2() { for (int i = 0; i < 3; i++) { rw_task_if::addr_t addr = i; rw_task_if::data_t data = transactor->read(&addr); - cout << "at time " << sc_time_stamp() << ": "; - cout << "received data : " << data << endl; + SCINFO(sc_get_current_object()->name()) << "received data : " << data; } scv_smart_ptr addr; @@ -233,14 +239,14 @@ inline void test::main2() { addr->next(); rw_task_if::data_t data = transactor->read(addr->get_instance()); - cout << "data for address " << *addr << " is " << data << endl; + SCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data; } scv_smart_ptr write; for (int i = 0; i < 3; i++) { write->next(); transactor->write(write->get_instance()); - cout << "send data : " << write->data << endl; + SCINFO(sc_get_current_object()->name()) << "send data : " << write->data; } scv_smart_ptr data; @@ -291,8 +297,7 @@ inline void design::addr_phase() { outstandingAddresses.push_back(_addr); outstandingType.push_back(_rw); - cout << "at time " << sc_time_stamp() << ": "; - cout << "received request for memory address " << _addr << endl; + SCINFO(sc_get_current_object()->name()) << "received request for memory address " << _addr; } } @@ -306,15 +311,15 @@ inline void design::data_phase() { wait(clk->posedge_event()); } if (outstandingType.front() == false) { - cout << "reading memory address " << outstandingAddresses.front() << " with value " - << memory[outstandingAddresses.front().to_ulong()] << endl; + SCINFO(sc_get_current_object()->name()) << "reading memory address " << outstandingAddresses.front() << " with value " + << memory[outstandingAddresses.front().to_ulong()]; bus_data = memory[outstandingAddresses.front().to_ulong()]; data_rdy = 1; wait(clk->posedge_event()); data_rdy = 0; } else { - cout << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data << endl; + SCINFO(sc_get_current_object()->name()) << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data; memory[outstandingAddresses.front().to_ulong()] = bus_data; data_rdy = 1; wait(clk->posedge_event()); @@ -324,17 +329,25 @@ inline void design::data_phase() { outstandingType.pop_front(); } } -extern void scv_tr_binary_init(); int sc_main(int argc, char *argv[]) { + auto start = std::chrono::system_clock::now(); scv_startup(); + scc::init_logging(logging::INFO); + LOGGER(SystemC)::print_time() = false; -#if 0 - scv_tr_text_init(); - const char* fileName = "my_db.txlog"; -#else +#if defined(BINARY_DB) scv_tr_binary_init(); const char *fileName = "my_db"; +#elif defined(CTXT_DB) + scv_tr_compressed_init(); + const char* fileName = "my_db.txlog"; +#elif defined(SQLITE_DB) + scv_tr_sqlite_init(); + const char* fileName = "my_db.txdb"; +#else + scv_tr_text_init(); + const char* fileName = "my_db.txlog"; #endif scv_tr_db db(fileName); scv_tr_db::set_default_db(&db); @@ -378,7 +391,9 @@ int sc_main(int argc, char *argv[]) { // Disable check for bus simulation. sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); // run the simulation - sc_start(1.0, SC_MS); + sc_start(10.0, SC_US); sc_close_vcd_trace_file(tf); + auto int_us = std::chrono::duration_cast(std::chrono::system_clock::now()-start); + SCINFO() << "simulation duration "<