mirror of
				https://github.com/cclassic/model-ghdl
				synced 2025-11-04 02:49:33 +01:00 
			
		
		
		
	Fully functional now
This commit is contained in:
		
							
								
								
									
										140
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								main.c
									
									
									
									
									
								
							@@ -1,5 +1,7 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gui.h"
 | 
					#include "gui.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef PROGRAM_REVISION
 | 
					#ifndef PROGRAM_REVISION
 | 
				
			||||||
@@ -25,7 +27,51 @@ int get_application(const char *call);
 | 
				
			|||||||
int vsim(int argc, char **argv);
 | 
					int vsim(int argc, char **argv);
 | 
				
			||||||
int vcom(int argc, char **argv);
 | 
					int vcom(int argc, char **argv);
 | 
				
			||||||
int run_ghdl(char *command, ...);
 | 
					int run_ghdl(char *command, ...);
 | 
				
			||||||
 | 
					int run_simulation(char *command, ...);
 | 
				
			||||||
 | 
					int run_gtkwave(char *toplevel, char *command, ...);
 | 
				
			||||||
char* append_string(char **dest, const char *src);
 | 
					char* append_string(char **dest, const char *src);
 | 
				
			||||||
 | 
					pid_t system2(const char * command, int * infp, int * outfp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Thanks GreenScape
 | 
				
			||||||
 | 
					// http://stackoverflow.com/questions/22802902/how-to-get-pid-of-process-executed-with-system-command-in-c
 | 
				
			||||||
 | 
					pid_t system2(const char * command, int * infp, int * outfp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int p_stdin[2];
 | 
				
			||||||
 | 
					    int p_stdout[2];
 | 
				
			||||||
 | 
					    pid_t pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pipe(p_stdin) == -1)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pipe(p_stdout) == -1) {
 | 
				
			||||||
 | 
					        close(p_stdin[0]);
 | 
				
			||||||
 | 
					        close(p_stdin[1]);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pid = fork();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pid < 0) {
 | 
				
			||||||
 | 
					        close(p_stdin[0]);
 | 
				
			||||||
 | 
					        close(p_stdin[1]);
 | 
				
			||||||
 | 
					        close(p_stdout[0]);
 | 
				
			||||||
 | 
					        close(p_stdout[1]);
 | 
				
			||||||
 | 
					        return pid;
 | 
				
			||||||
 | 
					    } else if (pid == 0) {
 | 
				
			||||||
 | 
					        close(p_stdin[1]);
 | 
				
			||||||
 | 
					        dup2(p_stdin[0], 0);
 | 
				
			||||||
 | 
					        close(p_stdout[0]);
 | 
				
			||||||
 | 
					        dup2(p_stdout[1], 1);
 | 
				
			||||||
 | 
					        dup2(open("/dev/null", O_RDONLY), 2);
 | 
				
			||||||
 | 
					        /// Close all other descriptors for the safety sake.
 | 
				
			||||||
 | 
					        for (int i = 3; i < 4096; ++i)
 | 
				
			||||||
 | 
					            close(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        setsid();
 | 
				
			||||||
 | 
					        execl("/bin/sh", "sh", "-c", command, NULL);
 | 
				
			||||||
 | 
					        _exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int run_ghdl(char *command, ...) {
 | 
					int run_ghdl(char *command, ...) {
 | 
				
			||||||
    FILE *proc;
 | 
					    FILE *proc;
 | 
				
			||||||
@@ -42,7 +88,7 @@ int run_ghdl(char *command, ...) {
 | 
				
			|||||||
    vsprintf(cmd, command, argptr);
 | 
					    vsprintf(cmd, command, argptr);
 | 
				
			||||||
    va_end(argptr);
 | 
					    va_end(argptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("RUN: %s\n", cmd);
 | 
					    printf("RUN_GHDL: %s\n", cmd);
 | 
				
			||||||
    proc = popen(cmd, "r");
 | 
					    proc = popen(cmd, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (proc == NULL) {
 | 
					    if (proc == NULL) {
 | 
				
			||||||
@@ -79,6 +125,83 @@ int run_ghdl(char *command, ...) {
 | 
				
			|||||||
    return pclose(proc);
 | 
					    return pclose(proc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int run_simulation(char *command, ...) {
 | 
				
			||||||
 | 
					    FILE *proc;
 | 
				
			||||||
 | 
					    char buf[1 K];
 | 
				
			||||||
 | 
					    char cmd[1 K];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_list argptr;
 | 
				
			||||||
 | 
					    va_start(argptr, command);
 | 
				
			||||||
 | 
					    vsprintf(cmd, command, argptr);
 | 
				
			||||||
 | 
					    va_end(argptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("RUN_SIM: %s\n", cmd);
 | 
				
			||||||
 | 
					    proc = popen(cmd, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (proc == NULL) {
 | 
				
			||||||
 | 
					        printf("Error: Could not start the simulation.\n");
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(fgets(buf, sizeof(buf), proc)!=NULL){
 | 
				
			||||||
 | 
					        printf("** sim: %s", buf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pclose(proc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int run_gtkwave(char *toplevel, char *command, ...) {
 | 
				
			||||||
 | 
					    FILE *fp;
 | 
				
			||||||
 | 
					    pid_t pid;
 | 
				
			||||||
 | 
					    char cmd[1 K];
 | 
				
			||||||
 | 
					    char lockpath[1 K];
 | 
				
			||||||
 | 
					    va_list argptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sprintf(lockpath, "/tmp/model-ghdl-gtkw-%s.lock", toplevel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fp = fopen(lockpath,"r");
 | 
				
			||||||
 | 
					    if (fp) {
 | 
				
			||||||
 | 
					        fgets(cmd, sizeof(cmd), fp); // lets (ab)use the cmd variable here
 | 
				
			||||||
 | 
					        pid = atoi(cmd);
 | 
				
			||||||
 | 
					        fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (kill(pid, 0)) { // Check if the process still lives
 | 
				
			||||||
 | 
					            pid = -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            printf("GtkWave is already running.\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        pid = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pid < 0) {
 | 
				
			||||||
 | 
					        va_start(argptr, command);
 | 
				
			||||||
 | 
					        vsprintf(cmd, command, argptr);
 | 
				
			||||||
 | 
					        va_end(argptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        printf("RUN_SIM: %s\n", cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pid = system2(cmd, NULL, NULL);
 | 
				
			||||||
 | 
					        printf("--> PID=%d\n", pid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Prevent gtkw from starting again each time
 | 
				
			||||||
 | 
					        fp = fopen(lockpath,"w");
 | 
				
			||||||
 | 
					        if (fp) {
 | 
				
			||||||
 | 
					            fprintf(fp, "%d", pid);
 | 
				
			||||||
 | 
					            fclose(fp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            printf("Could not create temp file /tmp/model-ghdl-vcom! Ignoring...");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int vsim(int argc, char **argv)
 | 
					int vsim(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
@@ -95,6 +218,8 @@ int vsim(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    FILE *fp;
 | 
					    FILE *fp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    append_string(¶ms,"");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gui_init(&argc, &argv);
 | 
					    gui_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fp = fopen("/tmp/model-ghdl-vsim","r");
 | 
					    fp = fopen("/tmp/model-ghdl-vsim","r");
 | 
				
			||||||
@@ -166,9 +291,18 @@ int vsim(int argc, char **argv)
 | 
				
			|||||||
                fprintf(fp, "%s", simtime);
 | 
					                fprintf(fp, "%s", simtime);
 | 
				
			||||||
                fclose(fp);
 | 
					                fclose(fp);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            printf("Simulating...\n");
 | 
					            printf("Simulating...\n");
 | 
				
			||||||
            // TODO: Exec program
 | 
					            if (run_simulation("%s/%s --stop-time=%s --wave=%s.ghw", workdir, toplevel, simtime, toplevel)) {
 | 
				
			||||||
            // TODO: Exec GtkWave
 | 
					                fprintf(stderr, "[E] Simulation failed!");
 | 
				
			||||||
 | 
					                showMessage(MESSAGE_ERROR, "Error! Simulation failed.", NULL, NULL);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                if (run_gtkwave(toplevel, "gtkwave %s/%s.ghw --save=\"%s.gtkw\"", workdir, toplevel, toplevel)) { // TODO: PATH FOR Savefile
 | 
				
			||||||
 | 
					                    fprintf(stderr, "[E] Could not open GtkWave!");
 | 
				
			||||||
 | 
					                    showMessage(MESSAGE_ERROR, "Error! Could not open GtkWave!", NULL, NULL);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user