#pragma once #include #include #include #include #define TPU_MAP_BUCKETS 64 #define LABEL_MAP_BUCKETS 64 #define TPU_MAX_INST_CNT 15 #define TPU_MAX_ROWS 15 #define TPU_MAX_COLS 18 #define TIS_MAX_IO_PORTS 36 /* what tpu will attempt next (order important) */ enum tpu_mode { MODE_IDLE, MODE_RUN, MODE_READ, MODE_WRITE }; enum tpu_inst_type { INST_NOP, INST_MOV, INST_SWP, INST_SAV, INST_ADD, INST_SUB, INST_NEG, INST_JMP, INST_JEZ, INST_JNZ, INST_JGZ, INST_JLZ, INST_JRO }; enum tpu_inst_op_type { OP_ACC, OP_NIL, OP_LEFT, OP_RIGHT, OP_UP, OP_DOWN, OP_ANY, OP_LAST, OP_LIT, OP_LABEL }; enum tpu_port_dir { DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN }; enum tpu_port_type { PORT_IN = 0b01, PORT_OUT = 0b10, PORT_BIDI = 0b11 }; union tpu_inst_op_val { int lit; char *label; }; struct label_map_link { int pc; bool prefix; struct label_map_link *next; }; struct label { char *str; bool prefix; }; struct label_map { struct label labels[TPU_MAX_INST_CNT]; struct label_map_link *buckets[LABEL_MAP_BUCKETS]; }; struct tpu_inst_op { enum tpu_inst_op_type type; union tpu_inst_op_val val; }; struct tpu_inst { enum tpu_inst_type type; struct tpu_inst_op ops[2]; unsigned opcnt; }; struct tpu_port { struct tpu *tpu; enum tpu_port_type type; /* set only if managed by io port */ struct tpu_io_port *io; /* NOTE: dont access dst_port during execution, * values are transfered in post execution phase */ struct tpu_port *dst_port; bool attached; int in, out; bool avail, writing; bool reset_in; }; struct tpu { enum tpu_mode mode; bool idle; bool disabled; int x, y; struct tpu_port ports[4]; int io_port; int last; size_t steps; size_t idle_steps; int acc, bak; int pc; struct label_map label_map; struct tpu_inst insts[TPU_MAX_INST_CNT]; size_t inst_cnt, rows; }; struct tpu_map_link { int x, y; struct tpu *tpu; struct tpu_map_link *next; }; struct tpu_map { struct tpu_map_link *buckets[TPU_MAP_BUCKETS]; }; struct tpu_io_port { struct tpu_port port; enum tpu_port_dir dir; enum tpu_port_type type; size_t io_step; FILE *file; int x, y; char c; }; struct tis { struct tpu_map tpu_map; struct tpu_io_port *in_ports[TIS_MAX_IO_PORTS]; struct tpu_io_port *out_ports[TIS_MAX_IO_PORTS]; size_t steps; bool show_stats; char *asm_filepath; }; struct tis_stats { size_t steps; size_t nodes; size_t insts; float idle; }; void label_map_init(struct label_map *map); void label_map_deinit(struct label_map *map); bool label_map_add(struct label_map *map, const char *name, int pc, bool prefix); int label_map_get(struct label_map *map, const char *name); void tpu_port_init(struct tpu_port *port, struct tpu *tpu); void tpu_port_deinit(struct tpu_port *port); void tpu_io_port_init(struct tpu_io_port *io_port, char c, enum tpu_port_dir dir, enum tpu_port_type type, int x, int y); void tpu_io_port_deinit(struct tpu_io_port *io_port); void tpu_io_port_attach(struct tpu_io_port *io_port, FILE *file); void tpu_init(struct tpu *tpu); void tpu_deinit(struct tpu *tpu); struct tpu_inst *tpu_current_inst(struct tpu *tpu); void tpu_init_ports(struct tpu *tpu, struct tpu_map *map); void tpu_update_ports(struct tpu *tpu); bool tpu_set_inst(struct tpu *tpu, int pc, enum tpu_inst_type inst, unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2); struct tpu_inst *tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst, unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2); void tpu_clear_ports(struct tpu *tpu); enum tpu_mode tpu_exec(struct tpu *tpu, struct tpu_inst *inst); void tpu_step(struct tpu *tpu); void tpu_map_init(struct tpu_map *map); void tpu_map_deinit(struct tpu_map *map); bool tpu_map_add(struct tpu_map *map, struct tpu *tpu); struct tpu *tpu_map_get(struct tpu_map *map, int x, int y); void tis_init(struct tis *tis); void tis_deinit(struct tis *tis); bool tis_step(struct tis *tis); void tis_communicate(struct tis *tis); struct tis_stats tis_gen_stats(struct tis *tis); extern const char *dir_reprs[]; extern const char *mode_reprs[]; extern const char *inst_reprs[]; extern const char *op_reprs[];