1
0

Allow the number of memory channels to be picked at runtime

We're building a chip with 8 memory channels.  Since this will require a
complicated test setup we want to also be able to bring up the chip with fewer
memory channels.  This commit adds a SCR that controls the number of active
memory channels on a chip.  Toggling this SCR will scramble memory and drop
Nasti messages, so it's only possible to change while the chip is booting.

By default this just adds a 1-bit SCR, which essentially no extra logic.

When multiple memory channel configurations are enabled at elaboration time, a
NastiMemoryInterconnect is generated for each channel configuration.  The
number of outstanding misses is increased to coorespond to the maximum number
of banks per memory channel (added as a parameter), which I believe is
necessary to avoid deadlock in the memory system.

A configuration is added that supports 8 memory channels but has only 1 enabled
by default.
This commit is contained in:
Palmer Dabbelt
2016-02-17 15:23:30 -08:00
parent 95b065153d
commit 926efd0cab
6 changed files with 78 additions and 9 deletions

View File

@ -7,12 +7,20 @@
class htif_emulator_t : public htif_pthread_t
{
int memory_channel_mux_select;
public:
htif_emulator_t(uint32_t memsz_mb, const std::vector<std::string>& args)
: htif_pthread_t(args)
: htif_pthread_t(args),
memory_channel_mux_select(0)
{
this->_memsz_mb = memsz_mb;
}
for (const auto& arg: args) {
if (!strncmp(arg.c_str(), "+memory_channel_mux_select=", 27))
memory_channel_mux_select = atoi(arg.c_str()+27);
}
}
void set_clock_divisor(int divisor, int hold_cycles)
{
@ -22,6 +30,7 @@ class htif_emulator_t : public htif_pthread_t
void start()
{
set_clock_divisor(5, 2);
write_cr(-1, UNCORE_SCR__MEMORY_CHANNEL_MUX_SELECT, memory_channel_mux_select);
htif_pthread_t::start();
}

View File

@ -14,11 +14,24 @@ extern "C" {
extern int vcs_main(int argc, char** argv);
static const int MEMORY_CHANNEL_MUX_CONFIGS[] = {
#ifdef MEMORY_CHANNEL_MUX_CONFIGS__0
MEMORY_CHANNEL_MUX_CONFIGS__0,
#endif
#ifdef MEMORY_CHANNEL_MUX_CONFIGS__1
MEMORY_CHANNEL_MUX_CONFIGS__1,
#endif
#ifdef MEMORY_CHANNEL_MUX_CONFIGS__2
#error "Add a preprocessor repeat macro"
#endif
};
static htif_emulator_t* htif;
static unsigned htif_bytes = HTIF_WIDTH / 8;
static mm_t* mm[N_MEM_CHANNELS];
static const char* loadmem;
static bool dramsim = false;
static int memory_channel_mux_select = 0;
void htif_fini(vc_handle failure)
{
@ -37,21 +50,25 @@ int main(int argc, char** argv)
dramsim = true;
else if (!strncmp(argv[i], "+loadmem=", 9))
loadmem = argv[i]+9;
else if (!strncmp(argv[i], "+memory_channel_mux_select=", 27))
memory_channel_mux_select = atoi(argv[i]+27);
}
int enabled_mem_channels = MEMORY_CHANNEL_MUX_CONFIGS[memory_channel_mux_select];
htif = new htif_emulator_t(memsz_mb,
std::vector<std::string>(argv + 1, argv + argc));
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]->init(MEM_SIZE / N_MEM_CHANNELS, MEM_DATA_BITS / 8, CACHE_BLOCK_BYTES);
mm[i]->init(MEM_SIZE / enabled_mem_channels, MEM_DATA_BITS / 8, CACHE_BLOCK_BYTES);
}
if (loadmem) {
void *mems[N_MEM_CHANNELS];
for (int i = 0; i < N_MEM_CHANNELS; i++)
mems[i] = mm[i]->get_data();
load_mem(mems, loadmem, CACHE_BLOCK_BYTES, N_MEM_CHANNELS);
load_mem(mems, loadmem, CACHE_BLOCK_BYTES, enabled_mem_channels);
}
vcs_main(argc, argv);