OpenASIP 2.2
Loading...
Searching...
No Matches
HDBManager.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2014 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 HDBManager.cc
26 *
27 * Implementation of HDBManager class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @author Esa Määttä 2007 (esa.maatta-no.spam-tut.fi)
31 * @author Vinogradov Viacheslav(added Verilog generating) 2012
32 * @note rating: red
33 */
34
35#include <string>
36#include <sstream>
37#include <list>
38#include <map>
39#include <boost/format.hpp>
40
41#include "HDBManager.hh"
42#include "FUEntry.hh"
43#include "FUArchitecture.hh"
44#include "FUImplementation.hh"
46#include "FUExternalPort.hh"
47#include "RFExternalPort.hh"
48#include "RFArchitecture.hh"
49#include "RFEntry.hh"
50#include "RFImplementation.hh"
53#include "CostFunctionPlugin.hh"
54
55#include "FunctionUnit.hh"
56#include "FUPort.hh"
57#include "HWOperation.hh"
58#include "ExecutionPipeline.hh"
59#include "PipelineElement.hh"
60
61#include "SQLite.hh"
63#include "DataObject.hh"
64#include "Application.hh"
65#include "MapTools.hh"
66#include "AssocTools.hh"
67#include "SetTools.hh"
68
69#include "FUValidator.hh"
71#include "Conversion.hh"
72
73using std::string;
74using boost::format;
75using namespace TTAMachine;
76
77// Remove this define when opcode editing should be disabled.
78// Also edit HDBEditor/FUImplementationDialog.hh/.cc to hide the ability to
79// modify opcodes
80#define ALLOW_OPCODE_EDITING
81
82const bool READ_ACTION = true;
83const bool WRITE_ACTION = false;
84
85const string IN_DIRECTION = "IN";
86const string OUT_DIRECTION = "OUT";
87const string BIDIR_DIRECTION = "BIDIR";
88const string VHDL_FORMAT = "VHDL";
89const string VERILOG_FORMAT = "Verilog";
90const string VHDL_SIM_FORMAT = "VHDL simulation";
91const string VERILOG_SIM_FORMAT = "Verilog simulation";
92
93const int DEFAULT_PORT_WIDTH = 32;
94
95/// Possible cost function plugin types
96const std::string COST_PLUGIN_TYPE_FU = "fu";
97const std::string COST_PLUGIN_TYPE_RF = "rf";
98const std::string COST_PLUGIN_TYPE_DECOMP = "decomp";
99const std::string COST_PLUGIN_TYPE_ICDEC = "icdec";
100
101// database table Creation Queries (CQ)
102const string CQ_FU =
103 "CREATE TABLE fu ("
104 " id INTEGER PRIMARY KEY,"
105 " architecture REFERENCES fu_architecture(id),"
106 " cost_function REFERENCES cost_function_plugin(id));";
107
108const string CQ_FU_ARCHITECTURE =
109 "CREATE TABLE fu_architecture("
110 " id INTEGER PRIMARY KEY);";
111
113 "CREATE TABLE pipeline_resource("
114 " id INTEGER PRIMARY KEY,"
115 " fu_arch REFERENCES fu_architecture(id) NOT NULL);";
116
118 "CREATE TABLE operation_pipeline("
119 " id INTEGER PRIMARY KEY,"
120 " fu_arch REFERENCES fu_architecture(id) NOT NULL,"
121 " operation REFERENCES operation(id) NOT NULL);";
122
124 "CREATE TABLE pipeline_resource_usage("
125 " id INTEGER PRIMARY KEY,"
126 " cycle INTEGER NOT NULL,"
127 " resource REFERENCES pipeline_resource(id) NOT NULL,"
128 " pipeline REFERENCES operation_pipeline(id) NOT NULL);";
129
130const string CQ_IO_USAGE =
131 "CREATE TABLE io_usage("
132 " id INTEGER PRIMARY KEY,"
133 " cycle INTEGER NOT NULL,"
134 " io_number INTEGER NOT NULL,"
135 " action BOOLEAN NOT NULL,"
136 " pipeline REFERENCES operation_pipeline(id) NOT NULL);";
137
138const string CQ_OPERATION =
139 "CREATE TABLE operation("
140 " id INTEGER PRIMARY KEY,"
141 " name TEXT UNIQUE NOT NULL);";
142
143const string CQ_FU_DATA_PORT =
144 "CREATE TABLE fu_data_port("
145 " id INTEGER PRIMARY KEY,"
146 " triggers BOOLEAN NOT NULL,"
147 " sets_opcode BOOLEAN NOT NULL,"
148 " guard_support BOOLEAN NOT NULL,"
149 " width INTEGER,"
150 " fu_arch REFERENCES fu_architecture(id));";
151
152const string CQ_IO_BINDING =
153 "CREATE TABLE io_binding("
154 " id INTEGER PRIMARY KEY,"
155 " io_number INTEGER NOT NULL,"
156 " port REFERENCES fu_data_port(id) NOT NULL,"
157 " operation REFERENCES operation(id) NOT NULL);";
158
160 "CREATE TABLE fu_implementation("
161 " id INTEGER PRIMARY KEY,"
162 " name TEXT NOT NULL,"
163 " opcode_port TEXT,"
164 " clk_port TEXT NOT NULL,"
165 " rst_port TEXT NOT NULL,"
166 " glock_port TEXT NOT NULL,"
167 " glock_req_port TEXT,"
168 " fu REFERENCES fu(id) UNIQUE NOT NULL);";
169
170const string CQ_OPCODE_MAP =
171 "CREATE TABLE opcode_map("
172 " id INTEGER PRIMARY KEY,"
173 " opcode INTEGER NOT NULL,"
174 " operation REFERENCES operation(id) NOT NULL,"
175 " fu_impl REFERENCES fu_implementation(id) NOT NULL);";
176
177const string CQ_FU_PORT_MAP =
178 "CREATE TABLE fu_port_map("
179 " id INTEGER PRIMARY KEY,"
180 " name TEXT NOT NULL,"
181 " width_formula TEXT NOT NULL,"
182 " load_port TEXT,"
183 " guard_port TEXT,"
184 " fu_impl REFERENCES fu_implementation(id) NOT NULL,"
185 " arch_port REFERENCES fu_data_port(id) NOT NULL,"
186 " UNIQUE (name, fu_impl));";
187
189 "CREATE TABLE fu_external_port("
190 " id INTEGER PRIMARY KEY,"
191 " name TEXT NOT NULL,"
192 " direction TEXT NOT NULL,"
193 " width_formula TEXT NOT NULL,"
194 " description TEXT,"
195 " fu_impl REFERENCES fu_implementation(id) NOT NULL, "
196 " UNIQUE (name, fu_impl));";
197
199 "CREATE TABLE rf_external_port("
200 " id INTEGER PRIMARY KEY,"
201 " name TEXT NOT NULL,"
202 " direction TEXT NOT NULL,"
203 " width_formula TEXT NOT NULL,"
204 " description TEXT,"
205 " rf_impl REFERENCES rf_implementation(id) NOT NULL, "
206 " UNIQUE (name, rf_impl));";
207
209 "CREATE TABLE fu_implementation_parameter("
210 " id INTEGER PRIMARY KEY,"
211 " name TEXT NOT NULL,"
212 " type TEXT,"
213 " value TEXT,"
214 " fu_impl REFERENCES fu_implementation(id) NOT NULL);";
215
217 "CREATE TABLE rf_implementation_parameter("
218 " id INTEGER PRIMARY KEY,"
219 " name TEXT NOT NULL,"
220 " type TEXT,"
221 " value TEXT,"
222 " rf_impl REFERENCES rf_implementation(id) NOT NULL);";
223
225 "CREATE TABLE fu_ext_port_parameter_dependency("
226 " id INTEGER PRIMARY KEY,"
227 " port REFERENCES fu_external_port(id) NOT NULL,"
228 " parameter REFERENCES fu_implementation_parameter(id) NOT NULL);";
229
231 "CREATE TABLE rf_ext_port_parameter_dependency("
232 " id INTEGER PRIMARY KEY,"
233 " port REFERENCES rf_external_port(id) NOT NULL,"
234 " parameter REFERENCES rf_implementation_parameter(id) NOT NULL);";
235
236const string CQ_RF =
237 "CREATE TABLE rf("
238 " id INTEGER PRIMARY KEY,"
239 " architecture REFERENCES rf_architecture(id),"
240 " cost_function REFERENCES cost_function_plugin(id));";
241
242const string CQ_RF_ARCHITECTURE =
243 "CREATE TABLE rf_architecture("
244 " id INTEGER PRIMARY KEY,"
245 " size INTEGER,"
246 " width INTEGER,"
247 " read_ports INTEGER NOT NULL,"
248 " write_ports INTEGER NOT NULL,"
249 " bidir_ports INTEGER NOT NULL,"
250 " latency INTEGER NOT NULL,"
251 " max_reads INTEGER NOT NULL,"
252 " max_writes INTEGER NOT NULL,"
253 " guard_support BOOLEAN NOT NULL,"
254 " guard_latency INTEGER NOT NULL,"
255 " zero_register BOOLEAN DEFAULT FALSE);";
256
258 "CREATE TABLE rf_implementation("
259 " id INTEGER PRIMARY KEY,"
260 " name TEXT NOT NULL,"
261 " size_param TEXT,"
262 " width_param TEXT,"
263 " clk_port TEXT NOT NULL,"
264 " rst_port TEXT NOT NULL,"
265 " glock_port TEXT NOT NULL,"
266 " guard_port TEXT,"
267 " rf REFERENCES rf(id) NOT NULL,"
268 " sac_param INTEGER DEFAULT 0);"; // Separate address cycle
269
270const string CQ_RF_DATA_PORT =
271 "CREATE TABLE rf_data_port("
272 " id INTEGER PRIMARY KEY,"
273 " name TEXT NOT NULL,"
274 " direction TEXT NOT NULL,"
275 " load_port TEXT NOT NULL,"
276 " opcode_port TEXT NOT NULL,"
277 " opcode_port_width_formula TEXT NOT NULL,"
278 " rf_impl REFERENCES rf_implementation(id),"
279 " UNIQUE (name, rf_impl));";
280
282 "CREATE TABLE block_source_file("
283 " id INTEGER PRIMARY KEY,"
284 " file TEXT NOT NULL,"
285 " format REFERENCES format(id));";
286
287const string CQ_RF_SOURCE_FILE =
288 "CREATE TABLE rf_source_file("
289 " id INTEGER PRIMARY KEY,"
290 " rf_impl REFERENCES rf_implementation(id),"
291 " file REFERENCES block_source_file(id));";
292
293const string CQ_FU_SOURCE_FILE =
294 "CREATE TABLE fu_source_file("
295 " id INTEGER PRIMARY KEY,"
296 " fu_impl REFERENCES fu_implementation(id),"
297 " file REFERENCES block_source_file(id));";
298
299const string CQ_FORMAT =
300 "CREATE TABLE format("
301 " id INTEGER PRIMARY KEY,"
302 " format TEXT NOT NULL);";
303
304const string CQ_BUS =
305 "CREATE TABLE bus ("
306 " id INTEGER PRIMARY KEY);";
307
308const string CQ_SOCKET =
309 "CREATE TABLE socket ("
310 " id INTEGER PRIMARY KEY);";
311
313 "CREATE TABLE cost_function_plugin("
314 " id INTEGER PRIMARY KEY, "
315 " description TEXT, "
316 " name TEXT, "
317 " plugin_file_path TEXT NOT NULL, "
318 " type STRING NOT NULL);"; /// type: {'fu'|'rf'|'decomp'|'icdec'}
319
321 "CREATE TABLE cost_estimation_data("
322 " id INTEGER PRIMARY KEY, "
323 " plugin_reference REFERENCES cost_function_plugin(id), "
324 " rf_reference REFERENCES rf(id), "
325 " fu_reference REFERENCES fu(id), "
326 " bus_reference REFERENCES bus(id), "
327 " socket_reference REFERENCES socket(id), "
328 " name TEXT, "
329 " value TEXT);";
330
332 "CREATE INDEX fu_port_map_arch_index ON fu_port_map(arch_port)";
333
335 "CREATE INDEX fu_impl_entry_index ON fu_implementation(fu)";
336
338 "CREATE INDEX rf_impl_entry_index ON rf_implementation(rf)";
339
341 "CREATE TABLE operation_implementation_resource_source_file("
342 " id INTEGER PRIMARY KEY,"
343 " resource REFERENCES operation_implementation_resource(id),"
344 " file REFERENCES block_source_file(id)"
345 ");";
346
348 "CREATE TABLE operation_implementation_source_file("
349 " id INTEGER PRIMARY KEY,"
350 " operation REFERENCES operation_implementation(id),"
351 " file REFERENCES block_source_file(id)"
352 ");";
353
355 "CREATE TABLE operation_implementation_resource("
356 " id INTEGER PRIMARY KEY,"
357 " name TEXT NOT NULL"
358 ");";
359
361 "CREATE TABLE operation_implementation("
362 " id INTEGER PRIMARY KEY,"
363 " name TEXT NOT NULL"
364 ");";
365
367 "CREATE TABLE operation_implementation_resources("
368 " id INTEGER PRIMARY KEY,"
369 " operation REFERENCES operation_implementation(id),"
370 " resource REFERENCES operation_implementation_resource(id),"
371 " count INTEGER NOT NULL"
372 ");";
373
375 "CREATE TABLE operation_implementation_variable("
376 " id INTEGER PRIMARY KEY,"
377 " operation REFERENCES operation_implementation(id),"
378 " name TEXT NOT NULL,"
379 " width TEXT NOT NULL,"
380 " type TEXT NOT NULL,"
381 " language TEXT NOT NULL"
382 ");";
383
384namespace HDB {
385
386HDBManager* HDBManager::instance_ = NULL;
387
388/**
389 * The constructor.
390 *
391 * @param hdbFile Name of the HDB file to be managed by the manager.
392 * @exception IOException If connection to the DB cannot be established.
393 */
394HDBManager::HDBManager(const std::string& hdbFile)
395 : db_(new SQLite()), dbConnection_(NULL), hdbFile_(hdbFile) {
396 if (!FileSystem::fileExists(hdbFile)) {
397 string errorMsg = "File '" + hdbFile + "' doesn't exist.";
398 throw FileNotFound(__FILE__, __LINE__, __func__, errorMsg);
399 }
400
401 if (!FileSystem::fileIsReadable(hdbFile)) {
402 string errorMsg = "File '" + hdbFile + "' has no read rights.";
403 throw IOException(__FILE__, __LINE__, __func__, errorMsg);
404 }
405
406 try {
407 dbConnection_ = &db_->connect(hdbFile);
408 } catch (const RelationalDBException& exception) {
409 throw IOException(
410 __FILE__, __LINE__, __func__, exception.errorMessage());
411 }
412
413 // Update outdated HDB.
414 // Version 0 indicates db without version number also.
415 int dbVersion = dbConnection_->version();
416
417 // Version 0 -> 1
418 if (dbVersion < 1) {
419 // Initial fu-gen tables and fugen stuff.
426 dbConnection_->updateQuery(std::string(
427 "INSERT INTO format(id,format) VALUES"
428 "(NULL,\"" + VHDL_SIM_FORMAT + "\");"));
429 dbConnection_->updateQuery(std::string(
430 "INSERT INTO format(id,format) VALUES"
431 "(NULL,\"" + VERILOG_SIM_FORMAT + "\");"));
433 }
434
435 // Version 1 -> 2
436 if (dbVersion < 2) {
437 // Variables for operation snippets.
440 }
441
442 // Version 2 -> 3
443 if (dbVersion < 3) {
444 // ipxact to resource table
445 dbConnection_->updateQuery(std::string(
446 "ALTER TABLE operation_implementation_resource ADD COLUMN "
447 "ipxact TEXT;"));
449 }
450
451 // Version 3 -> 4
452 if (dbVersion < 4) {
453 // support for post-operation (for LOADs) and
454 // operation bus definitions for FUGen.
455 dbConnection_->updateQuery(std::string(
456 "ALTER TABLE operation_implementation ADD COLUMN "
457 "bus_definition TEXT;"));
458 dbConnection_->updateQuery(std::string(
459 "ALTER TABLE operation_implementation ADD COLUMN "
460 "post_op_vhdl TEXT;"));
461 dbConnection_->updateQuery(std::string(
462 "ALTER TABLE operation_implementation ADD COLUMN "
463 "post_op_verilog TEXT;"));
465 }
466
467 // Version 4 -> 5
468 if (dbVersion < 5) {
469 dbConnection_->updateQuery(std::string(
470 "ALTER TABLE operation_implementation_resource ADD COLUMN "
471 "latency INTEGER;"));
472 dbConnection_->updateQuery(std::string(
473 "ALTER TABLE operation_implementation ADD COLUMN "
474 "default_verilog TEXT;"));
475 dbConnection_->updateQuery(std::string(
476 "ALTER TABLE operation_implementation ADD COLUMN "
477 "default_vhdl TEXT;"));
479 }
480
481 // Version 5 -> 6
482 if (dbVersion < 6) {
483 try {
484 // rename default_vhdl and default_verilog to initial_*
485 // and add latency column
486 dbConnection_->updateQuery(std::string(
487 "ALTER TABLE operation_implementation ADD COLUMN "
488 "latency INTEGER;"));
489 dbConnection_->updateQuery(std::string(
490 "ALTER TABLE operation_implementation RENAME COLUMN "
491 "default_vhdl TO initial_vhdl;"));
492 dbConnection_->updateQuery(std::string(
493 "ALTER TABLE operation_implementation RENAME COLUMN "
494 "default_verilog TO initial_verilog;"));
496 } catch (const RelationalDBException& exception) {
497 throw IOException(
498 __FILE__, __LINE__, __func__, exception.errorMessage());
499 }
501 }
502
503 if (dbVersion < 7) {
504 try {
505 if (!hasColumn("rf_architecture", "zero_register")) {
506 addBooleanColumn("rf_architecture", "zero_register");
507 }
508 } catch (const RelationalDBException& exception) {
509 throw IOException(
510 __FILE__, __LINE__, __func__, exception.errorMessage());
511 }
513 }
514
515}
516
517/**
518 * The destructor.
519 */
522 delete db_;
523}
524
525
526/**
527 * Creates a new HDB to the given file.
528 *
529 * @param file The database file to be created.
530 * @exception UnreachableStream If the given file exists already or cannot be
531 * created for another reason.
532 */
533void
534HDBManager::createNew(const std::string& file) {
535 if (!FileSystem::fileIsCreatable(file)) {
536 const string procName = "HDBManager::createNew";
537 throw UnreachableStream(__FILE__, __LINE__, procName);
538 }
539
540 try {
541 SQLite db;
542 RelationalDBConnection& connection = db.connect(file);
543
544 // create tables to the database
545 connection.DDLQuery(CQ_FU);
546 connection.DDLQuery(CQ_FU_ARCHITECTURE);
547 connection.DDLQuery(CQ_PIPELINE_RESOURCE);
550 connection.DDLQuery(CQ_IO_USAGE);
551 connection.DDLQuery(CQ_OPERATION);
552 connection.DDLQuery(CQ_FU_DATA_PORT);
553 connection.DDLQuery(CQ_IO_BINDING);
554 connection.DDLQuery(CQ_FU_IMPLEMENTATION);
555 connection.DDLQuery(CQ_OPCODE_MAP);
556 connection.DDLQuery(CQ_FU_PORT_MAP);
557 connection.DDLQuery(CQ_FU_EXTERNAL_PORT);
560 connection.DDLQuery(CQ_RF);
561 connection.DDLQuery(CQ_RF_ARCHITECTURE);
562 connection.DDLQuery(CQ_RF_IMPLEMENTATION);
564 connection.DDLQuery(CQ_RF_EXTERNAL_PORT);
566 connection.DDLQuery(CQ_RF_DATA_PORT);
567 connection.DDLQuery(CQ_FORMAT);
568 connection.DDLQuery(CQ_BUS);
569 connection.DDLQuery(CQ_SOCKET);
572 connection.DDLQuery(CQ_BLOCK_SOURCE_FILE);
573 connection.DDLQuery(CQ_RF_SOURCE_FILE);
574 connection.DDLQuery(CQ_FU_SOURCE_FILE);
578
579 // insert the contents to format table
580 insertFileFormats(connection);
581 db.close(connection);
582 } catch (const Exception& e) {
583 debugLog(
584 std::string("Initialization of HDB failed. ") +
585 e.errorMessage());
586 // this should not normally happen, but only if our table creation
587 // queries are broken, thus it's a program error and not input error
588 assert(false);
589 }
590}
591
592/**
593 * Returns the file name of the HDB managed by this HDBManager.
594 *
595 * @return Absolute path to the HDB file.
596 */
597std::string
601
602
603/**
604 * Add the given CostFunctionPlugin to the database.
605 *
606 * @param plugin The CostFunctionPlugin to add.
607 * @return ID of the plugin added.
608 * @exception Exception May throw InvalidData if the CostFunctionPlugin type
609 * is unknown.
610 */
611RowID
613 RowID pluginID;
614 try {
616
617 // insert into cost_function_plugin table
618 string description = plugin.description();
619 string pluginFilePath = plugin.pluginFilePath();
620 string type = "";
621 switch (plugin.type()) {
623 type = COST_PLUGIN_TYPE_FU;
624 break;
626 type = COST_PLUGIN_TYPE_RF;
627 break;
630 break;
633 break;
634 default:
635 InvalidData ex(
636 __FILE__, __LINE__, __func__,
637 (boost::format("Illegal cost_function_plugin type %d.") %
638 type).str());
639 throw ex;
640 break;
641 }
642 string name = plugin.name();
643
645 std::string(
646 "INSERT INTO cost_function_plugin(id,description,name,"
647 "plugin_file_path,type) VALUES"
648 "(NULL,\"" + description + "\",\"" + name + "\",\"" +
649 pluginFilePath + "\",\"" + type + "\");"));
650 pluginID = dbConnection_->lastInsertRowID();
652 } catch (const RelationalDBException& e) {
655 assert(false);
656 } catch (const Exception& e) {
659 assert(false);
660 }
661 return pluginID;
662}
663
664/**
665 * Removes the CostFunctionPlugin that has the given ID.
666 *
667 * @param pluginID ID of the cost plugin.
668 */
669void
671
672 try {
674
675 // remove from cost_function_plugin table
677 std::string(
678 "DELETE FROM cost_function_plugin "
679 "WHERE id=" + Conversion::toString(pluginID) + ";"));
681 std::string(
682 "DELETE FROM cost_estimation_data "
683 "WHERE plugin_reference=" +
684 Conversion::toString(pluginID) + ";"));
685
687 } catch (const Exception& e) {
690 assert(false);
691 }
692}
693
694
695/**
696 * Adds the given FU architecture to the database.
697 *
698 * @param arch The FU architecture to add.
699 * @return ID of the architecture added.
700 * @exception InvalidData If the FU architecture is invalid.
701 */
702RowID
704 // check the operand bindings of the FU
705 FunctionUnit& fu = arch.architecture();
707 FUValidator::checkOperations(fu, results);
709 if (results.errorCount() > 0) {
710 throw InvalidData(
711 __FILE__, __LINE__, __func__, results.error(0).second);
712 }
713
714 RowID archID;
715 std::map<FUPort*, RowID> portIDMap;
716
717 try {
719
720 // insert into fu_architecture table
722 std::string("INSERT INTO fu_architecture(id) VALUES(NULL);"));
723 archID = dbConnection_->lastInsertRowID();
724
725 // insert into fu_data_port table
726 for (int i = 0; i < fu.operationPortCount(); i++) {
727 FUPort* port = fu.operationPort(i);
728 string query(
729 "INSERT INTO fu_data_port(id,triggers,sets_opcode,"
730 "guard_support,width,fu_arch) "
731 "VALUES(NULL," +
732 Conversion::toString(port->isTriggering()) + "," +
735 + ",");
736 if (arch.hasParameterizedWidth(port->name())) {
737 query += "NULL,";
738 } else {
739 query += (Conversion::toString(port->width()) + ",");
740 }
741 query += (Conversion::toString(archID) + ");");
744 portIDMap.insert(std::pair<FUPort*, RowID>(port, portID));
745 }
746
747 // insert into operation table
748 for (int i = 0; i < fu.operationCount(); i++) {
749 HWOperation* operation = fu.operation(i);
750 if (!containsOperation(operation->name())) {
752 std::string(
753 "INSERT INTO operation(id,name) VALUES(NULL,\"" +
754 operation->name() + "\");"));
755 }
756 }
757
758 // insert into io_binding table
759 for (int i = 0; i < fu.operationCount(); i++) {
760 HWOperation* operation = fu.operation(i);
761 for (int i = 0; i < fu.operationPortCount(); i++) {
762 FUPort* port = fu.operationPort(i);
763 if (operation->isBound(*port)) {
764 int io = operation->io(*port);
765 string query(
766 "INSERT INTO io_binding(id,io_number,port,operation)"
767 " VALUES(NULL," + Conversion::toString(io) + "," +
769 MapTools::valueForKey<RowID>(portIDMap, port)) +
770 ",(SELECT id FROM operation WHERE "
771 "lower(name)=\"" + operation->name() + "\"));");
773 }
774 }
775 }
776
777 std::map<HWOperation*, RowID> pLineIDMap;
778
779 // insert into operation pipeline table
780 for (int i = 0; i < fu.operationCount(); i++) {
781 HWOperation* operation = fu.operation(i);
783 std::string(
784 "INSERT INTO operation_pipeline(id,fu_arch,operation) "
785 "VALUES(NULL," + Conversion::toString(archID) +
786 ",(SELECT id FROM operation WHERE lower(name)=\"" +
787 operation->name() + "\"));"));
788 pLineIDMap.insert(
789 std::pair<HWOperation*, RowID>(
790 operation, dbConnection_->lastInsertRowID()));
791 }
792
793 // insert into io_usage_table
794 for (int i = 0; i < fu.operationCount(); i++) {
795 HWOperation* operation = fu.operation(i);
796 ExecutionPipeline* pLine = operation->pipeline();
797 for (int cycle = 0; cycle < pLine->latency(); cycle++) {
798 ExecutionPipeline::OperandSet readOperands =
799 pLine->readOperands(cycle);
800 ExecutionPipeline::OperandSet writtenOperands =
801 pLine->writtenOperands(cycle);
802 for (ExecutionPipeline::OperandSet::const_iterator iter =
803 readOperands.begin();
804 iter != readOperands.end(); iter++) {
806 std::string(
807 "INSERT INTO io_usage(id,cycle,io_number,action,"
808 "pipeline) VALUES(NULL," +
809 Conversion::toString(cycle) + "," +
810 Conversion::toString(*iter) + "," +
814 pLineIDMap, operation)) + ");"));
815 }
816 for (ExecutionPipeline::OperandSet::const_iterator iter =
817 writtenOperands.begin();
818 iter != writtenOperands.end(); iter++) {
820 std::string(
821 "INSERT INTO io_usage(id,cycle,io_number,action,"
822 "pipeline) VALUES(NULL," +
823 Conversion::toString(cycle) + "," +
824 Conversion::toString(*iter) + "," +
828 pLineIDMap, operation)) + ");"));
829 }
830 }
831 }
832
833 // insert into pipeline_resource table
834 std::map<PipelineElement*, RowID> pipelineElementMap;
835 for (int i = 0; i < fu.pipelineElementCount(); i++) {
836 PipelineElement* element = fu.pipelineElement(i);
838 std::string(
839 "INSERT INTO pipeline_resource(id,fu_arch) VALUES "
840 "(NULL," + Conversion::toString(archID) + ");"));
841 pipelineElementMap.insert(
842 std::pair<PipelineElement*, RowID>(
843 element, dbConnection_->lastInsertRowID()));
844 }
845
846 // insert into pipeline_resource_usage table
847 for (int i = 0; i < fu.operationCount(); i++) {
848 HWOperation* operation = fu.operation(i);
849 ExecutionPipeline* pLine = operation->pipeline();
850 for (int i = 0; i < fu.pipelineElementCount(); i++) {
851 PipelineElement* element = fu.pipelineElement(i);
852 for (int cycle = 0; cycle < pLine->latency(); cycle++) {
853 if (pLine->isResourceUsed(element->name(), cycle)) {
854 string resID = Conversion::toString(
856 pipelineElementMap, element));
857 string pLineID = Conversion::toString(
859 pLineIDMap, operation));
861 std::string(
862 "INSERT INTO pipeline_resource_usage(id,"
863 "cycle,resource,pipeline) VALUES(NULL," +
864 Conversion::toString(cycle) + "," +
865 resID + "," + pLineID + ");"));
866 }
867 }
868 }
869 }
870
872
873 } catch (const Exception& e) {
876 assert(false);
877 }
878
879 return archID;
880}
881
882/**
883 * Tells whether the FU architecture that has the given ID can be removed
884 * from the database. It can be removed only if no FU entry uses it.
885 *
886 * @param archID ID of the FU architecture.
887 * @return True if the architecture can be removed, otherwise false.
888 */
889bool
891
892 // check whether the architecture is used by FU entries
893 try {
895 std::string(
896 "SELECT id FROM fu WHERE architecture=" +
897 Conversion::toString(archID) + ";"));
898 if (queryResult->hasNext()) {
899 // there is an FU entry using the architecture
900 delete queryResult;
901 return false;
902 } else {
903 delete queryResult;
904 return true;
905 }
906 } catch (const Exception& e) {
908 assert(false);
909 }
910
911 // dummy return to avoid compiler whining
912 assert(false);
913 return false;
914}
915
916
917/**
918 * Removes the FU architecture that has the given ID. The architecture is
919 * removed only it is not used by any FU entry. Otherwise an exception is
920 * thrown.
921 *
922 * @param archID ID of the FU architecture.
923 * @exception InvalidData If the architecture cannot be removed since it
924 * is used by some FU entry.
925 */
926void
928 if (!canRemoveFUArchitecture(archID)) {
929 throw InvalidData(__FILE__, __LINE__, __func__);
930 }
931
932 try {
934
935 // remove from io_binding table
937 std::string(
938 "DELETE FROM io_binding "
939 "WHERE port IN "
940 "(SELECT id "
941 "FROM fu_data_port "
942 "WHERE fu_arch=" + Conversion::toString(archID) + ");"));
943
944 // remove from fu_data_port table
946 std::string(
947 "DELETE FROM fu_data_port "
948 "WHERE fu_arch=" + Conversion::toString(archID) + ";"));
949
950 // remove from io_usage_table
952 std::string(
953 "DELETE FROM io_usage "
954 "WHERE pipeline IN "
955 "(SELECT id FROM operation_pipeline "
956 "WHERE fu_arch=" + Conversion::toString(archID) + ");"));
957
958 // remove from pipeline_resource_usage table
960 std::string(
961 "DELETE FROM pipeline_resource_usage "
962 "WHERE pipeline IN "
963 "(SELECT id FROM operation_pipeline "
964 "WHERE fu_arch=" + Conversion::toString(archID) + ");"));
965
966 // remove from pipeline_resource_table
968 std::string(
969 "DELETE FROM pipeline_resource "
970 "WHERE fu_arch=" + Conversion::toString(archID) + ";"));
971
972 // remove from operation_pipeline_table
974 std::string(
975 "DELETE FROM operation_pipeline "
976 "WHERE fu_arch=" + Conversion::toString(archID) + ";"));
977
978 // remove from fu_architecture table
980 std::string(
981 "DELETE FROM fu_architecture "
982 "WHERE id=" + Conversion::toString(archID) + ";"));
983
985
986 } catch (const Exception& e) {
989 assert(false);
990 }
991}
992
993/**
994 * Adds an empty FU entry to the database.
995 *
996 * @param entry The FU entry.
997 * @return ID of the added FU entry.
998 */
999RowID
1001 try {
1003 std::string("INSERT INTO fu(id) VALUES(NULL);"));
1005 } catch (const Exception& e) {
1007 assert(false);
1008 }
1009
1010 // dummy return to avoid compiler whining
1011 assert(false);
1012 return 0;
1013}
1014
1015
1016/**
1017 * Removes the FU entry that has the given ID from the database.
1018 *
1019 * The entry is removed entirely, meaning that all also FU implementation
1020 * and cost estimation data of that entry are removed.
1021 *
1022 * @param id The ID of the FU entry.
1023 */
1024void
1026
1027 if (!hasFUEntry(id)) {
1028 return;
1029 }
1030
1031 // remove implementation
1032 try {
1033 // get the ID of the implementation
1035 std::string(
1036 "SELECT id FROM fu_implementation "
1037 "WHERE fu=" + Conversion::toString(id) + ";"));
1038 if (result->hasNext()) {
1039 result->next();
1040 const DataObject& implIDData = result->data(0);
1041 int implID = implIDData.integerValue();
1042 removeFUImplementation(implID);
1043 }
1044 delete result;
1045 } catch (const Exception& e) {
1047 assert(false);
1048 }
1049
1050 // remove cost estimation data
1051 try {
1052 // get the IDs of cost estimation datas
1054 std::string(
1055 "SELECT id FROM cost_estimation_data "
1056 "WHERE fu_reference=" + Conversion::toString(id) + ";"));
1057 while (result->hasNext()) {
1058 result->next();
1059 const DataObject& costIDData = result->data(0);
1060 int dataID = costIDData.integerValue();
1062 }
1063 delete result;
1064 } catch (const Exception& e) {
1066 assert(false);
1067 }
1068
1069 // remove from fu table
1070 try {
1072 std::string(
1073 "DELETE FROM fu "
1074 "WHERE id=" + Conversion::toString(id) + ";"));
1075 } catch (const Exception& e) {
1077 assert(false);
1078 }
1079}
1080
1081
1082/**
1083 * Adds the implementation of the given FU entry to the database.
1084 *
1085 * In practice the implementation is added for the FU entry that has the
1086 * same ID as the given FUEntry instance. The given FUEntry instance must
1087 * also have an architecture similar to the architecture of the FU entry
1088 * in the database. This is required in port mapping.
1089 *
1090 * @param entry The FU entry containing the implementation to add.
1091 * @return ID of the implementation that was added.
1092 * @exception InvalidData If the given FUEntry instance is invalid or
1093 * if the FU entry does not have architecture in
1094 * the database of if the FU entry has an
1095 * implementation already.
1096 */
1097RowID
1099 if (!entry.hasID() || !entry.hasImplementation() ||
1100 !entry.hasArchitecture() || !hasFUEntry(entry.id())) {
1101 throw InvalidData(__FILE__, __LINE__, __func__);
1102 }
1103
1104 FUImplementation& impl = entry.implementation();
1105 FUArchitecture& arch = entry.architecture();
1106 FunctionUnit& fu = arch.architecture();
1107
1108 FUEntry* existingEntry = fuByEntryID(entry.id());
1109 if (existingEntry->hasImplementation() ||
1110 !existingEntry->hasArchitecture()) {
1111 delete existingEntry;
1112 throw InvalidData(__FILE__, __LINE__, __func__);
1113 }
1114 delete existingEntry;
1115 existingEntry = NULL;
1116
1117 RowID archID = fuArchitectureID(entry.id());
1118 RowID implID;
1119
1120 try {
1122
1123 // insert into fu_implementation table
1124 string module = impl.moduleName();
1125 string opcPort = impl.opcodePort();
1126 string clkPort = impl.clkPort();
1127 string rstPort = impl.rstPort();
1128 string glockPort = impl.glockPort();
1129 string glockReqPort = impl.glockReqPort();
1130
1132 std::string(
1133 "INSERT INTO fu_implementation(id,name,opcode_port,"
1134 "clk_port,rst_port,glock_port,glock_req_port,fu) VALUES"
1135 "(NULL,\"" + module + "\",\"" + opcPort + "\",\"" +
1136 clkPort + "\",\"" + rstPort + "\",\"" + glockPort + "\",\""
1137 + glockReqPort + "\"," + Conversion::toString(entry.id())
1138 + ");"));
1139 implID = dbConnection_->lastInsertRowID();
1140
1141 // insert into fu_port_map table
1142 for (int i = 0; i < impl.architecturePortCount(); i++) {
1143 FUPortImplementation& portImpl = impl.architecturePort(i);
1144 string name = portImpl.name();
1145 string widthFormula = portImpl.widthFormula();
1146 string loadPort = portImpl.loadPort();
1147 string guardPort = portImpl.guardPort();
1148 string archPortName = portImpl.architecturePort();
1149 if (!fu.hasOperationPort(archPortName)) {
1150 throw InvalidData(__FILE__, __LINE__, __func__);
1151 }
1152 FUPort* port = fu.operationPort(archPortName);
1153 bool portAdded = false;
1154 for (int j = 0; j < fu.operationCount(); j++) {
1155 HWOperation* operation = fu.operation(j);
1156 if (operation->isBound(*port)) {
1157 int io = operation->io(*port);
1158 // find the fu_data_port from DB
1160 std::string(
1161 "SELECT fu_data_port.id FROM fu_data_port,"
1162 "io_binding,operation WHERE "
1163 "fu_data_port.fu_arch=" +
1164 Conversion::toString(archID) +
1165 " AND io_binding.port=fu_data_port.id AND "
1166 "io_binding.io_number=" +
1168 " AND lower(operation.name)=\"" +
1169 operation->name() +
1170 "\" AND io_binding.operation=operation.id;"));
1171 if (!result->hasNext()) {
1172 delete result;
1173 throw InvalidData(__FILE__, __LINE__, __func__);
1174 }
1175 result->next();
1176 string portID = result->data(0).stringValue();
1177 delete result;
1178
1179 // update fu_port_map table
1181 std::string(
1182 "INSERT INTO fu_port_map(id,name,width_formula,"
1183 "load_port,guard_port,fu_impl,arch_port) VALUES"
1184 "(NULL,\"" + name + "\",\"" + widthFormula +
1185 "\",\"" + loadPort + "\",\"" + guardPort +
1186 "\"," + Conversion::toString(implID) + "," +
1187 portID + ");"));
1188 portAdded = true;
1189 break;
1190 }
1191 }
1192
1193 if (!portAdded) {
1194 throw InvalidData(__FILE__, __LINE__, __func__);
1195 }
1196 }
1197#ifdef ALLOW_OPCODE_EDITING
1198 // insert into opcode_map table
1199 for (int i = 0; i < fu.operationCount(); i++) {
1200 HWOperation* operation = fu.operation(i);
1201 if (!containsOperation(operation->name())) {
1202 format errorMsg(
1203 "FU implementation uses unknown operation %1%.");
1204 errorMsg % operation->name();
1205 throw InvalidData(
1206 __FILE__, __LINE__, __func__, errorMsg.str());
1207 }
1208 if (fu.operationCount() > 1 &&
1209 !impl.hasOpcode(operation->name())) {
1210 format errorMsg("Opcode not defined for operation %1%.");
1211 errorMsg % operation->name();
1212 throw InvalidData(
1213 __FILE__, __LINE__, __func__, errorMsg.str());
1214 }
1215 if (fu.operationCount() > 1) {
1216 int opcode = impl.opcode(operation->name());
1218 std::string(
1219 "INSERT INTO opcode_map(id,opcode,operation,fu_impl)"
1220 " VALUES(NULL," + Conversion::toString(opcode) +
1221 ",(SELECT id FROM operation WHERE lower(name)=\"" +
1222 operation->name() + "\")," +
1223 Conversion::toString(implID) + ");"));
1224 }
1225 }
1226#endif
1227 // insert into fu_external_port table
1228 for (int i = 0; i < impl.externalPortCount(); i++) {
1229 FUExternalPort& port = impl.externalPort(i);
1230 string direction = directionString(port.direction());
1232 std::string(
1233 "INSERT INTO fu_external_port(id,name,direction,"
1234 "width_formula,description,fu_impl) VALUES(NULL,\"" +
1235 port.name() + "\",\"" + direction + "\",\"" +
1236 port.widthFormula() + "\",\"" + port.description() +
1237 "\"," + Conversion::toString(implID) + ");"));
1238 }
1239
1240 // insert into fu_implementation_parameter table
1241 for (int i = 0; i < impl.parameterCount(); i++) {
1242 FUImplementation::Parameter param = impl.parameter(i);
1244 std::string(
1245 "INSERT INTO fu_implementation_parameter(id,name,type,"
1246 "value,fu_impl) VALUES(NULL,\"" + param.name +
1247 "\",\"" + param.type + "\",\"" + param.value +
1248 "\"," + Conversion::toString(implID) + ");"));
1249 }
1250
1251 // insert into fu_ext_port_parameter_dependency table
1252 for (int i = 0; i < impl.externalPortCount(); i++) {
1253 FUExternalPort& port = impl.externalPort(i);
1254 for (int i = 0; i < port.parameterDependencyCount(); i++) {
1255 string param = port.parameterDependency(i);
1257 std::string(
1258 "INSERT INTO fu_ext_port_parameter_dependency(id,"
1259 "port,parameter) VALUES(NULL,(SELECT id FROM "
1260 "fu_external_port WHERE fu_impl=" +
1261 Conversion::toString(implID) + " AND name=\"" +
1262 port.name() + "\"),(SELECT id FROM "
1263 "fu_implementation_parameter WHERE fu_impl=" +
1264 Conversion::toString(implID) + " AND name=\"" +
1265 param + "\"));"));
1266 }
1267 }
1268
1269 // insert into block_source_file table
1270 for (int i = 0; i < impl.implementationFileCount(); i++) {
1271 BlockImplementationFile& file = impl.file(i);
1273 }
1274
1275 // insert into fu_source_file table
1276 for (int i = 0; i < impl.implementationFileCount(); i++) {
1277 BlockImplementationFile& file = impl.file(i);
1278 string path = file.pathToFile();
1280 std::string(
1281 "INSERT INTO fu_source_file(id,fu_impl,file) "
1282 "VALUES(NULL," + Conversion::toString(implID) +
1283 ",(SELECT id FROM block_source_file WHERE file=\"" +
1284 path + "\"));"));
1285 }
1286
1288
1289 } catch (const RelationalDBException& e) {
1292 assert(false);
1293 } catch (const InvalidData& e) {
1295 throw;
1296 } catch (const Exception& e) {
1299 assert(false);
1300 }
1301
1302 return implID;
1303}
1304
1305/**
1306 * Removes the given FU implementation from the database.
1307 *
1308 * @param implID ID of the FU implementation.
1309 */
1310void
1312
1313 try {
1315
1316 // remove from fu_ext_port_parameter_dependency table
1318 std::string(
1319 "DELETE FROM fu_ext_port_parameter_dependency "
1320 "WHERE parameter in (SELECT ALL id FROM "
1321 "fu_implementation_parameter WHERE fu_impl="
1322 + Conversion::toString(implID) + ");"));
1323
1324 // remove from fu_external_port table
1326 std::string(
1327 "DELETE FROM fu_external_port "
1328 "WHERE fu_impl=" + Conversion::toString(implID) + ";"));
1329
1330 // remove from fu_port_map table
1332 std::string(
1333 "DELETE FROM fu_port_map "
1334 "WHERE fu_impl=" + Conversion::toString(implID) + ";"));
1335
1336 // remove from opcode_map table
1338 std::string(
1339 "DELETE FROM opcode_map "
1340 "WHERE fu_impl=" + Conversion::toString(implID) + ";"));
1341
1342 // remove from fu_implementation_parameter
1344 std::string(
1345 "DELETE FROM fu_implementation_parameter "
1346 "WHERE fu_impl=" + Conversion::toString(implID) + ";"));
1347
1348 // remove from fu_source_file
1350 std::string(
1351 "DELETE FROM fu_source_file "
1352 "WHERE fu_impl=" + Conversion::toString(implID) + ";"));
1353
1354 // remove from block_source_file
1356 std::string(
1357 "DELETE FROM block_source_file "
1358 "WHERE id NOT IN "
1359 "(SELECT file FROM fu_source_file UNION "
1360 "SELECT file FROM rf_source_file);"));
1361
1362 // remove from fu_implementation
1364 std::string(
1365 "DELETE FROM fu_implementation "
1366 "WHERE id=" + Conversion::toString(implID) + ";"));
1367
1369
1370 } catch (const Exception& e) {
1373 assert(false);
1374 }
1375}
1376
1377
1378/**
1379 * Sets the given architecture for the given FU entry.
1380 *
1381 * @param fuID ID of the FU entry.
1382 * @param archID ID of the FU architecture.
1383 * @exception InvalidData If the FU entry has an implementation already or
1384 * if the HDB does not have FU or architecture by the given ID.
1385 */
1386void
1388 if (!hasFUEntry(fuID) || !containsFUArchitecture(archID)) {
1389 throw InvalidData(__FILE__, __LINE__, __func__);
1390 }
1391
1392 FUEntry* entry = fuByEntryID(fuID);
1393 if (entry->hasImplementation()) {
1394 throw InvalidData(__FILE__, __LINE__, __func__);
1395 }
1396
1397 // set the architecture
1398 try {
1400 std::string(
1401 "UPDATE fu SET architecture=" +
1402 Conversion::toString(archID) + " WHERE id=" +
1403 Conversion::toString(fuID) + ";"));
1404 } catch (const Exception& e) {
1406 assert(false);
1407 }
1408}
1409
1410/**
1411 * Unsets the architecture of the given FU entry.
1412 *
1413 * @param fuID ID of the FU entry.
1414 * @exception InvalidData If the HDB does not contain the given FU entry
1415 * or if the FU entry has an implementation.
1416 */
1417void
1419 if (!hasFUEntry(fuID)) {
1420 throw InvalidData(__FILE__, __LINE__, __func__);
1421 }
1422
1423 FUEntry* entry = fuByEntryID(fuID);
1424 if (entry->hasImplementation()) {
1425 throw InvalidData(__FILE__, __LINE__, __func__);
1426 }
1427
1428 // unset the architecture
1429 try {
1431 std::string(
1432 "UPDATE fu SET architecture=NULL WHERE id=" +
1433 Conversion::toString(fuID)));
1434 } catch (const Exception& e) {
1436 assert(false);
1437 }
1438}
1439
1440/**
1441 * Adds the given RF architecture to the HDB.
1442 *
1443 * @param architecture The architecture to add.
1444 * @return ID of the architecture added.
1445 */
1446RowID
1448
1449 try {
1450 string query =
1451 "INSERT INTO rf_architecture(id,size,width,read_ports,"
1452 "write_ports,bidir_ports,latency,max_reads,max_writes,"
1453 "guard_support,guard_latency,zero_register) VALUES(NULL,";
1454 if (architecture.hasParameterizedSize()) {
1455 query += "NULL,";
1456 } else {
1457 query += (Conversion::toString(architecture.size()) + ",");
1458 }
1459 if (architecture.hasParameterizedWidth()) {
1460 query += "NULL,";
1461 } else {
1462 query += (Conversion::toString(architecture.width()) + ",");
1463 }
1464 query += (Conversion::toString(architecture.readPortCount()) + ",");
1465 query += (Conversion::toString(architecture.writePortCount()) + ",");
1466 query += (Conversion::toString(architecture.bidirPortCount()) + ",");
1467 query += (Conversion::toString(architecture.latency()) + ",");
1468 query += (Conversion::toString(architecture.maxReads()) + ",");
1469 query += (Conversion::toString(architecture.maxWrites()) + ",");
1470 query +=
1471 (Conversion::toString(architecture.hasGuardSupport()) + ",");
1472 query += (Conversion::toString(architecture.guardLatency()) + ",");
1473 query += (Conversion::toString(architecture.zeroRegister()));
1474 query += ");";
1475
1476 dbConnection_->updateQuery(query);
1477 } catch (const Exception& e) {
1479 assert(false);
1480 }
1481
1483}
1484
1485
1486/**
1487 * Tells whether the given RF architecture can be removed.
1488 *
1489 * The architecture can be removed if it is not used by any RF entry.
1490 *
1491 * @param archID ID of the RF architecture.
1492 */
1493bool
1495 try {
1497 std::string(
1498 "SELECT id FROM rf WHERE architecture=" +
1499 Conversion::toString(archID) + ";"));
1500 bool returnValue = !result->hasNext();
1501 delete result;
1502 return returnValue;
1503 } catch (const Exception& e) {
1505 assert(false);
1506 }
1507
1508 // dummy return to avoid compiler whining
1509 assert(false);
1510 return false;
1511}
1512
1513
1514/**
1515 * Removes the RF architecture that has the given ID.
1516 *
1517 * @param archID ID of the RF architecture.
1518 * @exception InvalidData If the RF architecture cannot be removed.
1519 */
1520void
1522 if (!canRemoveRFArchitecture(archID)) {
1523 throw InvalidData(__FILE__, __LINE__, __func__);
1524 }
1525
1526 try {
1528 std::string(
1529 "DELETE FROM rf_architecture WHERE id=" +
1530 Conversion::toString(archID) + ";"));
1531 } catch (const Exception& e) {
1533 assert(false);
1534 }
1535}
1536
1537/**
1538 * Adds an empty RF entry to the database.
1539 *
1540 * @return ID of the entry added.
1541 */
1542RowID
1544 try {
1546 std::string(
1547 "INSERT INTO rf(id,architecture,cost_function) "
1548 "VALUES(NULL,NULL,NULL);"));
1550 } catch (const Exception& e) {
1552 assert(false);
1553 }
1554
1555 // dummy return to avoid compiler whining
1556 assert(false);
1557 return 0;
1558}
1559
1560
1561/**
1562 * Removes the RF entry that has the given ID.
1563 *
1564 * Cost estimation data and implementation of the entry are removed too.
1565 *
1566 * @param id ID of the RF entry.
1567 */
1568void
1570
1571 if (!hasRFEntry(id)) {
1572 return;
1573 }
1574
1575 // remove from cost_estimation_data
1576 try {
1578 std::string(
1579 "DELETE FROM cost_estimation_data WHERE rf_reference=" +
1580 Conversion::toString(id) + ";"));
1581 } catch (const Exception& e) {
1583 assert(false);
1584 }
1585
1586 // remove implementation
1587 try {
1589 std::string(
1590 "SELECT id FROM rf_implementation WHERE rf=" +
1591 Conversion::toString(id) + ";"));
1592 if (result->hasNext()) {
1593 result->next();
1594 RowID implID = result->data(0).integerValue();
1595 removeRFImplementation(implID);
1596 }
1597 delete result;
1598 } catch (const Exception& e) {
1600 assert(false);
1601 }
1602
1603 // remove the entry
1604 try {
1606 std::string(
1607 "DELETE FROM rf WHERE id=" + Conversion::toString(id)
1608 + ";"));
1609 } catch (const Exception& e) {
1611 assert(false);
1612 }
1613}
1614
1615
1616/**
1617 * Adds an implementation for the the given RF entry.
1618 *
1619 * @param implementation The implementation to add.
1620 * @param rfEntryID ID of the RF entry.
1621 * @exception InvalidData If the RF entry has an implementation already or
1622 * if the database does not contain an RF entry
1623 * with the given ID.
1624 */
1625RowID
1627 const RFImplementation& implementation, RowID rfEntryID) {
1628 if (!hasRFEntry(rfEntryID)) {
1629 throw InvalidData(__FILE__, __LINE__, __func__);
1630 }
1631
1632 RFEntry* entry = rfByEntryID(rfEntryID);
1633 if (entry->hasImplementation()) {
1634 throw InvalidData(__FILE__, __LINE__, __func__);
1635 }
1636 delete entry;
1637 entry = NULL;
1638
1639 if(!hasColumn("rf_implementation", "sac_param")) {
1640 addBooleanColumn("rf_implementation", "sac_param");
1641 }
1642
1643 // Create tables for external ports, parameters and parameter dependecies
1644 // if needed.
1645 if (!dbConnection_->tableExistsInDB("rf_implementation_parameter")) {
1647 }
1648 if (!dbConnection_->tableExistsInDB("rf_external_port")) {
1650 }
1651 if (!dbConnection_->tableExistsInDB("rf_ext_port_parameter_dependency")) {
1653
1654 }
1655
1656 try {
1658
1659 int sacFlagAsInt = implementation.separateAddressCycleParameter();
1660
1661 // insert into rf_implementation table
1662 std::string insert_query(
1663 "INSERT INTO rf_implementation(id,name,size_param,"
1664 "width_param,clk_port,rst_port,glock_port,guard_port,sac_param,rf) "
1665 "VALUES(NULL,\"" + implementation.moduleName() + "\",\"" +
1666 implementation.sizeParameter() + "\",\"" +
1667 implementation.widthParameter() + "\",\"" +
1668 implementation.clkPort() + "\",\"" +
1669 implementation.rstPort() + "\",\"" +
1670 implementation.glockPort() + "\",\"" +
1671 implementation.guardPort() + "\"," +
1672 Conversion::toString(sacFlagAsInt) + "," +
1673 Conversion::toString(rfEntryID) + ");");
1674
1675 dbConnection_->updateQuery(insert_query);
1677
1678 // insert into rf_data_port table
1679 for (int i = 0; i < implementation.portCount(); i++) {
1680 RFPortImplementation& port = implementation.port(i);
1682 std::string(
1683 "INSERT INTO rf_data_port(id,name,direction,load_port,"
1684 "opcode_port,opcode_port_width_formula,rf_impl) "
1685 "VALUES(NULL,\"" + port.name() + "\",\"" +
1686 directionString(port.direction()) + "\",\"" +
1687 port.loadPort() + "\",\"" + port.opcodePort() + "\",\""
1688 + port.opcodePortWidthFormula() + "\"," +
1689 Conversion::toString(implID) + ");"));
1690 }
1691
1692 // insert into block_source_file table
1693 for (int i = 0; i < implementation.implementationFileCount(); i++) {
1696 }
1697
1698 // insert into rf_source_file table
1699 for (int i = 0; i < implementation.implementationFileCount(); i++) {
1701 string path = file.pathToFile();
1703 std::string(
1704 "INSERT INTO rf_source_file values(NULL, " +
1705 Conversion::toString(implID) +
1706 ", (SELECT id FROM block_source_file WHERE file=\"" +
1707 path + "\"));"));
1708 }
1709
1710 // insert into rf_external_port table
1711 for (int i = 0; i < implementation.externalPortCount(); i++) {
1712 RFExternalPort& port = implementation.externalPort(i);
1713 string direction = directionString(port.direction());
1715 std::string(
1716 "INSERT INTO rf_external_port(id,name,direction,"
1717 "width_formula,description,rf_impl) VALUES(NULL,\"" +
1718 port.name() + "\",\"" + direction + "\",\"" +
1719 port.widthFormula() + "\",\"" + port.description() +
1720 "\"," + Conversion::toString(implID) + ");"));
1721 }
1722
1723 // insert into rf_implementation_parameter table
1724 for (int i = 0; i < implementation.parameterCount(); i++) {
1725 RFImplementation::Parameter param = implementation.parameter(i);
1727 std::string(
1728 "INSERT INTO rf_implementation_parameter(id,name,type,"
1729 "value,rf_impl) VALUES(NULL,\"" + param.name +
1730 "\",\"" + param.type + "\",\"" + param.value +
1731 "\"," + Conversion::toString(implID) + ");"));
1732 }
1733
1734 // Insert implicit parameters to rf_implementation_parameter table
1735 // (size and width parameter references if not empty and parameters
1736 // for them do not exists).
1737 string widthParam = implementation.widthParameter();
1738 if (!widthParam.empty() && !implementation.hasParameter(widthParam)) {
1740 std::string(
1741 "INSERT INTO rf_implementation_parameter(id,name,type,"
1742 "value,rf_impl) VALUES(NULL,\"" + widthParam +
1743 "\", \"integer\", \"\"," +
1744 Conversion::toString(implID) + ");"));
1745 }
1746 string sizeParam = implementation.sizeParameter();
1747 if (!sizeParam.empty() && !implementation.hasParameter(sizeParam)) {
1749 std::string(
1750 "INSERT INTO rf_implementation_parameter(id,name,type,"
1751 "value,rf_impl) VALUES(NULL,\"" + sizeParam +
1752 "\", \"integer\", \"\"," +
1753 Conversion::toString(implID) + ");"));
1754 }
1755
1756 // insert into rf_ext_port_parameter_dependency table
1757 for (int i = 0; i < implementation.externalPortCount(); i++) {
1758 RFExternalPort& port = implementation.externalPort(i);
1759 for (int i = 0; i < port.parameterDependencyCount(); i++) {
1760 string param = port.parameterDependency(i);
1762 std::string(
1763 "INSERT INTO rf_ext_port_parameter_dependency(id,"
1764 "port,parameter) VALUES(NULL,(SELECT id FROM "
1765 "rf_external_port WHERE rf_impl=" +
1766 Conversion::toString(implID) + " AND name=\"" +
1767 port.name() + "\"),(SELECT id FROM "
1768 "rf_implementation_parameter WHERE rf_impl=" +
1769 Conversion::toString(implID) + " AND name=\"" +
1770 param + "\"));"));
1771 }
1772 }
1773
1775 return implID;
1776
1777 } catch (const Exception& e) {
1780 assert(false);
1781 }
1782
1783 // dummy return to avoid compiler whining
1784 assert(false);
1785 return 0;
1786}
1787
1788/**
1789 * Removes the RF implementation that has the given ID.
1790 *
1791 * @param implID ID of the RF implementation.
1792 */
1793void
1795
1796 bool dependencyTableExists =
1797 dbConnection_->tableExistsInDB("rf_ext_port_parameter_dependency");
1798 bool parameterTableExists =
1799 dbConnection_->tableExistsInDB("rf_implementation_parameter");
1800 bool externalPortTableExists =
1801 dbConnection_->tableExistsInDB("rf_external_port");
1802
1803 try {
1805
1806 // remove from rf_ext_port_parameter_dependency table if it exists
1807 // (backward compatibility for old HDBs).
1808 if (dependencyTableExists) {
1809 assert(parameterTableExists && externalPortTableExists);
1811 std::string(
1812 "DELETE FROM rf_ext_port_parameter_dependency "
1813 "WHERE parameter in (SELECT ALL id "
1814 "FROM rf_implementation_parameter WHERE rf_impl = " +
1815 Conversion::toString(implID) + ");"));
1816 }
1817
1818 // remove from rf_external_port table if it exists
1819 // (backward compatibility for old HDBs).
1820 if (externalPortTableExists) {
1822 std::string(
1823 "DELETE FROM rf_external_port "
1824 "WHERE rf_impl=" +
1825 Conversion::toString(implID) + ";"));
1826 }
1827
1828 // remove from rf_implementation_parameter table if it exists
1829 // (backward compatibility for old HDBs).
1830 if (parameterTableExists) {
1832 std::string(
1833 "DELETE FROM rf_implementation_parameter "
1834 "WHERE rf_impl=" + Conversion::toString(implID) + ";"));
1835 }
1836
1837 // remove from rf_source_file table
1839 std::string(
1840 "DELETE FROM rf_source_file WHERE rf_impl=" +
1841 Conversion::toString(implID) + ";"));
1842
1843 // remove from block_source_file table
1845 std::string(
1846 "DELETE FROM block_source_file WHERE id NOT IN "
1847 "(SELECT file FROM fu_source_file UNION "
1848 "SELECT file FROM rf_source_file);"));
1849
1850 // remove from rf_data_port
1852 std::string(
1853 "DELETE FROM rf_data_port WHERE rf_impl=" +
1854 Conversion::toString(implID) + ";"));
1855
1856 // remove from rf_implementation
1858 std::string(
1859 "DELETE FROM rf_implementation WHERE id=" +
1860 Conversion::toString(implID) + ";"));
1861
1863
1864 } catch (const Exception& e) {
1867 assert(false);
1868 }
1869}
1870
1871
1872/**
1873 * Sets architecture for an RF entry.
1874 *
1875 * @param rfID ID of the RF entry.
1876 * @param archID ID of the RF architecture to set.
1877 * @exception InvalidData If the database does not contain the given IDs or
1878 * if the RF entry has an architecture already.
1879 */
1880void
1882 if (!hasRFEntry(rfID)) {
1883 throw InvalidData(__FILE__, __LINE__, __func__);
1884 }
1885
1886 RFEntry* entry = rfByEntryID(rfID);
1887 if (entry->hasArchitecture()) {
1888 delete entry;
1889 throw InvalidData(__FILE__, __LINE__, __func__);
1890 }
1891 delete entry;
1892 entry = NULL;
1893
1894 if (!containsRFArchitecture(archID)) {
1895 throw InvalidData(__FILE__, __LINE__, __func__);
1896 }
1897
1898 try {
1900 std::string(
1901 "UPDATE rf SET architecture=" +
1902 Conversion::toString(archID) + " WHERE id=" +
1903 Conversion::toString(rfID) + ";"));
1904 } catch (const Exception& e) {
1906 assert(false);
1907 }
1908}
1909
1910/**
1911 * Unsets architecture of the given RF entry.
1912 *
1913 * @param rfID ID of the RF entry.
1914 */
1915void
1917 try {
1919 std::string(
1920 "UPDATE rf SET architecture=NULL WHERE id=" +
1921 Conversion::toString(rfID)));
1922 } catch (const Exception& e) {
1924 assert(false);
1925 }
1926}
1927
1928
1929/**
1930 * Sets the given cost function plugin for the given FU entry.
1931 *
1932 * @param fuID ID of the FU entry.
1933 * @param pluginID ID of the cost function plugin.
1934 */
1935void
1937
1938 // set the cost function plugin for fu
1939 try {
1941 std::string(
1942 "UPDATE fu SET cost_function=" +
1943 Conversion::toString(pluginID) + " WHERE id=" +
1944 Conversion::toString(fuID) + ";"));
1945 } catch (const Exception& e) {
1947 assert(false);
1948 }
1949}
1950
1951/**
1952 * Unsets cost function plugin of the given FU entry.
1953 *
1954 * @param fuID ID of the FU entry.
1955 */
1956void
1958
1959 // unset the cost function plugin
1960 try {
1962 std::string(
1963 "UPDATE fu SET cost_function=NULL WHERE id=" +
1964 Conversion::toString(fuID)));
1965 } catch (const Exception& e) {
1967 assert(false);
1968 }
1969}
1970
1971
1972/**
1973 * Sets the given cost function plugin for the given RF entry.
1974 *
1975 * @param rfID ID of the RF entry.
1976 * @param pluginID ID of the cost function plugin.
1977 */
1978void
1980
1981 // set the cost function plugin for rf
1982 try {
1984 std::string(
1985 "UPDATE rf SET cost_function=" +
1986 Conversion::toString(pluginID) + " WHERE id=" +
1987 Conversion::toString(rfID) + ";"));
1988 } catch (const Exception& e) {
1990 assert(false);
1991 }
1992}
1993
1994/**
1995 * Unsets cost function plugin of the given RF entry.
1996 *
1997 * @param rfID ID of the RF entry.
1998 */
1999void
2001
2002 // unset the cost function plugin
2003 try {
2005 std::string(
2006 "UPDATE rf SET cost_function=NULL WHERE id=" +
2007 Conversion::toString(rfID)));
2008 } catch (const Exception& e) {
2010 assert(false);
2011 }
2012}
2013
2014
2015/**
2016 * Returns a set of FU entry IDs in the database.
2017 *
2018 * @return A set containing all the FU entry IDs in the database.
2019 */
2020std::set<RowID>
2022
2023 string query = "SELECT id AS 'fu.id' FROM fu;";
2024
2025 // make the SQL query to obtain all the IDs
2026 RelationalDBQueryResult* queryResult = NULL;
2027 try {
2028 queryResult = dbConnection_->query(query);
2029 } catch (const Exception& e) {
2030 // should not throw in any case
2032 assert(false);
2033 }
2034
2035 std::set<RowID> idSet;
2036 while (queryResult->hasNext()) {
2037 queryResult->next();
2038 const DataObject& idData = queryResult->data("fu.id");
2039 idSet.insert(idData.integerValue());
2040 }
2041
2042 delete queryResult;
2043 return idSet;
2044}
2045
2046
2047/**
2048 * Returns a set of RF entry IDs in the database.
2049 *
2050 * @return A set containing all the RF entry IDs in the database.
2051 */
2052std::set<RowID>
2054
2055 string query = "SELECT id AS 'rf.id' FROM rf;";
2056
2057 // make the SQL query to obtain all the IDs
2058 RelationalDBQueryResult* queryResult = NULL;
2059 try {
2060 queryResult = dbConnection_->query(query);
2061 } catch (const Exception& e) {
2062 // should not throw in any case
2064 assert(false);
2065 }
2066
2067 std::set<RowID> idSet;
2068 while (queryResult->hasNext()) {
2069 queryResult->next();
2070 const DataObject& idData = queryResult->data("rf.id");
2071 idSet.insert(idData.integerValue());
2072 }
2073
2074 delete queryResult;
2075 return idSet;
2076}
2077
2078
2079/**
2080 * Returns a set of Bus entry IDs in the database.
2081 *
2082 * @return A set containing all the Bus entry IDs in the database.
2083 */
2084std::set<RowID>
2086
2087 string query = "SELECT id AS 'bus.id' FROM bus;";
2088
2089 // make the SQL query to obtain all the IDs
2090 RelationalDBQueryResult* queryResult = NULL;
2091 try {
2092 queryResult = dbConnection_->query(query);
2093 } catch (const Exception& e) {
2094 // should not throw in any case
2096 assert(false);
2097 }
2098
2099 std::set<RowID> idSet;
2100 while (queryResult->hasNext()) {
2101 queryResult->next();
2102 const DataObject& idData = queryResult->data("bus.id");
2103 idSet.insert(idData.integerValue());
2104 }
2105
2106 delete queryResult;
2107 return idSet;
2108}
2109
2110
2111/**
2112 * Returns a set of Socket entry IDs in the database.
2113 *
2114 * @return A set containing all the Socket entry IDs in the database.
2115 */
2116std::set<RowID>
2118
2119 string query = "SELECT id AS 'socket.id' FROM socket;";
2120
2121 // make the SQL query to obtain all the IDs
2122 RelationalDBQueryResult* queryResult = NULL;
2123 try {
2124 queryResult = dbConnection_->query(query);
2125 } catch (const Exception& e) {
2126 // should not throw in any case
2128 assert(false);
2129 }
2130
2131 std::set<RowID> idSet;
2132 while (queryResult->hasNext()) {
2133 queryResult->next();
2134 const DataObject& idData = queryResult->data("socket.id");
2135 idSet.insert(idData.integerValue());
2136 }
2137
2138 delete queryResult;
2139 return idSet;
2140}
2141
2142
2143/**
2144 * Returns a set of FU architecture IDs in the database.
2145 *
2146 * @return A set containing all the FU architecture IDs in the database.
2147 */
2148std::set<RowID>
2150
2151 RelationalDBQueryResult* result = NULL;
2152 try {
2153 result = dbConnection_->query(
2154 std::string("SELECT id FROM fu_architecture;"));
2155 } catch (const Exception& e) {
2157 assert(false);
2158 }
2159
2160 std::set<RowID> idSet;
2161 while (result->hasNext()) {
2162 result->next();
2163 const DataObject& idData = result->data(0);
2164 idSet.insert(idData.integerValue());
2165 }
2166
2167 delete result;
2168 return idSet;
2169}
2170
2171
2172/**
2173 * Returns a set of Operation Implementation Resource IDs in the database.
2174 *
2175 * @return A set containing all the Operation Implementation Resource
2176 * IDs in the database.
2177 */
2178std::set<RowID>
2180 RelationalDBQueryResult* result = NULL;
2181 try {
2182 result = dbConnection_->query(
2183 std::string("SELECT id FROM operation_implementation;"));
2184 } catch (const Exception& e) {
2186 assert(false);
2187 }
2188
2189 std::set<RowID> idSet;
2190 while (result->hasNext()) {
2191 result->next();
2192 const DataObject& idData = result->data(0);
2193 idSet.insert(idData.integerValue());
2194 }
2195
2196 delete result;
2197 return idSet;
2198}
2199
2200/**
2201 * Returns a set of Operation Implementation IDs in the database.
2202 *
2203 * @return A set containing all the Operation Implemnetation
2204 * IDs in the database.
2205 */
2206std::set<RowID>
2208 RelationalDBQueryResult* result = NULL;
2209 try {
2210 result = dbConnection_->query(
2211 std::string("SELECT id FROM operation_implementation_resource;"));
2212 } catch (const Exception& e) {
2214 assert(false);
2215 }
2216
2217 std::set<RowID> idSet;
2218 while (result->hasNext()) {
2219 result->next();
2220 const DataObject& idData = result->data(0);
2221 idSet.insert(idData.integerValue());
2222 }
2223
2224 delete result;
2225 return idSet;
2226}
2227
2228/**
2229 * Returns OperationImplementation.
2230 *
2231 * @return OperationImplementation.
2232 */
2235 RelationalDBQueryResult* result = nullptr;
2236 try {
2237 result = dbConnection_->query(
2238 std::string("SELECT * FROM operation_implementation WHERE id = ") +
2239 std::to_string(id) +
2240 std::string(";"));
2241 } catch (const Exception& e) {
2243 assert(false);
2244 }
2245
2247 if (result->hasNext()) {
2248 result->next();
2249
2250 retval.id = id;
2251 retval.latency = result->data("latency").integerValue();
2252 retval.name = result->data("name").stringValue();
2253 retval.postOpImplFileVhdl =
2254 result->data("post_op_vhdl").stringValue();
2255 retval.postOpImplFileVerilog =
2256 result->data("post_op_verilog").stringValue();
2257 retval.absBusDefFile =
2258 result->data("bus_definition").stringValue();
2259 retval.initialImplFileVerilog =
2260 result->data("initial_verilog").stringValue();
2261 retval.initialImplFileVhdl =
2262 result->data("initial_vhdl").stringValue();
2263 }
2264 delete result;
2265 result = nullptr;
2266
2267 try {
2268 result = dbConnection_->query(
2269 std::string("SELECT block_source_file.file "
2270 "FROM operation_implementation_source_file, "
2271 "block_source_file "
2272 "WHERE operation_implementation_source_"
2273 "file.operation = ") +
2274 std::to_string(id) +
2275 std::string(" AND operation_implementation_source_file.file = "
2276 " block_source_file.id"
2277 " AND block_source_file.format = "
2278 + std::to_string(
2280 ";"));
2281
2282 } catch (const Exception& e) {
2284 assert(false);
2285 }
2286 if (result->hasNext()) {
2287 result->next();
2288 retval.implFileVhdl = result->data("file").stringValue();
2289 }
2290 delete result;
2291 result = nullptr;
2292
2293 try {
2294 result = dbConnection_->query(
2295 std::string("SELECT block_source_file.file "
2296 "FROM operation_implementation_source_file, "
2297 "block_source_file "
2298 "WHERE operation_implementation_"
2299 "source_file.operation = ") +
2300 std::to_string(id) +
2301 std::string(" AND operation_implementation_source_file.file = "
2302 " block_source_file.id"
2303 " AND block_source_file.format = "
2304 + std::to_string(
2306 ";"));
2307
2308 } catch (const Exception& e) {
2310 assert(false);
2311 }
2312 if (result->hasNext()) {
2313 result->next();
2314 retval.implFileVerilog = result->data("file").stringValue();
2315 }
2316 delete result;
2317 result = nullptr;
2318
2319 std::string q1 = "SELECT resource, count "
2320 "FROM operation_implementation_resources "
2321 "WHERE operation_implementation_resources.operation = "
2322 + std::to_string(id) + ";";
2323 result = dbConnection_->query(q1);
2324 while (result->hasNext()) {
2325 result->next();
2326 int resource = result->data("resource").integerValue();
2329 r.count = result->data("count").integerValue();
2330 retval.resources.emplace_back(r);
2331 }
2332
2333 std::string q2 = "SELECT name, width, type, language "
2334 "FROM operation_implementation_variable "
2335 "WHERE CAST(operation as TEXT) = \"" + std::to_string(id) + "\";";
2336 result = dbConnection_->query(q2);
2337 while (result->hasNext()) {
2338 result->next();
2339 std::string name = result->data("name").stringValue();
2340 std::string width = result->data("width").stringValue();
2341 std::string type = result->data("type").stringValue();
2342 std::string lang = result->data("language").stringValue();
2343 // TODO not all HDBs have a rename column yet, so variable renaming is
2344 // hardcoded
2345 bool rename = true;
2346 // std::string renamestr = result->data("rename").stringValue();
2347 // bool rename = renamestr != "0";
2348 if (lang == "VHDL") {
2349 Variable var = {name, width, type, rename};
2350 retval.vhdlVariables.emplace_back(var);
2351 } else if (lang == "Verilog") {
2352 retval.verilogVariables.emplace_back(
2353 Variable{name, width, type, rename});
2354 } else {
2355 throw std::runtime_error("Unknown language");
2356 }
2357 }
2358
2360 "operation_implementation_globalsignal")) {
2361 std::string q3 =
2362 "SELECT name, width, type, language, rename "
2363 "FROM operation_implementation_globalsignal "
2364 "WHERE CAST(operation as TEXT) = \"" +
2365 std::to_string(id) + "\";";
2366 result = dbConnection_->query(q3);
2367 while (result->hasNext()) {
2368 result->next();
2369 std::string name = result->data("name").stringValue();
2370 std::string width = result->data("width").stringValue();
2371 std::string type = result->data("type").stringValue();
2372 std::string lang = result->data("language").stringValue();
2373 std::string renamestr = result->data("rename").stringValue();
2374 bool rename = renamestr != "0";
2375 if (lang == "VHDL") {
2376 Variable var = {name, width, type, rename};
2377 retval.vhdlGlobalSignals.emplace_back(var);
2378 } else if (lang == "Verilog") {
2379 retval.verilogGlobalSignals.emplace_back(
2380 Variable{name, width, type, rename});
2381 } else {
2382 throw std::runtime_error("Unknown language");
2383 }
2384 }
2385 }
2386
2387 return retval;
2388}
2389
2390/**
2391 * Returns OperationImplementationResource.
2392 *
2393 * @return OperationImplementationResource.
2394 */
2397 RelationalDBQueryResult* result = nullptr;
2398 try {
2399 result = dbConnection_->query(
2400 std::string("SELECT * FROM "
2401 "operation_implementation_resource WHERE id = ") +
2402 std::to_string(id) +
2403 std::string(";"));
2404 } catch (const Exception& e) {
2406 assert(false);
2407 }
2408
2410 if (result->hasNext()) {
2411 result->next();
2412
2413 retval.id = id;
2414 retval.name = result->data("name").stringValue();
2415 retval.ipxact = result->data("ipxact").stringValue();
2416 }
2417 delete result;
2418 result = nullptr;
2419
2420 try {
2421 result = dbConnection_->query(
2422 std::string("SELECT block_source_file.file, "
2423 "format.format "
2424 "FROM operation_implementation_resource_"
2425 "source_file, block_source_file, "
2426 "format "
2427 "WHERE operation_implementation_resource_"
2428 "source_file.resource = ") +
2429 std::to_string(id) +
2430 std::string(" AND operation_implementation_resource_"
2431 "source_file.file = "
2432 " block_source_file.id "
2433 "AND block_source_file.format = "
2434 "format.id;"
2435 ));
2436
2437 } catch (const Exception& e) {
2439 assert(false);
2440 }
2441 while (result->hasNext()) {
2442 result->next();
2443 std::string format = result->data("format").stringValue();
2444 if (format == VHDL_FORMAT) {
2445 retval.synFiles.push_back(result->data("file").stringValue());
2446 retval.synFormats.push_back(format);
2447 } else if (format == VHDL_SIM_FORMAT) {
2448 retval.simFiles.push_back(result->data("file").stringValue());
2449 retval.simFormats.push_back(format);
2450 } else if (format == VERILOG_FORMAT) {
2451 retval.synFiles.push_back(result->data("file").stringValue());
2452 retval.synFormats.push_back(format);
2453 } else if (format == VERILOG_SIM_FORMAT) {
2454 retval.simFiles.push_back(result->data("file").stringValue());
2455 retval.simFormats.push_back(format);
2456 }
2457 }
2458 delete result;
2459 result = nullptr;
2460
2461 return retval;
2462}
2463
2464/**
2465 * Add addOperationImplementationResource to the DB.
2466 */
2467void
2469 const OperationImplementationResource& resource) {
2470
2472 std::string(
2473 "INSERT INTO operation_implementation_resource(id,name,ipxact) "
2474 "VALUES (NULL, \"" +
2475 resource.name +"\", \"" + resource.ipxact+ "\");"));
2476 RowID resourceID = dbConnection_->lastInsertRowID();
2477
2478 auto t = resource.simFormats.begin();
2479 auto f = resource.simFiles.begin();
2480 for (; f != resource.simFiles.end(); ++f, ++t) {
2481 int type = fileFormat(*t) + 1;
2482
2484 std::string(
2485 "INSERT INTO block_source_file(id,file,format) "
2486 "VALUES (NULL, \"" + *f + "\","
2487 + std::to_string(type) +
2488 ");"));
2490
2492 std::string(
2493 "INSERT INTO operation_implementation_resource_source_file"
2494 "(id,resource,file) "
2495 "VALUES (NULL, " + std::to_string(resourceID) + ", "
2496 + std::to_string(fileID) +
2497 ");"));
2498 }
2499
2500 auto st = resource.synFormats.begin();
2501 auto sf = resource.synFiles.begin();
2502 for (; sf != resource.synFiles.end(); ++sf, ++st) {
2503 int type = fileFormat(*st) + 1;
2504
2506 std::string(
2507 "INSERT INTO block_source_file(id,file,format) "
2508 "VALUES (NULL, \"" + *sf + "\","
2509 + std::to_string(type) +
2510 ");"));
2512
2514 std::string(
2515 "INSERT INTO operation_implementation_resource_source_file"
2516 "(id,resource,file) "
2517 "VALUES (NULL, " + std::to_string(resourceID) + ", "
2518 + std::to_string(fileID) +
2519 ");"));
2520 }
2521}
2522
2523/**
2524 * Add addOperationImplementation to the DB.
2525 */
2526void
2528 const OperationImplementation& operation) {
2529
2530
2531 std::string i1 = "INSERT INTO operation_implementation(id,name,latency,"
2532 "post_op_vhdl,post_op_verilog,bus_definition,"
2533 "initial_vhdl,initial_verilog) "
2534 "VALUES (NULL,\"" + operation.name + "\","
2535 + std::to_string(operation.latency) + ","
2536 "\"" + operation.postOpImplFileVhdl + "\","
2537 "\"" + operation.postOpImplFileVerilog + "\","
2538 "\"" + operation.absBusDefFile + "\","
2539 "\"" + operation.initialImplFileVhdl + "\","
2540 "\"" + operation.initialImplFileVerilog +
2541 "\");";
2544
2545 for (const auto r : operation.resources) {
2546 std::string i2 = "INSERT INTO operation_implementation_resources("
2547 "id, operation, resource, count) "
2548 "VALUES (NULL, " + std::to_string(newid)
2549 + ", " + std::to_string(r.id)
2550 + ", " + std::to_string(r.count)
2551 + ");";
2553 }
2554
2555 for (const auto r : operation.vhdlVariables) {
2556 std::string i2 = "INSERT INTO operation_implementation_variable("
2557 "id, operation, name, width, type, language) "
2558 "VALUES (NULL, " + std::to_string(newid)
2559 + ", \"" + r.name + "\""
2560 + ", \"" + r.width + "\""
2561 + ", \"" + r.type + "\""
2562 + ", \"VHDL\");";
2564 }
2565
2566 for (const auto r : operation.verilogVariables) {
2567 std::string i2 = "INSERT INTO operation_implementation_variable("
2568 "id, operation, name, width, type, language) "
2569 "VALUES (NULL, " + std::to_string(newid)
2570 + ", \"" + r.name + "\""
2571 + ", \"" + r.width + "\""
2572 + ", \"" + r.type + "\""
2573 + ", \"Verilog\");";
2575 }
2576
2577 std::string i3 = "INSERT INTO block_source_file(id,file,format) "
2578 "VALUES (NULL,\"" + operation.implFileVhdl +
2579 "\", " + std::to_string(BlockImplementationFile::VHDL) + ");";
2582
2583 std::string i4 = "INSERT INTO "
2584 "operation_implementation_source_file(id, operation, file) "
2585 "VALUES (NULL, " + std::to_string(newid) +
2586 ", " + std::to_string(vhdl) +
2587 ");";
2589
2590 std::string i5 = "INSERT INTO block_source_file(id,file,format) "
2591 "VALUES (NULL,\"" + operation.implFileVerilog +
2592 "\", " + std::to_string(BlockImplementationFile::Verilog) + ");";
2594 RowID verilog = dbConnection_->lastInsertRowID();
2595
2596 std::string i6 = "INSERT INTO "
2597 "operation_implementation_source_file(id, operation, file) "
2598 "VALUES (NULL, " + std::to_string(newid) +
2599 ", " + std::to_string(verilog) +
2600 ");";
2602}
2603
2604/**
2605 * Remove Operation Implemententation from DB.
2606 */
2607void
2609 std::string d1 = "DELETE FROM operation_implementation "
2610 "WHERE id = " + std::to_string(id) + ";";
2611 std::string d2 =
2612 "DELETE FROM operation_implementation_source_file "
2613 "WHERE operation = " + std::to_string(id) + ";";
2614 std::string d3 =
2615 "DELETE FROM operation_implementation_resources "
2616 "WHERE operation = " + std::to_string(id) + ";";
2617 std::string d4 =
2618 "DELETE FROM operation_implementation_variable "
2619 "WHERE operation = " + std::to_string(id) + ";";
2620 std::string s1 = "SELECT file FROM "
2621 "operation_implementation_source_file "
2622 "WHERE operation = " + std::to_string(id) + ";";
2623
2625 while (result->hasNext()) {
2626 result->next();
2627 int file_id = result->data(0).integerValue();
2628 std::string d3lete = "DELETE FROM block_source_file "
2629 "WHERE id = " + std::to_string(file_id) + ";";
2630 dbConnection_->updateQuery(d3lete);
2631 }
2632
2637 delete result;
2638}
2639
2640/**
2641 * Remove Operation Implemententation Resource from DB.
2642 */
2643void
2645 std::string d1 = "DELETE FROM operation_implementation_resource "
2646 "WHERE id = " + std::to_string(id) + ";";
2647 std::string d2 =
2648 "DELETE FROM operation_implementation_resource_source_file "
2649 "WHERE resource = " + std::to_string(id) + ";";
2650 std::string s1 = "SELECT file FROM "
2651 "operation_implementation_resource_source_file "
2652 "WHERE resource = " + std::to_string(id) + ";";
2653
2655 while (result->hasNext()) {
2656 result->next();
2657 int file_id = result->data(0).integerValue();
2658 std::string d3 = "DELETE FROM block_source_file "
2659 "WHERE id = " + std::to_string(file_id) + ";";
2661 }
2662
2665 delete result;
2666}
2667
2668
2669std::set<RowID>
2671 const std::set<std::string>& operationNames) const {
2672
2673 RelationalDBQueryResult* result = NULL;
2674 try {
2675 std::string operationQuery = "(";
2676 std::set<string>::const_iterator iter = operationNames.begin();
2677 while (iter != operationNames.end()) {
2678 // LIKE makes case-insensitive match to operation names
2679 operationQuery +=
2680 "operation.name LIKE '" + *iter + "'";
2681 iter++;
2682 if (iter != operationNames.end()) {
2683 operationQuery += " OR ";
2684 }
2685 }
2686 operationQuery += ")";
2687 if (operationQuery == "()") {
2688 return std::set<RowID>();
2689 }
2690 result = dbConnection_->query(
2691 std::string("SELECT fu_architecture.id FROM operation_pipeline,"
2692 "operation, fu_architecture WHERE "
2693 "operation.id=operation_pipeline.operation AND "
2694 "operation_pipeline.fu_arch=fu_architecture.id AND "
2695 + operationQuery +
2696 "GROUP BY fu_architecture.id ORDER BY "
2697 "fu_architecture.id;"));
2698 } catch (const Exception& e) {
2699 std::string eMsg = ", HDB file where error occurred was: " + hdbFile_;
2700 debugLog(e.errorMessage() + eMsg);
2701 assert(false);
2702 }
2703
2704 std::set<RowID> idSet;
2705 while (result->hasNext()) {
2706 result->next();
2707 const DataObject& idData = result->data(0);
2708 idSet.insert(idData.integerValue());
2709 }
2710
2711 delete result;
2712 return idSet;
2713}
2714/**
2715 * Returns a set of RF architecture IDs in the database.
2716 *
2717 * @return A set containing all the RF architecture IDs in the database.
2718 */
2719std::set<RowID>
2721
2722 RelationalDBQueryResult* result = NULL;
2723 try {
2724 result = dbConnection_->query(
2725 std::string("SELECT id FROM rf_architecture;"));
2726 } catch (const Exception& e) {
2728 assert(false);
2729 }
2730
2731 std::set<RowID> idSet;
2732 while (result->hasNext()) {
2733 result->next();
2734 const DataObject& idData = result->data(0);
2735 idSet.insert(idData.integerValue());
2736 }
2737
2738 delete result;
2739 return idSet;
2740}
2741
2742
2743/**
2744 * Returns the ID of the FU entry that has the given implementation ID.
2745 *
2746 * @param implID The implementation ID.
2747 * @return The FU entry ID.
2748 * @exception KeyNotFound If there is no implementation by the given ID.
2749 */
2750RowID
2752 RelationalDBQueryResult* result = NULL;
2753 try {
2754 result = dbConnection_->query(
2755 std::string(
2756 "SELECT fu from fu_implementation WHERE id=" +
2757 Conversion::toString(implID) + ";"));
2758 } catch (const Exception& e) {
2760 assert(false);
2761 }
2762
2763 if (result->hasNext()) {
2764 result->next();
2765 RowID id = result->data(0).integerValue();
2766 delete result;
2767 return id;
2768 } else {
2769 delete result;
2770 throw KeyNotFound(__FILE__, __LINE__, __func__);
2771 }
2772}
2773
2774/**
2775 * Returns the ID of the RF entry that has the given implementation ID.
2776 *
2777 * @param implID The implementation ID.
2778 * @return The RF entry ID.
2779 * @exception KeyNotFound If there is no implementation by the given ID.
2780 */
2781RowID
2783 RelationalDBQueryResult* result = NULL;
2784 try {
2785 result = dbConnection_->query(
2786 std::string(
2787 "SELECT rf from rf_implementation WHERE id=" +
2788 Conversion::toString(implID) + ";"));
2789 } catch (const Exception& e) {
2791 assert(false);
2792 }
2793
2794 if (result->hasNext()) {
2795 result->next();
2796 RowID id = result->data(0).integerValue();
2797 delete result;
2798 return id;
2799 } else {
2800 delete result;
2801 throw KeyNotFound(__FILE__, __LINE__, __func__);
2802 }
2803}
2804
2805/**
2806 * Returns the FU entry that has the given ID.
2807 *
2808 * @param id The ID of the FU entry.
2809 * @return The FU entry.
2810 * @excpetion KeyNotFound If the HDB does not contain an FU entry with the
2811 * given ID.
2812 */
2813FUEntry*
2815 std::string query = "SELECT architecture FROM fu WHERE id=";
2816 query += Conversion::toString(id) + ";";
2817
2818 RelationalDBQueryResult* result = NULL;
2819 try {
2820 result = dbConnection_->query(query);
2821 } catch (const Exception& e) {
2823 assert(false);
2824 }
2825
2826 bool hasArch = false;
2827 RowID archID = -1;
2828 if (result->hasNext()) {
2829 result->next();
2830 DataObject data = result->data(0);
2831 if (!data.isNull()) {
2832 hasArch = true;
2833 archID = data.integerValue();
2834 }
2835 delete result;
2836 result = NULL;
2837 } else {
2838 delete result;
2839 std::ostringstream stream;
2840 stream << "FU entry with id " << id << " not found from hdb "
2841 << hdbFile_;
2842 throw KeyNotFound(__FILE__, __LINE__, __func__, stream.str());
2843 }
2844
2845 FUEntry* entry = new FUEntry();
2846 entry->setID(id);
2847 if (hasArch) {
2848 FUArchitecture* architecture = fuArchitectureByID(archID);
2849 entry->setArchitecture(architecture);
2851 *architecture, id);
2853 }
2854
2855 CostFunctionPlugin* costFunction = createCostFunctionOfFU(id);
2856 entry->setCostFunction(costFunction);
2857 entry->setHDBFile(hdbFile_);
2858 delete result;
2859 return entry;
2860}
2861
2862/**
2863 * Returns the RF entry that has the given ID.
2864 *
2865 * @param id The ID of the RF entry.
2866 * @return The RF entry.
2867 * @exception KeyNotFound If the HDB does not contain an RF entry with the
2868 * given ID.
2869 */
2870RFEntry*
2872 std::string query = "SELECT architecture FROM rf WHERE id=";
2873 query += Conversion::toString(id) + ";";
2874
2875 RelationalDBQueryResult* result = NULL;
2876 try {
2877 result = dbConnection_->query(query);
2878 } catch (const Exception& e) {
2879 debugLog(e.errorMessage());
2880 assert(false);
2881 }
2882
2883 bool hasArch = false;
2884 RowID archID = -1;
2885 if (result->hasNext()) {
2886 result->next();
2887 DataObject data = result->data(0);
2888 if (!data.isNull()) {
2889 hasArch = true;
2890 archID = data.integerValue();
2891 }
2892 delete result;
2893 result = NULL;
2894 } else {
2895 delete result;
2896 throw KeyNotFound(__FILE__, __LINE__, __func__);
2897 }
2898
2899 RFEntry* entry = new RFEntry();
2900 entry->setID(id);
2901 if (hasArch) {
2902 RFArchitecture* architecture = rfArchitectureByID(archID);
2903 entry->setArchitecture(architecture);
2904 }
2905
2907 CostFunctionPlugin* costFunction = createCostFunctionOfRF(id);
2909 entry->setCostFunction(costFunction);
2910 entry->setHDBFile(hdbFile_);
2911 delete result;
2912
2913 return entry;
2914}
2915
2916/**
2917 * Creates an FUArchitecture instance of the FU architecture that has the
2918 * given ID.
2919 *
2920 * @param ID The ID of the FU architecture.
2921 * @return The newly created FUArchitecture instance.
2922 * @exception KeyNotFound If the HDB does not have a FU architecture with the
2923 * given ID.
2924 */
2927 if (!containsFUArchitecture(id)) {
2928 throw KeyNotFound(__FILE__, __LINE__, __func__);
2929 }
2930
2931 FunctionUnit* fu = new FunctionUnit("name");
2932 FUArchitecture* architecture = new FUArchitecture(fu);
2933 architecture->setID(id);
2934 addPortsAndBindingsToFUArchitecture(*architecture, id);
2935 addOperationPipelinesToFUArchitecture(*architecture, id);
2936 return architecture;
2937}
2938
2939/**
2940 * Creates an RFArchitecture instance of the RF architecture that has the
2941 * given ID.
2942 *
2943 * @param id The ID of the RF architecture.
2944 * @return The newly created RFArchitecture instance.
2945 * @exception KeyNotFound If the HDB does not contain RF architecture with the
2946 * given ID.
2947 */
2950 if (!containsRFArchitecture(id)) {
2951 throw KeyNotFound(__FILE__, __LINE__, __func__);
2952 }
2953
2954 RelationalDBQueryResult* architectureData;
2955 try {
2956 architectureData = dbConnection_->query(rfArchitectureByIDQuery(id));
2957 } catch (const Exception& e) {
2959 assert(false);
2960 }
2961
2962 int sizeColumn = architectureData->column("size");
2963 int widthColumn = architectureData->column("width");
2964 int readPortsColumn = architectureData->column("read_ports");
2965 int writePortsColumn = architectureData->column("write_ports");
2966 int bidirPortsColumn = architectureData->column("bidir_ports");
2967 int latencyColumn = architectureData->column("latency");
2968 int maxReadsColumn = architectureData->column("max_reads");
2969 int maxWritesColumn = architectureData->column("max_writes");
2970 int guardSupportColumn = architectureData->column("guard_support");
2971 int guardLatencyColumn = architectureData->column("guard_latency");
2972 int zeroRegisterColumn = architectureData->column("zero_register");
2973
2974 assert(architectureData->hasNext());
2975 architectureData->next();
2976 assert(!architectureData->hasNext());
2977 const DataObject& sizeData = architectureData->data(sizeColumn);
2978 const DataObject& widthData = architectureData->data(widthColumn);
2979 const DataObject& readPortsData = architectureData->data(
2980 readPortsColumn);
2981 const DataObject& writePortsData = architectureData->data(
2982 writePortsColumn);
2983 const DataObject& bidirPortsData = architectureData->data(
2984 bidirPortsColumn);
2985 const DataObject& latencyData = architectureData->data(
2986 latencyColumn);
2987 const DataObject& maxReadsData = architectureData->data(
2988 maxReadsColumn);
2989 const DataObject& maxWritesData = architectureData->data(
2990 maxWritesColumn);
2991 const DataObject& guardSupportData = architectureData->data(
2992 guardSupportColumn);
2993 const DataObject& guardLatencyData = architectureData->data(
2994 guardLatencyColumn);
2995 const DataObject& zeroRegisterData = architectureData->data(
2996 zeroRegisterColumn);
2997 RFArchitecture* architecture = new RFArchitecture(
2998 readPortsData.integerValue(), writePortsData.integerValue(),
2999 bidirPortsData.integerValue(), maxReadsData.integerValue(),
3000 maxWritesData.integerValue(), latencyData.integerValue(),
3001 guardSupportData.boolValue(), guardLatencyData.integerValue(),
3002 zeroRegisterData.boolValue());
3003 std::cout.flush();
3004 architecture->setID(id);
3005 if (!sizeData.isNull()) {
3006 architecture->setSize(sizeData.integerValue());
3007 }
3008 if (!widthData.isNull()) {
3009 architecture->setWidth(widthData.integerValue());
3010 }
3011 delete architectureData;
3012 return architecture;
3013}
3014
3015/**
3016 * Returns a set of FU entry IDs that have a corresponding architecture
3017 * with the given one.
3018 *
3019 * The set may contain FU entry IDs that have ports with parametrized
3020 * width while the given one has fixed width.
3021 *
3022 * @param fu The FU architecture.
3023 * @return Set of FU entry IDs.
3024 */
3025std::set<RowID>
3027 const TTAMachine::FunctionUnit& fu) const {
3028
3029 std::set<RowID> architectureIDs;
3030 std::set<RowID> entryIDs;
3031
3032 try {
3033 // get FU architectures with required operation set
3034 string query = "";
3035 for (int i = 0; i < fu.operationCount(); i++) {
3036 query +=
3037 "SELECT fu_arch FROM operation_pipeline,operation "
3038 "WHERE operation.name=\"" + fu.operation(i)->name() +
3039 "\" AND operation_pipeline.operation=operation.id";
3040 if (i+1 < fu.operationCount()) {
3041 query += " INTERSECT ";
3042 } else {
3043 query += ";";
3044 }
3045 }
3046
3047 RelationalDBQueryResult* queryResult = dbConnection_->query(query);
3048
3049 // check the architectures are compeletely similar
3050 while (queryResult->hasNext()) {
3051 queryResult->next();
3052 const DataObject& archID = queryResult->data(0);
3054 if (isMatchingArchitecture(fu, *arch)) {
3055 architectureIDs.insert(arch->id());
3056 }
3057 delete arch;
3058 }
3059
3060 delete queryResult;
3061
3062 if (!architectureIDs.empty()) {
3063 // find the FU entry IDs
3064 string fuEntryQuery = "SELECT id FROM fu WHERE ";
3065 for (std::set<RowID>::const_iterator iter =
3066 architectureIDs.begin();
3067 iter != architectureIDs.end(); iter++) {
3068 fuEntryQuery += "architecture=" +
3069 Conversion::toString(*iter);
3070 std::set<RowID>::const_iterator nextIter = iter;
3071 nextIter++;
3072 if (nextIter == architectureIDs.end()) {
3073 fuEntryQuery += ";";
3074 } else {
3075 fuEntryQuery += " OR ";
3076 }
3077 }
3078
3080 fuEntryQuery);
3081 while (fuEntryResult->hasNext()) {
3082 fuEntryResult->next();
3083 const DataObject& idData = fuEntryResult->data(0);
3084 entryIDs.insert(idData.integerValue());
3085 }
3086
3087 delete fuEntryResult;
3088 }
3089
3090 } catch (const Exception& e) {
3092 ;
3093 }
3094
3095 return entryIDs;
3096}
3097
3098
3099/**
3100 * Returns a set of RF entry IDs that have the described architecture.
3101 *
3102 * In case that size or width is given as a parameter are also the RF entries
3103 * with a parameterized width or size returned as are the entries with matched
3104 * width and/or size.
3105 *
3106 * @param readPorts The number of read ports.
3107 * @param writePorts The number of write ports.
3108 * @param bidirPorts The number of bidirectional ports.
3109 * @param maxRead The (minimum) max reads value.
3110 * @param latency The exact latency.
3111 * @param guardSupport Guard support.
3112 * @param guardLatency The guard latency.
3113 * @param width The bit withd of the register file.
3114 * @param size The number of registers in the register file.
3115 * @param zeroRegister zero register of the register file
3116 * @return Set of RF entry IDs.
3117 */
3118std::set<RowID>
3120 int readPorts,
3121 int writePorts,
3122 int bidirPorts,
3123 int maxReads,
3124 int maxWrites,
3125 int latency,
3126 bool guardSupport,
3127 int guardLatency,
3128 int width,
3129 int size,
3130 bool zeroRegister) const {
3131
3132 RelationalDBQueryResult* result = NULL;
3133 try {
3134 string query = "SELECT rf.id FROM rf,rf_architecture "
3135 "WHERE rf_architecture.read_ports=" +
3136 Conversion::toString(readPorts) +
3137 " AND rf_architecture.write_ports=" +
3138 Conversion::toString(writePorts) +
3139 " AND rf_architecture.bidir_ports=" +
3140 Conversion::toString(bidirPorts) +
3141 " AND rf_architecture.max_reads>=" +
3142 Conversion::toString(maxReads) +
3143 " AND rf_architecture.max_writes>=" +
3144 Conversion::toString(maxWrites) +
3145 " AND rf_architecture.latency=" +
3146 Conversion::toString(latency);
3147 if (guardSupport) {
3148 query += " AND rf_architecture.guard_support=" +
3149 Conversion::toString(guardSupport) +
3150 " AND rf_architecture.guard_latency=" +
3151 Conversion::toString(guardLatency);
3152 }
3153 if (size != 0) {
3154 query += " AND (rf_architecture.size=" +
3155 Conversion::toString(size) +
3156 " OR rf_architecture.size is NULL)";
3157 }
3158 if (width != 0) {
3159 query += " AND (rf_architecture.width=" +
3160 Conversion::toString(width) +
3161 " OR rf_architecture.width is NULL)";
3162 }
3163 query += " AND (rf_architecture.zero_register=" +
3164 Conversion::toString(zeroRegister);
3165 if (!zeroRegister) {
3166 query += " OR rf_architecture.zero_register is NULL";
3167 }
3168 query += ")";
3169 query += " AND rf.architecture=rf_architecture.id;";
3170 result = dbConnection_->query(query);
3171 } catch (const Exception& e) {
3173 ;
3174 }
3175
3176 std::set<RowID> entryIDs;
3177 while (result->hasNext()) {
3178 result->next();
3179 entryIDs.insert(result->data(0).integerValue());
3180 }
3181 delete result;
3182
3183 return entryIDs;
3184}
3185
3186
3187/**
3188 * Adds the given cost estimation data values to given FU entry.
3189 *
3190 * @param fuID The ID of the FU entry the cost data will be added.
3191 * @valueName The name of the cost value.
3192 * @value The cost value.
3193 * @pluginID The ID of the cost function plugin that owns this data.
3194 */
3195RowID
3197 RowID fuID,
3198 const std::string& valueName,
3199 const std::string& value,
3200 RowID pluginID) const {
3201
3202
3203 RowID dataID;
3204
3205 // add the data
3206 try {
3208 std::string(
3209 "INSERT INTO cost_estimation_data (id,plugin_reference,"
3210 "fu_reference,name,value) VALUES (NULL," +
3211 Conversion::toString(pluginID) + "," +
3212 Conversion::toString(fuID) + ",\"" + valueName + "\",\"" +
3213 value + "\");"));
3214 dataID = dbConnection_->lastInsertRowID();
3215 } catch (const Exception& e) {
3217 assert(false);
3218 }
3219 return dataID;
3220}
3221
3222
3223/**
3224 * Adds the given cost estimation data values to given RF entry.
3225 *
3226 * @param rfID The ID of the RF entry the cost data will be added.
3227 * @valueName The name of the cost value.
3228 * @value The cost value.
3229 * @pluginID The ID of the cost function plugin that owns this data.
3230 */
3231RowID
3233 RowID rfID,
3234 const std::string& valueName,
3235 const std::string& value,
3236 RowID pluginID) const {
3237
3238 RowID dataID;
3239
3240 // add the data
3241 try {
3243 std::string(
3244 "INSERT INTO cost_estimation_data (id,plugin_reference,"
3245 "rf_reference,name,value) VALUES (NULL," +
3246 Conversion::toString(pluginID) + "," +
3247 Conversion::toString(rfID) + ",\"" + valueName + "\",\"" +
3248 value + "\");"));
3249 dataID = dbConnection_->lastInsertRowID();
3250 } catch (const Exception& e) {
3252 assert(false);
3253 }
3254 return dataID;
3255}
3256
3257
3258/**
3259 * Returns FU cost estimation data.
3260 *
3261 * This version assumes that there's only one entry with given parameters.
3262 *
3263 * @todo Another version for fetching lists of data.
3264 * @todo Refactor most of the code in *costEstimationData() functions to
3265 * a helper function
3266 *
3267 * @param valueName Name of the value to fetch.
3268 * @param implementationId The ID of the FU entry.
3269 * @param pluginName Name of the cost estimation plugin that owns the data.
3270 * @return The data.
3271 * @exception KeyNotFound If the HDB does not contain FU cost estimation data
3272 * with the given arguments.
3273 */
3276 const std::string& valueName, RowID implementationId,
3277 const std::string& pluginName) const {
3278 // make the SQL query to obtain implementation data
3279 RelationalDBQueryResult* queryResult = NULL;
3280 try {
3281 queryResult = dbConnection_->query(
3282 std::string(
3283 "SELECT value "
3284 "FROM cost_estimation_data, cost_function_plugin "
3285 "WHERE plugin_reference = cost_function_plugin.id AND "
3286 "cost_function_plugin.name LIKE('") +
3287 pluginName + "') " +
3288 " AND rf_reference IS NULL " +
3289 " AND bus_reference IS NULL " +
3290 " AND socket_reference IS NULL AND " +
3291 " fu_reference = " + Conversion::toString(implementationId) +
3292 " AND cost_estimation_data.name LIKE('" + valueName + "');");
3293 } catch (const Exception& e) {
3294 // should not throw in any case
3296 assert(false);
3297 }
3298
3299 if (queryResult->hasNext()) {
3300 queryResult->next();
3301
3302 DataObject value = queryResult->data("value");
3303
3304 delete queryResult;
3305 queryResult = NULL;
3306
3307 return value;
3308 } else {
3309 delete queryResult;
3310 throw KeyNotFound(__FILE__, __LINE__, __func__);
3311 }
3312 // silence compiler warning
3313 throw 1;
3314}
3315
3316/**
3317 * Returns RF cost estimation data.
3318 *
3319 * This version assumes that there's only one entry with given parameters.
3320 *
3321 * @todo Another version for fetching lists of data.
3322 *
3323 * @param valueName Name of the value to fetch.
3324 * @param implementationId The ID of the RF entry.
3325 * @param pluginName Name of the cost estimation plugin that owns the data.
3326 * @return The data.
3327 * @exception KeyNotFound If the HDB does not contain RF cost estimation data
3328 * with the given arguments.
3329 */
3332 const std::string& valueName, RowID implementationId,
3333 const std::string& pluginName) const {
3334 // make the SQL query to obtain implementation data
3335 RelationalDBQueryResult* queryResult = NULL;
3336 try {
3337 queryResult = dbConnection_->query(
3338 std::string(
3339 "SELECT value "
3340 "FROM cost_estimation_data, cost_function_plugin "
3341 "WHERE plugin_reference = cost_function_plugin.id AND "
3342 "cost_function_plugin.name LIKE('") +
3343 pluginName + "') " +
3344 " AND fu_reference IS NULL " +
3345 " AND bus_reference IS NULL " +
3346 " AND socket_reference IS NULL AND " +
3347 " rf_reference = " + Conversion::toString(implementationId) +
3348 " AND cost_estimation_data.name LIKE('" + valueName + "');");
3349 } catch (const Exception& e) {
3350 // should not throw in any case
3352 assert(false);
3353 }
3354
3355 if (queryResult->hasNext()) {
3356 queryResult->next();
3357
3358 DataObject value = queryResult->data("value");
3359
3360 delete queryResult;
3361 queryResult = NULL;
3362
3363 return value;
3364 } else {
3365 delete queryResult;
3366 throw KeyNotFound(__FILE__, __LINE__, __func__);
3367 }
3368 // silence compiler warning
3369 throw 1;
3370}
3371
3372/**
3373 * Adds an empty Bus entry to the database.
3374 *
3375 * @param entry The Bus entry.
3376 * @return ID of the added Bus entry.
3377 */
3378RowID
3380 try {
3382 std::string("INSERT INTO bus(id) VALUES(NULL);"));
3384 } catch (const Exception& e) {
3386 assert(false);
3387 }
3388
3389 // dummy return to avoid compiler whining
3390 assert(false);
3391 return 0;
3392}
3393
3394
3395/**
3396 * Removes the Bus entry that has the given ID from the database.
3397 *
3398 * The entry is removed entirely, meaning that also cost estimation data
3399 * of that entry are removed.
3400 *
3401 * @param id The ID of the Bus entry.
3402 */
3403void
3405
3406 if (!hasBusEntry(id)) {
3407 return;
3408 }
3409
3410 // remove cost estimation data
3411 try {
3412 // get the IDs of cost estimation datas
3414 std::string(
3415 "SELECT id FROM cost_estimation_data "
3416 "WHERE bus_reference=" + Conversion::toString(id) + ";"));
3417 while (result->hasNext()) {
3418 result->next();
3419 const DataObject& costIDData = result->data(0);
3420 int dataID = costIDData.integerValue();
3422 }
3423 delete result;
3424 } catch (const Exception& e) {
3426 assert(false);
3427 }
3428
3429 // remove from bus table
3430 try {
3432 std::string(
3433 "DELETE FROM bus "
3434 "WHERE id=" + Conversion::toString(id) + ";"));
3435 } catch (const Exception& e) {
3437 assert(false);
3438 }
3439}
3440
3441
3442/**
3443 * Adds the given cost estimation data values to given Bus entry.
3444 *
3445 * @param busID The ID of the Bus entry the cost data will be added.
3446 * @valueName The name of the cost value.
3447 * @value The cost value.
3448 * @pluginID The ID of the cost function plugin that owns this data.
3449 */
3450RowID
3452 RowID busID,
3453 const std::string& valueName,
3454 const std::string& value,
3455 RowID pluginID) const {
3456
3457
3458 RowID dataID;
3459
3460 // add the data
3461 try {
3463 std::string(
3464 "INSERT INTO cost_estimation_data (id,plugin_reference,"
3465 "bus_reference,name,value) VALUES (NULL," +
3466 Conversion::toString(pluginID) + "," +
3467 Conversion::toString(busID) + ",\"" + valueName + "\",\"" +
3468 value + "\");"));
3469 dataID = dbConnection_->lastInsertRowID();
3470 } catch (const Exception& e) {
3472 assert(false);
3473 }
3474 return dataID;
3475}
3476
3477
3478
3479/**
3480 * Returns bus cost estimation data.
3481 *
3482 * This version assumes that there's only one entry with given parameters.
3483 *
3484 * @param valueName Name of the value to fetch.
3485 * @param busID The ID of the bus entry.
3486 * @param pluginName Name of the cost estimation plugin that owns the data.
3487 * @return The data.
3488 * @exception KeyNotFound If the HDB does not contain bus cost estimation data
3489 * with the given arguments.
3490 */
3493 const std::string& valueName, RowID busID,
3494 const std::string& pluginName) const {
3495 RelationalDBQueryResult* queryResult = NULL;
3496 try {
3497 queryResult = dbConnection_->query(
3498 std::string(
3499 "SELECT value "
3500 "FROM cost_estimation_data, cost_function_plugin "
3501 "WHERE plugin_reference = cost_function_plugin.id AND "
3502 "cost_function_plugin.name LIKE('") +
3503 pluginName + "') " +
3504 " AND rf_reference IS NULL " +
3505 " AND socket_reference IS NULL AND " +
3506 " bus_reference = " + Conversion::toString(busID) +
3507 " AND cost_estimation_data.name LIKE('" + valueName + "');");
3508 } catch (const Exception& e) {
3509 // should not throw in any case
3511 assert(false);
3512 }
3513
3514 if (queryResult->hasNext()) {
3515 queryResult->next();
3516
3517 DataObject value = queryResult->data("value");
3518
3519 delete queryResult;
3520 queryResult = NULL;
3521
3522 return value;
3523 } else {
3524 delete queryResult;
3525 throw KeyNotFound(__FILE__, __LINE__, __func__);
3526 }
3527 // silence compiler warning
3528 throw 1;
3529}
3530
3531/**
3532 * Returns a list of bus cost estimation data.
3533 *
3534 * @param valueName Name of the value to fetch.
3535 * @param busID The ID of the bus entry.
3536 * @param pluginName Name of the cost estimation plugin that owns the data.
3537 * @return The data. Becomes property of the caller.
3538 * @exception KeyNotFound If the HDB does not contain bus cost estimation data
3539 * with the given arguments.
3540 */
3543 const std::string& valueName, RowID busID,
3544 const std::string& pluginName) const {
3545 RelationalDBQueryResult* queryResult = NULL;
3546 try {
3547 queryResult = dbConnection_->query(
3548 std::string(
3549 "SELECT value "
3550 "FROM cost_estimation_data, cost_function_plugin "
3551 "WHERE plugin_reference = cost_function_plugin.id AND "
3552 "cost_function_plugin.name LIKE('") +
3553 pluginName + "') " +
3554 " AND rf_reference IS NULL " +
3555 " AND socket_reference IS NULL AND " +
3556 " bus_reference = " + Conversion::toString(busID) +
3557 " AND cost_estimation_data.name LIKE('" + valueName + "');");
3558 } catch (const Exception& e) {
3559 // should not throw in any case
3561 assert(false);
3562 }
3563
3564 if (queryResult->hasNext()) {
3565
3566 DataObjectList* data = new DataObjectList;
3567
3568 while (queryResult->hasNext()) {
3569 queryResult->next();
3570 DataObject value = queryResult->data("value");
3571 data->push_back(value);
3572 }
3573
3574 delete queryResult;
3575 queryResult = NULL;
3576 return data;
3577 } else {
3578 delete queryResult;
3579 throw KeyNotFound(__FILE__, __LINE__, __func__);
3580 }
3581 // silence compiler warning
3582 throw 1;
3583}
3584
3585/**
3586 * Adds an empty Socket entry to the database.
3587 *
3588 * @param entry The Socket entry.
3589 * @return ID of the added Socket entry.
3590 */
3591RowID
3593 try {
3595 std::string("INSERT INTO socket(id) VALUES(NULL);"));
3597 } catch (const Exception& e) {
3599 assert(false);
3600 }
3601
3602 // dummy return to avoid compiler whining
3603 assert(false);
3604 return 0;
3605}
3606
3607
3608/**
3609 * Removes the Socket entry that has the given ID from the database.
3610 *
3611 * The entry is removed entirely, meaning that also cost estimation data
3612 * of that entry are removed.
3613 *
3614 * @param id The ID of the Socket entry.
3615 */
3616void
3618
3619 if (!hasSocketEntry(id)) {
3620 return;
3621 }
3622
3623 // remove cost estimation data
3624 try {
3625 // get the IDs of cost estimation datas
3627 std::string(
3628 "SELECT id FROM cost_estimation_data "
3629 "WHERE socket_reference=" + Conversion::toString(id) + ";"));
3630 while (result->hasNext()) {
3631 result->next();
3632 const DataObject& costIDData = result->data(0);
3633 int dataID = costIDData.integerValue();
3635 }
3636 delete result;
3637 } catch (const Exception& e) {
3639 assert(false);
3640 }
3641
3642 // remove from socket table
3643 try {
3645 std::string(
3646 "DELETE FROM socket "
3647 "WHERE id=" + Conversion::toString(id) + ";"));
3648 } catch (const Exception& e) {
3650 assert(false);
3651 }
3652}
3653
3654
3655/**
3656 * Adds the given cost estimation data values to given Socket entry.
3657 *
3658 * @param socketID The ID of the Socket entry the cost data will be added.
3659 * @valueName The name of the cost value.
3660 * @value The cost value.
3661 * @pluginID The ID of the cost function plugin that owns this data.
3662 */
3663RowID
3665 RowID socketID,
3666 const std::string& valueName,
3667 const std::string& value,
3668 RowID pluginID) const {
3669
3670
3671 RowID dataID;
3672
3673 // add the data
3674 try {
3676 std::string(
3677 "INSERT INTO cost_estimation_data (id,plugin_reference,"
3678 "socket_reference,name,value) VALUES (NULL," +
3679 Conversion::toString(pluginID) + "," +
3680 Conversion::toString(socketID) + ",\"" + valueName + "\",\"" +
3681 value + "\");"));
3682 dataID = dbConnection_->lastInsertRowID();
3683 } catch (const Exception& e) {
3685 assert(false);
3686 }
3687 return dataID;
3688}
3689
3690
3691/**
3692 * Returns socket cost estimation data.
3693 *
3694 * This version assumes that there's only one entry with given parameters.
3695 *
3696 * @param valueName Name of the value to fetch.
3697 * @param socketID The ID of the socket entry.
3698 * @param pluginName Name of the cost estimation plugin that owns the data.
3699 * @return The data.
3700 * @exception KeyNotFound If the HDB does not contain socket cost estimation
3701 * data with the given arguments.
3702 */
3705 const std::string& valueName, RowID socketID,
3706 const std::string& pluginName) const {
3707 // make the SQL query to obtain implementation data
3708 RelationalDBQueryResult* queryResult = NULL;
3709 try {
3710 std::string theQuery =
3711 std::string(
3712 "SELECT value "
3713 "FROM cost_estimation_data, cost_function_plugin "
3714 "WHERE plugin_reference = cost_function_plugin.id AND "
3715 "cost_function_plugin.name LIKE('") +
3716 pluginName + "') " +
3717 " AND rf_reference IS NULL " +
3718 " AND bus_reference IS NULL AND " +
3719 " socket_reference = " +
3720 Conversion::toString(socketID) +
3721 " AND cost_estimation_data.name LIKE('" + valueName + "');";
3722 queryResult = dbConnection_->query(theQuery);
3723
3724 } catch (const Exception& e) {
3725 // should not throw in any case
3727 assert(false);
3728 }
3729
3730 if (queryResult->hasNext()) {
3731 queryResult->next();
3732
3733 DataObject value = queryResult->data("value");
3734
3735 delete queryResult;
3736 queryResult = NULL;
3737
3738 return value;
3739 } else {
3740 delete queryResult;
3741 throw KeyNotFound(__FILE__, __LINE__, __func__);
3742 }
3743 // silence compiler warning
3744 throw 1;
3745}
3746
3747/**
3748 * Returns socket cost estimation data.
3749 *
3750 * @param valueName Name of the value to fetch.
3751 * @param socketID The ID of the socket entry.
3752 * @param pluginName Name of the cost estimation plugin that owns the data.
3753 * @return The data. Becomes property of the caller.
3754 * @exception KeyNotFound If the HDB does not contain socket cost estimation
3755 * data with the given arguments.
3756 */
3759 const std::string& valueName, RowID socketID,
3760 const std::string& pluginName) const {
3761 RelationalDBQueryResult* queryResult = NULL;
3762 try {
3763 queryResult = dbConnection_->query(
3764 std::string(
3765 "SELECT value "
3766 "FROM cost_estimation_data, cost_function_plugin "
3767 "WHERE plugin_reference = cost_function_plugin.id AND "
3768 "cost_function_plugin.name LIKE('") +
3769 pluginName + "') " +
3770 " AND rf_reference IS NULL " +
3771 " AND bus_reference IS NULL AND " +
3772 " socket_reference = " +
3773 Conversion::toString(socketID) +
3774 " AND cost_estimation_data.name LIKE('" + valueName + "');");
3775 } catch (const Exception& e) {
3776 // should not throw in any case
3778 assert(false);
3779 }
3780
3781 if (queryResult->hasNext()) {
3782
3783 DataObjectList* data = new DataObjectList;
3784
3785 while (queryResult->hasNext()) {
3786 queryResult->next();
3787 DataObject value = queryResult->data("value");
3788 data->push_back(value);
3789 }
3790
3791 delete queryResult;
3792 queryResult = NULL;
3793 return data;
3794 } else {
3795 delete queryResult;
3796 throw KeyNotFound(__FILE__, __LINE__, __func__);
3797 }
3798 // silence compiler warning
3799 throw 1;
3800}
3801
3802/**
3803 * Returns cost estimation data which is not connected to any machine
3804 * implementation id.
3805 *
3806 * This version assumes that there's only one entry with given parameters.
3807 *
3808 * @todo Another version for fetching lists of data.
3809 *
3810 * @param valueName Name of the value to fetch.
3811 * @param pluginName Name of the cost estimation plugin that owns the data.
3812 * @return The data.
3813 * @exception KeyNotFound If the HDB does not contain cost estimation
3814 * data with the given arguments.
3815 */
3818 const std::string& valueName, const std::string& pluginName) const {
3819 // make the SQL query to obtain implementation data
3820 RelationalDBQueryResult* queryResult = NULL;
3821 try {
3822 std::string theQuery =
3823 std::string(
3824 "SELECT value "
3825 "FROM cost_estimation_data, cost_function_plugin "
3826 "WHERE plugin_reference = cost_function_plugin.id AND "
3827 "cost_function_plugin.name LIKE('") +
3828 pluginName + "') " +
3829 " AND rf_reference IS NULL " +
3830 " AND fu_reference IS NULL " +
3831 " AND socket_reference IS NULL " +
3832 " AND bus_reference IS NULL " +
3833 " AND cost_estimation_data.name LIKE('" + valueName + "');";
3834 queryResult = dbConnection_->query(theQuery);
3835
3836 } catch (const Exception& e) {
3837 // should not throw in any case
3839 assert(false);
3840 }
3841
3842 if (queryResult->hasNext()) {
3843 queryResult->next();
3844
3845 DataObject value = queryResult->data("value");
3846
3847 delete queryResult;
3848 queryResult = NULL;
3849
3850 return value;
3851 } else {
3852 delete queryResult;
3853 throw KeyNotFound(__FILE__, __LINE__, __func__);
3854 }
3855 // silence compiler warning
3856 throw 1;
3857}
3858
3859/**
3860 * Returns cost estimation data value with the given id.
3861 *
3862 * @param entryId Id of the cost estimation data entry.
3863 * @return The data.
3864 * @exception KeyNotFound If the HDB does not contain cost estimation
3865 * data with the given arguments.
3866 */
3869 // make the SQL query to obtain implementation data
3870 RelationalDBQueryResult* queryResult = NULL;
3871 try {
3872 std::string theQuery =
3873 std::string(
3874 "SELECT value "
3875 "FROM cost_estimation_data "
3876 "WHERE cost_estimation_data.id = ") +
3877 Conversion::toString(entryId);
3878
3879 queryResult = dbConnection_->query(theQuery);
3880
3881 } catch (const Exception& e) {
3882 // should not throw in any case
3884 assert(false);
3885 }
3886
3887 if (queryResult->hasNext()) {
3888 queryResult->next();
3889
3890 DataObject value = queryResult->data("value");
3891
3892 delete queryResult;
3893 queryResult = NULL;
3894
3895 return value;
3896 } else {
3897 delete queryResult;
3898 throw KeyNotFound(__FILE__, __LINE__, __func__);
3899 }
3900 // silence compiler warning
3901 throw 1;
3902}
3903
3904/**
3905 * Tells whether the HDB has an FU entry that has the given ID.
3906 *
3907 * @return True if the HDB has the entry, otherwise false.
3908 */
3909bool
3911
3913
3914 try {
3915 result = dbConnection_->query(fuEntryByIDQuery(id));
3916 } catch (const Exception&) {
3917 assert(false);
3918 }
3919
3920 if (result->hasNext()) {
3921 result->next();
3922 assert(!result->hasNext());
3923 delete result;
3924 return true;
3925 } else {
3926 delete result;
3927 return false;
3928 }
3929}
3930
3931
3932/**
3933 * Tells whether the HDB has an RF entry that has the given ID.
3934 *
3935 * @return True if the HDB has the entry, otherwise false.
3936 */
3937bool
3939
3941
3942 try {
3943 result = dbConnection_->query(rfEntryByIDQuery(id));
3944 } catch (const Exception&) {
3945 assert(false);
3946 }
3947
3948 if (result->hasNext()) {
3949 result->next();
3950 assert(!result->hasNext());
3951 delete result;
3952 return true;
3953 } else {
3954 delete result;
3955 return false;
3956 }
3957}
3958
3959
3960/**
3961 * Tells whether the HDB has an Bus entry that has the given ID.
3962 *
3963 * @return True if the HDB has the entry, otherwise false.
3964 */
3965bool
3967
3969
3970 try {
3971 result = dbConnection_->query(busEntryByIDQuery(id));
3972 } catch (const Exception&) {
3973 assert(false);
3974 }
3975
3976 if (result->hasNext()) {
3977 result->next();
3978 assert(!result->hasNext());
3979 delete result;
3980 return true;
3981 } else {
3982 delete result;
3983 return false;
3984 }
3985}
3986
3987
3988/**
3989 * Tells whether the HDB has an Socket entry that has the given ID.
3990 *
3991 * @return True if the HDB has the entry, otherwise false.
3992 */
3993bool
3995
3997
3998 try {
4000 } catch (const Exception&) {
4001 assert(false);
4002 }
4003
4004 if (result->hasNext()) {
4005 result->next();
4006 assert(!result->hasNext());
4007 delete result;
4008 return true;
4009 } else {
4010 delete result;
4011 return false;
4012 }
4013}
4014
4015/**
4016 * Tells whether the HDB has cost estimation data that has the given ID.
4017 *
4018 * @return True if the HDB has the data, otherwise false.
4019 */
4020bool
4022
4024 std::string query = "SELECT id FROM cost_estimation_data WHERE id=";
4025 query += Conversion::toString(id) + ";";
4026
4027 try {
4028 result = dbConnection_->query(query);
4029 } catch (const Exception&) {
4030 assert(false);
4031 }
4032
4033 if (result->hasNext()) {
4034 result->next();
4035 assert(!result->hasNext());
4036 delete result;
4037 return true;
4038 } else {
4039 delete result;
4040 return false;
4041 }
4042}
4043
4044/**
4045 * Tells whether the HDB has cost function plugin that has the given ID.
4046 *
4047 * @return True if the HDB has the plugin, otherwise false.
4048 */
4049bool
4051
4053 std::string query = "SELECT id FROM cost_function_plugin WHERE id=";
4054 query += Conversion::toString(id) + ";";
4055
4056 try {
4057 result = dbConnection_->query(query);
4058 } catch (const Exception&) {
4059 assert(false);
4060 }
4061
4062 if (result->hasNext()) {
4063 result->next();
4064 assert(!result->hasNext());
4065 delete result;
4066 return true;
4067 } else {
4068 delete result;
4069 return false;
4070 }
4071}
4072
4073
4074/**
4075 * Tells whether the FU entry that has the given ID has an architecture.
4076 *
4077 * @param id ID of the FU entry.
4078 * @return True if it has an architecture, otherwise false.
4079 * @exception KeyNotFound If the HDB does not contain a FU entry with the given
4080 * ID.
4081 */
4082bool
4085 try {
4086 result = dbConnection_->query(
4087 std::string(
4088 "SELECT architecture FROM fu WHERE id=" +
4089 Conversion::toString(id) + ";"));
4090 } catch (const Exception& e) {
4092 assert(false);
4093 }
4094
4095 if (result->hasNext()) {
4096 result->next();
4097 const DataObject& data = result->data(0);
4098 delete result;
4099 return !data.isNull();
4100 } else {
4101 delete result;
4102 throw KeyNotFound(__FILE__, __LINE__, __func__);
4103 }
4104}
4105
4106/**
4107 * Tells whether the RF entry that has the given ID has an architecture.
4108 *
4109 * @param id ID of the RF entry.
4110 * @return True if it has an architecture, otherwise false.
4111 * @exception KeyNotFound If the HDB does not contain a RF entry with the
4112 * given ID.
4113 */
4114bool
4117 try {
4118 result = dbConnection_->query(
4119 std::string(
4120 "SELECT architecture FROM rf WHERE id=" +
4121 Conversion::toString(id) + ";"));
4122 } catch (const Exception& e) {
4124 assert(false);
4125 }
4126
4127 if (result->hasNext()) {
4128 result->next();
4129 const DataObject& data = result->data(0);
4130 delete result;
4131 return !data.isNull();
4132 } else {
4133 delete result;
4134 throw KeyNotFound(__FILE__, __LINE__, __func__);
4135 }
4136}
4137
4138/**
4139 * Tells whether the HDB contains the given operation in operation table.
4140 *
4141 * @param opName Name of the operation.
4142 * @return True if HDB contains the operation, otherwise false.
4143 */
4144bool
4145HDBManager::containsOperation(const std::string& opName) const {
4146 try {
4148 std::string(
4149 "SELECT * FROM operation WHERE lower(name)=lower(\"" + opName
4150 + "\");"));
4151 bool returnValue = result->hasNext();
4152 delete result;
4153 return returnValue;
4154 } catch (const Exception& e) {
4156 assert(false);
4157 }
4158
4159 // dummy return to avoid compiler whining
4160 assert(false);
4161 return false;
4162}
4163
4164
4165/**
4166 * Tells whether the HDB contains the given block implementation file.
4167 *
4168 * @param pathToFile Full path to the file.
4169 */
4170bool
4171HDBManager::containsImplementationFile(const std::string& pathToFile) const {
4172 try {
4174 std::string(
4175 "SELECT * FROM block_source_file WHERE file=\"" +
4176 pathToFile + "\";"));
4177 bool returnValue = result->hasNext();
4178 delete result;
4179 return returnValue;
4180 } catch (const Exception& e) {
4182 assert(false);
4183 }
4184
4185 // dummy return to avoid compiler whining
4186 assert(false);
4187 return false;
4188}
4189
4190
4191/**
4192 * Tells whether the HDB contains a FU architecture that has the given ID.
4193 *
4194 * @param id The ID.
4195 * @return True if the HDB contains the architecture, otherwise false.
4196 */
4197bool
4199
4200 try {
4202 std::string(
4203 "SELECT id FROM fu_architecture WHERE id=" +
4204 Conversion::toString(id) + ";"));
4205 bool returnValue = result->hasNext();
4206 delete result;
4207 return returnValue;
4208 } catch (const Exception& e) {
4210 assert(false);
4211 }
4212
4213 // dummy return to avoid compiler whining
4214 assert(false);
4215 return false;
4216}
4217
4218
4219/**
4220 * Tells whether the HDB contains a RF architecture with the given ID.
4221 *
4222 * @param id The ID.
4223 * @return True if the HDB contains the architecture, otherwise false.
4224 */
4225bool
4227 try {
4229 std::string(
4230 "SELECT id FROM rf_architecture WHERE id=" +
4231 Conversion::toString(id) + ";"));
4232 bool returnValue = result->hasNext();
4233 delete result;
4234 return returnValue;
4235 } catch (const Exception& e) {
4237 assert(false);
4238 }
4239
4240 // dummy return to avoid compiler whining
4241 assert(false);
4242 return false;
4243}
4244
4245
4246/**
4247 * Returns the ID of the architecture of the given FU entry.
4248 *
4249 * @param fuEntryID ID of the FU entry.
4250 * @return ID of the FU architecture.
4251 * @exception NotAvailable If the FU entry does not have an architecture.
4252 */
4253RowID
4256 try {
4257 result = dbConnection_->query(
4258 std::string(
4259 "SELECT architecture FROM fu WHERE id=" +
4260 Conversion::toString(fuEntryID) + ";"));
4261 } catch (const Exception& e) {
4263 assert(false);
4264 }
4265
4266 if (!result->hasNext()) {
4267 delete result;
4268 throw NotAvailable(__FILE__, __LINE__, __func__);
4269 }
4270
4271 result->next();
4272 const DataObject& idData = result->data(0);
4273 if (idData.isNull()) {
4274 delete result;
4275 throw NotAvailable(__FILE__, __LINE__, __func__);
4276 } else {
4277 RowID retValue = idData.integerValue();
4278 delete result;
4279 return retValue;
4280 }
4281}
4282
4283/**
4284 * Returns the ID of the architecture of the given RF entry.
4285 *
4286 * @param rfEntryID ID of the RF entry.
4287 * @return ID of the RF architecture.
4288 * @exception NotAvailable If the RF entry does not have an architecture.
4289 */
4290RowID
4293 try {
4294 result = dbConnection_->query(
4295 std::string(
4296 "SELECT architecture FROM rf WHERE id=" +
4297 Conversion::toString(rfEntryID) + ";"));
4298 } catch (const Exception& e) {
4300 assert(false);
4301 }
4302
4303 if (!result->hasNext()) {
4304 delete result;
4305 throw NotAvailable(__FILE__, __LINE__, __func__);
4306 }
4307
4308 result->next();
4309 const DataObject& idData = result->data(0);
4310 if (idData.isNull()) {
4311 delete result;
4312 throw NotAvailable(__FILE__, __LINE__, __func__);
4313 } else {
4314 RowID retValue = idData.integerValue();
4315 delete result;
4316 return retValue;
4317 }
4318}
4319
4320/**
4321 * Returns true if a table by name has a column by given name.
4322 *
4323 * @param table The table by name to search the column from.
4324 * @param columnName The name of the column to be searched.
4325 * @return True if the table has the named column.
4326 */
4327bool
4329 const std::string& table, const std::string& columnName) const {
4330
4331 std::string table_info_query("PRAGMA table_info(");
4332 table_info_query += table;
4333 table_info_query += ");";
4334
4336 try {
4337 result = dbConnection_->query(table_info_query);
4338 } catch (const Exception& e) {
4340 assert(false);
4341 }
4342
4343 while(result->hasNext()) {
4344 result->next();
4345 // Second column in result row is column name of the table.
4346 const DataObject& columnData = result->data(1);
4347 std::string columnNameFromTable = columnData.stringValue();
4348
4349 assert(!columnNameFromTable.empty());
4350 if(columnNameFromTable == columnName) {
4351 return true;
4352 }
4353 }
4354
4355 return false;
4356}
4357
4358/**
4359 * Inserts a new boolean type column into existing table.
4360 *
4361 * @param table The name of the targeted table.
4362 * @param newColumn The name of the new column.
4363 * @return Number of rows affected by the change.
4364 */
4365int
4366HDBManager::addBooleanColumn(const std::string& table,
4367 const std::string& newcolumn) {
4368 std::string add_column_query("ALTER TABLE ");
4369 add_column_query += table + " ADD COLUMN " + newcolumn;
4370 add_column_query += " INTEGER DEFAULT 0;";
4371
4372 int result = 0;
4373
4374 try {
4375 result = dbConnection_->updateQuery(add_column_query);
4376 } catch (const Exception& e) {
4378 assert(false);
4379 }
4380
4381 return result;
4382}
4383
4384/**
4385 * Obtains data from HDB and creates ports and operand bindings to the given
4386 * FU architecture that has the given ID in HDB.
4387 *
4388 * @param architecture The FU architecture to which the ports are added.
4389 * @param id ID of the FU architecture in HDB.
4390 */
4391void
4393 FUArchitecture& architecture,
4394 RowID id) const {
4395
4396 FunctionUnit& fu = architecture.architecture();
4397
4398 // make the SQL query to obtain the ports
4399 RelationalDBQueryResult* fuPorts = NULL;
4400 try {
4402 } catch (const Exception& e) {
4404 }
4405 int portIDColumnIndex = fuPorts->column("fu_data_port.id");
4406 int triggersColumnIndex = fuPorts->column("fu_data_port.triggers");
4407 int setsOpcodeColumnIndex = fuPorts->column("fu_data_port.sets_opcode");
4408 int guardSupportColumnIndex = fuPorts->column(
4409 "fu_data_port.guard_support");
4410 int widthColumnIndex = fuPorts->column("fu_data_port.width");
4411 int operationColumnIndex = fuPorts->column("operation.name");
4412 int bindingColumnIndex = fuPorts->column("io_binding.io_number");
4413
4414 // @fixme Do not assert() inside a library function in case of broken
4415 // user input data!!
4416 assert(portIDColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4417 assert(triggersColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4418 assert(setsOpcodeColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4419 assert(
4420 guardSupportColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4422 assert(operationColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4423 assert(bindingColumnIndex != RelationalDBQueryResult::UNKNOWN_INDEX);
4424
4425 if (!fuPorts->hasNext()) {
4426 delete fuPorts;
4427 abortWithError("No row.");
4428 }
4429
4430 std::map<int, std::string> portIDMap;
4431
4432 // create ports, operations and bindings to the FU
4433 int name(1);
4434 while (fuPorts->hasNext()) {
4435 fuPorts->next();
4436
4437 const DataObject& idData = fuPorts->data(portIDColumnIndex);
4438 const DataObject& triggersData = fuPorts->data(triggersColumnIndex);
4439 const DataObject& setsOpcodeData = fuPorts->data(
4440 setsOpcodeColumnIndex);
4441 const DataObject& guardData = fuPorts->data(guardSupportColumnIndex);
4442 const DataObject& widthData = fuPorts->data(widthColumnIndex);
4443 const DataObject& operationData = fuPorts->data(
4444 operationColumnIndex);
4445 const DataObject& bindingData = fuPorts->data(bindingColumnIndex);
4446
4447 int portID = idData.integerValue();
4448
4449 // create operation if it is not created yet
4450 string operationName = operationData.stringValue();
4451 if (!fu.hasOperation(operationName)) {
4452 new HWOperation(operationName, fu);
4453 }
4454
4455 // create port if it is not created yet
4456 if (!MapTools::containsKey(portIDMap, portID)) {
4457 bool triggers = triggersData.boolValue();
4458 bool setsOpcode = setsOpcodeData.boolValue();
4459 string portName = "p" + Conversion::toString(name);
4460
4461 int width = DEFAULT_PORT_WIDTH;
4462 if (widthData.isNull()) {
4463 architecture.setParameterizedWidth(portName);
4464 } else {
4465 width = widthData.integerValue();
4466 }
4467 new FUPort(portName, width, fu, triggers, setsOpcode);
4468 portIDMap.insert(
4469 std::pair<int, string>(idData.integerValue(), portName));
4470 if (setsOpcode && !triggers)
4471 debugLog(
4472 std::string("Created a suspicious port ") + portName +
4473 " which sets opcode but does not trigger");
4474
4475 // set guard support
4476 if (guardData.boolValue()) {
4477 architecture.setGuardSupport(portName);
4478 }
4479
4480 name++;
4481 }
4482
4483 // create binding
4484 FUPort* portToBind = fu.operationPort(
4485 MapTools::valueForKey<string>(portIDMap, portID));
4486 HWOperation* operation = fu.operation(operationName);
4487 operation->bindPort(bindingData.integerValue(), *portToBind);
4488 }
4489
4490 delete fuPorts;
4491 fuPorts = NULL;
4492}
4493
4494
4495/**
4496 * Obtains data from HDB and creates the operation pipelines to the
4497 * given FU architecture.
4498 *
4499 * @param architecture The FU architecture to which the operations are added.
4500 * @param id ID the FU architecture in HDB.
4501 */
4502void
4504 FUArchitecture& architecture,
4505 RowID id) const {
4506
4507 FunctionUnit& fu = architecture.architecture();
4508
4509 // make the SQL query to obtain IO usage data
4510 RelationalDBQueryResult* ioUsageData = NULL;
4511 try {
4512 ioUsageData = dbConnection_->query(ioUsageDataByIDQuery(id));
4513 } catch (const Exception& e) {
4514 assert(false);
4515 }
4516 int operationColumn = ioUsageData->column("operation.name");
4517 int cycleColumn = ioUsageData->column("io_usage.cycle");
4518 int ioColumn = ioUsageData->column("io_usage.io_number");
4519 int actionColumn = ioUsageData->column("io_usage.action");
4520
4521 while (ioUsageData->hasNext()) {
4522 ioUsageData->next();
4523 const DataObject& operationData = ioUsageData->data(operationColumn);
4524 const DataObject& cycleData = ioUsageData->data(cycleColumn);
4525 const DataObject& ioData = ioUsageData->data(ioColumn);
4526 const DataObject& actionData = ioUsageData->data(actionColumn);
4527
4528 string operationName = operationData.stringValue();
4529 int cycle = cycleData.integerValue();
4530 int ioNumber = ioData.integerValue();
4531 int action = actionData.boolValue();
4532
4533 assert(fu.hasOperation(operationName));
4534 HWOperation* operation = fu.operation(operationName);
4535 ExecutionPipeline* pipeline = operation->pipeline();
4536 if (action == READ_ACTION) {
4537 pipeline->addPortRead(ioNumber, cycle, 1);
4538 } else if (action == WRITE_ACTION) {
4539 pipeline->addPortWrite(ioNumber, cycle, 1);
4540 }
4541 }
4542
4543 delete ioUsageData;
4544 ioUsageData = NULL;
4545
4546 // add resource usages
4547 RelationalDBQueryResult* resUsageData = NULL;
4548 try {
4549 resUsageData = dbConnection_->query(resourceUsageDataByIDQuery(id));
4550 } catch (const Exception&) {
4551 assert(false);
4552 }
4553 operationColumn = resUsageData->column("operation.name");
4554 cycleColumn = resUsageData->column("pipeline_resource_usage.cycle");
4555 int resourceColumn = resUsageData->column("pipeline_resource.id");
4556
4557 int resourceName(0);
4558 std::map<int, string> resourceMap;
4559
4560 while (resUsageData->hasNext()) {
4561 resUsageData->next();
4562 const DataObject& operationData = resUsageData->data(
4563 operationColumn);
4564 const DataObject& cycleData = resUsageData->data(cycleColumn);
4565 const DataObject& resourceData = resUsageData->data(resourceColumn);
4566
4567 string operationName = operationData.stringValue();
4568 int cycle = cycleData.integerValue();
4569 int resourceID = resourceData.integerValue();
4570
4571 assert(fu.hasOperation(operationName));
4572 HWOperation* operation = fu.operation(operationName);
4573 ExecutionPipeline* pipeline = operation->pipeline();
4574 if (!MapTools::containsKey(resourceMap, resourceID)) {
4575 resourceMap.insert(
4576 std::pair<int, string>(
4577 resourceID, "res" + Conversion::toString(resourceName)));
4578 resourceName++;
4579 }
4580 pipeline->addResourceUse(
4582 resourceMap, resourceID), cycle, 1);
4583 }
4584
4585 delete resUsageData;
4586 resUsageData = NULL;
4587}
4588
4589
4590/**
4591 * Obtains implementation data of the FU that has the given ID and creates an
4592 * FUImplementation instance of it.
4593 *
4594 * @param architecture Architecture of the FU (needed when matching the
4595 * ports in the implementation).
4596 * @param id ID of the FU entry.
4597 * @return The newly created FUImplementation instance or NULL if the FU
4598 * has no implementation.
4599 */
4602 FUArchitecture& architecture,
4603 RowID id) const {
4604
4605 // make the SQL query to obtain implementation data
4606 RelationalDBQueryResult* implData = NULL;
4607 const std::string queryString = fuImplementationByIDQuery(id);
4608 try {
4609 implData = dbConnection_->query(queryString);
4610 } catch (const Exception& e) {
4611 delete implData;
4612 debugLog(
4613 std::string("query ") + queryString + " threw something: " +
4614 e.errorMessage());
4615 return NULL;
4616 }
4617
4619
4620 if (implData->hasNext()) {
4621 implData->next();
4622 assert(!implData->hasNext());
4623
4624 int idColumn = implData->column("fu_implementation.id");
4625 int nameColumn = implData->column("fu_implementation.name");
4626 int opcodePortColumn = implData->column(
4627 "fu_implementation.opcode_port");
4628 int clkPortColumn = implData->column("fu_implementation.clk_port");
4629 int rstPortColumn = implData->column("fu_implementation.rst_port");
4630 int glockPortColumn = implData->column(
4631 "fu_implementation.glock_port");
4632 int glockReqPortColumn = implData->column(
4633 "fu_implementation.glock_req_port");
4634
4635 const DataObject& idData = implData->data(idColumn);
4636 const DataObject& nameData = implData->data(nameColumn);
4637 const DataObject& opcodePortData = implData->data(opcodePortColumn);
4638 const DataObject& clkPortData = implData->data(clkPortColumn);
4639 const DataObject& rstPortData = implData->data(rstPortColumn);
4640 const DataObject& glockPortData = implData->data(glockPortColumn);
4641 const DataObject& glockReqPortData = implData->data(
4642 glockReqPortColumn);
4643
4644 RowID implID = idData.integerValue();
4645 string name = nameData.stringValue();
4646 string opcodePort = opcodePortData.stringValue();
4647 string clkPort = clkPortData.stringValue();
4648 string rstPort = rstPortData.stringValue();
4649 string glockPort = glockPortData.stringValue();
4650 string glockReqPort = glockReqPortData.stringValue();
4651
4653 name, opcodePort, clkPort, rstPort, glockPort, glockReqPort);
4654 implementation->setID(implID);
4655
4658 addDataPortsToImplementation(*implementation, architecture, id);
4661 }
4662
4663 delete implData;
4664 implData = NULL;
4665 return implementation;
4666}
4667
4668/**
4669 * Obtains the cost function data of the FU that has the given ID and creates
4670 * a CostFunctionPlugin instance of it.
4671 *
4672 * @param id ID of the FU entry.
4673 * @return The newly created FUImplementation instance or NULL if the FU
4674 * has no cost function.
4675 */
4678
4679 // make the SQL query to obtain implementation data
4680 RelationalDBQueryResult* queryResult = NULL;
4681 try {
4682 queryResult = dbConnection_->query(
4683 "SELECT cost_function_plugin.id AS id, "
4684 " cost_function_plugin.description AS description,"
4685 " cost_function_plugin.name AS name, "
4686 " cost_function_plugin.plugin_file_path AS plugin_file_path "
4687 "FROM cost_function_plugin, fu "
4688 "WHERE fu.id = " + Conversion::toString(id) +
4689 " AND cost_function_plugin.id = fu.cost_function;");
4690 } catch (const Exception& e) {
4691 delete queryResult;
4693 return NULL;
4694 }
4695
4696 CostFunctionPlugin* costFunction = NULL;
4697
4698 if (queryResult->hasNext()) {
4699 queryResult->next();
4700
4701 const DataObject& pluginIdData =
4702 queryResult->data("id");
4703 const DataObject& descriptionData =
4704 queryResult->data("description");
4705 const DataObject& nameData =
4706 queryResult->data("name");
4707 const DataObject& pluginFilePathData =
4708 queryResult->data("plugin_file_path");
4709
4710 int pluginId = -1;
4711 string description = "";
4712 string name = "";
4713 string pluginFilePath = "";
4714 try {
4715 if (!pluginIdData.isNull()) {
4716 pluginId = pluginIdData.integerValue();
4717 }
4718 description = descriptionData.stringValue();
4719 name = nameData.stringValue();
4720 pluginFilePath = pluginFilePathData.stringValue();
4721 } catch (const Exception& e) {
4722 debugLog(
4723 std::string("Something wrong with conversion: ") +
4724 e.errorMessage());
4725 delete queryResult;
4726 queryResult = NULL;
4727 return NULL;
4728 }
4729
4730 costFunction = new CostFunctionPlugin(
4731 pluginId, description, name, pluginFilePath,
4733 }
4734
4735 delete queryResult;
4736 queryResult = NULL;
4737 return costFunction;
4738}
4739
4740/**
4741 * Obtains the cost function data of the RF that has the given ID and creates
4742 * a CostFunctionPlugin instance of it.
4743 *
4744 * @param id ID of the RF entry.
4745 * @return The newly created FUImplementation instance or NULL if the RF
4746 * has no cost function.
4747 */
4750
4751 // make the SQL query to obtain implementation data
4752 RelationalDBQueryResult* queryResult = NULL;
4753 try {
4754 queryResult = dbConnection_->query(
4755 "SELECT cost_function_plugin.id AS id, "
4756 " cost_function_plugin.description AS description,"
4757 " cost_function_plugin.name AS name, "
4758 " cost_function_plugin.plugin_file_path AS plugin_file_path "
4759 "FROM cost_function_plugin, rf "
4760 "WHERE rf.id = " + Conversion::toString(id) +
4761 " AND cost_function_plugin.id = rf.cost_function;");
4762 } catch (const Exception& e) {
4763 delete queryResult;
4765 return NULL;
4766 }
4767
4768 CostFunctionPlugin* costFunction = NULL;
4769
4770 if (queryResult->hasNext()) {
4771 queryResult->next();
4772
4773 const DataObject& pluginIdData =
4774 queryResult->data("id");
4775 const DataObject& descriptionData =
4776 queryResult->data("description");
4777 const DataObject& nameData =
4778 queryResult->data("name");
4779 const DataObject& pluginFilePathData =
4780 queryResult->data("plugin_file_path");
4781
4782 int pluginId = -1;
4783 string description = "";
4784 string name = "";
4785 string pluginFilePath = "";
4786 try {
4787 if (!pluginIdData.isNull()) {
4788 pluginId = pluginIdData.integerValue();
4789 }
4790 description = descriptionData.stringValue();
4791 name = nameData.stringValue();
4792 pluginFilePath = pluginFilePathData.stringValue();
4793 } catch (const Exception& e) {
4794 debugLog(
4795 std::string("Something wrong with conversion: ") +
4796 e.errorMessage());
4797 delete queryResult;
4798 queryResult = NULL;
4799 return NULL;
4800 }
4801
4802 costFunction = new CostFunctionPlugin(
4803 pluginId, description, name, pluginFilePath,
4805 }
4806
4807 delete queryResult;
4808 queryResult = NULL;
4809 return costFunction;
4810}
4811
4812
4813
4814/**
4815 * Obtains implementation data of the RF that has the given ID and creates
4816 * an RFImplementation instance of it.
4817 *
4818 * @param id ID of the RF entry.
4819 * @return The newly created RFImplementation instance or NULL if the RF
4820 * has no implementation.
4821 */
4824
4825 RelationalDBQueryResult* implementationData = NULL;
4826 try {
4827 if(hasColumn("rf_implementation", "sac_param")) {
4828 // Use new query.
4829 implementationData = dbConnection_->query(
4831 } else {
4832 // Use fallback query.
4833 implementationData = dbConnection_->query(
4835 }
4836 } catch (const Exception& e) {
4837 assert(false);
4838 }
4839
4841
4842 if (implementationData->hasNext()) {
4843 implementationData->next();
4844 assert(!implementationData->hasNext());
4845 int idColumn = implementationData->column("id");
4846 int nameColumn = implementationData->column("name");
4847 int sizeParamColumn = implementationData->column("size_param");
4848 int widthParamColumn = implementationData->column("width_param");
4849 int sacParamColumn = implementationData->column("sac_param");
4850 int clkPortColumn = implementationData->column("clk_port");
4851 int rstPortColumn = implementationData->column("rst_port");
4852 int glockPortColumn = implementationData->column("glock_port");
4853 int guardPortColumn = implementationData->column("guard_port");
4854
4855 const DataObject& idData = implementationData->data(idColumn);
4856 const DataObject& nameData = implementationData->data(nameColumn);
4857 const DataObject& sizeParamData = implementationData->data(
4858 sizeParamColumn);
4859 const DataObject& widthParamData = implementationData->data(
4860 widthParamColumn);
4861 const DataObject& clkPortData = implementationData->data(
4862 clkPortColumn);
4863 const DataObject& rstPortData = implementationData->data(
4864 rstPortColumn);
4865 const DataObject& glockPortData = implementationData->data(
4866 glockPortColumn);
4867 const DataObject& guardPortData = implementationData->data(
4868 guardPortColumn);
4869 const DataObject& sacParamData = implementationData->data(
4870 sacParamColumn);
4871
4872 string sizeParam = sizeParamData.stringValue();
4873 string widthParam = widthParamData.stringValue();
4874 string guardPort = guardPortData.stringValue();
4875 bool sacParam =
4876 (sacParamColumn != RelationalDBQueryResult::UNKNOWN_INDEX) ?
4877 sacParamData.boolValue() :
4878 false;
4879
4881 nameData.stringValue(), clkPortData.stringValue(),
4882 rstPortData.stringValue(), glockPortData.stringValue(),
4883 sizeParam, widthParam, guardPort, sacParam);
4884 implementation->setID(idData.integerValue());
4885
4890 }
4891
4892 delete implementationData;
4893 implementationData = NULL;
4894 return implementation;
4895}
4896
4897
4898/**
4899 * Resolves what is the architectural port corresponding to the given
4900 * implemented port.
4901 *
4902 * @param architecture The architecture of the FU.
4903 * @param id ID of the FU entry in the database.
4904 * @param implementedPort Name of the implemented port to resolve.
4905 * @return Name of the corresponding port in the FU architecture.
4906 */
4907std::string
4909 const FUArchitecture& architecture,
4910 RowID entryID,
4911 const std::string& implementedPort) const {
4912
4913 RelationalDBQueryResult* bindingData = NULL;
4914 try {
4915 bindingData = dbConnection_->query(
4916 fuPortBindingByNameQuery(entryID, implementedPort));
4917 } catch (const Exception&) {
4918 assert(false);
4919 }
4920
4921 int operationColumn = bindingData->column("operation.name");
4922 int ioColumn = bindingData->column("io_binding.io_number");
4925
4926 FunctionUnit& fu = architecture.architecture();
4927 string portName = "";
4928
4929 while (bindingData->hasNext()) {
4930 bindingData->next();
4931 const DataObject& operationData = bindingData->data(operationColumn);
4932 const DataObject& ioData = bindingData->data(ioColumn);
4933 string operationName = operationData.stringValue();
4934 int io = ioData.integerValue();
4935 assert(fu.hasOperation(operationName));
4936 HWOperation* operation = fu.operation(operationName);
4937 FUPort* port = operation->port(io);
4938 assert(portName == "" || portName == port->name());
4939 portName = port->name();
4940 }
4941
4942 delete bindingData;
4943 bindingData = NULL;
4944
4945 return portName;
4946}
4947
4948
4949/**
4950 * Adds the operation codes to the given FU implementation which is the
4951 * implementation of the FU entry that has the given ID.
4952 *
4953 * @param implementation The FU implementation.
4954 * @param entryID ID of the FU entry.
4955 */
4956void
4959 RowID entryID) const {
4960
4961 RelationalDBQueryResult* opcodeData = NULL;
4962 try {
4963 opcodeData = dbConnection_->query(opcodesByIDQuery(entryID));
4964 } catch (const Exception&) {
4965 assert(false);
4966 }
4967 int operationColumn = opcodeData->column("operation.name");
4968 int opcodeColumn = opcodeData->column("opcode_map.opcode");
4969 while (opcodeData->hasNext()) {
4970 opcodeData->next();
4971 const DataObject& operationData = opcodeData->data(
4972 operationColumn);
4973 const DataObject& opcodeDataObject = opcodeData->data(
4974 opcodeColumn);
4975 implementation.setOpcode(
4976 operationData.stringValue(), opcodeDataObject.integerValue());
4977 }
4978 delete opcodeData;
4979 opcodeData = NULL;
4980}
4981
4982
4983/**
4984 * Adds data ports to the given FU implementation which is the implementation
4985 * of the FU entry that has the given ID.
4986 *
4987 * @param implementation The implementation.
4988 * @param architecture The corresponding architecture.
4989 * @param entryID ID of the FU entry.
4990 */
4991void
4994 FUArchitecture& architecture,
4995 RowID entryID) const {
4996
4997 RelationalDBQueryResult* portData = NULL;
4998 try {
4999 portData = dbConnection_->query(
5001 } catch (const Exception& e) {
5002 assert(false);
5003 }
5004 int portNameColumn = portData->column("fu_port_map.name");
5005 int widthFormulaColumn = portData->column("fu_port_map.width_formula");
5006 int loadPortColumn = portData->column("fu_port_map.load_port");
5007 int guardPortColumn = portData->column("fu_port_map.guard_port");
5008
5009 while (portData->hasNext()) {
5010 portData->next();
5011 const DataObject& portNameData = portData->data(portNameColumn);
5012 const DataObject& widthFormulaData = portData->data(
5013 widthFormulaColumn);
5014 const DataObject& loadPortData = portData->data(loadPortColumn);
5015 const DataObject& guardPortData = portData->data(guardPortColumn);
5016
5017 string portName = portNameData.stringValue();
5018 string widthFormula = widthFormulaData.stringValue();
5019 string loadPort = loadPortData.stringValue();
5020 string guardPort = guardPortData.stringValue();
5021 string architecturePort = resolveArchitecturePort(
5022 architecture, entryID, portName);
5024 portName, architecturePort, widthFormula, loadPort, guardPort,
5026 }
5027
5028 delete portData;
5029 portData = NULL;
5030}
5031
5032
5033/**
5034 * Adds external ports to the given FU implementation which is the
5035 * implementation of the FU entry that has the given ID.
5036 *
5037 * @param implementation The implementation.
5038 * @param entryID ID of the FU entry.
5039 */
5040void
5043 RowID entryID) const {
5044
5045 RelationalDBQueryResult* extPortData = NULL;
5046 try {
5047 extPortData = dbConnection_->query(fuExternalPortsByIDQuery(entryID));
5048 } catch (const Exception& e) {
5049 assert(false);
5050 }
5051
5052 int extPortNameColumn = extPortData->column("fu_external_port.name");
5053 int directionColumn = extPortData->column(
5054 "fu_external_port.direction");
5055 int extPortWidthFormulaColumn = extPortData->column(
5056 "fu_external_port.width_formula");
5057 int descriptionColumn = extPortData->column(
5058 "fu_external_port.description");
5059
5060 while (extPortData->hasNext()) {
5061 extPortData->next();
5062 const DataObject& nameData = extPortData->data(
5063 extPortNameColumn);
5064 const DataObject& directionData = extPortData->data(
5065 directionColumn);
5066 const DataObject& widthFormulaData = extPortData->data(
5067 extPortWidthFormulaColumn);
5068 const DataObject& descriptionData = extPortData->data(
5069 descriptionColumn);
5070
5071 string name = nameData.stringValue();
5072 string widthFormula = widthFormulaData.stringValue();
5073 string description = descriptionData.stringValue();
5074
5075 Direction direction;
5076 if (directionData.stringValue() == IN_DIRECTION) {
5077 direction = IN;
5078 } else if (directionData.stringValue() == OUT_DIRECTION) {
5079 direction = OUT;
5080 } else {
5081 assert(directionData.stringValue() == BIDIR_DIRECTION);
5082 direction = BIDIR;
5083 }
5084
5085 new FUExternalPort(
5086 name, direction, widthFormula, description, implementation);
5087 }
5088
5089 delete extPortData;
5090 extPortData = NULL;
5091
5092 // add parameter dependencies
5093 for (int i = 0; i < implementation.externalPortCount(); i++) {
5094 FUExternalPort& port = implementation.externalPort(i);
5095 try {
5097 std::string(
5098 "SELECT fu_implementation_parameter.name FROM "
5099 "fu_implementation_parameter, fu_external_port, "
5100 "fu_ext_port_parameter_dependency, fu_implementation "
5101 "WHERE fu_implementation.fu=" +
5102 Conversion::toString(entryID) +
5103 " AND fu_external_port.fu_impl=fu_implementation.id AND "
5104 "fu_external_port.name=\"" + port.name() +
5105 "\" AND fu_ext_port_parameter_dependency.port="
5106 "fu_external_port.id AND fu_implementation_parameter.id="
5107 "fu_ext_port_parameter_dependency.parameter;"));
5108 while (result->hasNext()) {
5109 result->next();
5110 const DataObject& paramData = result->data(0);
5111 port.setParameterDependency(paramData.stringValue());
5112 }
5113 delete result;
5114 } catch (const Exception& e) {
5116 assert(false);
5117 }
5118 }
5119}
5120
5121/**
5122 * Adds external ports to the given RF implementation which is the
5123 * implementation of the RF entry that has the given ID.
5124 *
5125 * @param implementation The implementation.
5126 * @param entryID ID of the RF implementation entry.
5127 */
5128void
5131 RowID entryID) const {
5132
5133 if (!dbConnection_->tableExistsInDB("rf_external_port")) {
5134 return;
5135 }
5136
5137 RelationalDBQueryResult* extPortData = NULL;
5138 try {
5139 extPortData = dbConnection_->query(rfExternalPortsByIDQuery(entryID));
5140 } catch (const Exception& e) {
5141 assert(false);
5142 }
5143
5144 int extPortNameColumn = extPortData->column("rf_external_port.name");
5145 int directionColumn = extPortData->column(
5146 "rf_external_port.direction");
5147 int extPortWidthFormulaColumn = extPortData->column(
5148 "rf_external_port.width_formula");
5149 int descriptionColumn = extPortData->column(
5150 "rf_external_port.description");
5151
5152 while (extPortData->hasNext()) {
5153 extPortData->next();
5154 const DataObject& nameData = extPortData->data(
5155 extPortNameColumn);
5156 const DataObject& directionData = extPortData->data(
5157 directionColumn);
5158 const DataObject& widthFormulaData = extPortData->data(
5159 extPortWidthFormulaColumn);
5160 const DataObject& descriptionData = extPortData->data(
5161 descriptionColumn);
5162
5163 string name = nameData.stringValue();
5164 string widthFormula = widthFormulaData.stringValue();
5165 string description = descriptionData.stringValue();
5166
5167 Direction direction;
5168 if (directionData.stringValue() == IN_DIRECTION) {
5169 direction = IN;
5170 } else if (directionData.stringValue() == OUT_DIRECTION) {
5171 direction = OUT;
5172 } else {
5173 assert(directionData.stringValue() == BIDIR_DIRECTION);
5174 direction = BIDIR;
5175 }
5176
5177 new RFExternalPort(
5178 name, direction, widthFormula, description, implementation);
5179 }
5180
5181 delete extPortData;
5182 extPortData = NULL;
5183
5184 // add parameter dependencies
5185 if (!dbConnection_->tableExistsInDB("rf_ext_port_parameter_dependency")) {
5186 return;
5187 }
5188
5189 for (int i = 0; i < implementation.externalPortCount(); i++) {
5190 RFExternalPort& port = implementation.externalPort(i);
5191 try {
5193 std::string(
5194 "SELECT rf_implementation_parameter.name FROM "
5195 "rf_implementation_parameter, rf_external_port, "
5196 "rf_ext_port_parameter_dependency, rf_implementation "
5197 "WHERE rf_implementation.rf=" +
5198 Conversion::toString(entryID) +
5199 " AND rf_external_port.rf_impl=rf_implementation.id AND "
5200 "rf_external_port.name=\"" + port.name() +
5201 "\" AND rf_ext_port_parameter_dependency.port="
5202 "rf_external_port.id AND rf_implementation_parameter.id="
5203 "rf_ext_port_parameter_dependency.parameter;"));
5204 while (result->hasNext()) {
5205 result->next();
5206 const DataObject& paramData = result->data(0);
5207 port.setParameterDependency(paramData.stringValue());
5208 }
5209 delete result;
5210 } catch (const Exception& e) {
5212 assert(false);
5213 }
5214 }
5215}
5216
5217
5218/**
5219 * Adds parameters to the given FU implementation which is the implementation
5220 * of the FU entry that has the given ID.
5221 *
5222 * @param implementation The implementation.
5223 * @param entryID ID of the FU entry.
5224 */
5225void
5228 RowID entryID) const {
5229
5230 RelationalDBQueryResult* result = NULL;
5231 try {
5232 result = dbConnection_->query(
5234 } catch (const Exception&) {
5235 assert(false);
5236 }
5237
5238 while (result->hasNext()) {
5239 result->next();
5240 const DataObject& nameData = result->data("name");
5241 const DataObject& typeData = result->data("type");
5242 const DataObject& valueData = result->data("value");
5243 string name = nameData.stringValue();
5244 string type = typeData.stringValue();
5245 string value = valueData.stringValue();
5246 implementation.addParameter(name, type, value);
5247 }
5248 delete result;
5249}
5250
5251
5252/**
5253 * Adds parameters to the given RF implementation which is the implementation
5254 * of the RF entry that has the given ID.
5255 *
5256 * @param implementation The implementation.
5257 * @param entryID ID of the RF entry.
5258 */
5259void
5262 RowID entryID) const {
5263
5264 if (!dbConnection_->tableExistsInDB("rf_implementation_parameter")) {
5265 // Add implicit parameters: size and width parameters if older
5266 // hdb is opened.
5267 if (implementation.widthParameter() != "") {
5268 implementation.addParameter(implementation.widthParameter(),
5269 "integer", "");
5270 }
5271 if (implementation.sizeParameter() != "") {
5272 implementation.addParameter(implementation.sizeParameter(),
5273 "integer", "");
5274 }
5275 return;
5276 }
5277
5278 RelationalDBQueryResult* result = NULL;
5279 try {
5280 result = dbConnection_->query(
5282 } catch (const Exception&) {
5283 assert(false);
5284 }
5285
5286 while (result->hasNext()) {
5287 result->next();
5288 const DataObject& nameData = result->data("name");
5289 const DataObject& typeData = result->data("type");
5290 const DataObject& valueData = result->data("value");
5291 string name = nameData.stringValue();
5292 string type = typeData.stringValue();
5293 string value = valueData.stringValue();
5294 implementation.addParameter(name, type, value);
5295 }
5296
5297 // If RF implementation's size and width parameter dependencies do not have
5298 // parameter defined, add default parameters for them.
5299 if (implementation.widthParameter() != "" &&
5300 !implementation.hasParameter(implementation.widthParameter())) {
5301 implementation.addParameter(implementation.widthParameter(),
5302 "integer", "");
5303 implementation.addParameter(implementation.sizeParameter(),
5304 "integer", "");
5305 }
5306 if (implementation.sizeParameter() != "" &&
5307 !implementation.hasParameter(implementation.sizeParameter())) {
5308 implementation.addParameter(implementation.sizeParameter(),
5309 "integer", "");
5310 }
5311 delete result;
5312}
5313
5314
5315/**
5316 * Adds the block implementation files to the given FU implementation which
5317 * is the implementation of the FU entry that has the given ID.
5318 *
5319 * @param implementation The implementation.
5320 * @param entryID ID of the FU entry.
5321 */
5322void
5325 RowID entryID) const {
5326
5327 RelationalDBQueryResult* sourceFileData = NULL;
5328 try {
5329 sourceFileData = dbConnection_->query(
5330 fuSourceFilesByIDQuery(entryID));
5331 } catch (const Exception&) {
5332 assert(false);
5333 }
5334
5335 int fileColumn = sourceFileData->column("block_source_file.file");
5336 int formatColumn = sourceFileData->column("format.format");
5337
5338 while (sourceFileData->hasNext()) {
5339 sourceFileData->next();
5340 const DataObject& fileData = sourceFileData->data(fileColumn);
5341 const DataObject& formatData = sourceFileData->data(
5342 formatColumn);
5344 formatData.stringValue());
5346 fileData.stringValue(), format);
5347 implementation.addImplementationFile(file);
5348 }
5349
5350 delete sourceFileData;
5351 sourceFileData = NULL;
5352}
5353
5354
5355/**
5356 * Adds data ports to the given RF implementation which is the implementation
5357 * of the RF entry that has the given ID.
5358 *
5359 * @param implementation The implementation.
5360 * @param entryID ID of the RF entry.
5361 */
5362void
5365 RowID entryID) const {
5366
5367 // obtain port data from HDB and add ports to RF implementation
5368 RelationalDBQueryResult* portData = NULL;
5369 try {
5370 portData = dbConnection_->query(
5372 } catch (const Exception& e) {
5374 assert(false);
5375 }
5376
5377 int portNameColumn = portData->column("name");
5378 int directionColumn = portData->column("direction");
5379 int loadPortColumn = portData->column("load_port");
5380 int opcodePortColumn = portData->column("opcode_port");
5381 int opcodePortFormulaColumn = portData->column(
5382 "opcode_port_width_formula");
5387 assert(
5388 opcodePortFormulaColumn != RelationalDBQueryResult::UNKNOWN_INDEX);
5389
5390 while (portData->hasNext()) {
5391 portData->next();
5392 const DataObject& portNameData = portData->data(portNameColumn);
5393 const DataObject& directionData = portData->data(
5394 directionColumn);
5395 const DataObject& loadPortData = portData->data(loadPortColumn);
5396 const DataObject& opcodePortData = portData->data(
5397 opcodePortColumn);
5398 const DataObject& opcodePortFormulaData = portData->data(
5399 opcodePortFormulaColumn);
5400 Direction direction;
5401 if (directionData.stringValue() == IN_DIRECTION) {
5402 direction = IN;
5403 } else if (directionData.stringValue() == OUT_DIRECTION) {
5404 direction = OUT;
5405 } else if (directionData.stringValue() == BIDIR_DIRECTION) {
5406 direction = BIDIR;
5407 } else {
5408 assert(false);
5409 }
5411 portNameData.stringValue(), direction,
5412 loadPortData.stringValue(), opcodePortData.stringValue(),
5413 opcodePortFormulaData.stringValue(), implementation);
5414 }
5415
5416 delete portData;
5417 portData = NULL;
5418}
5419
5420
5421/**
5422 * Adds the block implementation files to the given RF implementation which
5423 * is the implementation of the RF entry that has the given ID.
5424 *
5425 * @param implementation The implementation.
5426 * @param entryID ID of the RF entry.
5427 */
5428void
5431 RowID entryID) const {
5432
5433 RelationalDBQueryResult* result = NULL;
5434 try {
5435 result = dbConnection_->query(rfSourceFilesByIDQuery(entryID));
5436 } catch (const Exception&) {
5437 assert(false);
5438 }
5439
5440 int fileColumn = result->column("block_source_file.file");
5441 int formatColumn = result->column("format.format");
5442
5443 while (result->hasNext()) {
5444 result->next();
5445 const DataObject& fileData = result->data(fileColumn);
5446 const DataObject& formatData = result->data(formatColumn);
5448 formatData.stringValue());
5450 fileData.stringValue(), format);
5451 implementation.addImplementationFile(file);
5452 }
5453
5454 delete result;
5455 result = NULL;
5456}
5457
5458
5459/**
5460 * Removes the cost estimation data that has the given ID.
5461 *
5462 * @param id ID of the cost estimation data.
5463 */
5464void
5466 try {
5468 std::string(
5469 "DELETE FROM cost_estimation_data "
5470 "WHERE id=" + Conversion::toString(id) + ";"));
5471 } catch (const Exception& e) {
5473 assert(false);
5474 }
5475}
5476
5477
5478/**
5479 * Adds the given block implementation file to the HDB.
5480 *
5481 * @param file The file to add.
5482 */
5483void
5485 const BlockImplementationFile& file) const {
5488 std::string(
5489 "INSERT INTO block_source_file(id,file,format) "
5490 "VALUES(NULL,\"" + file.pathToFile() +
5491 "\",(SELECT id FROM format WHERE format=\"" +
5492 formatString(file.format()) + "\"));"));
5493 }
5494}
5495
5496/**
5497 * Checks whether the given FU has a mathing architecture with the given FU
5498 * architecture instance.
5499 *
5500 * @param fu The function unit.
5501 * @param arch The FU architecture.
5502 * @return True if the architectures match, otherwise false.
5503 */
5504bool
5506 const TTAMachine::FunctionUnit& fu,
5507 const FUArchitecture& arch) {
5508
5509 if (fu.operationCount() != arch.architecture().operationCount()) {
5510 return false;
5511 }
5512
5513 std::map<const FUPort*, const FUPort*> portMap;
5514 for (int i = 0; i < fu.operationPortCount(); i++) {
5515 portMap.insert(
5516 std::pair<const FUPort*, const FUPort*>(
5517 fu.operationPort(i), NULL));
5518 }
5519
5520 PipelineElementUsageTable plineElementUsages;
5521
5522 for (int i = 0; i < fu.operationCount(); i++) {
5523 HWOperation* operation = fu.operation(i);
5524 if (!arch.architecture().hasOperation(operation->name())) {
5525 return false;
5526 }
5527 HWOperation* archOp = arch.architecture().operation(
5528 operation->name());
5529 if (operation->latency() != archOp->latency()) {
5530 return false;
5531 }
5532
5533 // check operand bindings
5534 for (int i = 0; i < fu.operationPortCount(); i++) {
5535 FUPort* port = fu.operationPort(i);
5536 if (operation->isBound(*port)) {
5537 int io = operation->io(*port);
5538 FUPort* samePort = archOp->port(io);
5539 if (samePort == NULL) {
5540 return false;
5541 }
5542 const FUPort* existingSamePort =
5544 if (existingSamePort != NULL &&
5545 existingSamePort != samePort) {
5546 return false;
5547 }
5548
5549 // check the width of the ports
5550 if (!arch.hasParameterizedWidth(samePort->name()) &&
5551 samePort->width() != port->width()) {
5552 return false;
5553 }
5554
5555 if (port->isOpcodeSetting() != samePort->isOpcodeSetting() ||
5556 port->isTriggering() != samePort->isTriggering()) {
5557 return false;
5558 }
5559 portMap.erase(port);
5560 portMap.insert(
5561 std::pair<const FUPort*, const FUPort*>(port, samePort));
5562 }
5563 }
5564
5565 // check operation pipeline
5566 ExecutionPipeline* opPipeline = operation->pipeline();
5567 ExecutionPipeline* archOpPipeline = archOp->pipeline();
5568 for (int cycle = 0; cycle < operation->latency(); cycle++) {
5570 opPipeline->writtenOperands(cycle);
5572 archOpPipeline->writtenOperands(cycle);
5573 if (written1 != written2) {
5574 return false;
5575 }
5577 opPipeline->readOperands(cycle);
5579 archOpPipeline->readOperands(cycle);
5580 if (read1 != read2) {
5581 return false;
5582 }
5583
5585 for (int i = 0; i < fu.pipelineElementCount(); i++) {
5586 const PipelineElement* elem = fu.pipelineElement(i);
5587 if (opPipeline->isResourceUsed(elem->name(),cycle)) {
5588 usage.usage1.insert(elem);
5589 }
5590 }
5591
5592 for (int i = 0; i < arch.architecture().pipelineElementCount();
5593 i++) {
5594 const PipelineElement* elem =
5595 arch.architecture().pipelineElement(i);
5596 if (archOpPipeline->isResourceUsed(elem->name(), cycle)) {
5597 usage.usage2.insert(elem);
5598 }
5599 }
5600
5601 plineElementUsages.push_back(usage);
5602 }
5603 }
5604
5605 return areCompatiblePipelines(plineElementUsages);
5606}
5607
5608
5609/**
5610 * Checks whether the pipeline element usages of the given table are
5611 * compatible.
5612 *
5613 * They are compatible if the first pipeline is more restrictive or
5614 * equal to the second pipeline.
5615 *
5616 * @param table The table that describes the pipeline usages.
5617 * @return True if the pipelines are compatible, otherwise false.
5618 */
5619bool
5621
5622 for (size_t i = 0; i < table.size(); i++) {
5623 std::set<const PipelineElement*> usedResources1 = table[i].usage1;
5624 // create a set of vector indices which mean what stages cannot be
5625 // executed at the same time
5626 std::set<size_t> illegalStages1;
5627 for (size_t usageIndex = 0; usageIndex < table.size();
5628 usageIndex++) {
5629 if (usageIndex == i) {
5630 continue;
5631 }
5632 std::set<const PipelineElement*> resources =
5633 table[usageIndex].usage1;
5634 std::set<const PipelineElement*> intersect;
5635 SetTools::intersection(usedResources1, resources, intersect);
5636 if (!intersect.empty()) {
5637 illegalStages1.insert(usageIndex);
5638 }
5639 }
5640
5641 // create a similar vector of the other pipeline
5642 std::set<const PipelineElement*> usedResources2 = table[i].usage2;
5643 std::set<size_t> illegalStages2;
5644 for (size_t usageIndex = 0; usageIndex < table.size();
5645 usageIndex++) {
5646 if (usageIndex == i) {
5647 continue;
5648 }
5649 std::set<const PipelineElement*> resources =
5650 table[usageIndex].usage2;
5651 std::set<const PipelineElement*> intersect;
5652 SetTools::intersection(usedResources2, resources, intersect);
5653 if (!intersect.empty()) {
5654 illegalStages2.insert(usageIndex);
5655 }
5656 }
5657
5658 std::set<size_t> difference;
5659 AssocTools::difference(illegalStages2, illegalStages1, difference);
5660 if (!difference.empty()) {
5661 return false;
5662 }
5663 }
5664
5665 return true;
5666}
5667
5668
5669/**
5670 * Inserts the supported formats to the format table.
5671 *
5672 * @param connection The connection used when inserting the formats.
5673 */
5674void
5676 try {
5677 connection.updateQuery(
5678 std::string(
5679 "INSERT INTO format(id,format) VALUES(1,\"" +
5680 VHDL_FORMAT + "\");"));
5681 connection.updateQuery(
5682 std::string(
5683 "INSERT INTO format(id,format) VALUES(2,\"" +
5684 VERILOG_FORMAT + "\");"));
5685 } catch (const Exception& e) {
5687 assert(false);
5688 }
5689}
5690
5691
5692/**
5693 * Returns the format corresponding to the given string which is stored in
5694 * the database.
5695 *
5696 * @param formatString The format string stored in the database.
5697 * @return The format.
5698 */
5700HDBManager::fileFormat(const std::string& formatString) {
5701 if (formatString == VHDL_FORMAT) {
5703 } else if (formatString == VERILOG_FORMAT) {
5705 } else if (formatString == VHDL_SIM_FORMAT) {
5707 } else if (formatString == VERILOG_SIM_FORMAT) {
5709 }
5710 assert(false);
5711 // dummy return to avoid whining with some compilers
5713}
5714
5715
5716/**
5717 * Returns the string used to represent the given file format in HDB.
5718 *
5719 * @param format The format.
5720 * @return The string.
5721 */
5722std::string
5724 if (format == BlockImplementationFile::VHDL) {
5725 return VHDL_FORMAT;
5726 } else if (format == BlockImplementationFile::Verilog) {
5727 return VERILOG_FORMAT;
5728 } else if (format == BlockImplementationFile::VHDLsim) {
5729 return VHDL_SIM_FORMAT;
5730 } else if (format == BlockImplementationFile::Verilogsim) {
5731 return VERILOG_SIM_FORMAT;
5732 }
5733
5734 // dummy return to avoid compiler whining
5735 assert(false);
5736 return "";
5737}
5738
5739
5740/**
5741 * Returns the string used to represent the given direction in HDB.
5742 *
5743 * @param direction The direction.
5744 * @return The string.
5745 */
5746std::string
5748 if (direction == HDB::IN) {
5749 return IN_DIRECTION;
5750 } else if (direction == HDB::OUT) {
5751 return OUT_DIRECTION;
5752 } else {
5753 return BIDIR_DIRECTION;
5754 }
5755}
5756
5757
5758/**
5759 * Creates an SQL query for getting the FU entry that has the given ID.
5760 *
5761 * The result set has fields {id, architecture, cost_function}.
5762 *
5763 * @param id ID of the entry.
5764 * @return The SQL query.
5765 */
5766std::string
5768 string idString = Conversion::toString(id);
5769 string query =
5770 "SELECT * "
5771 "FROM fu "
5772 "WHERE fu.id=" + idString + ";";
5773 return query;
5774}
5775
5776
5777/**
5778 * Creates an SQL query for getting the RF entry that has the given ID.
5779 *
5780 * The result set has fields {id, architecture, cost_function}.
5781 *
5782 * @param id ID of the entry.
5783 * @return The SQL query.
5784 */
5785std::string
5787 string idString = Conversion::toString(id);
5788 string query =
5789 "SELECT * "
5790 "FROM rf "
5791 "WHERE rf.id=" + idString + ";";
5792 return query;
5793}
5794
5795
5796/**
5797 * Creates an SQL query for getting the Bus entry that has the given ID.
5798 *
5799 * The result set has fields {id}.
5800 *
5801 * @param id ID of the entry.
5802 * @return The SQL query.
5803 */
5804std::string
5806 string idString = Conversion::toString(id);
5807 string query =
5808 "SELECT * "
5809 "FROM bus "
5810 "WHERE bus.id=" + idString + ";";
5811 return query;
5812}
5813
5814
5815/**
5816 * Creates an SQL query for getting the Socket entry that has the given ID.
5817 *
5818 * The result set has fields {id}.
5819 *
5820 * @param id ID of the entry.
5821 * @return The SQL query.
5822 */
5823std::string
5825 string idString = Conversion::toString(id);
5826 string query =
5827 "SELECT * "
5828 "FROM socket "
5829 "WHERE socket.id=" + idString + ";";
5830 return query;
5831}
5832
5833
5834/**
5835 * Creates an SQL query for getting the architecture of the FU entry that
5836 * has the given ID.
5837 *
5838 * The result set has all the fields of fu_architecture.
5839 *
5840 * @param id ID of the FU entry.
5841 */
5842std::string
5844 string idString = Conversion::toString(id);
5845 string query =
5846 "SELECT * "
5847 "FROM fu, fu_architecture "
5848 "WHERE fu.id=" + idString + " AND"
5849 " fu_architecture.id = fu.architecture;";
5850 return query;
5851}
5852
5853
5854/**
5855 * Creates an SQL query for getting the architectural ports and their
5856 * operand bindings of the FU architecture that has the given ID.
5857 *
5858 * The result table has fields {fu_data_port.id, fu_data_port.triggers,
5859 * fu_data_port.sets-opcode, fu_data_port.guard_support,
5860 * fu_data_port.width, operation.name,
5861 * io_binding.io_number}
5862 *
5863 * @param id The ID of the FU architecture.
5864 */
5865std::string
5867 string idString = Conversion::toString(id);
5868 string query =
5869 "SELECT fu_data_port.id AS 'fu_data_port.id',"
5870 " fu_data_port.triggers AS 'fu_data_port.triggers',"
5871 " fu_data_port.sets_opcode AS 'fu_data_port.sets_opcode',"
5872 " fu_data_port.guard_support AS 'fu_data_port.guard_support',"
5873 " fu_data_port.width AS 'fu_data_port.width',"
5874 " operation.name AS 'operation.name',"
5875 " io_binding.io_number AS 'io_binding.io_number' "
5876 "FROM fu_data_port, io_binding, operation "
5877 "WHERE fu_data_port.fu_arch=" + idString + " AND"
5878 " io_binding.port=fu_data_port.id AND"
5879 " io_binding.operation=operation.id;";
5880 return query;
5881}
5882
5883
5884/**
5885 * Creates an SQL query for getting the IO usage data of pipelines of
5886 * operations contained in the FU architecture that has the given ID.
5887 *
5888 * The result table has fields {operation.name, io_usage.cycle,
5889 * io_usage.io_number, io_usage.action}.
5890 *
5891 * @param id ID of the FU architecture in HDB.
5892 */
5893std::string
5895 string idString = Conversion::toString(id);
5896 string query =
5897 "SELECT operation.name AS 'operation.name',"
5898 " io_usage.cycle AS 'io_usage.cycle',"
5899 " io_usage.io_number AS 'io_usage.io_number',"
5900 " io_usage.action AS 'io_usage.action' "
5901 "FROM operation_pipeline, io_usage, operation "
5902 "WHERE operation_pipeline.fu_arch=" + idString + " AND"
5903 " io_usage.pipeline=operation_pipeline.id AND"
5904 " operation.id=operation_pipeline.operation;";
5905 return query;
5906}
5907
5908
5909/**
5910 * Creates an SQL query for getting resource usage data of pipelines
5911 * of the FU architecture that has the given ID.
5912 *
5913 * The result table has fields {operation.name,
5914 * pipeline_resource_usage.cycle, pipeline_resource.id}
5915 *
5916 * @param id ID of the FU architecture in HDB.
5917 */
5918std::string
5920 string idString = Conversion::toString(id);
5921 string query =
5922 "SELECT operation.name AS 'operation.name',"
5923 " pipeline_resource_usage.cycle AS "
5924 " 'pipeline_resource_usage.cycle',"
5925 " pipeline_resource.id AS 'pipeline_resource.id' "
5926 "FROM pipeline_resource_usage, pipeline_resource, operation,"
5927 " operation_pipeline "
5928 "WHERE operation_pipeline.fu_arch=" + idString + " AND"
5929 " pipeline_resource_usage.pipeline=operation_pipeline.id AND"
5930 " pipeline_resource.id = pipeline_resource_usage.resource AND"
5931 " operation.id=operation_pipeline.operation;";
5932 return query;
5933}
5934
5935
5936/**
5937 * Creates an SQL query for getting FU implementation data of the FU that has
5938 * the given ID.
5939 *
5940 * The result table has fields {fu_implementation.id, fu_implementation.name,
5941 * fu_implementation.opcode_port, fu_implementation.clk_port,
5942 * fu_implementation.rst_port, fu_implementation.glock_port,
5943 * fu_implementation.glock_req_port}.
5944 *
5945 * @param id ID of the FU entry in HDB.
5946 */
5947std::string
5949 string idString = Conversion::toString(id);
5950 string query =
5951 "SELECT fu_implementation.id AS 'fu_implementation.id',"
5952 " fu_implementation.name AS 'fu_implementation.name',"
5953 " fu_implementation.opcode_port AS "
5954 "'fu_implementation.opcode_port',"
5955 " fu_implementation.clk_port AS 'fu_implementation.clk_port',"
5956 " fu_implementation.rst_port AS 'fu_implementation.rst_port',"
5957 " fu_implementation.glock_port AS "
5958 " 'fu_implementation.glock_port',"
5959 " fu_implementation.glock_req_port AS "
5960 " 'fu_implementation.glock_req_port' "
5961 "FROM fu, fu_implementation "
5962 "WHERE fu.id=" + idString + " AND"
5963 " fu_implementation.fu=fu.id;";
5964 return query;
5965}
5966
5967
5968/**
5969 * Creates an SQL query for getting operation code data of the FU that has the
5970 * given ID.
5971 *
5972 * The result table has fields {operation.name, opcode_map.opcode}.
5973 *
5974 * @param id ID of the FU entry in HDB.
5975 */
5976std::string
5978 string idString = Conversion::toString(id);
5979 string query =
5980 "SELECT operation.name AS 'operation.name',"
5981 " opcode_map.opcode AS 'opcode_map.opcode' "
5982 "FROM fu, fu_implementation, operation, opcode_map "
5983 "WHERE fu.id=" + idString + " AND"
5984 " fu_implementation.fu=fu.id AND"
5985 " opcode_map.fu_impl=fu_implementation.id AND"
5986 " operation.id=opcode_map.operation;";
5987 return query;
5988}
5989
5990
5991/**
5992 * Creates an SQL qury for getting data port data of implementation of
5993 * the FU that has the given ID.
5994 *
5995 * The result table has fields {fu_port_map.name,
5996 * fu_port_map.width_formula, fu_port_map.load_port,
5997 * fu_port_map.guard_port}
5998 *
5999 * @param id ID of the FU entry in HDB.
6000 */
6001std::string
6003 string idString = Conversion::toString(id);
6004 string query =
6005 "SELECT fu_port_map.name AS 'fu_port_map.name',"
6006 " fu_port_map.width_formula AS 'fu_port_map.width_formula',"
6007 " fu_port_map.load_port AS 'fu_port_map.load_port',"
6008 " fu_port_map.guard_port AS 'fu_port_map.guard_port' "
6009 "FROM fu, fu_port_map, fu_implementation "
6010 "WHERE fu.id=" + idString + " AND"
6011 " fu_implementation.fu=fu.id AND"
6012 " fu_port_map.fu_impl=fu_implementation.id;";
6013 return query;
6014}
6015
6016
6017/**
6018 * Creates an SQL query for getting external port data of implementation of
6019 * the FU that has the given ID.
6020 *
6021 * The result table has fields {fu_external_port.name,
6022 * fu_external_port.direction, fu_external_port.width_formula,
6023 * fu_external_port.description}.
6024 *
6025 * @param id ID of the FU entry in HDB.
6026 * @return The SQL query.
6027 */
6028std::string
6030 string idString = Conversion::toString(id);
6031 string query =
6032 "SELECT fu_external_port.name AS 'fu_external_port.name',"
6033 " fu_external_port.direction AS 'fu_external_port.direction',"
6034 " fu_external_port.width_formula AS "
6035 " 'fu_external_port.width_formula',"
6036 " fu_external_port.description AS "
6037 " 'fu_external_port.description' "
6038 "FROM fu, fu_implementation, fu_external_port "
6039 "WHERE fu.id=" + idString + " AND"
6040 " fu_implementation.fu=fu.id AND"
6041 " fu_external_port.fu_impl=fu_implementation.id;";
6042 return query;
6043}
6044
6045
6046/**
6047 * Creates an SQL query for getting external port data of implementation of
6048 * the RF that has the given ID.
6049 *
6050 * The result table has fields {rf_external_port.name,
6051 * rf_external_port.direction, rf_external_port.width_formula,
6052 * rf_external_port.description}.
6053 *
6054 * @param id ID of the RF entry in HDB.
6055 * @return The SQL query.
6056 */
6057std::string
6059 string idString = Conversion::toString(id);
6060 string query =
6061 "SELECT rf_external_port.name AS 'rf_external_port.name',"
6062 " rf_external_port.direction AS 'rf_external_port.direction',"
6063 " rf_external_port.width_formula AS "
6064 " 'rf_external_port.width_formula',"
6065 " rf_external_port.description AS "
6066 " 'rf_external_port.description' "
6067 "FROM rf, rf_implementation, rf_external_port "
6068 "WHERE rf.id=" + idString + " AND"
6069 " rf_implementation.rf=rf.id AND"
6070 " rf_external_port.rf_impl=rf_implementation.id;";
6071 return query;
6072}
6073
6074
6075/**
6076 * Creates an SQL query for getting the parameters of the implementation
6077 * of the FU that has the given ID.
6078 *
6079 * The result table has fields {name, type, value}.
6080 *
6081 * @param id ID of the FU implementation entry.
6082 * @return The SQL query.
6083 */
6084std::string
6086 string idString = Conversion::toString(id);
6087 string query =
6088 "SELECT fu_implementation_parameter.name AS 'name',"
6089 " fu_implementation_parameter.type AS 'type',"
6090 " fu_implementation_parameter.value AS 'value' "
6091 "FROM fu_implementation, fu_implementation_parameter "
6092 "WHERE fu_implementation.fu=" + idString + " AND"
6093 " fu_implementation_parameter.fu_impl=fu_implementation.id;";
6094 return query;
6095}
6096
6097
6098/**
6099 * Creates an SQL query for getting the parameters of the implementation
6100 * of the RF that has the given ID.
6101 *
6102 * The result table has fields {name, type, value}.
6103 *
6104 * @param id ID of the RF entry.
6105 * @return The SQL query.
6106 */
6107std::string
6109 string idString = Conversion::toString(id);
6110 string query =
6111 "SELECT rf_implementation_parameter.name AS 'name',"
6112 " rf_implementation_parameter.type AS 'type',"
6113 " rf_implementation_parameter.value AS 'value' "
6114 "FROM rf_implementation, rf_implementation_parameter "
6115 "WHERE rf_implementation.rf=" + idString + " AND"
6116 " rf_implementation_parameter.rf_impl=rf_implementation.id;";
6117 return query;
6118}
6119
6120
6121/**
6122 * Creates an SQL query for getting io binding data of port that has
6123 * the given name.
6124 *
6125 * The result table has fields {operation.name, io_binding.io_number}.
6126 *
6127 * @param fuID ID of the FU entry.
6128 * @param portName Name of the implemented port.
6129 * @return The SQL query.
6130 */
6131std::string
6133 RowID fuID,
6134 const std::string& portName) {
6135
6136 string idString = Conversion::toString(fuID);
6137 string query =
6138 "SELECT operation.name AS 'operation.name',"
6139 " io_binding.io_number AS 'io_binding.io_number' "
6140 "FROM operation, io_binding, fu_port_map, fu_implementation "
6141 "WHERE fu_implementation.fu=" + idString + " AND"
6142 " fu_port_map.fu_impl=fu_implementation.id AND"
6143 " fu_port_map.name='" + portName + "' AND"
6144 " io_binding.port=fu_port_map.arch_port AND"
6145 " operation.id=io_binding.operation;";
6146 return query;
6147}
6148
6149
6150/**
6151 * Creates an SQL query for getting the block source files of the FU
6152 * entry that has the given ID.
6153 *
6154 * The result table has fields {block_source_file.file, format.format}.
6155 *
6156 * @param id ID of the FU entry.
6157 * @return The SQL query.
6158 */
6159std::string
6161 string idString = Conversion::toString(id);
6162 string query =
6163 "SELECT block_source_file.file AS 'block_source_file.file',"
6164 " format.format AS 'format.format' "
6165 "FROM block_source_file, fu_source_file, fu_implementation, format "
6166 "WHERE fu_implementation.fu=" + idString + " AND"
6167 " fu_source_file.fu_impl=fu_implementation.id AND"
6168 " block_source_file.id=fu_source_file.file AND"
6169 " format.id=block_source_file.format;";
6170 return query;
6171}
6172
6173
6174/**
6175 * Creates an SQL query for getting the architecture data of the RF
6176 * architecture that has the given ID.
6177 *
6178 * The result table has all the fields of rf_architecture table.
6179 *
6180 * @param id ID of the RF architecture.
6181 * @return The SQL query.
6182 */
6183std::string
6185 string idString = Conversion::toString(id);
6186 string query =
6187 "SELECT * "
6188 "FROM rf_architecture "
6189 "WHERE id=" + idString + ";";
6190 return query;
6191}
6192
6193
6194/**
6195 * Creates an SQL query for getting the implementation of the RF entry that
6196 * has the given ID.
6197 *
6198 * The result table has fields {id, name, size_param, width_param,
6199 * clk_port, rst_port, glock_port, guard_port}.
6200 *
6201 * @param id The ID of the RF entry.
6202 * @return The SQL query.
6203 */
6204std::string
6206 string idString = Conversion::toString(id);
6207 string query =
6208 "SELECT id,"
6209 " name,"
6210 " size_param,"
6211 " width_param,"
6212 " clk_port,"
6213 " rst_port,"
6214 " glock_port,"
6215 " guard_port "
6216 "FROM rf_implementation "
6217 "WHERE rf_implementation.rf=" + idString + ";";
6218 return query;
6219}
6220
6221/**
6222 * Same as rfImplementationByIDQuery() bus has additional field for separate
6223 * address cycle.
6224 *
6225 * The result table has fields {id, name, size_param, width_param,
6226 * clk_port, rst_port, glock_port, guard_port, sac_param}.
6227 *
6228 * @param id The ID of the RF entry.
6229 * @return The SQL query.
6230 */
6231std::string
6233 string idString = Conversion::toString(id);
6234 string query =
6235 "SELECT id,"
6236 " name,"
6237 " size_param,"
6238 " width_param,"
6239 " clk_port,"
6240 " rst_port,"
6241 " glock_port,"
6242 " guard_port, "
6243 " sac_param "
6244 "FROM rf_implementation "
6245 "WHERE rf_implementation.rf=" + idString + ";";
6246 return query;
6247}
6248
6249/**
6250 * Creates an SQL query for getting the data ports of the implementation of
6251 * the RF entry that has the given ID.
6252 *
6253 * The result table has fields {name, direction, load_port, opcode_port,
6254 * opcode_port_width_formula}.
6255 *
6256 * @param id ID of the RF entry.
6257 * @return The SQL query.
6258 */
6259std::string
6261 string idString = Conversion::toString(id);
6262 string query =
6263 "SELECT rf_data_port.name AS 'name',"
6264 " rf_data_port.direction AS 'direction',"
6265 " rf_data_port.load_port AS 'load_port',"
6266 " rf_data_port.opcode_port AS 'opcode_port',"
6267 " rf_data_port.opcode_port_width_formula AS "
6268 " 'opcode_port_width_formula' "
6269 "FROM rf_data_port, rf_implementation "
6270 "WHERE rf_implementation.rf=" + idString + " AND"
6271 " rf_data_port.rf_impl=rf_implementation.id;";
6272 return query;
6273}
6274
6275
6276/**
6277 * Creates an SQL query for getting the block implementation files of the
6278 * RF entry that has the given ID.
6279 *
6280 * The result table has fields {block_source_file.file, format.format}.
6281 *
6282 * @param id ID of the RF entry.
6283 * @return The SQL query.
6284 */
6285std::string
6287 string idString = Conversion::toString(id);
6288 string query =
6289 "SELECT block_source_file.file AS 'block_source_file.file',"
6290 " format.format AS 'format.format' "
6291 "FROM block_source_file, format, rf_implementation, rf_source_file "
6292 "WHERE rf_implementation.rf=" + idString + " AND"
6293 " rf_source_file.rf_impl=rf_implementation.id AND"
6294 " block_source_file.id=rf_source_file.file AND"
6295 " format.id=block_source_file.format;";
6296 return query;
6297}
6298
6299
6300/**
6301 * Returns cost estimation data with the given id.
6302 *
6303 * @param entryId Id of the cost estimation data entry.
6304 * @return The data.
6305 * @exception KeyNotFound If the HDB does not contain cost estimation
6306 * data with the given arguments.
6307 */
6310 // make the SQL query to obtain implementation data
6311 RelationalDBQueryResult* queryResult = NULL;
6312 try {
6313 std::string theQuery =
6314 std::string(
6315 "SELECT value, cost_estimation_data.name AS data_name, "
6316 " cost_function_plugin.id AS plugin_id, "
6317 " fu_reference, rf_reference, bus_reference, "
6318 " socket_reference "
6319 "FROM cost_estimation_data, cost_function_plugin "
6320 "WHERE cost_estimation_data.plugin_reference="
6321 " cost_function_plugin.id AND "
6322 " cost_estimation_data.id = ") +
6323 Conversion::toString(entryId);
6324
6325 queryResult = dbConnection_->query(theQuery);
6326
6327 } catch (const Exception& e) {
6328 // should not throw in any case
6330 assert(false);
6331 }
6332
6333 if (queryResult->hasNext()) {
6334 queryResult->next();
6335
6336 std::string name = queryResult->data("data_name").stringValue();
6337
6338 CostEstimationData data;
6339 data.setName(name);
6340 data.setValue(queryResult->data("value"));
6341 data.setPluginID(queryResult->data("plugin_id").integerValue());
6342
6343 if (!queryResult->data("fu_reference").isNull()) {
6344 data.setFUReference(queryResult->data("fu_reference").integerValue());
6345 }
6346 if (!queryResult->data("rf_reference").isNull()) {
6347 data.setRFReference(queryResult->data("rf_reference").integerValue());
6348 }
6349 if (!queryResult->data("bus_reference").isNull()) {
6350 data.setBusReference(queryResult->data("bus_reference").integerValue());
6351 }
6352 if (!queryResult->data("socket_reference").isNull()) {
6353 data.setSocketReference(
6354 queryResult->data("socket_reference").integerValue());
6355 }
6356
6357 delete queryResult;
6358 queryResult = NULL;
6359
6360 return data;
6361 } else {
6362 delete queryResult;
6363 throw KeyNotFound(__FILE__, __LINE__, __func__);
6364 }
6365 // silence compiler warning
6366 throw 1;
6367}
6368
6369/**
6370 * Returns a set of cost estimation data IDs which reference the give FU
6371 * implementation.
6372 *
6373 * @param fuImplID ID of the FU implementation.
6374 * @return Set of cost estimation data IDs.
6375 */
6376std::set<RowID>
6378
6379 // make the SQL query to obtain IDs.
6380 RelationalDBQueryResult* queryResult = NULL;
6381 try {
6382 std::string theQuery =
6383 std::string(
6384 "SELECT id "
6385 "FROM cost_estimation_data "
6386 "WHERE fu_reference = ") +
6387 Conversion::toString(fuImplID);
6388
6389 queryResult = dbConnection_->query(theQuery);
6390
6391 } catch (const Exception& e) {
6392 // should not throw in any case
6394 assert(false);
6395 }
6396
6397 std::set<RowID> ids;
6398
6399 while (queryResult->hasNext()) {
6400 queryResult->next();
6401
6402 ids.insert(queryResult->data("id").integerValue());
6403 }
6404
6405 delete queryResult;
6406 queryResult = NULL;
6407 return ids;
6408}
6409
6410/**
6411 * Returns a set of cost estimation data IDs which reference the give RF
6412 * implementation.
6413 *
6414 * @param rfImplID ID of the RF implementation.
6415 * @return Set of cost estimation data IDs.
6416 */
6417std::set<RowID>
6419
6420 // make the SQL query to obtain IDs.
6421 RelationalDBQueryResult* queryResult = NULL;
6422 try {
6423 std::string theQuery =
6424 std::string(
6425 "SELECT id "
6426 "FROM cost_estimation_data "
6427 "WHERE rf_reference = ") +
6428 Conversion::toString(rfImplID);
6429
6430 queryResult = dbConnection_->query(theQuery);
6431
6432 } catch (const Exception& e) {
6433 // should not throw in any case
6435 assert(false);
6436 }
6437
6438 std::set<RowID> ids;
6439
6440 while (queryResult->hasNext()) {
6441 queryResult->next();
6442
6443 ids.insert(queryResult->data("id").integerValue());
6444 }
6445
6446 delete queryResult;
6447 queryResult = NULL;
6448 return ids;
6449}
6450
6451/**
6452 * Returns a set of cost estimation data IDs which reference the given
6453 * socket entry.
6454 *
6455 * @param socketID ID of the socket entry.
6456 * @return Set of cost estimation data IDs.
6457 */
6458std::set<RowID>
6460
6461 // make the SQL query to obtain IDs.
6462 RelationalDBQueryResult* queryResult = NULL;
6463 try {
6464 std::string theQuery =
6465 std::string(
6466 "SELECT id "
6467 "FROM cost_estimation_data "
6468 "WHERE socket_reference = ") +
6469 Conversion::toString(socketID);
6470
6471 queryResult = dbConnection_->query(theQuery);
6472
6473 } catch (const Exception& e) {
6474 // should not throw in any case
6476 assert(false);
6477 }
6478
6479 std::set<RowID> ids;
6480
6481 while (queryResult->hasNext()) {
6482 queryResult->next();
6483
6484 ids.insert(queryResult->data("id").integerValue());
6485 }
6486
6487 delete queryResult;
6488 queryResult = NULL;
6489 return ids;
6490}
6491
6492/**
6493 * Returns a set of cost estimation data IDs which reference the given
6494 * bus entry.
6495 *
6496 * @param busID ID of the bus entry.
6497 * @return Set of cost estimation data IDs.
6498 */
6499std::set<RowID>
6501
6502 // make the SQL query to obtain IDs.
6503 RelationalDBQueryResult* queryResult = NULL;
6504 try {
6505 std::string theQuery =
6506 std::string(
6507 "SELECT id "
6508 "FROM cost_estimation_data "
6509 "WHERE bus_reference = ") +
6510 Conversion::toString(busID);
6511
6512 queryResult = dbConnection_->query(theQuery);
6513
6514 } catch (const Exception& e) {
6515 // should not throw in any case
6517 assert(false);
6518 }
6519
6520 std::set<RowID> ids;
6521
6522 while (queryResult->hasNext()) {
6523 queryResult->next();
6524
6525 ids.insert(queryResult->data("id").integerValue());
6526 }
6527
6528 delete queryResult;
6529 queryResult = NULL;
6530 return ids;
6531}
6532
6533/**
6534 * Returns RowIDs of cost fucntion plugins in the HDB.
6535 *
6536 * @return All cost function plugin IDs.
6537 */
6538std::set<RowID>
6540
6541 // make the SQL query to obtain IDs.
6542 RelationalDBQueryResult* queryResult = NULL;
6543 try {
6544 std::string theQuery =
6545 "SELECT id FROM cost_function_plugin";
6546
6547 queryResult = dbConnection_->query(theQuery);
6548
6549 } catch (const Exception& e) {
6550 // should not throw in any case
6552 assert(false);
6553 }
6554
6555 std::set<RowID> ids;
6556
6557 while (queryResult->hasNext()) {
6558 queryResult->next();
6559
6560 ids.insert(queryResult->data("id").integerValue());
6561 }
6562
6563 delete queryResult;
6564 queryResult = NULL;
6565 return ids;
6566}
6567
6568/**
6569 * Returns cost estimation data IDs related to the given cost function plugin.
6570 *
6571 * @param pluginID ID of the cost function plugin.
6572 * @return IDs of the cost function plugin estimation data.
6573 */
6574std::set<RowID>
6576
6577 // make the SQL query to obtain IDs.
6578 RelationalDBQueryResult* queryResult = NULL;
6579 try {
6580 std::string theQuery =
6581 std::string(
6582 "SELECT id "
6583 "FROM cost_estimation_data "
6584 "WHERE plugin_reference = ") +
6585 Conversion::toString(pluginID);
6586
6587 queryResult = dbConnection_->query(theQuery);
6588
6589 } catch (const Exception& e) {
6590 // should not throw in any case
6592 assert(false);
6593 }
6594
6595 std::set<RowID> ids;
6596
6597 while (queryResult->hasNext()) {
6598 queryResult->next();
6599
6600 ids.insert(queryResult->data("id").integerValue());
6601 }
6602
6603 delete queryResult;
6604 queryResult = NULL;
6605 return ids;
6606}
6607
6608/**
6609 * Returns cost function plugin with the given ID.
6610 *
6611 * @param pluginID ID of the cost function plugin.
6612 * @return Cost function plugin with the given ID.
6613 * @exception Exception Throws if pluginID not found (KeyNotFound) or
6614 * illegal cost_function_plugin row found.
6615 */
6618 RelationalDBQueryResult* pluginData;
6619
6620 std::string pluginDataQuery =
6621 "SELECT id, description, name, plugin_file_path, type "
6622 " FROM cost_function_plugin WHERE id = ";
6623
6624 pluginDataQuery += Conversion::toString(pluginID);
6625
6626 try {
6627 pluginData = dbConnection_->query(pluginDataQuery);
6628 } catch (const Exception& e) {
6630 assert(false);
6631 }
6632
6633 if (pluginData->hasNext()) {
6634 pluginData->next();
6635
6636 int id = pluginData->data("id").integerValue();
6637 std::string name = pluginData->data("name").stringValue();
6638 std::string desc = pluginData->data("description").stringValue();
6639 std::string path = pluginData->data("plugin_file_path").stringValue();
6640 std::string typeStr = pluginData->data("type").stringValue();
6641
6644 if (typeStr == COST_PLUGIN_TYPE_FU) {
6646 } else if (typeStr == COST_PLUGIN_TYPE_RF) {
6648 } else if (typeStr == COST_PLUGIN_TYPE_DECOMP) {
6650 } else if (typeStr == COST_PLUGIN_TYPE_ICDEC) {
6652 } else {
6653 delete pluginData;
6654 InvalidData ex(
6655 __FILE__, __LINE__, __func__,
6656 (boost::format("Illegal cost_function_plugin type %d.") %
6657 type).str());
6658 throw ex;
6659 }
6660
6661 delete pluginData;
6662 return new CostFunctionPlugin(id, desc, name, path, type);
6663
6664 } else {
6665 delete pluginData;
6666 throw KeyNotFound(
6667 __FILE__, __LINE__, __func__,
6668 (boost::format("Cost function plugin with id %d not found.") %
6669 pluginID).str());
6670 }
6671}
6672
6673/**
6674 * Adds cost estimation data to the HDB.
6675 *
6676 * @param data Cost estimation data to add.
6677 * @return Row ID of the added cost data.
6678 */
6679RowID
6681 if (!data.hasName() || !data.hasValue() || !data.hasPluginID()) {
6682 throw InvalidData(__FILE__, __LINE__, __func__);
6683 }
6684
6685 std::string query =
6686 std::string("INSERT INTO cost_estimation_data"
6687 " (id, name, value, plugin_reference, "
6688 " fu_reference, rf_reference, "
6689 " bus_reference, socket_reference) VALUES (") +
6690 "NULL, '" + data.name() + "', '" +
6691 data.value().stringValue() + "', " +
6692 Conversion::toString(data.pluginID()) + ", ";
6693
6694 // FU Reference
6695 if (data.hasFUReference()) {
6696 if (!hasFUEntry(data.fuReference())) {
6697 throw KeyNotFound(__FILE__, __LINE__, __func__);
6698 }
6699 query += Conversion::toString(data.fuReference());
6700 query += ", ";
6701 } else {
6702 query += "NULL, ";
6703 }
6704
6705 // RF Reference
6706 if (data.hasRFReference()) {
6707 if (!hasRFEntry(data.rfReference())) {
6708 throw KeyNotFound(__FILE__, __LINE__, __func__);
6709 }
6710 query += Conversion::toString(data.rfReference());
6711 query += ", ";
6712 } else {
6713 query += "NULL, ";
6714 }
6715
6716 // Bus Reference
6717 if (data.hasBusReference()) {
6718 if (!hasBusEntry(data.busReference())) {
6719 throw KeyNotFound(__FILE__, __LINE__, __func__);
6720 }
6721 query += Conversion::toString(data.busReference());
6722 query += ", ";
6723 } else {
6724 query += "NULL, ";
6725 }
6726
6727 // Socket Reference
6728 if (data.hasSocketReference()) {
6729 if (!hasSocketEntry(data.socketReference())) {
6730 throw KeyNotFound(__FILE__, __LINE__, __func__);
6731 }
6732 query += Conversion::toString(data.socketReference());
6733 query += ");";
6734 } else {
6735 query += "NULL);";
6736 }
6737
6738 try {
6739 dbConnection_->updateQuery(query);
6741 } catch (const Exception& e) {
6743 assert(false);
6744 }
6745
6746 // dummy return to avoid compiler whining
6747 assert(false);
6748 return 0;
6749}
6750
6751/**
6752 * Function for querying cost estimation data from the HDB.
6753 *
6754 * Returns set of cost estiamtion data Row IDs that match the given
6755 * datas attributes that are set.
6756 *
6757 * @param match CostEstimationData which is matched to the HDB data.
6758 * @param useCompiledQueries if true use a compiled query instead of making a
6759 * new one.
6760 * @param compiledQuery Pointer to a prepared query to be used.
6761 * @return Set of cost estimation data row IDs that match the query.
6762 */
6763std::set<RowID>
6765 const CostEstimationData& match,
6766 bool /*useCompiledQueries*/,
6767 RelationalDBQueryResult* compiledQuery) const {
6768
6769 std::string query = "";
6770 if (!compiledQuery) {
6771 createCostEstimatioDataIdsQuery(match, &query);
6772 } else {
6773 // only bind query variables
6774 createCostEstimatioDataIdsQuery(match, NULL, compiledQuery, NULL);
6775 }
6776
6777 RelationalDBQueryResult* result = NULL;
6778
6779 if (compiledQuery) {
6780 result = compiledQuery;
6781 } else {
6782 try {
6783 result = dbConnection_->query(query);
6784 } catch (const Exception& e) {
6785 debugLog(query);
6787 assert(false);
6788 }
6789 }
6790
6791 std::set<RowID> dataIDs;
6792 while (result->hasNext()) {
6793 result->next();
6794 dataIDs.insert(result->data(0).integerValue());
6795 }
6796
6797 if (!compiledQuery) {
6798 delete result;
6799 } else {
6800 compiledQuery->reset();
6801 }
6802
6803 return dataIDs;
6804}
6805
6806
6807/**
6808 * Creates or prepares the query for cost estimation data ids.
6809 *
6810 * @param match CostEstimationData which is matched to the HDB data.
6811 * @param query String variable where query is stored, null if no query is to
6812 * be created.
6813 * @param compiledQuery Pointer to a prepared query to be used, null if not to
6814 * be used.
6815 * @param queryHash Pointer to unique id variable to be created for the
6816 * query, null if not to be created.
6817 * @param createBindableQuery If true query of a kind where variables can be
6818 * binded is created, if false normal query with values is created.
6819 */
6820void
6822 const CostEstimationData& match,
6823 std::string* query,
6824 RelationalDBQueryResult* compiledQuery,
6825 short int* queryHash,
6826 bool createBindableQuery) const {
6827
6828 if (queryHash) {
6829 *queryHash = 0;
6830 }
6831 bool firstMatch = true;
6832 unsigned int count = 0;
6833
6834 if (query) {
6835 *query = "SELECT id FROM cost_estimation_data WHERE ";
6836 }
6837
6838 if (match.hasName()) {
6839 if (queryHash) {
6840 *queryHash |= 1;
6841 }
6842
6843 if (compiledQuery) {
6844 compiledQuery->bindString(++count, match.name());
6845 }
6846
6847 if (query) {
6848 firstMatch = false;
6849 *query += "name='";
6850 *query += createBindableQuery ? "?" : match.name();
6851 *query += "'";
6852 }
6853 }
6854
6855 if (match.hasValue()) {
6856 if (queryHash) {
6857 *queryHash |= 2;
6858 }
6859
6860 if (compiledQuery) {
6861 compiledQuery->bindString(++count, match.name());
6862 }
6863
6864 if (query) {
6865 if (!firstMatch) *query += " AND ";
6866 firstMatch = false;
6867 *query += "value='";
6868 *query += createBindableQuery ? "?" : match.name();
6869 *query += "'";
6870 }
6871 }
6872
6873 if (match.hasPluginID()) {
6874 if (queryHash) {
6875 *queryHash |= 4;
6876 }
6877
6878 if (compiledQuery) {
6879 compiledQuery->bindInt(++count, match.pluginID());
6880 }
6881
6882 if (query) {
6883 if (!firstMatch) *query += " AND ";
6884 firstMatch = false;
6885 *query += "plugin_reference = ";
6886 *query += createBindableQuery ? "?" :
6888 }
6889 }
6890
6891 if (match.hasFUReference()) {
6892 if (queryHash) {
6893 *queryHash |= 8;
6894 }
6895
6896 if (compiledQuery) {
6897 compiledQuery->bindInt(++count, match.fuReference());
6898 }
6899
6900 if (query) {
6901 if (!firstMatch) *query += " AND ";
6902 firstMatch = false;
6903 *query += "fu_reference = ";
6904 *query += createBindableQuery ? "?" :
6906 }
6907 }
6908
6909 if (match.hasRFReference()) {
6910 if (queryHash) {
6911 *queryHash |= 16;
6912 }
6913
6914 if (compiledQuery) {
6915 compiledQuery->bindInt(++count, match.rfReference());
6916 }
6917
6918 if (query) {
6919 if (!firstMatch) *query += " AND ";
6920 firstMatch = false;
6921 *query += "rf_reference = ";
6922 *query += createBindableQuery ? "?" :
6924 }
6925 }
6926
6927 if (match.hasBusReference()) {
6928 if (queryHash) {
6929 *queryHash |= 32;
6930 }
6931
6932 if (compiledQuery) {
6933 compiledQuery->bindInt(++count, match.rfReference());
6934 }
6935
6936 if (query) {
6937 if (!firstMatch) *query += " AND ";
6938 firstMatch = false;
6939 *query += "bus_reference = ";
6940 *query += createBindableQuery ? "?" :
6942 }
6943 }
6944
6945 if (match.hasSocketReference()) {
6946 if (queryHash) {
6947 *queryHash |= 64;
6948 }
6949
6950 if (compiledQuery) {
6951 compiledQuery->bindInt(++count, match.rfReference());
6952 }
6953
6954 if (query) {
6955 if (!firstMatch) *query += " AND ";
6956 firstMatch = false;
6957 *query += "socket_reference = ";
6958 *query += createBindableQuery ? "?" :
6960 }
6961 }
6962
6963 if (query) {
6964 *query += ";";
6965 }
6966}
6967
6968
6969/**
6970 * Returns used database connection.
6971 */
6974 return dbConnection_;
6975}
6976
6977
6978/**
6979 * Updates cost estimation data in the HDB.
6980 *
6981 * @param id Row ID of the data to update.
6982 * @param data Updated data.
6983 */
6984void
6986 if (!data.hasName() || !data.hasValue() || !data.hasPluginID()) {
6987 throw InvalidData(__FILE__, __LINE__, __func__);
6988 }
6989
6990 if (!hasCostEstimationDataByID(id)) {
6991 throw KeyNotFound(__FILE__, __LINE__, __func__);
6992 }
6993
6994 std::string query =
6995 std::string("UPDATE cost_estimation_data SET ") +
6996 " name='" + data.name() +
6997 "', value='" + data.value().stringValue() +
6998 "', plugin_reference=" + Conversion::toString(data.pluginID());
6999
7000 // FU entry reference.
7001 if (data.hasFUReference()) {
7002 if (!hasFUEntry(data.fuReference())) {
7003 throw KeyNotFound(__FILE__, __LINE__, __func__);
7004 }
7005 query += ", fu_reference=";
7006 query += Conversion::toString(data.fuReference());
7007 } else {
7008 query += ", fu_reference=NULL";
7009 }
7010
7011 // RF entry reference.
7012 if (data.hasRFReference()) {
7013 if (!hasRFEntry(data.rfReference())) {
7014 throw KeyNotFound(__FILE__, __LINE__, __func__);
7015 }
7016 query += ", rf_reference=";
7017 query += Conversion::toString(data.rfReference());
7018 } else {
7019 query += ", rf_reference=NULL";
7020 }
7021
7022 // Bus entry reference
7023 if (data.hasBusReference()) {
7024 if (!hasBusEntry(data.busReference())) {
7025 throw KeyNotFound(__FILE__, __LINE__, __func__);
7026 }
7027 query += ", bus_reference=";
7028 query += Conversion::toString(data.busReference());
7029 } else {
7030 query += ", bus_reference=NULL";
7031 }
7032
7033 // Socket entry reference.
7034 if (data.hasSocketReference()) {
7035 if (!hasSocketEntry(data.socketReference())) {
7036 throw KeyNotFound(__FILE__, __LINE__, __func__);
7037 }
7038 query += ", socket_reference=";
7039 query += Conversion::toString(data.socketReference());
7040 } else {
7041 query += ", socket_reference=NULL";
7042 }
7043
7044 query += " WHERE id=";
7045 query += Conversion::toString(id);
7046 query += ";";
7047
7048 try {
7049 dbConnection_->updateQuery(query);
7050 } catch (const Exception& e) {
7052 assert(false);
7053 }
7054}
7055
7056/**
7057 * Modifies cost estimation function plugin attributes.
7058 *
7059 * @param id RowID of the plugin to modify.
7060 * @param plugin Modified plugin (ID is ignored).
7061 * @exception InvalidData Throws if the given plugin was invalid.
7062 * @exception KeyNotFound Throws if no cost function plugin was found with
7063 * given RowID.
7064 */
7065void
7067 RowID id, const CostFunctionPlugin& plugin) {
7068 if (plugin.name() == "") {
7069 throw InvalidData(__FILE__, __LINE__, __func__);
7070 }
7071
7072 if (!hasCostFunctionPluginByID(id)) {
7073 throw KeyNotFound(__FILE__, __LINE__, __func__);
7074 }
7075
7076 string type = "";
7077 switch (plugin.type()) {
7079 type = COST_PLUGIN_TYPE_FU;
7080 break;
7082 type = COST_PLUGIN_TYPE_RF;
7083 break;
7086 break;
7089 break;
7090 default:
7091 InvalidData ex(
7092 __FILE__, __LINE__, __func__,
7093 (boost::format("Illegal cost_function_plugin type %d.") %
7094 type).str());
7095 throw ex;
7096 break;
7097 }
7098
7099 std::string query =
7100 std::string("UPDATE cost_function_plugin SET ") +
7101 " name='" + plugin.name() +
7102 "', description='" + plugin.description() +
7103 "', plugin_file_path='" + plugin.pluginFilePath() +
7104 "', type='" + type + "'";
7105
7106 query += " WHERE id=";
7107 query += Conversion::toString(id);
7108 query += ";";
7109
7110 try {
7111 dbConnection_->updateQuery(query);
7112 } catch (const Exception& e) {
7114 assert(false);
7115 }
7116}
7117
7118/**
7119 * Returns block source file names
7120 *
7121 * @return List of block source file names.
7122 */
7123std::list<std::string>
7125
7126 RelationalDBQueryResult* queryResult;
7127 try {
7128 queryResult = dbConnection_->query(
7129 std::string("SELECT * FROM block_source_file"));
7130 } catch (const Exception& e) {
7132 assert(false);
7133 }
7134
7135 std::list<std::string> files;
7136 while (queryResult->hasNext()) {
7137 queryResult->next();
7138 files.push_back(queryResult->data(1).stringValue());
7139 }
7140
7141 delete queryResult;
7142 return files;
7143}
7144
7145} // namespace HDB
#define debugLog(text)
#define __func__
#define abortWithError(message)
#define assert(condition)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
IDF::MachineImplementation * implementation
the implementation definition of the estimated processor
const string IN_DIRECTION
Definition HDBManager.cc:85
const string CQ_FU
const string CQ_OPERATION_IMPLEMENTATION_VARIABLE
const string CQ_PIPELINE_RESOURCE_USAGE
const string CQ_FU_SOURCE_FILE
const string CQ_FU_IMPL_ENTRY_INDEX
const std::string COST_PLUGIN_TYPE_DECOMP
Definition HDBManager.cc:98
const string CQ_FU_ARCHITECTURE
const string CQ_IO_USAGE
const string BIDIR_DIRECTION
Definition HDBManager.cc:87
const bool WRITE_ACTION
Definition HDBManager.cc:83
const std::string COST_PLUGIN_TYPE_RF
Definition HDBManager.cc:97
const string CQ_RF_EXT_PORT_PARAMETER_DEPENDENCY
const string CQ_RF
const string CQ_OPERATION_IMPLEMENTATION
const string CQ_OPERATION_IMPLEMENTATION_SOURCE_FILE
const string CQ_RF_IMPL_ENTRY_INDEX
const string CQ_RF_ARCHITECTURE
const string CQ_RF_IMPLEMENTATION_PARAMETER
const string CQ_OPERATION_PIPELINE
const string CQ_RF_EXTERNAL_PORT
const string CQ_SOCKET
const string CQ_OPERATION_IMPLEMENTATION_RESOURCE_SOURCE_FILE
const string CQ_FU_PORT_MAP_ARCH_INDEX
const string CQ_OPERATION_IMPLEMENTATION_RESOURCE
const string CQ_PIPELINE_RESOURCE
const string CQ_BLOCK_SOURCE_FILE
const string CQ_BUS
const string CQ_FU_IMPLEMENTATION_PARAMETER
const string CQ_RF_IMPLEMENTATION
const string CQ_FU_DATA_PORT
const string CQ_FU_IMPLEMENTATION
const string CQ_FU_EXT_PORT_PARAMETER_DEPENDENCY
const string CQ_RF_DATA_PORT
const string VHDL_FORMAT
Definition HDBManager.cc:88
const std::string COST_PLUGIN_TYPE_ICDEC
Definition HDBManager.cc:99
const string CQ_OPCODE_MAP
const std::string COST_PLUGIN_TYPE_FU
Possible cost function plugin types.
Definition HDBManager.cc:96
const string CQ_COST_ESTIMATION_DATA
type: {'fu'|'rf'|'decomp'|'icdec'}
const int DEFAULT_PORT_WIDTH
Definition HDBManager.cc:93
const string CQ_RF_SOURCE_FILE
const bool READ_ACTION
Definition HDBManager.cc:82
const string CQ_COST_FUNCTION_PLUGIN
const string CQ_FU_PORT_MAP
const string OUT_DIRECTION
Definition HDBManager.cc:86
const string CQ_OPERATION
const string VERILOG_SIM_FORMAT
Definition HDBManager.cc:91
const string CQ_IO_BINDING
const string VHDL_SIM_FORMAT
Definition HDBManager.cc:90
const string CQ_FORMAT
const string CQ_OPERATION_IMPLEMENTATION_RESOURCES
const string VERILOG_FORMAT
Definition HDBManager.cc:89
const string CQ_FU_EXTERNAL_PORT
static void difference(const ContainerType &firstContainer, const ContainerType &secondContainer, ContainerType &difference)
static std::string toString(const T &source)
DataObject value() const
void setBusReference(RowID busEntryID)
void setValue(const DataObject &value)
bool hasBusReference() const
bool hasFUReference() const
std::string name() const
bool hasName() const
void setPluginID(RowID pluginID)
bool hasValue() const
RowID socketReference() const
void setRFReference(RowID rfEntryID)
bool hasSocketReference() const
void setSocketReference(RowID socketEntryID)
void setFUReference(RowID fuEntryID)
void setName(const std::string &name)
bool hasRFReference() const
bool hasPluginID() const
virtual std::string stringValue() const
virtual bool isNull() const
virtual bool boolValue() const
virtual int integerValue() const
std::string errorMessage() const
Definition Exception.cc:123
static void checkOperations(const TTAMachine::FunctionUnit &fu, MachineValidatorResults &results)
static void checkOperandBindings(const TTAMachine::FunctionUnit &fu, MachineValidatorResults &results)
static std::string absolutePathOf(const std::string &pathName)
static bool fileIsReadable(const std::string fileName)
static bool fileIsCreatable(const std::string fileName)
static bool fileExists(const std::string fileName)
@ Verilogsim
Verilog simulation file.
CostFunctionPluginType
all supported cost function plugin types
@ COST_RF
register file cost estimator
@ COST_ICDEC
interconnection network & decoder cost estimator
@ COST_FU
function unit cost estimator
@ COST_DECOMP
decompressor cost estimator
CostFunctionPluginType type() const
std::string description() const
std::string pluginFilePath() const
std::string widthFormula() const
std::string parameterDependency(int index) const
bool setParameterDependency(const std::string &parameter)
int parameterDependencyCount() const
std::string name() const
std::string description() const
Direction direction() const
bool hasGuardSupport(const std::string &port) const
void setGuardSupport(const std::string &port)
void setParameterizedWidth(const std::string &port)
bool hasParameterizedWidth(const std::string &port) const
TTAMachine::FunctionUnit & architecture() const
void setImplementation(FUImplementation *implementation)
Definition FUEntry.cc:103
FUImplementation & implementation() const
Definition FUEntry.cc:86
virtual bool hasImplementation() const
Definition FUEntry.cc:74
FUArchitecture & architecture() const
Definition FUEntry.cc:129
virtual bool hasArchitecture() const
Definition FUEntry.cc:117
void setArchitecture(FUArchitecture *architecture)
Definition FUEntry.cc:146
FUPortImplementation & architecturePort(int index) const
Parameter parameter(int index) const
bool hasOpcode(const std::string &operation) const
std::string glockReqPort() const
FUExternalPort & externalPort(int index) const
std::string opcodePort() const
int opcode(const std::string &operation) const
std::string architecturePort() const
void setCostFunction(CostFunctionPlugin *costFunction)
Definition HDBEntry.cc:127
void setID(RowID id)
Definition HDBEntry.cc:73
bool hasID() const
Definition HDBEntry.cc:62
void setHDBFile(const std::string &file)
Definition HDBEntry.cc:152
RowID id() const
Definition HDBEntry.cc:85
static std::string rfImplementationDataPortsByIDQuery(RowID id)
std::set< RowID > socketCostEstimationDataIDs(RowID socketID) const
DataObjectList * busCostEstimationDataList(const std::string &valueName, RowID implementationId, const std::string &pluginName) const
std::set< RowID > fuEntriesByArchitecture(const TTAMachine::FunctionUnit &fu) const
static std::string busEntryByIDQuery(RowID id)
static std::string ioUsageDataByIDQuery(RowID id)
HDBManager(const std::string &hdbFile)
std::set< RowID > busCostEstimationDataIDs(RowID busID) const
bool containsRFArchitecture(RowID id) const
bool fuEntryHasArchitecture(RowID id) const
virtual ~HDBManager()
std::vector< PipelineElementUsage > PipelineElementUsageTable
static BlockImplementationFile::Format fileFormat(const std::string &formatString)
static std::string rfImplementationByIDQuery(RowID id)
static std::string fuExternalPortsByIDQuery(RowID id)
void createCostEstimatioDataIdsQuery(const CostEstimationData &match, std::string *query, RelationalDBQueryResult *compiledQuery=NULL, short int *queryHash=NULL, bool createBindableQuery=false) const
static void createNew(const std::string &file)
RowID addBusEntry() const
FUEntry * fuByEntryID(RowID id) const
int addBooleanColumn(const std::string &table, const std::string &newcolumn)
std::set< RowID > rfArchitectureIDs() const
bool hasBusEntry(RowID id) const
void addOpcodesToImplementation(FUImplementation &implementation, RowID entryID) const
virtual void modifyCostFunctionPlugin(RowID id, const CostFunctionPlugin &plugin)
std::set< RowID > fuArchitectureIDsByOperationSet(const std::set< std::string > &operationNames) const
RowID addRFArchitecture(const RFArchitecture &architecture) const
RowID addCostFunctionPlugin(const CostFunctionPlugin &plugin) const
static bool isMatchingArchitecture(const TTAMachine::FunctionUnit &fu, const FUArchitecture &arch)
void addOperationPipelinesToFUArchitecture(FUArchitecture &architecture, RowID id) const
virtual void removeFUEntry(RowID id) const
RowID addFUEntry() const
void removeOperationImplementation(RowID id)
RowID addRFEntry() const
void setArchitectureForRF(RowID rfID, RowID archID) const
RowID addBusCostEstimationData(RowID busID, const std::string &valueName, const std::string &value, RowID pluginID) const
RowID rfArchitectureID(RowID rfEntryID) const
CostFunctionPlugin * costFunctionPluginByID(RowID pluginID) const
RelationalDBConnection * dbConnection_
Handle to the database connection.
OperationImplementationResource OperationImplementationResourceByID(RowID id) const
static std::string formatString(BlockImplementationFile::Format format)
static std::string fuSourceFilesByIDQuery(RowID id)
static std::string fuImplementationDataPortsByIDQuery(RowID id)
std::list< std::string > blockSourceFile()
void addDataPortsToImplementation(FUImplementation &implementation, FUArchitecture &architecture, RowID entryID) const
void addOperationImplementationResource(const OperationImplementationResource &resource)
std::string fileName() const
std::set< RowID > OperationImplementationIDs() const
bool containsOperation(const std::string &opName) const
RowID addRFCostEstimationData(RowID rfID, const std::string &valueName, const std::string &value, RowID pluginID) const
RelationalDBConnection * getDBConnection() const
virtual void removeFUImplementation(RowID implementationID) const
static std::string fuImplementationParametersByIDQuery(RowID id)
std::set< RowID > costFunctionPluginDataIDs(RowID pluginID) const
RowID addSocketCostEstimationData(RowID socketID, const std::string &valueName, const std::string &value, RowID pluginID) const
static std::string fuArchitectureByIDQuery(RowID id)
virtual std::set< RowID > costEstimationDataIDs(const CostEstimationData &match, bool useCompiledQueries=false, RelationalDBQueryResult *compiledQuery=NULL) const
void setCostFunctionPluginForFU(RowID fuID, RowID pluginID) const
virtual void removeSocketEntry(RowID id) const
void addPortsAndBindingsToFUArchitecture(FUArchitecture &architecture, RowID id) const
void unsetCostFunctionPluginForFU(RowID fuID) const
void removeOperationImplementationResource(RowID id)
static std::string directionString(HDB::Direction direction)
RowID addSocketEntry() const
virtual void removeRFImplementation(RowID implID) const
virtual void modifyCostEstimationData(RowID id, const CostEstimationData &data)
virtual RFArchitecture * rfArchitectureByID(RowID id) const
void addFUExternalPortsToImplementation(FUImplementation &implementation, RowID entryID) const
RowID fuArchitectureID(RowID fuEntryID) const
OperationImplementation OperationImplementationByID(RowID id) const
bool canRemoveFUArchitecture(RowID archID) const
virtual DataObject costEstimationDataValue(const std::string &valueName, const std::string &pluginName) const
bool hasRFEntry(RowID id) const
bool rfEntryHasArchitecture(RowID id) const
bool containsImplementationFile(const std::string &pathToFile) const
void unsetArchitectureForRF(RowID rfID) const
bool hasColumn(const std::string &table, const std::string &columnName) const
static std::string socketEntryByIDQuery(RowID id)
std::set< RowID > fuArchitectureIDs() const
RowID addFUArchitecture(const FUArchitecture &architecture) const
CostEstimationData costEstimationData(RowID id) const
void addBlockImplementationFiles(FUImplementation &implementation, RowID entryID) const
RowID addFUImplementation(const FUEntry &entry) const
bool containsFUArchitecture(RowID id) const
static HDBManager * instance_
Unique instance of the HDBManager.
static std::string fuImplementationByIDQuery(RowID id)
virtual void removeCostEstimationData(RowID id) const
static std::string rfSourceFilesByIDQuery(RowID id)
virtual FUImplementation * createImplementationOfFU(FUArchitecture &architecture, RowID id) const
static void insertFileFormats(RelationalDBConnection &connection)
virtual void removeRFEntry(RowID id) const
static std::string fuEntryByIDQuery(RowID id)
void setCostFunctionPluginForRF(RowID rfID, RowID pluginID) const
DataObjectList * socketCostEstimationDataList(const std::string &valueName, RowID implementationID, const std::string &pluginName) const
std::set< RowID > socketEntryIDs() const
bool hasSocketEntry(RowID id) const
void addOperationImplementation(const OperationImplementation &operation)
bool hasCostFunctionPluginByID(RowID id) const
CostFunctionPlugin * createCostFunctionOfFU(RowID id) const
SQLite * db_
Handle to the database.
static std::string rfImplementationByIDQuery2(RowID id)
RowID addFUCostEstimationData(RowID fuID, const std::string &valueName, const std::string &value, RowID pluginID) const
DataObject socketCostEstimationData(const std::string &valueName, RowID socketID, const std::string &pluginName) const
void unsetCostFunctionPluginForRF(RowID rfID) const
std::set< RowID > fuCostEstimationDataIDs(RowID fuImplID) const
RowID addRFImplementation(const RFImplementation &implementation, RowID rfEntryID)
std::string hdbFile_
The HDB file to manager.
std::set< RowID > rfCostEstimationDataIDs(RowID rfImplID) const
void addBlockImplementationFileToHDB(const BlockImplementationFile &file) const
RowID fuEntryIDOfImplementation(RowID implID) const
std::set< RowID > rfEntryIDs() const
static std::string opcodesByIDQuery(RowID id)
void setArchitectureForFU(RowID fuID, RowID archID) const
virtual void removeBusEntry(RowID id) const
virtual void removeRFArchitecture(RowID archID) const
static std::string rfExternalPortsByIDQuery(RowID id)
void addFUParametersToImplementation(FUImplementation &implementation, RowID entryID) const
std::set< RowID > rfEntriesByArchitecture(int readPorts, int writePorts, int bidirPorts, int maxReads, int maxWrites, int latency, bool guardSupport, int guardLatency=0, int width=0, int size=0, bool zeroRegister=false) const
static std::string resourceUsageDataByIDQuery(RowID id)
std::set< RowID > costFunctionPluginIDs() const
static std::string fuPortsAndBindingsByIDQuery(RowID id)
DataObject busCostEstimationData(const std::string &valueName, RowID busID, const std::string &pluginName) const
bool hasFUEntry(RowID id) const
static bool areCompatiblePipelines(const PipelineElementUsageTable &table)
std::set< RowID > busEntryIDs() const
static std::string rfEntryByIDQuery(RowID id)
void addRFExternalPortsToImplementation(RFImplementation &implementation, RowID entryID) const
RowID rfEntryIDOfImplementation(RowID implID) const
virtual FUArchitecture * fuArchitectureByID(RowID id) const
static std::string rfArchitectureByIDQuery(RowID id)
virtual void removeCostFunctionPlugin(RowID pluginID) const
RFEntry * rfByEntryID(RowID id) const
DataObject fuCostEstimationData(const std::string &valueName, RowID implementationId, const std::string &pluginName) const
static std::string rfImplementationParametersByIDQuery(RowID id)
void addRFParametersToImplementation(RFImplementation &implementation, RowID entryID) const
CostFunctionPlugin * createCostFunctionOfRF(RowID id) const
bool canRemoveRFArchitecture(RowID archID) const
virtual void removeFUArchitecture(RowID archID) const
std::set< RowID > fuEntryIDs() const
void unsetArchitectureForFU(RowID fuID) const
std::set< RowID > OperationImplementationResourceIDs() const
static std::string fuPortBindingByNameQuery(RowID fuID, const std::string &portName)
std::string resolveArchitecturePort(const FUArchitecture &architecture, RowID entryID, const std::string &implementedPort) const
bool hasCostEstimationDataByID(RowID id) const
RowID addCostEstimationData(const CostEstimationData &data) const
DataObject rfCostEstimationData(const std::string &valueName, RowID implementationId, const std::string &pluginName) const
virtual RFImplementation * createImplementationOfRF(RowID id) const
std::list< DataObject > DataObjectList
Definition HDBManager.hh:86
BlockImplementationFile & file(int index) const
std::string loadPort() const
bool hasGuardSupport() const
bool hasParameterizedWidth() const
void setSize(int size)
bool zeroRegister() const
void setWidth(int width)
bool hasParameterizedSize() const
void setImplementation(RFImplementation *implementation)
Definition RFEntry.cc:87
virtual bool hasImplementation() const
Definition RFEntry.cc:74
virtual bool hasArchitecture() const
Definition RFEntry.cc:117
void setArchitecture(RFArchitecture *architecture)
Definition RFEntry.cc:130
std::string opcodePortWidthFormula() const
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
virtual void updateVersion(int version)=0
virtual int updateQuery(const std::string &queryString)=0
virtual RowID lastInsertRowID()=0
virtual RelationalDBQueryResult * query(const std::string &queryString, bool init=true)=0
virtual bool tableExistsInDB(const std::string &tableName)=0
virtual void DDLQuery(const std::string &queryString)=0
virtual int column(const std::string &name) const
virtual void bindInt(unsigned int position, int value)
virtual const DataObject & data(std::size_t column) const =0
virtual void bindString(unsigned int position, const std::string &value)
virtual void close(const RelationalDBConnection &connection)
Definition SQLite.cc:100
virtual RelationalDBConnection & connect(const std::string &database, const std::string &login="", const std::string &password="", bool readOnly=false)
Definition SQLite.cc:69
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
virtual int width() const
OperandSet writtenOperands(int cycle) const
void addResourceUse(const std::string &name, int start, int duration)
void addPortRead(int operand, int start, int duration)
OperandSet readOperands(int cycle) const
std::set< int > OperandSet
Set for operand indexes.
void addPortWrite(int operand, int start, int duration)
bool isResourceUsed(const std::string &name, int cycle) const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
virtual int pipelineElementCount() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual FUPort * operationPort(const std::string &name) const
virtual bool hasOperationPort(const std::string &name) const
virtual PipelineElement * pipelineElement(int index) const
virtual bool hasOperation(const std::string &name) const
virtual int operationPortCount() const
ExecutionPipeline * pipeline() const
virtual void bindPort(int operand, const FUPort &port)
virtual FUPort * port(int operand) const
int io(const FUPort &port) const
const std::string & name() const
bool isBound(const FUPort &port) const
const std::string & name() const
virtual std::string name() const
Definition Port.cc:141
Direction
Direction of port.
Definition HDBTypes.hh:40
@ OUT
Output port.
Definition HDBTypes.hh:42
@ BIDIR
Bidirectional port.
Definition HDBTypes.hh:43
@ IN
Input port.
Definition HDBTypes.hh:41
std::set< const TTAMachine::PipelineElement * > usage2
std::set< const TTAMachine::PipelineElement * > usage1
std::vector< Variable > verilogVariables
std::vector< Variable > vhdlGlobalSignals
std::vector< Variable > verilogGlobalSignals
std::vector< OperationImplementationResource > resources
std::vector< Variable > vhdlVariables
std::string value
Value of the parameter.
Definition HDBTypes.hh:49
std::string type
Type of the parameter.
Definition HDBTypes.hh:48
std::string name
Name of the parameter.
Definition HDBTypes.hh:47