From 6516244afea76ad6f6ee0b9ed132ea1b670b28de Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 2 Oct 2022 08:14:58 +0200 Subject: [PATCH] cleans up project and adds axi4_pin_level test --- .cproject | 272 +----------- CMakeLists.txt | 8 +- etc/irq_wave.sav | 60 --- etc/simple_system.launch | 44 -- examples/CMakeLists.txt | 8 - examples/ahb_bfm/CMakeLists.txt | 10 - examples/ahb_bfm/sc_main.cpp | 145 ------- examples/simple_system/CMakeLists.txt | 18 - examples/simple_system/gen/e300_plat_t.h | 27 -- examples/simple_system/gen/gpio_regs.h | 152 ------- examples/simple_system/gen/plic_regs.h | 96 ----- examples/simple_system/gen/spi_regs.h | 192 --------- examples/simple_system/gen/uart_regs.h | 125 ------ examples/simple_system/gpio.cpp | 220 ---------- examples/simple_system/gpio.h | 86 ---- examples/simple_system/plic.cpp | 177 -------- examples/simple_system/plic.h | 57 --- examples/simple_system/sc_main.cpp | 92 ---- examples/simple_system/simple_system.cpp | 87 ---- examples/simple_system/simple_system.h | 64 --- examples/simple_system/spi.cpp | 47 -- examples/simple_system/spi.h | 43 -- examples/simple_system/test_initiator.cpp | 272 ------------ examples/simple_system/test_initiator.h | 55 --- examples/simple_system/uart.cpp | 47 -- examples/simple_system/uart.h | 43 -- examples/transaction_recording/CMakeLists.txt | 7 - .../scv_tr_recording_example.cpp | 406 ------------------ scc | 2 +- src/CMakeLists.txt | 4 + src/factory.cpp | 46 ++ src/factory.h | 78 ++++ tests/CMakeLists.txt | 1 + tests/axi4_pin_level/CMakeLists.txt | 9 + tests/axi4_pin_level/narrow_burst_test.cpp | 119 +++++ tests/axi4_pin_level/sc_main.cpp | 25 ++ tests/axi4_pin_level/testbench.h | 78 ++++ 37 files changed, 386 insertions(+), 2836 deletions(-) delete mode 100644 etc/irq_wave.sav delete mode 100644 etc/simple_system.launch delete mode 100644 examples/CMakeLists.txt delete mode 100644 examples/ahb_bfm/CMakeLists.txt delete mode 100644 examples/ahb_bfm/sc_main.cpp delete mode 100644 examples/simple_system/CMakeLists.txt delete mode 100644 examples/simple_system/gen/e300_plat_t.h delete mode 100644 examples/simple_system/gen/gpio_regs.h delete mode 100644 examples/simple_system/gen/plic_regs.h delete mode 100644 examples/simple_system/gen/spi_regs.h delete mode 100644 examples/simple_system/gen/uart_regs.h delete mode 100644 examples/simple_system/gpio.cpp delete mode 100644 examples/simple_system/gpio.h delete mode 100644 examples/simple_system/plic.cpp delete mode 100644 examples/simple_system/plic.h delete mode 100644 examples/simple_system/sc_main.cpp delete mode 100644 examples/simple_system/simple_system.cpp delete mode 100644 examples/simple_system/simple_system.h delete mode 100644 examples/simple_system/spi.cpp delete mode 100644 examples/simple_system/spi.h delete mode 100644 examples/simple_system/test_initiator.cpp delete mode 100644 examples/simple_system/test_initiator.h delete mode 100644 examples/simple_system/uart.cpp delete mode 100644 examples/simple_system/uart.h delete mode 100644 examples/transaction_recording/CMakeLists.txt delete mode 100644 examples/transaction_recording/scv_tr_recording_example.cpp create mode 100644 src/CMakeLists.txt create mode 100644 src/factory.cpp create mode 100644 src/factory.h create mode 100644 tests/axi4_pin_level/CMakeLists.txt create mode 100644 tests/axi4_pin_level/narrow_burst_test.cpp create mode 100644 tests/axi4_pin_level/sc_main.cpp create mode 100644 tests/axi4_pin_level/testbench.h diff --git a/.cproject b/.cproject index ff869b6..61da564 100644 --- a/.cproject +++ b/.cproject @@ -1,285 +1,53 @@ - - - - - - - - - + + + + - + + - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - CMAKE_BUILD_TOOL - $<cmake4eclipse_dyn> - test - true - true - true - - + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2213296..8fe20db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include(BuildType) #enable_testing() -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -61,7 +61,7 @@ endif() endif() conan_check() -conan_configure(REQUIRES fmt/6.1.2 boost/1.75.0 gsl-lite/0.37.0 systemc/2.3.3 systemc-cci/1.0.0 +conan_configure(REQUIRES fmt/6.1.2 boost/1.75.0 gsl-lite/0.37.0 systemc/2.3.3 systemc-cci/1.0.0 catch2/3.1.0 GENERATORS cmake_find_package OPTIONS fmt:header_only=True ) @@ -72,10 +72,12 @@ find_package(ZLIB) set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install. find_package(Boost COMPONENTS program_options filesystem system thread REQUIRED) find_package(fmt) +find_package(Catch2) + include(SystemCPackage) enable_testing() add_subdirectory(scc) -add_subdirectory(examples) +add_subdirectory(src) add_subdirectory(tests) diff --git a/etc/irq_wave.sav b/etc/irq_wave.sav deleted file mode 100644 index 85c2b53..0000000 --- a/etc/irq_wave.sav +++ /dev/null @@ -1,60 +0,0 @@ -[*] -[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI -[*] Fri Sep 22 20:16:21 2017 -[*] -[dumpfile] "/home/valid/project/minres2/SystemC-Components-Test/simple_system.vcd" -[dumpfile_mtime] "Fri Sep 22 20:15:38 2017" -[dumpfile_size] 69714 -[savefile] "/home/valid/project/minres2/SystemC-Components-Test/etc/irq_wave.sav" -[timestart] 4 -[size] 1920 924 -[pos] -1 -1 -*-3.538420 30 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -[sst_width] 397 -[signals_width] 422 -[sst_expanded] 1 -[sst_vpaned_height] 334 -@200 --System signals -@28 -SystemC.\i_simple_system.s_rst -@24 -SystemC.\i_simple_system.s_clk[63:0] -@28 -SystemC.\i_simple_system.s_core_interrupt -SystemC.\i_simple_system.s_global_interrupts_0 -SystemC.\i_simple_system.s_global_interrupts_1 -SystemC.\i_simple_system.s_global_interrupts_2 -SystemC.\i_simple_system.s_global_interrupts_3 -SystemC.\i_simple_system.s_global_interrupts_4 -@200 --Master -@28 -SystemC.\i_simple_system.i_master.rst_i -SystemC.\i_simple_system.i_master.core_interrupt_i -@200 --PLIC ports -@24 -SystemC.\i_simple_system.i_plic.rst_i -SystemC.\i_simple_system.i_plic.clk_i[63:0] -@28 -SystemC.\i_simple_system.i_plic.global_interrupts_i_0 -SystemC.\i_simple_system.i_plic.global_interrupts_i_1 -SystemC.\i_simple_system.i_plic.global_interrupts_i_2 -SystemC.\i_simple_system.i_plic.global_interrupts_i_3 -SystemC.\i_simple_system.i_plic.global_interrupts_i_4 -@200 --PLIC regs -@22 -SystemC.\i_simple_system.i_plic.regs.enabled[31:0] -SystemC.\i_simple_system.i_plic.regs.pending[31:0] -@23 -SystemC.\i_simple_system.i_plic.regs.priority0[31:0] -@22 -SystemC.\i_simple_system.i_plic.regs.priority1[31:0] -SystemC.\i_simple_system.i_plic.regs.priority2[31:0] -SystemC.\i_simple_system.i_plic.regs.priority3[31:0] -SystemC.\i_simple_system.i_plic.regs.threshold[31:0] -SystemC.\i_simple_system.i_plic.regs.claim_complete[31:0] -[pattern_trace] 1 -[pattern_trace] 0 diff --git a/etc/simple_system.launch b/etc/simple_system.launch deleted file mode 100644 index 0dd0585..0000000 --- a/etc/simple_system.launch +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 64f95c4..0000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -if(SCV_FOUND) - add_subdirectory(transaction_recording) -endif() - -add_subdirectory(simple_system) -add_subdirectory(ahb_bfm) diff --git a/examples/ahb_bfm/CMakeLists.txt b/examples/ahb_bfm/CMakeLists.txt deleted file mode 100644 index 26a00a3..0000000 --- a/examples/ahb_bfm/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.3) -# Add executable called "transaction_recording" that is built from the source files -# "scv_tr_recording_example.cpp". The extensions are automatically found. -add_executable (ahb_bfm - sc_main.cpp -) -# Link the executable to the sc_components library. Since the sc_components library has -# public include directories we will use those link directories when building -# transaction_recording -target_link_libraries (ahb_bfm LINK_PUBLIC scc) diff --git a/examples/ahb_bfm/sc_main.cpp b/examples/ahb_bfm/sc_main.cpp deleted file mode 100644 index ca278c6..0000000 --- a/examples/ahb_bfm/sc_main.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#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; -} - diff --git a/examples/simple_system/CMakeLists.txt b/examples/simple_system/CMakeLists.txt deleted file mode 100644 index ee8c673..0000000 --- a/examples/simple_system/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -find_package(Boost COMPONENTS program_options REQUIRED) -add_executable (simple_system - plic.cpp - uart.cpp - spi.cpp - gpio.cpp - test_initiator.cpp - simple_system.cpp - sc_main.cpp -) -target_link_libraries (simple_system LINK_PUBLIC scc) -if(TARGET Boost::program_options) - target_link_libraries(simple_system PUBLIC Boost::program_options) -else() - target_link_libraries(simple_system PUBLIC ${BOOST_program_options_LIBRARY}) -endif() -add_test(NAME simple_system_test COMMAND simple_system) \ No newline at end of file diff --git a/examples/simple_system/gen/e300_plat_t.h b/examples/simple_system/gen/e300_plat_t.h deleted file mode 100644 index 57ce875..0000000 --- a/examples/simple_system/gen/e300_plat_t.h +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ -#ifndef _E300_PLAT_MAP_H_ -#define _E300_PLAT_MAP_H_ -// need double braces, see -// https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 -const std::array, 4> e300_plat_map = {{ - {"plic", 0x0c000000, 0x200008}, - {"gpio", 0x10012000, 0x1000}, - {"uart", 0x10013000, 0x1000}, - {"spi", 0x10014000, 0x1000}, -}}; - -#endif /* _E300_PLAT_MAP_H_ */ diff --git a/examples/simple_system/gen/gpio_regs.h b/examples/simple_system/gen/gpio_regs.h deleted file mode 100644 index 541adf9..0000000 --- a/examples/simple_system/gen/gpio_regs.h +++ /dev/null @@ -1,152 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -// Created on: Wed Sep 20 11:47:24 CEST 2017 -// * gpio_regs.h Author: -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef _GPIO_REGS_H_ -#define _GPIO_REGS_H_ - -#include -#include "scc/register.h" -#include "scc/tlm_target.h" -#include "scc/utilities.h" - -namespace sysc { - -class gpio_regs : public sc_core::sc_module, public scc::resetable { -public: - // storage declarations - uint32_t r_value; - - uint32_t r_input_en; - - uint32_t r_output_en; - - uint32_t r_port; - - uint32_t r_pue; - - uint32_t r_ds; - - uint32_t r_rise_ie; - - uint32_t r_rise_ip; - - uint32_t r_fall_ie; - - uint32_t r_fall_ip; - - uint32_t r_high_ie; - - uint32_t r_high_ip; - - uint32_t r_low_ie; - - uint32_t r_low_ip; - - uint32_t r_iof_en; - - uint32_t r_iof_sel; - - uint32_t r_out_xor; - - // register declarations - scc::sc_register value; - scc::sc_register input_en; - scc::sc_register output_en; - scc::sc_register port; - scc::sc_register pue; - scc::sc_register ds; - scc::sc_register rise_ie; - scc::sc_register rise_ip; - scc::sc_register fall_ie; - scc::sc_register fall_ip; - scc::sc_register high_ie; - scc::sc_register high_ip; - scc::sc_register low_ie; - scc::sc_register low_ip; - scc::sc_register iof_en; - scc::sc_register iof_sel; - scc::sc_register out_xor; - -public: - gpio_regs(sc_core::sc_module_name nm); - - template void registerResources(scc::tlm_target &target); -}; -} -////////////////////////////////////////////////////////////////////////////// -// member functions -////////////////////////////////////////////////////////////////////////////// - -inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, NAMED(value, r_value, 0, *this) -, NAMED(input_en, r_input_en, 0, *this) -, NAMED(output_en, r_output_en, 0, *this) -, NAMED(port, r_port, 0, *this) -, NAMED(pue, r_pue, 0, *this) -, NAMED(ds, r_ds, 0, *this) -, NAMED(rise_ie, r_rise_ie, 0, *this) -, NAMED(rise_ip, r_rise_ip, 0, *this) -, NAMED(fall_ie, r_fall_ie, 0, *this) -, NAMED(fall_ip, r_fall_ip, 0, *this) -, NAMED(high_ie, r_high_ie, 0, *this) -, NAMED(high_ip, r_high_ip, 0, *this) -, NAMED(low_ie, r_low_ie, 0, *this) -, NAMED(low_ip, r_low_ip, 0, *this) -, NAMED(iof_en, r_iof_en, 0, *this) -, NAMED(iof_sel, r_iof_sel, 0, *this) -, NAMED(out_xor, r_out_xor, 0, *this) {} - -template inline void sysc::gpio_regs::registerResources(scc::tlm_target &target) { - target.addResource(value, 0x0UL); - target.addResource(input_en, 0x4UL); - target.addResource(output_en, 0x8UL); - target.addResource(port, 0xcUL); - target.addResource(pue, 0x10UL); - target.addResource(ds, 0x14UL); - target.addResource(rise_ie, 0x18UL); - target.addResource(rise_ip, 0x1cUL); - target.addResource(fall_ie, 0x20UL); - target.addResource(fall_ip, 0x24UL); - target.addResource(high_ie, 0x28UL); - target.addResource(high_ip, 0x2cUL); - target.addResource(low_ie, 0x30UL); - target.addResource(low_ip, 0x34UL); - target.addResource(iof_en, 0x38UL); - target.addResource(iof_sel, 0x3cUL); - target.addResource(out_xor, 0x40UL); -} - -#endif // _GPIO_REGS_H_ diff --git a/examples/simple_system/gen/plic_regs.h b/examples/simple_system/gen/plic_regs.h deleted file mode 100644 index 6864328..0000000 --- a/examples/simple_system/gen/plic_regs.h +++ /dev/null @@ -1,96 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -// Created on: Wed Sep 20 22:30:45 CEST 2017 -// * plic_regs.h Author: -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef _PLIC_REGS_H_ -#define _PLIC_REGS_H_ - -#include -#include "scc/register.h" -#include "scc/tlm_target.h" -#include "scc/utilities.h" - -namespace sysc { - -class plic_regs : public sc_core::sc_module, public scc::resetable { -public: - // storage declarations - BEGIN_BF_DECL(priority_t, uint32_t); - BF_FIELD(priority, 0, 3); - END_BF_DECL(); - std::array r_priority; - - uint32_t r_pending; - - uint32_t r_enabled; - - BEGIN_BF_DECL(threshold_t, uint32_t); - BF_FIELD(threshold, 0, 3); - END_BF_DECL() r_threshold; - - uint32_t r_claim_complete; - - // register declarations - scc::sc_register_indexed priority; - scc::sc_register pending; - scc::sc_register enabled; - scc::sc_register threshold; - scc::sc_register claim_complete; - - plic_regs(sc_core::sc_module_name nm); - - template void registerResources(scc::tlm_target &target); -}; -} -////////////////////////////////////////////////////////////////////////////// -// member functions -////////////////////////////////////////////////////////////////////////////// - -inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, NAMED(priority, r_priority, 0, *this) -, NAMED(pending, r_pending, 0, *this) -, NAMED(enabled, r_enabled, 0, *this) -, NAMED(threshold, r_threshold, 0, *this) -, NAMED(claim_complete, r_claim_complete, 0, *this) {} - -template inline void sysc::plic_regs::registerResources(scc::tlm_target &target) { - target.addResource(priority, 0x4UL); - target.addResource(pending, 0x1000UL); - target.addResource(enabled, 0x2000UL); - target.addResource(threshold, 0x00200000UL); - target.addResource(claim_complete, 0x00200004UL); -} - -#endif // _PLIC_REGS_H_ diff --git a/examples/simple_system/gen/spi_regs.h b/examples/simple_system/gen/spi_regs.h deleted file mode 100644 index 871a87a..0000000 --- a/examples/simple_system/gen/spi_regs.h +++ /dev/null @@ -1,192 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -// Created on: Wed Sep 20 22:30:45 CEST 2017 -// * spi_regs.h Author: -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef _SPI_REGS_H_ -#define _SPI_REGS_H_ - -#include -#include "scc/register.h" -#include "scc/tlm_target.h" -#include "scc/utilities.h" - -namespace sysc { - -class spi_regs : public sc_core::sc_module, public scc::resetable { -protected: - // storage declarations - BEGIN_BF_DECL(sckdiv_t, uint32_t); - BF_FIELD(div, 0, 12); - END_BF_DECL() r_sckdiv; - - BEGIN_BF_DECL(sckmode_t, uint32_t); - BF_FIELD(pha, 0, 1); - BF_FIELD(pol, 1, 1); - END_BF_DECL() r_sckmode; - - uint32_t r_csid; - - uint32_t r_csdef; - - BEGIN_BF_DECL(csmode_t, uint32_t); - BF_FIELD(mode, 0, 2); - END_BF_DECL() r_csmode; - - BEGIN_BF_DECL(delay0_t, uint32_t); - BF_FIELD(cssck, 0, 8); - BF_FIELD(sckcs, 16, 8); - END_BF_DECL() r_delay0; - - BEGIN_BF_DECL(delay1_t, uint32_t); - BF_FIELD(intercs, 0, 16); - BF_FIELD(interxfr, 16, 8); - END_BF_DECL() r_delay1; - - BEGIN_BF_DECL(fmt_t, uint32_t); - BF_FIELD(proto, 0, 2); - BF_FIELD(endian, 2, 1); - BF_FIELD(dir, 3, 1); - BF_FIELD(len, 16, 4); - END_BF_DECL() r_fmt; - - BEGIN_BF_DECL(txdata_t, uint32_t); - BF_FIELD(data, 0, 8); - BF_FIELD(full, 31, 1); - END_BF_DECL() r_txdata; - - BEGIN_BF_DECL(rxdata_t, uint32_t); - BF_FIELD(data, 0, 8); - BF_FIELD(empty, 31, 1); - END_BF_DECL() r_rxdata; - - BEGIN_BF_DECL(txmark_t, uint32_t); - BF_FIELD(txmark, 0, 3); - END_BF_DECL() r_txmark; - - BEGIN_BF_DECL(rxmark_t, uint32_t); - BF_FIELD(rxmark, 0, 3); - END_BF_DECL() r_rxmark; - - BEGIN_BF_DECL(fctrl_t, uint32_t); - BF_FIELD(en, 0, 1); - END_BF_DECL() r_fctrl; - - BEGIN_BF_DECL(ffmt_t, uint32_t); - BF_FIELD(cmd_en, 0, 1); - BF_FIELD(addr_len, 1, 2); - BF_FIELD(pad_cnt, 3, 4); - BF_FIELD(cmd_proto, 7, 2); - BF_FIELD(addr_proto, 9, 2); - BF_FIELD(data_proto, 11, 2); - BF_FIELD(cmd_code, 16, 8); - BF_FIELD(pad_code, 24, 8); - END_BF_DECL() r_ffmt; - - BEGIN_BF_DECL(ie_t, uint32_t); - BF_FIELD(txwm, 0, 1); - BF_FIELD(rxwm, 1, 1); - END_BF_DECL() r_ie; - - BEGIN_BF_DECL(ip_t, uint32_t); - BF_FIELD(txwm, 0, 1); - BF_FIELD(rxwm, 1, 1); - END_BF_DECL() r_ip; - - // register declarations - scc::sc_register sckdiv; - scc::sc_register sckmode; - scc::sc_register csid; - scc::sc_register csdef; - scc::sc_register csmode; - scc::sc_register delay0; - scc::sc_register delay1; - scc::sc_register fmt; - scc::sc_register txdata; - scc::sc_register rxdata; - scc::sc_register txmark; - scc::sc_register rxmark; - scc::sc_register fctrl; - scc::sc_register ffmt; - scc::sc_register ie; - scc::sc_register ip; - -public: - spi_regs(sc_core::sc_module_name nm); - - template void registerResources(scc::tlm_target &target); -}; -} -////////////////////////////////////////////////////////////////////////////// -// member functions -////////////////////////////////////////////////////////////////////////////// - -inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, NAMED(sckdiv, r_sckdiv, 0, *this) -, NAMED(sckmode, r_sckmode, 0, *this) -, NAMED(csid, r_csid, 0, *this) -, NAMED(csdef, r_csdef, 0, *this) -, NAMED(csmode, r_csmode, 0, *this) -, NAMED(delay0, r_delay0, 0, *this) -, NAMED(delay1, r_delay1, 0, *this) -, NAMED(fmt, r_fmt, 0, *this) -, NAMED(txdata, r_txdata, 0, *this) -, NAMED(rxdata, r_rxdata, 0, *this) -, NAMED(txmark, r_txmark, 0, *this) -, NAMED(rxmark, r_rxmark, 0, *this) -, NAMED(fctrl, r_fctrl, 0, *this) -, NAMED(ffmt, r_ffmt, 0, *this) -, NAMED(ie, r_ie, 0, *this) -, NAMED(ip, r_ip, 0, *this) {} - -template inline void sysc::spi_regs::registerResources(scc::tlm_target &target) { - target.addResource(sckdiv, 0x0UL); - target.addResource(sckmode, 0x4UL); - target.addResource(csid, 0x10UL); - target.addResource(csdef, 0x14UL); - target.addResource(csmode, 0x18UL); - target.addResource(delay0, 0x28UL); - target.addResource(delay1, 0x2cUL); - target.addResource(fmt, 0x40UL); - target.addResource(txdata, 0x48UL); - target.addResource(rxdata, 0x4cUL); - target.addResource(txmark, 0x50UL); - target.addResource(rxmark, 0x54UL); - target.addResource(fctrl, 0x60UL); - target.addResource(ffmt, 0x64UL); - target.addResource(ie, 0x70UL); - target.addResource(ip, 0x74UL); -} - -#endif // _SPI_REGS_H_ diff --git a/examples/simple_system/gen/uart_regs.h b/examples/simple_system/gen/uart_regs.h deleted file mode 100644 index e61d300..0000000 --- a/examples/simple_system/gen/uart_regs.h +++ /dev/null @@ -1,125 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -// Created on: Wed Sep 20 22:30:45 CEST 2017 -// * uart_regs.h Author: -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef _UART_REGS_H_ -#define _UART_REGS_H_ - -#include -#include "scc/register.h" -#include "scc/tlm_target.h" -#include "scc/utilities.h" - -namespace sysc { - -class uart_regs : public sc_core::sc_module, public scc::resetable { -protected: - // storage declarations - BEGIN_BF_DECL(txdata_t, uint32_t); - BF_FIELD(data, 0, 8); - BF_FIELD(full, 31, 1); - END_BF_DECL() r_txdata; - - BEGIN_BF_DECL(rxdata_t, uint32_t); - BF_FIELD(data, 0, 8); - BF_FIELD(empty, 31, 1); - END_BF_DECL() r_rxdata; - - BEGIN_BF_DECL(txctrl_t, uint32_t); - BF_FIELD(txen, 0, 1); - BF_FIELD(nstop, 1, 1); - BF_FIELD(reserved, 2, 14); - BF_FIELD(txcnt, 16, 3); - END_BF_DECL() r_txctrl; - - BEGIN_BF_DECL(rxctrl_t, uint32_t); - BF_FIELD(rxen, 0, 1); - BF_FIELD(reserved, 1, 15); - BF_FIELD(rxcnt, 16, 3); - END_BF_DECL() r_rxctrl; - - BEGIN_BF_DECL(ie_t, uint32_t); - BF_FIELD(txwm, 0, 1); - BF_FIELD(rxwm, 1, 1); - END_BF_DECL() r_ie; - - BEGIN_BF_DECL(ip_t, uint32_t); - BF_FIELD(txwm, 0, 1); - BF_FIELD(rxwm, 1, 1); - END_BF_DECL() r_ip; - - BEGIN_BF_DECL(div_t, uint32_t); - BF_FIELD(div, 0, 16); - END_BF_DECL() r_div; - - // register declarations - scc::sc_register txdata; - scc::sc_register rxdata; - scc::sc_register txctrl; - scc::sc_register rxctrl; - scc::sc_register ie; - scc::sc_register ip; - scc::sc_register div; - -public: - uart_regs(sc_core::sc_module_name nm); - - template void registerResources(scc::tlm_target &target); -}; -} -////////////////////////////////////////////////////////////////////////////// -// member functions -////////////////////////////////////////////////////////////////////////////// - -inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, NAMED(txdata, r_txdata, 0, *this) -, NAMED(rxdata, r_rxdata, 0, *this) -, NAMED(txctrl, r_txctrl, 0, *this) -, NAMED(rxctrl, r_rxctrl, 0, *this) -, NAMED(ie, r_ie, 0, *this) -, NAMED(ip, r_ip, 0, *this) -, NAMED(div, r_div, 0, *this) {} - -template inline void sysc::uart_regs::registerResources(scc::tlm_target &target) { - target.addResource(txdata, 0x0UL); - target.addResource(rxdata, 0x4UL); - target.addResource(txctrl, 0x8UL); - target.addResource(rxctrl, 0xcUL); - target.addResource(ie, 0x10UL); - target.addResource(ip, 0x14UL); - target.addResource(div, 0x18UL); -} - -#endif // _UART_REGS_H_ diff --git a/examples/simple_system/gpio.cpp b/examples/simple_system/gpio.cpp deleted file mode 100644 index b662311..0000000 --- a/examples/simple_system/gpio.cpp +++ /dev/null @@ -1,220 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 -// -// -//////////////////////////////////////////////////////////////////////////////// - -#include "gpio.h" -#include "scc/report.h" -#include "scc/utilities.h" -#include "gen/gpio_regs.h" -#include - -namespace sysc { - -using namespace sc_core; - -gpio::gpio(sc_module_name nm) -: sc_module(nm) -, tlm_target<>(clk) -, NAMED(clk_i) -, NAMED(rst_i) -, 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(regs, gpio_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::scc::tlm_signal_gp<>& gp, - tlm::tlm_phase& phase, 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::scc::tlm_signal_gp<>& gp, - tlm::tlm_phase& phase, 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::scc::tlm_signal_gp<>& gp, - tlm::tlm_phase& phase, 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_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() = default; - -void gpio::reset_cb() { - if (rst_i.read()){ - regs->reset_start(); - } 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::scc::tlm_signal_gp& gp, size_t i, bool val) { - 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_inout_rv<32>::data_type out_val; - tlm::scc::tlm_signal_gp gp; - bool val{false}; - 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::scc::tlm_signal_gp& gp, sc_time& delay) { - if(delay>SC_ZERO_TIME){ - wait(delay); - delay=SC_ZERO_TIME; - } - auto mask = 1u<r_output_en&mask)==0){ - if(gp.get_value()) - regs->r_value|=mask; - else - regs->r_value&=~mask; - forward_pin_input(tag, gp); - } -} - -void gpio::forward_pin_input(unsigned int tag, tlm::scc::tlm_signal_gp& gp) { - const auto mask = 1U<iof_en&mask){ - auto& socket = regs->iof_sel&mask?iof1_o[tag]:iof0_o[tag]; - tlm::scc::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::scc::tlm_signal_gp<>& gp, 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 deleted file mode 100644 index 3c1c97e..0000000 --- a/examples/simple_system/gpio.h +++ /dev/null @@ -1,86 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 "scc/tlm_target.h" -#include "tlm/scc/signal_target_mixin.h" -#include "tlm/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_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() 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::scc::tlm_signal_gp<>& gp, sc_core::sc_time& delay); - void forward_pin_input(unsigned int tag, tlm::scc::tlm_signal_gp<>& gp); - void iof_input(unsigned int tag, unsigned iof_idx, tlm::scc::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::scc::tlm_signal_gp<>& gp, size_t i, bool val); -}; - -} /* namespace sysc */ - -#endif /* _GPIO_H_ */ diff --git a/examples/simple_system/plic.cpp b/examples/simple_system/plic.cpp deleted file mode 100644 index 3b4cbac..0000000 --- a/examples/simple_system/plic.cpp +++ /dev/null @@ -1,177 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 LIABILITY0x200004, 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 API and implementation -// -// -//////////////////////////////////////////////////////////////////////////////// - -// todo: truncate values beyond 7 (in prio_threshold write_cb) - -#include "plic.h" -#include "gen/plic_regs.h" -#include "scc/utilities.h" -#include - -namespace sysc { - -plic::plic(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, tlm_target<>(clk) -, NAMED(clk_i) -, NAMED(rst_i) -, NAMED(global_interrupts_i, 256) -, NAMED(core_interrupt_o) -, NAMEDD(regs, plic_regs) -{ - regs->registerResources(*this); - // register callbacks - init_callbacks(); - regs->claim_complete.set_write_cb(m_claim_complete_write_cb); - - // port callbacks - SC_METHOD(global_int_port_cb); - for (uint8_t i = 0; i < 255; i++) { - sensitive << global_interrupts_i[i].pos(); - } - dont_initialize(); - - // register event callbacks - SC_METHOD(clock_cb); - sensitive << clk_i; - SC_METHOD(reset_cb); - sensitive << rst_i; -} - -plic::~plic() = default; - -void plic::init_callbacks() { - m_claim_complete_write_cb = [=](scc::sc_register reg, uint32_t v) -> bool { - reg.put(v); - reset_pending_int(v); - // std::cout << "Value of register: 0x" << std::hex << reg << std::endl; - // todo: reset related interrupt and find next high-prio interrupt - return true; - }; -} - -void plic::clock_cb() { this->clk = clk_i.read(); } - -void plic::reset_cb() { - if (rst_i.read()) - regs->reset_start(); - else - regs->reset_stop(); -} - -// Functional handling of interrupts: -// - global_int_port_cb() -// - set pending register bits -// - called by: incoming global_int -// - handle_pending_int() -// - update claim register content -// - generate core-interrupt pulse -// - called by: -// - incoming global_int -// - complete-register write access -// - reset_pending_int(int-id) -// - reset pending bit -// - call next handle_pending_int() -// - called by: -// - complete-reg write register content - -void plic::global_int_port_cb() { - - // set related pending bit if enable is set for incoming global_interrupt - - // todo: extend up to 255 bits (limited to 32 right now) - for (uint32_t i = 1; i < 32; i++) { - uint32_t enable_bits = regs->r_enabled; - bool enable = enable_bits & (0x1 << i); // read enable bit - - if (enable && global_interrupts_i[i].read() == 1) { - regs->r_pending = regs->r_pending | (0x1 << i); - SCCDEBUG("plic") << "pending interrupt identified: " << i; - } - } - - handle_pending_int(); -} - -void plic::handle_pending_int() { - // identify high-prio pending interrupt and raise a core-interrupt - uint32_t claim_int = 0; // claim interrupt - uint32_t claim_prio = 0; // related priority (highest prio interrupt wins the race) - bool raise_int = false; - uint32_t thold = regs->r_threshold.threshold; // threshold value - - // todo: extend up to 255 bits (limited to 32 right now) - for (uint32_t i = 1; i < 32; i++) { - uint32_t pending_bits = regs->r_pending; - bool pending = (pending_bits & (0x1 << i)) ? true : false; - uint32_t prio = regs->r_priority[i - 1].priority; // read priority value - - if (pending && thold < prio) { - regs->r_pending = regs->r_pending | (0x1 << i); - // below condition ensures implicitly that lowest id is selected in case of multiple identical - // priority-interrupts - if (prio > claim_prio) { - claim_prio = prio; - claim_int = i; - raise_int = true; - SCCDEBUG("plic") << "pending interrupt activated: " << i; - } - } - } - - if (raise_int) { - regs->r_claim_complete = claim_int; - core_interrupt_o.write(true); - // todo: evluate clock period - } else { - regs->r_claim_complete = 0; - SCCDEBUG("plic") << "no further pending interrupt."; - } -} - -void plic::reset_pending_int(uint32_t irq) { - // todo: evaluate enable register (see spec) - // todo: make sure that pending is set, otherwise don't reset irq ... read spec. - SCCDEBUG("plic") << "reset pending interrupt: " << irq; - // reset related pending bit - regs->r_pending &= ~(0x1 << irq); - core_interrupt_o.write(false); - - // evaluate next pending interrupt - handle_pending_int(); -} - -} /* namespace sysc */ diff --git a/examples/simple_system/plic.h b/examples/simple_system/plic.h deleted file mode 100644 index 0cb60b5..0000000 --- a/examples/simple_system/plic.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ - -#ifndef _PLIC_H_ -#define _PLIC_H_ - -#include -#include - -namespace sysc { - -class plic_regs; - -class plic : public sc_core::sc_module, public scc::tlm_target<> { -public: - SC_HAS_PROCESS(plic); - sc_core::sc_in clk_i; - sc_core::sc_in rst_i; - sc_core::sc_vector> global_interrupts_i; - sc_core::sc_out core_interrupt_o; - sc_core::sc_event raise_int_ev; - sc_core::sc_event clear_int_ev; - plic(sc_core::sc_module_name nm); - virtual ~plic(); - -protected: - void clock_cb(); - void reset_cb(); - void init_callbacks(); - - void global_int_port_cb(); - void handle_pending_int(); - void reset_pending_int(uint32_t irq); - - void raise_core_interrupt(); - void clear_core_interrupt(); - sc_core::sc_time clk; - std::unique_ptr regs; - std::function, uint32_t)> m_claim_complete_write_cb; -}; - -} /* namespace sysc */ - -#endif /* _PLIC_H_ */ diff --git a/examples/simple_system/sc_main.cpp b/examples/simple_system/sc_main.cpp deleted file mode 100644 index 131b19f..0000000 --- a/examples/simple_system/sc_main.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -//////////////////////////////////////////////////////////////////////////////// -/* - * sc_main.cpp - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ - -#include "simple_system.h" -#include -#include -#include - -using namespace sysc; -using namespace scc; -namespace po = boost::program_options; - -namespace { -const size_t ERROR_IN_COMMAND_LINE = 1; -const size_t SUCCESS = 0; -const size_t ERROR_UNHANDLED_EXCEPTION = 2; -} // namespace - -int sc_main(int argc, char *argv[]) { - sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING ); - sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING); - /////////////////////////////////////////////////////////////////////////// - // CLI argument parsing - /////////////////////////////////////////////////////////////////////////// - po::options_description desc("Options"); - // clang-format off - desc.add_options() - ("help,h", "Print help message") - ("debug,d", "set debug level") - ("trace,t", "trace SystemC signals"); - // clang-format on - po::variables_map vm; - try { - po::store(po::parse_command_line(argc, argv, desc), vm); // can throw - // --help option - if (vm.count("help")) { - std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; - return SUCCESS; - } - po::notify(vm); // throws on error, so do after help in case - // there are any problems - } catch (po::error &e) { - std::cerr << "ERROR: " << e.what() << std::endl << std::endl; - std::cerr << desc << std::endl; - return ERROR_IN_COMMAND_LINE; - } - /////////////////////////////////////////////////////////////////////////// - // configure logging - /////////////////////////////////////////////////////////////////////////// - scc::init_logging(vm.count("debug")?scc::log::DEBUG:scc::log::INFO); - /////////////////////////////////////////////////////////////////////////// - // set up tracing & transaction recording - /////////////////////////////////////////////////////////////////////////// - tracer trace("simple_system", tracer::COMPRESSED, vm.count("trace")); - // todo: fix displayed clock period in VCD - - /////////////////////////////////////////////////////////////////////////// - // instantiate top level - /////////////////////////////////////////////////////////////////////////// - simple_system i_simple_system("i_simple_system"); - - /////////////////////////////////////////////////////////////////////////// - // run simulation - /////////////////////////////////////////////////////////////////////////// - sc_start(sc_core::sc_time(1, sc_core::SC_MS)); - // todo: provide end-of-simulation macros - - if (!sc_core::sc_end_of_simulation_invoked()) { - SCCERR() << "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 deleted file mode 100644 index 852d33f..0000000 --- a/examples/simple_system/simple_system.cpp +++ /dev/null @@ -1,87 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -//////////////////////////////////////////////////////////////////////////////// -/* - * simplesystem.cpp - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ - -#include "simple_system.h" - -namespace sysc { - -simple_system::simple_system(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, NAMED(i_master) -, NAMED(i_router, 4, 1) -, NAMED(i_uart) -, NAMED(i_spi) -, NAMED(i_gpio) -, NAMED(i_plic) -, NAMED(s_clk) -, NAMED(s_rst) -, NAMED(s_global_interrupts, 256) -, NAMED(s_core_interrupt) -, NAMED(s_gpio, 32) -{ - // todo: discuss naming conventions (s_ vs. _i/_o) --> covnert into _s - - // bus connections - i_master.intor(i_router.target[0]); - i_router.bind_target(i_plic.socket, 0, "plic"); - i_router.bind_target(i_uart.socket, 1, "uart"); - i_router.bind_target(i_spi.socket, 2, "spi"); - i_router.bind_target(i_gpio.socket, 3, "gpio"); - - // target address ranges - for (const auto &e : e300_plat_map) - i_router.add_target_range(e.name, e.start, e.size); - - // clock/reset connections - i_uart.clk_i(s_clk); - i_spi.clk_i(s_clk); - i_gpio.clk_i(s_clk); - i_plic.clk_i(s_clk); - s_clk.write(10_ns); - - i_uart.rst_i(s_rst); - i_spi.rst_i(s_rst); - i_gpio.rst_i(s_rst); - i_plic.rst_i(s_rst); - i_master.rst_i(s_rst); - - // interrupt connections - i_plic.core_interrupt_o(s_core_interrupt); - i_plic.global_interrupts_i.bind(s_global_interrupts); - i_master.global_interrupts_o(s_global_interrupts); - i_master.core_interrupt_i(s_core_interrupt); - - for(auto i=0U; i -#include -#include - -namespace sysc { - -class simple_system : public sc_core::sc_module { -public: - SC_HAS_PROCESS(simple_system); - - test_initiator i_master; - scc::router<> i_router; - uart i_uart; - spi i_spi; - gpio i_gpio; - plic i_plic; - sc_core::sc_signal s_clk; - sc_core::sc_signal 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); - -protected: - void gen_reset(); - -#include "gen/e300_plat_t.h" -}; - -} /* namespace sysc */ - -#endif /* SIMPLESYSTEM_H_ */ diff --git a/examples/simple_system/spi.cpp b/examples/simple_system/spi.cpp deleted file mode 100644 index 94e0e5c..0000000 --- a/examples/simple_system/spi.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -//////////////////////////////////////////////////////////////////////////////// - -#include "spi.h" -#include "gen/spi_regs.h" -#include "scc/utilities.h" - -namespace sysc { - -spi::spi(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, tlm_target<>(clk) -, NAMED(clk_i) -, NAMED(rst_i) -, NAMEDD(regs, spi_regs) { - regs->registerResources(*this); - SC_METHOD(clock_cb); - sensitive << clk_i; - SC_METHOD(reset_cb); - sensitive << rst_i; -} - -spi::~spi() {} // NOLINT - -void spi::clock_cb() { this->clk = clk_i.read(); } - -void spi::reset_cb() { - if (rst_i.read()) - regs->reset_start(); - else - regs->reset_stop(); -} - -} /* namespace sysc */ diff --git a/examples/simple_system/spi.h b/examples/simple_system/spi.h deleted file mode 100644 index b97fbf8..0000000 --- a/examples/simple_system/spi.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ - -#ifndef _SPI_H_ -#define _SPI_H_ - -#include - -namespace sysc { - -class spi_regs; - -class spi : public sc_core::sc_module, public scc::tlm_target<> { -public: - SC_HAS_PROCESS(spi); - sc_core::sc_in clk_i; - sc_core::sc_in rst_i; - spi(sc_core::sc_module_name nm); - virtual ~spi(); - -protected: - void clock_cb(); - void reset_cb(); - sc_core::sc_time clk; - std::unique_ptr regs; -}; - -} /* namespace sysc */ - -#endif /* _SPI_H_ */ diff --git a/examples/simple_system/test_initiator.cpp b/examples/simple_system/test_initiator.cpp deleted file mode 100644 index c2effde..0000000 --- a/examples/simple_system/test_initiator.cpp +++ /dev/null @@ -1,272 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -//////////////////////////////////////////////////////////////////////////////// -/* - * test_initiator.cpp - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ - -#include "test_initiator.h" -#include -#include -#include - -// todo: move into gen folder somewhere (adapt code-generator) -#define PLIC_PRIO1_REG 0x0C000004 -#define PLIC_PRIO2_REG 0x0C000008 -#define PLIC_PRIO3_REG 0x0C00000C -#define PLIC_PRIO4_REG 0x0C000010 -#define PLIC_PENDING_REG 0x0C001000 -#define PLIC_ENABLE_REG 0x0C002000 -#define PLIC_PRIO_TRESHOLD_REG 0x0C200000 -#define PLIC_CLAIM_COMPLETE_REG 0x0C200004 - -namespace sysc { -using namespace sc_core; - -test_initiator::test_initiator(sc_module_name nm) -: sc_module(nm) -, NAMED(intor) -, NAMED(rst_i) -, NAMED(global_interrupts_o, 256) -, NAMED(core_interrupt_i) { - SC_THREAD(run); - - SC_METHOD(core_irq_handler); - sensitive << core_interrupt_i; - dont_initialize(); -} - -void test_initiator::run() { - // wait for reset - if (rst_i.read() == false) wait(rst_i.posedge_event()); - wait(rst_i.negedge_event()); - wait(10_ns); - - // apply test-sequences - test_unique_irq(); - test_frequent_irq(); - test_parallel_irq(); - test_irq_stress(); - - // todo: review irq sequences from FW point of view ... expected ??? - wait(100_ns); - sc_stop(); -} - -void test_initiator::test_unique_irq() { - - //// enable reg is not set - // -> irq to be ignored - // -> no core_interrupt - // -> no entry in pending reg - - // generate interrupt pulse (note: 1 is lowest usable register) - global_interrupts_o[2].write(true); - wait(10_ns); - global_interrupts_o[2].write(false); - wait(10_ns); - - reg_check(PLIC_PENDING_REG, 0x0); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x0); - wait(10_ns); - - //// enable reg is set, then - // -> pending bit change expected - // -> core_interrupt expected - - read_bus(PLIC_PRIO1_REG); - wait(10_ns); - - // enable single interrupt - write_bus(PLIC_PRIO1_REG, 0x1); - wait(10_ns); - - write_bus(PLIC_ENABLE_REG, 0x2); - wait(10_ns); - - // generate interrupt pulse (note: 1 is lowest usable register) - global_interrupts_o[1].write(true); - wait(10_ns); - global_interrupts_o[1].write(false); - wait(10_ns); - - // read claim_complete register - reg_check(PLIC_PENDING_REG, 0x2); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x1); - wait(10_ns); - - //// after writing to claim_complete reg (per fw) - // -> pending bit expected to be unset - // -> enable bit expected to be set ... test with / without enable being set - write_bus(PLIC_CLAIM_COMPLETE_REG, 0x1); - wait(10_ns); - reg_check(PLIC_PENDING_REG, 0x0); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x0); - wait(10_ns); - - // todo: remove wait statements once the tlm_initiator is in place - // todo: evaluate error messages ... provide correct pass/fail verdict - - wait(100_ns); -} - -void test_initiator::test_frequent_irq() {} - -void test_initiator::test_parallel_irq() { - - //// create three parallel global_int requests - // -> read and clear bits one after the other - // -> different priorities applied (reverse order) - // -> correct priority handing expected - // -> three core interrupts expected in total - - // reverse order priority configuration - write_bus(PLIC_PRIO1_REG, 0x3); - wait(10_ns); - write_bus(PLIC_PRIO2_REG, 0x2); - wait(10_ns); - write_bus(PLIC_PRIO3_REG, 0x1); - wait(10_ns); - - // enable all three interrupts - write_bus(PLIC_ENABLE_REG, 0xE); - wait(10_ns); - - // generate interrupt pulse (note: 1 is lowest usable register) - global_interrupts_o[1].write(true); - wait(10_ns); - global_interrupts_o[1].write(false); - wait(10_ns); - global_interrupts_o[2].write(true); - wait(10_ns); - global_interrupts_o[2].write(false); - wait(10_ns); - global_interrupts_o[3].write(true); - wait(10_ns); - global_interrupts_o[3].write(false); - wait(10_ns); - - // expect three pending registers - reg_check(PLIC_PENDING_REG, 0xE); - wait(10_ns); - - // expect lowest interrupt id to be highest int - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x1); - wait(10_ns); - - //// after writing to claim_complete reg (per fw) - // -> next int to become highest irq - write_bus(PLIC_CLAIM_COMPLETE_REG, 0x1); - wait(10_ns); - reg_check(PLIC_PENDING_REG, 0xC); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x2); - wait(10_ns); - - //// after writing to claim_complete reg again (per fw) - // -> next int to become highest irq - write_bus(PLIC_CLAIM_COMPLETE_REG, 0x2); - wait(10_ns); - reg_check(PLIC_PENDING_REG, 0x8); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x3); - wait(10_ns); - - //// after last writing to claim_complete reg again (per fw) - // -> no further pending irq expected - write_bus(PLIC_CLAIM_COMPLETE_REG, 0x3); - wait(10_ns); - reg_check(PLIC_PENDING_REG, 0x0); - wait(10_ns); - reg_check(PLIC_CLAIM_COMPLETE_REG, 0x0); - wait(10_ns); - - // todo: advance upon register-write access ... remove above 10_ns waits - // todo: evaluate error messages ... provide correct pass/fail verdict - - wait(100_ns); -} - -void test_initiator::test_irq_stress() {} - -void test_initiator::write_bus(std::uint32_t adr, std::uint32_t dat) { - tlm::tlm_generic_payload gp; - std::array data; - data[3] = 0xff & dat >> 24; - data[2] = 0xff & dat >> 16; - data[1] = 0xff & dat >> 8; - data[0] = 0xff & dat; - - SCCDEBUG("test_initiator") << "write_bus(0x" << std::hex << adr << ") : " << dat; - - gp.set_command(tlm::TLM_WRITE_COMMAND); - gp.set_address(adr); - gp.set_data_ptr(data.data()); - gp.set_data_length(data.size()); - gp.set_streaming_width(4); - sc_time delay; - intor->b_transport(gp, delay); - - if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { - throw std::exception(); - } -} - -std::uint32_t test_initiator::read_bus(std::uint32_t adr) { - - tlm::tlm_generic_payload gp; - std::array data; - - gp.set_command(tlm::TLM_READ_COMMAND); - gp.set_address(adr); - gp.set_data_ptr(data.data()); - gp.set_data_length(data.size()); - gp.set_streaming_width(4); - sc_time delay; - intor->b_transport(gp, delay); - - if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { - // todo: improve output in case of exception, define own exception class to carry transaction-infos - // ... i.e. out-of-range report with info about legal mem boundaries - throw std::exception(); - } - - // todo: use reinterpret_cast instead - std::uint32_t rdat = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0]; - - SCCDEBUG("test_initiator") << "read_bus(0x" << std::hex << adr << ") -> " << rdat; - return rdat; -} - -void test_initiator::reg_check(std::uint32_t adr, std::uint32_t exp) { - uint32_t dat = read_bus(adr); - if (dat != exp) { - SCCERR("test_initiator") << "register check failed for address 0x" << std::hex << adr << ": " << dat << " != " << exp; - } else { - SCCDEBUG("test_initiator") << "register check passed for address 0x" << std::hex << adr << ": " << dat; - } -} - -void test_initiator::core_irq_handler() { - SCCDEBUG("test_initiator") << "core_interrupt_i edge detected -> " << core_interrupt_i.read(); -} - -} /* namespace sysc */ diff --git a/examples/simple_system/test_initiator.h b/examples/simple_system/test_initiator.h deleted file mode 100644 index ee69ace..0000000 --- a/examples/simple_system/test_initiator.h +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ -/* - * test_initiator.h - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ - -#ifndef _TEST_INITIATOR_H_ -#define _TEST_INITIATOR_H_ - -#include -#include - -namespace sysc { - -class test_initiator : public sc_core::sc_module { -public: - SC_HAS_PROCESS(test_initiator); - tlm_utils::simple_initiator_socket intor; - sc_core::sc_vector> global_interrupts_o; - sc_core::sc_in core_interrupt_i; - sc_core::sc_in rst_i; - test_initiator(sc_core::sc_module_name nm); - -protected: - void run(); - void test_unique_irq(); - void test_frequent_irq(); - void test_parallel_irq(); - void test_irq_stress(); - void write_bus(std::uint32_t adr, std::uint32_t dat); - std::uint32_t read_bus(std::uint32_t adr); - void reg_check(std::uint32_t adr, std::uint32_t exp); - - void core_irq_handler(); -}; - -} /* namespace sysc */ - -#endif /* _TEST_INITIATOR_H_ */ diff --git a/examples/simple_system/uart.cpp b/examples/simple_system/uart.cpp deleted file mode 100644 index e3f7995..0000000 --- a/examples/simple_system/uart.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -//////////////////////////////////////////////////////////////////////////////// - -#include "uart.h" -#include "gen/uart_regs.h" -#include "scc/utilities.h" - -namespace sysc { - -uart::uart(sc_core::sc_module_name nm) -: sc_core::sc_module(nm) -, tlm_target<>(clk) -, NAMED(clk_i) -, NAMED(rst_i) -, NAMEDD(regs, uart_regs) { - regs->registerResources(*this); - SC_METHOD(clock_cb); - sensitive << clk_i; - SC_METHOD(reset_cb); - sensitive << rst_i; -} - -uart::~uart() {} // NOLINT - -void uart::clock_cb() { this->clk = clk_i.read(); } - -void uart::reset_cb() { - if (rst_i.read()) - regs->reset_start(); - else - regs->reset_stop(); -} - -} /* namespace sysc */ diff --git a/examples/simple_system/uart.h b/examples/simple_system/uart.h deleted file mode 100644 index 3725003..0000000 --- a/examples/simple_system/uart.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ - -#ifndef _UART_H_ -#define _UART_H_ - -#include - -namespace sysc { - -class uart_regs; - -class uart : public sc_core::sc_module, public scc::tlm_target<> { -public: - SC_HAS_PROCESS(uart); - sc_core::sc_in clk_i; - sc_core::sc_in rst_i; - uart(sc_core::sc_module_name nm); - virtual ~uart(); - -protected: - void clock_cb(); - void reset_cb(); - sc_core::sc_time clk; - std::unique_ptr regs; -}; - -} /* namespace sysc */ - -#endif /* _UART_H_ */ diff --git a/examples/transaction_recording/CMakeLists.txt b/examples/transaction_recording/CMakeLists.txt deleted file mode 100644 index 42f8db7..0000000 --- a/examples/transaction_recording/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -add_executable (transaction_recording - scv_tr_recording_example.cpp -) -target_link_libraries (transaction_recording LINK_PUBLIC scc) - -add_test(NAME tx_rec_test COMMAND transaction_recording) \ No newline at end of file diff --git a/examples/transaction_recording/scv_tr_recording_example.cpp b/examples/transaction_recording/scv_tr_recording_example.cpp deleted file mode 100644 index 7535acc..0000000 --- a/examples/transaction_recording/scv_tr_recording_example.cpp +++ /dev/null @@ -1,406 +0,0 @@ -// -*- C++ -*- -/***************************************************************************** - - The following code is derived, directly or indirectly, from the SystemC - source code Copyright (c) 1996-2014 by all Contributors. - All Rights reserved. - - The contents of this file are subject to the restrictions and limitations - set forth in the SystemC Open Source License (the "License"); - You may not use this file except in compliance with such restrictions and - limitations. You may obtain instructions on how to receive a copy of the - License at http://www.accellera.org/. Software distributed by Contributors - under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF - ANY KIND, either express or implied. See the License for the specific - language governing rights and limitations under the License. - - *****************************************************************************/ -#include "scv.h" -#include "scc/scv_tr_db.h" -#include "scc/report.h" -#include "scc/value_registry.h" -#include - -// text 11308µs/11602µs -// compressed 10365µs/ 9860µs -// binary 13233µs/10698µs -// SQLite 30363µs/30018µs -// LeveDB 23898µs/22367µs - -// hack to fake a true fifo_mutex -#define fifo_mutex sc_mutex - -const unsigned ram_size = 256; - -class rw_task_if : virtual public sc_interface { -public: - using addr_t = sc_uint<8>; - using data_t = sc_uint<8>; - struct write_t { - addr_t addr; - data_t data; - }; - - virtual data_t read(const addr_t *) = 0; - virtual void write(const write_t *) = 0; -}; - -SCV_EXTENSIONS(rw_task_if::write_t) { -public: - scv_extensions addr; - scv_extensions data; - SCV_EXTENSIONS_CTOR(rw_task_if::write_t) { - SCV_FIELD(addr); - SCV_FIELD(data); - } -}; - -class pipelined_bus_ports : public sc_module { -public: - sc_in clk; - sc_inout rw; - sc_inout addr_req; - sc_inout addr_ack; - sc_inout> bus_addr; - sc_inout data_rdy; - sc_inout> bus_data; - - SC_CTOR(pipelined_bus_ports) - : clk("clk") - , rw("rw") - , addr_req("addr_req") - , addr_ack("addr_ack") - , bus_addr("bus_addr") - , data_rdy("data_rdy") - , bus_data("bus_data") {} - void trace(sc_trace_file *tf) const override; -}; - -void pipelined_bus_ports::trace(sc_trace_file *tf) const { - sc_trace(tf, clk, clk.name()); - sc_trace(tf, rw, rw.name()); - sc_trace(tf, addr_req, addr_req.name()); - sc_trace(tf, addr_ack, addr_ack.name()); - sc_trace(tf, bus_addr, bus_addr.name()); - sc_trace(tf, data_rdy, data_rdy.name()); - sc_trace(tf, bus_data, bus_data.name()); -} - -class rw_pipelined_transactor : public rw_task_if, public pipelined_bus_ports { - - fifo_mutex addr_phase; - fifo_mutex data_phase; - - scv_tr_stream pipelined_stream; - scv_tr_stream addr_stream; - scv_tr_stream data_stream; - scv_tr_generator, sc_uint<8>> read_gen; - scv_tr_generator, sc_uint<8>> write_gen; - scv_tr_generator> addr_gen; - scv_tr_generator<_scv_tr_generator_default_data, sc_uint<8>> rdata_gen; - scv_tr_generator> wdata_gen; - -public: - rw_pipelined_transactor(sc_module_name nm) - : pipelined_bus_ports(nm) - , addr_phase("addr_phase") - , data_phase("data_phase") - , pipelined_stream((std::string(name()) + ".pipelined_stream").c_str(), "transactor") - , addr_stream((std::string(name()) + ".addr_stream").c_str(), "transactor") - , data_stream((std::string(name()) + ".data_stream").c_str(), "transactor") - , read_gen("read", pipelined_stream, "addr", "data") - , write_gen("write", pipelined_stream, "addr", "data") - , addr_gen("addr", addr_stream, "addr") - , rdata_gen("rdata", data_stream, nullptr, "data") - , wdata_gen("wdata", data_stream, "data") {} - data_t read(const addr_t *p_addr) override; - void write(const write_t *req) override; -}; - -rw_task_if::data_t rw_pipelined_transactor::read(const addr_t *addr) { - addr_phase.lock(); - scv_tr_handle h = read_gen.begin_transaction(*addr); - h.record_attribute("data_size", sizeof(data_t)); - scv_tr_handle h1 = addr_gen.begin_transaction(*addr, "addr_phase", h); - wait(clk->posedge_event()); - bus_addr = *addr; - rw = false; - addr_req = true; - wait(addr_ack->posedge_event()); - wait(clk->negedge_event()); - addr_req = false; - wait(addr_ack->negedge_event()); - addr_gen.end_transaction(h1); - addr_phase.unlock(); - - data_phase.lock(); - scv_tr_handle h2 = rdata_gen.begin_transaction("data_phase", h); - wait(data_rdy->posedge_event()); - data_t data = bus_data.read(); - wait(data_rdy->negedge_event()); - rdata_gen.end_transaction(h2, data); - read_gen.end_transaction(h, data); - data_phase.unlock(); - - return data; -} - -void rw_pipelined_transactor::write(const write_t *req) { - addr_phase.lock(); - scv_tr_handle h = write_gen.begin_transaction(req->addr); - h.record_attribute("data_size", sizeof(data_t)); - scv_tr_handle h1 = addr_gen.begin_transaction(req->addr, "addr_phase", h); - wait(clk->posedge_event()); - bus_addr = req->addr; - rw = true; - addr_req = true; - wait(addr_ack->posedge_event()); - wait(clk->negedge_event()); - addr_req = false; - wait(addr_ack->negedge_event()); - addr_gen.end_transaction(h1); - addr_phase.unlock(); - - data_phase.lock(); - scv_tr_handle h2 = wdata_gen.begin_transaction(req->data, "data_phase", h); - bus_data = req->data; - wait(data_rdy->posedge_event()); - wait(data_rdy->negedge_event()); - wdata_gen.end_transaction(h2); - write_gen.end_transaction(h, req->data); - data_phase.unlock(); -} - -class test : public sc_module { -public: - sc_port transactor; - SC_HAS_PROCESS(test); - test(::sc_core::sc_module_name) { - SC_THREAD(main1); - SC_THREAD(main2); - } - void main1(); - void main2(); -}; - -class write_constraint : virtual public scv_constraint_base { -public: - scv_smart_ptr write; - SCV_CONSTRAINT_CTOR(write_constraint) { // NOLINT - SCV_CONSTRAINT(write->addr() <= ram_size); // NOLINT - SCV_CONSTRAINT(write->addr() != write->data()); // NOLINT - } -}; - -inline void process(scv_smart_ptr data) {} - -inline void test::main1() { - // simple sequential tests - for (int i = 0; i < 3; i++) { - rw_task_if::addr_t addr = i; - rw_task_if::data_t data = transactor->read(&addr); - SCCINFO(sc_get_current_object()->name()) << "received data : " << data; - } - - scv_smart_ptr addr; - for (int i = 0; i < 3; i++) { - - addr->next(); - rw_task_if::data_t data = transactor->read(addr->get_instance()); - SCCINFO(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()); - SCCINFO(sc_get_current_object()->name()) << "send data : " << write->data; - } - - scv_smart_ptr data; - scv_bag distribution; - distribution.push(1, 40); - distribution.push(2, 60); - data->set_mode(distribution); - for (int i = 0; i < 3; i++) { - data->next(); - process(data); - } -} - -inline void test::main2() { - // simple sequential tests - for (int i = 0; i < 3; i++) { - rw_task_if::addr_t addr = i; - rw_task_if::data_t data = transactor->read(&addr); - SCCINFO(sc_get_current_object()->name()) << "received data : " << data; - } - - scv_smart_ptr addr; - for (int i = 0; i < 3; i++) { - - addr->next(); - rw_task_if::data_t data = transactor->read(addr->get_instance()); - SCCINFO(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()); - SCCINFO(sc_get_current_object()->name()) << "send data : " << write->data; - } - - scv_smart_ptr data; - scv_bag distribution; - distribution.push(1, 140); - distribution.push(2, 160); - data->set_mode(distribution); - for (int i = 0; i < 3; i++) { - data->next(); - process(data); - } -} -class design : public pipelined_bus_ports { - std::list> outstandingAddresses; - std::list outstandingType; - sc_uint<8> memory[ram_size]; - -public: - SC_HAS_PROCESS(design); - design(sc_module_name nm) - : pipelined_bus_ports(nm) { - for (unsigned i = 0; i < ram_size; ++i) { - memory[i] = i; - } - SC_THREAD(addr_phase); - SC_THREAD(data_phase); - } - void addr_phase(); - void data_phase(); -}; - -inline void design::addr_phase() { - while (true) { - while (addr_req.read() != 1) { - wait(addr_req->value_changed_event()); - } - sc_uint<8> _addr = bus_addr.read(); - bool _rw = rw.read(); - - int cycle = rand() % 10 + 1; - while (cycle-- > 0) { - wait(clk->posedge_event()); - } - - addr_ack = true; - wait(clk->posedge_event()); - addr_ack = false; - - outstandingAddresses.push_back(_addr); - outstandingType.push_back(_rw); - SCCINFO(sc_get_current_object()->name()) << "received request for memory address " << _addr; - } -} - -inline void design::data_phase() { - while (true) { - while (outstandingAddresses.empty()) { - wait(clk->posedge_event()); - } - int cycle = rand() % 10 + 1; - while (cycle-- > 0) { - wait(clk->posedge_event()); - } - if (outstandingType.front() == false) { - SCCINFO(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 = true; - wait(clk->posedge_event()); - data_rdy = false; - - } else { - SCCINFO(sc_get_current_object()->name()) << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data; - memory[outstandingAddresses.front().to_ulong()] = bus_data; - data_rdy = true; - wait(clk->posedge_event()); - data_rdy = false; - } - outstandingAddresses.pop_front(); - outstandingType.pop_front(); - } -} - -inline const char* init_db(char type){ - switch(type){ - case '2': - scv_tr_compressed_init(); - return "my_db.txlog"; - break; - case '3': - scv_tr_sqlite_init(); - return "my_db.txdb"; - break; - default: - scv_tr_text_init(); - return "my_db.txlog"; - break; - } -} - -int sc_main(int argc, char *argv[]) { - auto start = std::chrono::system_clock::now(); - scv_startup(); - scc::init_logging(scc::LogConfig().logLevel(scc::log::DEBUG)); - const char *fileName = argc==2? init_db(argv[1][0]): "my_db.txlog"; - if(argc<2) scv_tr_text_init(); - scv_tr_db db(fileName); - scv_tr_db::set_default_db(&db); - sc_trace_file *tf = sc_create_vcd_trace_file("my_db"); - // create signals - sc_clock clk("clk", 20.0, SC_NS, 0.5, 0.0, SC_NS, true); - sc_signal rw; - sc_signal addr_req; - sc_signal addr_ack; - sc_signal> bus_addr; - sc_signal data_rdy; - sc_signal> bus_data; - - scc::value_registry registry; - // create modules/channels - test t("t"); - rw_pipelined_transactor tr("tr"); - design duv("duv"); - - // connect them up - t.transactor(tr); - - tr.clk(clk); - tr.rw(rw); - tr.addr_req(addr_req); - tr.addr_ack(addr_ack); - tr.bus_addr(bus_addr); - tr.data_rdy(data_rdy); - tr.bus_data(bus_data); - tr.trace(tf); - - duv.clk(clk); - duv.rw(rw); - duv.addr_req(addr_req); - duv.addr_ack(addr_ack); - duv.bus_addr(bus_addr); - duv.data_rdy(data_rdy); - duv.bus_data(bus_data); - duv.trace(tf); - - // Accellera SystemC >=2.2 got picky about multiple drivers. - // 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(10.0, SC_US); - sc_close_vcd_trace_file(tf); - auto int_us = std::chrono::duration_cast(std::chrono::system_clock::now()-start); - SCCINFO() << "simulation duration "< + +auto factory::get_instance() -> factory& { + static factory instance{}; + return instance; +} + +factory::factory() : + m_constructors{}, + m_objects{} +{ } + +void factory::create() { + for (const auto& item : m_constructors) { + m_objects[item.first] = item.second(); + } +} + +void factory::destroy() { + m_objects.clear(); +} + +void factory::add_object(const std::string& name, constructor create) { + auto it = m_constructors.find(name); + + if (it == m_constructors.cend()) { + m_constructors[name] = create; + } + else { + throw std::runtime_error("factory::add(): " + + name + " object already exist in factory"); + } +} + +auto factory::get_object(const std::string& name) -> void* { + auto it = m_objects.find(name); + + if (it == m_objects.cend()) { + throw std::runtime_error("factory::get(): " + + name + " object doesn't exist in factory"); + } + + return it->second.get(); +} diff --git a/src/factory.h b/src/factory.h new file mode 100644 index 0000000..7184037 --- /dev/null +++ b/src/factory.h @@ -0,0 +1,78 @@ +/* + * according to https://forums.accellera.org/topic/5754-unit-testing-with-gtest/ + * factory.h + * + * Created on: Oct 1, 2022 + * Author: eyck + */ + +#ifndef SRC_FACTORY_H_ +#define SRC_FACTORY_H_ + +#include +#include +#include +#include + +class factory { +public: + static factory& get_instance(); + + template + class add { + public: + add(Args&&... args); + + add(const std::string& name, Args&&... args); + }; + + template + static T& get(const std::string& name = ""); + + void create(); + + void destroy(); +private: + using destructor = std::function; + using object = std::unique_ptr; + using constructor = std::function; + + factory(); + + factory(const factory& other) = delete; + + factory& operator=(const factory& other) = delete; + + void add_object(const std::string& name, constructor create); + + void* get_object(const std::string& name); + + std::map m_constructors; + std::map m_objects; +}; + +template +factory::add::add(Args&&... args) { + add("", args...); +} + +template +factory::add::add(const std::string& name, Args&&... args) { + factory::get_instance().add_object(name, + [args...] () -> object { + return object{ + new T(std::forward(args)...), + [] (void* obj) { + delete static_cast(obj); + } + }; + } + ); +} + +template auto +factory::get(const std::string& name) -> T& { + return *static_cast(factory::get_instance().get_object(name)); +} + +#endif /* SRC_FACTORY_H_ */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dc55372..4310a6b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(io-redirector) add_subdirectory(sim_performance) add_subdirectory(ordered_semaphore) +add_subdirectory(axi4_pin_level) diff --git a/tests/axi4_pin_level/CMakeLists.txt b/tests/axi4_pin_level/CMakeLists.txt new file mode 100644 index 0000000..368643e --- /dev/null +++ b/tests/axi4_pin_level/CMakeLists.txt @@ -0,0 +1,9 @@ +project (axi4_pin_level) + +add_executable(${PROJECT_NAME} + sc_main.cpp + narrow_burst_test.cpp +) +target_link_libraries (${PROJECT_NAME} PUBLIC scc test_util Catch2::Catch2) + +add_test(NAME narrow_burst COMMAND ${PROJECT_NAME}) \ No newline at end of file diff --git a/tests/axi4_pin_level/narrow_burst_test.cpp b/tests/axi4_pin_level/narrow_burst_test.cpp new file mode 100644 index 0000000..69872c3 --- /dev/null +++ b/tests/axi4_pin_level/narrow_burst_test.cpp @@ -0,0 +1,119 @@ + +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "../axi4_pin_level/testbench.h" +#include + +#include + +using namespace sc_core; + +template +tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, size_t len, unsigned id_offs = 0, + unsigned addr_offs = 0) { + static uint8_t id{0}; + auto trans = tlm::scc::tlm_mm<>::get().allocate(len); + trans->set_address(start_address); + tlm::scc::setId(*trans, id); + auto ext = trans->get_extension(); + trans->set_data_length(len); + trans->set_streaming_width(len); + ext->set_size(scc::ilog2(4)); + sc_assert(len < (bus_cfg::BUSWIDTH / 8) || len % (bus_cfg::BUSWIDTH / 8) == 0); + auto length = (len * 8 - 1) / 32; + if(start_address % (bus_cfg::BUSWIDTH / 8)) + length++; + ext->set_length(length); + // ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED); + ext->set_burst(axi::burst_e::INCR); + ext->set_id(id | id_offs); + id = (id + 1) % 8; + return trans; +} + +inline void randomize(tlm::tlm_generic_payload& gp) { + static uint8_t req_cnt{0}; + auto addr = gp.get_address(); + uint8_t const* src = reinterpret_cast(&addr); + for(size_t i = 0; i < gp.get_data_length(); ++i) { + *(gp.get_data_ptr() + i) = i % 2 ? i : req_cnt; + } + req_cnt++; +} + +TEST_CASE("AXI", "[axi]") { + struct { + unsigned int ResetCycles{10}; + unsigned int BurstLengthByte{16}; + unsigned int NumberOfIterations{10}; + unsigned resp_cnt{0}; + } setup; + + auto& dut = factory::get(); + dut.tgt_pe.set_operation_cb([&setup](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned { + auto addr = trans.get_address(); + uint8_t const* src = reinterpret_cast(&addr); + for(size_t i = 0; i < trans.get_data_length(); ++i) { + *(trans.get_data_ptr() + i) = i % 2 ? i : setup.resp_cnt; + } + setup.resp_cnt++; + return 0; + }); + + dut.rst.write(false); + sc_start(3*dut.clk.period()); + dut.rst.write(true); + sc_start(3*dut.clk.period()); + + auto run1 = sc_spawn([&dut, &setup](){ + unsigned int StartAddr{0x20}; + for(int i = 0; i < setup.NumberOfIterations; ++i) { + SCCDEBUG("test") << "run0 executing transactions in iteration " << i; + { // 1 + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte); + randomize(*trans); + trans->set_command(tlm::TLM_READ_COMMAND); + dut.intor_pe.transport(*trans, false); + if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) + SCCERR() << "Invalid response status" << trans->get_response_string(); + } + StartAddr += setup.BurstLengthByte; + { // 2 + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte); + trans->set_command(tlm::TLM_WRITE_COMMAND); + randomize(*trans); + dut.intor_pe.transport(*trans, false); + if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) + SCCERR() << "Invalid response status" << trans->get_response_string(); + } + StartAddr += setup.BurstLengthByte; + } + }); + auto run2 = sc_spawn([&dut, &setup](){ + unsigned int StartAddr{0x1020}; + for(int i = 0; i < setup.NumberOfIterations; ++i) { + SCCDEBUG("test") << "run1 executing transactions in iteration " << i; + { // 1 + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte, 0x8); + randomize(*trans); + trans->set_command(tlm::TLM_READ_COMMAND); + dut.intor_pe.transport(*trans, false); + if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) + SCCERR() << "Invalid response status" << trans->get_response_string(); + } + StartAddr += setup.BurstLengthByte; + { // 2 + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte, 0x8); + trans->set_command(tlm::TLM_WRITE_COMMAND); + randomize(*trans); + dut.intor_pe.transport(*trans, false); + if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) + SCCERR() << "Invalid response status" << trans->get_response_string(); + } + StartAddr += setup.BurstLengthByte; + } + }); + sc_start(1000 * dut.clk.period()); + REQUIRE(run1.terminated()); + REQUIRE(run2.terminated()); + REQUIRE(setup.resp_cnt==40); +} diff --git a/tests/axi4_pin_level/sc_main.cpp b/tests/axi4_pin_level/sc_main.cpp new file mode 100644 index 0000000..cb38fd8 --- /dev/null +++ b/tests/axi4_pin_level/sc_main.cpp @@ -0,0 +1,25 @@ +/* + * sc_main.cpp + * + * Created on: + * Author: + */ + +#include "factory.h" +#include +#include "../axi4_pin_level/testbench.h" + +using namespace scc; +int sc_main(int argc, char* argv[]) { + sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); + scc::init_logging(LogConfig().logLevel(log::INFO).logAsync(false)); + scc::tracer trace("axi4_tlm_pin_tlm", scc::tracer::file_type::NONE, true); + + factory::add tb; + + factory::get_instance().create(); + int result = Catch::Session().run( argc, argv ); + factory::get_instance().destroy(); + + return result + sc_report_handler::get_count(SC_ERROR) + sc_report_handler::get_count(SC_WARNING); +} diff --git a/tests/axi4_pin_level/testbench.h b/tests/axi4_pin_level/testbench.h new file mode 100644 index 0000000..bfad95b --- /dev/null +++ b/tests/axi4_pin_level/testbench.h @@ -0,0 +1,78 @@ +#ifndef _TESTBENCH_H_ +#define _TESTBENCH_H_ + +#include +#include +#include +#include +#include +#include + +using namespace sc_core; +using namespace axi; +using namespace axi::pe; + +class testbench : public sc_core::sc_module { +public: + using bus_cfg = axi::axi4_cfg; + + sc_core::sc_time clk_period{10, sc_core::SC_NS}; + sc_core::sc_clock clk{"clk", clk_period, 0.5, sc_core::SC_ZERO_TIME, true}; + sc_core::sc_signal rst{"rst"}; + // initiator side + axi::axi_initiator_socket intor{"intor"}; + axi::scv::axi_recorder_module intor_rec{"intor_rec"}; + axi::pin::axi4_initiator intor_bfm{"intor_bfm"}; + // signal accurate bus + axi::aw_ch aw; + axi::wdata_ch wdata; + axi::b_ch b; + axi::ar_ch ar; + axi::rresp_ch rresp; + axi::pin::axi4_target tgt_bfm{"tgt_bfm"}; + // target side + axi::scv::axi_recorder_module tgt_rec{"tgt_rec"}; + axi::axi_target_socket tgt{"tgt"}; + // engines + axi::pe::axi_initiator intor_pe; + axi::pe::simple_target tgt_pe; + +public: + SC_HAS_PROCESS(testbench); + testbench(): testbench("testbench") {} + testbench(sc_core::sc_module_name nm) + : sc_core::sc_module(nm) + , intor_pe("intor_pe", intor) + , tgt_pe("tgt_pe", tgt) { + intor_pe.clk_i(clk); + intor_bfm.clk_i(clk); + tgt_bfm.clk_i(clk); + tgt_pe.clk_i(clk); + // pe socket to recorder + intor(intor_rec.tsckt); + // recorder to bfm + intor_rec.isckt(intor_bfm.tsckt); + // bfm to signals + intor_bfm.bind_aw(aw); + intor_bfm.bind_w(wdata); + intor_bfm.bind_b(b); + intor_bfm.bind_ar(ar); + intor_bfm.bind_r(rresp); + // signals to bfm + tgt_bfm.bind_aw(aw); + tgt_bfm.bind_w(wdata); + tgt_bfm.bind_b(b); + tgt_bfm.bind_ar(ar); + tgt_bfm.bind_r(rresp); + // bfm to recorder + tgt_bfm.isckt(tgt_rec.tsckt); + // recorder to target + tgt_rec.isckt(tgt); + } + + + void run1() { + } +}; + +#endif // _TESTBENCH_H_