OpenASIP 2.2
Loading...
Searching...
No Matches
AddFUFromHDBDialog.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 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 AddFUFromHDBDialog.cc
26 *
27 * Implementation of AddFUFromHDBDialog class.
28 *
29 * @author Veli-Pekka Jääskeläinen 2006 (vjaaskel-no.spam-cs.tut.fi)
30 * @note rating: red
31 */
32
33#include <sstream>
34
35#include <boost/format.hpp>
36#include <wx/statline.h>
37#include <wx/listctrl.h>
38#include <wx/dir.h>
39#include <wx/textctrl.h>
40#include <wx/imaglist.h>
41#include <wx/srchctrl.h>
42
43#include "AddFUFromHDBDialog.hh"
44#include "Model.hh"
45#include "Machine.hh"
46#include "WxConversion.hh"
47#include "WidgetTools.hh"
48#include "HDBManager.hh"
49#include "FUArchitecture.hh"
50#include "FunctionUnit.hh"
51#include "HWOperation.hh"
52#include "WarningDialog.hh"
53#include "ErrorDialog.hh"
54#include "MapTools.hh"
55#include "Environment.hh"
56#include "FileSystem.hh"
57#include "FUPort.hh"
58#include "ExecutionPipeline.hh"
59#include "HDBRegistry.hh"
60#include "ObjectState.hh"
61#include "ProDeConstants.hh"
62
63#if !wxCHECK_VERSION(3, 0, 0)
64 typedef long int wxIntPtr;
65#endif
66
67using std::string;
68using boost::format;
69using namespace TTAMachine;
70using namespace HDB;
71
72BEGIN_EVENT_TABLE(AddFUFromHDBDialog, wxDialog)
77 EVT_TEXT(ID_FILTER_TEXTCTRL, AddFUFromHDBDialog::onFilterChange)
78 EVT_LIST_COL_CLICK(ID_LIST, AddFUFromHDBDialog::onColumnClick)
79 EVT_TIMER(ID_FILTER_TIMER, AddFUFromHDBDialog::onFilterTimeOut)
81
82
83const wxString AddFUFromHDBDialog::HDB_FILE_FILTER = _T("*.hdb");
84
85int wxCALLBACK
86FUListCompareASC(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData) {
87
88 ListItemData* lid1 = (ListItemData*)item1;
89 ListItemData* lid2 = (ListItemData*)item2;
90 int sortColumn = (int)sortData;
91
92 if (sortColumn == 0) {
93 return lid1->latency - lid2->latency;
94 } else if (sortColumn == 1) {
95 return lid1->operations.Cmp(lid2->operations);
96 } else if (sortColumn == 3) {
97 return lid1->hdbId - lid2->hdbId;
98 } else if (sortColumn == 4) {
99 return lid1->path.Cmp(lid2->path);
100 }
101
102 return 0;
103}
104
105int wxCALLBACK
107
108 ListItemData* lid1 = (ListItemData*)item1;
109 ListItemData* lid2 = (ListItemData*)item2;
110 int sortColumn = (int)sortData;
111
112 if (sortColumn == 0) {
113 return lid2->latency - lid1->latency;
114 } else if (sortColumn == 1) {
115 return lid2->operations.Cmp(lid1->operations);
116 } else if (sortColumn == 3) {
117 return lid2->hdbId - lid1->hdbId;
118 } else if (sortColumn == 4) {
119 return lid2->path.Cmp(lid1->path);
120 }
121
122 return 0;
123}
124
125/**
126 * The Constructor.
127 *
128 * @param parent Parent window of the dialog.
129 * @param machine Parent Machine of the immediate slots.
130 */
132 wxWindow* parent,
133 Model* model) :
134 wxDialog(
135 parent, -1, _T("HDB Function Units"),
136 wxDefaultPosition, wxDefaultSize,
137 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
138 model_(model),
139 filterTimer_(this, ID_FILTER_TIMER),
140 sortColumn_(1), sortASC_(true) {
141
142 createContents(this, true, true);
143 SetSize(500, 400);
144
145 list_ = dynamic_cast<wxListCtrl*>(FindWindow(ID_LIST));
146
147 list_->InsertColumn(0, _T("Latency"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE);
148 list_->InsertColumn(
149 1, _T("Operations"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE);
150 list_->InsertColumn(2, _T("Impls"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE);
151 list_->InsertColumn(3, _T("HDB ID"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE);
152 list_->InsertColumn(4, _T("HDB"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE);
153
154 string iconPath =
156
157 wxImageList* imageList = new wxImageList(13, 17);
158 imageList->Add(wxIcon(
160 imageList->Add(wxIcon(
162 list_->SetImageList(imageList, wxIMAGE_LIST_SMALL);
163
164 // Disable conditional buttons.
165 FindWindow(ID_ADD)->Disable();
166}
167
168
169/**
170 * The Destructor.
171 */
175
176
177/**
178 * Transfers data from the HDBs to the dialog list widget.
179 */
180bool
182
184 list_->DeleteAllItems();
185
186 if (filterCtrl_) {
187 std::string tmp = WxConversion::toString(filterCtrl_->GetValue());
188 std::istringstream rawFilterRules(tmp.c_str());
189 filterPatterns_.clear();
190 std::string keyword;
191 while (rawFilterRules >> keyword) {
192 filterPatterns_.push_back(keyword);
193 }
194 }
195
197 registry.loadFromSearchPaths();
198
199 for (int i = 0; i < registry.hdbCount(); i++) {
200 loadHDB(registry.hdb(i));
201 }
202
203 wxString message;
204 for (int i = 0; i < registry.hdbErrorCount(); i++) {
205 message.Append(WxConversion::toWxString(registry.hdbErrorMessage(i)));
206 message.Append(_T("\n"));
207 WarningDialog dialog(this, message);
208 dialog.ShowModal();
209 }
210
211 if (registry.hdbCount() < 1) {
212 wxString message = _T("No HDBs found in HDB search paths.");
213 WarningDialog dialog(this, message);
214 dialog.ShowModal();
215 }
216
217 list_->SetColumnWidth(1, 200);
218 list_->SetColumnWidth(4, wxLIST_AUTOSIZE);
219 return wxDialog::TransferDataToWindow();
220}
221
222/**
223 * Loads register files from a HDB to the dialog list.
224 *
225 * @param manager HDB manager to load.
226 * @return True, if the HDB was succesfully loaded.
227 */
228bool
230
231 const std::set<RowID> fuArchIDs = manager.fuArchitectureIDs();
232 std::set<RowID>::iterator iter = fuArchIDs.begin();
233
234 std::string path = manager.fileName();
235
236 // Read properties of all function units found in the HDB and append
237 // data to the dialog FU list widget.
238 for (; iter != fuArchIDs.end(); iter++) {
239
240 FUArchitecture* arch = manager.fuArchitectureByID(*iter);
241 FunctionUnit& fu = arch->architecture();
242
243 if (!acceptToList(path, *arch, filterPatterns_)) {
244 continue;
245 }
246
247 fuArchitectures_.insert(
248 std::pair<int, FUArchitecture*>(list_->GetItemCount(), arch));
249
250 ListItemData* lid = new ListItemData;
251
252 list_->InsertItem(0, _T(""));
253 if (fu.operationCount() > 0) {
254 wxString operations;
255 int minLatency = fu.operation(0)->latency();
256 int maxLatency = fu.operation(0)->latency();
257 for (int i = 0; i < fu.operationCount(); i++) {
258 if (i > 0) {
259 operations.Append(_T(", "));
260 }
261 operations.Append(
263 operations.Append(_T("("));
264 operations.Append(
266 operations.Append(_T(")"));
267
268 if (fu.operation(i)->latency() > maxLatency) {
269 maxLatency = fu.operation(i)->latency();
270 }
271 if (fu.operation(i)->latency() < minLatency) {
272 minLatency = fu.operation(i)->latency();
273 }
274 }
275 wxString latency = WxConversion::toWxString(minLatency);
276 if (maxLatency != minLatency) {
277 latency.Append(_T(".."));
278 latency.Append(WxConversion::toWxString(maxLatency));
279 }
280
281 list_->SetItem(0, 0, latency);
282 lid->latency = minLatency;
283 list_->SetItem(0, 1, operations);
284 lid->operations = operations;
285 }
286 list_->SetItem(0, 3, WxConversion::toWxString(*iter));
287 lid->hdbId = *iter;
288 list_->SetItem(0, 4, WxConversion::toWxString(path));
289 lid->path = WxConversion::toWxString(path);
290 lid->id = list_->GetItemCount() - 1;
291 list_->SetItemData(0, (long)lid);
292 }
293 // default sorting column is "Operations"
294 list_->SortItems(FUListCompareASC, 1);
296
297 return true;
298}
299
300
301/**
302 * Returns true if the FU architecture should not be viewed.
303 *
304 * @param filterList The list of all keywords (uppercase), that the FU
305 * architecture should contain.
306 */
307bool
309 const std::string hdbFilePath,
310 const HDB::FUArchitecture& arch,
311 const std::vector<std::string>& filterList) {
312
313 if (filterList.empty()) {
314 return true;
315 }
316
317 // Construct string from where the keywords are searched.
318 std::string archStr;
319 const FunctionUnit& fu = arch.architecture();
320 for (int i = 0; i < fu.operationCount(); i++) {
321 const HWOperation& oper = *fu.operation(i);
322
323 // Operation with latency as viewed in the list.
324 archStr += oper.name()
325 + "(" + Conversion::toString(oper.latency()) + ") ";
326
327 }
328
329 for (auto& c : archStr) c = tolower(c);
330
331 for (const string& keyword : filterList) {
332 if (keyword.size() > 0 && keyword.front() == '!') {
333 if (keyword.size() < 2) {
334 continue;
335 } else if (archStr.find(keyword.substr(1)) != std::string::npos ||
336 hdbFilePath.find(keyword.substr(1)) != std::string::npos) {
337 return false;
338 }
339 } else if (archStr.find(keyword) == std::string::npos &&
340 hdbFilePath.find(keyword) == std::string::npos) {
341 return false;
342 }
343 }
344
345 return true;
346}
347
348
349/**
350 * Updates FU architecture list view accordingly to new filter rule.
351 */
352void
354 if (filterTimer_.Start(250, /*oneShot = */ true)) {
355 return;
356 }
357
358 // Timer could not be started for some reason.
359 // Do filtering immediately instead.
361}
362
363
364void
368
369
370/**
371 * Enables and disables the delete button according to slot list selection.
372 */
373void
375 if (list_->GetSelectedItemCount() == 1) {
376 FindWindow(ID_ADD)->Enable();
377 } else {
378 FindWindow(ID_ADD)->Disable();
379 }
380}
381
382
383/**
384 * Adds a new register file to the machine when "Add" button is pressed.
385 */
386void
388
389 long item = -1;
390 item = list_->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
391 if ( item == -1 ) return;
392
393 ListItemData* lid = (ListItemData*)list_->GetItemData(item);
394 int id = lid->id;
395 const FUArchitecture* arch =
397
398 // Copy the architecture of the selected function unit from HDB.
399 // Copying is done by saving and loading the FU state to an ObjectState
400 // object, because FunctionUnit class doesn't have a copy constructor.
401 ObjectState* fuState = arch->architecture().saveState();
402 FunctionUnit* fu = NULL;
403 try {
404 fu = new FunctionUnit(fuState);
405 delete fuState;
406 } catch (Exception& e) {
407 wxString message = _T("Error while adding function unit:\n");
408 message.Append(WxConversion::toWxString(e.errorMessage()));
409 ErrorDialog dialog(this, message);
410 dialog.ShowModal();
411 }
412
413 int inIndex = 1;
414 int outIndex = 1;
415 int ioIndex = 1;
416 int unusedIndex = 1;
417
418 // Rename ports.
419 for (int p = 0; p < fu->portCount(); p++) {
420 FUPort* port = dynamic_cast<FUPort*>(fu->port(p));
421 bool read = false;
422 bool write = false;
423
424 // Check from the operation pipelines if the port is read or written.
425 for (int o = 0; o < fu->operationCount(); o++) {
426 const HWOperation* operation = fu->operation(o);
427 const ExecutionPipeline* pipeline = operation->pipeline();
428 for (int cycle = 0; cycle < operation->latency(); cycle++) {
429 if (pipeline->isPortRead(*port, cycle)) read = true;
430 if (pipeline->isPortWritten(*port, cycle)) write = true;
431 }
432 }
433
434 // Generate new name for the port according to if it's read/written.
435 std::string portName = "";
436 if (read && write) {
437 portName = "io" + Conversion::toString(ioIndex);
438 ioIndex++;
439 } else if (read) {
440 portName = "in" + Conversion::toString(inIndex);
441 inIndex++;
442 } else if (write) {
443 portName = "out" + Conversion::toString(outIndex);
444 outIndex++;
445 } else {
446 portName = "unused" + Conversion::toString(unusedIndex);
447 unusedIndex++;
448 }
449 if (port->isTriggering()) {
450 portName = portName + "t";
451 }
452 port->setName(portName);
453 }
454
455 // Rename the function unit. All operation names are appended to the
456 // function unit name.
457 std::string name;
458 for (int i = 0; i < fu->operationCount(); i++) {
459 if (i > 0) name += "_";
460 name += fu->operation(i)->name();
461 }
462
464 std::string fuName = name;
465 int i = 1;
466 while (machine->functionUnitNavigator().hasItem(fuName)) {
467 fuName = name + "_" + Conversion::toString(i);
468 i++;
469 }
470
471 fu->setName(fuName);
475
476}
477
478/**
479 * Closes the dialog when the close button is pressed.
480 */
481void
483 Close();
484}
485
486
487/**
488 * Creates the dialog contents.
489 *
490 * @param parent Parent dialog of the contents.
491 * @param call_fit If true, fits the contents inside the dialog.
492 * @param set_sizer If true, sets the main sizer as dialog contents.
493 * @return Top level sizer of the dialog contents.
494 */
495wxSizer*
497 wxWindow *parent, bool call_fit, bool set_sizer) {
498
499 wxFlexGridSizer *item0 = new wxFlexGridSizer( 1, 0, 0 );
500 item0->AddGrowableCol( 0 );
501 item0->AddGrowableRow( 0 );
502
503 wxListCtrl *item1 = new wxListCtrl( parent, ID_LIST, wxDefaultPosition, wxSize(160,120), wxLC_REPORT|wxSUNKEN_BORDER );
504 item0->Add( item1, 0, wxGROW|wxALL, 5 );
505
506 filterCtrl_ = new wxSearchCtrl(parent,
507 ID_FILTER_TEXTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, 0);
508 filterCtrl_->SetDescriptiveText(
509 wxT("Filter operations or HDBs. '!PATTERN' to exclude."));
510 item0->Add(filterCtrl_, 0, wxGROW|wxALL, 5);
511
512 wxButton *item2 = new wxButton( parent, ID_ADD, wxT("&Add"), wxDefaultPosition, wxDefaultSize, 0 );
513 item0->Add( item2, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
514
515 wxStaticLine *item3 = new wxStaticLine( parent, ID_LINE, wxDefaultPosition, wxSize(20,-1), wxLI_HORIZONTAL );
516 item0->Add( item3, 0, wxGROW|wxALL, 5 );
517
518 wxButton *item4 = new wxButton( parent, ID_CLOSE, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
519 item0->Add( item4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
520
521 if (set_sizer) {
522 parent->SetSizer( item0 );
523 if (call_fit) {
524 item0->SetSizeHints( parent );
525 }
526 }
527
528 return item0;
529}
530
531
532/**
533 * Sorts HDB FU list according to clicked column.
534 */
535void
537
538 int clickedColumn = event.GetColumn();
539
540 if (clickedColumn == sortColumn_) {
542 } else {
543 sortASC_ = true;
544 setColumnImage(sortColumn_, -1); // removes arrow from old column
545 sortColumn_ = clickedColumn;
546 }
547
548 setColumnImage(clickedColumn, sortASC_);
549
550 if (sortASC_) {
551 list_->SortItems(FUListCompareASC, clickedColumn);
552 } else {
553 list_->SortItems(FUListCompareDESC, clickedColumn);
554 }
555}
556
557
558/**
559 * Sets sorting arrow image on selected column
560 *
561 * @param col Column index to set the image
562 * @param image Image index in wxImageList
563 */
564void
566 wxListItem item;
567 item.SetMask(wxLIST_MASK_IMAGE);
568 item.SetImage(image);
569 list_->SetColumn(col, item);
570}
long int wxIntPtr
int wxCALLBACK FUListCompareDESC(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
int wxCALLBACK FUListCompareASC(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
END_EVENT_TABLE() using namespace IDF
TTAMachine::Machine * machine
the architecture definition of the estimated processor
FUImplementationDialog::onAddExternalPort FUImplementationDialog::onDeleteExternalPort FUImplementationDialog::onArchPortSelection EVT_LIST_ITEM_DESELECTED(ID_ARCH_PORT_LIST, FUImplementationDialog::onArchPortSelection) EVT_LIST_ITEM_ACTIVATED(ID_ARCH_PORT_LIST
FUImplementationDialog::onAddExternalPort FUImplementationDialog::onDeleteExternalPort FUImplementationDialog::onArchPortSelection FUImplementationDialog::onArchPortActivation EVT_LIST_ITEM_SELECTED(ID_EXTERNAL_PORT_LIST, FUImplementationDialog::onExternalPortSelection) EVT_LIST_ITEM_ACTIVATED(ID_EXTERNAL_PORT_LIST
EVT_BUTTON(ID_EDIT_ARCH_PORT, FUImplementationDialog::onEditArchitecturePort) EVT_BUTTON(ID_ADD_EXTERNAL_PORT
void setColumnImage(int col, int image)
void onAdd(wxCommandEvent &event)
bool acceptToList(const std::string hdbFilePath, const HDB::FUArchitecture &arch, const std::vector< std::string > &filterList)
wxTimer filterTimer_
Timer to postpone filtering while typing filter patterns.
std::vector< std::string > filterPatterns_
Keywords to filter HDB entries.
wxSearchCtrl * filterCtrl_
The list filter text control.
wxSizer * createContents(wxWindow *parent, bool call_fit, bool set_sizer)
void onColumnClick(wxListEvent &event)
void onFilterChange(wxCommandEvent &event)
void onFilterTimeOut(wxTimerEvent &event)
wxListCtrl * list_
Immediate slot list widget.
bool loadHDB(const HDB::HDBManager &manager)
virtual bool TransferDataToWindow()
std::map< int, HDB::FUArchitecture * > fuArchitectures_
Map of iu architectures displayed in the dialog list.
Model * model_
Model of the current adf file.
void onListSelectionChange(wxListEvent &event)
AddFUFromHDBDialog(wxWindow *parent, Model *model)
void onClose(wxCommandEvent &event)
static std::string toString(const T &source)
static std::string iconDirPath()
std::string errorMessage() const
Definition Exception.cc:123
static const std::string DIRECTORY_SEPARATOR
TTAMachine::FunctionUnit & architecture() const
std::string fileName() const
std::set< RowID > fuArchitectureIDs() const
virtual FUArchitecture * fuArchitectureByID(RowID id) const
static HDBRegistry & instance()
CachedHDBManager & hdb(const std::string fileName)
void loadFromSearchPaths()
std::string hdbErrorMessage(unsigned int index)
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static void deleteAllValues(MapType &aMap)
Definition Model.hh:50
void pushToStack()
Definition Model.cc:167
void notifyObservers(bool modified=true)
Definition Model.cc:152
TTAMachine::Machine * getMachine()
Definition Model.cc:88
static const std::string ICON_SORT_DESC
Icon location for descending sort.
static const std::string ICON_SORT_ASC
Icon location for ascending sort.
bool isPortWritten(const FUPort &port, int cycle) const
bool isPortRead(const FUPort &port, int cycle) const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual HWOperation * operation(const std::string &name) const
virtual ObjectState * saveState() const
virtual int operationCount() const
virtual void setName(const std::string &name)
virtual BaseFUPort * port(const std::string &name) const
ExecutionPipeline * pipeline() const
const std::string & name() const
bool hasItem(const std::string &name) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202
virtual void setName(const std::string &name)
Definition Port.cc:155
virtual int portCount() const
Definition Unit.cc:135
static wxString toWxString(const std::string &source)
static std::string toString(const wxString &source)