diff options
Diffstat (limited to 'sim/gentestvec')
-rw-r--r-- | sim/gentestvec/Makefile | 33 | ||||
-rw-r--r-- | sim/gentestvec/src/alu.c | 117 | ||||
-rw-r--r-- | sim/gentestvec/src/cpu.c | 6 | ||||
-rw-r--r-- | sim/gentestvec/src/register_file.c | 49 |
4 files changed, 205 insertions, 0 deletions
diff --git a/sim/gentestvec/Makefile b/sim/gentestvec/Makefile new file mode 100644 index 0000000..a546b0d --- /dev/null +++ b/sim/gentestvec/Makefile @@ -0,0 +1,33 @@ +BUILD_DIR ?= build + +# tools +CC = clang + +# flags +CFLAGS = -O3 + +# dirs and files +SOURCE_DIR = src +SOURCES = $(wildcard $(SOURCE_DIR)/*.c) +GENTESTVECS = $(patsubst $(SOURCE_DIR)/%.c, $(BUILD_DIR)/gentestvec_%, $(SOURCES)) +TESTVECS = $(patsubst $(BUILD_DIR)/gentestvec_%, $(BUILD_DIR)/testvec_%.txt, $(GENTESTVECS)) + + +# targets +all: $(TESTVECS) + +# build testvec generator executables +$(BUILD_DIR)/gentestvec_%: $(SOURCE_DIR)/%.c | $(BUILD_DIR) + $(CC) $(CFLAGS) -o $@ $< + +# generate testvecs +$(BUILD_DIR)/testvec_%.txt: $(BUILD_DIR)/gentestvec_% + $< > $@ + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +clean: + rm -rf $(BUILD_DIR) + +.PHONY: all clean
\ No newline at end of file diff --git a/sim/gentestvec/src/alu.c b/sim/gentestvec/src/alu.c new file mode 100644 index 0000000..4a11a74 --- /dev/null +++ b/sim/gentestvec/src/alu.c @@ -0,0 +1,117 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +typedef enum { + ADD = 0b0000, + SUB = 0b0001, + SLT = 0b0010, + SLTU = 0b0011, + + AND = 0b0100, + OR = 0b0101, + XOR = 0b0110, + + SLL = 0b1000, + SRL = 0b1001, + SRA = 0b1011, +} OP; + +void test_op(OP op, uint32_t a, uint32_t b) { + uint32_t result; + bool zero; + + switch (op) { + case ADD: + result = a + b; + break; + case SUB: + result = a - b; + break; + case SLT: + result = (int32_t)a < (int32_t)b; + break; + case SLTU: + result = a < b; + break; + + case AND: + result = a & b; + break; + case OR: + result = a | b; + break; + case XOR: + result = a ^ b; + break; + + case SLL: + result = a << b % 32; + break; + case SRL: + result = a >> b % 32; + break; + case SRA: + result = ((int32_t)a) >> b % 32; + break; + } + + zero = result == 0; + + printf("%01X__%08X_%08X__%08X_%01X\n", op & 0x0f, a, b, result, zero); +} + +void test_op_random(OP op, int num) { + for (int i = 0; i < num; ++i) { + uint32_t a = (rand() << 16) | rand(); + uint32_t b = (rand() << 16) | rand(); + test_op(op, a, b); + } +} + +int main(int argc, const char *argv[]) { + srand(time(NULL)); + + test_op_random(ADD, 1000); + test_op(ADD, 0x00000000, 0x00000000); + test_op(ADD, 0xffffffff, 0xffffffff); + test_op(ADD, 0xffffffff, 0x00000001); + test_op_random(SUB, 1000); + test_op(SUB, 0xffffffff, 0xffffffff); + test_op_random(SLT, 1000); + test_op(SLT, 0x8fffffff, 0xffffffff); + test_op(SLT, 0xffffffff, 0x00000001); + test_op(SLT, 0x00000001, 0xffffffff); + test_op_random(SLTU, 1000); + + test_op_random(OR, 1000); + test_op(OR, 0x00000000, 0x00000000); + test_op(OR, 0xffffffff, 0x00000000); + test_op(OR, 0x00000000, 0xffffffff); + test_op(OR, 0xffffffff, 0xffffffff); + test_op_random(AND, 1000); + test_op(AND, 0x00000000, 0x00000000); + test_op(AND, 0xffffffff, 0x00000000); + test_op(AND, 0x00000000, 0xffffffff); + test_op(AND, 0xffffffff, 0xffffffff); + test_op_random(XOR, 1000); + test_op(XOR, 0x00000000, 0x00000000); + test_op(XOR, 0xffffffff, 0x00000000); + test_op(XOR, 0x00000000, 0xffffffff); + test_op(XOR, 0xffffffff, 0xffffffff); + + test_op_random(SLL, 1000); + test_op(SLL, 0x0000000f, 0x00000004); + test_op(SLL, 0xffffffff, 0x0000001c); + test_op(SLL, 0xf0000000, 0x00000002); + test_op(SLL, 0x01234567, 0x00000001); + test_op_random(SRL, 1000); + test_op(SRL, 0xf0000000, 0x0000001c); + test_op(SRL, 0x0000000f, 0x0000004); + test_op_random(SRA, 1000); + test_op(SRA, 0xf0000000, 0x0000001c); + test_op(SRA, 0x0000000f, 0x0000004); + + return 0; +} diff --git a/sim/gentestvec/src/cpu.c b/sim/gentestvec/src/cpu.c new file mode 100644 index 0000000..8500dd9 --- /dev/null +++ b/sim/gentestvec/src/cpu.c @@ -0,0 +1,6 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +int main(int argc, const char *argv[]) { return 0; } diff --git a/sim/gentestvec/src/register_file.c b/sim/gentestvec/src/register_file.c new file mode 100644 index 0000000..5a50d9b --- /dev/null +++ b/sim/gentestvec/src/register_file.c @@ -0,0 +1,49 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +uint32_t registers[32]; + +uint32_t read_reg(uint32_t addr) { return addr == 0 ? 0 : registers[addr]; } + +void write_reg(uint32_t addr, uint32_t data, bool we) { + if (addr != 0 && we) + registers[addr] = data; +} + +void test(uint32_t addr_rs0, uint32_t addr_rs1, uint32_t addr_rd2, + uint32_t data_rd2, bool we) { + + write_reg(addr_rd2, data_rd2, we); + uint32_t data_rs0 = read_reg(addr_rs0); + uint32_t data_rs1 = read_reg(addr_rs1); + printf("%08X_%08X__%08X_%08X__%08X_%08X_%01X\n", addr_rs0, data_rs0, addr_rs1, + data_rs1, addr_rd2, data_rd2, we); +} + +void tests(int num) { + for (int i = 0; i < num; ++i) { + uint32_t addr_rs0 = ((uint32_t)((rand() << 16) | rand())) % 32; + uint32_t addr_rs1 = ((uint32_t)((rand() << 16) | rand())) % 32; + uint32_t addr_rd2 = ((uint32_t)((rand() << 16) | rand())) % 32; + uint32_t data_rd2 = ((uint32_t)((rand() << 16) | rand())); + bool we = ((uint32_t)rand()) % 2; + test(addr_rs0, addr_rs1, addr_rd2, data_rd2, we); + } +} + +int main(int argc, const char *argv[]) { + srand(time(NULL)); + for (int i = 0; i < 32; ++i) + registers[0] = 0; + + for (int i = 0; i < 32; ++i) + test(i, i, 0, 0, false); + + for (int i = 0; i < 32; ++i) + test(i, i, i, 0xffffffff, true); + + tests(10000); + return 0; +} |