blob: 9c77ecd0672b2e59f93e1f7d33bf85d8c161c13b [file] [log] [blame]
// Copyright 2023 Google LLC
#ifndef TESTS_VERILATOR_SIM_MATCHA_KELVIN_IF_H_
#define TESTS_VERILATOR_SIM_MATCHA_KELVIN_IF_H_
#include "tests/verilator_sim/kelvin/memory_if.h"
#include "tests/verilator_sim/kelvin/kelvin_cfg.h"
// [Bus] addr
// 1cc [SRAM] addr
// 2cc [SRAM] rdata
// [Bus] rdata
constexpr int kWaitState = 2;
constexpr int kBusBits = 256;
struct Kelvin_if : Memory_if {
sc_in<bool> io_bus_cvalid;
sc_out<bool> io_bus_cready;
sc_in<bool> io_bus_cwrite;
sc_in<sc_bv<7> > io_bus_cid;
sc_in<sc_bv<32> > io_bus_caddr;
sc_in<sc_bv<kBusBits> > io_bus_wdata;
sc_in<sc_bv<32> > io_bus_wmask;
sc_out<bool> io_bus_rvalid;
sc_out<sc_bv<7> > io_bus_rid;
sc_out<sc_bv<kBusBits> > io_bus_rdata;
Kelvin_if(sc_module_name n, const char* bin) : Memory_if(n, bin) {
for (int i = 0; i < kBusBits / 32; ++i) {
runused_.set_word(i, 0);
}
}
void eval() {
if (reset) {
return;
}
cycle_++;
io_bus_cready = true;
// Bus read.
if (io_bus_cvalid && io_bus_cready && !io_bus_cwrite) {
sc_bv<kBusBits> rdata;
uint32_t addr = io_bus_caddr.read().get_word(0);
uint32_t words[kBusBits / 32];
Read(addr, kBusBits / 8, (uint8_t*) words);
for (int i = 0; i < kBusBits / 32; ++i) {
rdata.set_word(i, words[i]);
}
resp_t resp;
resp.cycle = cycle_;
resp.id = io_bus_cid.read().get_word(0);
for (int i = 0; i < kBusBits / 32; ++i) {
resp.data.set_word(i, words[i]);
}
resp_.write(resp);
}
// Bus read response.
resp_t resp;
bool read = resp_.next(resp);
if (read && (cycle_ - resp.cycle) >= kWaitState) {
assert(resp_.remove());
io_bus_rid = resp.id;
io_bus_rdata = resp.data;
} else {
read = false;
io_bus_rid = 0;
io_bus_rdata = runused_;
}
io_bus_rvalid = read;
// Bus write.
if (io_bus_cvalid && io_bus_cready && io_bus_cwrite) {
uint8_t wdata[kBusBits / 8];
uint32_t addr = io_bus_caddr.read().get_word(0);
uint32_t* p_wdata = (uint32_t*) wdata;
for (int i = 0; i < kBusBits / 32; ++i) {
p_wdata[i] = io_bus_wdata.read().get_word(i);
}
for (int i = 0; i < kBusBits / 8; ++i) {
if (io_bus_wmask.read().get_bit(i) != 0) {
Write(addr + i, 1, wdata + i);
}
}
}
}
private:
uint32_t cycle_ = 0;
struct resp_t {
uint32_t cycle;
uint32_t id : 7;
sc_bv<kBusBits> data;
};
fifo_t<resp_t> resp_;
sc_bv<kBusBits> runused_;
};
#endif // TESTS_VERILATOR_SIM_MATCHA_KELVIN_IF_H_