blob: 81d26521d2d5c0843515025df2d1591ddee68d40 [file]
// Copyright 2024 Google LLC
//
// 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 <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <elf.h>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/flags/usage.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "tests/systemc/Xbar.h"
#include "tests/verilator_sim/elf.h"
#include "tests/verilator_sim/sysc_tb.h"
#include "tests/verilator_sim/util.h"
// Headers for our Verilator model.
#include "VCoreMiniAxi.h"
#include "hdl/chisel/src/kelvin/VCoreMiniAxi_parameters.h"
/* clang-format off */
#include <systemc>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include "checkers/pc-axi.h"
#include "tlm-bridges/tlm2axi-bridge.h"
#include "tlm-bridges/axi2tlm-bridge.h"
#include "traffic-generators/tg-tlm.h"
#include "traffic-generators/traffic-desc.h"
#include "tests/test-modules/signals-axi.h"
#include "tests/test-modules/utils.h"
/* clang-format on */
ABSL_FLAG(int, cycles, 100000000, "Simulation cycles");
ABSL_FLAG(bool, trace, false, "Dump VCD trace");
ABSL_FLAG(std::string, binary, "", "Binary to execute");
ABSL_FLAG(bool, debug_axi, false, "Enable AXI traffic debugging");
struct SlogIO {
sc_signal<bool> valid;
sc_signal<sc_bv<5>> addr;
sc_signal<sc_bv<32>> data;
};
struct DebugIO {
sc_signal<sc_bv<4>> en;
sc_signal<sc_bv<32>> cycles;
sc_signal<sc_bv<32>> addr_0;
sc_signal<sc_bv<32>> addr_1;
sc_signal<sc_bv<32>> addr_2;
sc_signal<sc_bv<32>> addr_3;
sc_signal<sc_bv<32>> inst_0;
sc_signal<sc_bv<32>> inst_1;
sc_signal<sc_bv<32>> inst_2;
sc_signal<sc_bv<32>> inst_3;
};
struct CoreMiniAxi_tb : Sysc_tb {
sc_in<bool> io_halted;
sc_in<bool> io_fault;
sc_in<bool> io_wfi;
sc_out<bool> io_irq;
sc_out<bool> io_te;
CoreMiniAxi_tb(sc_module_name n, int loops, bool random, std::string binary)
: Sysc_tb(n, loops, random),
file_name_(binary),
tg_("traffic_generator"),
tlm2axi_bridge_("tlm2axi_bridge"),
axi2tlm_bridge_("axi2tlm_bridge"),
tlm2axi_checker_("tlm2axi_checker"),
axi2tlm_checker_("axi2tlm_checker"),
tlm2axi_signals_("tlm2axi_signals"),
axi2tlm_signals_("axi2tlm_signals"),
xbar_("xbar") {
if (CoreMiniAxi_tb::singleton_ != nullptr) {
CHECK(false);
}
CoreMiniAxi_tb::singleton_ = this;
// TLM2AXI
tlm2axi_bridge_.clk(clock);
tlm2axi_bridge_.resetn(resetn);
// AXI Protocol checker
tlm2axi_checker_.clk(clock);
tlm2axi_checker_.resetn(resetn);
// AXI2TLM
axi2tlm_bridge_.clk(clock);
axi2tlm_bridge_.resetn(resetn);
axi2tlm_checker_.clk(clock);
axi2tlm_checker_.resetn(resetn);
tlm2axi_signals_.connect(tlm2axi_bridge_);
tlm2axi_signals_.connect(tlm2axi_checker_);
axi2tlm_signals_.connect(axi2tlm_bridge_);
axi2tlm_signals_.connect(axi2tlm_checker_);
int fd = open(file_name_.c_str(), 0);
CHECK(fd > 0);
struct stat sb;
CHECK(fstat(fd, &sb) == 0);
file_size_ = sb.st_size;
file_data_ = mmap(nullptr, file_size_, PROT_READ, MAP_PRIVATE, fd, 0);
CHECK(file_data_ != MAP_FAILED);
close(fd);
uint32_t elf_magic = 0x464c457f;
uint8_t* data8 = reinterpret_cast<uint8_t*>(file_data_);
if (memcmp(file_data_, &elf_magic, sizeof(elf_magic)) == 0) {
std::vector<DataTransfer> elf_transfers;
const Elf32_Ehdr* elf_header = reinterpret_cast<Elf32_Ehdr*>(file_data_);
elf_transfers.reserve(3 * elf_header->e_phnum);
LoadElf(data8, [&elf_transfers](void* dest, const void* src, size_t count){
elf_transfers.push_back(utils::Write(
reinterpret_cast<uint64_t>(dest),
reinterpret_cast<uint8_t*>(const_cast<void*>(src)), count));
elf_transfers.push_back(utils::Read(
reinterpret_cast<uint64_t>(dest), count
));
elf_transfers.push_back(utils::Expect(
reinterpret_cast<uint8_t*>(const_cast<void*>(src)), count
));
return dest;
});
bin_transfer_ = std::make_unique<TrafficDesc>(utils::merge(elf_transfers));
} else {
// Transaction to fill ITCM with the provided binary.
bin_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(std::vector<DataTransfer>(
{utils::Write(0, data8, file_size_), utils::Read(0, file_size_),
utils::Expect(data8, file_size_)})));
}
// Transaction to disable the internal clock gate.
disable_cg_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(std::vector<DataTransfer>(
{utils::Write(csr_addr_, DATA(1, 0, 0, 0)), utils::Read(csr_addr_, 4),
utils::Expect(DATA(1, 0, 0, 0), 4)})));
// Transaction to release the reset signal.
release_reset_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(std::vector<DataTransfer>(
{utils::Write(csr_addr_, DATA(0, 0, 0, 0)), utils::Read(csr_addr_, 4),
utils::Expect(DATA(0, 0, 0, 0), 4)})));
// Transaction to read the status register.
status_read_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(std::vector<DataTransfer>(
{utils::Read(csr_addr_ + 0x8, 4), utils::Expect(DATA(1, 0, 0, 0), 4)})));
DataTransfer wrap_write, wrap_read, wrap_expect;
/* WRAP */
wrap_write.addr = 0x0;
wrap_write.cmd = DataTransfer::WRITE;
wrap_write.data =
DATA(0x81, 0x82, 0x83, 0x84, 0x71, 0x72, 0x73, 0x74, 0x91, 0x92, 0x93,
0x94, 0x81, 0x82, 0x83, 0x84, 0xa1, 0xa2, 0xa3, 0xa4, 0x91, 0x92,
0x93, 0x94, 0xb1, 0xb2, 0xb3, 0xb4, 0xa1, 0xa2, 0xa3, 0xa4);
wrap_write.byte_enable = nullptr;
wrap_write.length = 32;
wrap_write.streaming_width = 32;
wrap_write.ext.gen_attr.enabled = true;
wrap_write.ext.gen_attr.wrap = true;
wrap_read.addr = 0x0;
wrap_read.cmd = DataTransfer::READ;
wrap_read.byte_enable = nullptr;
wrap_read.length = 32;
wrap_read.streaming_width = 32;
wrap_read.ext.gen_attr.enabled = true;
wrap_read.ext.gen_attr.wrap = true;
wrap_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(std::vector<DataTransfer>({
utils::Write(0,
DATA(0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad),
32),
wrap_write,
wrap_read,
utils::Expect(DATA(0xa1, 0xa2, 0xa3, 0xa4, 0x91, 0x92, 0x93, 0x94,
0xb1, 0xb2, 0xb3, 0xb4, 0xa1, 0xa2, 0xa3, 0xa4,
0xa1, 0xa2, 0xa3, 0xa4, 0x91, 0x92, 0x93, 0x94,
0xb1, 0xb2, 0xb3, 0xb4, 0xa1, 0xa2, 0xa3, 0xa4),
32),
})));
uint32_t dummy_data = 0x1234abcd;
DataTransfer write32;
write32.addr = 0;
write32.cmd = DataTransfer::WRITE;
write32.data = reinterpret_cast<uint8_t*>(&dummy_data);
write32.length = 4;
write32.byte_enable = nullptr;
write32.byte_enable_length = 0;
write32.streaming_width = 4;
write32.ext.gen_attr.enabled = true;
write32.ext.gen_attr.burst_width = 4;
DataTransfer read32;
read32.addr = 0;
read32.cmd = DataTransfer::READ;
read32.data = reinterpret_cast<uint8_t*>(&dummy_data);
read32.length = 4;
read32.byte_enable = nullptr;
read32.byte_enable_length = 0;
read32.streaming_width = 4;
read32.ext.gen_attr.enabled = true;
read32.ext.gen_attr.burst_width = 4;
std::vector<DataTransfer> narrow_transfers;
narrow_transfers.push_back(write32);
narrow_transfers.push_back(read32);
narrow_transfers.push_back(utils::Expect(reinterpret_cast<uint8_t*>(&dummy_data), 4));
write32.addr = 4;
read32.addr = 4;
narrow_transfers.push_back(write32);
narrow_transfers.push_back(read32);
narrow_transfers.push_back(utils::Expect(reinterpret_cast<uint8_t*>(&dummy_data), 4));
write32.addr = 8;
read32.addr = 8;
narrow_transfers.push_back(write32);
narrow_transfers.push_back(read32);
narrow_transfers.push_back(utils::Expect(reinterpret_cast<uint8_t*>(&dummy_data), 4));
narrow_transfer_ =
std::make_unique<TrafficDesc>(utils::merge(narrow_transfers));
tg_.setStartDelay(sc_time(5, SC_US));
tg_.addTransfers(bin_transfer_.get(), 0,
CoreMiniAxi_tb::bin_transfer_done_cb);
tg_.socket.bind(tlm2axi_bridge_.tgt_socket);
if (absl::GetFlag(FLAGS_debug_axi)) {
tg_.enableDebug();
}
axi2tlm_bridge_.socket.bind(xbar_.socket());
}
~CoreMiniAxi_tb() {
if (file_data_) {
munmap(file_data_, file_size_);
file_data_ = nullptr;
file_size_ = 0;
}
singleton_ = nullptr;
}
void posedge() {
check(!io_fault, "io_fault");
static bool enqueued_csr_read = false;
if (io_halted && !enqueued_csr_read) {
enqueued_csr_read = true;
tg_.addTransfers(status_read_transfer_.get(), 0,
CoreMiniAxi_tb::status_read_transfer_done_cb);
}
static bool wfi_seen = false;
if (io_wfi && !wfi_seen) {
io_irq = true;
wfi_seen = true;
} else if (!io_wfi && wfi_seen) {
io_irq = false;
wfi_seen = false;
} else {
io_irq = false;
}
}
typedef AXISignals<KP_axi2AddrBits, // ADDR_WIDTH
KP_lsuDataBits, // DATA_WIDTH
KP_axi2IdBits, // ID_WIDTH
8, // AxLEN_WIDTH
2, // AxLOCK_WIDTH
0, 0, 0, 0, 0 // User
>
CoreMiniAxiSignals;
CoreMiniAxiSignals* tlm2axi_signals() { return &tlm2axi_signals_; }
CoreMiniAxiSignals* axi2tlm_signals() { return &axi2tlm_signals_; }
static void bin_transfer_done_cb(TLMTrafficGenerator* gen, int threadId) {
getSingleton()->bin_transfer_done_cb_(gen, threadId);
}
static void disable_cg_transfer_done_cb(TLMTrafficGenerator* gen,
int threadId) {
getSingleton()->disable_cg_transfer_done_cb_(gen, threadId);
}
static void status_read_transfer_done_cb(TLMTrafficGenerator* gen,
int threadId) {
getSingleton()->status_read_transfer_done_cb_(gen, threadId);
}
static void wrap_transfer_done_cb(TLMTrafficGenerator* gen, int threadId) {
getSingleton()->wrap_transfer_done_cb_(gen, threadId);
}
static void narrow_transfer_done_cb(TLMTrafficGenerator* gen, int threadId) {
getSingleton()->narrow_transfer_done_cb_(gen, threadId);
}
private:
std::string file_name_;
TLMTrafficGenerator tg_;
tlm2axi_bridge<KP_axi2AddrBits, KP_lsuDataBits, KP_axi2IdBits, 8, 2, 0, 0, 0,
0, 0>
tlm2axi_bridge_;
axi2tlm_bridge<KP_axi2AddrBits, KP_lsuDataBits, KP_axi2IdBits, 8, 2, 0, 0, 0,
0, 0>
axi2tlm_bridge_;
typedef AXIProtocolChecker<KP_axi2AddrBits, KP_lsuDataBits, KP_axi2IdBits, 8,
2, 0, 0, 0, 0, 0>
CoreMiniAxiProtocolChecker;
CoreMiniAxiProtocolChecker tlm2axi_checker_;
CoreMiniAxiProtocolChecker axi2tlm_checker_;
// NB: Used to bind bridge and checker, DUT needs manual wiring.
CoreMiniAxiSignals tlm2axi_signals_;
CoreMiniAxiSignals axi2tlm_signals_;
Xbar xbar_;
size_t file_size_;
void* file_data_ = nullptr;
std::unique_ptr<TrafficDesc> bin_transfer_;
void bin_transfer_done_cb_(TLMTrafficGenerator* gen, int threadId) {
tg_.addTransfers(disable_cg_transfer_.get(), 0,
CoreMiniAxi_tb::disable_cg_transfer_done_cb);
}
std::unique_ptr<TrafficDesc> disable_cg_transfer_;
void disable_cg_transfer_done_cb_(TLMTrafficGenerator* gen, int threadId) {
tg_.addTransfers(release_reset_transfer_.get(), 0);
}
std::unique_ptr<TrafficDesc> release_reset_transfer_;
std::unique_ptr<TrafficDesc> status_read_transfer_;
void status_read_transfer_done_cb_(TLMTrafficGenerator* gen, int threadId) {
tg_.addTransfers(wrap_transfer_.get(), 0,
CoreMiniAxi_tb::wrap_transfer_done_cb);
}
std::unique_ptr<TrafficDesc> wrap_transfer_;
void wrap_transfer_done_cb_(TLMTrafficGenerator* gen, int threadId) {
tg_.addTransfers(narrow_transfer_.get(), 0,
CoreMiniAxi_tb::narrow_transfer_done_cb);
}
std::unique_ptr<TrafficDesc> narrow_transfer_;
void narrow_transfer_done_cb_(TLMTrafficGenerator* gen, int threadId) {
sc_stop();
}
static CoreMiniAxi_tb* singleton_;
static CoreMiniAxi_tb* getSingleton() { return singleton_; }
static constexpr uint32_t csr_addr_ = 0x30000;
};
CoreMiniAxi_tb* CoreMiniAxi_tb::singleton_ = nullptr;
static void run(const char* name, const std::string binary, const int cycles,
const bool trace) {
VCoreMiniAxi core(name);
CoreMiniAxi_tb tb("CoreMiniAxi_tb", cycles, /* random= */ false, binary);
sc_signal<bool> io_halted;
sc_signal<bool> io_fault;
sc_signal<bool> io_wfi;
sc_signal<bool> io_irq;
sc_signal<bool> io_te;
tb.io_halted(io_halted);
tb.io_fault(io_fault);
tb.io_wfi(io_wfi);
tb.io_irq(io_irq);
tb.io_te(io_te);
core.io_aclk(tb.clock);
core.io_aresetn(tb.resetn);
core.io_halted(io_halted);
core.io_fault(io_fault);
core.io_wfi(io_wfi);
core.io_irq(io_irq);
core.io_te(io_te);
SlogIO slog;
core.io_slog_valid(slog.valid);
core.io_slog_addr(slog.addr);
core.io_slog_data(slog.data);
DebugIO debug;
core.io_debug_en(debug.en);
core.io_debug_cycles(debug.cycles);
core.io_debug_addr_0(debug.addr_0);
core.io_debug_addr_1(debug.addr_1);
core.io_debug_addr_2(debug.addr_2);
core.io_debug_addr_3(debug.addr_3);
core.io_debug_inst_0(debug.inst_0);
core.io_debug_inst_1(debug.inst_1);
core.io_debug_inst_2(debug.inst_2);
core.io_debug_inst_3(debug.inst_3);
// AR
core.io_axi_master_read_addr_ready(tb.axi2tlm_signals()->arready);
core.io_axi_master_read_addr_valid(tb.axi2tlm_signals()->arvalid);
core.io_axi_master_read_addr_bits_addr(tb.axi2tlm_signals()->araddr);
core.io_axi_master_read_addr_bits_prot(tb.axi2tlm_signals()->arprot);
core.io_axi_master_read_addr_bits_id(tb.axi2tlm_signals()->arid);
core.io_axi_master_read_addr_bits_len(tb.axi2tlm_signals()->arlen);
core.io_axi_master_read_addr_bits_size(tb.axi2tlm_signals()->arsize);
core.io_axi_master_read_addr_bits_burst(tb.axi2tlm_signals()->arburst);
core.io_axi_master_read_addr_bits_lock(tb.axi2tlm_signals()->arlock);
core.io_axi_master_read_addr_bits_cache(tb.axi2tlm_signals()->arcache);
core.io_axi_master_read_addr_bits_qos(tb.axi2tlm_signals()->arqos);
core.io_axi_master_read_addr_bits_region(tb.axi2tlm_signals()->arregion);
// R
core.io_axi_master_read_data_ready(tb.axi2tlm_signals()->rready);
core.io_axi_master_read_data_valid(tb.axi2tlm_signals()->rvalid);
core.io_axi_master_read_data_bits_data(tb.axi2tlm_signals()->rdata);
core.io_axi_master_read_data_bits_id(tb.axi2tlm_signals()->rid);
core.io_axi_master_read_data_bits_resp(tb.axi2tlm_signals()->rresp);
core.io_axi_master_read_data_bits_last(tb.axi2tlm_signals()->rlast);
// AW
core.io_axi_master_write_addr_ready(tb.axi2tlm_signals()->awready);
core.io_axi_master_write_addr_valid(tb.axi2tlm_signals()->awvalid);
core.io_axi_master_write_addr_bits_addr(tb.axi2tlm_signals()->awaddr);
core.io_axi_master_write_addr_bits_prot(tb.axi2tlm_signals()->awprot);
core.io_axi_master_write_addr_bits_id(tb.axi2tlm_signals()->awid);
core.io_axi_master_write_addr_bits_len(tb.axi2tlm_signals()->awlen);
core.io_axi_master_write_addr_bits_size(tb.axi2tlm_signals()->awsize);
core.io_axi_master_write_addr_bits_burst(tb.axi2tlm_signals()->awburst);
core.io_axi_master_write_addr_bits_lock(tb.axi2tlm_signals()->awlock);
core.io_axi_master_write_addr_bits_cache(tb.axi2tlm_signals()->awcache);
core.io_axi_master_write_addr_bits_qos(tb.axi2tlm_signals()->awqos);
core.io_axi_master_write_addr_bits_region(tb.axi2tlm_signals()->awregion);
// W
core.io_axi_master_write_data_ready(tb.axi2tlm_signals()->wready);
core.io_axi_master_write_data_valid(tb.axi2tlm_signals()->wvalid);
core.io_axi_master_write_data_bits_data(tb.axi2tlm_signals()->wdata);
core.io_axi_master_write_data_bits_last(tb.axi2tlm_signals()->wlast);
core.io_axi_master_write_data_bits_strb(tb.axi2tlm_signals()->wstrb);
// B
core.io_axi_master_write_resp_ready(tb.axi2tlm_signals()->bready);
core.io_axi_master_write_resp_valid(tb.axi2tlm_signals()->bvalid);
core.io_axi_master_write_resp_bits_id(tb.axi2tlm_signals()->bid);
core.io_axi_master_write_resp_bits_resp(tb.axi2tlm_signals()->bresp);
// AR
core.io_axi_slave_read_addr_ready(tb.tlm2axi_signals()->arready);
core.io_axi_slave_read_addr_valid(tb.tlm2axi_signals()->arvalid);
core.io_axi_slave_read_addr_bits_addr(tb.tlm2axi_signals()->araddr);
core.io_axi_slave_read_addr_bits_prot(tb.tlm2axi_signals()->arprot);
core.io_axi_slave_read_addr_bits_id(tb.tlm2axi_signals()->arid);
core.io_axi_slave_read_addr_bits_len(tb.tlm2axi_signals()->arlen);
core.io_axi_slave_read_addr_bits_size(tb.tlm2axi_signals()->arsize);
core.io_axi_slave_read_addr_bits_burst(tb.tlm2axi_signals()->arburst);
core.io_axi_slave_read_addr_bits_lock(tb.tlm2axi_signals()->arlock);
core.io_axi_slave_read_addr_bits_cache(tb.tlm2axi_signals()->arcache);
core.io_axi_slave_read_addr_bits_qos(tb.tlm2axi_signals()->arqos);
core.io_axi_slave_read_addr_bits_region(tb.tlm2axi_signals()->arregion);
// R
core.io_axi_slave_read_data_ready(tb.tlm2axi_signals()->rready);
core.io_axi_slave_read_data_valid(tb.tlm2axi_signals()->rvalid);
core.io_axi_slave_read_data_bits_data(tb.tlm2axi_signals()->rdata);
core.io_axi_slave_read_data_bits_id(tb.tlm2axi_signals()->rid);
core.io_axi_slave_read_data_bits_resp(tb.tlm2axi_signals()->rresp);
core.io_axi_slave_read_data_bits_last(tb.tlm2axi_signals()->rlast);
// AW
core.io_axi_slave_write_addr_ready(tb.tlm2axi_signals()->awready);
core.io_axi_slave_write_addr_valid(tb.tlm2axi_signals()->awvalid);
core.io_axi_slave_write_addr_bits_addr(tb.tlm2axi_signals()->awaddr);
core.io_axi_slave_write_addr_bits_prot(tb.tlm2axi_signals()->awprot);
core.io_axi_slave_write_addr_bits_id(tb.tlm2axi_signals()->awid);
core.io_axi_slave_write_addr_bits_len(tb.tlm2axi_signals()->awlen);
core.io_axi_slave_write_addr_bits_size(tb.tlm2axi_signals()->awsize);
core.io_axi_slave_write_addr_bits_burst(tb.tlm2axi_signals()->awburst);
core.io_axi_slave_write_addr_bits_lock(tb.tlm2axi_signals()->awlock);
core.io_axi_slave_write_addr_bits_cache(tb.tlm2axi_signals()->awcache);
core.io_axi_slave_write_addr_bits_qos(tb.tlm2axi_signals()->awqos);
core.io_axi_slave_write_addr_bits_region(tb.tlm2axi_signals()->awregion);
// W
core.io_axi_slave_write_data_ready(tb.tlm2axi_signals()->wready);
core.io_axi_slave_write_data_valid(tb.tlm2axi_signals()->wvalid);
core.io_axi_slave_write_data_bits_data(tb.tlm2axi_signals()->wdata);
core.io_axi_slave_write_data_bits_last(tb.tlm2axi_signals()->wlast);
core.io_axi_slave_write_data_bits_strb(tb.tlm2axi_signals()->wstrb);
// B
core.io_axi_slave_write_resp_ready(tb.tlm2axi_signals()->bready);
core.io_axi_slave_write_resp_valid(tb.tlm2axi_signals()->bvalid);
core.io_axi_slave_write_resp_bits_id(tb.tlm2axi_signals()->bid);
core.io_axi_slave_write_resp_bits_resp(tb.tlm2axi_signals()->bresp);
if (trace) {
tb.trace(&core);
}
tb.start();
}
extern "C" int sc_main(int argc, char** argv) {
absl::SetProgramUsageMessage("CoreMiniAxi simulator");
auto args = absl::ParseCommandLine(argc, argv);
argc = args.size();
argv = &args[0];
if (absl::GetFlag(FLAGS_binary) == "") {
LOG(ERROR) << "--binary is required!";
return -1;
}
run(Sysc_tb::get_name(argv[0]), absl::GetFlag(FLAGS_binary),
absl::GetFlag(FLAGS_cycles), absl::GetFlag(FLAGS_trace));
return 0;
}