Remove HTIF; use debug module for testing in simulation
This commit is contained in:
parent
255ef05e21
commit
30331fcaeb
171
csrc/emulator.cc
171
csrc/emulator.cc
@ -1,6 +1,5 @@
|
|||||||
// See LICENSE for license details.
|
// See LICENSE for license details.
|
||||||
|
|
||||||
#include "htif_emulator.h"
|
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#else
|
#else
|
||||||
@ -11,6 +10,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "mm.h"
|
#include "mm.h"
|
||||||
#include "mm_dramsim2.h"
|
#include "mm_dramsim2.h"
|
||||||
|
#include <fesvr/dtm.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -24,12 +24,12 @@
|
|||||||
|
|
||||||
#include "emulator_type.h"
|
#include "emulator_type.h"
|
||||||
|
|
||||||
htif_emulator_t* htif;
|
static dtm_t* dtm;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
|
||||||
void handle_sigterm(int sig)
|
void handle_sigterm(int sig)
|
||||||
{
|
{
|
||||||
htif->stop();
|
dtm->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
@ -126,34 +126,24 @@ int main(int argc, char** argv)
|
|||||||
load_mem(mems, loadmem, CACHE_BLOCK_BYTES, N_MEM_CHANNELS);
|
load_mem(mems, loadmem, CACHE_BLOCK_BYTES, N_MEM_CHANNELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate HTIF
|
dtm = new dtm_t(std::vector<std::string>(argv + 1, argv + argc));
|
||||||
htif = new htif_emulator_t(std::vector<std::string>(argv + 1, argv + argc));
|
|
||||||
assert(HTIF_WIDTH % 8 == 0 && HTIF_WIDTH <= 8*sizeof(uint64_t));
|
|
||||||
|
|
||||||
signal(SIGTERM, handle_sigterm);
|
signal(SIGTERM, handle_sigterm);
|
||||||
|
|
||||||
// reset for one host_clk cycle to handle pipelined reset
|
// reset for several cycles to handle pipelined reset
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
tile.Top__io_host_in_valid = LIT<1>(0);
|
|
||||||
tile.Top__io_host_out_ready = LIT<1>(0);
|
|
||||||
for (int i = 0; i < 3; i += tile.Top__io_host_clk_edge.to_bool())
|
|
||||||
{
|
|
||||||
tile.clock_lo(LIT<1>(1));
|
tile.clock_lo(LIT<1>(1));
|
||||||
tile.clock_hi(LIT<1>(1));
|
tile.clock_hi(LIT<1>(1));
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
tile.io_host_in_valid = 0;
|
|
||||||
tile.io_host_out_ready = 0;
|
|
||||||
for (int i = 0; i < 3; i += tile.io_host_clk_edge)
|
|
||||||
{
|
|
||||||
tile.reset = 1;
|
tile.reset = 1;
|
||||||
tile.clk = 0;
|
tile.clk = 0;
|
||||||
tile.eval();
|
tile.eval();
|
||||||
tile.clk = 1;
|
tile.clk = 1;
|
||||||
tile.eval();
|
tile.eval();
|
||||||
}
|
|
||||||
tile.reset = 0;
|
tile.reset = 0;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool_t *mem_ar_valid[N_MEM_CHANNELS];
|
bool_t *mem_ar_valid[N_MEM_CHANNELS];
|
||||||
bool_t *mem_ar_ready[N_MEM_CHANNELS];
|
bool_t *mem_ar_ready[N_MEM_CHANNELS];
|
||||||
@ -189,42 +179,31 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
#include TBFRAG
|
#include TBFRAG
|
||||||
|
|
||||||
while (!htif->done() && (trace_count >> 1) < max_cycles && ret == 0)
|
while (!dtm->done() && (trace_count >> 1) < max_cycles && ret == 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < N_MEM_CHANNELS; i++) {
|
for (int i = 0; i < N_MEM_CHANNELS; i++) {
|
||||||
#ifndef VERILATOR
|
value(mem_ar_ready[i]) = mm[i]->ar_ready();
|
||||||
*mem_ar_ready[i] = LIT<1>(mm[i]->ar_ready());
|
value(mem_aw_ready[i]) = mm[i]->aw_ready();
|
||||||
*mem_aw_ready[i] = LIT<1>(mm[i]->aw_ready());
|
value(mem_w_ready[i]) = mm[i]->w_ready();
|
||||||
*mem_w_ready[i] = LIT<1>(mm[i]->w_ready());
|
|
||||||
|
|
||||||
*mem_b_valid[i] = LIT<1>(mm[i]->b_valid());
|
value(mem_b_valid[i]) = mm[i]->b_valid();
|
||||||
*mem_b_bits_resp[i] = LIT<64>(mm[i]->b_resp());
|
value(mem_b_bits_resp[i]) = mm[i]->b_resp();
|
||||||
*mem_b_bits_id[i] = LIT<64>(mm[i]->b_id());
|
value(mem_b_bits_id[i]) = mm[i]->b_id();
|
||||||
|
|
||||||
*mem_r_valid[i] = LIT<1>(mm[i]->r_valid());
|
value(mem_r_valid[i]) = mm[i]->r_valid();
|
||||||
*mem_r_bits_resp[i] = LIT<64>(mm[i]->r_resp());
|
value(mem_r_bits_resp[i]) = mm[i]->r_resp();
|
||||||
*mem_r_bits_id[i] = LIT<64>(mm[i]->r_id());
|
value(mem_r_bits_id[i]) = mm[i]->r_id();
|
||||||
*mem_r_bits_last[i] = LIT<1>(mm[i]->r_last());
|
value(mem_r_bits_last[i]) = mm[i]->r_last();
|
||||||
|
|
||||||
memcpy(mem_r_bits_data[i]->values, mm[i]->r_data(), mem_width);
|
memcpy(values(mem_r_bits_data[i]), mm[i]->r_data(), mem_width);
|
||||||
#else
|
|
||||||
*mem_ar_ready[i] = mm[i]->ar_ready();
|
|
||||||
*mem_aw_ready[i] = mm[i]->aw_ready();
|
|
||||||
*mem_w_ready[i] = mm[i]->w_ready();
|
|
||||||
|
|
||||||
*mem_b_valid[i] = mm[i]->b_valid();
|
|
||||||
*mem_b_bits_resp[i] = mm[i]->b_resp();
|
|
||||||
*mem_b_bits_id[i] = mm[i]->b_id();
|
|
||||||
|
|
||||||
*mem_r_valid[i] = mm[i]->r_valid();
|
|
||||||
*mem_r_bits_resp[i] = mm[i]->r_resp();
|
|
||||||
*mem_r_bits_id[i] = mm[i]->r_id();
|
|
||||||
*mem_r_bits_last[i] = mm[i]->r_last();
|
|
||||||
|
|
||||||
memcpy(mem_r_bits_data[i], mm[i]->r_data(), mem_width);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value(field(io_debug_resp_ready)) = dtm->resp_ready();
|
||||||
|
value(field(io_debug_req_valid)) = dtm->req_valid();
|
||||||
|
value(field(io_debug_req_bits_addr)) = dtm->req_bits().addr;
|
||||||
|
value(field(io_debug_req_bits_op)) = dtm->req_bits().op;
|
||||||
|
value(field(io_debug_req_bits_data)) = dtm->req_bits().data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
tile.clock_lo(LIT<1>(0));
|
tile.clock_lo(LIT<1>(0));
|
||||||
@ -244,67 +223,41 @@ int main(int argc, char** argv)
|
|||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dtm_t::resp debug_resp_bits;
|
||||||
|
debug_resp_bits.resp = value(field(io_debug_resp_bits_resp));
|
||||||
|
debug_resp_bits.data = value(field(io_debug_resp_bits_data));
|
||||||
|
|
||||||
|
dtm->tick(
|
||||||
|
value(field(io_debug_req_ready)),
|
||||||
|
value(field(io_debug_resp_valid)),
|
||||||
|
debug_resp_bits
|
||||||
|
);
|
||||||
|
|
||||||
for (int i = 0; i < N_MEM_CHANNELS; i++) {
|
for (int i = 0; i < N_MEM_CHANNELS; i++) {
|
||||||
mm[i]->tick(
|
mm[i]->tick(
|
||||||
#ifndef VERILATOR
|
value(mem_ar_valid[i]),
|
||||||
mem_ar_valid[i]->to_bool(),
|
value(mem_ar_bits_addr[i]) - MEM_BASE,
|
||||||
mem_ar_bits_addr[i]->lo_word() - MEM_BASE,
|
value(mem_ar_bits_id[i]),
|
||||||
mem_ar_bits_id[i]->lo_word(),
|
value(mem_ar_bits_size[i]),
|
||||||
mem_ar_bits_size[i]->lo_word(),
|
value(mem_ar_bits_len[i]),
|
||||||
mem_ar_bits_len[i]->lo_word(),
|
|
||||||
|
|
||||||
mem_aw_valid[i]->to_bool(),
|
value(mem_aw_valid[i]),
|
||||||
mem_aw_bits_addr[i]->lo_word() - MEM_BASE,
|
value(mem_aw_bits_addr[i]) - MEM_BASE,
|
||||||
mem_aw_bits_id[i]->lo_word(),
|
value(mem_aw_bits_id[i]),
|
||||||
mem_aw_bits_size[i]->lo_word(),
|
value(mem_aw_bits_size[i]),
|
||||||
mem_aw_bits_len[i]->lo_word(),
|
value(mem_aw_bits_len[i]),
|
||||||
|
|
||||||
mem_w_valid[i]->to_bool(),
|
value(mem_w_valid[i]),
|
||||||
mem_w_bits_strb[i]->lo_word(),
|
value(mem_w_bits_strb[i]),
|
||||||
mem_w_bits_data[i]->values,
|
values(mem_w_bits_data[i]),
|
||||||
mem_w_bits_last[i]->to_bool(),
|
value(mem_w_bits_last[i]),
|
||||||
|
|
||||||
mem_r_ready[i]->to_bool(),
|
value(mem_r_ready[i]),
|
||||||
mem_b_ready[i]->to_bool()
|
value(mem_b_ready[i])
|
||||||
#else
|
|
||||||
*mem_ar_valid[i],
|
|
||||||
*mem_ar_bits_addr[i] - MEM_BASE,
|
|
||||||
*mem_ar_bits_id[i],
|
|
||||||
*mem_ar_bits_size[i],
|
|
||||||
*mem_ar_bits_len[i],
|
|
||||||
|
|
||||||
*mem_aw_valid[i],
|
|
||||||
*mem_aw_bits_addr[i] - MEM_BASE,
|
|
||||||
*mem_aw_bits_id[i],
|
|
||||||
*mem_aw_bits_size[i],
|
|
||||||
*mem_aw_bits_len[i],
|
|
||||||
|
|
||||||
*mem_w_valid[i],
|
|
||||||
*mem_w_bits_strb[i],
|
|
||||||
mem_w_bits_data[i],
|
|
||||||
*mem_w_bits_last[i],
|
|
||||||
|
|
||||||
*mem_r_ready[i],
|
|
||||||
*mem_b_ready[i]
|
|
||||||
#endif
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
if (tile.Top__io_host_clk_edge.to_bool())
|
|
||||||
{
|
|
||||||
static bool htif_in_valid = false;
|
|
||||||
static val_t htif_in_bits;
|
|
||||||
if (tile.Top__io_host_in_ready.to_bool() || !htif_in_valid)
|
|
||||||
htif_in_valid = htif->recv_nonblocking(&htif_in_bits, HTIF_WIDTH/8);
|
|
||||||
tile.Top__io_host_in_valid = LIT<1>(htif_in_valid);
|
|
||||||
tile.Top__io_host_in_bits = LIT<64>(htif_in_bits);
|
|
||||||
|
|
||||||
if (tile.Top__io_host_out_valid.to_bool())
|
|
||||||
htif->send(tile.Top__io_host_out_bits.values, HTIF_WIDTH/8);
|
|
||||||
tile.Top__io_host_out_ready = LIT<1>(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose && (trace_count >> 1) >= start)
|
if (verbose && (trace_count >> 1) >= start)
|
||||||
tile.print(stderr);
|
tile.print(stderr);
|
||||||
|
|
||||||
@ -314,20 +267,6 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
tile.clock_hi(LIT<1>(0));
|
tile.clock_hi(LIT<1>(0));
|
||||||
#else
|
#else
|
||||||
if (tile.io_host_clk_edge)
|
|
||||||
{
|
|
||||||
static bool htif_in_valid = false;
|
|
||||||
static uint64_t htif_in_bits;
|
|
||||||
if (tile.io_host_in_ready || !htif_in_valid)
|
|
||||||
htif_in_valid = htif->recv_nonblocking(&htif_in_bits, HTIF_WIDTH/8);
|
|
||||||
tile.io_host_in_valid = htif_in_valid;
|
|
||||||
tile.io_host_in_bits = htif_in_bits;
|
|
||||||
|
|
||||||
if (tile.io_host_out_valid)
|
|
||||||
htif->send(&tile.io_host_out_bits, HTIF_WIDTH/8);
|
|
||||||
tile.io_host_out_ready = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tile.clk = 1;
|
tile.clk = 1;
|
||||||
tile.eval();
|
tile.eval();
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
@ -347,10 +286,10 @@ int main(int argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (htif->exit_code())
|
if (dtm->exit_code())
|
||||||
{
|
{
|
||||||
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", htif->exit_code(), random_seed, trace_count >> 1);
|
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count >> 1);
|
||||||
ret = htif->exit_code();
|
ret = dtm->exit_code();
|
||||||
}
|
}
|
||||||
else if ((trace_count >> 1) == max_cycles)
|
else if ((trace_count >> 1) == max_cycles)
|
||||||
{
|
{
|
||||||
@ -362,7 +301,7 @@ int main(int argc, char** argv)
|
|||||||
fprintf(stderr, "Completed after %ld cycles\n", trace_count >> 1);
|
fprintf(stderr, "Completed after %ld cycles\n", trace_count >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete htif;
|
delete dtm;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
// See LICENSE for license details.
|
// See LICENSE for license details.
|
||||||
|
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
#define bool_t dat_t<1>
|
# define bool_t dat_t<1>
|
||||||
|
# define values(x) ((x)->values)
|
||||||
|
# define field(name) &(tile.Top__ ## name)
|
||||||
#else
|
#else
|
||||||
#define bool_t CData
|
# define bool_t CData
|
||||||
|
# define values(x) (x)
|
||||||
|
# define field(name) &(tile.name)
|
||||||
#endif
|
#endif
|
||||||
|
#define value(x) (*values(x))
|
||||||
|
|
||||||
#ifndef VERILATOR
|
#ifndef VERILATOR
|
||||||
#define mem_addr_t dat_t<MEM_ADDR_BITS>
|
#define mem_addr_t dat_t<MEM_ADDR_BITS>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
// See LICENSE for license details.
|
// See LICENSE for license details.
|
||||||
|
|
||||||
#include "htif_emulator.h"
|
|
||||||
#include "mm.h"
|
#include "mm.h"
|
||||||
#include "mm_dramsim2.h"
|
#include "mm_dramsim2.h"
|
||||||
|
#include <fesvr/dtm.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <DirectC.h>
|
#include <DirectC.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -14,17 +15,14 @@ extern "C" {
|
|||||||
|
|
||||||
extern int vcs_main(int argc, char** argv);
|
extern int vcs_main(int argc, char** argv);
|
||||||
|
|
||||||
static htif_emulator_t* htif;
|
static dtm_t* dtm;
|
||||||
static unsigned htif_bytes = HTIF_WIDTH / 8;
|
|
||||||
static mm_t* mm[N_MEM_CHANNELS];
|
static mm_t* mm[N_MEM_CHANNELS];
|
||||||
static const char* loadmem;
|
static const char* loadmem;
|
||||||
static bool dramsim = false;
|
static bool dramsim = false;
|
||||||
static int memory_channel_mux_select = 0;
|
static int memory_channel_mux_select = 0;
|
||||||
|
|
||||||
void htif_fini(vc_handle failure)
|
void do_exit(vc_handle failure)
|
||||||
{
|
{
|
||||||
delete htif;
|
|
||||||
htif = NULL;
|
|
||||||
exit(vc_getScalar(failure));
|
exit(vc_getScalar(failure));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +38,7 @@ int main(int argc, char** argv)
|
|||||||
memory_channel_mux_select = atoi(argv[i]+27);
|
memory_channel_mux_select = atoi(argv[i]+27);
|
||||||
}
|
}
|
||||||
|
|
||||||
htif = new htif_emulator_t(std::vector<std::string>(argv + 1, argv + argc));
|
dtm = new dtm_t(std::vector<std::string>(argv + 1, argv + argc));
|
||||||
|
|
||||||
for (int i=0; i<N_MEM_CHANNELS; i++) {
|
for (int i=0; i<N_MEM_CHANNELS; i++) {
|
||||||
mm[i] = dramsim ? (mm_t*)(new mm_dramsim2_t) : (mm_t*)(new mm_magic_t);
|
mm[i] = dramsim ? (mm_t*)(new mm_dramsim2_t) : (mm_t*)(new mm_magic_t);
|
||||||
@ -172,36 +170,45 @@ void memory_tick(
|
|||||||
vc_put4stVector(r_data, d);
|
vc_put4stVector(r_data, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void htif_tick
|
void debug_tick
|
||||||
(
|
(
|
||||||
vc_handle htif_in_valid,
|
vc_handle debug_req_valid,
|
||||||
vc_handle htif_in_ready,
|
vc_handle debug_req_ready,
|
||||||
vc_handle htif_in_bits,
|
vc_handle debug_req_bits_addr,
|
||||||
vc_handle htif_out_valid,
|
vc_handle debug_req_bits_op,
|
||||||
vc_handle htif_out_ready,
|
vc_handle debug_req_bits_data,
|
||||||
vc_handle htif_out_bits,
|
vc_handle debug_resp_valid,
|
||||||
|
vc_handle debug_resp_ready,
|
||||||
|
vc_handle debug_resp_bits_resp,
|
||||||
|
vc_handle debug_resp_bits_data,
|
||||||
vc_handle exit
|
vc_handle exit
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static bool peek_in_valid;
|
vec32 tmp[2];
|
||||||
static uint32_t peek_in_bits;
|
dtm_t::resp resp_bits;
|
||||||
if (vc_getScalar(htif_in_ready))
|
vc_get4stVector(debug_resp_bits_resp, tmp);
|
||||||
peek_in_valid = htif->recv_nonblocking(&peek_in_bits, htif_bytes);
|
resp_bits.resp = tmp[0].d;
|
||||||
|
vc_get4stVector(debug_resp_bits_data, tmp);
|
||||||
|
resp_bits.data = tmp[0].d | ((uint64_t)tmp[1].d << 32);
|
||||||
|
|
||||||
vc_putScalar(htif_out_ready, 1);
|
dtm->tick
|
||||||
if (vc_getScalar(htif_out_valid))
|
(
|
||||||
{
|
vc_getScalar(debug_req_ready),
|
||||||
vec32* bits = vc_4stVectorRef(htif_out_bits);
|
vc_getScalar(debug_resp_valid),
|
||||||
htif->send(&bits->d, htif_bytes);
|
resp_bits
|
||||||
}
|
);
|
||||||
|
|
||||||
vec32 bits = {0, 0};
|
vc_putScalar(debug_resp_ready, dtm->resp_ready());
|
||||||
bits.d = peek_in_bits;
|
vc_putScalar(debug_req_valid, dtm->req_valid());
|
||||||
vc_put4stVector(htif_in_bits, &bits);
|
tmp[0].d = dtm->req_bits().addr;
|
||||||
vc_putScalar(htif_in_valid, peek_in_valid);
|
vc_put4stVector(debug_req_bits_addr, tmp);
|
||||||
|
tmp[0].d = dtm->req_bits().op;
|
||||||
bits.d = htif->done() ? (htif->exit_code() << 1 | 1) : 0;
|
vc_put4stVector(debug_req_bits_op, tmp);
|
||||||
vc_put4stVector(exit, &bits);
|
tmp[0].d = dtm->req_bits().data;
|
||||||
|
tmp[1].d = dtm->req_bits().data >> 32;
|
||||||
|
vc_put4stVector(debug_req_bits_data, tmp);
|
||||||
|
tmp[0].d = dtm->done() ? (dtm->exit_code() << 1 | 1) : 0;
|
||||||
|
vc_put4stVector(exit, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 5a79333c1c559bbaeedfd6e57bdcd8797558f616
|
Subproject commit 0cce8c5d84efd1d62da81f9b885c6835459de0a7
|
2
rocket
2
rocket
@ -1 +1 @@
|
|||||||
Subproject commit eb9d014c8fb1ed51b9a1b6f898b890271169d917
|
Subproject commit 781b814e1b333262eb78c5b62c6aabf4b6afc9d3
|
@ -262,12 +262,12 @@ class BaseConfig extends Config (
|
|||||||
case TLKey("L1toL2") =>
|
case TLKey("L1toL2") =>
|
||||||
TileLinkParameters(
|
TileLinkParameters(
|
||||||
coherencePolicy = new MESICoherence(site(L2DirectoryRepresentation)),
|
coherencePolicy = new MESICoherence(site(L2DirectoryRepresentation)),
|
||||||
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1,
|
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */,
|
||||||
nCachingClients = site(NCachedTileLinkPorts),
|
nCachingClients = site(NCachedTileLinkPorts),
|
||||||
nCachelessClients = site(NUncachedTileLinkPorts),
|
nCachelessClients = site(NUncachedTileLinkPorts),
|
||||||
maxClientXacts = max_int(
|
maxClientXacts = max_int(
|
||||||
// L1 cache
|
// L1 cache
|
||||||
site(NMSHRs) + 1,
|
site(NMSHRs) + 1 /* IOMSHR */,
|
||||||
// RoCC
|
// RoCC
|
||||||
if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)),
|
if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)),
|
||||||
maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
|
maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
|
||||||
|
@ -18,10 +18,8 @@ class ZynqAdapter(implicit val p: Parameters) extends Module
|
|||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val nasti = new NastiIO()(adapterParams).flip
|
val nasti = new NastiIO()(adapterParams).flip
|
||||||
val host = new HostIO(htifW).flip
|
|
||||||
val reset = Bool(OUTPUT)
|
val reset = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val conv = Module(new NastiIOHostIOConverter(htifW)(adapterParams))
|
require(false, "TODO reimplement using debug port, not HTIF")
|
||||||
io <> conv.io
|
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,7 @@ trait HasTopLevelParameters {
|
|||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
lazy val nTiles = p(NTiles)
|
lazy val nTiles = p(NTiles)
|
||||||
lazy val nCachedTilePorts = p(NCachedTileLinkPorts)
|
lazy val nCachedTilePorts = p(NCachedTileLinkPorts)
|
||||||
lazy val nUncachedTilePorts = p(NUncachedTileLinkPorts) - 1
|
lazy val nUncachedTilePorts = p(NUncachedTileLinkPorts)
|
||||||
lazy val htifW = p(HtifKey).width
|
|
||||||
lazy val csrAddrBits = 12
|
lazy val csrAddrBits = 12
|
||||||
lazy val tMemChannels = p(TMemoryChannels)
|
lazy val tMemChannels = p(TMemoryChannels)
|
||||||
lazy val nMemChannels = p(NMemoryChannels)
|
lazy val nMemChannels = p(NMemoryChannels)
|
||||||
@ -83,9 +82,7 @@ class MemBackupCtrlIO extends Bundle {
|
|||||||
|
|
||||||
/** Top-level io for the chip */
|
/** Top-level io for the chip */
|
||||||
class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||||
with HasTopLevelParameters {
|
with HasTopLevelParameters
|
||||||
val host = new HostIO(htifW)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
|
class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
|
||||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||||
@ -120,8 +117,10 @@ object TopUtils {
|
|||||||
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
|
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
|
||||||
val configStringAddr = p(ResetVector).toInt + rom.capacity
|
val configStringAddr = p(ResetVector).toInt + rom.capacity
|
||||||
|
|
||||||
rom.putInt(0x00000297 + resetToMemDist.toInt) // auipc t0, &mem - &here
|
// This boot ROM doesn't know about any boot devices, so it just spins,
|
||||||
rom.putInt(0x00028067) // jr t0
|
// waiting for the debugger to load a program and change the PC.
|
||||||
|
rom.putInt(0x0000006f) // loop forever
|
||||||
|
rom.putInt(0) // reserved
|
||||||
rom.putInt(0) // reserved
|
rom.putInt(0) // reserved
|
||||||
rom.putInt(configStringAddr) // pointer to config string
|
rom.putInt(configStringAddr) // pointer to config string
|
||||||
rom.putInt(0) // default trap vector
|
rom.putInt(0) // default trap vector
|
||||||
@ -151,7 +150,7 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
|
|||||||
case HastiId => "TL"
|
case HastiId => "TL"
|
||||||
case TLId => "L1toL2"
|
case TLId => "L1toL2"
|
||||||
case NCachedTileLinkPorts => nCachedPorts
|
case NCachedTileLinkPorts => nCachedPorts
|
||||||
case NUncachedTileLinkPorts => nUncachedPorts + 1 // 1 for HTIF
|
case NUncachedTileLinkPorts => nUncachedPorts
|
||||||
})
|
})
|
||||||
|
|
||||||
val uncore = Module(new Uncore()(innerTLParams))
|
val uncore = Module(new Uncore()(innerTLParams))
|
||||||
@ -165,7 +164,6 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
|
|||||||
// Connect the uncore to the tile memory ports, HostIO and MemIO
|
// Connect the uncore to the tile memory ports, HostIO and MemIO
|
||||||
uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten
|
uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten
|
||||||
uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten
|
uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten
|
||||||
io.host <> uncore.io.host
|
|
||||||
uncore.io.interrupts <> io.interrupts
|
uncore.io.interrupts <> io.interrupts
|
||||||
uncore.io.debugBus <> io.debug
|
uncore.io.debugBus <> io.debug
|
||||||
|
|
||||||
@ -185,7 +183,6 @@ class Uncore(implicit val p: Parameters) extends Module
|
|||||||
|
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HostIO(htifW)
|
|
||||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||||
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
||||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||||
@ -197,30 +194,15 @@ class Uncore(implicit val p: Parameters) extends Module
|
|||||||
val debugBus = new DebugBusIO()(p).flip
|
val debugBus = new DebugBusIO()(p).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
val htif = Module(new Htif(CSRs.mreset)) // One HTIF module per chip
|
|
||||||
val outmemsys = Module(new OuterMemorySystem) // NoC, LLC and SerDes
|
val outmemsys = Module(new OuterMemorySystem) // NoC, LLC and SerDes
|
||||||
outmemsys.io.incoherent := htif.io.cpu.map(_.reset)
|
outmemsys.io.incoherent foreach (_ := false)
|
||||||
outmemsys.io.htif_uncached <> htif.io.mem
|
|
||||||
outmemsys.io.tiles_uncached <> io.tiles_uncached
|
outmemsys.io.tiles_uncached <> io.tiles_uncached
|
||||||
outmemsys.io.tiles_cached <> io.tiles_cached
|
outmemsys.io.tiles_cached <> io.tiles_cached
|
||||||
|
|
||||||
val scrFile = Module(new SCRFile("UNCORE_SCR", 0))
|
|
||||||
scrFile.io.smi <> htif.io.scr
|
|
||||||
// scrFile.io.scr <> (... your SCR connections ...)
|
|
||||||
|
|
||||||
buildMMIONetwork(p.alterPartial({case TLId => "MMIO_Outermost"}))
|
buildMMIONetwork(p.alterPartial({case TLId => "MMIO_Outermost"}))
|
||||||
|
|
||||||
// Wire the htif to the memory port(s) and host interface
|
|
||||||
io.mem_axi <> outmemsys.io.mem_axi
|
io.mem_axi <> outmemsys.io.mem_axi
|
||||||
io.mem_ahb <> outmemsys.io.mem_ahb
|
io.mem_ahb <> outmemsys.io.mem_ahb
|
||||||
if(p(UseHtifClockDiv)) {
|
|
||||||
VLSIUtils.padOutHTIFWithDividedClock(htif.io.host, scrFile.io.scr, io.host, htifW)
|
|
||||||
} else {
|
|
||||||
io.host <> htif.io.host
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tie off HTIF CSR ports
|
|
||||||
htif.io.cpu.foreach { _.csr.resp.valid := Bool(false) }
|
|
||||||
|
|
||||||
def buildMMIONetwork(implicit p: Parameters) = {
|
def buildMMIONetwork(implicit p: Parameters) = {
|
||||||
val ioAddrMap = p(GlobalAddrMap).subMap("io")
|
val ioAddrMap = p(GlobalAddrMap).subMap("io")
|
||||||
@ -254,9 +236,7 @@ class Uncore(implicit val p: Parameters) extends Module
|
|||||||
prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
|
prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
|
||||||
prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
|
prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
|
||||||
|
|
||||||
io.prci(i).reset := reset || Reg(init = Bool(true),
|
io.prci(i).reset := reset
|
||||||
next=Reg(init = Bool(true),
|
|
||||||
next=htif.io.cpu(i).reset)) // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val bootROM = Module(new ROMSlave(TopUtils.makeBootROM()))
|
val bootROM = Module(new ROMSlave(TopUtils.makeBootROM()))
|
||||||
@ -289,14 +269,13 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
|||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||||
val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
|
val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
|
||||||
val htif_uncached = (new ClientUncachedTileLinkIO).flip
|
|
||||||
val incoherent = Vec(nTiles, Bool()).asInput
|
val incoherent = Vec(nTiles, Bool()).asInput
|
||||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||||
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
||||||
val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"}))
|
val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory
|
// Create a simple L1toL2 NoC between the tiles and the banks of outer memory
|
||||||
// Cached ports are first in client list, making sharerToClientId just an indentity function
|
// Cached ports are first in client list, making sharerToClientId just an indentity function
|
||||||
// addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
|
// addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
|
||||||
def sharerToClientId(sharerId: UInt) = sharerId
|
def sharerToClientId(sharerId: UInt) = sharerId
|
||||||
@ -320,10 +299,10 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
|||||||
})))
|
})))
|
||||||
io.mmio <> mmioManager.io.outer
|
io.mmio <> mmioManager.io.outer
|
||||||
|
|
||||||
// Wire the tiles and htif to the TileLink client ports of the L1toL2 network,
|
// Wire the tiles to the TileLink client ports of the L1toL2 network,
|
||||||
// and coherence manager(s) to the other side
|
// and coherence manager(s) to the other side
|
||||||
l1tol2net.io.clients_cached <> io.tiles_cached
|
l1tol2net.io.clients_cached <> io.tiles_cached
|
||||||
l1tol2net.io.clients_uncached <> io.tiles_uncached ++ Seq(io.htif_uncached)
|
l1tol2net.io.clients_uncached <> io.tiles_uncached
|
||||||
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
|
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
|
||||||
|
|
||||||
// Create a converter between TileLinkIO and MemIO for each channel
|
// Create a converter between TileLinkIO and MemIO for each channel
|
||||||
|
@ -17,6 +17,56 @@ object TestBenchGeneration extends FileSystemUtilities {
|
|||||||
// bit collection on the DirectC side. I had to individually define the
|
// bit collection on the DirectC side. I had to individually define the
|
||||||
// wires.
|
// wires.
|
||||||
|
|
||||||
|
val daw = p(DMKey).nDebugBusAddrSize
|
||||||
|
val dow = DbBusConsts.dbOpSize
|
||||||
|
val ddw = DbBusConsts.dbDataSize
|
||||||
|
val drw = DbBusConsts.dbRespSize
|
||||||
|
|
||||||
|
val debugDefs = s"""
|
||||||
|
wire debug_req_valid_delay;
|
||||||
|
reg debug_req_valid;
|
||||||
|
assign #0.1 debug_req_valid_delay = debug_req_valid;
|
||||||
|
|
||||||
|
wire debug_req_ready, debug_req_ready_delay;
|
||||||
|
assign #0.1 debug_req_ready = debug_req_ready_delay;
|
||||||
|
|
||||||
|
wire [${daw-1}:0] debug_req_bits_addr_delay;
|
||||||
|
reg [${daw-1}:0] debug_req_bits_addr;
|
||||||
|
assign #0.1 debug_req_bits_addr_delay = debug_req_bits_addr;
|
||||||
|
|
||||||
|
wire [${dow-1}:0] debug_req_bits_op_delay;
|
||||||
|
reg [${dow-1}:0] debug_req_bits_op;
|
||||||
|
assign #0.1 debug_req_bits_op_delay = debug_req_bits_op;
|
||||||
|
|
||||||
|
wire [${ddw-1}:0] debug_req_bits_data_delay;
|
||||||
|
reg [${ddw-1}:0] debug_req_bits_data;
|
||||||
|
assign #0.1 debug_req_bits_data_delay = debug_req_bits_data;
|
||||||
|
|
||||||
|
wire debug_resp_valid, debug_resp_valid_delay;
|
||||||
|
assign #0.1 debug_resp_valid = debug_resp_valid_delay;
|
||||||
|
|
||||||
|
wire debug_resp_ready_delay;
|
||||||
|
reg debug_resp_ready;
|
||||||
|
assign #0.1 debug_resp_ready_delay = debug_resp_ready;
|
||||||
|
|
||||||
|
wire [${drw-1}:0] debug_resp_bits_resp, debug_resp_bits_resp_delay;
|
||||||
|
assign #0.1 debug_resp_bits_resp = debug_resp_bits_resp_delay;
|
||||||
|
|
||||||
|
wire [${ddw-1}:0] debug_resp_bits_data, debug_resp_bits_data_delay;
|
||||||
|
assign #0.1 debug_resp_bits_data = debug_resp_bits_data_delay;
|
||||||
|
"""
|
||||||
|
|
||||||
|
val debugBus = s"""
|
||||||
|
.io_debug_req_ready(debug_req_ready_delay),
|
||||||
|
.io_debug_req_valid(debug_req_valid_delay),
|
||||||
|
.io_debug_req_bits_addr(debug_req_bits_addr_delay),
|
||||||
|
.io_debug_req_bits_op(debug_req_bits_op_delay),
|
||||||
|
.io_debug_req_bits_data(debug_req_bits_data_delay),
|
||||||
|
.io_debug_resp_ready(debug_resp_ready_delay),
|
||||||
|
.io_debug_resp_valid(debug_resp_valid_delay),
|
||||||
|
.io_debug_resp_bits_resp(debug_resp_bits_resp_delay),
|
||||||
|
.io_debug_resp_bits_data(debug_resp_bits_data_delay)
|
||||||
|
"""
|
||||||
val nasti_defs = (0 until nMemChannel) map { i => s"""
|
val nasti_defs = (0 until nMemChannel) map { i => s"""
|
||||||
wire ar_valid_$i;
|
wire ar_valid_$i;
|
||||||
reg ar_ready_$i;
|
reg ar_ready_$i;
|
||||||
@ -52,25 +102,6 @@ object TestBenchGeneration extends FileSystemUtilities {
|
|||||||
|
|
||||||
""" } mkString
|
""" } mkString
|
||||||
|
|
||||||
val delays = s"""
|
|
||||||
wire htif_clk;
|
|
||||||
wire htif_in_valid_delay;
|
|
||||||
wire htif_in_ready_delay;
|
|
||||||
wire [`HTIF_WIDTH-1:0] htif_in_bits_delay;
|
|
||||||
|
|
||||||
wire htif_out_valid_delay;
|
|
||||||
wire htif_out_ready_delay;
|
|
||||||
wire [`HTIF_WIDTH-1:0] htif_out_bits_delay;
|
|
||||||
|
|
||||||
assign #0.1 htif_in_valid_delay = htif_in_valid;
|
|
||||||
assign #0.1 htif_in_ready = htif_in_ready_delay;
|
|
||||||
assign #0.1 htif_in_bits_delay = htif_in_bits;
|
|
||||||
|
|
||||||
assign #0.1 htif_out_valid = htif_out_valid_delay;
|
|
||||||
assign #0.1 htif_out_ready_delay = htif_out_ready;
|
|
||||||
assign #0.1 htif_out_bits = htif_out_bits_delay;
|
|
||||||
"""
|
|
||||||
|
|
||||||
val nasti_delays = (0 until nMemChannel) map { i => s"""
|
val nasti_delays = (0 until nMemChannel) map { i => s"""
|
||||||
wire ar_valid_delay_$i;
|
wire ar_valid_delay_$i;
|
||||||
wire ar_ready_delay_$i;
|
wire ar_ready_delay_$i;
|
||||||
@ -195,27 +226,8 @@ object TestBenchGeneration extends FileSystemUtilities {
|
|||||||
.io_interrupts_$i (1'b0),
|
.io_interrupts_$i (1'b0),
|
||||||
""" } mkString
|
""" } mkString
|
||||||
|
|
||||||
val daw = p(DMKey).nDebugBusAddrSize
|
|
||||||
val dow = DbBusConsts.dbOpSize
|
|
||||||
val ddw = DbBusConsts.dbDataSize
|
|
||||||
val debug_bus = s"""
|
|
||||||
.io_debug_req_ready( ),
|
|
||||||
.io_debug_req_valid(1'b0),
|
|
||||||
.io_debug_req_bits_addr($daw'b0),
|
|
||||||
.io_debug_req_bits_op($dow'b0),
|
|
||||||
.io_debug_req_bits_data($ddw'b0),
|
|
||||||
.io_debug_resp_ready(1'b0),
|
|
||||||
.io_debug_resp_valid( ),
|
|
||||||
.io_debug_resp_bits_resp( ),
|
|
||||||
.io_debug_resp_bits_data( ),
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
val instantiation = s"""
|
val instantiation = s"""
|
||||||
`ifdef FPGA
|
|
||||||
assign htif_clk = clk;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
Top dut
|
Top dut
|
||||||
(
|
(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
@ -225,22 +237,7 @@ object TestBenchGeneration extends FileSystemUtilities {
|
|||||||
|
|
||||||
$interrupts
|
$interrupts
|
||||||
|
|
||||||
$debug_bus
|
$debugBus
|
||||||
|
|
||||||
`ifndef FPGA
|
|
||||||
.io_host_clk(htif_clk),
|
|
||||||
.io_host_clk_edge(),
|
|
||||||
`else
|
|
||||||
.io_host_clk (),
|
|
||||||
.io_host_clk_edge (),
|
|
||||||
`endif // FPGA
|
|
||||||
|
|
||||||
.io_host_in_valid(htif_in_valid_delay),
|
|
||||||
.io_host_in_ready(htif_in_ready_delay),
|
|
||||||
.io_host_in_bits(htif_in_bits_delay),
|
|
||||||
.io_host_out_valid(htif_out_valid_delay),
|
|
||||||
.io_host_out_ready(htif_out_ready_delay),
|
|
||||||
.io_host_out_bits(htif_out_bits_delay)
|
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -302,7 +299,7 @@ object TestBenchGeneration extends FileSystemUtilities {
|
|||||||
""" } mkString
|
""" } mkString
|
||||||
|
|
||||||
val f = createOutputFile(s"$topModuleName.$configClassName.tb.vfrag")
|
val f = createOutputFile(s"$topModuleName.$configClassName.tb.vfrag")
|
||||||
f.write(nasti_defs + delays + nasti_delays + instantiation + ticks)
|
f.write(debugDefs + nasti_defs + nasti_delays + instantiation + ticks)
|
||||||
f.close
|
f.close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
// See LICENSE for license details.
|
|
||||||
|
|
||||||
package rocketchip
|
|
||||||
|
|
||||||
import Chisel._
|
|
||||||
import cde.Parameters
|
|
||||||
import junctions._
|
|
||||||
import uncore._
|
|
||||||
|
|
||||||
object VLSIUtils {
|
|
||||||
def doOuterMemorySystemSerdes(
|
|
||||||
llcs: Seq[NastiIO],
|
|
||||||
mems: Seq[NastiIO],
|
|
||||||
backup: MemSerializedIO,
|
|
||||||
en: Bool,
|
|
||||||
nMemChannels: Int,
|
|
||||||
htifWidth: Int,
|
|
||||||
blockOffsetBits: Int)
|
|
||||||
(implicit p: Parameters) {
|
|
||||||
|
|
||||||
val arb = Module(new NastiArbiter(nMemChannels))
|
|
||||||
val conv = Module(new MemIONastiIOConverter(blockOffsetBits))
|
|
||||||
val mem_serdes = Module(new MemSerdes(htifWidth))
|
|
||||||
|
|
||||||
conv.io.nasti <> arb.io.slave
|
|
||||||
mem_serdes.io.wide <> conv.io.mem
|
|
||||||
backup <> mem_serdes.io.narrow
|
|
||||||
|
|
||||||
llcs zip mems zip arb.io.master foreach { case ((llc, mem), wide) =>
|
|
||||||
llc.ar.ready := Mux(en, wide.ar.ready, mem.ar.ready)
|
|
||||||
mem.ar.valid := llc.ar.valid && !en
|
|
||||||
mem.ar.bits := llc.ar.bits
|
|
||||||
wide.ar.valid := llc.ar.valid && en
|
|
||||||
wide.ar.bits := llc.ar.bits
|
|
||||||
|
|
||||||
llc.aw.ready := Mux(en, wide.aw.ready, mem.aw.ready)
|
|
||||||
mem.aw.valid := llc.aw.valid && !en
|
|
||||||
mem.aw.bits := llc.aw.bits
|
|
||||||
wide.aw.valid := llc.aw.valid && en
|
|
||||||
wide.aw.bits := llc.aw.bits
|
|
||||||
|
|
||||||
llc.w.ready := Mux(en, wide.w.ready, mem.w.ready)
|
|
||||||
mem.w.valid := llc.w.valid && !en
|
|
||||||
mem.w.bits := llc.w.bits
|
|
||||||
wide.w.valid := llc.w.valid && en
|
|
||||||
wide.w.bits := llc.w.bits
|
|
||||||
|
|
||||||
llc.b.valid := Mux(en, wide.b.valid, mem.b.valid)
|
|
||||||
llc.b.bits := Mux(en, wide.b.bits, mem.b.bits)
|
|
||||||
mem.b.ready := llc.b.ready && !en
|
|
||||||
wide.b.ready := llc.b.ready && en
|
|
||||||
|
|
||||||
llc.r.valid := Mux(en, wide.r.valid, mem.r.valid)
|
|
||||||
llc.r.bits := Mux(en, wide.r.bits, mem.r.bits)
|
|
||||||
mem.r.ready := llc.r.ready && !en
|
|
||||||
wide.r.ready := llc.r.ready && en
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def makeHTIFClockDivider(scr: SCRIO, host: HostIO, htifW: Int) = {
|
|
||||||
val hio = Module((new SlowIO(512)) { Bits(width = htifW) })
|
|
||||||
hio.io.set_divisor.valid := scr.wen && (scr.waddr === UInt(63))
|
|
||||||
hio.io.set_divisor.bits := scr.wdata
|
|
||||||
scr.rdata(63) := hio.io.divisor
|
|
||||||
scr.allocate(63, "HTIF_IO_CLOCK_DIVISOR")
|
|
||||||
host.clk := hio.io.clk_slow
|
|
||||||
host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk))
|
|
||||||
hio
|
|
||||||
}
|
|
||||||
|
|
||||||
def padOutHTIFWithDividedClock(
|
|
||||||
htif: HostIO,
|
|
||||||
scr: SCRIO,
|
|
||||||
host: HostIO,
|
|
||||||
htifW: Int) {
|
|
||||||
val hio = makeHTIFClockDivider(scr, host, htifW)
|
|
||||||
|
|
||||||
hio.io.out_fast <> htif.out
|
|
||||||
host.out <> hio.io.out_slow
|
|
||||||
hio.io.in_slow <> host.in
|
|
||||||
htif.in <> hio.io.in_fast
|
|
||||||
}
|
|
||||||
|
|
||||||
def padOutHTIFWithDividedClock(
|
|
||||||
htif: HostIO,
|
|
||||||
scr: SCRIO,
|
|
||||||
child: MemSerializedIO,
|
|
||||||
parent: MemBackupCtrlIO,
|
|
||||||
host: HostIO,
|
|
||||||
htifW: Int) {
|
|
||||||
val hio = makeHTIFClockDivider(scr, host, htifW+1)
|
|
||||||
|
|
||||||
hio.io.out_fast.valid := htif.out.valid || child.req.valid
|
|
||||||
hio.io.out_fast.bits := Cat(htif.out.valid, Mux(htif.out.valid, htif.out.bits, child.req.bits))
|
|
||||||
htif.out.ready := hio.io.out_fast.ready
|
|
||||||
child.req.ready := hio.io.out_fast.ready && !htif.out.valid
|
|
||||||
host.out.valid := hio.io.out_slow.valid && hio.io.out_slow.bits(htifW)
|
|
||||||
host.out.bits := hio.io.out_slow.bits
|
|
||||||
parent.out_valid := hio.io.out_slow.valid && !hio.io.out_slow.bits(htifW)
|
|
||||||
hio.io.out_slow.ready := Mux(hio.io.out_slow.bits(htifW), host.out.ready, parent.out_ready)
|
|
||||||
|
|
||||||
val mem_backup_resp_valid = parent.en && parent.in_valid
|
|
||||||
hio.io.in_slow.valid := mem_backup_resp_valid || host.in.valid
|
|
||||||
hio.io.in_slow.bits := Cat(mem_backup_resp_valid, host.in.bits)
|
|
||||||
host.in.ready := hio.io.in_slow.ready
|
|
||||||
child.resp.valid := hio.io.in_fast.valid && hio.io.in_fast.bits(htifW)
|
|
||||||
child.resp.bits := hio.io.in_fast.bits
|
|
||||||
htif.in.valid := hio.io.in_fast.valid && !hio.io.in_fast.bits(htifW)
|
|
||||||
htif.in.bits := hio.io.in_fast.bits
|
|
||||||
hio.io.in_fast.ready := Mux(hio.io.in_fast.bits(htifW), Bool(true), htif.in.ready)
|
|
||||||
}
|
|
||||||
}
|
|
2
uncore
2
uncore
@ -1 +1 @@
|
|||||||
Subproject commit 34f5fad9429ebc8922aa14e1808b2565432de986
|
Subproject commit b92487d5934d9efba0e960466455c32c36874c81
|
@ -1,16 +1,19 @@
|
|||||||
// See LICENSE for license details.
|
// See LICENSE for license details.
|
||||||
|
|
||||||
extern "A" void htif_fini(input reg failure);
|
extern "A" void do_exit(input reg failure);
|
||||||
|
|
||||||
extern "A" void htif_tick
|
extern "A" void debug_tick
|
||||||
(
|
(
|
||||||
output reg htif_in_valid,
|
output reg debug_req_valid,
|
||||||
input reg htif_in_ready,
|
input reg debug_req_ready,
|
||||||
output reg [`HTIF_WIDTH-1:0] htif_in_bits,
|
output reg [ 4:0] debug_req_bits_addr,
|
||||||
|
output reg [ 1:0] debug_req_bits_op,
|
||||||
|
output reg [33:0] debug_req_bits_data,
|
||||||
|
|
||||||
input reg htif_out_valid,
|
input reg debug_resp_valid,
|
||||||
output reg htif_out_ready,
|
output reg debug_resp_ready,
|
||||||
input reg [`HTIF_WIDTH-1:0] htif_out_bits,
|
input reg [ 1:0] debug_resp_bits_resp,
|
||||||
|
input reg [33:0] debug_resp_bits_data,
|
||||||
|
|
||||||
output reg [31:0] exit
|
output reg [31:0] exit
|
||||||
);
|
);
|
||||||
@ -68,7 +71,6 @@ module rocketTestHarness;
|
|||||||
always #`CLOCK_PERIOD clk = ~clk;
|
always #`CLOCK_PERIOD clk = ~clk;
|
||||||
|
|
||||||
reg [ 31:0] n_mem_channel = `N_MEM_CHANNELS;
|
reg [ 31:0] n_mem_channel = `N_MEM_CHANNELS;
|
||||||
reg [ 31:0] htif_width = `HTIF_WIDTH;
|
|
||||||
reg [ 31:0] mem_width = `MEM_DATA_BITS;
|
reg [ 31:0] mem_width = `MEM_DATA_BITS;
|
||||||
reg [ 63:0] max_cycles = 0;
|
reg [ 63:0] max_cycles = 0;
|
||||||
reg [ 63:0] trace_count = 0;
|
reg [ 63:0] trace_count = 0;
|
||||||
@ -79,12 +81,6 @@ module rocketTestHarness;
|
|||||||
wire printf_cond = verbose && !reset;
|
wire printf_cond = verbose && !reset;
|
||||||
integer stderr = 32'h80000002;
|
integer stderr = 32'h80000002;
|
||||||
|
|
||||||
reg htif_out_ready;
|
|
||||||
reg htif_in_valid;
|
|
||||||
reg [`HTIF_WIDTH-1:0] htif_in_bits;
|
|
||||||
wire htif_in_ready, htif_out_valid;
|
|
||||||
wire [`HTIF_WIDTH-1:0] htif_out_bits;
|
|
||||||
|
|
||||||
`include `TBVFRAG
|
`include `TBVFRAG
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
@ -94,24 +90,26 @@ module rocketTestHarness;
|
|||||||
|
|
||||||
reg [31:0] exit = 0;
|
reg [31:0] exit = 0;
|
||||||
|
|
||||||
always @(posedge htif_clk)
|
always @(posedge clk)
|
||||||
begin
|
begin
|
||||||
if (reset || r_reset)
|
if (reset || r_reset)
|
||||||
begin
|
begin
|
||||||
htif_in_valid <= 0;
|
debug_req_valid <= 0;
|
||||||
htif_out_ready <= 0;
|
debug_resp_ready <= 0;
|
||||||
exit <= 0;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
htif_tick
|
debug_tick
|
||||||
(
|
(
|
||||||
htif_in_valid,
|
debug_req_valid,
|
||||||
htif_in_ready,
|
debug_req_ready,
|
||||||
htif_in_bits,
|
debug_req_bits_addr,
|
||||||
htif_out_valid,
|
debug_req_bits_op,
|
||||||
htif_out_ready,
|
debug_req_bits_data,
|
||||||
htif_out_bits,
|
debug_resp_valid,
|
||||||
|
debug_resp_ready,
|
||||||
|
debug_resp_bits_resp,
|
||||||
|
debug_resp_bits_data,
|
||||||
exit
|
exit
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
@ -161,7 +159,7 @@ module rocketTestHarness;
|
|||||||
begin
|
begin
|
||||||
$fdisplay(stderr, "*** FAILED *** (%s) after %d simulation cycles", reason, trace_count);
|
$fdisplay(stderr, "*** FAILED *** (%s) after %d simulation cycles", reason, trace_count);
|
||||||
`VCDPLUSCLOSE
|
`VCDPLUSCLOSE
|
||||||
htif_fini(1'b1);
|
do_exit(1'b1);
|
||||||
end
|
end
|
||||||
|
|
||||||
if (exit == 1)
|
if (exit == 1)
|
||||||
@ -169,7 +167,7 @@ module rocketTestHarness;
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
$fdisplay(stderr, "Completed after %d simulation cycles", trace_count);
|
$fdisplay(stderr, "Completed after %d simulation cycles", trace_count);
|
||||||
`VCDPLUSCLOSE
|
`VCDPLUSCLOSE
|
||||||
htif_fini(1'b0);
|
do_exit(1'b0);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user