summaryrefslogtreecommitdiff
path: root/csim
diff options
context:
space:
mode:
Diffstat (limited to 'csim')
-rw-r--r--csim/Makefile2
-rw-r--r--csim/load.c47
-rw-r--r--csim/main.c14
-rw-r--r--csim/sim.c38
-rw-r--r--csim/sim.h17
-rw-r--r--csim/util.c48
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]);
diff --git a/csim/sim.c b/csim/sim.c
index 9c766e9..56c061b 100644
--- a/csim/sim.c
+++ b/csim/sim.c
@@ -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];
diff --git a/csim/sim.h b/csim/sim.h
index 8b4a726..27b492d 100644
--- a/csim/sim.h
+++ b/csim/sim.h
@@ -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;
+}