Added clang format
This commit is contained in:
		| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -15,12 +15,13 @@ | ||||
|  ******************************************************************************/ | ||||
| #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 | ||||
| // need double braces, see | ||||
| // https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 | ||||
| const std::array<sysc::target_memory_map_entry<32>, 4> e300_plat_map = {{ | ||||
|     {&i_plic, 0x0c000000, 0x200008}, | ||||
|     {&i_gpio, 0x10012000, 0x1000}, | ||||
|     {&i_uart, 0x10013000, 0x1000}, | ||||
|     {&i_spi,  0x10014000, 0x1000}, | ||||
|     {&i_spi, 0x10014000, 0x1000}, | ||||
| }}; | ||||
|  | ||||
| #endif /* _E300_PLAT_MAP_H_ */ | ||||
|   | ||||
| @@ -36,53 +36,50 @@ | ||||
| #ifndef _GPIO_REGS_H_ | ||||
| #define _GPIO_REGS_H_ | ||||
|  | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include <sysc/register.h> | ||||
| #include <sysc/tlm_target.h> | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class gpio_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public sysc::resetable | ||||
| { | ||||
| class gpio_regs : public sc_core::sc_module, public sysc::resetable { | ||||
| protected: | ||||
|     // 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 | ||||
|     sysc::sc_register<uint32_t> value; | ||||
|     sysc::sc_register<uint32_t> input_en; | ||||
| @@ -101,12 +98,11 @@ protected: | ||||
|     sysc::sc_register<uint32_t> iof_en; | ||||
|     sysc::sc_register<uint32_t> iof_sel; | ||||
|     sysc::sc_register<uint32_t> out_xor; | ||||
|      | ||||
|  | ||||
| public: | ||||
|     gpio_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(sysc::tlm_target<BUSWIDTH>& target); | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -131,12 +127,9 @@ inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm) | ||||
| , 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) | ||||
| { | ||||
| } | ||||
| , NAMED(out_xor, r_out_xor, 0, *this) {} | ||||
|  | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::gpio_regs::registerResources(sysc::tlm_target<BUSWIDTH>& target) { | ||||
| template <unsigned BUSWIDTH> inline void sysc::gpio_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||
|     target.addResource(value, 0x0UL); | ||||
|     target.addResource(input_en, 0x4UL); | ||||
|     target.addResource(output_en, 0x8UL); | ||||
|   | ||||
| @@ -36,45 +36,41 @@ | ||||
| #ifndef _PLIC_REGS_H_ | ||||
| #define _PLIC_REGS_H_ | ||||
|  | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include <sysc/register.h> | ||||
| #include <sysc/tlm_target.h> | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class plic_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public sysc::resetable | ||||
| { | ||||
| class plic_regs : public sc_core::sc_module, public sysc::resetable { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(priority_t, uint32_t); | ||||
|         BF_FIELD(priority, 0, 3); | ||||
|     END_BF_DECL() ; | ||||
|     BF_FIELD(priority, 0, 3); | ||||
|     END_BF_DECL(); | ||||
|     std::array<priority_t, 255> r_priority; | ||||
|      | ||||
|  | ||||
|     uint32_t r_pending; | ||||
|      | ||||
|  | ||||
|     uint32_t r_enabled; | ||||
|      | ||||
|  | ||||
|     BEGIN_BF_DECL(threshold_t, uint32_t); | ||||
|         BF_FIELD(threshold, 0, 3); | ||||
|     BF_FIELD(threshold, 0, 3); | ||||
|     END_BF_DECL() r_threshold; | ||||
|      | ||||
|  | ||||
|     uint32_t r_claim_complete; | ||||
|      | ||||
|  | ||||
|     // register declarations | ||||
|     sysc::sc_register_indexed<priority_t, 255> priority; | ||||
|     sysc::sc_register<uint32_t> pending; | ||||
|     sysc::sc_register<uint32_t> enabled; | ||||
|     sysc::sc_register<threshold_t> threshold; | ||||
|     sysc::sc_register<uint32_t> claim_complete; | ||||
|      | ||||
|  | ||||
|     plic_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(sysc::tlm_target<BUSWIDTH>& target); | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -87,12 +83,9 @@ inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm) | ||||
| , 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) | ||||
| { | ||||
| } | ||||
| , NAMED(claim_complete, r_claim_complete, 0, *this) {} | ||||
|  | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::plic_regs::registerResources(sysc::tlm_target<BUSWIDTH>& target) { | ||||
| template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||
|     target.addResource(priority, 0x4UL); | ||||
|     target.addResource(pending, 0x1000UL); | ||||
|     target.addResource(enabled, 0x2000UL); | ||||
|   | ||||
| @@ -36,96 +36,93 @@ | ||||
| #ifndef _SPI_REGS_H_ | ||||
| #define _SPI_REGS_H_ | ||||
|  | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include <sysc/register.h> | ||||
| #include <sysc/tlm_target.h> | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class spi_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public sysc::resetable | ||||
| { | ||||
| class spi_regs : public sc_core::sc_module, public sysc::resetable { | ||||
| protected: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(sckdiv_t, uint32_t); | ||||
|         BF_FIELD(div, 0, 12); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     BF_FIELD(txmark, 0, 3); | ||||
|     END_BF_DECL() r_txmark; | ||||
|      | ||||
|  | ||||
|     BEGIN_BF_DECL(rxmark_t, uint32_t); | ||||
|         BF_FIELD(rxmark, 0, 3); | ||||
|     BF_FIELD(rxmark, 0, 3); | ||||
|     END_BF_DECL() r_rxmark; | ||||
|      | ||||
|  | ||||
|     BEGIN_BF_DECL(fctrl_t, uint32_t); | ||||
|         BF_FIELD(en, 0, 1); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     BF_FIELD(txwm, 0, 1); | ||||
|     BF_FIELD(rxwm, 1, 1); | ||||
|     END_BF_DECL() r_ip; | ||||
|      | ||||
|  | ||||
|     // register declarations | ||||
|     sysc::sc_register<sckdiv_t> sckdiv; | ||||
|     sysc::sc_register<sckmode_t> sckmode; | ||||
| @@ -143,12 +140,11 @@ protected: | ||||
|     sysc::sc_register<ffmt_t> ffmt; | ||||
|     sysc::sc_register<ie_t> ie; | ||||
|     sysc::sc_register<ip_t> ip; | ||||
|      | ||||
|  | ||||
| public: | ||||
|     spi_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(sysc::tlm_target<BUSWIDTH>& target); | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -172,12 +168,9 @@ inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(fctrl, r_fctrl, 0, *this) | ||||
| , NAMED(ffmt, r_ffmt, 0, *this) | ||||
| , NAMED(ie, r_ie, 0, *this) | ||||
| , NAMED(ip, r_ip, 0, *this) | ||||
| { | ||||
| } | ||||
| , NAMED(ip, r_ip, 0, *this) {} | ||||
|  | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::spi_regs::registerResources(sysc::tlm_target<BUSWIDTH>& target) { | ||||
| template <unsigned BUSWIDTH> inline void sysc::spi_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||
|     target.addResource(sckdiv, 0x0UL); | ||||
|     target.addResource(sckmode, 0x4UL); | ||||
|     target.addResource(csid, 0x10UL); | ||||
|   | ||||
| @@ -36,56 +36,53 @@ | ||||
| #ifndef _UART_REGS_H_ | ||||
| #define _UART_REGS_H_ | ||||
|  | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include <sysc/register.h> | ||||
| #include <sysc/tlm_target.h> | ||||
| #include <sysc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class uart_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public sysc::resetable | ||||
| { | ||||
| class uart_regs : public sc_core::sc_module, public sysc::resetable { | ||||
| protected: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(txdata_t, uint32_t); | ||||
|         BF_FIELD(data, 0, 8); | ||||
|         BF_FIELD(full, 31, 1); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     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); | ||||
|     BF_FIELD(div, 0, 16); | ||||
|     END_BF_DECL() r_div; | ||||
|      | ||||
|  | ||||
|     // register declarations | ||||
|     sysc::sc_register<txdata_t> txdata; | ||||
|     sysc::sc_register<rxdata_t> rxdata; | ||||
| @@ -94,12 +91,11 @@ protected: | ||||
|     sysc::sc_register<ie_t> ie; | ||||
|     sysc::sc_register<ip_t> ip; | ||||
|     sysc::sc_register<div_t> div; | ||||
|      | ||||
|  | ||||
| public: | ||||
|     uart_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(sysc::tlm_target<BUSWIDTH>& target); | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -114,12 +110,9 @@ inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(rxctrl, r_rxctrl, 0, *this) | ||||
| , NAMED(ie, r_ie, 0, *this) | ||||
| , NAMED(ip, r_ip, 0, *this) | ||||
| , NAMED(div, r_div, 0, *this) | ||||
| { | ||||
| } | ||||
| , NAMED(div, r_div, 0, *this) {} | ||||
|  | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::uart_regs::registerResources(sysc::tlm_target<BUSWIDTH>& target) { | ||||
| template <unsigned BUSWIDTH> inline void sysc::uart_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||
|     target.addResource(txdata, 0x0UL); | ||||
|     target.addResource(rxdata, 0x4UL); | ||||
|     target.addResource(txctrl, 0x8UL); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -25,23 +25,20 @@ gpio::gpio(sc_core::sc_module_name nm) | ||||
| , tlm_target<>(clk) | ||||
| , NAMED(clk_i) | ||||
| , NAMED(rst_i) | ||||
| , NAMEDD(gpio_regs, regs) | ||||
| { | ||||
| , NAMEDD(gpio_regs, regs) { | ||||
|     regs->registerResources(*this); | ||||
|     SC_METHOD(clock_cb); | ||||
|     sensitive<<clk_i; | ||||
|     sensitive << clk_i; | ||||
|     SC_METHOD(reset_cb); | ||||
|     sensitive<<rst_i; | ||||
|     sensitive << rst_i; | ||||
| } | ||||
|  | ||||
| gpio::~gpio() { | ||||
| } | ||||
| gpio::~gpio() {} | ||||
|  | ||||
| void gpio::clock_cb() { | ||||
| } | ||||
| void gpio::clock_cb() {} | ||||
|  | ||||
| void gpio::reset_cb() { | ||||
|     if(rst_i.read()) | ||||
|     if (rst_i.read()) | ||||
|         regs->reset_start(); | ||||
|     else | ||||
|         regs->reset_stop(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -23,13 +23,14 @@ namespace sysc { | ||||
|  | ||||
| class gpio_regs; | ||||
|  | ||||
| class gpio: public sc_core::sc_module, public tlm_target<> { | ||||
| class gpio : public sc_core::sc_module, public tlm_target<> { | ||||
| public: | ||||
|     SC_HAS_PROCESS(gpio); | ||||
|     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||
|     sc_core::sc_in<bool>             rst_i; | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|     gpio(sc_core::sc_module_name nm); | ||||
|     virtual ~gpio(); | ||||
|  | ||||
| protected: | ||||
|     void clock_cb(); | ||||
|     void reset_cb(); | ||||
|   | ||||
| @@ -54,48 +54,40 @@ plic::plic(sc_core::sc_module_name nm) | ||||
|  | ||||
| { | ||||
|     regs->registerResources(*this); | ||||
| 	// register callbacks | ||||
| 	init_callbacks(); | ||||
| 	regs->claim_complete.set_write_cb(m_claim_complete_write_cb); | ||||
|     // 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(); | ||||
|     // 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 | ||||
|     // register event callbacks | ||||
|     SC_METHOD(clock_cb); | ||||
|     sensitive<<clk_i; | ||||
|     sensitive << clk_i; | ||||
|     SC_METHOD(reset_cb); | ||||
|     sensitive<<rst_i; | ||||
|  | ||||
|     sensitive << rst_i; | ||||
| } | ||||
|  | ||||
| plic::~plic() { | ||||
| plic::~plic() {} | ||||
|  | ||||
| void plic::init_callbacks() { | ||||
|     m_claim_complete_write_cb = [=](sysc::sc_register<uint32_t> 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::init_callbacks() | ||||
| { | ||||
| 	m_claim_complete_write_cb = [=](sysc::sc_register<uint32_t> 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::clock_cb() | ||||
| { | ||||
|     this->clk=clk_i.read(); | ||||
| } | ||||
|  | ||||
| void plic::reset_cb() | ||||
| { | ||||
|     if(rst_i.read()) | ||||
| void plic::reset_cb() { | ||||
|     if (rst_i.read()) | ||||
|         regs->reset_start(); | ||||
|     else | ||||
|         regs->reset_stop(); | ||||
| @@ -117,77 +109,70 @@ void plic::reset_cb() | ||||
| //   - called by: | ||||
| //     - complete-reg write register content | ||||
|  | ||||
| void plic::global_int_port_cb() { | ||||
|  | ||||
| void plic::global_int_port_cb() | ||||
| { | ||||
|     // set related pending bit if enable is set for incoming global_interrupt | ||||
|  | ||||
| 	// 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 | ||||
|  | ||||
| 	// 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); | ||||
|             LOG(INFO) << "pending interrupt identified: " << i; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| 		if ( enable && global_interrupts_i[i].read() == 1 ) { | ||||
| 			regs->r_pending = regs->r_pending | ( 0x1 << i); | ||||
| 			LOG(logging::INFO) << "pending interrupt identified: " << i; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	handle_pending_int(); | ||||
|     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    = 0; | ||||
| 	uint32_t thold      = regs->r_threshold.threshold;   // threshold value | ||||
| 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 = 0; | ||||
|     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  = 1; | ||||
| 				LOG(logging::INFO) << "pending interrupt activated: " << i; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if ( raise_int ) { | ||||
| 		regs->r_claim_complete = claim_int; | ||||
| 		core_interrupt_o.write(1); | ||||
| 		// todo: evluate clock period | ||||
| 	} else { | ||||
| 		regs->r_claim_complete = 0; | ||||
| 		LOG(logging::INFO) << "no further pending interrupt."; | ||||
| 	} | ||||
|     // 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 = 1; | ||||
|                 LOG(INFO) << "pending interrupt activated: " << i; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (raise_int) { | ||||
|         regs->r_claim_complete = claim_int; | ||||
|         core_interrupt_o.write(1); | ||||
|         // todo: evluate clock period | ||||
|     } else { | ||||
|         regs->r_claim_complete = 0; | ||||
|         LOG(INFO) << "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. | ||||
| 	LOG(logging::INFO) << "reset pending interrupt: " << irq; | ||||
| 	// reset related pending bit | ||||
| 	regs->r_pending &= ~(0x1 << irq); | ||||
| 	core_interrupt_o.write(0); | ||||
| 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. | ||||
|     LOG(INFO) << "reset pending interrupt: " << irq; | ||||
|     // reset related pending bit | ||||
|     regs->r_pending &= ~(0x1 << irq); | ||||
|     core_interrupt_o.write(0); | ||||
|  | ||||
| 	// evaluate next pending interrupt | ||||
| 	handle_pending_int(); | ||||
|     // evaluate next pending interrupt | ||||
|     handle_pending_int(); | ||||
| } | ||||
|  | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -17,24 +17,25 @@ | ||||
| #ifndef _PLIC_H_ | ||||
| #define _PLIC_H_ | ||||
|  | ||||
| #include <sysc/tlm_target.h> | ||||
| #include <sysc/register.h> | ||||
| #include <sysc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class plic_regs; | ||||
|  | ||||
| class plic: public sc_core::sc_module, public tlm_target<> { | ||||
| class plic : public sc_core::sc_module, public tlm_target<> { | ||||
| public: | ||||
|     SC_HAS_PROCESS(plic); | ||||
|     sc_core::sc_in<sc_core::sc_time>          clk_i; | ||||
|     sc_core::sc_in<bool>                      rst_i; | ||||
|     sc_core::sc_vector<sc_core::sc_in<bool>>  global_interrupts_i; | ||||
|     sc_core::sc_out<bool>                     core_interrupt_o; | ||||
|     sc_core::sc_event                         raise_int_ev; | ||||
|     sc_core::sc_event                         clear_int_ev; | ||||
|     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|     sc_core::sc_vector<sc_core::sc_in<bool>> global_interrupts_i; | ||||
|     sc_core::sc_out<bool> 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(); | ||||
| @@ -48,7 +49,7 @@ protected: | ||||
|     void clear_core_interrupt(); | ||||
|     sc_core::sc_time clk; | ||||
|     std::unique_ptr<plic_regs> regs; | ||||
|     std::function<bool(sc_register<uint32_t>,uint32_t)> m_claim_complete_write_cb; | ||||
|     std::function<bool(sc_register<uint32_t>, uint32_t)> m_claim_complete_write_cb; | ||||
| }; | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -21,12 +21,11 @@ | ||||
|  */ | ||||
|  | ||||
| #include "simple_system.h" | ||||
| #include <sysc/tracer.h> | ||||
| #include <sysc/scv_tr_db.h> | ||||
| #include <sysc/report.h> | ||||
| #include <boost/program_options.hpp> | ||||
| #include <sysc/report.h> | ||||
| #include <sstream> | ||||
| #include <sysc/report.h> | ||||
| #include <sysc/scv_tr_db.h> | ||||
| #include <sysc/tracer.h> | ||||
|  | ||||
| using namespace sysc; | ||||
| namespace po = boost::program_options; | ||||
| @@ -37,34 +36,32 @@ const size_t SUCCESS = 0; | ||||
| const size_t ERROR_UNHANDLED_EXCEPTION = 2; | ||||
| } // namespace | ||||
|  | ||||
| int sc_main(int argc, char* argv[]){ | ||||
| int sc_main(int argc, char *argv[]) { | ||||
|  | ||||
| 	// Environment adaptations | ||||
| 	putenv(const_cast<char*>("SC_SIGNAL_WRITE_CHECK=DISABLE")); | ||||
|     // Environment adaptations | ||||
|     putenv(const_cast<char *>("SC_SIGNAL_WRITE_CHECK=DISABLE")); | ||||
|  | ||||
| //    sc_report_handler::set_handler(my_report_handler); | ||||
|     sysc::Logger::reporting_level()=log::DEBUG; | ||||
|     //    sc_report_handler::set_handler(my_report_handler); | ||||
|     sysc::Logger::reporting_level() = log::DEBUG; | ||||
|     // todo: add module-name to log-file | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // CLI argument parsing | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     po::options_description desc("Options");\ | ||||
|     desc.add_options()\ | ||||
|         ("help,h", "Print help message")\ | ||||
|         ("debug,d", po::value<int>(), "set debug level")\ | ||||
|         ("trace,t", "trace SystemC signals"); | ||||
|     po::options_description desc("Options"); | ||||
|     desc.add_options()("help,h", "Print help message")("debug,d", po::value<int>(), | ||||
|                                                        "set debug level")("trace,t", "trace SystemC signals"); | ||||
|     po::variables_map vm; | ||||
|     try { | ||||
|         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw | ||||
|         // --help option | ||||
|         if ( vm.count("help")  ){ | ||||
|         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){ | ||||
|     } catch (po::error &e) { | ||||
|         std::cerr << "ERROR: " << e.what() << std::endl << std::endl; | ||||
|         std::cerr << desc << std::endl; | ||||
|         return ERROR_IN_COMMAND_LINE; | ||||
| @@ -79,7 +76,7 @@ int sc_main(int argc, char* argv[]){ | ||||
|     // instantiate top level | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     simple_system i_simple_system("i_simple_system"); | ||||
|     //sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, sc_core::SC_WARNING, sc_core::SC_MEDIUM); | ||||
|     // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, sc_core::SC_WARNING, sc_core::SC_MEDIUM); | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // run simulation | ||||
| @@ -87,10 +84,9 @@ int sc_main(int argc, char* argv[]){ | ||||
|     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()) { | ||||
|         LOG(logging::ERROR) << "simulation timed out"; | ||||
|     	sc_core::sc_stop(); | ||||
|     if (!sc_core::sc_end_of_simulation_invoked()) { | ||||
|         LOG(ERROR) << "simulation timed out"; | ||||
|         sc_core::sc_stop(); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -35,14 +35,13 @@ simple_system::simple_system(sc_core::sc_module_name nm) | ||||
| , NAMED(s_clk) | ||||
| , NAMED(s_rst) | ||||
| , NAMED(s_global_interrupts, 256) | ||||
| , NAMED(s_core_interrupt) | ||||
| { | ||||
| 	// todo: discuss naming conventions (s_<signal> vs. <port>_i/_o) --> covnert into _s | ||||
| , NAMED(s_core_interrupt) { | ||||
|     // todo: discuss naming conventions (s_<signal> vs. <port>_i/_o) --> covnert into _s | ||||
|  | ||||
| 	// bus connections | ||||
|     // bus connections | ||||
|     i_master.intor(i_router.target[0]); | ||||
|     size_t i=0; | ||||
|     for(const auto& e: e300_plat_map){ | ||||
|     size_t i = 0; | ||||
|     for (const auto &e : e300_plat_map) { | ||||
|         i_router.initiator[i](e.target->socket); | ||||
|         i_router.add_target_range(i, e.start, e.size); | ||||
|         i++; | ||||
| @@ -71,9 +70,9 @@ simple_system::simple_system(sc_core::sc_module_name nm) | ||||
| } | ||||
|  | ||||
| void simple_system::gen_reset() { | ||||
|     s_rst=true; | ||||
|     s_rst = true; | ||||
|     wait(10_ns); | ||||
|     s_rst=false; | ||||
|     s_rst = false; | ||||
| } | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -23,20 +23,19 @@ | ||||
| #ifndef SIMPLESYSTEM_H_ | ||||
| #define SIMPLESYSTEM_H_ | ||||
|  | ||||
| #include "uart.h" | ||||
| #include "spi.h" | ||||
| #include "gpio.h" | ||||
| #include "plic.h" | ||||
| #include "spi.h" | ||||
| #include "uart.h" | ||||
|  | ||||
| #include "test_initiator.h" | ||||
| #include <sysc/router.h> | ||||
| #include <sysc/kernel/sc_module.h> | ||||
| #include <array> | ||||
|  | ||||
| #include <sysc/kernel/sc_module.h> | ||||
| #include <sysc/router.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class simple_system: public sc_core::sc_module { | ||||
| class simple_system : public sc_core::sc_module { | ||||
| public: | ||||
|     SC_HAS_PROCESS(simple_system); | ||||
|  | ||||
| @@ -52,6 +51,7 @@ public: | ||||
|     sc_core::sc_signal<bool> s_core_interrupt; | ||||
|  | ||||
|     simple_system(sc_core::sc_module_name nm); | ||||
|  | ||||
| protected: | ||||
|     void gen_reset(); | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -25,24 +25,20 @@ spi::spi(sc_core::sc_module_name nm) | ||||
| , tlm_target<>(clk) | ||||
| , NAMED(clk_i) | ||||
| , NAMED(rst_i) | ||||
| , NAMEDD(spi_regs, regs) | ||||
| { | ||||
| , NAMEDD(spi_regs, regs) { | ||||
|     regs->registerResources(*this); | ||||
|     SC_METHOD(clock_cb); | ||||
|     sensitive<<clk_i; | ||||
|     sensitive << clk_i; | ||||
|     SC_METHOD(reset_cb); | ||||
|     sensitive<<rst_i; | ||||
|     sensitive << rst_i; | ||||
| } | ||||
|  | ||||
| spi::~spi() { | ||||
| } | ||||
| spi::~spi() {} | ||||
|  | ||||
| void spi::clock_cb() { | ||||
|     this->clk=clk_i.read(); | ||||
| } | ||||
| void spi::clock_cb() { this->clk = clk_i.read(); } | ||||
|  | ||||
| void spi::reset_cb() { | ||||
|     if(rst_i.read()) | ||||
|     if (rst_i.read()) | ||||
|         regs->reset_start(); | ||||
|     else | ||||
|         regs->reset_stop(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -23,13 +23,14 @@ namespace sysc { | ||||
|  | ||||
| class spi_regs; | ||||
|  | ||||
| class spi: public sc_core::sc_module, public tlm_target<> { | ||||
| class spi : public sc_core::sc_module, public tlm_target<> { | ||||
| public: | ||||
|     SC_HAS_PROCESS(spi); | ||||
|     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||
|     sc_core::sc_in<bool>             rst_i; | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|     spi(sc_core::sc_module_name nm); | ||||
|     virtual ~spi(); | ||||
|  | ||||
| protected: | ||||
|     void clock_cb(); | ||||
|     void reset_cb(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -21,18 +21,18 @@ | ||||
|  */ | ||||
|  | ||||
| #include "test_initiator.h" | ||||
| #include <array> | ||||
| #include <sysc/report.h> | ||||
| #include <sysc/utilities.h> | ||||
| #include <array> | ||||
|  | ||||
| // 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_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 { | ||||
| @@ -41,38 +41,35 @@ test_initiator::test_initiator(sc_core::sc_module_name nm) | ||||
| , NAMED(intor) | ||||
| , NAMED(rst_i) | ||||
| , NAMED(global_interrupts_o, 256) | ||||
| , NAMED(core_interrupt_i) | ||||
| { | ||||
| 	SC_THREAD(run); | ||||
| , NAMED(core_interrupt_i) { | ||||
|     SC_THREAD(run); | ||||
|  | ||||
| 	SC_METHOD(core_irq_handler); | ||||
| 	sensitive << core_interrupt_i; | ||||
| 	dont_initialize(); | ||||
|     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()); | ||||
| 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(); | ||||
|     test_unique_irq(); | ||||
|     test_frequent_irq(); | ||||
|     test_parallel_irq(); | ||||
|     test_irq_stress(); | ||||
|  | ||||
| 	// todo: review irq sequences from FW point of view ... expected ??? | ||||
|     // todo: review irq sequences from FW point of view ... expected ??? | ||||
| } | ||||
|  | ||||
| void test_initiator::test_unique_irq() | ||||
| { | ||||
| void test_initiator::test_unique_irq() { | ||||
|  | ||||
| 	//// enable reg is not set | ||||
| 	// -> irq to be ignored | ||||
| 	// -> no core_interrupt | ||||
| 	// -> no entry in pending reg | ||||
|     //// 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(1); | ||||
| @@ -85,9 +82,9 @@ void test_initiator::test_unique_irq() | ||||
|     reg_check(PLIC_CLAIM_COMPLETE_REG, 0x0); | ||||
|     wait(10_ns); | ||||
|  | ||||
| 	//// enable reg is set, then | ||||
| 	// -> pending bit change expected | ||||
| 	// -> core_interrupt expected | ||||
|     //// enable reg is set, then | ||||
|     // -> pending bit change expected | ||||
|     // -> core_interrupt expected | ||||
|  | ||||
|     uint32_t v = read_bus(PLIC_PRIO1_REG); | ||||
|     wait(10_ns); | ||||
| @@ -111,9 +108,9 @@ void test_initiator::test_unique_irq() | ||||
|     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 | ||||
|     //// 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); | ||||
| @@ -125,23 +122,17 @@ void test_initiator::test_unique_irq() | ||||
|     // todo: evaluate error messages ... provide correct pass/fail verdict | ||||
|  | ||||
|     wait(100_ns); | ||||
|  | ||||
| } | ||||
|  | ||||
| void test_initiator::test_frequent_irq() | ||||
| { | ||||
| 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 | ||||
| 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); | ||||
| @@ -177,8 +168,8 @@ void test_initiator::test_parallel_irq() | ||||
|     reg_check(PLIC_CLAIM_COMPLETE_REG, 0x1); | ||||
|     wait(10_ns); | ||||
|  | ||||
| 	//// after writing to claim_complete reg (per fw) | ||||
| 	// -> next int to become highest irq | ||||
|     //// 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); | ||||
| @@ -186,8 +177,8 @@ void test_initiator::test_parallel_irq() | ||||
|     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 | ||||
|     //// 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); | ||||
| @@ -195,8 +186,8 @@ void test_initiator::test_parallel_irq() | ||||
|     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 | ||||
|     //// 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); | ||||
| @@ -204,29 +195,23 @@ void test_initiator::test_parallel_irq() | ||||
|     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::test_irq_stress() {} | ||||
|  | ||||
| } | ||||
|  | ||||
| void test_initiator::write_bus(std::uint32_t adr, std::uint32_t dat) | ||||
| { | ||||
| void test_initiator::write_bus(std::uint32_t adr, std::uint32_t dat) { | ||||
|     tlm::tlm_generic_payload gp; | ||||
|     std::array<uint8_t, 4> data; | ||||
|     data[3] = 0xff & dat>>24; | ||||
|     data[2] = 0xff & dat>>16; | ||||
|     data[1] = 0xff & dat>>8; | ||||
|     data[3] = 0xff & dat >> 24; | ||||
|     data[2] = 0xff & dat >> 16; | ||||
|     data[1] = 0xff & dat >> 8; | ||||
|     data[0] = 0xff & dat; | ||||
|  | ||||
|     LOG(logging::INFO) << "write_bus(0x" << std::hex << adr << ") : " << dat; | ||||
|     LOG(INFO) << "write_bus(0x" << std::hex << adr << ") : " << dat; | ||||
|  | ||||
|     gp.set_command(tlm::TLM_WRITE_COMMAND); | ||||
|     gp.set_address(adr); | ||||
| @@ -236,13 +221,12 @@ void test_initiator::write_bus(std::uint32_t adr, std::uint32_t dat) | ||||
|     sc_core::sc_time delay; | ||||
|     intor->b_transport(gp, delay); | ||||
|  | ||||
|     if ( gp.get_response_status() != tlm::TLM_OK_RESPONSE ) { | ||||
|       throw std::exception(); | ||||
|     if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { | ||||
|         throw std::exception(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::uint32_t test_initiator::read_bus(std::uint32_t adr) | ||||
| { | ||||
| std::uint32_t test_initiator::read_bus(std::uint32_t adr) { | ||||
|  | ||||
|     tlm::tlm_generic_payload gp; | ||||
|     std::array<uint8_t, 4> data; | ||||
| @@ -255,32 +239,30 @@ std::uint32_t test_initiator::read_bus(std::uint32_t adr) | ||||
|     sc_core::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 | ||||
|     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]; | ||||
|     std::uint32_t rdat = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0]; | ||||
|  | ||||
|     LOG(logging::INFO) << "read_bus(0x" << std::hex << adr << ") -> " << rdat; | ||||
|     LOG(INFO) << "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 ) { | ||||
| 		LOG(logging::ERROR) << "register check failed for address 0x" << std::hex << adr << ": " << dat << " !=  " << exp; | ||||
| 	} else { | ||||
| 		LOG(logging::INFO)  << "register check passed for address 0x" << std::hex << adr << ": " << dat; | ||||
| 	} | ||||
| void test_initiator::reg_check(std::uint32_t adr, std::uint32_t exp) { | ||||
|     uint32_t dat = read_bus(adr); | ||||
|     if (dat != exp) { | ||||
|         LOG(ERROR) << "register check failed for address 0x" << std::hex << adr << ": " << dat << " !=  " << exp; | ||||
|     } else { | ||||
|         LOG(INFO) << "register check passed for address 0x" << std::hex << adr << ": " << dat; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void test_initiator::core_irq_handler() | ||||
| { | ||||
| 	LOG(logging::INFO) << "core_interrupt_i edge detected -> " << core_interrupt_i.read(); | ||||
| void test_initiator::core_irq_handler() { | ||||
|     LOG(INFO) << "core_interrupt_i edge detected -> " << core_interrupt_i.read(); | ||||
| } | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -28,20 +28,21 @@ | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class test_initiator: public sc_core::sc_module { | ||||
| class test_initiator : public sc_core::sc_module { | ||||
| public: | ||||
|     SC_HAS_PROCESS(test_initiator); | ||||
|     tlm_utils::simple_initiator_socket<test_initiator, 32> intor; | ||||
|     sc_core::sc_vector<sc_core::sc_out<bool>>              global_interrupts_o; | ||||
|     sc_core::sc_in<bool>                                   core_interrupt_i; | ||||
|     sc_core::sc_in<bool>                                   rst_i; | ||||
|     sc_core::sc_vector<sc_core::sc_out<bool>> global_interrupts_o; | ||||
|     sc_core::sc_in<bool> core_interrupt_i; | ||||
|     sc_core::sc_in<bool> 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 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); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // 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 | ||||
| @@ -25,24 +25,20 @@ uart::uart(sc_core::sc_module_name nm) | ||||
| , tlm_target<>(clk) | ||||
| , NAMED(clk_i) | ||||
| , NAMED(rst_i) | ||||
| , NAMEDD(uart_regs, regs) | ||||
| { | ||||
| , NAMEDD(uart_regs, regs) { | ||||
|     regs->registerResources(*this); | ||||
|     SC_METHOD(clock_cb); | ||||
|     sensitive<<clk_i; | ||||
|     sensitive << clk_i; | ||||
|     SC_METHOD(reset_cb); | ||||
|     sensitive<<rst_i; | ||||
|     sensitive << rst_i; | ||||
| } | ||||
|  | ||||
| uart::~uart() { | ||||
| } | ||||
| uart::~uart() {} | ||||
|  | ||||
| void uart::clock_cb() { | ||||
|     this->clk=clk_i.read(); | ||||
| } | ||||
| void uart::clock_cb() { this->clk = clk_i.read(); } | ||||
|  | ||||
| void uart::reset_cb() { | ||||
|     if(rst_i.read()) | ||||
|     if (rst_i.read()) | ||||
|         regs->reset_start(); | ||||
|     else | ||||
|         regs->reset_stop(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /******************************************************************************* | ||||
|  * 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 | ||||
| @@ -23,13 +23,14 @@ namespace sysc { | ||||
|  | ||||
| class uart_regs; | ||||
|  | ||||
| class uart: public sc_core::sc_module, public tlm_target<> { | ||||
| class uart : public sc_core::sc_module, public tlm_target<> { | ||||
| public: | ||||
|     SC_HAS_PROCESS(uart); | ||||
|     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||
|     sc_core::sc_in<bool>             rst_i; | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|     uart(sc_core::sc_module_name nm); | ||||
|     virtual ~uart(); | ||||
|  | ||||
| protected: | ||||
|     void clock_cb(); | ||||
|     void reset_cb(); | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|  | ||||
| const unsigned ram_size = 256; | ||||
|  | ||||
| class rw_task_if: virtual public sc_interface { | ||||
| class rw_task_if : virtual public sc_interface { | ||||
| public: | ||||
|     typedef sc_uint<8> addr_t; | ||||
|     typedef sc_uint<8> data_t; | ||||
| @@ -31,38 +31,42 @@ public: | ||||
|         data_t data; | ||||
|     }; | ||||
|  | ||||
|     virtual data_t read(const addr_t*) = 0; | ||||
|     virtual void write(const write_t*) = 0; | ||||
|     virtual data_t read(const addr_t *) = 0; | ||||
|     virtual void write(const write_t *) = 0; | ||||
| }; | ||||
|  | ||||
| SCV_EXTENSIONS(rw_task_if::write_t){ | ||||
| SCV_EXTENSIONS(rw_task_if::write_t) { | ||||
| public: | ||||
| scv_extensions<rw_task_if::addr_t> addr; | ||||
| scv_extensions<rw_task_if::data_t> data; | ||||
| SCV_EXTENSIONS_CTOR(rw_task_if::write_t) { | ||||
|     SCV_FIELD(addr); | ||||
|     SCV_FIELD(data); | ||||
| } | ||||
|     scv_extensions<rw_task_if::addr_t> addr; | ||||
|     scv_extensions<rw_task_if::data_t> data; | ||||
|     SCV_EXTENSIONS_CTOR(rw_task_if::write_t) { | ||||
|         SCV_FIELD(addr); | ||||
|         SCV_FIELD(data); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class pipelined_bus_ports: public sc_module { | ||||
| class pipelined_bus_ports : public sc_module { | ||||
| public: | ||||
|     sc_in<bool> clk; | ||||
|     sc_inout<bool> rw; | ||||
|     sc_inout<bool> addr_req; | ||||
|     sc_inout<bool> addr_ack; | ||||
|     sc_inout<sc_uint<8> > bus_addr; | ||||
|     sc_inout<sc_uint<8>> bus_addr; | ||||
|     sc_inout<bool> data_rdy; | ||||
|     sc_inout<sc_uint<8> > bus_data; | ||||
|     sc_inout<sc_uint<8>> 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") { | ||||
|     } | ||||
|     virtual void trace( sc_trace_file* tf ) const; | ||||
|     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") {} | ||||
|     virtual void trace(sc_trace_file *tf) const; | ||||
| }; | ||||
|  | ||||
| void pipelined_bus_ports::trace( sc_trace_file* tf ) const { | ||||
| 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()); | ||||
| @@ -72,46 +76,45 @@ void pipelined_bus_ports::trace( sc_trace_file* tf ) const { | ||||
|     sc_trace(tf, bus_data, bus_data.name()); | ||||
| } | ||||
|  | ||||
| class rw_pipelined_transactor: public rw_task_if, public pipelined_bus_ports { | ||||
| class rw_pipelined_transactor : public rw_task_if, public pipelined_bus_ports { | ||||
|  | ||||
|     fifo_mutex addr_phase;fifo_mutex data_phase; | ||||
|     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>, sc_uint<8> > read_gen; | ||||
|     scv_tr_generator<sc_uint<8>, sc_uint<8> > write_gen; | ||||
|     scv_tr_generator<sc_uint<8> > addr_gen; | ||||
|     scv_tr_generator<_scv_tr_generator_default_data, sc_uint<8> > rdata_gen; | ||||
|     scv_tr_generator<sc_uint<8> > wdata_gen; | ||||
|     scv_tr_generator<sc_uint<8>, sc_uint<8>> read_gen; | ||||
|     scv_tr_generator<sc_uint<8>, sc_uint<8>> write_gen; | ||||
|     scv_tr_generator<sc_uint<8>> addr_gen; | ||||
|     scv_tr_generator<_scv_tr_generator_default_data, sc_uint<8>> rdata_gen; | ||||
|     scv_tr_generator<sc_uint<8>> 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, NULL, "data") | ||||
|         , wdata_gen("wdata", data_stream, "data") | ||||
|     { | ||||
|     } | ||||
|     virtual data_t read(const addr_t* p_addr); | ||||
|     virtual void write(const write_t * req); | ||||
|     : 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, NULL, "data") | ||||
|     , wdata_gen("wdata", data_stream, "data") {} | ||||
|     virtual data_t read(const addr_t *p_addr); | ||||
|     virtual void write(const write_t *req); | ||||
| }; | ||||
|  | ||||
| rw_task_if::data_t rw_pipelined_transactor::read(const addr_t* addr) { | ||||
| 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; | ||||
|     rw = false; | ||||
|     addr_req = 1; | ||||
|     wait(addr_ack->posedge_event()); | ||||
|     wait(clk->negedge_event()); | ||||
| @@ -132,14 +135,14 @@ rw_task_if::data_t rw_pipelined_transactor::read(const addr_t* addr) { | ||||
|     return data; | ||||
| } | ||||
|  | ||||
| void rw_pipelined_transactor::write(const write_t * req) { | ||||
| 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; | ||||
|     rw = true; | ||||
|     addr_req = 1; | ||||
|     wait(addr_ack->posedge_event()); | ||||
|     wait(clk->negedge_event()); | ||||
| @@ -150,7 +153,7 @@ void rw_pipelined_transactor::write(const write_t * req) { | ||||
|  | ||||
|     data_phase.lock(); | ||||
|     scv_tr_handle h2 = wdata_gen.begin_transaction(req->data, "data_phase", h); | ||||
|     bus_data=req->data; | ||||
|     bus_data = req->data; | ||||
|     wait(data_rdy->posedge_event()); | ||||
|     wait(data_rdy->negedge_event()); | ||||
|     wdata_gen.end_transaction(h2); | ||||
| @@ -158,11 +161,11 @@ void rw_pipelined_transactor::write(const write_t * req) { | ||||
|     data_phase.unlock(); | ||||
| } | ||||
|  | ||||
| class test: public sc_module { | ||||
| class test : public sc_module { | ||||
| public: | ||||
|     sc_port<rw_task_if> transactor; | ||||
|     SC_HAS_PROCESS(test); | ||||
|     test( ::sc_core::sc_module_name ){ | ||||
|     test(::sc_core::sc_module_name) { | ||||
|         SC_THREAD(main1); | ||||
|         SC_THREAD(main2); | ||||
|     } | ||||
| @@ -170,16 +173,16 @@ public: | ||||
|     void main2(); | ||||
| }; | ||||
|  | ||||
| class write_constraint: virtual public scv_constraint_base { | ||||
| class write_constraint : virtual public scv_constraint_base { | ||||
| public: | ||||
|     scv_smart_ptr<rw_task_if::write_t> write;SCV_CONSTRAINT_CTOR(write_constraint) { | ||||
|     scv_smart_ptr<rw_task_if::write_t> write; | ||||
|     SCV_CONSTRAINT_CTOR(write_constraint) { | ||||
|         SCV_CONSTRAINT(write->addr() <= ram_size); | ||||
|         SCV_CONSTRAINT(write->addr() != write->data()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| inline void process(scv_smart_ptr<int> data) { | ||||
| } | ||||
| inline void process(scv_smart_ptr<int> data) {} | ||||
|  | ||||
| inline void test::main1() { | ||||
|     // simple sequential tests | ||||
| @@ -250,15 +253,15 @@ inline void test::main2() { | ||||
|         process(data); | ||||
|     } | ||||
| } | ||||
| class design: public pipelined_bus_ports { | ||||
|     std::list<sc_uint<8> > outstandingAddresses; | ||||
| class design : public pipelined_bus_ports { | ||||
|     std::list<sc_uint<8>> outstandingAddresses; | ||||
|     std::list<bool> outstandingType; | ||||
|     sc_uint<8> memory[ram_size]; | ||||
|  | ||||
| public: | ||||
|     SC_HAS_PROCESS(design); | ||||
|     design(sc_module_name nm) : | ||||
|             pipelined_bus_ports(nm) { | ||||
|     design(sc_module_name nm) | ||||
|     : pipelined_bus_ports(nm) { | ||||
|         for (unsigned i = 0; i < ram_size; ++i) { | ||||
|             memory[i] = i; | ||||
|         } | ||||
| @@ -304,16 +307,15 @@ inline void design::data_phase() { | ||||
|         } | ||||
|         if (outstandingType.front() == false) { | ||||
|             cout << "reading memory address " << outstandingAddresses.front() << " with value " | ||||
|                     << memory[outstandingAddresses.front().to_ulong()] << endl; | ||||
|                  << memory[outstandingAddresses.front().to_ulong()] << endl; | ||||
|             bus_data = memory[outstandingAddresses.front().to_ulong()]; | ||||
|             data_rdy = 1; | ||||
|             wait(clk->posedge_event()); | ||||
|             data_rdy = 0; | ||||
|  | ||||
|         } else { | ||||
|             cout << "writing memory address " << outstandingAddresses.front() << " with value " | ||||
|                     << bus_data << endl; | ||||
|             memory[outstandingAddresses.front().to_ulong()]=bus_data; | ||||
|             cout << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data << endl; | ||||
|             memory[outstandingAddresses.front().to_ulong()] = bus_data; | ||||
|             data_rdy = 1; | ||||
|             wait(clk->posedge_event()); | ||||
|             data_rdy = 0; | ||||
| @@ -332,19 +334,19 @@ int sc_main(int argc, char *argv[]) { | ||||
|     const char* fileName = "my_db.txlog"; | ||||
| #else | ||||
|     scv_tr_sqlite_init(); | ||||
|     const char* fileName = "my_db"; | ||||
|     const char *fileName = "my_db"; | ||||
| #endif | ||||
|     scv_tr_db db(fileName); | ||||
|     scv_tr_db::set_default_db(&db); | ||||
|     sc_trace_file* tf = sc_create_vcd_trace_file("my_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<bool> rw; | ||||
|     sc_signal<bool> addr_req; | ||||
|     sc_signal<bool> addr_ack; | ||||
|     sc_signal<sc_uint<8> > bus_addr; | ||||
|     sc_signal<sc_uint<8>> bus_addr; | ||||
|     sc_signal<bool> data_rdy; | ||||
|     sc_signal<sc_uint<8> > bus_data; | ||||
|     sc_signal<sc_uint<8>> bus_data; | ||||
|  | ||||
|     // create modules/channels | ||||
|     test t("t"); | ||||
| @@ -380,4 +382,3 @@ int sc_main(int argc, char *argv[]) { | ||||
|     sc_close_vcd_trace_file(tf); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user