OpenASIP  2.0
LoopBufferBlock.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 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 LoopBufferBlock.cc
26  *
27  * Implementation of LoopBufferBlock class.
28  *
29  * Created on: 3.12.2015
30  * @author Henry Linjam�ki 2015 (henry.linjamaki-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
34 #include "LoopBufferBlock.hh"
35 
36 #include "NetlistFactories.hh"
37 #include "Netlist.hh"
38 #include "NetlistPort.hh"
39 #include "NetlistPortGroup.hh"
40 
41 #include "MachineInfo.hh"
42 
44 #include "FileSystem.hh"
45 
46 namespace ProGe {
47 
48 /**
49  * Constructs the loop buffer block that automatically selects suitable
50  * implementation.
51  *
52  * The constructor inspects operations in the CU of the machine and selects
53  * an appropriate loop buffer implementation.
54  *
55  * @exception NotAvailable If the CU does not include an operation, which
56  * utilizes the loop buffer.
57  */
59  const ProGeContext& context, BaseNetlistBlock* parent)
60 
61  : BaseNetlistBlock("not_set_yet", "loopbuffer", parent) {
63  cuOps = MachineInfo::getOpset(*context.adf().controlUnit());
64 
65  if (!cuOps.count("hwloop") && !cuOps.count("lbufs") &&
66  !cuOps.count("infloop")) {
69  "Could not recognize any loop buffer "
70  "utilizing operations in CU");
71  } else if (cuOps.count("hwloop") && cuOps.count("lbufs")) {
74  "Can not support hwloop and lbufs "
75  "operation combination.");
76  } else if (cuOps.count("lbufs") && cuOps.count("infloop")) {
79  "Can not support lbufs and infloop "
80  "operation combination.");
81  }
82 
83  entityStr_ = context.coreEntityName();
84 
85  // Common block construction //
86  setParameter(Parameter("depth", "integer", ""));
87  setParameter(Parameter("instw", "integer", ""));
88  setParameter(Parameter("core_id", "integer", "0"));
89  setParameter(Parameter("enable_usage_trace", "boolean", "false"));
90 
93 
94  lockReqPortIn_ = addPort(new InBitPort("lock_req_in"));
95  lockReqPortOut_ = addPort(new OutBitPort("lock_req_out"));
96  lockPortIn_ = addPort(new InBitPort("glock_in"));
97  lockPortOut_ = addPort(new OutBitPort("glock_out"));
98  // note: port widths "IMEMWIDTHINMAUS*IMEMMAUWIDTH", "LBUFMAXDEPTH" and
99  // "LBUFMAXITER" are temporary solutions for instancing blocks. The actual
100  // port width formulas use generics.
102  addPort(new InPort("fetchblock_in", "IMEMWIDTHINMAUS*IMEMMAUWIDTH"));
104  addPort(new OutPort("dispatch_out", "IMEMWIDTHINMAUS*IMEMMAUWIDTH"));
105  startPortIn_ = addPort(new InBitPort("loop_start_in"));
106 
107  if (cuOps.count("hwloop")) {
109  addPort(new InPort("loop_len_in", "IMEMADDRWIDTH"));
110  } else {
112  addPort(new InPort("loop_len_in", "bit_width(LBUFMAXDEPTH+1)"));
113  }
114 
115  // Ports used with HWLOOP
116  if (cuOps.count("hwloop")) {
118  addPort(new OutPort("len_cntr_out", "IMEMADDRWIDTH"));
119  loopFromImemPortOut_ = addPort(new OutBitPort("loop_from_imem_out"));
120  }
121 
122  // Variated block construction //
123  // note: assuming here that only one operation in CU utilizes loop buffer.
124  if (cuOps.count("hwloop")) {
125  if (cuOps.count("lbufc")) {
127  NotAvailable,
128  "BREAK-operation is not currently "
129  "available with HWLOOP operation.");
130  }
131  setModuleName(context.coreEntityName() + "_hwloop");
132  addParameter(Parameter("iterw", "integer", ""));
134  addPort(new InPort("loop_iter_in", "LBUFMAXITER"));
135  implmenetationFile_ = "hwloop";
136  } else if (cuOps.count("lbufs")) {
137  if (cuOps.count("lbufc")) {
139  NotAvailable,
140  "BREAK-operation is not currently "
141  "available with LBUFS operation.");
142  }
143  setModuleName(context.coreEntityName() + "_loopbuf");
144  addParameter(Parameter("iterw", "integer", ""));
146  addPort(new InPort("loop_iter_in", "LBUFMAXITER"));
147  implmenetationFile_ = "loopbuffer";
148  } else if (cuOps.count("infloop")) {
149  if (cuOps.count("lbufc")) {
150  stopPortIn_ = addPort(new InBitPort("loop_stop_in"));
151  }
152  setModuleName(context.coreEntityName() + "_inflooper");
153  implmenetationFile_ = "inflooper";
154  } else {
155  assert(false);
156  }
157 }
158 
160  // Managed by BaseNetlistBlock
161 }
162 
163 /**
164  * Sets the width of the blocks (i.e. instructions).
165  */
166 void
167 LoopBufferBlock::setBlockWidthParameter(const std::string value) {
168  setParameter(Parameter("instw", "integer", value));
169 }
170 
171 /**
172  * Sets the depth of the loop buffer.
173  *
174  * The depth is the number of blocks that can be stored in the buffer at most.
175  *
176  */
177 void
178 LoopBufferBlock::setBufferSizeParameter(const std::string value) {
179  setParameter(Parameter("depth", "integer", value));
180 }
181 
182 /**
183  * Sets the width of control port for iteration count if applicable.
184  *
185  * The maximum amount of iterations via the port is 2^n-1, where n is the
186  * port width.
187  *
188  */
189 void
191  // Constructor creates the parameter when needed.
192  if (hasParameter("iterw")) {
193  setParameter(Parameter("iterw", "integer", value));
194  }
195 }
196 
197 /**
198  * Sets core id for usage tracing.
199  *
200  * By default the core id is set to "0".
201  */
202 void
203 LoopBufferBlock::setCoreIdParameter(const std::string value) {
204  setParameter(Parameter("core_id", "integer", value));
205 }
206 
207 /**
208  * Sets usage tracing.
209  *
210  * By default the trace is disabled (set to false).
211  *
212  * When enabled the instance dumps the usage trace into a file
213  * (core<core_id>_l0_access_trace.dump) in RTL-simulation.
214  *
215  */
216 void
218  setParameter(
219  Parameter("enable_usage_trace", "boolean", value ? "true" : "false"));
220 }
221 
222 /**
223  * Returns (global) lock request input port.
224  *
225  */
226 const NetlistPort&
228  assert(lockReqPortIn_ != nullptr && "Unset port.");
229  return *lockReqPortIn_;
230 }
231 
232 /**
233  * Returns (global) lock request output port.
234  */
235 const NetlistPort&
237  assert(lockReqPortOut_ != nullptr && "Unset port.");
238  return *lockReqPortOut_;
239 }
240 
241 /**
242  * Returns (global) lock input port.
243  */
244 const NetlistPort&
246  assert(lockPortIn_ != nullptr && "Unset port.");
247  return *lockPortIn_;
248 }
249 
250 /**
251  * Returns (global) lock output port.
252  */
253 const NetlistPort&
255  assert(lockPortOut_ != nullptr && "Unset port.");
256  return *lockPortOut_;
257 }
258 
259 /**
260  * Returns input port for instruction word.
261  */
262 const NetlistPort&
264  assert(instructionPortIn_ != nullptr && "Unset port.");
265  return *instructionPortIn_;
266 }
267 
268 /**
269  * Returns output port for instruction word.
270  */
271 const NetlistPort&
273  assert(instructionPortOut_ != nullptr && "Unset port.");
274  return *instructionPortOut_;
275 }
276 
277 /**
278  * Returns control port for starting loop buffer.
279  */
280 const NetlistPort&
282  assert(startPortIn_ != nullptr && "Unset port.");
283  return *startPortIn_;
284 }
285 
286 /**
287  * Returns port that is used to stop looping.
288  *
289  @return The stop looping control port, if applicable.
290  * Otherwise, returns nullptr denoting unavailability of the port.
291  */
292 const NetlistPort*
294  return stopPortIn_;
295 }
296 
297 /**
298  * Returns control port for setting loop body size.
299  */
300 const NetlistPort&
302  assert(loopBodySizePortIn_ != nullptr && "Unset port.");
303  return *loopBodySizePortIn_;
304 }
305 
306 /**
307  * Returns control port for setting iteration count.
308  *
309  * @return The control port for setting iteration count, if applicable.
310  * Otherwise, returns nullptr denoting unavailability of the port.
311  */
312 const NetlistPort*
314  return loopIterationPortIn_;
315 }
316 
317 /**
318  * Returns control port for outputting current loop instruction index.
319  */
320 const NetlistPort&
322  assert(lenCntrPortOut_ != nullptr && "Unset port.");
323  return *lenCntrPortOut_;
324 }
325 
326 /**
327  * Returns control port for indicating that loop is executed
328  * from outside of loopbuffer module.
329  */
330 const NetlistPort&
332  assert(loopFromImemPortOut_ != nullptr && "Unset port.");
333  return *loopFromImemPortOut_;
334 }
335 
336 void
337 LoopBufferBlock::write(const Path& targetBaseDir, HDL targetLang) const {
338  if (targetLang != HDL::VHDL) {
339  THROW_EXCEPTION(NotAvailable, "Unsupported HDL language.");
340  }
341  assert(moduleName() != "not_set_yet");
342 
343  std::string target = targetBaseDir.string() +
346 
347  bool usesLoopBreaking = stopPortIn() != nullptr;
348 
349  Path progeDataDir(Environment::dataDirPath("ProGe"));
350  HDLTemplateInstantiator instantiator(entityStr_);
351 
352  if (usesLoopBreaking) {
353  instantiator.replacePlaceholder(
354  "port-declarations",
355  "-- Stops looping\n"
356  "loop_stop_in : in std_logic;");
357  instantiator.replacePlaceholderFromFile(
358  "fsm-logic",
359  progeDataDir / "inflooper_fsm_with_stopping.snippet");
360  instantiator.replacePlaceholderFromFile(
361  "signal-declarations",
362  progeDataDir / "inflooper_stop_signals.snippet");
363  instantiator.replacePlaceholderFromFile(
364  "stop-reg", progeDataDir / "inflooper_stop_register.snippet");
365  } else {
366  instantiator.replacePlaceholderFromFile(
367  "fsm-logic", progeDataDir / "inflooper_fsm_default.snippet");
368  }
369 
370  instantiator.instantiateTemplateFile(
371  (progeDataDir / (implmenetationFile_ + ".vhdl.tmpl")).string(),
372  target + implmenetationFile_ + ".vhdl");
373 }
374 
375 } /* namespace ProGe */
ProGe::BaseNetlistBlock::setModuleName
void setModuleName(const std::string &name)
Definition: BaseNetlistBlock.cc:392
ProGe::LoopBufferBlock::lockReqPortIn_
NetlistPort * lockReqPortIn_
Definition: LoopBufferBlock.hh:82
ProGe::BaseNetlistBlock::addPort
NetlistPort * addPort(NetlistPort *port)
Definition: BaseNetlistBlock.cc:467
ProGe::LoopBufferBlock::entityStr_
std::string entityStr_
Definition: LoopBufferBlock.hh:96
ProGe::BaseNetlistBlock
Definition: BaseNetlistBlock.hh:59
Netlist.hh
Path
Definition: FileSystem.hh:197
FileSystem.hh
NetlistFactories.hh
ProGe::LoopBufferBlock::lenCntrPortOut
const NetlistPort & lenCntrPortOut() const
Definition: LoopBufferBlock.cc:321
ProGe::LoopBufferBlock::lockReqPortOut
const NetlistPort & lockReqPortOut() const
Definition: LoopBufferBlock.cc:236
HDLTemplateInstantiator
Definition: HDLTemplateInstantiator.hh:45
ProGe::LoopBufferBlock::stopPortIn_
NetlistPort * stopPortIn_
Definition: LoopBufferBlock.hh:89
ProGe::ProGeContext::adf
const TTAMachine::Machine & adf() const
Definition: ProGeContext.cc:57
ProGe::PortFactory::resetPort
static NetlistPort * resetPort(Direction direction=IN)
Definition: NetlistFactories.cc:209
ProGe::BaseNetlistBlock::setParameter
void setParameter(const Parameter &param)
Definition: BaseNetlistBlock.cc:532
ProGe::OutBitPort
Convenience class for output bit ports.
Definition: NetlistPort.hh:181
ProGe::BaseNetlistBlock::addParameter
void addParameter(const Parameter &param)
Definition: BaseNetlistBlock.cc:547
MachineInfo.hh
HDLTemplateInstantiator.hh
ProGe::LoopBufferBlock::loopFromImemPortOut
const NetlistPort & loopFromImemPortOut() const
Definition: LoopBufferBlock.cc:331
ProGe::LoopBufferBlock::setBufferSizeParameter
void setBufferSizeParameter(const std::string value)
Definition: LoopBufferBlock.cc:178
ProGe::LoopBufferBlock::setCoreIdParameter
void setCoreIdParameter(const std::string value)
Definition: LoopBufferBlock.cc:203
ProGe::BaseNetlistBlock::Parameter
friend class Parameter
Definition: BaseNetlistBlock.hh:63
ProGe::LoopBufferBlock::loopIterationPortIn_
NetlistPort * loopIterationPortIn_
Definition: LoopBufferBlock.hh:91
ProGe::LoopBufferBlock::instructionPortIn_
NetlistPort * instructionPortIn_
Definition: LoopBufferBlock.hh:86
NotAvailable
Definition: Exception.hh:728
HDLTemplateInstantiator::replacePlaceholderFromFile
void replacePlaceholderFromFile(const std::string &key, const Path &filePath, bool append=false)
Definition: HDLTemplateInstantiator.cc:89
ProGe::LoopBufferBlock::lockPortOut_
NetlistPort * lockPortOut_
Definition: LoopBufferBlock.hh:85
ProGe::LoopBufferBlock::instructionPortOut
const NetlistPort & instructionPortOut() const
Definition: LoopBufferBlock.cc:272
ProGe::LoopBufferBlock::instructionPortIn
const NetlistPort & instructionPortIn() const
Definition: LoopBufferBlock.cc:263
ProGe::LoopBufferBlock::loopIterationPortIn
const NetlistPort * loopIterationPortIn() const
Definition: LoopBufferBlock.cc:313
NetlistPortGroup.hh
assert
#define assert(condition)
Definition: Application.hh:86
ProGe::LoopBufferBlock::startPortIn_
NetlistPort * startPortIn_
Definition: LoopBufferBlock.hh:88
ProGe::LoopBufferBlock::loopBodySizePortIn_
NetlistPort * loopBodySizePortIn_
Definition: LoopBufferBlock.hh:90
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
ProGe::VHDL
@ VHDL
VHDL.
Definition: ProGeTypes.hh:41
LoopBufferBlock.hh
ProGe::InPort
Convenience class for input ports.
Definition: NetlistPort.hh:193
ProGe::BaseNetlistBlock::hasParameter
virtual bool hasParameter(const std::string &name) const
Definition: BaseNetlistBlock.cc:183
ProGe::LoopBufferBlock::LoopBufferBlock
LoopBufferBlock()=delete
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
ProGe::LoopBufferBlock::lockPortOut
const NetlistPort & lockPortOut() const
Definition: LoopBufferBlock.cc:254
NetlistPort.hh
ProGe::LoopBufferBlock::lockReqPortOut_
NetlistPort * lockReqPortOut_
Definition: LoopBufferBlock.hh:83
ProGe::LoopBufferBlock::lockPortIn
const NetlistPort & lockPortIn() const
Definition: LoopBufferBlock.cc:245
ProGe::LoopBufferBlock::setUsageTracingParameter
void setUsageTracingParameter(bool setting)
Definition: LoopBufferBlock.cc:217
MachineInfo::getOpset
static OperationSet getOpset(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:65
ProGe::LoopBufferBlock::lenCntrPortOut_
NetlistPort * lenCntrPortOut_
Definition: LoopBufferBlock.hh:92
ProGe::LoopBufferBlock::lockReqPortIn
const NetlistPort & lockReqPortIn() const
Definition: LoopBufferBlock.cc:227
ProGe::LoopBufferBlock::loopBodySizePortIn
const NetlistPort & loopBodySizePortIn() const
Definition: LoopBufferBlock.cc:301
ProGe::LoopBufferBlock::loopFromImemPortOut_
NetlistPort * loopFromImemPortOut_
Definition: LoopBufferBlock.hh:93
ProGe::ProGeContext::coreEntityName
const std::string & coreEntityName() const
Definition: ProGeContext.cc:77
ProGe::LoopBufferBlock::lockPortIn_
NetlistPort * lockPortIn_
Definition: LoopBufferBlock.hh:84
ProGe::LoopBufferBlock::stopPortIn
const NetlistPort * stopPortIn() const
Definition: LoopBufferBlock.cc:293
ProGe::LoopBufferBlock::setIterationPortWidthParameter
void setIterationPortWidthParameter(const std::string value)
Definition: LoopBufferBlock.cc:190
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
ProGe::PortFactory::clockPort
static NetlistPort * clockPort(Direction direction=IN)
Definition: NetlistFactories.cc:200
ProGe::LoopBufferBlock::~LoopBufferBlock
virtual ~LoopBufferBlock()
Definition: LoopBufferBlock.cc:159
HDLTemplateInstantiator::replacePlaceholder
void replacePlaceholder(const std::string &key, const std::string &replacer, bool append=false)
Definition: HDLTemplateInstantiator.cc:62
MachineInfo::OperationSet
TCETools::CIStringSet OperationSet
Definition: MachineInfo.hh:60
ProGe::LoopBufferBlock::implmenetationFile_
std::string implmenetationFile_
Definition: LoopBufferBlock.hh:95
ProGe
Definition: FUGen.hh:54
ProGe::LoopBufferBlock::instructionPortOut_
NetlistPort * instructionPortOut_
Definition: LoopBufferBlock.hh:87
ProGe::HDL
HDL
HDLs supported by ProGe.
Definition: ProGeTypes.hh:40
ProGe::NetlistPort
Definition: NetlistPort.hh:70
ProGe::BaseNetlistBlock::moduleName
const std::string & moduleName() const
Definition: BaseNetlistBlock.cc:140
HDLTemplateInstantiator::instantiateTemplateFile
void instantiateTemplateFile(const std::string &templateFile, const std::string &dstFile)
Definition: HDLTemplateInstantiator.cc:113
ProGe::ProGeContext
Definition: ProGeContext.hh:60
ProGe::NetlistPort::rename
void rename(const std::string &newname)
Definition: NetlistPort.cc:294
ProGe::LoopBufferBlock::setBlockWidthParameter
void setBlockWidthParameter(const std::string value)
Definition: LoopBufferBlock.cc:167
ProGe::LoopBufferBlock::startPortIn
const NetlistPort & startPortIn() const
Definition: LoopBufferBlock.cc:281
ProGe::InBitPort
Convenience class for input bit ports.
Definition: NetlistPort.hh:216
ProGe::OutPort
Convenience class for output ports.
Definition: NetlistPort.hh:158
ProGe::LoopBufferBlock::write
virtual void write(const Path &targetBaseDir, HDL targetLang=VHDL) const override
Definition: LoopBufferBlock.cc:337
Environment::dataDirPath
static std::string dataDirPath(const std::string &prog)
Definition: Environment.cc:176