summaryrefslogtreecommitdiff
path: root/csim
diff options
context:
space:
mode:
Diffstat (limited to 'csim')
-rw-r--r--csim/load.c304
-rw-r--r--csim/main.c154
-rw-r--r--csim/sim.c382
-rw-r--r--csim/sim.h122
-rw-r--r--csim/util.c52
5 files changed, 507 insertions, 507 deletions
diff --git a/csim/load.c b/csim/load.c
index 607e0e2..4e7583a 100644
--- a/csim/load.c
+++ b/csim/load.c
@@ -1,10 +1,10 @@
/*
- Système Digital
- 2013-2014
- Alex AUVOLAT
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
- load.c Code for loading dumbed-down netlist files
- (no parsing of .net files !!)
+ load.c Code for loading dumbed-down netlist files
+ (no parsing of .net files !!)
*/
#include <stdlib.h>
@@ -14,154 +14,154 @@
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;
+ 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, as, ws;
- t_rom *r;
-
- // let us suppose that the input to be read is well-formed.
- t_program *p = malloc(sizeof(t_program));
-
- // Read variable list, with sizes and identifiers
- fscanf(stream, "%d ", &(p->n_vars));
- p->vars = malloc(p->n_vars * sizeof(t_variable));
-
- for (i = 0; i < p->n_vars; i++) {
- fscanf(stream, "%d ", &(p->vars[i].size));
- for(j = 0; j < p->vars[i].size; j++) {
- p->vars[i].mask = (p->vars[i].mask << 1) | 1;
- }
-
- p->vars[i].name = malloc(42); // let's bet that the name of a variable will never be longer than 42 chars
- fscanf(stream, "%s\n", p->vars[i].name);
-
- if (p->vars[i].size >= 8*sizeof(t_value)) {
- fprintf(stderr, "Warning: variable %s might be too big for machine integers.\n", p->vars[i].name);
- }
- }
-
- // read input list
- fscanf(stream, "%d ", &(p->n_inputs));
- p->inputs = malloc(p->n_inputs * sizeof(t_id));
- for (i = 0; i < p->n_inputs; i++) {
- fscanf(stream, "%d ", &(p->inputs[i]));
- }
- // read output list
- fscanf(stream, "%d ", &(p->n_outputs));
- p->outputs = malloc(p->n_outputs * sizeof(t_id));
- for (i = 0; i < p->n_outputs; i++) {
- fscanf(stream, "%d ", &(p->outputs[i]));
- }
-
- // read register list
- fscanf(stream, "%d", &(p->n_regs));
- p->regs = malloc(p->n_regs * sizeof(t_reg));
- for (i = 0; i < p->n_regs; i++) {
- fscanf(stream, "%d %d\n", &(p->regs[i].dest), &(p->regs[i].source));
- }
- // read RAM list
- fscanf(stream, "%d", &(p->n_rams));
- p->rams = malloc(p->n_rams * sizeof(t_ram));
- for (i = 0; i < p->n_rams; i++) {
- fscanf(stream, "%d %d %d %d %d\n",
- &(p->rams[i].addr_size),
- &(p->rams[i].word_size),
- &(p->rams[i].write_enable),
- &(p->rams[i].write_addr), &(p->rams[i].data));
- }
-
- // read equation list
- fscanf(stream, "%d ", &(p->n_eqs));
- p->eqs = malloc(p->n_eqs * sizeof(t_equation));
- for (i = 0; i < p->n_eqs; i++) {
- fscanf(stream, "%d ", &(p->eqs[i].dest_var));
- fscanf(stream, "%d ", &(p->eqs[i].type));
- switch (p->eqs[i].type) {
- case C_COPY:
- fscanf(stream, "%d ", &(p->eqs[i].Copy.a));
- break;
- case C_NOT:
- fscanf(stream, "%d ", &(p->eqs[i].Not.a));
- break;
- case C_BINOP:
- fscanf(stream, "%d %d %d ",
- &(p->eqs[i].Binop.op),
- &(p->eqs[i].Binop.a),
- &(p->eqs[i].Binop.b));
- break;
- case C_MUX:
- fscanf(stream, "%d %d %d ",
- &(p->eqs[i].Mux.a),
- &(p->eqs[i].Mux.b),
- &(p->eqs[i].Mux.c));
- break;
- case C_ROM:
- fscanf(stream, "%d %d %d ",
- &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 ",
- &(p->eqs[i].Concat.a),
- &(p->eqs[i].Concat.b));
- p->eqs[i].Concat.shift = p->vars[p->eqs[i].Concat.a].size;
- break;
- case C_SLICE:
- fscanf(stream, "%d %d %d ",
- &(p->eqs[i].Slice.begin),
- &(p->eqs[i].Slice.end),
- &(p->eqs[i].Slice.source));
- break;
- case C_SELECT:
- fscanf(stream, "%d %d ",
- &(p->eqs[i].Select.i),
- &(p->eqs[i].Select.source));
- break;
- case C_READRAM:
- fscanf(stream, "%d %d ",
- &(p->eqs[i].ReadRAM.ram_id),
- &(p->eqs[i].ReadRAM.source));
- break;
- }
- }
-
- return p;
+ 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));
+
+ // Read variable list, with sizes and identifiers
+ fscanf(stream, "%d ", &(p->n_vars));
+ p->vars = malloc(p->n_vars * sizeof(t_variable));
+
+ for (i = 0; i < p->n_vars; i++) {
+ fscanf(stream, "%d ", &(p->vars[i].size));
+ for(j = 0; j < p->vars[i].size; j++) {
+ p->vars[i].mask = (p->vars[i].mask << 1) | 1;
+ }
+
+ p->vars[i].name = malloc(42); // let's bet that the name of a variable will never be longer than 42 chars
+ fscanf(stream, "%s\n", p->vars[i].name);
+
+ if (p->vars[i].size >= 8*sizeof(t_value)) {
+ fprintf(stderr, "Warning: variable %s might be too big for machine integers.\n", p->vars[i].name);
+ }
+ }
+
+ // read input list
+ fscanf(stream, "%d ", &(p->n_inputs));
+ p->inputs = malloc(p->n_inputs * sizeof(t_id));
+ for (i = 0; i < p->n_inputs; i++) {
+ fscanf(stream, "%d ", &(p->inputs[i]));
+ }
+ // read output list
+ fscanf(stream, "%d ", &(p->n_outputs));
+ p->outputs = malloc(p->n_outputs * sizeof(t_id));
+ for (i = 0; i < p->n_outputs; i++) {
+ fscanf(stream, "%d ", &(p->outputs[i]));
+ }
+
+ // read register list
+ fscanf(stream, "%d", &(p->n_regs));
+ p->regs = malloc(p->n_regs * sizeof(t_reg));
+ for (i = 0; i < p->n_regs; i++) {
+ fscanf(stream, "%d %d\n", &(p->regs[i].dest), &(p->regs[i].source));
+ }
+ // read RAM list
+ fscanf(stream, "%d", &(p->n_rams));
+ p->rams = malloc(p->n_rams * sizeof(t_ram));
+ for (i = 0; i < p->n_rams; i++) {
+ fscanf(stream, "%d %d %d %d %d\n",
+ &(p->rams[i].addr_size),
+ &(p->rams[i].word_size),
+ &(p->rams[i].write_enable),
+ &(p->rams[i].write_addr), &(p->rams[i].data));
+ }
+
+ // read equation list
+ fscanf(stream, "%d ", &(p->n_eqs));
+ p->eqs = malloc(p->n_eqs * sizeof(t_equation));
+ for (i = 0; i < p->n_eqs; i++) {
+ fscanf(stream, "%d ", &(p->eqs[i].dest_var));
+ fscanf(stream, "%d ", &(p->eqs[i].type));
+ switch (p->eqs[i].type) {
+ case C_COPY:
+ fscanf(stream, "%d ", &(p->eqs[i].Copy.a));
+ break;
+ case C_NOT:
+ fscanf(stream, "%d ", &(p->eqs[i].Not.a));
+ break;
+ case C_BINOP:
+ fscanf(stream, "%d %d %d ",
+ &(p->eqs[i].Binop.op),
+ &(p->eqs[i].Binop.a),
+ &(p->eqs[i].Binop.b));
+ break;
+ case C_MUX:
+ fscanf(stream, "%d %d %d ",
+ &(p->eqs[i].Mux.a),
+ &(p->eqs[i].Mux.b),
+ &(p->eqs[i].Mux.c));
+ break;
+ case C_ROM:
+ fscanf(stream, "%d %d %d ",
+ &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 ",
+ &(p->eqs[i].Concat.a),
+ &(p->eqs[i].Concat.b));
+ p->eqs[i].Concat.shift = p->vars[p->eqs[i].Concat.a].size;
+ break;
+ case C_SLICE:
+ fscanf(stream, "%d %d %d ",
+ &(p->eqs[i].Slice.begin),
+ &(p->eqs[i].Slice.end),
+ &(p->eqs[i].Slice.source));
+ break;
+ case C_SELECT:
+ fscanf(stream, "%d %d ",
+ &(p->eqs[i].Select.i),
+ &(p->eqs[i].Select.source));
+ break;
+ case C_READRAM:
+ fscanf(stream, "%d %d ",
+ &(p->eqs[i].ReadRAM.ram_id),
+ &(p->eqs[i].ReadRAM.source));
+ break;
+ }
+ }
+
+ return p;
}
diff --git a/csim/main.c b/csim/main.c
index 6e5bc29..5689cb4 100644
--- a/csim/main.c
+++ b/csim/main.c
@@ -1,9 +1,9 @@
/*
- Système Digital
- 2013-2014
- Alex AUVOLAT
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
- main.c Main file for the C simulator
+ main.c Main file for the C simulator
*/
#include <stdlib.h>
@@ -14,14 +14,14 @@
void usage() {
- printf ("\nUsage:\n\tcsim [options] <netlist_file>\n\n");
- printf("Available options:\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");
- exit(1);
+ printf ("\nUsage:\n\tcsim [options] <netlist_file>\n\n");
+ printf("Available options:\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");
+ exit(1);
}
// Arguments to be parsed
@@ -31,77 +31,77 @@ char *infile = NULL;
char *outfile = NULL;
int main(int argc, char **argv) {
- int i;
- for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-rom")) {
- if (++i == argc) usage();
- 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]);
- } else if (!strcmp(argv[i], "-in")) {
- if (++i == argc) usage();
- infile = argv[i];
- } else if (!strcmp(argv[i], "-out")) {
- if (++i == argc) usage();
- outfile = argv[i];
- } else {
- filename = argv[i];
- }
- }
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-rom")) {
+ if (++i == argc) usage();
+ 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]);
+ } else if (!strcmp(argv[i], "-in")) {
+ if (++i == argc) usage();
+ infile = argv[i];
+ } else if (!strcmp(argv[i], "-out")) {
+ if (++i == argc) usage();
+ outfile = argv[i];
+ } else {
+ filename = argv[i];
+ }
+ }
- if (filename == NULL) usage();
+ if (filename == NULL) usage();
- // Load program
- FILE *p_in;
- p_in = fopen(filename, "r");
- if (!p_in) {
- fprintf(stderr, "Error: could not open file %s for input.\n", filename);
- return 1;
- }
- t_program* program = load_dumb_netlist(p_in);
- fclose(p_in);
+ // Load program
+ FILE *p_in;
+ p_in = fopen(filename, "r");
+ if (!p_in) {
+ fprintf(stderr, "Error: could not open file %s for input.\n", filename);
+ return 1;
+ }
+ t_program* program = load_dumb_netlist(p_in);
+ fclose(p_in);
- // Setup input and outputs
- FILE *input = stdin, *output = stdout;
- if (infile != NULL) {
- input = fopen(infile, "r");
- if (!infile) {
- fprintf(stderr, "Error: could not open file %s for input.\n", infile);
- return 1;
- }
- }
- if (outfile != NULL) {
- output = fopen(outfile, "w");
- if (!output) {
- fprintf(stderr, "Error: could not open file %s for output.\n", outfile);
- return 1;
- }
- }
+ // Setup input and outputs
+ FILE *input = stdin, *output = stdout;
+ if (infile != NULL) {
+ input = fopen(infile, "r");
+ if (!infile) {
+ fprintf(stderr, "Error: could not open file %s for input.\n", infile);
+ return 1;
+ }
+ }
+ if (outfile != NULL) {
+ output = fopen(outfile, "w");
+ if (!output) {
+ fprintf(stderr, "Error: could not open file %s for output.\n", outfile);
+ return 1;
+ }
+ }
- // Run
- t_machine *machine = init_machine(program);
- i = 0;
- while (i < steps || steps == 0) {
- read_inputs(machine, input);
- machine_step(machine);
- write_outputs(machine, output);
- i++;
- }
+ // Run
+ t_machine *machine = init_machine(program);
+ i = 0;
+ while (i < steps || steps == 0) {
+ read_inputs(machine, input);
+ machine_step(machine);
+ write_outputs(machine, output);
+ i++;
+ }
- // Cleanup
- if (input != stdin) fclose(input);
- if (output != stdout) fclose(output);
+ // Cleanup
+ if (input != stdin) fclose(input);
+ if (output != stdout) fclose(output);
- // No need to free memory, the OS deletes everything anyways when the process ends.
+ // No need to free memory, the OS deletes everything anyways when the process ends.
- return 0;
+ return 0;
}
diff --git a/csim/sim.c b/csim/sim.c
index db30ea3..e3d61da 100644
--- a/csim/sim.c
+++ b/csim/sim.c
@@ -1,9 +1,9 @@
/*
- Système Digital
- 2013-2014
- Alex AUVOLAT
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
- sim.c The code that actually runs the machine
+ sim.c The code that actually runs the machine
*/
#include <stdlib.h>
@@ -15,203 +15,203 @@
t_machine *init_machine (t_program *p) {
- int i, j;
-
- t_machine *m = malloc(sizeof(t_machine));
- m->prog = p;
-
- // Allocate variables
- m->var_values = malloc(p->n_vars * sizeof(t_value));
- for (i = 0; i < p->n_vars; i++) {
- m->var_values[i] = 0;
- if (p->vars[i].name[0] == '$') {
- // setup constant value
- t_value a = 1;
- char *o = p->vars[i].name + 1;
- while (*o) {
- if (*o == '1') m->var_values[i] |= a;
- a <<= 1;
- o++;
- }
- }
- }
-
- // Allocate space for registers and rams
- m->reg_data = malloc(p->n_regs * sizeof(t_value));
- for (i = 0; i < p->n_regs; i++) {
- m->reg_data[i] = 0;
- }
- m->ram_data = malloc(p->n_rams * sizeof(t_value*));
- for (i = 0; i < p->n_rams; i++) {
- m->ram_data[i] = malloc(pow2(p->rams[i].addr_size) * sizeof(t_value));
- for (j = 0; j < pow2(p->rams[i].addr_size); j++) {
- m->ram_data[i][j] = 0;
- }
- }
-
- return m;
+ int i, j;
+
+ t_machine *m = malloc(sizeof(t_machine));
+ m->prog = p;
+
+ // Allocate variables
+ m->var_values = malloc(p->n_vars * sizeof(t_value));
+ for (i = 0; i < p->n_vars; i++) {
+ m->var_values[i] = 0;
+ if (p->vars[i].name[0] == '$') {
+ // setup constant value
+ t_value a = 1;
+ char *o = p->vars[i].name + 1;
+ while (*o) {
+ if (*o == '1') m->var_values[i] |= a;
+ a <<= 1;
+ o++;
+ }
+ }
+ }
+
+ // Allocate space for registers and rams
+ m->reg_data = malloc(p->n_regs * sizeof(t_value));
+ for (i = 0; i < p->n_regs; i++) {
+ m->reg_data[i] = 0;
+ }
+ m->ram_data = malloc(p->n_rams * sizeof(t_value*));
+ for (i = 0; i < p->n_rams; i++) {
+ m->ram_data[i] = malloc(pow2(p->rams[i].addr_size) * sizeof(t_value));
+ for (j = 0; j < pow2(p->rams[i].addr_size); j++) {
+ m->ram_data[i][j] = 0;
+ }
+ }
+
+ return m;
}
void read_inputs(t_machine *m, FILE *stream) {
- /* FORMAT :
- For each input in the list, *in the order specified*,
- either '/' followed by the decimal value
- or the binary value
- */
- int i;
- t_id var;
- t_program *p = m->prog;
-
- if (p->n_inputs == 0) return; // nothing to do
-
- for (i = 0; i < p->n_inputs; i++) {
- var = p->inputs[i];
- fscanf(stream, " ");
- if (fscanf(stream, "/%lu", &(m->var_values[var]))) {
- // ok, value is read
- } else {
- m->var_values[var] = read_bool(stream, NULL);
- }
- m->var_values[var] &= p->vars[var].mask;
- }
+ /* FORMAT :
+ For each input in the list, *in the order specified*,
+ either '/' followed by the decimal value
+ or the binary value
+ */
+ int i;
+ t_id var;
+ t_program *p = m->prog;
+
+ if (p->n_inputs == 0) return; // nothing to do
+
+ for (i = 0; i < p->n_inputs; i++) {
+ var = p->inputs[i];
+ fscanf(stream, " ");
+ if (fscanf(stream, "/%lu", &(m->var_values[var]))) {
+ // ok, value is read
+ } else {
+ m->var_values[var] = read_bool(stream, NULL);
+ }
+ m->var_values[var] &= p->vars[var].mask;
+ }
}
void machine_step(t_machine *m) {
- int i, j;
- t_value a, b, c, d, e, ma, mb, v;
- t_program *p = m->prog;
-
- // READ REGISTERS && MEMORY
- for (i = 0; i < p->n_regs; i++) {
- m->var_values[p->regs[i].dest] = m->reg_data[i];
- if (DEBUG) fprintf(stderr, "%s <- reg %s : %lx\n",
- p->vars[p->regs[i].dest].name,
- p->vars[p->regs[i].dest].name,
- m->reg_data[i]);
- }
-
- // DO THE LOGIC
- for (i = 0; i < p->n_eqs; i++) {
- v = 0;
- switch (p->eqs[i].type) {
- case C_COPY:
- v = m->var_values[p->eqs[i].Copy.a];
- break;
- case C_NOT:
- v = ~m->var_values[p->eqs[i].Not.a];
- break;
- case C_BINOP:
- a = m->var_values[p->eqs[i].Binop.a];
- b = m->var_values[p->eqs[i].Binop.b];
- if (p->eqs[i].Binop.op == OP_OR) v = a | b;
- if (p->eqs[i].Binop.op == OP_AND) v = a & b;
- if (p->eqs[i].Binop.op == OP_XOR) v = a ^ b;
- if (p->eqs[i].Binop.op == OP_NAND) v = ~(a & b);
- break;
- case C_MUX:
- a = m->var_values[p->eqs[i].Mux.a];
- b = m->var_values[p->eqs[i].Mux.b];
- c = m->var_values[p->eqs[i].Mux.c];
- ma = m->prog->vars[p->eqs[i].Mux.a].mask;
- if (ma == 1) {
- v = (a ? c : b);
- } else {
- v = (a & c) | (~a & b);
- }
- break;
- case C_ROM:
- 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];
- b = m->var_values[p->eqs[i].Concat.b];
- ma = p->vars[p->eqs[i].Concat.a].mask;
- mb = p->vars[p->eqs[i].Concat.b].mask;
- b <<= p->eqs[i].Concat.shift;
- v = a | b;
- if (DEBUG) fprintf (stderr, "concat %lx (&%lx) %lx (&%lx) <%d = %lx .. ",
- a, ma, b, mb, p->eqs[i].Concat.shift, v);
- break;
- case C_SLICE:
- a = m->var_values[p->eqs[i].Slice.source];
- ma = 1;
- mb = 0;
- for (j = 0; j <= p->eqs[i].Slice.end; j++) {
- if (j >= p->eqs[i].Slice.begin) mb |= ma;
- ma <<= 1;
- }
- v = (a & mb) >> p->eqs[i].Slice.begin;
- if (DEBUG) fprintf(stderr, "slice %d-%d m=%lx %lx->%lx .. ",
- p->eqs[i].Slice.begin,
- p->eqs[i].Slice.end,
- mb, a, v);
- break;
- case C_SELECT:
- a = m->var_values[p->eqs[i].Select.source];
- v = (a >> p->eqs[i].Select.i) & 1;
- if (DEBUG) fprintf(stderr, "select %d %lx->%lx .. ",
- p->eqs[i].Select.i, a, v);
- break;
- case C_READRAM:
- a = m->var_values[p->eqs[i].ReadRAM.source];
- v = m->ram_data[p->eqs[i].ReadRAM.ram_id][a];
- if (DEBUG) fprintf(stderr, "Read ram %lx = %lx\n", a, v);
- }
- m->var_values[p->eqs[i].dest_var] = v & (p->vars[p->eqs[i].dest_var].mask);
- if (DEBUG) fprintf(stderr, "%s &%lx : %lx\n",
- p->vars[p->eqs[i].dest_var].name,
- p->vars[p->eqs[i].dest_var].mask,
- m->var_values[p->eqs[i].dest_var]);
- }
-
- // SAVE REGISTERS && MEMORY
- for (i = 0; i < p->n_regs; i++) {
- m->reg_data[i] = m->var_values[p->regs[i].source];
- if (DEBUG) fprintf(stderr, "reg %s <- %s : %lx\n",
- p->vars[p->regs[i].dest].name,
- p->vars[p->regs[i].source].name,
- m->reg_data[i]);
- }
- for (i = 0; i < p->n_rams; i++) {
- e = m->var_values[p->rams[i].write_enable];
- if (e != 0) {
- a = m->var_values[p->rams[i].write_addr];
- d = m->var_values[p->rams[i].data];
- m->ram_data[i][a] = d;
- if (DEBUG) fprintf(stderr, "Write ram %lx = %lx\n", a, d);
- }
- }
+ int i, j;
+ t_value a, b, c, d, e, ma, mb, v;
+ t_program *p = m->prog;
+
+ // READ REGISTERS && MEMORY
+ for (i = 0; i < p->n_regs; i++) {
+ m->var_values[p->regs[i].dest] = m->reg_data[i];
+ if (DEBUG) fprintf(stderr, "%s <- reg %s : %lx\n",
+ p->vars[p->regs[i].dest].name,
+ p->vars[p->regs[i].dest].name,
+ m->reg_data[i]);
+ }
+
+ // DO THE LOGIC
+ for (i = 0; i < p->n_eqs; i++) {
+ v = 0;
+ switch (p->eqs[i].type) {
+ case C_COPY:
+ v = m->var_values[p->eqs[i].Copy.a];
+ break;
+ case C_NOT:
+ v = ~m->var_values[p->eqs[i].Not.a];
+ break;
+ case C_BINOP:
+ a = m->var_values[p->eqs[i].Binop.a];
+ b = m->var_values[p->eqs[i].Binop.b];
+ if (p->eqs[i].Binop.op == OP_OR) v = a | b;
+ if (p->eqs[i].Binop.op == OP_AND) v = a & b;
+ if (p->eqs[i].Binop.op == OP_XOR) v = a ^ b;
+ if (p->eqs[i].Binop.op == OP_NAND) v = ~(a & b);
+ break;
+ case C_MUX:
+ a = m->var_values[p->eqs[i].Mux.a];
+ b = m->var_values[p->eqs[i].Mux.b];
+ c = m->var_values[p->eqs[i].Mux.c];
+ ma = m->prog->vars[p->eqs[i].Mux.a].mask;
+ if (ma == 1) {
+ v = (a ? c : b);
+ } else {
+ v = (a & c) | (~a & b);
+ }
+ break;
+ case C_ROM:
+ 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];
+ b = m->var_values[p->eqs[i].Concat.b];
+ ma = p->vars[p->eqs[i].Concat.a].mask;
+ mb = p->vars[p->eqs[i].Concat.b].mask;
+ b <<= p->eqs[i].Concat.shift;
+ v = a | b;
+ if (DEBUG) fprintf (stderr, "concat %lx (&%lx) %lx (&%lx) <%d = %lx .. ",
+ a, ma, b, mb, p->eqs[i].Concat.shift, v);
+ break;
+ case C_SLICE:
+ a = m->var_values[p->eqs[i].Slice.source];
+ ma = 1;
+ mb = 0;
+ for (j = 0; j <= p->eqs[i].Slice.end; j++) {
+ if (j >= p->eqs[i].Slice.begin) mb |= ma;
+ ma <<= 1;
+ }
+ v = (a & mb) >> p->eqs[i].Slice.begin;
+ if (DEBUG) fprintf(stderr, "slice %d-%d m=%lx %lx->%lx .. ",
+ p->eqs[i].Slice.begin,
+ p->eqs[i].Slice.end,
+ mb, a, v);
+ break;
+ case C_SELECT:
+ a = m->var_values[p->eqs[i].Select.source];
+ v = (a >> p->eqs[i].Select.i) & 1;
+ if (DEBUG) fprintf(stderr, "select %d %lx->%lx .. ",
+ p->eqs[i].Select.i, a, v);
+ break;
+ case C_READRAM:
+ a = m->var_values[p->eqs[i].ReadRAM.source];
+ v = m->ram_data[p->eqs[i].ReadRAM.ram_id][a];
+ if (DEBUG) fprintf(stderr, "Read ram %lx = %lx\n", a, v);
+ }
+ m->var_values[p->eqs[i].dest_var] = v & (p->vars[p->eqs[i].dest_var].mask);
+ if (DEBUG) fprintf(stderr, "%s &%lx : %lx\n",
+ p->vars[p->eqs[i].dest_var].name,
+ p->vars[p->eqs[i].dest_var].mask,
+ m->var_values[p->eqs[i].dest_var]);
+ }
+
+ // SAVE REGISTERS && MEMORY
+ for (i = 0; i < p->n_regs; i++) {
+ m->reg_data[i] = m->var_values[p->regs[i].source];
+ if (DEBUG) fprintf(stderr, "reg %s <- %s : %lx\n",
+ p->vars[p->regs[i].dest].name,
+ p->vars[p->regs[i].source].name,
+ m->reg_data[i]);
+ }
+ for (i = 0; i < p->n_rams; i++) {
+ e = m->var_values[p->rams[i].write_enable];
+ if (e != 0) {
+ a = m->var_values[p->rams[i].write_addr];
+ d = m->var_values[p->rams[i].data];
+ m->ram_data[i][a] = d;
+ if (DEBUG) fprintf(stderr, "Write ram %lx = %lx\n", a, d);
+ }
+ }
}
void write_outputs(t_machine *m, FILE *stream) {
- /* FORMAT :
- For each output value, a line in the form
- var_name binary_value decimal_value
- */
- int i;
- t_id var;
- t_value v, mask;
- t_program *p = m->prog;
-
- for (i = 0; i < p->n_outputs; i++) {
- var = p->outputs[i];
- fprintf(stream, "%s\t", p->vars[var].name);
- v = m->var_values[var];
- mask = p->vars[var].mask;
- while (mask > 0) {
- fprintf(stream, "%d", v & 1);
- v >>= 1;
- mask >>= 1;
- }
- fprintf(stream, "\t%ld\n", m->var_values[var]);
- }
- fprintf(stream, "\n");
+ /* FORMAT :
+ For each output value, a line in the form
+ var_name binary_value decimal_value
+ */
+ int i;
+ t_id var;
+ t_value v, mask;
+ t_program *p = m->prog;
+
+ for (i = 0; i < p->n_outputs; i++) {
+ var = p->outputs[i];
+ fprintf(stream, "%s\t", p->vars[var].name);
+ v = m->var_values[var];
+ mask = p->vars[var].mask;
+ while (mask > 0) {
+ fprintf(stream, "%d", v & 1);
+ v >>= 1;
+ mask >>= 1;
+ }
+ fprintf(stream, "\t%ld\n", m->var_values[var]);
+ }
+ fprintf(stream, "\n");
}
diff --git a/csim/sim.h b/csim/sim.h
index 80fab56..c331fa5 100644
--- a/csim/sim.h
+++ b/csim/sim.h
@@ -26,93 +26,93 @@
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;
+ 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;
-typedef struct { // a variable in the simulator
- t_value mask;
- int size;
- char *name;
+typedef struct { // a variable in the simulator
+ t_value mask;
+ int size;
+ char *name;
} t_variable;
typedef struct {
- t_id dest, source;
+ t_id dest, source;
} t_reg;
typedef struct {
- int addr_size, word_size;
- t_id write_enable, write_addr, data;
+ int addr_size, word_size;
+ t_id write_enable, write_addr, data;
} t_ram;
typedef struct {
- int type;
- t_id dest_var;
- union {
- struct {
- t_id a;
- } Copy;
- struct {
- t_id a;
- } Not;
- struct {
- int op;
- t_id a, b;
- } Binop;
- struct {
- t_id a, b, c;
- } Mux;
- struct {
- t_rom *rom;
- t_id read_addr;
- } Rom;
- struct {
- t_id a, b;
- int shift;
- } Concat;
- struct {
- int begin, end;
- t_id source;
- } Slice;
- struct {
- int i;
- t_id source;
- } Select;
- struct {
- int ram_id;
- t_id source;
- } ReadRAM;
- };
+ int type;
+ t_id dest_var;
+ union {
+ struct {
+ t_id a;
+ } Copy;
+ struct {
+ t_id a;
+ } Not;
+ struct {
+ int op;
+ t_id a, b;
+ } Binop;
+ struct {
+ t_id a, b, c;
+ } Mux;
+ struct {
+ t_rom *rom;
+ t_id read_addr;
+ } Rom;
+ struct {
+ t_id a, b;
+ int shift;
+ } Concat;
+ struct {
+ int begin, end;
+ t_id source;
+ } Slice;
+ struct {
+ int i;
+ t_id source;
+ } Select;
+ struct {
+ int ram_id;
+ t_id source;
+ } ReadRAM;
+ };
} t_equation;
typedef struct {
- int n_vars, n_inputs, n_outputs;
-
- t_variable *vars;
- t_id *inputs, *outputs;
+ int n_vars, n_inputs, n_outputs;
+
+ t_variable *vars;
+ t_id *inputs, *outputs;
- int n_regs, n_rams;
- t_reg *regs;
- t_ram *rams;
+ int n_regs, n_rams;
+ t_reg *regs;
+ t_ram *rams;
- int n_eqs;
- t_equation *eqs;
+ int n_eqs;
+ t_equation *eqs;
} t_program;
// machine = execution instance
typedef struct {
- t_program *prog;
- t_value *var_values; // indexed by variable ID
+ t_program *prog;
+ t_value *var_values; // indexed by variable ID
- t_value *reg_data; // indexed by number in register list
- t_value **ram_data; // indexed by number in ram list
+ t_value *reg_data; // indexed by number in register list
+ t_value **ram_data; // indexed by number in ram list
} t_machine;
diff --git a/csim/util.c b/csim/util.c
index c815e8e..ac8bdc3 100644
--- a/csim/util.c
+++ b/csim/util.c
@@ -1,45 +1,45 @@
/*
- Système Digital
- 2013-2014
- Alex AUVOLAT
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
- util.c Various utility functions used elsewhere
+ util.c Various utility functions used elsewhere
*/
#include "sim.h"
int pow2(int exp) {
- return (1 << exp);
+ return (1 << exp);
}
t_value read_bool(FILE *stream, t_value *mask) {
- t_value r = 0;
- t_value pow = 1;
+ t_value r = 0;
+ t_value pow = 1;
- char c;
- if (mask != NULL) *mask = 0;
+ 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;
+ for(;;) {
+ fscanf(stream, "%c", &c);
+ if (c == '1') {
+ r |= pow;
+ } else if (c != '0') {
+ break;
+ }
+ if (mask != NULL) (*mask) |= pow;
- pow *= 2;
- }
+ pow *= 2;
+ }
- return r;
+ return r;
}
int is_prefix(const char *prefix, const char *str) {
- while (*prefix) {
- if (*prefix != *str) return 0;
- prefix++;
- str++;
- }
- return 1;
+ while (*prefix) {
+ if (*prefix != *str) return 0;
+ prefix++;
+ str++;
+ }
+ return 1;
}