Merge pull request #638 from firesim/support-no-mem
Add support for target designs with SerialBridge but no DRAM
This commit is contained in:
commit
0ad13d1093
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue