Add support for TightlyCoupledMemory for SpikeTile
This commit is contained in:
@@ -6,6 +6,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vpi_user.h>
|
#include <vpi_user.h>
|
||||||
#include <svdpi.h>
|
#include <svdpi.h>
|
||||||
|
#include "testchip_tsi.h"
|
||||||
|
|
||||||
|
extern testchip_tsi_t* tsi;
|
||||||
|
|
||||||
enum transfer_t {
|
enum transfer_t {
|
||||||
NToB,
|
NToB,
|
||||||
@@ -73,6 +76,12 @@ public:
|
|||||||
void dcache_b(uint64_t address, uint64_t source, int param);
|
void dcache_b(uint64_t address, uint64_t source, int param);
|
||||||
bool dcache_c(uint64_t *address, uint64_t* source, int* param, unsigned char* voluntary, unsigned char* has_data, uint64_t* data[8]);
|
bool dcache_c(uint64_t *address, uint64_t* source, int* param, unsigned char* voluntary, unsigned char* has_data, uint64_t* data[8]);
|
||||||
void dcache_d(uint64_t sourceid, uint64_t data[8], unsigned char has_data, unsigned char grantack);
|
void dcache_d(uint64_t sourceid, uint64_t data[8], unsigned char has_data, unsigned char grantack);
|
||||||
|
|
||||||
|
void tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size);
|
||||||
|
bool tcm_d(uint64_t *data);
|
||||||
|
|
||||||
|
void loadmem(const char* fname);
|
||||||
|
|
||||||
void drain_stq();
|
void drain_stq();
|
||||||
bool stq_empty() { return st_q.size() == 0; };
|
bool stq_empty() { return st_q.size() == 0; };
|
||||||
|
|
||||||
@@ -86,9 +95,13 @@ public:
|
|||||||
char* readonly_uncacheable,
|
char* readonly_uncacheable,
|
||||||
char* executable,
|
char* executable,
|
||||||
size_t icache_sourceids,
|
size_t icache_sourceids,
|
||||||
size_t dcache_sourceids);
|
size_t dcache_sourceids,
|
||||||
|
size_t tcm_base,
|
||||||
|
size_t tcm_size);
|
||||||
uint64_t cycle;
|
uint64_t cycle;
|
||||||
bool use_stq;
|
bool use_stq;
|
||||||
|
htif_t *htif;
|
||||||
|
bool fast_clint;
|
||||||
private:
|
private:
|
||||||
bool handle_cache_access(reg_t addr, size_t len,
|
bool handle_cache_access(reg_t addr, size_t len,
|
||||||
uint8_t* load_bytes,
|
uint8_t* load_bytes,
|
||||||
@@ -133,6 +146,11 @@ private:
|
|||||||
uint64_t mmio_stdata;
|
uint64_t mmio_stdata;
|
||||||
size_t mmio_len;
|
size_t mmio_len;
|
||||||
uint64_t mmio_lddata;
|
uint64_t mmio_lddata;
|
||||||
|
|
||||||
|
uint64_t tcm_base;
|
||||||
|
uint64_t tcm_size;
|
||||||
|
uint8_t* tcm;
|
||||||
|
std::vector<uint64_t> tcm_q;
|
||||||
};
|
};
|
||||||
|
|
||||||
class tile_t {
|
class tile_t {
|
||||||
@@ -163,6 +181,7 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
int dcache_sets, int dcache_ways,
|
int dcache_sets, int dcache_ways,
|
||||||
char* cacheable, char* uncacheable, char* readonly_uncacheable, char* executable,
|
char* cacheable, char* uncacheable, char* readonly_uncacheable, char* executable,
|
||||||
int icache_sourceids, int dcache_sourceids,
|
int icache_sourceids, int dcache_sourceids,
|
||||||
|
long long int tcm_base, long long int tcm_size,
|
||||||
long long int reset_vector,
|
long long int reset_vector,
|
||||||
long long int ipc,
|
long long int ipc,
|
||||||
long long int cycle,
|
long long int cycle,
|
||||||
@@ -237,7 +256,18 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
int* mmio_a_size,
|
int* mmio_a_size,
|
||||||
|
|
||||||
unsigned char mmio_d_valid,
|
unsigned char mmio_d_valid,
|
||||||
long long int mmio_d_data
|
long long int mmio_d_data,
|
||||||
|
|
||||||
|
unsigned char tcm_a_valid,
|
||||||
|
long long int tcm_a_address,
|
||||||
|
long long int tcm_a_data,
|
||||||
|
int tcm_a_mask,
|
||||||
|
int tcm_a_opcode,
|
||||||
|
int tcm_a_size,
|
||||||
|
|
||||||
|
unsigned char* tcm_d_valid,
|
||||||
|
unsigned char tcm_d_ready,
|
||||||
|
long long int* tcm_d_data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!host) {
|
if (!host) {
|
||||||
@@ -251,7 +281,8 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
chipyard_simif_t* simif = new chipyard_simif_t(icache_ways, icache_sets,
|
chipyard_simif_t* simif = new chipyard_simif_t(icache_ways, icache_sets,
|
||||||
dcache_ways, dcache_sets,
|
dcache_ways, dcache_sets,
|
||||||
cacheable, uncacheable, readonly_uncacheable, executable,
|
cacheable, uncacheable, readonly_uncacheable, executable,
|
||||||
icache_sourceids, dcache_sourceids);
|
icache_sourceids, dcache_sourceids,
|
||||||
|
tcm_base, tcm_size);
|
||||||
std::string* isastr = new std::string(isa);
|
std::string* isastr = new std::string(isa);
|
||||||
cfg_t* cfg = new cfg_t(std::make_pair(0, 0),
|
cfg_t* cfg = new cfg_t(std::make_pair(0, 0),
|
||||||
nullptr,
|
nullptr,
|
||||||
@@ -278,6 +309,7 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
s_vpi_vlog_info vinfo;
|
s_vpi_vlog_info vinfo;
|
||||||
if (!vpi_get_vlog_info(&vinfo))
|
if (!vpi_get_vlog_info(&vinfo))
|
||||||
abort();
|
abort();
|
||||||
|
std::string loadmem_file = "";
|
||||||
for (int i = 1; i < vinfo.argc; i++) {
|
for (int i = 1; i < vinfo.argc; i++) {
|
||||||
std::string arg(vinfo.argv[i]);
|
std::string arg(vinfo.argv[i]);
|
||||||
if (arg == "+spike-debug") {
|
if (arg == "+spike-debug") {
|
||||||
@@ -286,7 +318,15 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
if (arg == "+spike-stq") {
|
if (arg == "+spike-stq") {
|
||||||
simif->use_stq = true;
|
simif->use_stq = true;
|
||||||
}
|
}
|
||||||
|
if (arg.find("+loadmem=") == 0) {
|
||||||
|
loadmem_file = arg.substr(strlen("+loadmem="));
|
||||||
}
|
}
|
||||||
|
if (arg == "+spike-fast-clint") {
|
||||||
|
simif->fast_clint = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loadmem_file != "" && tcm_size > 0)
|
||||||
|
simif->loadmem(loadmem_file.c_str());
|
||||||
|
|
||||||
p->reset();
|
p->reset();
|
||||||
p->get_state()->pc = reset_vector;
|
p->get_state()->pc = reset_vector;
|
||||||
@@ -296,6 +336,9 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
tile_t* tile = tiles[hartid];
|
tile_t* tile = tiles[hartid];
|
||||||
chipyard_simif_t* simif = tile->simif;
|
chipyard_simif_t* simif = tile->simif;
|
||||||
processor_t* proc = tile->proc;
|
processor_t* proc = tile->proc;
|
||||||
|
if (!simif->htif && tsi) {
|
||||||
|
simif->htif = (htif_t*) tsi;
|
||||||
|
}
|
||||||
|
|
||||||
simif->cycle = cycle;
|
simif->cycle = cycle;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@@ -357,6 +400,13 @@ extern "C" void spike_tile(int hartid, char* isa,
|
|||||||
if (mmio_d_valid) {
|
if (mmio_d_valid) {
|
||||||
simif->mmio_d(mmio_d_data);
|
simif->mmio_d(mmio_d_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tcm_a_valid) {
|
||||||
|
simif->tcm_a(tcm_a_address, tcm_a_data, tcm_a_mask, tcm_a_opcode, tcm_a_size);
|
||||||
|
}
|
||||||
|
if (tcm_d_ready) {
|
||||||
|
*tcm_d_valid = simif->tcm_d((uint64_t*)tcm_d_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -369,14 +419,20 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
|
|||||||
char* readonly_uncacheable,
|
char* readonly_uncacheable,
|
||||||
char* executable,
|
char* executable,
|
||||||
size_t ic_sourceids,
|
size_t ic_sourceids,
|
||||||
size_t dc_sourceids
|
size_t dc_sourceids,
|
||||||
|
size_t tcm_base,
|
||||||
|
size_t tcm_size
|
||||||
) :
|
) :
|
||||||
cycle(0),
|
cycle(0),
|
||||||
use_stq(false),
|
use_stq(false),
|
||||||
|
htif(nullptr),
|
||||||
|
fast_clint(false),
|
||||||
icache_ways(icache_ways),
|
icache_ways(icache_ways),
|
||||||
icache_sets(icache_sets),
|
icache_sets(icache_sets),
|
||||||
dcache_ways(dcache_ways),
|
dcache_ways(dcache_ways),
|
||||||
dcache_sets(dcache_sets),
|
dcache_sets(dcache_sets),
|
||||||
|
tcm_base(tcm_base),
|
||||||
|
tcm_size(tcm_size),
|
||||||
mmio_valid(false),
|
mmio_valid(false),
|
||||||
mmio_inflight(false)
|
mmio_inflight(false)
|
||||||
{
|
{
|
||||||
@@ -432,6 +488,8 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
|
|||||||
uint64_t size_int = std::stoul(size);
|
uint64_t size_int = std::stoul(size);
|
||||||
executables.push_back(mem_region_t { base_int, size_int });
|
executables.push_back(mem_region_t { base_int, size_int });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcm = (uint8_t*)malloc(tcm_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool chipyard_simif_t::reservable(reg_t addr) {
|
bool chipyard_simif_t::reservable(reg_t addr) {
|
||||||
@@ -440,12 +498,20 @@ bool chipyard_simif_t::reservable(reg_t addr) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool chipyard_simif_t::mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) {
|
bool chipyard_simif_t::mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) {
|
||||||
bool executable = false;
|
bool executable = false;
|
||||||
|
|
||||||
|
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||||
|
memcpy(bytes, tcm + addr - tcm_base, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& r: executables) {
|
for (auto& r: executables) {
|
||||||
if (addr >= r.base && addr + len <= r.base + r.size) {
|
if (addr >= r.base && addr + len <= r.base + r.size) {
|
||||||
executable = true;
|
executable = true;
|
||||||
@@ -466,6 +532,10 @@ bool chipyard_simif_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) {
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
bool cacheable = false;
|
bool cacheable = false;
|
||||||
bool readonly = false;
|
bool readonly = false;
|
||||||
|
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||||
|
memcpy(bytes, tcm + addr - tcm_base, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (auto& r: cacheables) {
|
for (auto& r: cacheables) {
|
||||||
if (addr >= r.base && addr + len <= r.base + r.size) {
|
if (addr >= r.base && addr + len <= r.base + r.size) {
|
||||||
cacheable = true;
|
cacheable = true;
|
||||||
@@ -829,6 +899,11 @@ bool chipyard_simif_t::dcache_c(uint64_t* address, uint64_t* source, int* param,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) {
|
bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) {
|
||||||
|
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||||
|
memcpy(tcm + addr - tcm_base, bytes, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
bool cacheable = false;
|
bool cacheable = false;
|
||||||
for (auto& r: cacheables) {
|
for (auto& r: cacheables) {
|
||||||
@@ -899,11 +974,64 @@ void chipyard_simif_t::dcache_d(uint64_t sourceid, uint64_t data[8], unsigned ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void chipyard_simif_t::tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size) {
|
||||||
|
bool load = opcode == 4;
|
||||||
|
uint64_t rdata = 0;
|
||||||
|
memcpy(&rdata, tcm + address - tcm_base, 8);
|
||||||
|
tcm_q.push_back(rdata);
|
||||||
|
|
||||||
|
if (!load) {
|
||||||
|
for (size_t i = 0; i < 8; i++) {
|
||||||
|
if ((mask >> i) & 1) {
|
||||||
|
memcpy(tcm + address - tcm_base + i, ((uint8_t*)&data) + i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool chipyard_simif_t::tcm_d(uint64_t* data) {
|
||||||
|
if (tcm_q.size() == 0)
|
||||||
|
return false;
|
||||||
|
*data = tcm_q[0];
|
||||||
|
tcm_q.erase(tcm_q.begin());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define parse_nibble(c) ((c) >= 'a' ? (c)-'a'+10 : (c)-'0')
|
||||||
|
void chipyard_simif_t::loadmem(const char* fname) {
|
||||||
|
std::ifstream in(fname);
|
||||||
|
std::string line;
|
||||||
|
if (!in.is_open()) {
|
||||||
|
printf("SpikeTile couldn't open loadmem file %s\n", fname);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
size_t fsize = 0;
|
||||||
|
size_t start = 0;
|
||||||
|
while (std::getline(in, line)) {
|
||||||
|
for (ssize_t i = line.length()-2, j = 0; i >= 0; i -= 2, j++) {
|
||||||
|
char byte = (parse_nibble(line[i]) << 4) | parse_nibble(line[i+1]);
|
||||||
|
ssize_t addr = (start + j) % tcm_size;
|
||||||
|
tcm[addr] = (uint8_t)byte;
|
||||||
|
}
|
||||||
|
start += line.length()/2;
|
||||||
|
fsize += line.length()/2;
|
||||||
|
|
||||||
|
if (fsize > tcm_size) {
|
||||||
|
fprintf(stderr, "Loadmem file is too large\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool insn_should_fence(uint64_t bits) {
|
bool insn_should_fence(uint64_t bits) {
|
||||||
uint8_t opcode = bits & 0x7f;
|
uint8_t opcode = bits & 0x7f;
|
||||||
return opcode == 0b0101111 || opcode == 0b0001111;
|
return opcode == 0b0101111 || opcode == 0b0001111;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool insn_is_wfi(uint64_t bits) {
|
||||||
|
return bits == 0x10500073;
|
||||||
|
}
|
||||||
|
|
||||||
void spike_thread_main(void* arg)
|
void spike_thread_main(void* arg)
|
||||||
{
|
{
|
||||||
tile_t* tile = (tile_t*) arg;
|
tile_t* tile = (tile_t*) arg;
|
||||||
@@ -913,12 +1041,30 @@ void spike_thread_main(void* arg)
|
|||||||
}
|
}
|
||||||
while (tile->max_insns != 0) {
|
while (tile->max_insns != 0) {
|
||||||
// TODO: Fences don't work
|
// TODO: Fences don't work
|
||||||
// uint64_t last_bits = tile->proc->get_last_bits();
|
//uint64_t last_bits = tile->proc->get_last_bits();
|
||||||
// if (insn_should_fence(last_bits) && !tile->simif->stq_empty()) {
|
// if (insn_should_fence(last_bits) && !tile->simif->stq_empty()) {
|
||||||
// host->switch_to();
|
// host->switch_to();
|
||||||
// }
|
// }
|
||||||
|
uint64_t old_minstret = tile->proc->get_state()->minstret->read();
|
||||||
tile->proc->step(1);
|
tile->proc->step(1);
|
||||||
tile->max_insns--;
|
tile->max_insns--;
|
||||||
|
if (tile->proc->is_waiting_for_interrupt()) {
|
||||||
|
if (tile->simif->fast_clint) {
|
||||||
|
tile->proc->get_state()->mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP);
|
||||||
|
}
|
||||||
|
tile->max_insns = 0;
|
||||||
|
}
|
||||||
|
if (tile->max_insns % 100 == 0) {
|
||||||
|
uint64_t tohost_addr = tile->simif->htif ? tile->simif->htif->get_tohost_addr() : 0;
|
||||||
|
uint64_t fromhost_addr = tile->simif->htif ? tile->simif->htif->get_fromhost_addr() : 0;
|
||||||
|
auto& mem_read = tile->proc->get_state()->log_mem_read;
|
||||||
|
reg_t mem_read_addr = mem_read.empty() ? 0 : std::get<0>(mem_read[0]);
|
||||||
|
if ((old_minstret == tile->proc->get_state()->minstret->read()) ||
|
||||||
|
(tohost_addr && mem_read_addr == tohost_addr) ||
|
||||||
|
(fromhost_addr && mem_read_addr == fromhost_addr)) {
|
||||||
|
tile->max_insns == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
tile->proc->get_state()->mcycle->write(tile->simif->cycle);
|
tile->proc->get_state()->mcycle->write(tile->simif->cycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import "DPI-C" function void spike_tile(input int hartid,
|
|||||||
input string executable,
|
input string executable,
|
||||||
input int icache_sourceids,
|
input int icache_sourceids,
|
||||||
input int dcache_sourceids,
|
input int dcache_sourceids,
|
||||||
|
input longint tcm_base,
|
||||||
|
input longint tcm_size,
|
||||||
input longint reset_vector,
|
input longint reset_vector,
|
||||||
input longint ipc,
|
input longint ipc,
|
||||||
input longint cycle,
|
input longint cycle,
|
||||||
@@ -89,7 +91,18 @@ import "DPI-C" function void spike_tile(input int hartid,
|
|||||||
output int mmio_a_size,
|
output int mmio_a_size,
|
||||||
|
|
||||||
input bit mmio_d_valid,
|
input bit mmio_d_valid,
|
||||||
input longint mmio_d_data
|
input longint mmio_d_data,
|
||||||
|
|
||||||
|
input bit tcm_a_valid,
|
||||||
|
input longint tcm_a_address,
|
||||||
|
input longint tcm_a_data,
|
||||||
|
input int tcm_a_mask,
|
||||||
|
input int tcm_a_opcode,
|
||||||
|
input int tcm_a_size,
|
||||||
|
|
||||||
|
output bit tcm_d_valid,
|
||||||
|
input bit tcm_d_ready,
|
||||||
|
output longint tcm_d_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -106,7 +119,9 @@ module SpikeBlackBox #(
|
|||||||
parameter READONLY_UNCACHEABLE,
|
parameter READONLY_UNCACHEABLE,
|
||||||
parameter EXECUTABLE,
|
parameter EXECUTABLE,
|
||||||
parameter ICACHE_SOURCEIDS,
|
parameter ICACHE_SOURCEIDS,
|
||||||
parameter DCACHE_SOURCEIDS )(
|
parameter DCACHE_SOURCEIDS,
|
||||||
|
parameter TCM_BASE,
|
||||||
|
parameter TCM_SIZE)(
|
||||||
input clock,
|
input clock,
|
||||||
input reset,
|
input reset,
|
||||||
input [63:0] reset_vector,
|
input [63:0] reset_vector,
|
||||||
@@ -185,7 +200,18 @@ module SpikeBlackBox #(
|
|||||||
output [31:0] mmio_a_size,
|
output [31:0] mmio_a_size,
|
||||||
|
|
||||||
input mmio_d_valid,
|
input mmio_d_valid,
|
||||||
input [63:0] mmio_d_data
|
input [63:0] mmio_d_data,
|
||||||
|
|
||||||
|
input tcm_a_valid,
|
||||||
|
input [63:0] tcm_a_address,
|
||||||
|
input [63:0] tcm_a_data,
|
||||||
|
input [31:0] tcm_a_mask,
|
||||||
|
input [31:0] tcm_a_opcode,
|
||||||
|
input [31:0] tcm_a_size,
|
||||||
|
|
||||||
|
output tcm_d_valid,
|
||||||
|
input tcm_d_ready,
|
||||||
|
output [63:0] tcm_d_data
|
||||||
);
|
);
|
||||||
|
|
||||||
longint __insns_retired;
|
longint __insns_retired;
|
||||||
@@ -257,6 +283,12 @@ module SpikeBlackBox #(
|
|||||||
reg [63:0] __dcache_c_data_6_reg;
|
reg [63:0] __dcache_c_data_6_reg;
|
||||||
reg [63:0] __dcache_c_data_7_reg;
|
reg [63:0] __dcache_c_data_7_reg;
|
||||||
|
|
||||||
|
wire __tcm_d_ready;
|
||||||
|
bit __tcm_d_valid;
|
||||||
|
longint __tcm_d_data;
|
||||||
|
|
||||||
|
reg __tcm_d_valid_reg;
|
||||||
|
reg [63:0] __tcm_d_data_reg;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -322,12 +354,18 @@ module SpikeBlackBox #(
|
|||||||
__dcache_c_data_6_reg <= 64'h0;
|
__dcache_c_data_6_reg <= 64'h0;
|
||||||
__dcache_c_data_7 = 64'h0;
|
__dcache_c_data_7 = 64'h0;
|
||||||
__dcache_c_data_7_reg <= 64'h0;
|
__dcache_c_data_7_reg <= 64'h0;
|
||||||
|
|
||||||
|
__tcm_d_valid = 1'b0;
|
||||||
|
__tcm_d_valid_reg <= 1'b0;
|
||||||
|
__tcm_d_data = 64'h0;
|
||||||
|
__tcm_d_data_reg <= 64'h0;
|
||||||
spike_tile_reset(HARTID);
|
spike_tile_reset(HARTID);
|
||||||
end else begin
|
end else begin
|
||||||
spike_tile(HARTID, ISA, PMPREGIONS,
|
spike_tile(HARTID, ISA, PMPREGIONS,
|
||||||
ICACHE_SETS, ICACHE_WAYS, DCACHE_SETS, DCACHE_WAYS,
|
ICACHE_SETS, ICACHE_WAYS, DCACHE_SETS, DCACHE_WAYS,
|
||||||
CACHEABLE, UNCACHEABLE, READONLY_UNCACHEABLE, EXECUTABLE,
|
CACHEABLE, UNCACHEABLE, READONLY_UNCACHEABLE, EXECUTABLE,
|
||||||
ICACHE_SOURCEIDS, DCACHE_SOURCEIDS,
|
ICACHE_SOURCEIDS, DCACHE_SOURCEIDS,
|
||||||
|
TCM_BASE, TCM_SIZE,
|
||||||
reset_vector, ipc, cycle, __insns_retired,
|
reset_vector, ipc, cycle, __insns_retired,
|
||||||
debug, mtip, msip, meip, seip,
|
debug, mtip, msip, meip, seip,
|
||||||
|
|
||||||
@@ -350,7 +388,10 @@ module SpikeBlackBox #(
|
|||||||
dcache_d_data_4, dcache_d_data_5, dcache_d_data_6, dcache_d_data_7,
|
dcache_d_data_4, dcache_d_data_5, dcache_d_data_6, dcache_d_data_7,
|
||||||
|
|
||||||
__mmio_a_ready, __mmio_a_valid, __mmio_a_address, __mmio_a_data, __mmio_a_store, __mmio_a_size,
|
__mmio_a_ready, __mmio_a_valid, __mmio_a_address, __mmio_a_data, __mmio_a_store, __mmio_a_size,
|
||||||
mmio_d_valid, mmio_d_data
|
mmio_d_valid, mmio_d_data,
|
||||||
|
|
||||||
|
tcm_a_valid, tcm_a_address, tcm_a_data, tcm_a_mask, tcm_a_opcode, tcm_a_size,
|
||||||
|
__tcm_d_valid, __tcm_d_ready, __tcm_d_data
|
||||||
);
|
);
|
||||||
__insns_retired_reg <= __insns_retired;
|
__insns_retired_reg <= __insns_retired;
|
||||||
|
|
||||||
@@ -385,6 +426,10 @@ module SpikeBlackBox #(
|
|||||||
__mmio_a_data_reg <= __mmio_a_data;
|
__mmio_a_data_reg <= __mmio_a_data;
|
||||||
__mmio_a_store_reg <= __mmio_a_store;
|
__mmio_a_store_reg <= __mmio_a_store;
|
||||||
__mmio_a_size_reg <= __mmio_a_size;
|
__mmio_a_size_reg <= __mmio_a_size;
|
||||||
|
|
||||||
|
__tcm_d_valid_reg <= __tcm_d_valid;
|
||||||
|
__tcm_d_data_reg <= __tcm_d_data;
|
||||||
|
|
||||||
end
|
end
|
||||||
end // always @ (posedge clock)
|
end // always @ (posedge clock)
|
||||||
assign insns_retired = __insns_retired_reg;
|
assign insns_retired = __insns_retired_reg;
|
||||||
@@ -424,6 +469,8 @@ module SpikeBlackBox #(
|
|||||||
assign mmio_a_size = __mmio_a_size_reg;
|
assign mmio_a_size = __mmio_a_size_reg;
|
||||||
assign __mmio_a_ready = mmio_a_ready;
|
assign __mmio_a_ready = mmio_a_ready;
|
||||||
|
|
||||||
|
assign tcm_d_valid = __tcm_d_valid_reg;
|
||||||
|
assign tcm_d_data = __tcm_d_data_reg;
|
||||||
|
assign __tcm_d_ready = tcm_d_ready;
|
||||||
|
|
||||||
endmodule;
|
endmodule;
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ import freechips.rocketchip.util._
|
|||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import freechips.rocketchip.prci.ClockSinkParameters
|
import freechips.rocketchip.prci.ClockSinkParameters
|
||||||
|
|
||||||
case class SpikeCoreParams(
|
case class SpikeCoreParams() extends CoreParams {
|
||||||
) extends CoreParams {
|
|
||||||
val useVM = true
|
val useVM = true
|
||||||
val useHypervisor = false
|
val useHypervisor = false
|
||||||
val useSupervisor = true
|
val useSupervisor = true
|
||||||
@@ -79,7 +78,8 @@ case class SpikeTileParams(
|
|||||||
hartId: Int = 0,
|
hartId: Int = 0,
|
||||||
val core: SpikeCoreParams = SpikeCoreParams(),
|
val core: SpikeCoreParams = SpikeCoreParams(),
|
||||||
icacheParams: ICacheParams = ICacheParams(nWays = 32),
|
icacheParams: ICacheParams = ICacheParams(nWays = 32),
|
||||||
dcacheParams: DCacheParams = DCacheParams(nWays = 32)
|
dcacheParams: DCacheParams = DCacheParams(nWays = 32),
|
||||||
|
tcmParams: Option[MasterPortParams] = None // tightly coupled memory
|
||||||
) extends InstantiableTileParams[SpikeTile]
|
) extends InstantiableTileParams[SpikeTile]
|
||||||
{
|
{
|
||||||
val name = Some("spike_tile")
|
val name = Some("spike_tile")
|
||||||
@@ -145,6 +145,27 @@ class SpikeTile(
|
|||||||
sourceId = IdRange(0, 1),
|
sourceId = IdRange(0, 1),
|
||||||
requestFifo = true))))))
|
requestFifo = true))))))
|
||||||
|
|
||||||
|
tlSlaveXbar.node :*= slaveNode
|
||||||
|
val tcmNode = spikeTileParams.tcmParams.map { tcmP =>
|
||||||
|
val device = new MemoryDevice
|
||||||
|
val base = AddressSet.misaligned(tcmP.base, tcmP.size)
|
||||||
|
val tcmNode = TLManagerNode(Seq(TLSlavePortParameters.v1(
|
||||||
|
managers = Seq(TLSlaveParameters.v1(
|
||||||
|
address = base,
|
||||||
|
resources = device.reg,
|
||||||
|
regionType = RegionType.IDEMPOTENT, // not cacheable
|
||||||
|
executable = true,
|
||||||
|
supportsGet = TransferSizes(1, 8),
|
||||||
|
supportsPutFull = TransferSizes(1, 8),
|
||||||
|
supportsPutPartial = TransferSizes(1, 8),
|
||||||
|
fifoId = Some(0)
|
||||||
|
)),
|
||||||
|
beatBytes = 8
|
||||||
|
)))
|
||||||
|
connectTLSlave(tcmNode := TLBuffer(), 8)
|
||||||
|
tcmNode
|
||||||
|
}
|
||||||
|
|
||||||
tlOtherMastersNode := TLBuffer() := tlMasterXbar.node
|
tlOtherMastersNode := TLBuffer() := tlMasterXbar.node
|
||||||
masterNode :=* tlOtherMastersNode
|
masterNode :=* tlOtherMastersNode
|
||||||
tlMasterXbar.node := TLWidthWidget(64) := TLBuffer():= icacheNode
|
tlMasterXbar.node := TLWidthWidget(64) := TLBuffer():= icacheNode
|
||||||
@@ -166,7 +187,9 @@ class SpikeBlackBox(
|
|||||||
cacheable_regions: String,
|
cacheable_regions: String,
|
||||||
uncacheable_regions: String,
|
uncacheable_regions: String,
|
||||||
readonly_uncacheable_regions: String,
|
readonly_uncacheable_regions: String,
|
||||||
executable_regions: String) extends BlackBox(Map(
|
executable_regions: String,
|
||||||
|
tcm_base: BigInt,
|
||||||
|
tcm_size: BigInt) extends BlackBox(Map(
|
||||||
"HARTID" -> IntParam(hartId),
|
"HARTID" -> IntParam(hartId),
|
||||||
"ISA" -> StringParam(isa),
|
"ISA" -> StringParam(isa),
|
||||||
"PMPREGIONS" -> IntParam(pmpregions),
|
"PMPREGIONS" -> IntParam(pmpregions),
|
||||||
@@ -179,7 +202,9 @@ class SpikeBlackBox(
|
|||||||
"UNCACHEABLE" -> StringParam(uncacheable_regions),
|
"UNCACHEABLE" -> StringParam(uncacheable_regions),
|
||||||
"READONLY_UNCACHEABLE" -> StringParam(readonly_uncacheable_regions),
|
"READONLY_UNCACHEABLE" -> StringParam(readonly_uncacheable_regions),
|
||||||
"CACHEABLE" -> StringParam(cacheable_regions),
|
"CACHEABLE" -> StringParam(cacheable_regions),
|
||||||
"EXECUTABLE" -> StringParam(executable_regions)
|
"EXECUTABLE" -> StringParam(executable_regions),
|
||||||
|
"TCM_BASE" -> IntParam(tcm_base),
|
||||||
|
"TCM_SIZE" -> IntParam(tcm_size)
|
||||||
)) with HasBlackBoxResource {
|
)) with HasBlackBoxResource {
|
||||||
|
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
@@ -258,6 +283,22 @@ class SpikeBlackBox(
|
|||||||
val data = Input(UInt(64.W))
|
val data = Input(UInt(64.W))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val tcm = new Bundle {
|
||||||
|
val a = new Bundle {
|
||||||
|
val valid = Input(Bool())
|
||||||
|
val address = Input(UInt(64.W))
|
||||||
|
val data = Input(UInt(64.W))
|
||||||
|
val mask = Input(UInt(32.W))
|
||||||
|
val opcode = Input(UInt(32.W))
|
||||||
|
val size = Input(UInt(32.W))
|
||||||
|
}
|
||||||
|
val d = new Bundle {
|
||||||
|
val valid = Output(Bool())
|
||||||
|
val ready = Input(Bool())
|
||||||
|
val data = Output(UInt(64.W))
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
addResource("/vsrc/spiketile.v")
|
addResource("/vsrc/spiketile.v")
|
||||||
addResource("/csrc/spiketile.cc")
|
addResource("/csrc/spiketile.cc")
|
||||||
@@ -289,7 +330,10 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
|||||||
tileParams.icache.get.nSets, tileParams.icache.get.nWays,
|
tileParams.icache.get.nSets, tileParams.icache.get.nWays,
|
||||||
tileParams.dcache.get.nSets, tileParams.dcache.get.nWays,
|
tileParams.dcache.get.nSets, tileParams.dcache.get.nWays,
|
||||||
tileParams.dcache.get.nMSHRs,
|
tileParams.dcache.get.nMSHRs,
|
||||||
cacheable_regions, uncacheable_regions, readonly_uncacheable_regions, executable_regions))
|
cacheable_regions, uncacheable_regions, readonly_uncacheable_regions, executable_regions,
|
||||||
|
outer.spikeTileParams.tcmParams.map(_.base).getOrElse(0),
|
||||||
|
outer.spikeTileParams.tcmParams.map(_.size).getOrElse(0)
|
||||||
|
))
|
||||||
spike.io.clock := clock.asBool
|
spike.io.clock := clock.asBool
|
||||||
val cycle = RegInit(0.U(64.W))
|
val cycle = RegInit(0.U(64.W))
|
||||||
cycle := cycle + 1.U
|
cycle := cycle + 1.U
|
||||||
@@ -304,45 +348,41 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
|||||||
spike.io.msip := int_bundle.msip
|
spike.io.msip := int_bundle.msip
|
||||||
spike.io.meip := int_bundle.meip
|
spike.io.meip := int_bundle.meip
|
||||||
spike.io.seip := int_bundle.seip.get
|
spike.io.seip := int_bundle.seip.get
|
||||||
spike.io.ipc := PlusArg("spike-ipc", 10000, width=64)
|
spike.io.ipc := PlusArg("spike-ipc", width=32, default=10000)
|
||||||
|
|
||||||
val blockBits = log2Ceil(p(CacheBlockBytes))
|
val blockBits = log2Ceil(p(CacheBlockBytes))
|
||||||
|
spike.io.icache.a.ready := icache_tl.a.ready
|
||||||
val icache_a_q = Module(new Queue(new TLBundleA(icacheEdge.bundle), 1, flow=true, pipe=true))
|
icache_tl.a.valid := spike.io.icache.a.valid
|
||||||
spike.io.icache.a.ready := icache_a_q.io.enq.ready && icache_a_q.io.count === 0.U
|
icache_tl.a.bits := icacheEdge.Get(
|
||||||
icache_tl.a <> icache_a_q.io.deq
|
|
||||||
icache_a_q.io.enq.valid := spike.io.icache.a.valid
|
|
||||||
icache_a_q.io.enq.bits := icacheEdge.Get(
|
|
||||||
fromSource = spike.io.icache.a.sourceid,
|
fromSource = spike.io.icache.a.sourceid,
|
||||||
toAddress = (spike.io.icache.a.address >> blockBits) << blockBits,
|
toAddress = (spike.io.icache.a.address >> blockBits) << blockBits,
|
||||||
lgSize = blockBits.U)._2
|
lgSize = blockBits.U)._2
|
||||||
|
|
||||||
icache_tl.d.ready := true.B
|
icache_tl.d.ready := true.B
|
||||||
spike.io.icache.d.valid := icache_tl.d.valid
|
spike.io.icache.d.valid := icache_tl.d.valid
|
||||||
spike.io.icache.d.sourceid := icache_tl.d.bits.source
|
spike.io.icache.d.sourceid := icache_tl.d.bits.source
|
||||||
spike.io.icache.d.data := icache_tl.d.bits.data.asTypeOf(Vec(8, UInt(64.W)))
|
spike.io.icache.d.data := icache_tl.d.bits.data.asTypeOf(Vec(8, UInt(64.W)))
|
||||||
|
|
||||||
val dcache_a_q = Module(new Queue(new TLBundleA(dcacheEdge.bundle), 1, flow=true, pipe=true))
|
spike.io.dcache.a.ready := dcache_tl.a.ready
|
||||||
spike.io.dcache.a.ready := dcache_a_q.io.enq.ready && dcache_a_q.io.count === 0.U
|
dcache_tl.a.valid := spike.io.dcache.a.valid
|
||||||
dcache_tl.a <> dcache_a_q.io.deq
|
if (dcacheEdge.manager.anySupportAcquireB) {
|
||||||
dcache_a_q.io.enq.valid := spike.io.dcache.a.valid
|
dcache_tl.a.bits := dcacheEdge.AcquireBlock(
|
||||||
dcache_a_q.io.enq.bits := dcacheEdge.AcquireBlock(
|
|
||||||
fromSource = spike.io.dcache.a.sourceid,
|
fromSource = spike.io.dcache.a.sourceid,
|
||||||
toAddress = (spike.io.dcache.a.address >> blockBits) << blockBits,
|
toAddress = (spike.io.dcache.a.address >> blockBits) << blockBits,
|
||||||
lgSize = blockBits.U,
|
lgSize = blockBits.U,
|
||||||
growPermissions = Mux(spike.io.dcache.a.state_old, 2.U, Mux(spike.io.dcache.a.state_new, 1.U, 0.U)))._2
|
growPermissions = Mux(spike.io.dcache.a.state_old, 2.U, Mux(spike.io.dcache.a.state_new, 1.U, 0.U)))._2
|
||||||
|
} else {
|
||||||
|
dcache_tl.a.bits := DontCare
|
||||||
|
}
|
||||||
dcache_tl.b.ready := true.B
|
dcache_tl.b.ready := true.B
|
||||||
spike.io.dcache.b.valid := dcache_tl.b.valid
|
spike.io.dcache.b.valid := dcache_tl.b.valid
|
||||||
spike.io.dcache.b.address := dcache_tl.b.bits.address
|
spike.io.dcache.b.address := dcache_tl.b.bits.address
|
||||||
spike.io.dcache.b.source := dcache_tl.b.bits.source
|
spike.io.dcache.b.source := dcache_tl.b.bits.source
|
||||||
spike.io.dcache.b.param := dcache_tl.b.bits.param
|
spike.io.dcache.b.param := dcache_tl.b.bits.param
|
||||||
|
|
||||||
val dcache_c_q = Module(new Queue(new TLBundleC(dcacheEdge.bundle), 1, flow=true, pipe=true))
|
spike.io.dcache.c.ready := dcache_tl.c.ready
|
||||||
spike.io.dcache.c.ready := dcache_c_q.io.enq.ready && dcache_c_q.io.count === 0.U
|
dcache_tl.c.valid := spike.io.dcache.c.valid
|
||||||
dcache_tl.c <> dcache_c_q.io.deq
|
if (dcacheEdge.manager.anySupportAcquireB) {
|
||||||
dcache_c_q.io.enq.valid := spike.io.dcache.c.valid
|
dcache_tl.c.bits := Mux(spike.io.dcache.c.voluntary,
|
||||||
dcache_c_q.io.enq.bits := Mux(spike.io.dcache.c.voluntary,
|
|
||||||
dcacheEdge.Release(
|
dcacheEdge.Release(
|
||||||
fromSource = spike.io.dcache.c.sourceid,
|
fromSource = spike.io.dcache.c.sourceid,
|
||||||
toAddress = spike.io.dcache.c.address,
|
toAddress = spike.io.dcache.c.address,
|
||||||
@@ -362,6 +402,9 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
|||||||
lgSize = blockBits.U,
|
lgSize = blockBits.U,
|
||||||
reportPermissions = spike.io.dcache.c.param)
|
reportPermissions = spike.io.dcache.c.param)
|
||||||
))
|
))
|
||||||
|
} else {
|
||||||
|
dcache_tl.c.bits := DontCare
|
||||||
|
}
|
||||||
|
|
||||||
val has_data = dcacheEdge.hasData(dcache_tl.d.bits)
|
val has_data = dcacheEdge.hasData(dcache_tl.d.bits)
|
||||||
val should_finish = dcacheEdge.isRequest(dcache_tl.d.bits)
|
val should_finish = dcacheEdge.isRequest(dcache_tl.d.bits)
|
||||||
@@ -376,12 +419,10 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
|||||||
dcache_tl.e.valid := dcache_tl.d.valid && should_finish
|
dcache_tl.e.valid := dcache_tl.d.valid && should_finish
|
||||||
dcache_tl.e.bits := dcacheEdge.GrantAck(dcache_tl.d.bits)
|
dcache_tl.e.bits := dcacheEdge.GrantAck(dcache_tl.d.bits)
|
||||||
|
|
||||||
val mmio_a_q = Module(new Queue(new TLBundleA(mmioEdge.bundle), 1, flow=true, pipe=true))
|
spike.io.mmio.a.ready := mmio_tl.a.ready
|
||||||
spike.io.mmio.a.ready := mmio_a_q.io.enq.ready && mmio_a_q.io.count === 0.U
|
mmio_tl.a.valid := spike.io.mmio.a.valid
|
||||||
mmio_tl.a <> mmio_a_q.io.deq
|
|
||||||
mmio_a_q.io.enq.valid := spike.io.mmio.a.valid
|
|
||||||
val log_size = MuxCase(0.U, (0 until 3).map { i => (spike.io.mmio.a.size === (1 << i).U) -> i.U })
|
val log_size = MuxCase(0.U, (0 until 3).map { i => (spike.io.mmio.a.size === (1 << i).U) -> i.U })
|
||||||
mmio_a_q.io.enq.bits := Mux(spike.io.mmio.a.store,
|
mmio_tl.a.bits := Mux(spike.io.mmio.a.store,
|
||||||
mmioEdge.Put(0.U, spike.io.mmio.a.address, log_size, spike.io.mmio.a.data)._2,
|
mmioEdge.Put(0.U, spike.io.mmio.a.address, log_size, spike.io.mmio.a.data)._2,
|
||||||
mmioEdge.Get(0.U, spike.io.mmio.a.address, log_size)._2)
|
mmioEdge.Get(0.U, spike.io.mmio.a.address, log_size)._2)
|
||||||
|
|
||||||
@@ -389,9 +430,33 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
|||||||
spike.io.mmio.d.valid := mmio_tl.d.valid
|
spike.io.mmio.d.valid := mmio_tl.d.valid
|
||||||
spike.io.mmio.d.data := mmio_tl.d.bits.data
|
spike.io.mmio.d.data := mmio_tl.d.bits.data
|
||||||
|
|
||||||
|
spike.io.tcm := DontCare
|
||||||
|
spike.io.tcm.a.valid := false.B
|
||||||
|
spike.io.tcm.d.ready := true.B
|
||||||
|
outer.tcmNode.map { tcmNode =>
|
||||||
|
val (tcm_tl, tcmEdge) = tcmNode.in(0)
|
||||||
|
val debug_tcm_tl = WireInit(tcm_tl)
|
||||||
|
dontTouch(debug_tcm_tl)
|
||||||
|
tcm_tl.a.ready := true.B
|
||||||
|
spike.io.tcm.a.valid := tcm_tl.a.valid
|
||||||
|
spike.io.tcm.a.address := tcm_tl.a.bits.address
|
||||||
|
spike.io.tcm.a.data := tcm_tl.a.bits.data
|
||||||
|
spike.io.tcm.a.mask := tcm_tl.a.bits.mask
|
||||||
|
spike.io.tcm.a.opcode := tcm_tl.a.bits.opcode
|
||||||
|
spike.io.tcm.a.size := tcm_tl.a.bits.size
|
||||||
|
|
||||||
|
spike.io.tcm.d.ready := tcm_tl.d.ready
|
||||||
|
tcm_tl.d.bits := tcmEdge.AccessAck(RegNext(tcm_tl.a.bits))
|
||||||
|
when (RegNext(tcm_tl.a.bits.opcode === TLMessages.Get)) {
|
||||||
|
tcm_tl.d.bits.opcode := TLMessages.AccessAckData
|
||||||
|
}
|
||||||
|
tcm_tl.d.valid := spike.io.tcm.d.valid
|
||||||
|
tcm_tl.d.bits.data := spike.io.tcm.d.data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithNSpikeCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
class WithNSpikeCores(n: Int = 1, tileParams: SpikeTileParams = SpikeTileParams(),
|
||||||
|
overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
||||||
case TilesLocated(InSubsystem) => {
|
case TilesLocated(InSubsystem) => {
|
||||||
// Calculate the next available hart ID (since hart ID cannot be duplicated)
|
// Calculate the next available hart ID (since hart ID cannot be duplicated)
|
||||||
val prev = up(TilesLocated(InSubsystem), site)
|
val prev = up(TilesLocated(InSubsystem), site)
|
||||||
@@ -399,8 +464,21 @@ class WithNSpikeCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends
|
|||||||
// Create TileAttachParams for every core to be instantiated
|
// Create TileAttachParams for every core to be instantiated
|
||||||
(0 until n).map { i =>
|
(0 until n).map { i =>
|
||||||
SpikeTileAttachParams(
|
SpikeTileAttachParams(
|
||||||
tileParams = SpikeTileParams(hartId = i + idOffset)
|
tileParams = tileParams.copy(hartId = i + idOffset)
|
||||||
)
|
)
|
||||||
} ++ prev
|
} ++ prev
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithSpikeTCM extends Config((site, here, up) => {
|
||||||
|
case TilesLocated(InSubsystem) => {
|
||||||
|
val prev = up(TilesLocated(InSubsystem))
|
||||||
|
require(prev.size == 1)
|
||||||
|
val spike = prev(0).asInstanceOf[SpikeTileAttachParams]
|
||||||
|
Seq(spike.copy(tileParams = spike.tileParams.copy(
|
||||||
|
tcmParams = Some(up(ExtMem).get.master)
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
case ExtMem => None
|
||||||
|
case BankedL2Key => up(BankedL2Key).copy(nBanks = 0)
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package chipyard
|
package chipyard
|
||||||
|
|
||||||
import freechips.rocketchip.config.{Config}
|
import freechips.rocketchip.config.{Config}
|
||||||
|
import freechips.rocketchip.rocket.{DCacheParams}
|
||||||
|
|
||||||
// Configs which instantiate a Spike-simulated
|
// Configs which instantiate a Spike-simulated
|
||||||
// tile that interacts with the Chipyard SoC
|
// tile that interacts with the Chipyard SoC
|
||||||
@@ -14,6 +15,18 @@ class SpikeConfig extends Config(
|
|||||||
class SpikeFastUARTConfig extends Config(
|
class SpikeFastUARTConfig extends Config(
|
||||||
new chipyard.WithNSpikeCores(1) ++
|
new chipyard.WithNSpikeCores(1) ++
|
||||||
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
||||||
new chipyard.config.WithMemoryBusFrequency(1) ++
|
new chipyard.config.WithMemoryBusFrequency(2) ++
|
||||||
new chipyard.config.WithPeripheryBusFrequency(1) ++
|
new chipyard.config.WithPeripheryBusFrequency(2) ++
|
||||||
new chipyard.config.AbstractConfig)
|
new chipyard.config.AbstractConfig)
|
||||||
|
|
||||||
|
// Makes the UART fast, also builds no L2 and a ludicrous L1D
|
||||||
|
class SpikeUltraFastConfig extends Config(
|
||||||
|
new chipyard.WithSpikeTCM ++
|
||||||
|
new chipyard.WithNSpikeCores(1) ++
|
||||||
|
new testchipip.WithSerialPBusMem ++
|
||||||
|
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
||||||
|
new chipyard.config.WithMemoryBusFrequency(2) ++
|
||||||
|
new chipyard.config.WithPeripheryBusFrequency(2) ++
|
||||||
|
new chipyard.config.WithBroadcastManager ++
|
||||||
|
new chipyard.config.AbstractConfig)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user