update scc, add minimal test for ordered_semaphore
This commit is contained in:
parent
d3da1aefcf
commit
ae5ba9ca8e
@ -117,7 +117,7 @@ int sc_main (int argc , char *argv[]){
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// configure logging
|
// configure logging
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
scc::init_logging(logging::DEBUG);
|
scc::init_logging(scc::log::DEBUG);
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// set up configuration and tracing
|
// set up configuration and tracing
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -119,7 +119,7 @@ void plic::global_int_port_cb() {
|
|||||||
|
|
||||||
if (enable && global_interrupts_i[i].read() == 1) {
|
if (enable && global_interrupts_i[i].read() == 1) {
|
||||||
regs->r_pending = regs->r_pending | (0x1 << i);
|
regs->r_pending = regs->r_pending | (0x1 << i);
|
||||||
SCDEBUG("plic") << "pending interrupt identified: " << i;
|
SCCDEBUG("plic") << "pending interrupt identified: " << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ void plic::handle_pending_int() {
|
|||||||
claim_prio = prio;
|
claim_prio = prio;
|
||||||
claim_int = i;
|
claim_int = i;
|
||||||
raise_int = 1;
|
raise_int = 1;
|
||||||
SCDEBUG("plic") << "pending interrupt activated: " << i;
|
SCCDEBUG("plic") << "pending interrupt activated: " << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,14 +158,14 @@ void plic::handle_pending_int() {
|
|||||||
// todo: evluate clock period
|
// todo: evluate clock period
|
||||||
} else {
|
} else {
|
||||||
regs->r_claim_complete = 0;
|
regs->r_claim_complete = 0;
|
||||||
SCDEBUG("plic") << "no further pending interrupt.";
|
SCCDEBUG("plic") << "no further pending interrupt.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void plic::reset_pending_int(uint32_t irq) {
|
void plic::reset_pending_int(uint32_t irq) {
|
||||||
// todo: evaluate enable register (see spec)
|
// todo: evaluate enable register (see spec)
|
||||||
// todo: make sure that pending is set, otherwise don't reset irq ... read spec.
|
// todo: make sure that pending is set, otherwise don't reset irq ... read spec.
|
||||||
SCDEBUG("plic") << "reset pending interrupt: " << irq;
|
SCCDEBUG("plic") << "reset pending interrupt: " << irq;
|
||||||
// reset related pending bit
|
// reset related pending bit
|
||||||
regs->r_pending &= ~(0x1 << irq);
|
regs->r_pending &= ~(0x1 << irq);
|
||||||
core_interrupt_o.write(0);
|
core_interrupt_o.write(0);
|
||||||
|
@ -67,7 +67,7 @@ int sc_main(int argc, char *argv[]) {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// configure logging
|
// configure logging
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
scc::init_logging(vm.count("debug")?logging::DEBUG:logging::INFO);
|
scc::init_logging(vm.count("debug")?scc::log::DEBUG:scc::log::INFO);
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// set up tracing & transaction recording
|
// set up tracing & transaction recording
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -86,7 +86,7 @@ int sc_main(int argc, char *argv[]) {
|
|||||||
// todo: provide end-of-simulation macros
|
// todo: provide end-of-simulation macros
|
||||||
|
|
||||||
if (!sc_core::sc_end_of_simulation_invoked()) {
|
if (!sc_core::sc_end_of_simulation_invoked()) {
|
||||||
SCERR() << "simulation timed out";
|
SCCERR() << "simulation timed out";
|
||||||
sc_core::sc_stop();
|
sc_core::sc_stop();
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -215,7 +215,7 @@ void test_initiator::write_bus(std::uint32_t adr, std::uint32_t dat) {
|
|||||||
data[1] = 0xff & dat >> 8;
|
data[1] = 0xff & dat >> 8;
|
||||||
data[0] = 0xff & dat;
|
data[0] = 0xff & dat;
|
||||||
|
|
||||||
SCDEBUG("test_initiator") << "write_bus(0x" << std::hex << adr << ") : " << dat;
|
SCCDEBUG("test_initiator") << "write_bus(0x" << std::hex << adr << ") : " << dat;
|
||||||
|
|
||||||
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
||||||
gp.set_address(adr);
|
gp.set_address(adr);
|
||||||
@ -252,21 +252,21 @@ std::uint32_t test_initiator::read_bus(std::uint32_t adr) {
|
|||||||
// todo: use reinterpret_cast instead
|
// 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];
|
||||||
|
|
||||||
SCDEBUG("test_initiator") << "read_bus(0x" << std::hex << adr << ") -> " << rdat;
|
SCCDEBUG("test_initiator") << "read_bus(0x" << std::hex << adr << ") -> " << rdat;
|
||||||
return rdat;
|
return rdat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_initiator::reg_check(std::uint32_t adr, std::uint32_t exp) {
|
void test_initiator::reg_check(std::uint32_t adr, std::uint32_t exp) {
|
||||||
uint32_t dat = read_bus(adr);
|
uint32_t dat = read_bus(adr);
|
||||||
if (dat != exp) {
|
if (dat != exp) {
|
||||||
SCERR("test_initiator") << "register check failed for address 0x" << std::hex << adr << ": " << dat << " != " << exp;
|
SCCERR("test_initiator") << "register check failed for address 0x" << std::hex << adr << ": " << dat << " != " << exp;
|
||||||
} else {
|
} else {
|
||||||
SCDEBUG("test_initiator") << "register check passed for address 0x" << std::hex << adr << ": " << dat;
|
SCCDEBUG("test_initiator") << "register check passed for address 0x" << std::hex << adr << ": " << dat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_initiator::core_irq_handler() {
|
void test_initiator::core_irq_handler() {
|
||||||
SCDEBUG("test_initiator") << "core_interrupt_i edge detected -> " << core_interrupt_i.read();
|
SCCDEBUG("test_initiator") << "core_interrupt_i edge detected -> " << core_interrupt_i.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "scc/scv_tr_db.h"
|
#include "scc/scv_tr_db.h"
|
||||||
#include "scc/report.h"
|
#include "scc/report.h"
|
||||||
#include "scc/value_registry.h"
|
#include "scc/value_registry.h"
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
// text 11308µs/11602µs
|
// text 11308µs/11602µs
|
||||||
// compressed 10365µs/ 9860µs
|
// compressed 10365µs/ 9860µs
|
||||||
@ -198,7 +199,7 @@ inline void test::main1() {
|
|||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
rw_task_if::addr_t addr = i;
|
rw_task_if::addr_t addr = i;
|
||||||
rw_task_if::data_t data = transactor->read(&addr);
|
rw_task_if::data_t data = transactor->read(&addr);
|
||||||
SCINFO(sc_get_current_object()->name()) << "received data : " << data;
|
SCCINFO(sc_get_current_object()->name()) << "received data : " << data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<rw_task_if::addr_t> addr;
|
scv_smart_ptr<rw_task_if::addr_t> addr;
|
||||||
@ -206,14 +207,14 @@ inline void test::main1() {
|
|||||||
|
|
||||||
addr->next();
|
addr->next();
|
||||||
rw_task_if::data_t data = transactor->read(addr->get_instance());
|
rw_task_if::data_t data = transactor->read(addr->get_instance());
|
||||||
SCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data;
|
SCCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<rw_task_if::write_t> write;
|
scv_smart_ptr<rw_task_if::write_t> write;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
write->next();
|
write->next();
|
||||||
transactor->write(write->get_instance());
|
transactor->write(write->get_instance());
|
||||||
SCINFO(sc_get_current_object()->name()) << "send data : " << write->data;
|
SCCINFO(sc_get_current_object()->name()) << "send data : " << write->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<int> data;
|
scv_smart_ptr<int> data;
|
||||||
@ -232,7 +233,7 @@ inline void test::main2() {
|
|||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
rw_task_if::addr_t addr = i;
|
rw_task_if::addr_t addr = i;
|
||||||
rw_task_if::data_t data = transactor->read(&addr);
|
rw_task_if::data_t data = transactor->read(&addr);
|
||||||
SCINFO(sc_get_current_object()->name()) << "received data : " << data;
|
SCCINFO(sc_get_current_object()->name()) << "received data : " << data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<rw_task_if::addr_t> addr;
|
scv_smart_ptr<rw_task_if::addr_t> addr;
|
||||||
@ -240,14 +241,14 @@ inline void test::main2() {
|
|||||||
|
|
||||||
addr->next();
|
addr->next();
|
||||||
rw_task_if::data_t data = transactor->read(addr->get_instance());
|
rw_task_if::data_t data = transactor->read(addr->get_instance());
|
||||||
SCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data;
|
SCCINFO(sc_get_current_object()->name()) << "data for address " << *addr << " is " << data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<rw_task_if::write_t> write;
|
scv_smart_ptr<rw_task_if::write_t> write;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
write->next();
|
write->next();
|
||||||
transactor->write(write->get_instance());
|
transactor->write(write->get_instance());
|
||||||
SCINFO(sc_get_current_object()->name()) << "send data : " << write->data;
|
SCCINFO(sc_get_current_object()->name()) << "send data : " << write->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
scv_smart_ptr<int> data;
|
scv_smart_ptr<int> data;
|
||||||
@ -298,7 +299,7 @@ inline void design::addr_phase() {
|
|||||||
|
|
||||||
outstandingAddresses.push_back(_addr);
|
outstandingAddresses.push_back(_addr);
|
||||||
outstandingType.push_back(_rw);
|
outstandingType.push_back(_rw);
|
||||||
SCINFO(sc_get_current_object()->name()) << "received request for memory address " << _addr;
|
SCCINFO(sc_get_current_object()->name()) << "received request for memory address " << _addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +313,7 @@ inline void design::data_phase() {
|
|||||||
wait(clk->posedge_event());
|
wait(clk->posedge_event());
|
||||||
}
|
}
|
||||||
if (outstandingType.front() == false) {
|
if (outstandingType.front() == false) {
|
||||||
SCINFO(sc_get_current_object()->name()) << "reading memory address " << outstandingAddresses.front() << " with value "
|
SCCINFO(sc_get_current_object()->name()) << "reading memory address " << outstandingAddresses.front() << " with value "
|
||||||
<< memory[outstandingAddresses.front().to_ulong()];
|
<< memory[outstandingAddresses.front().to_ulong()];
|
||||||
bus_data = memory[outstandingAddresses.front().to_ulong()];
|
bus_data = memory[outstandingAddresses.front().to_ulong()];
|
||||||
data_rdy = 1;
|
data_rdy = 1;
|
||||||
@ -320,7 +321,7 @@ inline void design::data_phase() {
|
|||||||
data_rdy = 0;
|
data_rdy = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SCINFO(sc_get_current_object()->name()) << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data;
|
SCCINFO(sc_get_current_object()->name()) << "writing memory address " << outstandingAddresses.front() << " with value " << bus_data;
|
||||||
memory[outstandingAddresses.front().to_ulong()] = bus_data;
|
memory[outstandingAddresses.front().to_ulong()] = bus_data;
|
||||||
data_rdy = 1;
|
data_rdy = 1;
|
||||||
wait(clk->posedge_event());
|
wait(clk->posedge_event());
|
||||||
@ -351,7 +352,7 @@ inline const char* init_db(char type){
|
|||||||
int sc_main(int argc, char *argv[]) {
|
int sc_main(int argc, char *argv[]) {
|
||||||
auto start = std::chrono::system_clock::now();
|
auto start = std::chrono::system_clock::now();
|
||||||
scv_startup();
|
scv_startup();
|
||||||
scc::init_logging(scc::LogConfig().logLevel(logging::DEBUG));
|
scc::init_logging(scc::LogConfig().logLevel(scc::log::DEBUG));
|
||||||
const char *fileName = argc==2? init_db(argv[1][0]): "my_db.txlog";
|
const char *fileName = argc==2? init_db(argv[1][0]): "my_db.txlog";
|
||||||
if(argc<2) scv_tr_text_init();
|
if(argc<2) scv_tr_text_init();
|
||||||
scv_tr_db db(fileName);
|
scv_tr_db db(fileName);
|
||||||
@ -400,6 +401,6 @@ int sc_main(int argc, char *argv[]) {
|
|||||||
sc_start(10.0, SC_US);
|
sc_start(10.0, SC_US);
|
||||||
sc_close_vcd_trace_file(tf);
|
sc_close_vcd_trace_file(tf);
|
||||||
auto int_us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now()-start);
|
auto int_us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now()-start);
|
||||||
SCINFO() << "simulation duration "<<int_us.count()<<"µs";
|
SCCINFO() << "simulation duration "<<int_us.count()<<"µs";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 213293bc01287e8104ca8b03e552d69376ebb7a3
|
Subproject commit d3b67bc32bf086321cd492d6d8f1aba30899699b
|
@ -1 +1,3 @@
|
|||||||
add_subdirectory(io-redirector)
|
add_subdirectory(io-redirector)
|
||||||
|
#add_subdirectory(sim_performance)
|
||||||
|
add_subdirectory(ordered_semaphore)
|
||||||
|
6
tests/ordered_semaphore/CMakeLists.txt
Normal file
6
tests/ordered_semaphore/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
add_executable (ordered_sem
|
||||||
|
sc_main.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries (ordered_sem LINK_PUBLIC scc)
|
||||||
|
target_link_libraries (ordered_sem LINK_PUBLIC ${Boost_LIBRARIES} )
|
111
tests/ordered_semaphore/sc_main.cpp
Normal file
111
tests/ordered_semaphore/sc_main.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <scc/report.h>
|
||||||
|
#include <scc/scv_tr_db.h>
|
||||||
|
#include <scc/tracer.h>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <scc/ordered_semaphore.h>
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class top: public sc_core::sc_module {
|
||||||
|
public:
|
||||||
|
top(sc_core::sc_module_name const&){
|
||||||
|
SC_HAS_PROCESS(top);
|
||||||
|
SC_THREAD(run);
|
||||||
|
}
|
||||||
|
virtual ~top(){};
|
||||||
|
private:
|
||||||
|
void run(){
|
||||||
|
sem.wait();
|
||||||
|
sem_t.wait();
|
||||||
|
sem.set_capacity(4);
|
||||||
|
sem_t.set_capacity(4);
|
||||||
|
sem_t.post();
|
||||||
|
sem.post();
|
||||||
|
sc_stop();
|
||||||
|
}
|
||||||
|
scc::ordered_semaphore sem{"sem", 2};
|
||||||
|
scc::ordered_semaphore_t<2> sem_t{"sem_t"};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// instantiate top level
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
top tb("tb");
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
auto errcnt = sc_report_handler::get_count(SC_ERROR);
|
||||||
|
auto warncnt = sc_report_handler::get_count(SC_WARNING);
|
||||||
|
SCCINFO() << "Finished, there were " << errcnt << " error" << (errcnt == 1 ? "" : "s") << " and " << warncnt << " warning"
|
||||||
|
<< (warncnt == 1 ? "" : "s, 1 warning expected");
|
||||||
|
return errcnt + (warncnt-1);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user