44 #include <boost/regex.hpp>
72 using namespace ProGe;
122 const std::string& dstDirectory,
const std::string& progeOutDir,
123 const std::string& entityStr) {
124 entityStr_ = entityStr;
125 language_ = language;
127 std::map<string, std::vector<FunctionUnit*> > ASFUs;
131 const unsigned int FUSPERAS = 2;
135 for (
int i = 0; i < FUNav.
count(); ++i) {
138 if (
FU->hasAddressSpace()) {
141 std::map<string, std::vector<FunctionUnit*> >::iterator it
142 = ASFUs.find(AS->
name());
143 if (it != ASFUs.end()) {
146 if (it->second.size() < FUSPERAS) {
147 it->second.push_back(
FU);
151 "More than two FUs use same address space.\n");
155 std::vector<FunctionUnit*> FUList;
156 FUList.push_back(
FU);
157 ASFUs.insert(make_pair(AS->
name(), FUList));
162 if (ASFUs.size() > 1) {
164 string eMsg =
"More than one address space used by FUs.";
170 copyTestBenchFiles(dstDirectory);
179 const string MEMORYNAME =
"dmem";
180 std::map<string, std::vector<FunctionUnit*> >::iterator it
182 std::map<string, std::vector<FunctionUnit*> >::iterator it_secLast
183 = (ASFUs.empty()) ? ASFUs.end() : --(ASFUs.end());
185 while (it != ASFUs.end()) {
188 for (
unsigned int i = 0; i < it->second.size(); ++i) {
197 HDBManager& manager = HDBRegistry::instance().hdb(
211 LSUMap.append(getSignalMapping(
FU->name(), ep.
name(),
213 ((i > 0) ?
"b" :
"a")));
215 if (it == it_secLast && (i+1) == it->second.size() &&
218 LSUMap.append(
");\n");
220 LSUMap.append(
",\n");
230 string dmemImageFilename(
"dmem_");
231 if (ASFUs.size() == 1) {
233 ASFUs.begin()->second.at(0)->addressSpace()->name();
234 dmemImageFilename +=
"_";
236 dmemImageFilename +=
"init.img";
241 if (string::npos != param.
name.find(
"dataw")
242 && param.
type ==
"integer") {
244 if (param.
value.length() < 1) {
250 dataWidth = param.
value;
253 && param.
type ==
"integer") {
258 static_cast<int>(ceil(log(AS->
end()) / log(2))));
271 if (widthFormula.empty()) {
272 addrWidth = internalAddrWidth;
282 dstDirectory, dmemImageFilename, dataWidth, addrWidth);
287 createTBConstFile(dstDirectory);
292 if (language ==
VHDL) {
298 "imem_en_x => imem_en_x,\n"
299 "imem_addr => imem_addr,\n"
300 "imem_data => imem_data,\n"
305 LSUMapConst.append(
",\n"
306 "db_pc_start => (others => '0'),\n"
307 "db_tta_nreset => '1',\n"
315 ".imem_en_x (imem_en_x),\n"
316 ".imem_addr (imem_addr),\n"
317 ".imem_data (imem_data)";
320 if (LSUMap.length() < 1) {
321 LSUMapConst.append(
");\n");
323 LSUMapConst.append(
",\n");
325 LSUMapConst.append(LSUMap);
330 ((language ==
VHDL) ?
"vhdl" :
"verilog") +
332 ((language ==
VHDL) ?
".vhdl" :
".v");
334 createProcArchVhdl(dstDirectory, toplevel, LSUMapConst);
352 const std::string& dstDirectory,
const std::string& topLevelVhdl,
353 const std::string& signalMappings) {
355 string eMsg =
"File was not readable: " + topLevelVhdl;
360 string startRE,endRE;
362 startRE = std::string(
".*entity.") + entityStr_ +
".is.*";
363 endRE = std::string(
".*end.") + entityStr_ +
";.*";
365 startRE = std::string(
".*module.") + entityStr_;
366 endRE = std::string(
".*endmodule.*");
372 topLevelVhdl, startRE, endRE, block,
false);
374 if (!ok || block ==
"")
377 "Could not read processor entity from ") +
384 ((language_==
VHDL)?
"proc_arch.vhdl.tmpl":
"proc_arch.v.tmpl");
388 ((language_==
VHDL)?
"proc_arch.vhdl":
"proc_arch.v");
398 string eMsg =
"File was not readable: " + procArch;
404 startRE = std::string(
".*component.") + entityStr_ +
".*";
405 endRE = std::string(
".*end.component;.*");
409 string eMsg =
"Could not write toplevel to: " + procArch;
416 startRE = std::string(
".*core.:.") + entityStr_ +
".*";
417 endRE =
".*datamem.:.synch_dualport_sram.*";
419 startRE = entityStr_ + std::string(
".*core.*");
420 endRE =
".*synch_dualport_sram.*";
425 string eMsg =
"Could not write core to: " + procArch;
447 const std::string& fuName,
const std::string& epName,
bool widthIsOne,
448 const std::string& memoryName,
const std::string& memoryLine) {
449 const string sep =
"_";
452 string fuSignalName(
"fu" + sep);
454 fuSignalName.append(fuName + sep + epName + ((widthIsOne) ?
"(0)" :
""));
456 fuSignalName.append(fuName + sep + epName);
459 string memSignalName(memoryName + sep);
461 if (epName ==
"data_in") {
462 memSignalName.append(
"q" + sep + memoryLine);
464 if (epName ==
"data_out") {
465 memSignalName.append(
"d" + sep + memoryLine);
467 if (epName ==
"addr") {
468 memSignalName.append(epName + sep + memoryLine);
470 if (epName ==
"mem_en_x") {
471 memSignalName.append(
"en" + sep + memoryLine + sep +
"x");
473 if (epName ==
"wr_en_x") {
474 memSignalName.append(
"wr" + sep + memoryLine + sep +
"x");
476 if (epName ==
"wr_mask_x") {
477 memSignalName.append(
"bit" + sep +
"wr" + sep + memoryLine + sep
480 string eMsg =
"External port name didn't match any: " + epName;
486 return string(fuSignalName +
" => " + memSignalName);
488 return string(
"."+fuSignalName +
"(" + memSignalName +
")");
500 std::string dstDirectory,
const std::string& dmemImage,
501 const string& dataWidth,
const string& addrWidth) {
503 ((language_ ==
VHDL) ?
"testbench_constants_pkg.vhdl"
504 :
"testbench_constants_pkg.vh");
508 std::ofstream stream(dstFile.c_str(), std::ofstream::out);
510 stream <<
"package testbench_constants is" << endl
511 <<
"-- width of the data memory" << endl
512 <<
"constant DMEMDATAWIDTH : positive := "
513 << ((dataWidth.empty()) ?
"1" : dataWidth) <<
";" << endl
515 <<
"-- address width of the data memory" << endl
516 <<
"constant DMEMADDRWIDTH : positive := "
517 << ((addrWidth.empty()) ?
"1" : addrWidth) <<
";" << endl
519 <<
"-- simulation run time" << endl
520 <<
"constant RUNTIME : time := 5234 * 10 ns;" << endl
522 <<
"-- memory init files" << endl
523 <<
"constant DMEM_INIT_FILE : string := "
524 << ((dataWidth.empty())
530 <<
"constant IMEM_INIT_FILE : string := "
534 <<
"end testbench_constants;" << endl;
536 stream <<
"// width of the data memory" << endl
537 <<
"parameter DMEMDATAWIDTH = "
538 << ((dataWidth.empty()) ?
"1" : dataWidth) <<
"," << endl
540 <<
"// address width of the data memory" << endl
541 <<
"parameter DMEMADDRWIDTH = "
542 << ((addrWidth.empty()) ?
"1" : addrWidth) <<
"," << endl
544 <<
"// simulation run time" << endl
545 <<
"parameter RUNTIME = `SIMTIME,// ns" << endl
547 <<
"// memory init files" << endl
548 <<
"parameter DMEM_INIT_FILE = "
549 << ((dataWidth.empty())
555 <<
"parameter IMEM_INIT_FILE = "
556 << ((addrWidth.empty())
581 sourceDir = sourceDir +
DS +
"tb";
582 std::list<string> foundSourceFiles;
584 string vhdlRegex = ((language_==
VHDL)?
".*\\.vhdl$":
".*\\.v*$");
586 std::list<string>::iterator it = foundSourceFiles.begin();
587 while (it != foundSourceFiles.end()) {
598 "legacy_testbench.vhdl.tmpl":
"legacy_testbench.v.tmpl"),
600 ((language_==
VHDL)?
"testbench.vhdl":
"testbench.v"));
604 sourceDir +
DS +
"proc_ent.vhdl.tmpl",
605 dstDirectory +
DS +
"proc_ent.vhdl");
620 string errorMsg =
"Unable to create file " + fileName;