2015-01-19 17:58:38 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
2015-01-19 20:07:58 +01:00
|
|
|
#include <stdlib.h>
|
2015-01-19 17:58:38 +01:00
|
|
|
#include <vector>
|
2015-01-19 18:08:00 +01:00
|
|
|
#include <fstream>
|
2015-01-31 14:46:51 +01:00
|
|
|
#include <string.h>
|
2015-01-19 17:58:38 +01:00
|
|
|
|
2015-04-11 20:20:14 +02:00
|
|
|
// #define DEBUG_EN DEBUG_EN
|
2015-01-19 17:58:38 +01:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
// Source: vsim -gui design.top(RTL)
|
2015-03-22 11:04:27 +01:00
|
|
|
// Target: ghdl -m --warn-no-vital-generic --workdir=simu --work=work testb_file
|
2015-01-19 17:58:38 +01:00
|
|
|
// ./testb_file --stop-time=500ns --vcdgz=testb_file.vcdgz
|
|
|
|
// gunzip --stdout testb_file.vcdgz | gtkwave --vcd
|
|
|
|
|
|
|
|
int run(string args);
|
|
|
|
|
|
|
|
int run(string args) {
|
|
|
|
FILE *proc;
|
|
|
|
char buf[512];
|
|
|
|
vector < string > result;
|
|
|
|
|
|
|
|
proc = popen(args.c_str(), "r");
|
|
|
|
|
|
|
|
if (proc == NULL) {
|
|
|
|
cerr << "Error: Could not invoke GHDL/GtkWave." << endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(fgets(buf, sizeof(buf), proc)!=NULL){
|
|
|
|
cout << buf;
|
|
|
|
}
|
2015-01-19 18:37:48 +01:00
|
|
|
|
|
|
|
return pclose(proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
string getSimulationTime() { // Very crude but works (for a proof-of-concept anyway^^)
|
|
|
|
FILE *proc;
|
|
|
|
char buf[512];
|
|
|
|
vector < string > result;
|
|
|
|
string defaultValue = "100ns";
|
|
|
|
|
2015-01-19 19:35:33 +01:00
|
|
|
ifstream myfile;
|
|
|
|
char fileTemp[128];
|
|
|
|
myfile.open ("/tmp/ghdl-simtime");
|
|
|
|
myfile.getline(fileTemp, sizeof(fileTemp));
|
|
|
|
myfile.close();
|
|
|
|
if (string(fileTemp) != "")
|
|
|
|
defaultValue = string(fileTemp);
|
|
|
|
|
2015-01-19 18:37:48 +01:00
|
|
|
string temp = "zenity --entry --text \"Enter the duration:\" --title \"Simulation time\" --entry-text=\"" + defaultValue + "\"";
|
|
|
|
proc = popen(temp.c_str(), "r");
|
|
|
|
|
|
|
|
if (proc == NULL) {
|
|
|
|
cerr << "Error: Could not invoke zenity." << endl;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
while(fgets(buf, sizeof(buf), proc)!=NULL){
|
|
|
|
cout << buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defaultValue.clear();
|
|
|
|
char *ptr = buf;
|
|
|
|
while (*ptr != '\0' && *ptr != '\n') {
|
|
|
|
defaultValue.append(" ");
|
|
|
|
defaultValue[defaultValue.length()-1] = *ptr;
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pclose(proc)) {
|
|
|
|
defaultValue = "";
|
|
|
|
}
|
2015-01-19 19:35:33 +01:00
|
|
|
else {
|
|
|
|
ofstream myfile;
|
|
|
|
myfile.open ("/tmp/ghdl-simtime");
|
|
|
|
myfile << defaultValue;
|
|
|
|
myfile.flush();
|
|
|
|
myfile.close();
|
|
|
|
}
|
2015-01-19 18:37:48 +01:00
|
|
|
|
|
|
|
return defaultValue;
|
2015-01-19 17:58:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#define ISOPT(cmd) (string(argv[i]) == cmd)
|
|
|
|
#define GETOPT(cmd) (string(argv[i]) == cmd) && (++i < argc)
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
2015-04-09 17:14:34 +02:00
|
|
|
string top = "";
|
|
|
|
string work = "";
|
|
|
|
string simtime = "";
|
2015-01-23 19:57:05 +01:00
|
|
|
string ghdlargs = "";
|
2015-04-09 17:14:34 +02:00
|
|
|
string wvargs = "";
|
|
|
|
string gtkargs = "";
|
|
|
|
string gtksave = "";
|
2015-01-19 17:58:38 +01:00
|
|
|
int i;
|
|
|
|
char tempdir[256] = ""; // Compile dir
|
|
|
|
|
2015-01-19 18:08:00 +01:00
|
|
|
ifstream myfile;
|
2015-01-19 19:29:35 +01:00
|
|
|
myfile.open ("/tmp/ghdl-workdir");
|
2015-01-19 18:08:00 +01:00
|
|
|
myfile.getline(tempdir, sizeof(tempdir));
|
|
|
|
myfile.close();
|
2015-01-19 17:58:38 +01:00
|
|
|
|
|
|
|
for (i=1; i < argc; ++i) {
|
|
|
|
if (ISOPT("-gui")) {
|
|
|
|
|
2015-01-31 14:46:51 +01:00
|
|
|
}
|
|
|
|
else if (GETOPT("-compiledir")) {
|
|
|
|
strcpy(tempdir, argv[i]);
|
2015-01-23 19:57:05 +01:00
|
|
|
}
|
|
|
|
else if (GETOPT("-ghdl")) {
|
|
|
|
ghdlargs = argv[i];
|
|
|
|
}
|
2015-04-09 08:54:02 +02:00
|
|
|
else if (GETOPT("-rargs")) {
|
2015-01-23 19:57:05 +01:00
|
|
|
wvargs = argv[i];
|
2015-01-19 17:58:38 +01:00
|
|
|
}
|
2015-04-09 08:54:02 +02:00
|
|
|
else if (GETOPT("-gtkwave")) {
|
|
|
|
gtkargs = argv[i];
|
|
|
|
}
|
2015-04-09 17:14:34 +02:00
|
|
|
else if (GETOPT("-gtksave")) {
|
|
|
|
gtksave = argv[i];
|
|
|
|
}
|
2015-01-19 17:58:38 +01:00
|
|
|
else {
|
|
|
|
if (argv[i][0] == '-') {
|
|
|
|
cerr << "INFO: Unknown command line opt: " << argv[i] << endl;
|
|
|
|
}
|
|
|
|
else {
|
2015-03-22 11:10:30 +01:00
|
|
|
top.append(argv[i]);
|
|
|
|
top.append(" ");
|
2015-01-19 17:58:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -gui work.toplevel(RTL)
|
|
|
|
string temp = "";
|
|
|
|
for (unsigned int i=0; i < top.length(); ++i) {
|
2015-04-10 22:42:18 +02:00
|
|
|
if (top.at(i) >= 'A' && top.at(i) <= 'Z')
|
|
|
|
top.at(i) = top.at(i) - ('A'-'a'); // convert to lower case
|
|
|
|
|
2015-01-19 17:58:38 +01:00
|
|
|
if (top.at(i) == '.') {
|
|
|
|
work = temp;
|
|
|
|
temp = "";
|
|
|
|
}
|
|
|
|
else if (top.at(i) == '(') {
|
|
|
|
top = temp;
|
|
|
|
temp = "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
temp.append(" ");
|
|
|
|
temp[temp.length()-1] = top.at(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_EN
|
|
|
|
cout << "\n\nVSIM CALL PARSED:" << endl;
|
|
|
|
cout << "\twork=" << work << endl;
|
|
|
|
cout << "\ttop=" << top<< endl;
|
|
|
|
cout << "\ttempdir=" << tempdir << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (work == "" || top == "" || string(tempdir) == "") {
|
|
|
|
cerr << "Error: Incomplete/Unsupported vsim call." << endl;
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2015-01-19 18:08:00 +01:00
|
|
|
|
2015-01-19 20:07:58 +01:00
|
|
|
//bool ex = false;
|
|
|
|
//while (!ex) {
|
2015-01-20 21:03:51 +01:00
|
|
|
cout << "Compiling..." << endl;
|
2015-03-22 11:04:27 +01:00
|
|
|
string cargs = "cd " + string(tempdir) + "; ghdl -m --warn-no-vital-generic " + ghdlargs + " -fexplicit --workdir=" + string(tempdir) + " --work=" + work + " " + top;
|
|
|
|
#ifdef DEBUG_EN
|
|
|
|
cout << "RUN: " << cargs << endl;
|
|
|
|
#endif
|
2015-01-19 20:07:58 +01:00
|
|
|
if (run(cargs)) {
|
|
|
|
cerr << "Error: Compilation failed." << endl;
|
|
|
|
run("zenity --error --text \"Compilation failed.\"");
|
2015-01-19 17:58:38 +01:00
|
|
|
}
|
2015-01-19 18:11:14 +01:00
|
|
|
else {
|
2015-01-20 21:03:51 +01:00
|
|
|
cout << "done." << endl;
|
2015-01-19 20:07:58 +01:00
|
|
|
cargs = "";
|
|
|
|
string st = getSimulationTime();
|
|
|
|
if (st != "") {
|
2015-01-20 21:03:51 +01:00
|
|
|
cout << "Simulating..." << endl;
|
2015-03-22 11:04:27 +01:00
|
|
|
#ifdef DEBUG_EN
|
2015-04-09 08:20:12 +02:00
|
|
|
cout << "RUN: " << "cd " + string(tempdir) + "; ./" + top + " " + wvargs + " --stop-time=" + st + " --wave=" + top + ".ghw" << endl;
|
2015-03-22 11:04:27 +01:00
|
|
|
#endif
|
2015-04-09 08:20:12 +02:00
|
|
|
if (run("cd " + string(tempdir) + "; ./" + top + " " + wvargs + " --stop-time=" + st + " --wave=" + top + ".ghw")) {
|
2015-01-19 20:07:58 +01:00
|
|
|
cerr << "Error: Simulation failed." << endl;
|
|
|
|
}
|
|
|
|
else {
|
2015-01-20 21:03:51 +01:00
|
|
|
cout << "==> All done!" << endl;
|
2015-04-09 17:14:34 +02:00
|
|
|
if (gtksave != "") {
|
|
|
|
gtkargs += " --save=\"" + gtksave + "/" + top + ".gtkw\"";
|
|
|
|
}
|
2015-04-09 08:54:02 +02:00
|
|
|
string wv = "gtkwave " + string(tempdir) + "/" + top + ".ghw " + gtkargs + " &";
|
2015-01-19 20:07:58 +01:00
|
|
|
if (run("pidof gtkwave")) {
|
|
|
|
if (system(wv.c_str())) {
|
|
|
|
cerr << "Error: GtkWave failed.";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cout << "GtkWave started." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-19 18:11:14 +01:00
|
|
|
}
|
|
|
|
}
|
2015-01-19 20:07:58 +01:00
|
|
|
//}
|
2015-01-19 17:58:38 +01:00
|
|
|
|
2015-01-19 20:07:58 +01:00
|
|
|
//cout << "Simulation ended." << endl;
|
2015-01-19 17:58:38 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|