OpenASIP  2.0
BlocksTranslator.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2021 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 BlocksTranslator.cc
26  *
27  * Implementation of the translation (Blocks to TTA) functions.
28  *
29  * @author Maarten Molendijk 2020 (m.j.molendijk@tue.nl)
30  * @author Kanishkan Vadivel 2021 (k.vadivel@tue.nl)
31  */
32 
33 #include "BlocksTranslator.hh"
34 
35 #include <map>
36 #include <memory>
37 #include <string>
38 
39 #include "BlocksModel.hh"
40 #include "ExecutionPipeline.hh"
41 #include "Segment.hh"
42 
43 using namespace TTAMachine;
44 using namespace std;
45 
46 /**
47  * Build the TTA model (adf file) from the Blocks model.
48  *
49  * @param BlocksModel The Blocks model created from the Blocks
50  * 'architecture.xml'.
51  * @param outputName The name of the output adf.
52  */
53 void
55  BlocksModel& blocksModel, const string& outputName) {
56  Machine ttaMach;
57  ttaMach.setLittleEndian(true);
58  // Create data and instruction adress spaces
59  const int bitWidth = 8;
60  const unsigned int minAddress = 0;
61  // TODO(mm): Allow for different instr mem size than default
62  const unsigned int maxAddressInstr = 2046;
63  // TODO(mm): Allow for different data mem size than default
64  const unsigned int maxAddressData = 32768;
65  AddressSpace asData(
66  "data", bitWidth, minAddress, maxAddressData, ttaMach);
67  AddressSpace asInstr(
68  "instructions", bitWidth, minAddress, maxAddressInstr, ttaMach);
69 
70  // Create a list for each functional unit type
71  list<BlocksALUPair*> aluList;
72  list<BlocksLSUPair*> lsuList;
73  list<BlocksRF*> rfList;
74  list<BlocksIMM*> iuList;
75  list<BlocksMULPair*> mulList;
76 
77  // Default required unit
78  InstructionTemplate limm("limm", ttaMach);
79  BlocksGCU gcu(
80  ttaMach, "abu",
81  asInstr); // Has to be created here so in IU slot can be added
82 
83  // Check which outputs of the FU are used, each output requires a seperate
84  // TTA FU.
85  for (auto& fu : blocksModel.mFunctionalUnitList) {
86  for (auto& source : fu.src) {
87  // Split the string into FU and port
88  string sourcePort = source.substr(source.rfind(".") + 1);
89  string sourceFu = source.substr(0, source.rfind("."));
90  // Set the usesOutx to true
91  for (auto& srcFu : blocksModel.mFunctionalUnitList) {
92  if (srcFu.name == sourceFu) {
93  if (sourcePort == "0")
94  srcFu.usesOut0 = true;
95  else
96  srcFu.usesOut1 = true;
97  }
98  }
99  }
100  }
101 
102  // Create for each Blocks unit a TTA unit (except default GCU and IDs)
103  for (auto& fu : blocksModel.mFunctionalUnitList) {
104  switch (fu.type) {
105  case FU_TYPE::ID:
106  break; // Instruction decoders are not taken into account.
107  case FU_TYPE::LSU:
108  lsuList.push_back(new BlocksLSUPair(
109  ttaMach, fu.name, fu.src, asData, fu.usesOut0,
110  fu.usesOut1));
111  break;
112  case FU_TYPE::ALU:
113  aluList.push_back(new BlocksALUPair(
114  ttaMach, fu.name, fu.src, fu.usesOut0, fu.usesOut1));
115  break;
116  case FU_TYPE::RF:
117  rfList.push_back(new BlocksRF(ttaMach, fu.name, fu.src));
118  break;
119  case FU_TYPE::IU:
120  iuList.push_back(new BlocksIMM(ttaMach, fu.name, fu.src));
121  if (iuList.size() == 1)
122  limm.addSlot("ra_out_to_ra_in", 32, *(iuList.back()->iu));
123  break;
124  case FU_TYPE::MUL:
125  mulList.push_back(new BlocksMULPair(
126  ttaMach, fu.name, fu.src, fu.usesOut0, fu.usesOut1));
127  break;
128  case FU_TYPE::ABU:
129  gcu.sources = fu.src;
130  break;
131  default:
132  try {
133  throw "Illegal function unit type in Blocks.xml file, aborting translation. \n";
134  } catch (const char* error) {
135  fprintf(stderr, "%s", error);
136  Deinitialize(
137  ttaMach, aluList, lsuList, rfList, iuList, mulList);
138  return;
139  }
140  }
141  }
142 
143  ConnectInputs(ttaMach, gcu, aluList, lsuList, rfList, mulList);
144  ttaMach.writeToADF(outputName);
145  Deinitialize(ttaMach, aluList, lsuList, rfList, iuList, mulList);
146 }
147 
148 /**
149  * Create a connection between two different sockets.
150  * Note: Input := Bus to port, output := Port to bus.
151  *
152  * @param mach The TTA machine where the connection needs to be made.
153  * @param inputSocket A pointer to the TTA input socket that needs to be
154  * connected.
155  * @param outputSocket A pointer to the TTA output socket that needs to be
156  * connected.
157  * @param gcu A reference to the TTA GCU (ABU) model.
158  */
159 Bus*
161  Machine& mach, Socket* inputSocket, Socket* outputSocket,
162  BlocksGCU& gcu) {
163  // TODO(mm): add exception catching where given "input" is not an input
164  // port
165  const int busWidth = 32;
166  const int immWidth = 0;
167  const string& to = inputSocket->name();
168  const string& from = outputSocket->name();
169  Machine::Extension busExt = Machine::Extension::ZERO;
170  Machine::BusNavigator busNav = mach.busNavigator();
171  const string newBusNum = to_string(busNav.count());
172  Bus* ttaBus;
173  // Verify if the socket is already attached to a bus (excluding
174  // 'ra_out_to_ra_in')
175  if (inputSocket->segmentCount() == 0) {
176  ttaBus = new Bus("bus_" + newBusNum, busWidth, immWidth, busExt);
177  mach.addBus(*ttaBus);
178  new Segment("seg1", *ttaBus);
179  if (inputSocket->name() == "ra_in" || inputSocket->name() == "pc") {
180  gcu.pcIn->attachBus(*ttaBus);
181  gcu.raIn->attachBus(*ttaBus);
182  } else {
183  inputSocket->attachBus(*ttaBus);
184  }
185  } else if (
186  inputSocket->segmentCount() == 1 &&
187  inputSocket->segment(0)->parentBus()->name() == "ra_out_to_ra_in") {
188  ttaBus = new Bus("bus_" + newBusNum, busWidth, immWidth, busExt);
189  mach.addBus(*ttaBus);
190  new Segment("seg1", *ttaBus);
191  if (inputSocket->name() == "ra_in" || inputSocket->name() == "pc") {
192  gcu.pcIn->attachBus(*ttaBus);
193  gcu.raIn->attachBus(*ttaBus);
194  } else {
195  inputSocket->attachBus(*ttaBus);
196  }
197  } else if (
198  inputSocket->segmentCount() == 2 &&
199  inputSocket->segment(0)->parentBus()->name() == "ra_out_to_ra_in") {
200  Segment* segment1 = inputSocket->segment(1);
201  ttaBus = segment1->parentBus();
202  }
203  // Not 'ra_out_to_ra_in' and segmentCount == 1
204  else {
205  Segment* segment1 = inputSocket->segment(0);
206  ttaBus = segment1->parentBus();
207  }
208  // Attach busses to sockets
209  outputSocket->attachBus(*ttaBus);
210  outputSocket->setDirection(Socket::Direction::OUTPUT);
211  return ttaBus;
212 }
213 
214 /**
215  * Create all the connectivity in the TTA model.
216  *
217  * @param mach The TTA machine where the connections need to be made.
218  * @param gcu A reference to the TTA GCU (ABU) model.
219  * @param aluList A list with all ALU pairs currently in the TTA model.
220  * @param lsuList A list with all LSU pairs currently in the TTA model.
221  * @param rfList A list with all RFs currently in the TTA model.
222  * @param mulList A list with all MUL pairs currently in the TTA model.
223  */
224 void
226  TTAMachine::Machine& mach, BlocksGCU& gcu,
227  std::list<BlocksALUPair*> aluList, std::list<BlocksLSUPair*> lsuList,
228  std::list<BlocksRF*> rfList, std::list<BlocksMULPair*> mulList) {
230  // Create ALU connections (all connections that are an input to the ALUs)
231  for (auto& blocksAlu : aluList) {
232  for (auto& source : blocksAlu->sources) {
233  Socket* outputSocket = FindOutputSocket(nav, source);
235  mach, blocksAlu->in1sock.get(), outputSocket, gcu);
237  mach, blocksAlu->in2sock.get(), outputSocket, gcu);
238  }
239  }
240 
241  // Create LSU connections (all connections that are an input to the LSUs)
242  for (auto& lsu : lsuList) {
243  for (auto& source : lsu->sources) {
244  Socket* outputSocket = FindOutputSocket(nav, source);
245  CreateConnection(mach, lsu->in1sock.get(), outputSocket, gcu);
246  CreateConnection(mach, lsu->in2sock.get(), outputSocket, gcu);
247  }
248  }
249 
250  // Create MUL connections (all connections that are an input to the MULs)
251  for (auto& mul : mulList) {
252  for (auto& source : mul->sources) {
253  Socket* outputSocket = FindOutputSocket(nav, source);
254  CreateConnection(mach, mul->in1sock.get(), outputSocket, gcu);
255  CreateConnection(mach, mul->in2sock.get(), outputSocket, gcu);
256  }
257  }
258 
259  // Create RF connections (all connections that are an input to the RFs)
260  for (auto& rf : rfList) {
261  for (auto& source : rf->sources) {
262  Socket* outputSocket = FindOutputSocket(nav, source);
263  CreateConnection(mach, rf->in1sock, outputSocket, gcu);
264  }
265  }
266 
267  // IMM has no input socket so is skipped.
268  // Create GCU connections
269  for (auto& source : gcu.sources) {
270  Socket* outputSocket = FindOutputSocket(nav, source);
271  CreateConnection(mach, gcu.pcIn, outputSocket, gcu);
272  CreateConnection(mach, gcu.valIn, outputSocket, gcu);
273  }
274 }
275 
276 /**
277  * Find the output socket corresponding to a FU name.
278  *
279  * @param nav An instance of a socketnavigator.
280  * @param source The source of which the handle to the output socket needs to
281  * be returned.
282  */
283 Socket*
285  Machine::SocketNavigator nav, string source) {
286  // String manipulation to get the right format
287  source.replace(source.rfind("."), 1, "_out");
288  assert(
289  nav.hasItem(source) &&
290  "Cannot create connection, output socket not found!");
291  return nav.item(source);
292 }
293 
294 /**
295  * Clean up the memory, deletes all FUs and busses.
296  *
297  * @param mach The TTA machine where the connections need to be made.
298  * @param aluList A list with all ALU pairs currently in the TTA model.
299  * @param lsuList A list with all LSU pairs currently in the TTA model.
300  * @param rfList A list with all RFs currently in the TTA model.
301  * @param mulList A list with all MUL pairs currently in the TTA model.
302  */
303 void
305  TTAMachine::Machine& mach, std::list<BlocksALUPair*> aluList,
306  std::list<BlocksLSUPair*> lsuList, std::list<BlocksRF*> rfList,
307  std::list<BlocksIMM*> iuList, std::list<BlocksMULPair*> mulList) {
308  while (!aluList.empty()) {
309  delete aluList.front();
310  aluList.pop_front();
311  }
312  while (!lsuList.empty()) {
313  delete lsuList.front();
314  lsuList.pop_front();
315  }
316  while (!rfList.empty()) {
317  delete rfList.front();
318  rfList.pop_front();
319  }
320  while (!iuList.empty()) {
321  delete iuList.front();
322  iuList.pop_front();
323  }
324  while (!mulList.empty()) {
325  delete mulList.front();
326  mulList.pop_front();
327  }
328  // Delete busses
329  Machine::BusNavigator busNav = mach.busNavigator();
330  while (busNav.count() != 0) {
331  Bus* toDelete = busNav.item(busNav.count() - 1);
332  delete toDelete->segment(0);
333  delete toDelete;
334  }
335 }
336 
337 /**
338  * main()
339  */
340 int
341 main(int argc, char* argv[]) {
342  // Define a structured way to represent the .xml architecture.
343  // Verify input arguments and open xml file.
344  try {
345  if (argc != 3)
346  throw "Invalid number of arguments, expected 2 arguments. \n";
347  } catch (const char* error) {
348  fprintf(stderr, "%s", error);
349  fprintf(
350  stdout,
351  "Expected path to .xml file with Blocks architecture and name of "
352  "output architecture (<name>.adf). \n");
353  return 1;
354  }
355 
356  const string filepath = string(argv[1]);
357  const string outputFileName = string(argv[2]);
358 
359  BlocksModel blocksModel(filepath);
361 }
BlocksTranslator::CreateConnection
TTAMachine::Bus * CreateConnection(TTAMachine::Machine &mach, TTAMachine::Socket *inputSocket, TTAMachine::Socket *outputSocket, BlocksGCU &gcu)
Definition: BlocksTranslator.cc:160
IU
const string IU
Definition: IDFSerializer.cc:72
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
BlocksGCU::raIn
TTAMachine::Socket * raIn
Definition: BlocksGCU.hh:55
outputFileName
static std::string outputFileName(const std::string &adfFile)
Definition: CreateBEM.cc:77
main
int main(int argc, char *argv[])
Definition: BlocksTranslator.cc:341
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
ExecutionPipeline.hh
TTAMachine::Segment
Definition: Segment.hh:54
BlocksRF
Definition: BlocksRF.hh:41
TTAMachine::Bus
Definition: Bus.hh:53
BlocksGCU::valIn
TTAMachine::Socket * valIn
Definition: BlocksGCU.hh:58
TTAMachine::InstructionTemplate::addSlot
virtual void addSlot(const std::string &slotName, int width, ImmediateUnit &dstUnit)
Definition: InstructionTemplate.cc:169
BlocksLSUPair
Definition: BlocksLSU.hh:68
BlocksTranslator::FindOutputSocket
TTAMachine::Socket * FindOutputSocket(TTAMachine::Machine::SocketNavigator nav, std::string source)
Definition: BlocksTranslator.cc:284
TTAMachine::Socket::segment
Segment * segment(int index) const
Definition: Socket.cc:401
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
BlocksTranslator::Deinitialize
void Deinitialize(TTAMachine::Machine &mach, std::list< BlocksALUPair * > aluList, std::list< BlocksLSUPair * > lsuList, std::list< BlocksRF * > rfList, std::list< BlocksIMM * > iuList, std::list< BlocksMULPair * > mulList)
Definition: BlocksTranslator.cc:304
BlocksMULPair
Definition: BlocksMUL.hh:67
BlocksGCU::sources
std::list< std::string > sources
Definition: BlocksGCU.hh:60
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
assert
#define assert(condition)
Definition: Application.hh:86
BlocksTranslator.hh
Segment.hh
TTAMachine::Socket::attachBus
void attachBus(Segment &bus)
Definition: Socket.cc:166
TTAMachine::Segment::parentBus
Bus * parentBus() const
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
TTAMachine::Socket
Definition: Socket.hh:53
BlocksTranslator::BuildTTAModel
void BuildTTAModel(BlocksModel &blocksModel, const std::string &outputName)
Definition: BlocksTranslator.cc:54
BlocksModel.hh
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
TTAMachine::Socket::setDirection
void setDirection(Direction direction)
Definition: Socket.cc:130
TTAMachine::Machine::addBus
virtual void addBus(Bus &bus)
Definition: Machine.cc:139
TTAMachine::Machine::writeToADF
void writeToADF(const std::string &adfFileName) const
Definition: Machine.cc:913
BlocksGCU
Definition: BlocksGCU.hh:46
BlocksModel
Definition: BlocksModel.hh:55
BlocksALUPair
Definition: BlocksALU.hh:62
BlocksGCU::pcIn
TTAMachine::Socket * pcIn
Definition: BlocksGCU.hh:57
BlocksTranslator::ConnectInputs
void ConnectInputs(TTAMachine::Machine &mach, BlocksGCU &gcu, std::list< BlocksALUPair * > aluList, std::list< BlocksLSUPair * > lsuList, std::list< BlocksRF * > rfList, std::list< BlocksMULPair * > mulList)
Definition: BlocksTranslator.cc:225
BlocksModel::mFunctionalUnitList
std::list< FunctionalUnit > mFunctionalUnitList
Definition: BlocksModel.hh:87
TTAMachine::Machine::setLittleEndian
void setLittleEndian(bool flag)
Definition: Machine.hh:259
BlocksIMM
Definition: BlocksIMM.hh:39
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
TTAMachine::Machine::Extension
Extension
Definition: Machine.hh:80
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::Socket::segmentCount
int segmentCount() const
TTAMachine
Definition: Assembler.hh:48
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
RF
const string RF
Definition: IDFSerializer.cc:68
TTAMachine::Machine
Definition: Machine.hh:73