Merge pull request #638 from firesim/support-no-mem

Add support for target designs with SerialBridge but no DRAM
This commit is contained in:
Jerry Zhao 2020-10-08 11:50:57 -07:00 committed by GitHub
commit 0ad13d1093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 15 deletions

View File

@ -4,8 +4,8 @@
#include <assert.h>
#include "serial.h"
serial_t::serial_t(simif_t* sim, const std::vector<std::string>& args, SERIALBRIDGEMODULE_struct * mmio_addrs, int serialno, int64_t mem_host_offset):
bridge_driver_t(sim), sim(sim), mem_host_offset(mem_host_offset) {
serial_t::serial_t(simif_t* sim, const std::vector<std::string>& args, SERIALBRIDGEMODULE_struct * mmio_addrs, int serialno, bool has_mem, int64_t mem_host_offset):
bridge_driver_t(sim), sim(sim), has_mem(has_mem), mem_host_offset(mem_host_offset) {
this->mmio_addrs = mmio_addrs;
@ -56,7 +56,7 @@ serial_t::serial_t(simif_t* sim, const std::vector<std::string>& args, SERIALBRI
printf("\n");
std::vector<std::string> args_new(argv_arr, argv_arr + argc_count);
fesvr = new firesim_fesvr_t(args_new);
fesvr = new firesim_fesvr_t(args_new, has_mem);
}
serial_t::~serial_t() {
@ -89,6 +89,7 @@ void serial_t::recv() {
void serial_t::handle_loadmem_read(fesvr_loadmem_t loadmem) {
assert(loadmem.size % sizeof(uint32_t) == 0);
assert(has_mem);
// Loadmem reads are in granularities of the width of the FPGA-DRAM bus
mpz_t buf;
mpz_init(buf);
@ -118,6 +119,7 @@ void serial_t::handle_loadmem_read(fesvr_loadmem_t loadmem) {
void serial_t::handle_loadmem_write(fesvr_loadmem_t loadmem) {
assert(loadmem.size <= 1024);
assert(has_mem);
static char buf[1024];
fesvr->recv_loadmem_data(buf, loadmem.size);
mpz_t data;

View File

@ -29,13 +29,14 @@ struct serial_data_t {
args, \
SERIALBRIDGEMODULE_ ## IDX ## _substruct, \
IDX, \
SERIALBRIDGEMODULE_ ## IDX ## _has_memory, \
SERIALBRIDGEMODULE_ ## IDX ## _memory_offset)); \
#ifdef SERIALBRIDGEMODULE_struct_guard
class serial_t: public bridge_driver_t
{
public:
serial_t(simif_t* sim, const std::vector<std::string>& args, SERIALBRIDGEMODULE_struct * mmio_addrs, int serialno, int64_t mem_host_offset);
serial_t(simif_t* sim, const std::vector<std::string>& args, SERIALBRIDGEMODULE_struct * mmio_addrs, int serialno, bool has_mem, int64_t mem_host_offset);
~serial_t();
virtual void init();
virtual void tick();
@ -47,6 +48,7 @@ class serial_t: public bridge_driver_t
SERIALBRIDGEMODULE_struct * mmio_addrs;
simif_t* sim;
firesim_fesvr_t* fesvr;
bool has_mem;
// host memory offset based on the number of memory models and their size
int64_t mem_host_offset;
// Number of target cycles between fesvr interactions

View File

@ -16,7 +16,7 @@ int firesim_fesvr_t::host_thread(void *arg)
return 0;
}
firesim_fesvr_t::firesim_fesvr_t(const std::vector<std::string> args) : htif_t(args)
firesim_fesvr_t::firesim_fesvr_t(const std::vector<std::string> args, bool has_loadmem) : htif_t(args), has_loadmem(has_loadmem)
{
is_loadmem = false;
is_busy = false;

View File

@ -26,7 +26,7 @@ struct fesvr_loadmem_t {
class firesim_fesvr_t : public htif_t
{
public:
firesim_fesvr_t(const std::vector<std::string> args);
firesim_fesvr_t(const std::vector<std::string> args, bool has_loadmem);
~firesim_fesvr_t(){};
bool busy() { return is_busy; }
bool data_available();
@ -44,7 +44,7 @@ class firesim_fesvr_t : public htif_t
void reset();
void load_program() {
wait(); // Switch back to commit all pending requests
is_loadmem = true;
is_loadmem = has_loadmem;
htif_t::load_program();
is_loadmem = false;
}
@ -65,6 +65,7 @@ class firesim_fesvr_t : public htif_t
private:
bool is_busy;
bool has_loadmem;
// A flag set only during program load to forward fesvr
// read/write_chunks to the loadmem unit instead of going over tsi
bool is_loadmem;

View File

@ -10,16 +10,26 @@ import freechips.rocketchip.config.Parameters
import testchipip.{SerialIO, SerialAdapter}
class SerialBridge(memoryRegionName: String) extends BlackBox with Bridge[HostPortIO[SerialBridgeTargetIO], SerialBridgeModule] {
/**
* Class which parameterizes the SerialBridge
*
* memoryRegionNameOpt, if unset, indicates that firesim-fesvr should not attempt to write a payload into DRAM through the loadmem unit.
* This is suitable for target designs which do not use the FASED DRAM model.
* If a FASEDBridge for the backing AXI4 memory is present, then memoryRegionNameOpt should be set to the same memory region name which is passed
* to the FASEDBridge. This enables fast payload loading in firesim-fesvr through the loadmem unit.
*/
case class SerialBridgeParams(memoryRegionNameOpt: Option[String])
class SerialBridge(memoryRegionNameOpt: Option[String]) extends BlackBox with Bridge[HostPortIO[SerialBridgeTargetIO], SerialBridgeModule] {
val io = IO(new SerialBridgeTargetIO)
val bridgeIO = HostPort(io)
val constructorArg = Some(memoryRegionName)
val constructorArg = Some(SerialBridgeParams(memoryRegionNameOpt))
generateAnnotations()
}
object SerialBridge {
def apply(clock: Clock, port: SerialIO, memoryRegionName: String)(implicit p: Parameters): SerialBridge = {
val ep = Module(new SerialBridge(memoryRegionName))
def apply(clock: Clock, port: SerialIO, memoryRegionNameOpt: Option[String])(implicit p: Parameters): SerialBridge = {
val ep = Module(new SerialBridge(memoryRegionNameOpt))
ep.io.serial <> port
ep.io.clock := clock
ep
@ -32,8 +42,8 @@ class SerialBridgeTargetIO extends Bundle {
val clock = Input(Clock())
}
class SerialBridgeModule(val memoryRegionName: String)(implicit p: Parameters)
extends BridgeModule[HostPortIO[SerialBridgeTargetIO]]()(p) with HostDramHeaderConsts {
class SerialBridgeModule(serialBridgeParams: SerialBridgeParams)(implicit p: Parameters)
extends BridgeModule[HostPortIO[SerialBridgeTargetIO]]()(p) {
lazy val module = new BridgeModuleImp(this) {
val io = IO(new WidgetIO)
val hPort = IO(HostPort(new SerialBridgeTargetIO))
@ -83,6 +93,9 @@ class SerialBridgeModule(val memoryRegionName: String)(implicit p: Parameters)
import CppGenerationUtils._
val headerWidgetName = getWName.toUpperCase
super.genHeader(base, sb)
val memoryRegionNameOpt = serialBridgeParams.memoryRegionNameOpt
val offsetConstName = memoryRegionNameOpt.map(GetMemoryRegionOffsetConstName(_)).getOrElse("0")
sb.append(genMacro(s"${headerWidgetName}_has_memory", memoryRegionNameOpt.isDefined.toString))
sb.append(genMacro(s"${headerWidgetName}_memory_offset", offsetConstName))
}
}

View File

@ -37,6 +37,7 @@ abstract class PlatformShim(implicit p: Parameters) extends LazyModule()(p) {
val top = LazyModule(new midas.core.FPGATop)
def genHeader(sb: StringBuilder, target: String) {
sb.append("#include <stdint.h>\n")
sb.append("#include <stdbool.h>\n")
sb.append(genStatic("TARGET_NAME", CStrLit(target)))
sb.append(genMacro("PLATFORM_TYPE", s"V${this.getClass.getSimpleName}"))
sb.append(genMacro("data_t", "uint32_t"))

View File

@ -35,6 +35,10 @@ import chisel3.util.isPow2
*/
case class MemorySlaveConstraints(address: Seq[AddressSet], supportsRead: TransferSizes, supportsWrite: TransferSizes)
object GetMemoryRegionOffsetConstName {
def apply(memoryRegionName: String) = s"${memoryRegionName}_offset"
}
/**
* A common trait for referring collateral in the generated header.
*
@ -50,7 +54,7 @@ trait HostDramHeaderConsts {
*
*/
def memoryRegionName: String
def offsetConstName = s"${memoryRegionName}_offset"
def offsetConstName = GetMemoryRegionOffsetConstName(memoryRegionName)
}
/**

@ -1 +1 @@
Subproject commit b76972d34b685a95fc130ad213fd19e23074fd4d
Subproject commit b057cfbd8c0560fb82cdad63a228c7b827c09bd7