mirror of
https://github.com/cclassic/model-ghdl
synced 2024-11-23 08:45:04 +01:00
Rewrite in plain C and gtk
This commit is contained in:
parent
ea1b2aff3f
commit
d65c627efa
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,3 +15,5 @@
|
||||
# Qt
|
||||
*.pro.user
|
||||
build-*
|
||||
*.txt.user
|
||||
|
||||
|
24
CMakeLists.txt
Normal file
24
CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
project(model-ghdl)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
aux_source_directory(. SRC_LIST)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
||||
|
||||
include_directories(${GTK3_INCLUDE_DIRS})
|
||||
link_directories(${GTK3_LIBRARY_DIRS})
|
||||
add_definitions(${GTK3_CFLAGS_OTHER})
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES})
|
||||
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ln -sf ${PROJECT_NAME} vsim
|
||||
COMMAND ln -sf ${PROJECT_NAME} vcom
|
||||
COMMAND ln -sf ${PROJECT_NAME} vmap
|
||||
COMMAND ln -sf ${PROJECT_NAME} vdel
|
||||
COMMAND ln -sf ${PROJECT_NAME} vlib
|
||||
)
|
@ -2,10 +2,3 @@ model-ghdl
|
||||
==========
|
||||
|
||||
A wrapper for GHDL to make it look like Mentor's ModelSim. Helpful for use with programs like Sigasi.
|
||||
|
||||
## Tips
|
||||
Add the following arguments in Sigasi:
|
||||
|
||||
### vsim
|
||||
* ```-ghdl "--std=08"``` to enable VHDL 2008 support (if any problems occur)
|
||||
* ```-gtksave "/path/to/your/gtkw-directory"``` to automatically load a specific wave layout (```<path>/<top_entity.gtkw>```)
|
||||
|
86
gui.c
Normal file
86
gui.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include "gui.h"
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
int gui_init(int *argc, char ***argv) {
|
||||
gtk_init (argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int showMessage(int message_type, char *text, char *defaultText, char **reply) {
|
||||
GtkWidget *window;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *buttonOkay;
|
||||
GtkWidget *buttonCancel;
|
||||
GtkWidget *buttonBox;
|
||||
GtkWidget *mainBox;
|
||||
GtkWidget *label;
|
||||
char *entryText;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), "Meow");
|
||||
|
||||
label = gtk_label_new(text);
|
||||
gtk_widget_show(label);
|
||||
|
||||
entry = gtk_entry_new();
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), (char*) defaultText);
|
||||
g_signal_connect (entry, "activate",
|
||||
G_CALLBACK(okay), entry);
|
||||
gtk_widget_show(entry);
|
||||
|
||||
buttonOkay = gtk_button_new_with_label("Okay!");
|
||||
gtk_widget_show(buttonOkay);
|
||||
buttonCancel = gtk_button_new_with_label("Cancel");
|
||||
gtk_widget_show(buttonCancel);
|
||||
|
||||
buttonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_box_pack_start(GTK_BOX(buttonBox), buttonCancel, true, true, 0);
|
||||
gtk_box_pack_start(GTK_BOX(buttonBox), buttonOkay, true, true, 0);
|
||||
g_signal_connect (buttonOkay, "clicked",
|
||||
G_CALLBACK(okay), entry);
|
||||
gtk_widget_show(buttonBox);
|
||||
|
||||
mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
|
||||
gtk_box_pack_start(GTK_BOX(mainBox), label, true, true, 0);
|
||||
gtk_box_pack_start(GTK_BOX(mainBox), entry, true, true, 0);
|
||||
gtk_box_pack_start(GTK_BOX(mainBox), buttonBox, true, true, 0);
|
||||
gtk_widget_show(mainBox);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(window), mainBox);
|
||||
gtk_widget_show (window);
|
||||
|
||||
gtk_main();
|
||||
|
||||
entryText = (char*) gtk_entry_get_text(GTK_ENTRY(entry));
|
||||
if (entryText[0] == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
*reply = realloc(*reply, sizeof(char)*strlen(entryText));
|
||||
if (*reply != NULL)
|
||||
strcpy(*reply, entryText);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
gtk_widget_destroy(window);
|
||||
}
|
||||
|
||||
static void okay( GtkWidget *widget,
|
||||
gpointer data )
|
||||
{
|
||||
//g_print ("TEXT = %s\n", gtk_entry_get_text(GTK_ENTRY(data)));
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
static void cancel( GtkWidget *widget,
|
||||
gpointer data )
|
||||
{
|
||||
gtk_entry_set_text(GTK_ENTRY(data), "");
|
||||
gtk_main_quit();
|
||||
}
|
13
gui.h
Normal file
13
gui.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int gui_init(int *argc, char ***argv);
|
||||
int showMessage(int message_type, char *text, char *defaultText, char **reply);
|
||||
|
||||
// Slots
|
||||
static void okay( GtkWidget *widget, gpointer data );
|
||||
|
||||
#endif // GUI_H
|
186
main.c
Normal file
186
main.c
Normal file
@ -0,0 +1,186 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gui.h"
|
||||
|
||||
#ifndef PROGRAM_REVISION
|
||||
#define PROGRAM_REVISION "#unknown"
|
||||
#endif
|
||||
|
||||
#define PROG_VCOM 0
|
||||
#define PROG_VSIM 1
|
||||
#define PROG_UNKNOWN 255
|
||||
|
||||
#define K *1024
|
||||
#define M K K
|
||||
#define G M K
|
||||
|
||||
#define ISOPT(cmd) (strcmp(argv[i], cmd) == 0)
|
||||
#define GETOPT(cmd) (strcmp(argv[i], cmd) == 0) && (++i < argc)
|
||||
|
||||
const char *laststrstr (const char *__haystack, const char *__needle);
|
||||
int get_application(const char *call);
|
||||
int vsim(int argc, char **argv);
|
||||
int vcom(int argc, char **argv);
|
||||
int run_ghdl(char *command, ...);
|
||||
char* append_string(char **dest, const char *src);
|
||||
|
||||
int run_ghdl(char *command, ...) {
|
||||
FILE *proc;
|
||||
char buf[1 K];
|
||||
char cmd[1 K];
|
||||
|
||||
char *arr[4];
|
||||
char *start;
|
||||
char *ptr;
|
||||
int arrc;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, command);
|
||||
vsprintf(cmd, command, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
printf("RUN: %s\n", cmd);
|
||||
proc = popen(cmd, "r");
|
||||
|
||||
if (proc == NULL) {
|
||||
printf("Error: Could not invoke GHDL/GtkWave.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ../blink/src/top.vhd:32:19: no declaration for "counter_i2"
|
||||
// v
|
||||
// ** Error: /tmp/filename.vhd(32): (vcom-1136) Unknown identifier "counter_i2".
|
||||
|
||||
while(fgets(buf, sizeof(buf), proc)!=NULL){
|
||||
ptr = buf;
|
||||
start = buf;
|
||||
arrc = 0;
|
||||
|
||||
do { // Search for EOL
|
||||
if (arrc < 4 && (*ptr == ':' || *ptr == '\0')) {
|
||||
*ptr++ = 0;
|
||||
arr[arrc++] = start;
|
||||
start = ptr;
|
||||
}
|
||||
} while (*ptr++ != '\0');
|
||||
|
||||
if (arrc == 4) {
|
||||
printf("** Error: %s(%s): (ghdl) %s", arr[0], arr[1], arr[3]);
|
||||
}
|
||||
else {
|
||||
printf("** ghdl: %s", buf);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return pclose(proc);
|
||||
}
|
||||
|
||||
int vsim(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
char *text = NULL;
|
||||
|
||||
gui_init(&argc, &argv);
|
||||
ret = showMessage(0, "Enter the simulation time: ", "100 ns", &text);
|
||||
printf("%d: %p: %s\n", ret, text, text);
|
||||
}
|
||||
|
||||
int vcom(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int slen = 0;
|
||||
char tempdir[1 K];
|
||||
char *work;
|
||||
char *files = NULL;
|
||||
|
||||
if (!getcwd(tempdir, sizeof(tempdir))) { // Default compile dir is cwd
|
||||
fprintf(stderr, "Error: Could not invoke GHDL!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i=1; i < argc; ++i) {
|
||||
if (GETOPT("-work")) {
|
||||
work = argv[i];
|
||||
}
|
||||
else if (GETOPT("-compiledir")) {
|
||||
strcpy(tempdir, argv[i]);
|
||||
}
|
||||
else if (argv[i][0] != '-'){ // VHDL file
|
||||
slen += strlen(argv[i]) + 1;
|
||||
files = realloc(files, slen * sizeof(char));
|
||||
strcat(files, " ");
|
||||
strcat(files, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
run_ghdl("ghdl -s %s 2>&1", files);
|
||||
|
||||
|
||||
free(files);
|
||||
|
||||
printf("DONE.\n");
|
||||
}
|
||||
|
||||
|
||||
char* append_string(char **dest, const char *src) {
|
||||
if (*dest == NULL) {
|
||||
*dest = malloc(strlen(src) * sizeof(char));
|
||||
if (*dest == NULL)
|
||||
return NULL;
|
||||
*dest[0] = 0;
|
||||
}
|
||||
else {
|
||||
*dest = realloc(*dest, (strlen(*dest) + strlen(src)) * sizeof(char));
|
||||
}
|
||||
|
||||
strcat(*dest, src);
|
||||
return *dest;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int app;
|
||||
printf ("model-ghdl revision %s, compiled on %s.\n", PROGRAM_REVISION, __DATE__);
|
||||
|
||||
app = get_application(argv[0]);
|
||||
|
||||
if (app == PROG_VCOM) {
|
||||
return vcom(argc, argv);
|
||||
}
|
||||
else if (app == PROG_VSIM) {
|
||||
return vsim(argc, argv);
|
||||
}
|
||||
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Detects which function to call depending on the program name in argv[0]
|
||||
int get_application(const char *call) {
|
||||
char *pos;
|
||||
pos = (char*) laststrstr(call, "/") + 1;
|
||||
if (strcmp(pos, "vcom") == 0) {
|
||||
return PROG_VCOM;
|
||||
}
|
||||
else if (strcmp(pos, "vsim") == 0) {
|
||||
return PROG_VCOM;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[E] Program not recognized: %s\n", pos);
|
||||
return PROG_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the string after the last occurence of __needle
|
||||
const char *laststrstr (const char *__haystack, const char *__needle) {
|
||||
char *pos, *realPos;
|
||||
char *haystack;
|
||||
haystack = (char*) __haystack;
|
||||
pos = (char*) __haystack;
|
||||
while (pos != NULL) {
|
||||
realPos = pos;
|
||||
pos = strstr(haystack, __needle);
|
||||
haystack = pos + 1;
|
||||
}
|
||||
return realPos;
|
||||
}
|
190
vcom/main.cpp
190
vcom/main.cpp
@ -1,190 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
// #define DEBUG_EN DEBUG_EN
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
> /tmp/SigasiCompileCache822149657706169838/blink/vcom > /home/markus/Downloads/Libero/install/Model/modeltech/linuxacoem/vcom -2008 -work design -modelsimini /tmp/SigasiCompileCache822149657706169838/blink/vcom/modelsim.ini /home/markus/workspaceSigasi/blink/src/top.vhd
|
||||
Model Technology ModelSim Microsemi vcom 10.3a Compiler 2014.04 Apr 15 2014
|
||||
Start time: 19:57:50 on Jan 18,2015
|
||||
vcom -2008 -work design -modelsimini /tmp/SigasiCompileCache822149657706169838/blink/vcom/modelsim.ini /home/markus/workspaceSigasi/blink/src/top.vhd
|
||||
-- Loading package STANDARD
|
||||
-- Loading package TEXTIO
|
||||
-- Loading package std_logic_1164
|
||||
-- Loading package NUMERIC_STD
|
||||
-- Compiling entity top
|
||||
-- Compiling architecture RTL of top
|
||||
** Error: /home/markus/workspaceSigasi/blink/src/top.vhd(32): (vcom-1136) Unknown identifier "counter_i2".
|
||||
** Error: /home/markus/workspaceSigasi/blink/src/top.vhd(33): VHDL Compiler exiting
|
||||
End time: 19:57:50 on Jan 18,2015, Elapsed time: 0: 0: 0
|
||||
Errors: 2, Warnings: 0
|
||||
|
||||
|
||||
|
||||
COMPILATION:
|
||||
> ghdl -i --warn-no-vital-generic --workdir=. --work=design ../blink/src/ *.vhd
|
||||
> ghdl -m --warn-no-vital-generic --workdir=. --work=work top
|
||||
../blink/src/top.vhd:32:19: no declaration for "counter_i2"
|
||||
|
||||
|
||||
SYNTAX CHECKING:
|
||||
> ghdl -s --warn-no-vital-generic --workdir=. --work=design ../blink/src/ *.vhd
|
||||
../blink/src/top.vhd:32:19: no declaration for "counter_i2"
|
||||
|
||||
|
||||
echo "EXTERNAL: $# $@"
|
||||
|
||||
vars=`echo "$@" | sed "s/-work /-work=/g"`;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define ISOPT(cmd) (string(argv[i]) == cmd)
|
||||
#define GETOPT(cmd) (string(argv[i]) == cmd) && (++i < argc)
|
||||
|
||||
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." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(fgets(buf, sizeof(buf), proc)!=NULL){
|
||||
//cout << buf;
|
||||
string temp = "";
|
||||
char *ptr = buf;
|
||||
|
||||
result.clear();
|
||||
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == ':' || *ptr == '\0') {
|
||||
result.push_back(temp);
|
||||
temp = "";
|
||||
}
|
||||
else {
|
||||
temp.append(" ");
|
||||
temp[temp.length()-1] = *ptr;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
result.push_back(temp);
|
||||
|
||||
if (result.size() == 4) {
|
||||
cout << "** Error: " << result[0] << "(" << result[1] << "):" << result[3];
|
||||
}
|
||||
else {
|
||||
cout << buf;
|
||||
}
|
||||
}
|
||||
pclose(proc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
string work = ""; // Current library
|
||||
string vhdl = ""; // Input VHDL files
|
||||
string vhdlver = ""; // VHDL Version
|
||||
string ghdlargs = ""; // Additional GHDL parameters
|
||||
char tempdir[256] = ""; // Compile dir
|
||||
|
||||
if (!getcwd(tempdir, sizeof(tempdir))) {
|
||||
cerr << "Error getting current working dir!" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i=1; i < argc; ++i) {
|
||||
if (GETOPT("-work")) {
|
||||
work = argv[i];
|
||||
//++i;
|
||||
}
|
||||
else if (GETOPT("-compiledir")) {
|
||||
strcpy(tempdir, argv[i]);
|
||||
}
|
||||
else if (ISOPT("-87")) {
|
||||
vhdlver = "--std=87";
|
||||
}
|
||||
else if (ISOPT("-93")) {
|
||||
vhdlver = "--std=93";
|
||||
}
|
||||
else if (ISOPT("-93c")) {
|
||||
vhdlver = "--std=93c";
|
||||
}
|
||||
else if (ISOPT("-2000")) {
|
||||
vhdlver = "--std=00";
|
||||
}
|
||||
else if (ISOPT("-2002")) {
|
||||
vhdlver = "--std=02";
|
||||
}
|
||||
else if (ISOPT("-2008")) {
|
||||
cerr << "WARN: VHDL 2008 is not yet fully supported by GHDL." << endl;
|
||||
vhdlver = "--std=08";
|
||||
}
|
||||
else if (GETOPT("-ghdl")) {
|
||||
ghdlargs += string(argv[i]) + " ";
|
||||
}
|
||||
else if (GETOPT("-modelsimini")) {
|
||||
// Not used
|
||||
// ++i; // But skip param
|
||||
}
|
||||
else {
|
||||
if (argv[i][0] == '-') {
|
||||
cerr << "INFO: Unknown command line opt: " << argv[i] << endl;
|
||||
}
|
||||
else {
|
||||
vhdl.append(argv[i]);
|
||||
vhdl.append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EN
|
||||
cout << "\n\nVCOM CALL PARSED:" << endl;
|
||||
cout << "\twork=" << work << endl;
|
||||
cout << "\tvhdl=" << vhdl << endl;
|
||||
cout << "\ttempdir=" << tempdir << endl;
|
||||
#endif
|
||||
|
||||
if (work == "" || vhdl == "" || string(tempdir) == "") {
|
||||
cerr << "Error: Incomplete/Unsupported vcom call." << endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Write temp path to /tmp
|
||||
ofstream myfile;
|
||||
myfile.open ("/tmp/ghdl-workdir");
|
||||
myfile << tempdir;
|
||||
myfile.flush();
|
||||
myfile.close();
|
||||
|
||||
string cargs = "ghdl -i " + vhdlver + " --warn-no-vital-generic " + ghdlargs + " --workdir=" + string(tempdir) + " --work=" + work + " " + vhdl + " 2>&1";
|
||||
string sargs = "ghdl -s " + vhdlver + " --warn-no-vital-generic " + ghdlargs + " --workdir=" + string(tempdir) + " --work=" + work + " " + vhdl + " 2>&1";
|
||||
|
||||
#ifdef DEBUG_EN
|
||||
cout << "RUN: " << cargs << endl;
|
||||
cout << "RUN: " << sargs << endl;
|
||||
#endif
|
||||
// Launch GHDL
|
||||
if (run(cargs) || run(sargs)) {
|
||||
cerr << "** Error: Error in model-ghdl." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
#QMAKE_CXXFLAGS += -std=c++11
|
238
vsim/main.cpp
238
vsim/main.cpp
@ -1,238 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
// #define DEBUG_EN DEBUG_EN
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Source: vsim -gui design.top(RTL)
|
||||
// Target: ghdl -m --warn-no-vital-generic --workdir=simu --work=work testb_file
|
||||
// ./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;
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
ifstream myfile;
|
||||
char fileTemp[128];
|
||||
myfile.open ("/tmp/ghdl-simtime");
|
||||
myfile.getline(fileTemp, sizeof(fileTemp));
|
||||
myfile.close();
|
||||
if (string(fileTemp) != "")
|
||||
defaultValue = string(fileTemp);
|
||||
|
||||
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 = "";
|
||||
}
|
||||
else {
|
||||
ofstream myfile;
|
||||
myfile.open ("/tmp/ghdl-simtime");
|
||||
myfile << defaultValue;
|
||||
myfile.flush();
|
||||
myfile.close();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
#define ISOPT(cmd) (string(argv[i]) == cmd)
|
||||
#define GETOPT(cmd) (string(argv[i]) == cmd) && (++i < argc)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
string top = "";
|
||||
string work = "";
|
||||
string simtime = "";
|
||||
string ghdlargs = "";
|
||||
string wvargs = "";
|
||||
string gtkargs = "";
|
||||
string gtksave = "";
|
||||
string vhdlver = ""; // VHDL Version
|
||||
int i;
|
||||
char tempdir[256] = ""; // Compile dir
|
||||
|
||||
ifstream myfile;
|
||||
myfile.open ("/tmp/ghdl-workdir");
|
||||
myfile.getline(tempdir, sizeof(tempdir));
|
||||
myfile.close();
|
||||
|
||||
for (i=1; i < argc; ++i) {
|
||||
if (ISOPT("-gui")) {
|
||||
|
||||
}
|
||||
else if (GETOPT("-compiledir")) {
|
||||
strcpy(tempdir, argv[i]);
|
||||
}
|
||||
else if (ISOPT("-87")) {
|
||||
vhdlver = "--std=87";
|
||||
}
|
||||
else if (ISOPT("-93")) {
|
||||
vhdlver = "--std=93";
|
||||
}
|
||||
else if (ISOPT("-93c")) {
|
||||
vhdlver = "--std=93c";
|
||||
}
|
||||
else if (ISOPT("-2000")) {
|
||||
vhdlver = "--std=00";
|
||||
}
|
||||
else if (ISOPT("-2002")) {
|
||||
vhdlver = "--std=02";
|
||||
}
|
||||
else if (ISOPT("-2008")) {
|
||||
cerr << "WARN: VHDL 2008 is not yet fully supported by GHDL." << endl;
|
||||
vhdlver = "--std=08";
|
||||
}
|
||||
else if (GETOPT("-ghdl")) {
|
||||
ghdlargs += string(argv[i]) + " ";
|
||||
}
|
||||
else if (GETOPT("-rargs")) {
|
||||
wvargs = argv[i];
|
||||
}
|
||||
else if (GETOPT("-gtkwave")) {
|
||||
gtkargs = argv[i];
|
||||
}
|
||||
else if (GETOPT("-gtksave")) {
|
||||
gtksave = argv[i];
|
||||
}
|
||||
else {
|
||||
if (argv[i][0] == '-') {
|
||||
cerr << "INFO: Unknown command line opt: " << argv[i] << endl;
|
||||
}
|
||||
else {
|
||||
top.append(argv[i]);
|
||||
top.append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -gui work.toplevel(RTL)
|
||||
string temp = "";
|
||||
for (unsigned int i=0; i < top.length(); ++i) {
|
||||
if (top.at(i) >= 'A' && top.at(i) <= 'Z')
|
||||
top.at(i) = top.at(i) - ('A'-'a'); // convert to lower case
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//bool ex = false;
|
||||
//while (!ex) {
|
||||
cout << "Compiling..." << endl;
|
||||
string cargs = "cd " + string(tempdir) + "; ghdl -m " + vhdlver + " " + ghdlargs + " --workdir=" + string(tempdir) + " --work=" + work + " " + top;
|
||||
#ifdef DEBUG_EN
|
||||
cout << "RUN: " << cargs << endl;
|
||||
#endif
|
||||
if (run(cargs)) {
|
||||
cerr << "Error: Compilation failed." << endl;
|
||||
run("zenity --error --text \"Compilation failed.\"");
|
||||
}
|
||||
else {
|
||||
cout << "done." << endl;
|
||||
cargs = "";
|
||||
string st = getSimulationTime();
|
||||
if (st != "") {
|
||||
cout << "Simulating..." << endl;
|
||||
#ifdef DEBUG_EN
|
||||
cout << "RUN: " << "cd " + string(tempdir) + "; ./" + top + " " + wvargs + " --stop-time=" + st + " --wave=" + top + ".ghw" << endl;
|
||||
#endif
|
||||
if (run("cd " + string(tempdir) + "; ./" + top + " " + wvargs + " --stop-time=" + st + " --wave=" + top + ".ghw")) {
|
||||
cerr << "Error: Simulation failed." << endl;
|
||||
}
|
||||
else {
|
||||
cout << "==> All done!" << endl;
|
||||
if (gtksave != "") {
|
||||
gtkargs += " --save=\"" + gtksave + "/" + top + ".gtkw\"";
|
||||
}
|
||||
string wv = "gtkwave " + string(tempdir) + "/" + top + ".ghw " + gtkargs + " &";
|
||||
if (run("pidof gtkwave")) {
|
||||
if (system(wv.c_str())) {
|
||||
cerr << "Error: GtkWave failed.";
|
||||
}
|
||||
else {
|
||||
cout << "GtkWave started." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
//cout << "Simulation ended." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user