35 #include <wx/spinctrl.h>
36 #include <wx/statline.h>
37 #include <wx/textctrl.h>
70 wxDialog(parent, -1, _T("Choose operation & latency"),
72 latency_(1), operation_("") {
74 createContents(
this,
true,
true);
75 operationList_ =
dynamic_cast<wxListBox*
>(
FindWindow(ID_LIST));
91 operationList_->Clear();
98 std::set<TCEString> opset;
103 if (opNameFilter_.empty()
104 || opName.find(opNameFilter_) != std::string::npos) {
105 opset.insert(opName);
110 for (
const auto& opName : opset) {
122 latency_ =
dynamic_cast<wxSpinCtrl*
>(
FindWindow(ID_LATENCY))->GetValue();
135 FindWindow(wxID_OK)->Enable(operationList_->GetSelection() != wxNOT_FOUND);
139 if (operation_ ==
"")
144 wxString outputCount;
153 "Error in loading the operation description.");
158 wxTextCtrl *opDescription =
dynamic_cast<wxTextCtrl*
>(
160 opDescription->Clear();
161 opDescription->AppendText(opDesc);
163 wxStaticText *inputsLabel =
dynamic_cast<wxStaticText*
>(
165 inputsLabel->SetLabel(wxT(
"Inputs: ") + inputCount);
166 wxStaticText *outputsLabel =
dynamic_cast<wxStaticText*
>(
168 outputsLabel->SetLabel(wxT(
"Outputs: ") + outputCount);
177 if (operationList_->GetSelection() == wxNOT_FOUND) {
178 wxString message = _T(
"No operation selected.");
183 TransferDataFromWindow();
193 std::string pattern(event.GetString().mb_str());
194 std::string::iterator it;
195 it = std::remove_if(pattern.begin(), pattern.end(), [](
const char& c) {
198 pattern.erase(it, pattern.end());
199 for (
auto& c : pattern) c = toupper(c);
200 opNameFilter_ = pattern;
217 wxString message = _T(
"Function unit already contains operation '");
219 message.Append(_T(
"'."));
231 std::map<int, std::set<int> > inputs;
232 std::map<int, std::set<int> > outputs;
249 opWidth = oper.
width();
251 inputs[opWidth].insert(oper.
index());
257 if (!inputs.empty()) {
260 int latency = (latency_ > 0) ? latency_ - 1 : latency_;
266 opWidths.RemoveLast(2);
267 opWidths.Append(_T(
"."));
274 inputPorts[port->
width()].insert(port);
276 outputPorts[port->
width()].insert(port);
278 unconnectedPorts[port->
width()].insert(port);
282 bool triggerBound =
false;
283 triggerBound |= bindPorts(*operation, inputs, inputPorts, !inputs.empty());
284 bindPorts(*operation, outputs, outputPorts,
false);
286 bindPorts(*operation, inputs, unconnectedPorts,
false);
287 bindPorts(*operation, outputs, unconnectedPorts,
false);
291 if (!inputs.empty() || !outputs.empty()
292 || (!inputs.empty() && !triggerBound)) {
294 if (!inputs.empty() && !triggerBound) {
296 _T(
"Could not bind operand to the trigger port. "));
298 _T(
"It may be too narrow or missing?\n"));
301 if (!inputs.empty()) {
303 _T(
"Not enough (wide enough?) input ports for the operation "
304 "input operands.\n"));
306 if (!outputs.empty()) {
308 _T(
"Not enough (wide enough?) output ports for the operation "
309 "output operands.\n"));
312 message.Append(_T(
" needs a "));
313 message.Append(opWidths);
334 std::map<
int, std::set<int> >& operands,
337 bool triggerBound =
false;
338 int triggerWidth = 0;
339 const FUPort* triggerPort = NULL;
342 triggerPort = findTriggerPort(ports);
344 triggerWidth = triggerPort->
width();
348 while (!operands.empty() && !ports.empty()) {
349 std::map<int, std::set<int> >::iterator j = operands.begin();
350 int width = j->first;
351 for (PortMap::iterator k = ports.begin();
353 if (k->first >= width) {
354 std::set<int>& operandsOfSize = j->second;
355 std::set<int>::iterator operandIter = operandsOfSize.begin();
357 && triggerPort !=
nullptr
358 && width <= triggerWidth
359 && operandsOfSize.size() == 1) {
360 std::map<int, std::set<int> >::iterator next = j;
362 if (next==operands.end() || next->first > triggerWidth) {
363 operation.
bindPort(*operandIter, *triggerPort);
364 operands.erase(j->first);
365 ports.erase(triggerWidth);
366 needsTrigger =
false;
371 PortSet& portsOfSize = k->second;
373 PortSet::iterator portIter = portsOfSize.end();
376 operation.
bindPort(*operandIter, *fuPort);
378 needsTrigger =
false;
381 operandsOfSize.erase(operandIter);
382 if (operandsOfSize.empty()) {
383 operands.erase(j->first);
385 portsOfSize.erase(portIter);
386 if (portsOfSize.empty()) {
387 ports.erase(k->first);
404 for (PortMap::iterator i = ports.begin(); i != ports.end(); i++) {
405 PortSet& portsOfSize = i->second;
406 for (PortSet::iterator j = portsOfSize.begin();
407 j != portsOfSize.end(); j++) {
425 wxBoxSizer *mainSizer =
new wxBoxSizer(wxVERTICAL);
427 wxBoxSizer *upperSizer =
new wxBoxSizer(wxHORIZONTAL);
430 wxBoxSizer *leftSizer =
new wxBoxSizer(wxVERTICAL);
432 wxListBox *opListBox =
new wxListBox(parent, ID_LIST, wxDefaultPosition,
433 wxSize(210, 150), 0, NULL, wxLB_SINGLE|wxLB_SORT);
434 leftSizer->Add(opListBox, 0, wxEXPAND|wxALL, 5);
437 wxBoxSizer *filterSizer =
new wxBoxSizer(wxHORIZONTAL);
439 wxStaticText *opNameFilterLabel =
new wxStaticText(parent,
440 ID_OP_FILTER_LABEL, wxT(
"Filter:"), wxDefaultPosition, wxDefaultSize,
443 wxTextCtrl *opNameFilter =
new wxTextCtrl(parent, ID_OP_FILTER, wxT(
""),
444 wxDefaultPosition, wxDefaultSize, 0);
445 filterSizer->Add(opNameFilterLabel, 0, 0);
446 filterSizer->Add(opNameFilter, 1, wxEXPAND);
447 leftSizer->Add(filterSizer, 0, wxEXPAND|wxALL, 5);
450 wxBoxSizer *latencySizer =
new wxBoxSizer(wxHORIZONTAL);
452 wxStaticText *latencyLabel =
new wxStaticText(parent, ID_TEXT,
453 wxT(
"Latency:"), wxDefaultPosition, wxDefaultSize, 0);
455 wxSpinCtrl *latencySpinner =
new wxSpinCtrl(parent, ID_LATENCY, wxT(
"1"),
456 wxDefaultPosition, wxSize(-1,-1), 0, 1, 100, 1);
457 latencySizer->Add(latencyLabel, 1, 0);
458 latencySizer->Add(latencySpinner, 1);
459 leftSizer->Add(latencySizer, 0, wxEXPAND|wxALL, 5);
462 wxStaticBoxSizer *rightSizer =
new wxStaticBoxSizer(wxVERTICAL, parent,
463 wxT(
"Operation description"));
465 wxTextCtrl *opDescription =
new wxTextCtrl(parent, ID_OP_DESCRIPTION,
466 wxT(
""), wxDefaultPosition, wxSize(210, -1),
467 wxTE_MULTILINE|wxTE_READONLY);
470 wxBoxSizer *insOutsSizer =
new wxBoxSizer(wxHORIZONTAL);
472 wxStaticText *inputsLabel =
new wxStaticText(parent, ID_OP_INPUTS,
473 wxT(
"Inputs:"), wxDefaultPosition, wxDefaultSize, 0);
475 wxStaticText *outputsLabel =
new wxStaticText(parent, ID_OP_OUTPUTS,
476 wxT(
"Outputs: "), wxDefaultPosition, wxDefaultSize, 0);
477 insOutsSizer->Add(inputsLabel, 1);
478 insOutsSizer->Add(outputsLabel, 1);
479 rightSizer->Add(opDescription, 1, wxEXPAND|wxALL, 5);
480 rightSizer->Add(insOutsSizer, 0, wxEXPAND|wxALL, 5);
482 upperSizer->Add(leftSizer, 0, wxALL, 5);
483 upperSizer->Add(rightSizer, 1, wxEXPAND|wxALL, 5);
485 mainSizer->Add(upperSizer, 1, wxEXPAND);
488 wxStaticLine *horisontalLine =
new wxStaticLine(parent, ID_LINE,
489 wxDefaultPosition, wxSize(20,-1), wxLI_HORIZONTAL);
490 mainSizer->Add(horisontalLine, 0, wxEXPAND|wxALL, 5);
493 wxBoxSizer *buttonsSizer =
new wxBoxSizer(wxHORIZONTAL);
495 wxButton *cancelButton =
new wxButton(parent, wxID_CANCEL, wxT(
"&Cancel"),
496 wxDefaultPosition, wxDefaultSize, 0);
497 buttonsSizer->Add(cancelButton, 0, wxALIGN_CENTER|wxALL, 5);
499 wxButton *okButton =
new wxButton(parent, wxID_OK, wxT(
"&OK"),
500 wxDefaultPosition, wxDefaultSize, 0);
501 buttonsSizer->Add(okButton, 0, wxALIGN_CENTER|wxALL, 5);
503 mainSizer->Add(buttonsSizer, 0, 0, 5);
506 parent->SetSizer(mainSizer);
508 mainSizer->SetSizeHints( parent );