OpenASIP 2.2
Loading...
Searching...
No Matches
AlmaIFIntegrator.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2016 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file AlmaIFIntegrator.cc
26 *
27 * Implementation of AlmaIFIntegrator class.
28 */
29
30#include "AlmaIFIntegrator.hh"
31#include "VhdlRomGenerator.hh"
33#include "Machine.hh"
34#include "HWOperation.hh"
35#include "NetlistPort.hh"
36#include "NetlistPortGroup.hh"
37#include "SignalGroup.hh"
38#include "NetlistBlock.hh"
41#include "DummyMemGenerator.hh"
42#include "Conversion.hh"
43#include "Environment.hh"
44#include "FileSystem.hh"
45#include "MathTools.hh"
47
51
56const TCEString AlmaIFIntegrator::DEFAULT_DEVICE = "xc7z020clg400-1";
57
60
63
66 ProGe::HDL hdl, TCEString progeOutputDir, TCEString coreEntityName,
67 TCEString outputDir, TCEString programName, int targetClockFreq,
68 std::ostream& warningStream, std::ostream& errorStream,
69 const MemInfo& imem, MemType dmemType, bool syncReset,
70 bool generateIntegratedTestbench)
72 machine, idf, hdl, progeOutputDir, coreEntityName, outputDir,
73 programName, targetClockFreq, warningStream, errorStream, imem,
74 dmemType),
75 imemGen_(NULL),
76 dmemGen_(),
77 almaifBlock_(NULL),
78 deviceFamily_(""),
79 fileGen_(new DefaultProjectFileGenerator(coreEntityName, this)),
80 secondDmem_(false),
81 secondPmem_(false),
82 dmemHandled_(false),
83 pmemHandled_(false),
84 syncReset_(syncReset),
85 broadcast_pmem_(false),
86 generateIntegratedTestbench_(generateIntegratedTestbench) {
87 if (idf->icDecoderParameterValue("debugger") == "external") {
88 hasMinimalDebugger_ = false;
89 } else if (idf->icDecoderParameterValue("debugger") == "minimal") {
91 } else {
92 TCEString msg =
93 "AlmaIF interface requires connections to an external debugger.";
94 throw InvalidData(__FILE__, __LINE__, "AlmaIFIntegrator", msg);
95 }
96}
97
99
100 if (imemGen_ != NULL) {
101 delete imemGen_;
102 }
103 if (!dmemGen_.empty()) {
104 std::map<TCEString, MemoryGenerator*>::iterator iter =
105 dmemGen_.begin();
106 while (iter != dmemGen_.end()) {
107 delete iter->second;
108 iter++;
109 }
110 }
111}
112
113void
115 dmemInfo_ = pmemInfo_ = {UNKNOWN, 0, 0, 0, 0, false, "", ""};
116
117 bool foundDmem = false;
118 bool foundPmem = false;
119
120 // This is more or less a duplicate of parseDataMemories in the superclass
121 // to get around it not parsing memories if dmem type is 'none' and it not
122 // handling multiple lsus well
123
124 MemInfo secondDmemInfo;
125 MemInfo secondPmemInfo;
128 for (int i = 0; i < fuNav.count(); i++) {
129 TTAMachine::FunctionUnit* fu = fuNav.item(i);
130 if (fu->hasAddressSpace()) {
132 bool isLSU = false;
133 for (int i = 0; i < fu->operationCount(); ++i) {
134 std::string operation = fu->operation(i)->name();
135 std::string prefix = operation.substr(0, 2);
136 if (prefix == "ld" || prefix == "st") {
137 isLSU = true;
138 break;
139 }
140 }
141
142 if (!isLSU) {
143 continue;
144 }
145
146 if (as->name() == DMEM_NAME) {
147 if (foundDmem) {
148 assert(!secondDmem_ && "Found third DMEM LSU");
149 secondDmem_ = true;
150 secondDmemInfo = readLsuParameters(*fu);
151 if (secondDmemInfo.portAddrw < dmemInfo_.portAddrw) {
152 // Second DMEM should have lesser or equal data
153 // width => greater or equal address width
154 // swap if this is not the case
155 secondDmemInfo = dmemInfo_;
157 }
158 secondDmemName_ = secondDmemInfo.lsuName;
159 } else {
160 foundDmem = true;
162 if (dmem_dram_) {
164 }
165 }
166 } else if (as->name() == PMEM_NAME) {
167 if (foundPmem) {
168 assert(!secondPmem_ && "Found third PMEM LSU");
169 secondPmem_ = true;
170 secondPmemInfo = readLsuParameters(*fu);
171 } else {
172 foundPmem = true;
174
175 // Needed for the case when the local memory doesn't exist
176 // and needs to reserved from the buffer memory
177 if (as->hasNumericalId(0)) {
179 }
180 }
181 }
182 }
183 }
184
185 if (secondDmem_) {
186 secondDmemName_ = secondDmemInfo.lsuName;
188 secondDmemInfo.mauWidth * secondDmemInfo.widthInMaus;
189 secondDmemAddrw_ = secondDmemInfo.portAddrw;
190 } else if (foundDmem) {
191 secondDmemDataw_ = 32;
193 }
194
195 if (secondPmem_) {
196 secondPmemName_ = secondPmemInfo.lsuName;
198 secondPmemInfo.mauWidth * secondDmemInfo.widthInMaus;
199 secondPmemAddrw_ = secondPmemInfo.portAddrw;
200 } else if (foundPmem) {
201 secondPmemDataw_ = 32;
203 }
204}
205
206void
208 const ProGe::NetlistBlock* progeBlockInOldNetlist) {
209
210 initPlatformNetlist(progeBlockInOldNetlist);
211 findMemories();
213 const NetlistBlock& cores = progeBlock();
214 int coreCount = 1;
215 for (int i = 0; i < coreCount; i++) {
216 int coreId = coreCount == 1 ? -1 : i;
217 if (!integrateCore(cores, coreId)) {
218 return;
219 }
220 }
221
223
226
229 }
230
232}
233
234/**
235 * Returns the AXI bus facing address width: 2 bits for address space select
236 * + maximum of the four address space widths (byte-addressed):
237 *
238 * - CTRL block (fixed 1024 bytes per core)
239 * - Instruction memory
240 * - Data and parameter memories
241 */
244 // IMEM address width
245 int imemAddressWidth = 0;
246 if (imemInfo().type != VHDL_ARRAY) {
247 imemAddressWidth =
249 (imemInfo().widthInMaus * imemInfo().mauWidth + 7) / 8 - 1) +
251 }
252 // Debugger address space:
253 int debugAddressWidth = 8;
254 int dmemAddressWidth =
257 std::max(0, dmemInfo_.mauWidth * dmemInfo_.widthInMaus / 8 - 1));
258
259 // Skip param if its width is set by a generic: if there is a larger
260 // memory (imem/dmem), the value will still be correct
261 int pmemAddressWidth = 0;
262 if (pmemInfo_.asAddrw != 32) {
263 pmemAddressWidth =
267 } else {
268 pmemAddressWidth = DEFAULT_LOCAL_MEMORY_WIDTH;
269 }
270 int axiAddressWidth = std::max(
271 std::max(imemAddressWidth, debugAddressWidth),
272 std::max(dmemAddressWidth, pmemAddressWidth));
273
275}
276
277void
279 ProGe::Netlist& netlist = integratorBlock()->netlist();
280 TCEString core_count = "1";
281
282 TCEString platformPath = Environment::dataDirPath("ProGe");
283 platformPath << FileSystem::DIRECTORY_SEPARATOR << "platform"
285
286 int imemdataw = imemInfo().mauWidth * imemInfo().widthInMaus;
287 int imemaddrw = imemInfo().portAddrw;
288 int imemAxiAddrw =
289 MathTools::requiredBits0Bit0((imemdataw + 31) / 32 - 1) + imemaddrw;
290 int bustrace_width = 0;
291
292 if (imem_dp_) {
293 imemdataw = MathTools::roundUpToPowerTwo(imemdataw);
294 }
295
296 for (int i = 0; i < machine()->busNavigator().count(); ++i) {
297 int bus_width = machine()->busNavigator().item(i)->width();
298 // Busess are padded to a multiple of 32 bits
299 bus_width = (bus_width + 31) / 32 * 32;
300 bustrace_width += bus_width;
301 }
302
305
306 netlist.setParameter("AXI_ADDR_WIDTH", "integer", axiAddressWidth());
308 "axi_addr_width_g", "integer", "AXI_ADDR_WIDTH");
309 netlist.setParameter("AXI_ID_WIDTH", "integer", "12");
311 "axi_id_width_g", "integer", "AXI_ID_WIDTH");
312 almaifBlock_->setParameter("core_count_g", "integer", core_count);
314 "axi_addr_width_g", "integer", "axi_addr_width_g");
315 almaifBlock_->setParameter("axi_id_width_g", "integer", "axi_id_width_g");
316
318 "imem_addr_width_g", "integer", Conversion::toString(imemaddrw));
319
321 "imem_axi_addr_width_g", "integer",
322 Conversion::toString(imemAxiAddrw));
323 if (imemInfo().type != VHDL_ARRAY) {
325 "imem_data_width_g", "integer", Conversion::toString(imemdataw));
326 } else {
327 almaifBlock_->setParameter("imem_data_width_g", "integer", "0");
328 }
329
331 "bus_count_g", "integer", Conversion::toString(bustrace_width / 32));
333 "local_mem_addrw_g", "integer", "local_mem_addrw_g");
334
335 // Add and connect clock and reset ports
336 NetlistPort* clk =
337 new NetlistPort("clk", "1", 1, ProGe::BIT, ProGe::IN, *almaifBlock_);
338 NetlistPort* rstx =
339 new NetlistPort("rstx", "1", 1, ProGe::BIT, ProGe::IN, *almaifBlock_);
340 netlist.connect(*clockPort(), *clk);
341 netlist.connect(*resetPort(), *rstx);
342
344 "second_dmem_data_width_g", "integer",
347 "second_dmem_addr_width_g", "integer",
349
350 if (secondDmem_) {
351 almaifBlock_->setParameter("enable_second_dmem_g", "integer", "1");
353 "second-dmem-port-declarations",
354 Path(platformPath + "second_dmem_port_declaration.snippet"));
355 } else {
356 almaifBlock_->setParameter("enable_second_dmem_g", "integer", "0");
358 "second-dmem-signal-declarations",
359 Path(platformPath + "second_dmem_signal_declaration.snippet"));
360 }
361
362 if (secondPmem_) {
363 almaifBlock_->setParameter("enable_second_pmem_g", "integer", "1");
365 "second-pmem-port-declarations",
366 Path(platformPath + "second_pmem_port_declaration.snippet"));
367 } else {
368 almaifBlock_->setParameter("enable_second_pmem_g", "integer", "0");
370 "second-pmem-signal-declarations",
371 Path(platformPath + "second_pmem_signal_declaration.snippet"));
372 }
373
375 "second_pmem_data_width_g", "integer",
377 if (pmemInfo_.asAddrw == 32) {
379 "second_pmem_addr_width_g", "integer", "local_mem_addrw_g");
380 } else {
382 "second_pmem_addr_width_g", "integer",
384 }
385
386 if (syncReset_) {
387 almaifBlock_->setParameter("sync_reset_g", "integer", "1");
388 } else {
389 almaifBlock_->setParameter("sync_reset_g", "integer", "0");
390 }
391
392 if (broadcast_pmem_) {
393 almaifBlock_->setParameter("broadcast_pmem_g", "integer", "1");
394
396 "pmem-bcast", Path(platformPath + "pmem_broadcast.snippet"));
397 } else {
398 almaifBlock_->setParameter("broadcast_pmem_g", "integer", "0");
399 }
400
401 // Add AXI4 slave interface to AlmaIF block and toplevel, and connect them
402 NetlistPortGroup* axislave_almaif = axiSlavePortGroup();
403 NetlistPortGroup* axislave_ext = axislave_almaif->clone();
404 almaifBlock_->addPortGroup(axislave_almaif);
405 integratorBlock()->addPortGroup(axislave_ext);
406 netlist.connectGroupByName(*axislave_almaif, *axislave_ext);
407
408 if (pmemInfo_.asAddrw == 32) {
409 assert(
410 broadcast_pmem_ == false &&
411 "Broadcasting pmem not supported with m_axi");
413 "local_mem_addrw_g", "integer",
415
417 "axi_offset_low_g", "integer", "1073741824");
418 integratorBlock()->setParameter("axi_offset_high_g", "integer", "0");
420 "axi_offset_low_g", "integer", "axi_offset_low_g");
422 "axi_offset_high_g", "integer", "axi_offset_high_g");
423
424 NetlistPortGroup* aximaster_almaif = axiMasterPortGroup();
425 NetlistPortGroup* aximaster_ext = aximaster_almaif->clone();
426 almaifBlock_->addPortGroup(aximaster_almaif);
427 integratorBlock()->addPortGroup(aximaster_ext);
428 netlist.connectGroupByName(*aximaster_almaif, *aximaster_ext);
429 } else {
431 "local_mem_addrw_g", "integer",
433 almaifBlock_->setParameter("axi_offset_low_g", "integer", "0");
435 "axi_offset_high_g", "integer", "0");
436 }
437
438 int coreCount = 1;
439 // Debug signals
440 if (!hasMinimalDebugger_) {
441 almaifBlock_->setParameter("full_debugger_g", "integer", "1");
443 "full-debugger-port-declarations",
444 Path(platformPath + "full_debugger_port_declaration.snippet"));
446 "debugger", Path(platformPath + "full_debugger.snippet"));
447
449 "core_db_pc_start", coreCount * imemaddrw, ProGe::OUT,
450 "db_pc_start");
452 "core_db_pc_next", coreCount * imemaddrw, ProGe::IN,
453 "db_pc_next");
455 "core_db_bustraces", coreCount * bustrace_width, ProGe::IN,
456 "db_bustraces");
457 } else {
458 almaifBlock_->setParameter("full_debugger_g", "integer", "0");
460 "mini-debugger-signal-declarations",
461 Path(platformPath + "mini_debugger_signal_declaration.snippet"));
463 "debugger", Path(platformPath + "mini_debugger.snippet"));
464 }
465
466 // Set the default value in case when there is no separate scratchpad memory.
467 // AlmaIF interface must reserve some part of the global buffer memory
468 // (pmem) and communicate that in the interface
471 "reserved_sp_bytes_g", "integer",
473 }
474
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");
485 if (dmem_dram_) {
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);");
491 // We want to disable dmem from tta-accel, because dmem exists in dram
493 "enable-dmem", "constant enable_dmem : boolean := false;");
494 } else {
495 // Dummy signal to connect to not leave minidebuggers portmap
496 // undefined
498 "dram-offset-dummy-declaration",
499 "signal core_db_dram_offset : std_logic_vector(32-1 downto 0);");
501 "enable-dmem",
502 "constant enable_dmem : boolean := dmem_data_width_g > 0;");
503 }
504
505 if (imemInfo().type != VHDL_ARRAY) {
506 // Ifetch signals
507 addPortToAlmaIFBlock("core_busy_out", coreCount, ProGe::OUT, "busy");
509 "core_imem_data_out", coreCount * imemdataw, ProGe::OUT,
510 "imem_data");
512 "core_imem_en_x_in", coreCount, ProGe::IN, "imem_en_x");
514 "core_imem_addr_in", coreCount * imemaddrw, ProGe::IN,
515 "imem_addr");
516
517 if (imem_dp_) {
518 const int strb_width = imemdataw / 8;
519 const int half_cores_ceil = (coreCount + 1) / 2;
520 // Dualport memories have identical a-b ports, except with odd
521 // corecounts the b is full and the a's msb-side is unconnected
523 "INSTR_a", half_cores_ceil, imemdataw * half_cores_ceil,
524 imemaddrw * half_cores_ceil, strb_width * half_cores_ceil,
525 false);
527 "INSTR_b", half_cores_ceil, imemdataw * half_cores_ceil,
528 imemaddrw * half_cores_ceil, strb_width * half_cores_ceil,
529 false);
530 } else {
531 addMemoryPorts("INSTR_a", imemdataw, imemaddrw, false, false);
532 addMemoryPorts("INSTR_b", 32, imemAxiAddrw, false, false);
533 }
534 TCEString platformPath = Environment::dataDirPath("ProGe");
535 platformPath << FileSystem::DIRECTORY_SEPARATOR << "platform"
537
539 "imem-statements",
540 Path(platformPath + "imem_statements.snippet"));
541 if (imem_dp_) {
543 "imem-bcast",
544 Path(platformPath + "imem_broadcast_dualport.snippet"));
546 "imem-port-declarations",
547 Path(
548 platformPath + "imem_port_declaration_dualport.snippet"));
549 } else {
551 "imem-bcast", Path(platformPath + "imem_broadcast.snippet"));
553 "imem-port-declarations",
554 Path(platformPath + "imem_port_declaration.snippet"));
555 }
556 }
557
558 connectCoreMemories(dmemInfo_, "dmem", "data", secondDmem_);
559 connectCoreMemories(pmemInfo_, "pmem", "param", secondPmem_);
560}
561
562void
564 MemInfo mem, TCEString mem_name, TCEString mem_block_name, bool seconds) {
566 mem_name + "_data_width_g", "integer",
569 mem_name + "_addr_width_g", "integer",
571
572 TCEString platformPath = Environment::dataDirPath("ProGe");
573 platformPath << FileSystem::DIRECTORY_SEPARATOR << "platform"
575
576 // If given memory wasn't found by findMemories(), we need dummy signals
577 // as a stand-in for the missing ports
578 if (mem.portAddrw == 0 || mem.type == DRAM) {
579 Path snippet(platformPath + mem_name + "_signal_declaration.snippet");
581 mem_name + "-signal-declarations", snippet);
582 return;
583 }
584
585 // Otherwise, instantiate the ports
586 if (mem_name == "pmem" && broadcast_pmem_) {
587 Path snippet(platformPath + "pmem_port_declaration_wide.snippet");
589 mem_name + "-port-declarations", snippet);
590 } else {
591 Path snippet(platformPath + mem_name + "_port_declaration.snippet");
593 mem_name + "-port-declarations", snippet);
594 }
595
596 TCEString lsu_prefix = "fu_" + mem.lsuName;
597
598 int coreCount = 1;
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,
607 ProGe::IN, lsu_prefix + "_aaddr_out");
609 "core_" + mem_name + "_awren_in", coreCount, ProGe::IN,
610 lsu_prefix + "_awren_out");
612 "core_" + mem_name + "_astrb_in",
613 (mem.mauWidth * mem.widthInMaus + 7) / 8 * coreCount, ProGe::IN,
614 lsu_prefix + "_astrb_out");
615
617 "core_" + mem_name + "_adata_in",
618 coreCount * mem.mauWidth * mem.widthInMaus, ProGe::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",
628 coreCount * mem.mauWidth * mem.widthInMaus, ProGe::OUT,
629 lsu_prefix + "_rdata_in");
630
631 if (seconds) {
632 int addrWidth, dataWidth;
633 if (mem.asName == DMEM_NAME) {
634 addrWidth = secondDmemAddrw_;
635 dataWidth = secondDmemDataw_;
636 lsu_prefix = "fu_" + secondDmemName_;
637 } else {
638 addrWidth = secondPmemAddrw_;
639 dataWidth = secondPmemDataw_;
640 lsu_prefix = "fu_" + secondPmemName_;
641 }
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,
650 ProGe::IN, lsu_prefix + "_aaddr_out");
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,
656 ProGe::IN, lsu_prefix + "_astrb_out");
657
659 "core_" + mem_name + "_2nd_adata_in", coreCount * dataWidth,
660 ProGe::IN, lsu_prefix + "_adata_out");
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,
669 ProGe::OUT, lsu_prefix + "_rdata_in");
670 }
671
673 mem_block_name + "_a", mem.mauWidth * mem.widthInMaus, mem.portAddrw,
674 mem.isShared, (mem.asAddrw == 32 && (mem.asName == PMEM_NAME)));
675 if (mem.asName == DMEM_NAME) {
677 mem_block_name + "_b", secondDmemDataw_, secondDmemAddrw_,
678 mem.isShared, false);
679 } else {
680 bool make_local_sized =
681 mem.asAddrw == 32 && (mem.asName == PMEM_NAME);
683 mem_block_name + "_b", secondPmemDataw_, secondPmemAddrw_,
684 mem.isShared, make_local_sized);
685 }
686}
687
688void
690 const TCEString name, const TCEString width, const ProGe::Direction dir,
691 const TCEString core_name) {
692 NetlistPort* port =
693 new NetlistPort(name, width, ProGe::BIT_VECTOR, dir, *almaifBlock_);
694 if (core_name != "") almaif_ttacore_ports[core_name] = port;
695}
696
697void
699 const TCEString name, const int width, const ProGe::Direction dir,
700 const TCEString core_name) {
701 NetlistPort* port = new NetlistPort(
702 name, Conversion::toString(width), width, ProGe::BIT_VECTOR, dir,
703 *almaifBlock_);
704 if (core_name != "") almaif_ttacore_ports[core_name] = port;
705}
706
707void
709 NetlistPortGroup* port_group, const ProGe::Direction dir,
710 const TCEString name, const TCEString width) {
712 if (width == "1") {
713 type = ProGe::BIT;
714 }
715 NetlistPort* port = new NetlistPort(name, width, type, dir);
716 port_group->addPort(*port);
717}
718
719/**
720 * Builds a representation of the AXI4 bus slave interface as a port group.
721 * Hardcoded signal widths for data (32b) and IDs (12b)
722 */
726
727 addPortToGroup(axiBus, ProGe::IN, "s_axi_awid", "axi_id_width_g");
728 addPortToGroup(axiBus, ProGe::IN, "s_axi_awaddr", "axi_addr_width_g");
729 addPortToGroup(axiBus, ProGe::IN, "s_axi_awlen", "8");
730 addPortToGroup(axiBus, ProGe::IN, "s_axi_awsize", "3");
731 addPortToGroup(axiBus, ProGe::IN, "s_axi_awburst", "2");
732 addPortToGroup(axiBus, ProGe::IN, "s_axi_awvalid", "1");
733 addPortToGroup(axiBus, ProGe::OUT, "s_axi_awready", "1");
734 addPortToGroup(axiBus, ProGe::IN, "s_axi_wdata", "32");
735 addPortToGroup(axiBus, ProGe::IN, "s_axi_wstrb", "4");
736 addPortToGroup(axiBus, ProGe::IN, "s_axi_wvalid", "1");
737 addPortToGroup(axiBus, ProGe::OUT, "s_axi_wready", "1");
738 addPortToGroup(axiBus, ProGe::OUT, "s_axi_bid", "axi_id_width_g");
739 addPortToGroup(axiBus, ProGe::OUT, "s_axi_bresp", "2");
740 addPortToGroup(axiBus, ProGe::OUT, "s_axi_bvalid", "1");
741 addPortToGroup(axiBus, ProGe::IN, "s_axi_bready", "1");
742 addPortToGroup(axiBus, ProGe::IN, "s_axi_arid", "axi_id_width_g");
743 addPortToGroup(axiBus, ProGe::IN, "s_axi_araddr", "axi_addr_width_g");
744 addPortToGroup(axiBus, ProGe::IN, "s_axi_arlen", "8");
745 addPortToGroup(axiBus, ProGe::IN, "s_axi_arsize", "3");
746 addPortToGroup(axiBus, ProGe::IN, "s_axi_arburst", "2");
747 addPortToGroup(axiBus, ProGe::IN, "s_axi_arvalid", "1");
748 addPortToGroup(axiBus, ProGe::OUT, "s_axi_arready", "1");
749 addPortToGroup(axiBus, ProGe::OUT, "s_axi_rid", "axi_id_width_g");
750 addPortToGroup(axiBus, ProGe::OUT, "s_axi_rdata", "32");
751 addPortToGroup(axiBus, ProGe::OUT, "s_axi_rresp", "2");
752 addPortToGroup(axiBus, ProGe::OUT, "s_axi_rlast", "1");
753 addPortToGroup(axiBus, ProGe::OUT, "s_axi_rvalid", "1");
754 addPortToGroup(axiBus, ProGe::IN, "s_axi_rready", "1");
755
756 return axiBus;
757}
758
759/**
760 * Builds a representation of the AXI4-Lite master interface as a port group.
761 */
765
766 addPortToGroup(axiBus, ProGe::OUT, "m_axi_awaddr", "32");
767 addPortToGroup(axiBus, ProGe::OUT, "m_axi_awvalid", "1");
768 addPortToGroup(axiBus, ProGe::IN, "m_axi_awready", "1");
769 addPortToGroup(axiBus, ProGe::OUT, "m_axi_awprot", "3");
770 addPortToGroup(axiBus, ProGe::OUT, "m_axi_wvalid", "1");
771 addPortToGroup(axiBus, ProGe::IN, "m_axi_wready", "1");
772 addPortToGroup(axiBus, ProGe::OUT, "m_axi_wdata", "32");
773 addPortToGroup(axiBus, ProGe::OUT, "m_axi_wstrb", "4");
774 addPortToGroup(axiBus, ProGe::IN, "m_axi_bvalid", "1");
775 addPortToGroup(axiBus, ProGe::OUT, "m_axi_bready", "1");
776 addPortToGroup(axiBus, ProGe::OUT, "m_axi_arvalid", "1");
777 addPortToGroup(axiBus, ProGe::IN, "m_axi_arready", "1");
778 addPortToGroup(axiBus, ProGe::OUT, "m_axi_araddr", "32");
779 addPortToGroup(axiBus, ProGe::OUT, "m_axi_arprot", "3");
780 addPortToGroup(axiBus, ProGe::IN, "m_axi_rdata", "32");
781 addPortToGroup(axiBus, ProGe::IN, "m_axi_rvalid", "1");
782 addPortToGroup(axiBus, ProGe::OUT, "m_axi_rready", "1");
783
784 return axiBus;
785}
786
787void
789 const TCEString prefix, int data_width, int addr_width,
790 const bool /* isShared */, const bool overrideAsWidth) {
791 int mem_count = 1;
792
793 data_width = data_width * mem_count;
794 addr_width = addr_width * mem_count;
795 // In case the data_width has been already multiplied by the mem_count,
796 // we have to undo the multiplication, so the rounding is done properly
797 // for the single memory version and only then multiplied by the
798 // mem_count.
799 int strb_width = (data_width / mem_count + 7) / 8 * mem_count;
800
802 prefix, mem_count, data_width, addr_width, strb_width,
803 overrideAsWidth);
804}
805
806void
808 const TCEString prefix, int mem_count, int data_width, int addr_width,
809 int strb_width, const bool overrideAsWidth) {
810 addPortToAlmaIFBlock(prefix + "_avalid_out", mem_count, ProGe::OUT);
811 addPortToAlmaIFBlock(prefix + "_aready_in", mem_count, ProGe::IN);
812 if (overrideAsWidth) {
814 prefix + "_aaddr_out", "local_mem_addrw_g", ProGe::OUT);
815 } else {
816 addPortToAlmaIFBlock(prefix + "_aaddr_out", addr_width, ProGe::OUT);
817 }
818 addPortToAlmaIFBlock(prefix + "_awren_out", mem_count, ProGe::OUT);
819 addPortToAlmaIFBlock(prefix + "_astrb_out", strb_width, ProGe::OUT);
820 addPortToAlmaIFBlock(prefix + "_adata_out", data_width, ProGe::OUT);
821 addPortToAlmaIFBlock(prefix + "_rvalid_in", mem_count, ProGe::IN);
822 addPortToAlmaIFBlock(prefix + "_rready_out", mem_count, ProGe::OUT);
823 addPortToAlmaIFBlock(prefix + "_rdata_in", data_width, ProGe::IN);
824}
825
826void
828 const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
829 std::vector<TCEString> almaifFiles;
830
831 TCEString basePath = Environment::dataDirPath("ProGe");
832 TCEString platformPath = basePath + DS + "platform" + DS;
833 TCEString dbPath = basePath + DS + "debugger" + DS;
834
835 TCEString outputPath = outputFilePath("tta-accel.vhdl", true);
836 if (pmemInfo_.asAddrw == 32) {
837 Path snippet(platformPath + "axi_master_port_declaration.snippet");
839 "m-axi-port-declarations", snippet);
840 } else {
841 Path snippet(platformPath + "axi_master_signal_declaration.snippet");
843 "m-axi-signal-declarations", snippet);
844 }
845
847 platformPath + "tta-accel.vhdl.tmpl", outputPath);
848 almaifFiles.push_back(outputPath);
849
850 copyPlatformFile(platformPath + "tta-axislave.vhdl", almaifFiles);
851 copyPlatformFile(platformPath + "almaif_decoder.vhdl", almaifFiles);
852 copyPlatformFile(platformPath + "almaif_axi_arbiter.vhdl", almaifFiles);
853 copyPlatformFile(platformPath + "almaif_mc_arbiter.vhdl", almaifFiles);
854 copyPlatformFile(platformPath + "almaif_axi_expander.vhdl", almaifFiles);
855 copyPlatformFile(platformPath + "membus_splitter.vhdl", almaifFiles);
856 copyPlatformFile(platformPath + "almaif_membus_delay.vhdl", almaifFiles);
857 copyPlatformFile(dbPath + "registers-pkg.vhdl", almaifFiles);
858
860 copyPlatformFile(dbPath + "minidebugger.vhdl", almaifFiles);
861 } else {
862 copyPlatformFile(dbPath + "dbregbank.vhdl", almaifFiles);
863 copyPlatformFile(dbPath + "dbsm-entity.vhdl", almaifFiles);
864 copyPlatformFile(dbPath + "dbsm-rtl.vhdl", almaifFiles);
865 copyPlatformFile(dbPath + "debugger.vhdl", almaifFiles);
866 }
867
868 // Copy synthesis scripts
869 TCEString scriptPath = basePath + DS + "synthesis" + DS;
872 "toplevel_entity", coreEntityName() + "_toplevel");
873 copyPlatformFile(scriptPath + "find_fmax.py", almaifFiles, true);
874 outputPath = progeFilePath("timing.tcl", true);
876 scriptPath + "timing.tcl.tmpl", outputPath);
877 outputPath = progeFilePath("utilization.tcl", true);
879 scriptPath + "utilization.tcl.tmpl", outputPath);
880
881 for (unsigned int i = 0; i < almaifFiles.size(); i++) {
882 projectFileGenerator()->addHdlFile(almaifFiles.at(i));
883 }
884}
885
886void
888 const TCEString inputPath, std::vector<TCEString>& fileList,
889 bool isScript) const {
891 if (isScript) {
893 } else {
895 }
896
897 FileSystem::copy(inputPath, outputPath);
898 fileList.push_back(outputPath);
899}
900
901bool
903 ProGe::Netlist& netlist = integratorBlock()->netlist();
904
907
908 if (!createMemories(coreId)) {
909 return false;
910 }
911
912 // Connect cycle count, stall count ports if needed by an FU
913 auto ttaCCPort = core.port("debug_cycle_count_in");
914 if (ttaCCPort) {
915 netlist.connect(*core.port("db_cyclecnt"), *ttaCCPort);
916 }
917 auto ttaLCPort = core.port("debug_lock_count_in");
918 if (ttaLCPort) {
919 netlist.connect(*core.port("db_lockcnt"), *ttaLCPort);
920 }
921 for (size_t i = 0; i < core.portCount(); ++i) {
922 TCEString portName = core.port(i).name();
923
924 // Connect global clock and reset ports
925 if (portName == PlatformIntegrator::TTA_CORE_CLK) {
926 netlist.connect(*clockPort(), core.port(i));
927 } else if (portName == PlatformIntegrator::TTA_CORE_RSTX) {
928 netlist.connect(*resetPort(), core.port(i));
929 } else {
930 // Strip coreN_ -prefix for multicore TTAs
931 if (portName.substr(0, 4) == "core") {
932 TCEString coreKey;
933 coreKey << "core" << coreId;
934 size_t cutoff = portName.find_first_of('_');
935 if (portName.substr(0, cutoff) != coreKey) {
936 // Port doesn't belong to core, skip
937 continue;
938 }
939 portName = portName.substr(cutoff + 1);
940 }
941 if (almaif_ttacore_ports.find(portName) !=
942 almaif_ttacore_ports.end()) {
943 int portWidth = almaif_ttacore_ports[portName]->realWidth();
944
945 // Connect AlmaIF block to TTA
946
947 if (coreId != -1 && imem_dp_ && portName == "imem_data") {
948 // imem_dp_ works with padded imem data signals. So here
949 // we connect only the real bits, but with padded
950 // differences.
951 netlist.connect(
952 core.port(i), *almaif_ttacore_ports[portName], 0,
953 portWidth * coreId, imemInfo().mauWidth);
954
955 } else if (coreId != -1) {
956 netlist.connect(
957 core.port(i), *almaif_ttacore_ports[portName], 0,
958 portWidth * coreId, portWidth);
959 } else {
960 netlist.connect(
961 core.port(i), *almaif_ttacore_ports[portName]);
962 }
963 } else if (
964 dmem_dram_ &&
965 portName ==
966 (boost::format("fu_%s_dram_offset") % dmemInfo_.lsuName)
967 .str()) {
968 netlist.connect(
969 core.port(i), *almaifBlock_->port("db_dram_offset"));
970 }
971 }
972 }
973
975 return true;
976}
977
978void
981
982 for (size_t i = 0; i < almaifBlock_->portCount(); i++) {
983 const NetlistPort& port = almaifBlock_->port(i);
984 if (!integratorBlock()->netlist().isPortConnected(port)) {
986 }
987 }
988}
989
992 assert(imem.type != UNKNOWN && "Imem type not set!");
993 int axiAddrWidth =
995 (imemInfo().widthInMaus * imemInfo().mauWidth + 31) / 32 - 1) +
997 if (imemGen_ == NULL) {
998 if (imem.type == ONCHIP) {
999 if (imem_dp_) {
1002 imem.widthInMaus, imem.portAddrw,
1004 imem.portAddrw, this, warningStream(), errorStream(),
1005 true, almaifBlock_, "INSTR", false, false);
1006 } else {
1008 imem.mauWidth, imem.widthInMaus, imem.portAddrw, 32,
1009 axiAddrWidth, this, warningStream(), errorStream(), true,
1010 almaifBlock_, "INSTR", false, false);
1011 }
1012 } else if (imem.type == VHDL_ARRAY) {
1014 imem.mauWidth, imem.widthInMaus, imem.portAddrw,
1015 programName() + "_imem_pkg.vhdl", this, warningStream(),
1016 errorStream());
1017 } else if (imem.type != NONE) {
1018 TCEString msg = "Unsupported instruction memory type";
1019 throw InvalidData(__FILE__, __LINE__, "AlmaIFIntegrator", msg);
1020 }
1021 }
1022 return *imemGen_;
1023}
1024
1027 MemInfo dmem, TTAMachine::FunctionUnit& lsuArch,
1028 std::vector<std::string> lsuPorts) {
1029 if (dmem.asName ==
1030 AXI_AS_NAME) { // AXI bus, export all ports to toplevel
1031 return *(new DummyMemGenerator(
1032 dmem.mauWidth, dmem.widthInMaus, dmem.portAddrw, this,
1034 }
1035
1036 bool genSingleRam = false;
1037 bool genDualPortRam = false;
1038 bool overrideAsWidth = false;
1039 bool isDmem = dmem.asName == DMEM_NAME;
1040 bool isPmem = dmem.asName == PMEM_NAME;
1041 bool isSecondInstance = false;
1042
1043 if (dmem.type == DRAM) { // AXI bus, export all ports to toplevel
1044 return *(new DummyMemGenerator(
1045 dmem.mauWidth, dmem.widthInMaus, dmem.portAddrw, this,
1047 }
1048
1049 int bDataWidth = 0;
1050 int bAddrWidth = 0;
1051
1052 if (isDmem || isPmem) {
1053 genDualPortRam = true;
1054 genSingleRam = dmem.isShared;
1055 if (isDmem) {
1056 if (dmemHandled_) {
1057 isSecondInstance = true;
1058 }
1059 dmem = dmemInfo_;
1060 bDataWidth = secondDmemDataw_;
1061 bAddrWidth = secondDmemAddrw_;
1062 dmemHandled_ = true;
1063 }
1064 if (isPmem) {
1065 if (pmemHandled_) {
1066 isSecondInstance = true;
1067 }
1068 dmem = pmemInfo_;
1069 bDataWidth = secondPmemDataw_;
1070 bAddrWidth = secondPmemAddrw_;
1071 pmemHandled_ = true;
1072 }
1073
1074 // TODO: Assumes 32b wide memory (32b address - 2 mask bits)
1075 // (the AXI-lite IF also assumes this)
1076 if (dmem.asName == PMEM_NAME && dmem.asAddrw == 32) {
1077 overrideAsWidth = true;
1078 }
1079 }
1080
1081 MemoryGenerator* memGen = NULL;
1082
1083 if ((isSecondInstance && dmem.isShared) || dmem.type == DRAM) {
1084 memGen = new DummyMemGenerator(
1085 dmem.mauWidth, dmem.widthInMaus, dmem.portAddrw, this,
1087 } else if (dmemGen_.find(dmem.asName) != dmemGen_.end()) {
1088 memGen = dmemGen_.find(dmem.asName)->second;
1089 } else {
1090 if (dmem.type == ONCHIP) {
1091 // onchip mem size is scalable, use value from adf's Address Space
1092 int addrw = dmem.portAddrw;
1093 memGen = new XilinxBlockRamGenerator(
1094 dmem.mauWidth, dmem.widthInMaus, addrw, bDataWidth,
1095 bAddrWidth, this, warningStream(), errorStream(),
1096 genDualPortRam, almaifBlock_, dmem.asName, overrideAsWidth,
1097 genSingleRam);
1098 } else {
1099 TCEString msg = "Unsupported data memory type";
1100 throw InvalidData(__FILE__, __LINE__, "AlmaIFIntegrator", msg);
1101 }
1102 memGen->addLsu(lsuArch, lsuPorts);
1103 dmemGen_[dmem.asName] = memGen;
1104 }
1105 return *memGen;
1106}
1107
1108void
1109AlmaIFIntegrator::printInfo(std::ostream& stream) const {
1110 stream
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'."
1116 << std::endl
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
1120 << std::endl;
1121}
1122
1123bool
1125 return true;
1126}
1127
1130
1131 return deviceFamily_;
1132}
1133
1134void
1136
1137 deviceFamily_ = devFamily;
1138}
1139
1140// these are not relevant here
1143 return "";
1144}
1145
1148 return "";
1149}
1150
1151int
1153 return 1;
1154}
1155
1158 return "";
1159}
1160
1165
1166void
1169
1171
1172 TCEString basePath = Environment::dataDirPath("ProGe");
1173 TCEString tbPath = basePath + DS + "tb" + DS + "almaif" + DS;
1174 TCEString outputPath = tbFilePath("almaif-tb.vhdl", true);
1175
1176 HDLTemplateInstantiator tbInstantiator(coreEntityName());
1177 if (pmemInfo_.asAddrw == 32) {
1178 tbInstantiator.replacePlaceholderFromFile(
1179 "m-axi-port-declarations",
1180 Path(tbPath + "almaif-tb-m-axi-port-declarations-snippet.vhdl"));
1181 tbInstantiator.replacePlaceholderFromFile(
1182 "m-axi-port-connections",
1183 Path(tbPath + "almaif-tb-m-axi-port-connections-snippet.vhdl"));
1184 tbInstantiator.replacePlaceholderFromFile(
1185 "m-axi-external-mem-instantiation",
1186 Path(
1187 tbPath +
1188 "almaif-tb-m-axi-external-mem-instantiation-snippet.vhdl"));
1189 FileSystem::copy(tbPath + "axi-mem.vhdl", tbFilePath("axi-mem.vhdl"));
1190 }
1191 tbInstantiator.instantiateTemplateFile(
1192 tbPath + "almaif-tb.vhdl.tmpl", outputPath);
1193}
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the false
#define DS
@ VHDL_ARRAY
@ ONCHIP
@ UNKNOWN
@ NONE
@ DRAM
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_
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
std::string secondDmemName_
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
static unsigned int roundUpToPowerTwo(unsigned int number)
static int requiredBits0Bit0(long unsigned int number)
void addLsu(TTAMachine::FunctionUnit &lsuArch, std::vector< std::string > lsuPorts)
ProGe::NetlistPort * resetPort() const
TCEString deviceName() const
virtual void initPlatformNetlist(const ProGe::NetlistBlock *progeBlock)
ProGe::NetlistPort * clockPort() const
virtual void exportUnconnectedPorts(int coreId)
const TTAMachine::Machine * machine() const
static const TCEString TTA_CORE_CLK
std::ostream & warningStream() const
virtual void connectToplevelPort(const ProGe::NetlistPort &corePort, const TCEString signalPrefix="")
const IDF::MachineImplementation * idf() const
TCEString tbFilePath(TCEString fileName, bool absolute=false) const
MemInfo readLsuParameters(const TTAMachine::FunctionUnit &lsu)
static const TCEString TTA_CORE_RSTX
TCEString programName() const
const MemInfo & imemInfo() const
std::ostream & errorStream() const
ProGe::NetlistBlock * integratorBlock()
const ProGe::NetlistBlock & progeBlock() const
virtual bool createMemories(int coreId)
TCEString progeFilePath(TCEString fileName, bool absolute=false) const
TCEString outputPath() const
virtual void writeNewToplevel()
TCEString outputFilePath(TCEString fileName, bool absolute=false) const
TCEString coreEntityName() const
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
std::string name() const
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition Netlist.cc:83
void setParameter(const std::string &name, const std::string &type, const std::string &value)
Definition Netlist.cc:362
bool connectGroupByName(const NetlistPortGroup &group1, const NetlistPortGroup &group2)
Definition Netlist.cc:238
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
Definition Machine.cc:380
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
DataType
Data types of hardware ports.
Definition ProGeTypes.hh:46
@ BIT
One bit.
Definition ProGeTypes.hh:47
@ BIT_VECTOR
Several bits.
Definition ProGeTypes.hh:48
Direction
Direction of the port.
Definition ProGeTypes.hh:52
@ OUT
Output port.
Definition ProGeTypes.hh:54
@ IN
Input port.
Definition ProGeTypes.hh:53
HDL
HDLs supported by ProGe.
Definition ProGeTypes.hh:40
MemType type
TCEString lsuName
TCEString asName