OpenASIP 2.2
Loading...
Searching...
No Matches
MemoryGenerator.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2010 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 MemoryGenerator.cc
26 *
27 * Implementation of MemoryGenerator class.
28 *
29 * @author Otto Esko 2010 (otto.esko-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <iostream>
34#include <map>
35#include "MemoryGenerator.hh"
36#include "PlatformIntegrator.hh"
37#include "NetlistBlock.hh"
39#include "NetlistPort.hh"
40#include "Exception.hh"
41#include "HDLPort.hh"
42#include "FileSystem.hh"
43#include "Environment.hh"
45#include "FUArchitecture.hh"
46#include "FUImplementation.hh"
47#include "FUExternalPort.hh"
48#include "FunctionUnit.hh"
49#include "InverterBlock.hh"
55
58
60 int mauWidth, int widthInMaus, int addrWidth, TCEString initFile,
61 const PlatformIntegrator* integrator, std::ostream& warningStream,
62 std::ostream& errorStream)
63 : mauWidth_(mauWidth),
64 widthInMaus_(widthInMaus),
65 addrWidth_(addrWidth),
66 initFile_(initFile),
67 integrator_(integrator),
68 warningStream_(warningStream),
69 errorStream_(errorStream),
70 lsuArch_(NULL),
71 lsuPorts_() {}
72
74
75 for (PortMap::iterator i = memPorts_.begin(); i != memPorts_.end(); i++) {
76 if (i->second != NULL)
77 delete i->second;
78 }
79}
80
81bool
83 const ProGe::NetlistBlock& ttaCore, int coreId,
84 std::vector<TCEString>& reasons) const {
85 for (std::string port : lsuPorts_) {
86 if (!checkFuPort(port, reasons)) {
87 return false;
88 }
89 }
90 bool foundAll = true;
91 PortMap::const_iterator iter = memPorts_.begin();
92 while (iter != memPorts_.end()) {
93 TCEString corePort = corePortName(iter->first, coreId);
94 if (ttaCore.port(corePort) == NULL) {
95 TCEString message = "Couldn't find port " + corePort +
96 " from toplevel";
97 reasons.push_back(message);
98 foundAll = false;
99 }
100 iter++;
101 }
102 return foundAll;
103}
104
105bool
107 const std::string fuPort, std::vector<TCEString>& reasons) const {
108 PortMap::const_iterator iter = memPorts_.find(fuPort);
109 if (iter == memPorts_.end()) {
110 TCEString msg;
111 msg << "MemoryGenerator does not have port " << fuPort;
112 reasons.push_back(msg);
113 return false;
114 }
115 return true;
116}
117
118void
120 const ProGe::NetlistBlock& ttaCore, ProGe::NetlistBlock& integratorBlock,
121 int memIndex, int coreId) {
122 BlockPair blocks =
123 createMemoryNetlistBlock(integratorBlock, memIndex, coreId);
124 NetlistBlock* mem = blocks.first;
125 VirtualNetlistBlock* virt = blocks.second;
126 assert(mem != NULL);
127 assert(virt != NULL);
128 if (virt->portCount() > 0) {
129 integratorBlock.addSubBlock(virt);
130 }
131
132 for (int i = 0; i < portCount(); i++) {
133 const HDLPort* hdlPort = port(i);
134 NetlistPort* memPort = mem->port(hdlPort->name());
135 if (memPort == NULL) {
136 memPort = virt->port(hdlPort->name());
137 if (memPort == NULL) {
138 TCEString msg = "Port ";
139 msg << hdlPort->name() << " not found from netlist block";
140 throw InvalidData(__FILE__, __LINE__, "MemoryGenerator", msg);
141 }
142 }
143
144 TCEString portName = corePortName(portKeyName(hdlPort), coreId);
145 const NetlistPort* corePort = NULL;
146 // clock and reset must be connected to new toplevel ports
147 if (portName == platformIntegrator()->clockPort()->name()) {
148 corePort = platformIntegrator()->clockPort();
149 } else if (portName == platformIntegrator()->resetPort()->name()) {
150 corePort = platformIntegrator()->resetPort();
151 } else {
152 corePort = ttaCore.port(portName);
153 }
154 assert(corePort != NULL);
155
157 integratorBlock, *memPort, *corePort, hdlPort->needsInversion(),
158 coreId);
159 }
160}
161
164 ProGe::NetlistBlock& integratorBlock, int memIndex, int coreId) {
165 VirtualNetlistBlock* staticConnectionsBlock = new VirtualNetlistBlock(
166 moduleName() + "_virt", instanceName(coreId, memIndex) + "_virt");
167
168 NetlistBlock* mem =
169 new NetlistBlock(moduleName(), instanceName(coreId, memIndex));
170 integratorBlock.addSubBlock(mem);
171
172 for (int i = 0; i < parameterCount(); i++) {
173 mem->setParameter(parameter(i));
174 }
175 for (int i = 0; i < portCount(); i++) {
176 const HDLPort* hdlPort = port(i);
177 NetlistPort* memPort = NULL;
178 if (hdlPort->hasStaticValue()) {
179 memPort = hdlPort->convertToNetlistPort(*staticConnectionsBlock);
180 } else {
181 memPort = hdlPort->convertToNetlistPort(*mem);
182 }
183 assert(memPort != NULL);
184 }
185
186 BlockPair blocks;
187 blocks.first = mem;
188 blocks.second = staticConnectionsBlock;
189 return blocks;
190}
191
192int
197
198int
200
201 return mauWidth_;
202}
203
204int
209
210
211int
213
214 return addrWidth_;
215}
216
217
220
221 return initFile_;
222}
223
229
230std::ostream&
235
236std::ostream&
241
242int
244
245 return memPorts_.size();
246}
247
248const HDLPort*
249MemoryGenerator::port(int index) const {
250
251 if (index > static_cast<int>(memPorts_.size())) {
252 TCEString message = "Index out of range";
253 throw OutOfRange(__FILE__, __LINE__, "MemoryGenerator", message);
254 }
255 PortMap::const_iterator iter = memPorts_.begin();
256 for (int i = 0; i < index; i++) {
257 iter++;
258 }
259 return iter->second;
260}
261
262
263const HDLPort*
265
266 if (memPorts_.find(name) == memPorts_.end()) {
267 TCEString message = "Port " + name + " not found";
268 throw KeyNotFound(__FILE__, __LINE__, "MemoryGenerator", message);
269 }
270 return memPorts_.find(name)->second;
271}
272
273
276
277 TCEString name = "";
278 PortMap::const_iterator iter = memPorts_.begin();
279 while (iter != memPorts_.end()) {
280 if (iter->second == port) {
281 name = iter->first;
282 break;
283 }
284 iter++;
285 }
286 if (name.empty()) {
287 TCEString message = "Key for port " + port->name() + " not found";
288 throw KeyNotFound(__FILE__, __LINE__, "MemoryGenerator", message);
289 }
290 return name;
291}
292
293void
295
296 assert(port != NULL);
297 memPorts_.insert(std::pair<TCEString, HDLPort*>(name, port));
298}
299
300
301int
303
304 return params_.size();
305}
306
307const ProGe::Parameter&
309 return params_.at(index);
310}
311
312void
314 ProGe::Parameter toAdd(add.name(), add.type(), add.value());
315 params_.push_back(toAdd);
316}
317
323
326
327 TCEString path = Environment::dataDirPath("ProGe");
328 path << FileSystem::DIRECTORY_SEPARATOR << "platform";
329 return path;
330}
331
332void
334 const TCEString& inFile,
335 const TCEString& outFile,
336 const TCEString& entity) const {
337
339 inst.setEntityString(entity);
340 inst.instantiateTemplateFile(inFile, outFile);
341}
342
343bool
345 return lsuArch_ != NULL;
346}
347
350
351 assert(lsuArch_ != NULL);
352 return *lsuArch_;
353}
354
357 const TCEString& portBaseName, int coreId) const {
358 // clock and reset port names are global
359 if (portBaseName == integrator_->clockPort()->name() ||
360 portBaseName == integrator_->resetPort()->name()) {
361 return portBaseName;
362 }
363
364 TCEString portName;
365 if (coreId >= 0) {
366 portName << "core" << coreId << "_";
367 }
368 if (lsuArch_ != NULL) {
369 portName << "fu_" << lsuArchitecture().name() << "_";
370 }
371 portName << portBaseName;
372 return portName;
373}
374
375void
377 TTAMachine::FunctionUnit& lsuArch, std::vector<std::string> lsuPorts) {
378 lsuArch_ = &lsuArch;
379 lsuPorts_ = lsuPorts;
380}
381
383MemoryGenerator::memoryIndexString(int coreId, int memIndex) const {
384 TCEString index;
385 if (coreId >= 0) {
386 index << coreId << "_";
387 }
388 return index << memIndex;
389}
390
391void
393 ProGe::NetlistBlock& netlistBlock, const ProGe::NetlistPort& memPort,
394 const ProGe::NetlistPort& corePort, bool inverted, int /*coreId*/) {
395 if (inverted) {
396 ProGe::InverterBlock* InvertedBlock =
397 new ProGe::InverterBlock(corePort, memPort);
398 netlistBlock.addSubBlock(InvertedBlock);
399
400 netlistBlock.netlist().connect(
401 corePort, InvertedBlock->inputPort(), 0, 0, 1);
402 netlistBlock.netlist().connect(
403 InvertedBlock->outputPort(), memPort, 0, 0, 1);
404
405 } else {
406 if (memPort.dataType() == corePort.dataType()) {
407 netlistBlock.netlist().connect(memPort, corePort);
408 } else {
409 // bit to bit vector connection, connect lowest bits
410 netlistBlock.netlist().connect(memPort, corePort, 0, 0, 1);
411 }
412 }
413}
#define assert(condition)
static std::string dataDirPath(const std::string &prog)
static const std::string DIRECTORY_SEPARATOR
bool hasStaticValue() const
Definition HDLPort.cc:153
ProGe::NetlistPort * convertToNetlistPort(ProGe::NetlistBlock &block) const
Definition HDLPort.cc:127
TCEString name() const
Definition HDLPort.cc:87
bool needsInversion() const
Definition HDLPort.cc:122
void instantiateTemplateFile(const std::string &templateFile, const std::string &dstFile)
void setEntityString(const TCEString &entityStr)
TCEString memoryIndexString(int coreId, int memIndex) const
int memoryWidthInMaus() const
TCEString initializationFile() const
const HDLPort * portByKeyName(TCEString name) const
const TTAMachine::FunctionUnit & lsuArchitecture() const
TCEString portKeyName(const HDLPort *port) const
static const TCEString RESET_PORT
MemoryGenerator(int memMauWidth, int widthInMaus, int addrWidth, TCEString initFile, const PlatformIntegrator *integrator, std::ostream &warningStream, std::ostream &errorStream)
TTAMachine::FunctionUnit * lsuArch_
static const TCEString CLOCK_PORT
ParameterList params_
const ProGe::Parameter & parameter(int index) const
std::ostream & warningStream()
void addLsu(TTAMachine::FunctionUnit &lsuArch, std::vector< std::string > lsuPorts)
virtual TCEString instanceName(int coreId, int memIndex) const =0
virtual TCEString moduleName() const =0
const PlatformIntegrator * platformIntegrator() const
const HDLPort * port(int index) const
virtual bool checkFuPort(const std::string fuPort, std::vector< TCEString > &reasons) const
void addParameter(const ProGe::Parameter &add)
std::pair< ProGe::NetlistBlock *, ProGe::VirtualNetlistBlock * > BlockPair
void addPort(const TCEString &name, HDLPort *port)
std::ostream & errorStream_
int memoryTotalWidth() const
virtual void addMemory(const ProGe::NetlistBlock &ttaCore, ProGe::NetlistBlock &integratorBlock, int memIndex, int coreId)
std::vector< std::string > lsuPorts_
bool hasLSUArchitecture() const
const PlatformIntegrator * integrator_
int parameterCount() const
std::ostream & warningStream_
std::ostream & errorStream()
virtual bool isCompatible(const ProGe::NetlistBlock &ttaCore, int coreId, std::vector< TCEString > &reasons) const
int memoryAddrWidth() const
virtual void connectPorts(ProGe::NetlistBlock &netlistBlock, const ProGe::NetlistPort &memPort, const ProGe::NetlistPort &corePort, bool inverted, int coreId)
virtual ~MemoryGenerator()
int memoryMauSize() const
TCEString corePortName(const TCEString &portBaseName, int coreId) const
TCEString templatePath() const
int portCount() const
void instantiateTemplate(const TCEString &inFile, const TCEString &outFile, const TCEString &entity) const
virtual MemoryGenerator::BlockPair createMemoryNetlistBlock(ProGe::NetlistBlock &integratorBlock, int memIndex, int coreId)
TCEString ttaCoreName() const
ProGe::NetlistPort * resetPort() const
ProGe::NetlistPort * clockPort() const
TCEString coreEntityName() const
const NetlistPort & outputPort() const
const NetlistPort & inputPort() const
void addSubBlock(BaseNetlistBlock *subBlock, const std::string &instanceName="")
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
virtual const Netlist & netlist() const
DataType dataType() const
std::string name() const
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition Netlist.cc:83
const TCEString & value() const
Definition Parameter.cc:143
const TCEString & type() const
Definition Parameter.cc:138
const TCEString & name() const
Definition Parameter.cc:133
virtual TCEString name() const