68 std::ostream& warningStream, std::ostream& errorStream,
70 bool generateIntegratedTestbench)
72 machine, idf, hdl, progeOutputDir, coreEntityName, outputDir,
73 programName, targetClockFreq, warningStream, errorStream, imem,
84 syncReset_(syncReset),
85 broadcast_pmem_(
false),
86 generateIntegratedTestbench_(generateIntegratedTestbench) {
93 "AlmaIF interface requires connections to an external debugger.";
94 throw InvalidData(__FILE__, __LINE__,
"AlmaIFIntegrator", msg);
104 std::map<TCEString, MemoryGenerator*>::iterator iter =
117 bool foundDmem =
false;
118 bool foundPmem =
false;
128 for (
int i = 0; i < fuNav.
count(); i++) {
135 std::string prefix = operation.substr(0, 2);
136 if (prefix ==
"ld" || prefix ==
"st") {
190 }
else if (foundDmem) {
200 }
else if (foundPmem) {
215 for (
int i = 0; i < coreCount; i++) {
216 int coreId = coreCount == 1 ? -1 : i;
245 int imemAddressWidth = 0;
253 int debugAddressWidth = 8;
254 int dmemAddressWidth =
261 int pmemAddressWidth = 0;
271 std::max(imemAddressWidth, debugAddressWidth),
272 std::max(dmemAddressWidth, pmemAddressWidth));
290 int bustrace_width = 0;
299 bus_width = (bus_width + 31) / 32 * 32;
300 bustrace_width += bus_width;
308 "axi_addr_width_g",
"integer",
"AXI_ADDR_WIDTH");
311 "axi_id_width_g",
"integer",
"AXI_ID_WIDTH");
314 "axi_addr_width_g",
"integer",
"axi_addr_width_g");
321 "imem_axi_addr_width_g",
"integer",
333 "local_mem_addrw_g",
"integer",
"local_mem_addrw_g");
344 "second_dmem_data_width_g",
"integer",
347 "second_dmem_addr_width_g",
"integer",
353 "second-dmem-port-declarations",
354 Path(platformPath +
"second_dmem_port_declaration.snippet"));
358 "second-dmem-signal-declarations",
359 Path(platformPath +
"second_dmem_signal_declaration.snippet"));
365 "second-pmem-port-declarations",
366 Path(platformPath +
"second_pmem_port_declaration.snippet"));
370 "second-pmem-signal-declarations",
371 Path(platformPath +
"second_pmem_signal_declaration.snippet"));
375 "second_pmem_data_width_g",
"integer",
379 "second_pmem_addr_width_g",
"integer",
"local_mem_addrw_g");
382 "second_pmem_addr_width_g",
"integer",
396 "pmem-bcast",
Path(platformPath +
"pmem_broadcast.snippet"));
411 "Broadcasting pmem not supported with m_axi");
413 "local_mem_addrw_g",
"integer",
417 "axi_offset_low_g",
"integer",
"1073741824");
420 "axi_offset_low_g",
"integer",
"axi_offset_low_g");
422 "axi_offset_high_g",
"integer",
"axi_offset_high_g");
431 "local_mem_addrw_g",
"integer",
435 "axi_offset_high_g",
"integer",
"0");
443 "full-debugger-port-declarations",
444 Path(platformPath +
"full_debugger_port_declaration.snippet"));
446 "debugger",
Path(platformPath +
"full_debugger.snippet"));
449 "core_db_pc_start", coreCount * imemaddrw,
ProGe::OUT,
452 "core_db_pc_next", coreCount * imemaddrw,
ProGe::IN,
455 "core_db_bustraces", coreCount * bustrace_width,
ProGe::IN,
460 "mini-debugger-signal-declarations",
461 Path(platformPath +
"mini_debugger_signal_declaration.snippet"));
463 "debugger",
Path(platformPath +
"mini_debugger.snippet"));
471 "reserved_sp_bytes_g",
"integer",
476 "core_db_pc", coreCount * imemaddrw,
ProGe::IN,
"db_pc");
478 "core_db_lockcnt", coreCount * 64,
ProGe::IN,
"db_lockcnt");
480 "core_db_cyclecnt", coreCount * 64,
ProGe::IN,
"db_cyclecnt");
482 "core_db_tta_nreset", coreCount,
ProGe::OUT,
"db_tta_nreset");
484 "core_db_lockrq", coreCount,
ProGe::OUT,
"db_lockrq");
487 "core_db_dram_offset", 32,
ProGe::OUT,
"db_dram_offset");
489 "dram-offset-port-declaration",
490 "core_db_dram_offset : out std_logic_vector(32-1 downto 0);");
493 "enable-dmem",
"constant enable_dmem : boolean := false;");
498 "dram-offset-dummy-declaration",
499 "signal core_db_dram_offset : std_logic_vector(32-1 downto 0);");
502 "constant enable_dmem : boolean := dmem_data_width_g > 0;");
509 "core_imem_data_out", coreCount * imemdataw,
ProGe::OUT,
512 "core_imem_en_x_in", coreCount,
ProGe::IN,
"imem_en_x");
514 "core_imem_addr_in", coreCount * imemaddrw,
ProGe::IN,
518 const int strb_width = imemdataw / 8;
519 const int half_cores_ceil = (coreCount + 1) / 2;
523 "INSTR_a", half_cores_ceil, imemdataw * half_cores_ceil,
524 imemaddrw * half_cores_ceil, strb_width * half_cores_ceil,
527 "INSTR_b", half_cores_ceil, imemdataw * half_cores_ceil,
528 imemaddrw * half_cores_ceil, strb_width * half_cores_ceil,
540 Path(platformPath +
"imem_statements.snippet"));
544 Path(platformPath +
"imem_broadcast_dualport.snippet"));
546 "imem-port-declarations",
548 platformPath +
"imem_port_declaration_dualport.snippet"));
551 "imem-bcast",
Path(platformPath +
"imem_broadcast.snippet"));
553 "imem-port-declarations",
554 Path(platformPath +
"imem_port_declaration.snippet"));
566 mem_name +
"_data_width_g",
"integer",
569 mem_name +
"_addr_width_g",
"integer",
579 Path snippet(platformPath + mem_name +
"_signal_declaration.snippet");
581 mem_name +
"-signal-declarations", snippet);
587 Path snippet(platformPath +
"pmem_port_declaration_wide.snippet");
589 mem_name +
"-port-declarations", snippet);
591 Path snippet(platformPath + mem_name +
"_port_declaration.snippet");
593 mem_name +
"-port-declarations", snippet);
600 "core_" + mem_name +
"_avalid_in", coreCount,
ProGe::IN,
601 lsu_prefix +
"_avalid_out");
603 "core_" + mem_name +
"_aready_out", coreCount,
ProGe::OUT,
604 lsu_prefix +
"_aready_in");
606 "core_" + mem_name +
"_aaddr_in", coreCount * mem.
portAddrw,
609 "core_" + mem_name +
"_awren_in", coreCount,
ProGe::IN,
610 lsu_prefix +
"_awren_out");
612 "core_" + mem_name +
"_astrb_in",
614 lsu_prefix +
"_astrb_out");
617 "core_" + mem_name +
"_adata_in",
619 lsu_prefix +
"_adata_out");
621 "core_" + mem_name +
"_rvalid_out", coreCount,
ProGe::OUT,
622 lsu_prefix +
"_rvalid_in");
624 "core_" + mem_name +
"_rready_in", coreCount,
ProGe::IN,
625 lsu_prefix +
"_rready_out");
627 "core_" + mem_name +
"_rdata_out",
629 lsu_prefix +
"_rdata_in");
632 int addrWidth, dataWidth;
643 "core_" + mem_name +
"_2nd_avalid_in", coreCount,
ProGe::IN,
644 lsu_prefix +
"_avalid_out");
646 "core_" + mem_name +
"_2nd_aready_out", coreCount,
ProGe::OUT,
647 lsu_prefix +
"_aready_in");
649 "core_" + mem_name +
"_2nd_aaddr_in", coreCount * addrWidth,
652 "core_" + mem_name +
"_2nd_awren_in", coreCount,
ProGe::IN,
653 lsu_prefix +
"_awren_out");
655 "core_" + mem_name +
"_2nd_astrb_in", coreCount * dataWidth / 8,
659 "core_" + mem_name +
"_2nd_adata_in", coreCount * dataWidth,
662 "core_" + mem_name +
"_2nd_rvalid_out", coreCount,
ProGe::OUT,
663 lsu_prefix +
"_rvalid_in");
665 "core_" + mem_name +
"_2nd_rready_in", coreCount,
ProGe::IN,
666 lsu_prefix +
"_rready_out");
668 "core_" + mem_name +
"_2nd_rdata_out", coreCount * dataWidth,
680 bool make_local_sized =
789 const TCEString prefix,
int data_width,
int addr_width,
790 const bool ,
const bool overrideAsWidth) {
793 data_width = data_width * mem_count;
794 addr_width = addr_width * mem_count;
799 int strb_width = (data_width / mem_count + 7) / 8 * mem_count;
802 prefix, mem_count, data_width, addr_width, strb_width,
808 const TCEString prefix,
int mem_count,
int data_width,
int addr_width,
809 int strb_width,
const bool overrideAsWidth) {
812 if (overrideAsWidth) {
814 prefix +
"_aaddr_out",
"local_mem_addrw_g",
ProGe::OUT);
829 std::vector<TCEString> almaifFiles;
837 Path snippet(platformPath +
"axi_master_port_declaration.snippet");
839 "m-axi-port-declarations", snippet);
841 Path snippet(platformPath +
"axi_master_signal_declaration.snippet");
843 "m-axi-signal-declarations", snippet);
847 platformPath +
"tta-accel.vhdl.tmpl",
outputPath);
879 scriptPath +
"utilization.tcl.tmpl",
outputPath);
881 for (
unsigned int i = 0; i < almaifFiles.size(); i++) {
888 const TCEString inputPath, std::vector<TCEString>& fileList,
889 bool isScript)
const {
913 auto ttaCCPort = core.
port(
"debug_cycle_count_in");
915 netlist.
connect(*core.
port(
"db_cyclecnt"), *ttaCCPort);
917 auto ttaLCPort = core.
port(
"debug_lock_count_in");
919 netlist.
connect(*core.
port(
"db_lockcnt"), *ttaLCPort);
921 for (
size_t i = 0; i < core.
portCount(); ++i) {
931 if (portName.substr(0, 4) ==
"core") {
933 coreKey <<
"core" << coreId;
934 size_t cutoff = portName.find_first_of(
'_');
935 if (portName.substr(0, cutoff) != coreKey) {
939 portName = portName.substr(cutoff + 1);
947 if (coreId != -1 &&
imem_dp_ && portName ==
"imem_data") {
953 portWidth * coreId,
imemInfo().mauWidth);
955 }
else if (coreId != -1) {
958 portWidth * coreId, portWidth);
1018 TCEString msg =
"Unsupported instruction memory type";
1019 throw InvalidData(__FILE__, __LINE__,
"AlmaIFIntegrator", msg);
1028 std::vector<std::string> lsuPorts) {
1036 bool genSingleRam =
false;
1037 bool genDualPortRam =
false;
1038 bool overrideAsWidth =
false;
1041 bool isSecondInstance =
false;
1052 if (isDmem || isPmem) {
1053 genDualPortRam =
true;
1057 isSecondInstance =
true;
1066 isSecondInstance =
true;
1077 overrideAsWidth =
true;
1099 TCEString msg =
"Unsupported data memory type";
1100 throw InvalidData(__FILE__, __LINE__,
"AlmaIFIntegrator", msg);
1102 memGen->
addLsu(lsuArch, lsuPorts);
1111 <<
"Integrator name: AlmaIFIntegrator" << std::endl
1112 <<
"-----------------------------" << std::endl
1113 <<
"Integrates the processor core to an AXI4 bus interface according "
1114 <<
"to ALMARVI HW Integration Interface specification." << std::endl
1115 <<
"Supported instruction memory types are 'onchip' and 'none'."
1117 <<
"Supported data memory types are 'onchip' and 'none'." << std::endl
1118 <<
"Data and Parameter memory spaces must be named '" <<
DMEM_NAME
1119 <<
"' and '" <<
PMEM_NAME <<
"' respectively." << std::endl
1179 "m-axi-port-declarations",
1180 Path(tbPath +
"almaif-tb-m-axi-port-declarations-snippet.vhdl"));
1182 "m-axi-port-connections",
1183 Path(tbPath +
"almaif-tb-m-axi-port-connections-snippet.vhdl"));
1185 "m-axi-external-mem-instantiation",
1188 "almaif-tb-m-axi-external-mem-instantiation-snippet.vhdl"));
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the false
virtual bool chopTaggedSignals() const
virtual MemoryGenerator & dmemInstance(MemInfo dmem, TTAMachine::FunctionUnit &lsuArch, std::vector< std::string > lsuPorts)
void exportUnconnectedPorts(int coreId)
virtual int targetClockFrequency() const
std::string secondPmemName_
ProGe::NetlistPortGroup * axiMasterPortGroup()
std::map< TCEString, MemoryGenerator * > dmemGen_
virtual ProjectFileGenerator * projectFileGenerator() const
static const int DEFAULT_LOCAL_MEMORY_WIDTH
virtual void printInfo(std::ostream &stream) const
virtual void setDeviceFamily(TCEString devFamily)
ProGe::NetlistBlock * almaifBlock_
ProGe::NetlistPortGroup * axiSlavePortGroup()
static const TCEString AXI_AS_NAME
virtual void integrateProcessor(const ProGe::NetlistBlock *progeBlock)
static const int DEFAULT_RESERVED_PRIVATE_MEM_SIZE
TCEString axiAddressWidth() const
static const TCEString ALMAIF_MODULE
HDLTemplateInstantiator accelInstantiator_
bool generateIntegratedTestbench_
virtual TCEString devicePackage() const
virtual TCEString deviceFamily() const
MemoryGenerator * imemGen_
std::map< TCEString, ProGe::NetlistPort * > almaif_ttacore_ports
virtual ~AlmaIFIntegrator()
virtual TCEString deviceSpeedClass() const
static const TCEString DMEM_NAME
void addMemoryPorts(const TCEString as_name, int data_width, int addr_width, const bool isShared, const bool overrideAsWidth)
static const TCEString PMEM_NAME
bool hasSeparateLocalMemory_
std::string secondDmemName_
void generateIntegratedTestbench()
virtual bool integrateCore(const ProGe::NetlistBlock &cores, int coreId)
virtual MemoryGenerator & imemInstance(MemInfo imem, int coreId)
void connectCoreMemories(MemInfo mem, TCEString mem_name, TCEString mem_block_name, bool seconds)
virtual TCEString pinTag() const
static const TCEString DEFAULT_DEVICE
void addPortToGroup(ProGe::NetlistPortGroup *port_group, const ProGe::Direction dir, const TCEString name, const TCEString width)
void copyPlatformFile(const TCEString inputPath, std::vector< TCEString > &fileList, bool isScript=false) const
DefaultProjectFileGenerator * fileGen_
void addPortToAlmaIFBlock(const TCEString name, const TCEString width, const ProGe::Direction dir, const TCEString core_name="")
static std::string toString(const T &source)
static std::string dataDirPath(const std::string &prog)
static bool createDirectory(const std::string &path)
static const std::string DIRECTORY_SEPARATOR
static std::string fileOfPath(const std::string pathName)
static void copy(const std::string &source, const std::string &target)
void instantiateTemplateFile(const std::string &templateFile, const std::string &dstFile)
void replacePlaceholderFromFile(const std::string &key, const Path &filePath, bool append=false)
void replacePlaceholder(const std::string &key, const std::string &replacer, bool append=false)
std::string icDecoderParameterValue(const std::string &name) const
void addLsu(TTAMachine::FunctionUnit &lsuArch, std::vector< std::string > lsuPorts)
void setParameter(const std::string &name, const std::string &type, const std::string &value)
virtual NetlistPort * port(const std::string &portName, bool partialMatch=true)
virtual size_t portCount() const
void addPortGroup(NetlistPortGroup *portGroup)
virtual const Netlist & netlist() const
void addPort(NetlistPort &port)
virtual NetlistPortGroup * clone(bool asMirrored=false) const
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
void setParameter(const std::string &name, const std::string &type, const std::string &value)
bool connectGroupByName(const NetlistPortGroup &group1, const NetlistPortGroup &group2)
virtual void writeProjectFiles()=0
void addHdlFile(const TCEString &file)
virtual bool hasNumericalId(unsigned id) const
virtual TCEString name() const
virtual AddressSpace * addressSpace() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasAddressSpace() const
const std::string & name() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
virtual BusNavigator busNavigator() const
DataType
Data types of hardware ports.
@ BIT_VECTOR
Several bits.
Direction
Direction of the port.
HDL
HDLs supported by ProGe.