diff options
Diffstat (limited to 'csim')
-rw-r--r-- | csim/Makefile | 2 | ||||
-rw-r--r-- | csim/load.c | 47 | ||||
-rw-r--r-- | csim/main.c | 14 | ||||
-rw-r--r-- | csim/sim.c | 38 | ||||
-rw-r--r-- | csim/sim.h | 17 | ||||
-rw-r--r-- | csim/util.c | 48 |
6 files changed, 124 insertions, 42 deletions
diff --git a/csim/Makefile b/csim/Makefile index cc88ac3..6827579 100644 --- a/csim/Makefile +++ b/csim/Makefile @@ -1,4 +1,4 @@ -csim: main.o load.o sim.o +csim: main.o load.o sim.o util.o gcc -o csim $^ %.o: %.c diff --git a/csim/load.c b/csim/load.c index eb441cc..e6fcf29 100644 --- a/csim/load.c +++ b/csim/load.c @@ -11,9 +11,34 @@ #include "sim.h" +t_rom *roms = NULL; + +void add_rom(const char *prefix, FILE *file) { + int i; + + t_rom *rom = malloc(sizeof(t_rom)); + rom->prefix = prefix; + + // Load ROM file + fscanf(file, "%d %d\n", &(rom->addr_size), &(rom->word_size)); + rom->data = malloc(pow2(rom->addr_size) * sizeof(t_value)); + + for (i = 0; i < pow2(rom->addr_size); i++) { + fscanf(file, " "); + if (fscanf(file, "/%lu", &(rom->data[i]))) { + // ok, value is read + } else { + rom->data[i] = read_bool(file, NULL); + } + } + + rom->next = roms; + roms = rom; +} t_program *load_dumb_netlist (FILE *stream) { - int i, j; + int i, j, as, ws; + t_rom *r; // let us suppose that the input to be read is well-formed. t_program *p = malloc(sizeof(t_program)); @@ -94,9 +119,25 @@ t_program *load_dumb_netlist (FILE *stream) { break; case C_ROM: fscanf(stream, "%d %d %d ", - &(p->eqs[i].Rom.addr_size), - &(p->eqs[i].Rom.word_size), + &as, &ws, &(p->eqs[i].Rom.read_addr)); + p->eqs[i].Rom.rom = NULL; + // find corresponding ROM + for (r = roms; r != NULL; r = r->next) { + if (is_prefix(r->prefix, p->vars[p->eqs[i].dest_var].name)) { + if (r->addr_size == as && r->word_size == ws) { + p->eqs[i].Rom.rom = r; + break; + } else { + fprintf(stderr, + "Error: ROM prefixed by '%s' does not have size corresponding to variable that uses it.\n", + r->prefix); + } + } + } + if (p->eqs[i].Rom.rom == NULL) + fprintf(stderr, "Warning: ROM variable '%s' has no ROM data.\n", + p->vars[p->eqs[i].dest_var].name); break; case C_CONCAT: fscanf(stream, "%d %d ", diff --git a/csim/main.c b/csim/main.c index a43d7c9..6e5bc29 100644 --- a/csim/main.c +++ b/csim/main.c @@ -12,10 +12,12 @@ #include "sim.h" + void usage() { printf ("\nUsage:\n\tcsim [options] <netlist_file>\n\n"); printf("Available options:\n"); - printf("\n -rom <file>\n\tLoad a filename as a ROM file for the machine\n"); + printf("\n -rom <prefix> <file>\n\tLoad a filename as a ROM file for the machine\n"); + printf("\tA given ROM file is used for all ROM chips with variable name having given prefix\n"); printf("\n -n <steps>\n\tOnly run #steps steps of simulation (0 = infinity)\n"); printf("\n -in <in-file>\n\tRead inputs from given file (eg. named pipe). Defaults to STDIN.\n"); printf("\n -out <out-file>\n\tWrite outputs to given file (eg. named pipe). Defaults to STDOut.\n"); @@ -24,7 +26,6 @@ void usage() { // Arguments to be parsed int steps = 12; -char *romfile = NULL; char *filename = NULL; char *infile = NULL; char *outfile = NULL; @@ -34,7 +35,14 @@ int main(int argc, char **argv) { for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-rom")) { if (++i == argc) usage(); - romfile = argv[i]; + if (++i == argc) usage(); + FILE *rom = fopen(argv[i], "r"); + if (!rom) { + fprintf(stderr, "Could not open ROM file: '%s'\n", argv[i]); + return 1; + } + add_rom(argv[i-1], rom); + fclose(rom); } else if (!strcmp(argv[i], "-n")) { if (++i == argc) usage(); steps = atoi(argv[i]); @@ -13,16 +13,6 @@ #define DEBUG 0 -// Util - -int pow2(int exp) { - if (exp == 0) return 1; - if (exp == 1) return 2; - int k = pow2(exp / 2); - return (exp % 2 == 0 ? k * k : 2 * k * k); -} - -// The code t_machine *init_machine (t_program *p) { int i, j; @@ -62,27 +52,6 @@ t_machine *init_machine (t_program *p) { return m; } -t_value read_bool(FILE *stream, t_value *mask) { - t_value r = 0; - t_value pow = 1; - - char c; - if (mask != NULL) *mask = 0; - - for(;;) { - fscanf(stream, "%c", &c); - if (c == '1') { - r |= pow; - } else if (c != '0') { - break; - } - if (mask != NULL) (*mask) |= pow; - - pow *= 2; - } - - return r; -} void read_inputs(t_machine *m, FILE *stream) { /* FORMAT : For each input in the list, *in the order specified*, @@ -161,7 +130,12 @@ void machine_step(t_machine *m) { } break; case C_ROM: - // TODO + if (p->eqs[i].Rom.rom != NULL) { + a = m->var_values[p->eqs[i].Rom.read_addr]; + v = p->eqs[i].Rom.rom->data[a]; + } else { + v = 0; + } break; case C_CONCAT: a = m->var_values[p->eqs[i].Concat.a]; @@ -1,8 +1,6 @@ #ifndef DEF_SIM_H #define DEF_SIM_H -// TODO implement ROM - #include <stdio.h> // Gate types @@ -25,6 +23,14 @@ // Use 64-bit ints as bit arrays. Bit index 0 is bitmask 1, bit index 1 is bitmask 2, etc. typedef unsigned long long int t_value; + +typedef struct _s_rom { + int addr_size, word_size; + t_value *data; + const char *prefix; + struct _s_rom *next; +} t_rom; + // Identifier for the variables of the circuit. typedef int t_id; @@ -62,7 +68,7 @@ typedef struct { t_id a, b, c; } Mux; struct { - int addr_size, word_size; + t_rom *rom; t_id read_addr; } Rom; struct { @@ -109,11 +115,16 @@ typedef struct { // The functions for doing stuff with these data structures t_program *load_dumb_netlist(FILE *stream); +void add_rom(const char *prefix, FILE *file); t_machine *init_machine(t_program *p); void read_inputs(t_machine *m, FILE *stream); void machine_step(t_machine *m); void write_outputs(t_machine *m, FILE *stream); +// util +int pow2(int exp); +t_value read_bool(FILE *stream, t_value *mask); +int is_prefix(char *prefix, char *str); #endif diff --git a/csim/util.c b/csim/util.c new file mode 100644 index 0000000..a09e959 --- /dev/null +++ b/csim/util.c @@ -0,0 +1,48 @@ +/* + Système Digital + 2013-2014 + Alex AUVOLAT + + util.c Various utility functions used elsewhere +*/ + + +#include "sim.h" + +int pow2(int exp) { + if (exp == 0) return 1; + if (exp == 1) return 2; + int k = pow2(exp / 2); + return (exp % 2 == 0 ? k * k : 2 * k * k); +} + +t_value read_bool(FILE *stream, t_value *mask) { + t_value r = 0; + t_value pow = 1; + + char c; + if (mask != NULL) *mask = 0; + + for(;;) { + fscanf(stream, "%c", &c); + if (c == '1') { + r |= pow; + } else if (c != '0') { + break; + } + if (mask != NULL) (*mask) |= pow; + + pow *= 2; + } + + return r; +} + +int is_prefix(char *prefix, char *str) { + while (*prefix) { + if (*prefix != *str) return 0; + prefix++; + str++; + } + return 1; +} |