mirror of
				https://github.com/cclassic/model-ghdl
				synced 2025-10-31 02:22: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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user