1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#ifndef DEF_SIM_H
#define DEF_SIM_H
#include <stdio.h>
// Gate types
#define C_COPY 0
#define C_NOT 1
#define C_BINOP 2
#define C_MUX 3
#define C_ROM 4
#define C_CONCAT 5
#define C_SLICE 6
#define C_SELECT 7
// Binary operators
#define OP_OR 0
#define OP_XOR 1
#define OP_AND 2
#define OP_NAND 3
// Data structures
// 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;
typedef struct { // a variable in the simulator
t_value mask;
int size;
char *name;
} t_variable;
typedef struct {
t_id dest, source;
} t_reg;
typedef struct {
t_id dest;
int addr_size, word_size;
t_id read_addr, 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;
};
} t_equation;
typedef struct {
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_eqs;
t_equation *eqs;
} t_program;
// machine = execution instance
typedef struct {
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_machine;
// 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
|