OpenASIP 2.2
Loading...
Searching...
No Matches
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
46namespace 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")) {
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")) {
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 */
166void
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 */
177void
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 */
189void
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 */
202void
203LoopBufferBlock::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 */
216void
219 Parameter("enable_usage_trace", "boolean", value ? "true" : "false"));
220}
221
222/**
223 * Returns (global) lock request input port.
224 *
225 */
226const NetlistPort&
228 assert(lockReqPortIn_ != nullptr && "Unset port.");
229 return *lockReqPortIn_;
230}
231
232/**
233 * Returns (global) lock request output port.
234 */
235const NetlistPort&
237 assert(lockReqPortOut_ != nullptr && "Unset port.");
238 return *lockReqPortOut_;
239}
240
241/**
242 * Returns (global) lock input port.
243 */
244const NetlistPort&
246 assert(lockPortIn_ != nullptr && "Unset port.");
247 return *lockPortIn_;
248}
249
250/**
251 * Returns (global) lock output port.
252 */
253const NetlistPort&
255 assert(lockPortOut_ != nullptr && "Unset port.");
256 return *lockPortOut_;
257}
258
259/**
260 * Returns input port for instruction word.
261 */
262const NetlistPort&
264 assert(instructionPortIn_ != nullptr && "Unset port.");
265 return *instructionPortIn_;
266}
267
268/**
269 * Returns output port for instruction word.
270 */
271const NetlistPort&
273 assert(instructionPortOut_ != nullptr && "Unset port.");
274 return *instructionPortOut_;
275}
276
277/**
278 * Returns control port for starting loop buffer.
279 */
280const 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 */
292const NetlistPort*
294 return stopPortIn_;
295}
296
297/**
298 * Returns control port for setting loop body size.
299 */
300const 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 */
312const NetlistPort*
316
317/**
318 * Returns control port for outputting current loop instruction index.
319 */
320const 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 */
330const NetlistPort&
332 assert(loopFromImemPortOut_ != nullptr && "Unset port.");
333 return *loopFromImemPortOut_;
334}
335
336void
337LoopBufferBlock::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"));
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 /
360 std::string("inflooper_fsm_with_stopping.snippet"));
361 instantiator.replacePlaceholderFromFile(
362 "signal-declarations",
363 progeDataDir / std::string("inflooper_stop_signals.snippet"));
364 instantiator.replacePlaceholderFromFile(
365 "stop-reg",
366 progeDataDir / std::string("inflooper_stop_register.snippet"));
367 } else {
368 instantiator.replacePlaceholderFromFile(
369 "fsm-logic",
370 progeDataDir / std::string("inflooper_fsm_default.snippet"));
371 }
372
373 instantiator.instantiateTemplateFile(
374 (progeDataDir / (implmenetationFile_ + ".vhdl.tmpl")).string(),
375 target + implmenetationFile_ + ".vhdl");
376}
377
378} /* namespace ProGe */
#define assert(condition)
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
static std::string dataDirPath(const std::string &prog)
static const std::string DIRECTORY_SEPARATOR
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)
TCETools::CIStringSet OperationSet
static OperationSet getOpset(const TTAMachine::Machine &mach)
virtual bool hasParameter(const std::string &name) const
void setModuleName(const std::string &name)
NetlistPort * addPort(NetlistPort *port)
void addParameter(const Parameter &param)
const std::string & moduleName() const
void setParameter(const Parameter &param)
Convenience class for input bit ports.
Convenience class for input ports.
void setUsageTracingParameter(bool setting)
virtual void write(const Path &targetBaseDir, HDL targetLang=VHDL) const override
const NetlistPort & instructionPortOut() const
void setBlockWidthParameter(const std::string value)
const NetlistPort * loopIterationPortIn() const
const NetlistPort & instructionPortIn() const
const NetlistPort & loopBodySizePortIn() const
void setCoreIdParameter(const std::string value)
void setBufferSizeParameter(const std::string value)
const NetlistPort & startPortIn() const
const NetlistPort & lenCntrPortOut() const
const NetlistPort & loopFromImemPortOut() const
NetlistPort * loopFromImemPortOut_
const NetlistPort & lockPortOut() const
NetlistPort * lockReqPortOut_
NetlistPort * loopBodySizePortIn_
NetlistPort * instructionPortOut_
const NetlistPort & lockReqPortIn() const
NetlistPort * loopIterationPortIn_
NetlistPort * lenCntrPortOut_
void setIterationPortWidthParameter(const std::string value)
const NetlistPort * stopPortIn() const
NetlistPort * instructionPortIn_
const NetlistPort & lockPortIn() const
const NetlistPort & lockReqPortOut() const
void rename(const std::string &newname)
Convenience class for output bit ports.
Convenience class for output ports.
static NetlistPort * resetPort(Direction direction=IN)
static NetlistPort * clockPort(Direction direction=IN)
const std::string & coreEntityName() const
const TTAMachine::Machine & adf() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
Definition FUGen.hh:54
HDL
HDLs supported by ProGe.
Definition ProGeTypes.hh:40
@ VHDL
VHDL.
Definition ProGeTypes.hh:41