diff options
Diffstat (limited to 'csim')
-rw-r--r-- | csim/load.c | 304 | ||||
-rw-r--r-- | csim/main.c | 154 | ||||
-rw-r--r-- | csim/sim.c | 382 | ||||
-rw-r--r-- | csim/sim.h | 122 | ||||
-rw-r--r-- | csim/util.c | 52 |
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; } @@ -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"); } @@ -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; } |