From dd3c90011ab33717e4c4175cd6804ae86582135f Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Tue, 11 Apr 2023 14:38:51 +0300 Subject: Refactor folder --- 16bit-cpu.md | 73 ++++-------------------- asm/fibo.atk16 | 66 ++++++++++++++++++++++ asm/sum.atk16 | 32 +++++++++++ src/asm_eval.py | 47 ++++++++++++++++ src/asm_ops.py | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/asm_pass1.py | 4 +- src/asm_pass2.py | 4 +- src/asm_pass3.py | 4 +- src/asm_pass4.py | 4 +- src/assembler.py | 4 +- src/assembler_eval.py | 47 ---------------- src/assembler_ops.py | 150 -------------------------------------------------- src/ext_std.py | 2 +- src/test.atk16 | 33 ----------- src/test_alu.py | 48 ---------------- src/test_fibo.atk16 | 66 ---------------------- src/test_sum.atk16 | 3 - src/test_utils.py | 93 ------------------------------- 18 files changed, 318 insertions(+), 512 deletions(-) create mode 100644 asm/fibo.atk16 create mode 100644 asm/sum.atk16 create mode 100644 src/asm_eval.py create mode 100644 src/asm_ops.py delete mode 100644 src/assembler_eval.py delete mode 100644 src/assembler_ops.py delete mode 100644 src/test.atk16 delete mode 100755 src/test_alu.py delete mode 100644 src/test_fibo.atk16 delete mode 100644 src/test_sum.atk16 delete mode 100644 src/test_utils.py diff --git a/16bit-cpu.md b/16bit-cpu.md index 73b588e..d862114 100644 --- a/16bit-cpu.md +++ b/16bit-cpu.md @@ -4,79 +4,30 @@ 16-bit data 16-bit address width 16-bit instruction width - -MISC +16-bit control word +Minimal instruction set computer (MISC) 4-bit opcodes +Memory mapped I/O instruction format xxxx xxxx xxxx xxxx - xxxx xxxx xxxx xxxx General purpose registers: - 000: Zero register - 001: RA - 010: RB - 011: RC - 100: RD - -Special registers: MAR (memory address), IR (instruction), FR (flag) - -Serial peripheral ports: - - 101: PA - 110: PB - -for communicating with the outside world. + RA (0) .. RH (7) Expansion port that connects directly to the main bus -Addressing mode: indirect absolute (addresses are stored in registers and point to a complete address) +Default addressing mode: indirect absolute (addresses are stored in registers and point to a complete address). Some instructions use PC-relative addressing. ## Operations -### Memory operations -Format: [ 4 opcode . 3 rt . 3 rx . 6 unused ] - - ldr [rx] [rt] # load value from memory at address (register value) rx to rt - str [rx] [rt] # store value in rt to memory address (register value) rx - -### Immediate operations -Format: [ 4 opcode . 3 reg . 9 imm ] - - ldi [rt] [imm] # load immediate value imm to rt - -### Nullary operations -Format: [ 4 opcode . 12 unused ] - - hlt # halt - -### Arithmetic and logic operations -Format [ 4 opcode . 3 rt . 3 rl . 3 rr . 3 alu S ] - - alu [rl] [rr] [rt] [S] # compute rl ? rr where ? is the operation defined by - # 0SSS in the ALU, and store result in rt - # see datasheet of 74382 and ALU impl - als [rl] [rr] [rt] [S] # compute rl ? rr where ? is the operation defined by - # 1SSS in the ALU, and store result in rt - # see datasheet of 74382 and ALU impl - -Note: mul, div, gt, lt, eq, neq are implemented as pseudoinstructions in the assembler - -### Jump -Format: [ 4 opcode . 3 rx . 9 unused ] - - jmp [rx] # Jump to address in register rx - -### Branch -Format: [ 4 opcode . 1 unused . 2 flag . 9 addr ] -Branch if flag is set (where flag 0b00 = Z, 0b01 = C, ...) - - br [flag] [addr] +TODO rewrite bit about operations -Flags: -- C = ALU carry bit -- O = ALU overflow bit -- Z = ALU zero bit -- S = ALU sign bit +ALU flags: +- C = carry bit +- O = overflow bit +- Z = zero bit +- S = sign bit -Interrupt lines: 1 (IRQ) +Interrupt lines: ??? diff --git a/asm/fibo.atk16 b/asm/fibo.atk16 new file mode 100644 index 0000000..8bb7a6e --- /dev/null +++ b/asm/fibo.atk16 @@ -0,0 +1,66 @@ +@opt stack_pointer RF +@opt csr_scratch RH +@use ext_std:* + +; jump over data segment + jpi program + +; data segment +@label ram_offset + 0x8000 + +@label program +; set up stack pointer to point to beginning of RAM + ldi ram_offset RA + ldr RA RF + +; call fibo subroutine with parameter 10 + ldi 10 RA + csi fibo + hlt + +@label fibo +; function fibo +; parameters: +; RA n : u16 +; return value: +; RA fibo(n) : u16 + +; store RB, RC on stack + spu RB + spu RC +; if n < 2, return n + subi RA 2 RA + bri sign fibo_early +; store also RD on stack + spu RD +; a = 0 + ldi 0 RB +; b = 1 + ldi 1 RC +@label fibo_loop +; v = a + b + add RB RC RD +; a = b + mov RC RB +; b = v + mov RD RC +; n -= 1 + dec RA +; loop while n > 0 + bri zero fibo_done + jpi fibo_loop +@label fibo_early +; restore used registers + spo RC + spo RB +; return from subroutine + rsr +@label fibo_done + mov RD RA +; restore used registers + spo RD + spo RC + spo RB +; return from subroutine + rsr diff --git a/asm/sum.atk16 b/asm/sum.atk16 new file mode 100644 index 0000000..1bc3277 --- /dev/null +++ b/asm/sum.atk16 @@ -0,0 +1,32 @@ +@use ext_std:* +; Program: sum two values and store the result in RAM + +; ROM (and program execution) starts at offset 0x0 +@address 0x0 + jpi program + +@label ram_offset + 0x8000 ; store ram offset for later memory access + +@label program + ldi 10 RA ; RA := 10 + ldi 20 RB ; RB := 20 + add RA RB RC ; RC := RA + RB + ldi ram_offset RD ; store address of ram_offset in RD + ldr RD RD ; dereference ram_offset address +@label debug + str RC RD ; store RC in RAM + +; Check that 10 + 20 = 30 + mov RC RA ; RA := result of sum + ldi 30 RB ; RB := 30 + sub RA RB RC ; RC := RA - RB + bri zero success ; if result is zero, jump to success + + ldi 2 RA ; RA := 2 to signal failure + hlt + +; Else +@label success + ldi 1 RA ; RA := 1 to signal success + hlt diff --git a/src/asm_eval.py b/src/asm_eval.py new file mode 100644 index 0000000..691e4eb --- /dev/null +++ b/src/asm_eval.py @@ -0,0 +1,47 @@ +constants: dict[str, str] = { + # Registers + "ra": "0", + "rb": "1", + "rc": "2", + "rd": "3", + "re": "4", + "rf": "5", + "rg": "6", + "rh": "7", + # ALU instructions + "al_plus": "0", + "al_minus": "1", + "al_and": "2", + "al_or": "3", + "al_xor": "4", + "al_slr": "5", + "al_sar": "6", + "al_sll": "7", + # ALU flags + "carry": "0", + "overflow": "1", + "zero": "2", + "sign": "3", +} + +Labels = dict[str, int] + +def check_size(bits: int, val: int) -> None: + if val >= 2 ** bits: + raise Exception(f"Value does not fit in {bits} bits: {val}") + +def eval_symbol(labels: Labels, c: str) -> str: + if c in labels: + return str(labels[c]) + + if c in constants: + return constants[c] + + return c + +def eval_expr(labels: Labels, expr: str, bits: int = 16) -> int: + expr = expr.lower() + expr = eval_symbol(labels, expr) + ret = eval(expr, labels.copy()) # eval as Python expr + check_size(bits, ret) + return ret diff --git a/src/asm_ops.py b/src/asm_ops.py new file mode 100644 index 0000000..74e7930 --- /dev/null +++ b/src/asm_ops.py @@ -0,0 +1,150 @@ +from typing import Callable +from asm_eval import * +from dataclasses import dataclass + +@dataclass +class Options: + stack_pointer = "rf" + csr_scratch = "rh" + +@dataclass +class Meta: + address: int + +def make_alr(meta: Meta, labels: Labels, alu_op: str, left: str, right: str, target: str) -> int: + """ALR 0000 TTTL LLRR RSSS""" + target_e = eval_expr(labels, target, bits=3) + left_e = eval_expr(labels, left, bits=3) + right_e = eval_expr(labels, right, bits=3) + alu_op_e = eval_expr(labels, alu_op, bits=3) + word = (0b0000 << 12) + \ + (target_e << 9) + \ + (left_e << 6) + \ + (right_e << 3) + \ + alu_op_e + return word + +def make_ali(meta: Meta, labels: Labels, alu_op: str, left: str, imm: str, target: str) -> int: + """ALI 0001 TTTL LLII ISSS""" + target_e = eval_expr(labels, target, bits=3) + left_e = eval_expr(labels, left, bits=3) + imm_e = eval_expr(labels, imm, bits=3) + alu_op_e = eval_expr(labels, alu_op, bits=3) + word = (0b0001 << 12) + \ + (target_e << 9) + \ + (left_e << 6) + \ + (imm_e << 3) + \ + alu_op_e + return word + +def make_ldr(meta: Meta, labels: Labels, addr_reg: str, to_reg: str) -> int: + """LDR 0010 TTTR RRXX XXXX""" + to_reg_e = eval_expr(labels, to_reg, bits=3) + addr_reg_e = eval_expr(labels, addr_reg, bits=3) + word = (0b0010 << 12) + \ + (to_reg_e << 9) + \ + (addr_reg_e << 6) + return word + +def make_str(meta: Meta, labels: Labels, from_reg: str, addr_reg: str) -> int: + """STR 0011 XXXL LLRR RXXX""" + from_reg_e = eval_expr(labels, from_reg, bits=3) + addr_reg_e = eval_expr(labels, addr_reg, bits=3) + word = (0b0011 << 12) + \ + (addr_reg_e << 6) + \ + (from_reg_e << 3) + return word + +def make_ldi(meta: Meta, labels: Labels, imm: str, to_reg: str) -> int: + """LDI 0100 TTTI IIII IIII""" + to_reg_e = eval_expr(labels, to_reg, bits=3) + imm_e = eval_expr(labels, imm, bits=9) + word = (0b0100 << 12) + \ + (to_reg_e << 9) + \ + imm_e + return word + +def make_jpr(meta: Meta, labels: Labels, addr_reg: str) -> int: + """JPR 0101 XXXR RRXX XXXX""" + addr_reg_e = eval_expr(labels, addr_reg, bits=3) + word = (0b0101 << 12) + \ + (addr_reg_e << 6) + return word + +def make_jpi(meta: Meta, labels: Labels, imm: str) -> int: + """JPI 0110 XXXI IIII IIII""" + imm_e = eval_expr(labels, imm, bits=9) + imm_e = imm_e - meta.address - 1 + imm_e = imm_e & (0b111111111) + word = (0b0110 << 12) + \ + imm_e + return word + +def make_brr(meta: Meta, labels: Labels, flag_s: str, addr_reg: str) -> int: + """brr 0111 XFFR RRXX XXXX""" + flag_s_e = eval_expr(labels, flag_s, bits=2) + addr_reg_e = eval_expr(labels, addr_reg, bits=3) + word = (0b0111 << 12) + \ + (flag_s_e << 9) + \ + (addr_reg_e << 6) + return word + +def make_bri(meta: Meta, labels: Labels, flag_s: str, imm: str) -> int: + """BRI 1000 XFFI IIII IIII""" + flag_s_e = eval_expr(labels, flag_s, bits=2) + imm_e = eval_expr(labels, imm, bits=9) + imm_e = imm_e - meta.address - 1 + imm_e = imm_e & (0b111111111) + word = (0b1000 << 12) + \ + (flag_s_e << 9) + \ + imm_e + return word + +def make_lpc(meta: Meta, labels: Labels, target: str) -> int: + """LPC 1001 TTTX XXXX XXXX""" + target_e = eval_expr(labels, target, bits=3) + word = (0b1001 << 12) + \ + (target_e << 9) + return word + +def make_hlt(meta: Meta, labels: Labels) -> int: + """HLT 1111 XXXX XXXX XXXX""" + word = (0b1111 << 12) + return word + +OpWordDict = dict[str, Callable[..., int]] +operations: OpWordDict = { + "alr": make_alr, + "ali": make_ali, + "ldr": make_ldr, + "str": make_str, + "ldi": make_ldi, + "jpr": make_jpr, + "jpi": make_jpi, + "brr": make_brr, + "bri": make_bri, + "lpc": make_lpc, + "hlt": make_hlt, +} + +ExpandResult = list[list[str]] +ExpandFn = Callable[..., ExpandResult] +OpExpansionDict = dict[str, ExpandFn] + +def expand_id(*parts: str) -> ExpandResult: + return [list(parts)] + +default_expansions: OpExpansionDict = { + "alr": lambda *args: expand_id("alr", *args), + "ali": lambda *args: expand_id("ali", *args), + "ldr": lambda *args: expand_id("ldr", *args), + "str": lambda *args: expand_id("str", *args), + "ldi": lambda *args: expand_id("ldi", *args), + "jpr": lambda *args: expand_id("jpr", *args), + "jpi": lambda *args: expand_id("jpi", *args), + "brr": lambda *args: expand_id("brr", *args), + "bri": lambda *args: expand_id("bri", *args), + "lpc": lambda *args: expand_id("lpc", *args), + "hlt": lambda *args: expand_id("hlt", *args), +} + diff --git a/src/asm_pass1.py b/src/asm_pass1.py index 6537aea..606a1a1 100644 --- a/src/asm_pass1.py +++ b/src/asm_pass1.py @@ -1,7 +1,7 @@ import importlib from dataclasses import dataclass -from assembler_ops import * -from assembler_eval import * +from asm_ops import * +from asm_eval import * @dataclass class Result1Line: diff --git a/src/asm_pass2.py b/src/asm_pass2.py index 261ba06..e7f48ac 100644 --- a/src/asm_pass2.py +++ b/src/asm_pass2.py @@ -1,6 +1,6 @@ from dataclasses import dataclass -from assembler_ops import * -from assembler_eval import * +from asm_ops import * +from asm_eval import * from asm_pass1 import * @dataclass diff --git a/src/asm_pass3.py b/src/asm_pass3.py index e8e44d3..038e3f7 100644 --- a/src/asm_pass3.py +++ b/src/asm_pass3.py @@ -1,6 +1,6 @@ from dataclasses import dataclass -from assembler_ops import * -from assembler_eval import * +from asm_ops import * +from asm_eval import * from asm_pass2 import * @dataclass diff --git a/src/asm_pass4.py b/src/asm_pass4.py index 926b354..3d4f45c 100644 --- a/src/asm_pass4.py +++ b/src/asm_pass4.py @@ -1,6 +1,6 @@ from dataclasses import dataclass -from assembler_ops import * -from assembler_eval import * +from asm_ops import * +from asm_eval import * from asm_pass3 import * @dataclass diff --git a/src/assembler.py b/src/assembler.py index 4e82deb..3f0c8bc 100755 --- a/src/assembler.py +++ b/src/assembler.py @@ -2,8 +2,8 @@ # Assemble ATK16 assembly to bytecode import sys -from assembler_ops import * -from assembler_eval import * +from asm_ops import * +from asm_eval import * from asm_pass1 import pass_1 from asm_pass2 import pass_2 from asm_pass3 import pass_3 diff --git a/src/assembler_eval.py b/src/assembler_eval.py deleted file mode 100644 index 691e4eb..0000000 --- a/src/assembler_eval.py +++ /dev/null @@ -1,47 +0,0 @@ -constants: dict[str, str] = { - # Registers - "ra": "0", - "rb": "1", - "rc": "2", - "rd": "3", - "re": "4", - "rf": "5", - "rg": "6", - "rh": "7", - # ALU instructions - "al_plus": "0", - "al_minus": "1", - "al_and": "2", - "al_or": "3", - "al_xor": "4", - "al_slr": "5", - "al_sar": "6", - "al_sll": "7", - # ALU flags - "carry": "0", - "overflow": "1", - "zero": "2", - "sign": "3", -} - -Labels = dict[str, int] - -def check_size(bits: int, val: int) -> None: - if val >= 2 ** bits: - raise Exception(f"Value does not fit in {bits} bits: {val}") - -def eval_symbol(labels: Labels, c: str) -> str: - if c in labels: - return str(labels[c]) - - if c in constants: - return constants[c] - - return c - -def eval_expr(labels: Labels, expr: str, bits: int = 16) -> int: - expr = expr.lower() - expr = eval_symbol(labels, expr) - ret = eval(expr, labels.copy()) # eval as Python expr - check_size(bits, ret) - return ret diff --git a/src/assembler_ops.py b/src/assembler_ops.py deleted file mode 100644 index b55927b..0000000 --- a/src/assembler_ops.py +++ /dev/null @@ -1,150 +0,0 @@ -from typing import Callable -from assembler_eval import * -from dataclasses import dataclass - -@dataclass -class Options: - stack_pointer = "rf" - csr_scratch = "rh" - -@dataclass -class Meta: - address: int - -def make_alr(meta: Meta, labels: Labels, alu_op: str, left: str, right: str, target: str) -> int: - """ALR 0000 TTTL LLRR RSSS""" - target_e = eval_expr(labels, target, bits=3) - left_e = eval_expr(labels, left, bits=3) - right_e = eval_expr(labels, right, bits=3) - alu_op_e = eval_expr(labels, alu_op, bits=3) - word = (0b0000 << 12) + \ - (target_e << 9) + \ - (left_e << 6) + \ - (right_e << 3) + \ - alu_op_e - return word - -def make_ali(meta: Meta, labels: Labels, alu_op: str, left: str, imm: str, target: str) -> int: - """ALI 0001 TTTL LLII ISSS""" - target_e = eval_expr(labels, target, bits=3) - left_e = eval_expr(labels, left, bits=3) - imm_e = eval_expr(labels, imm, bits=3) - alu_op_e = eval_expr(labels, alu_op, bits=3) - word = (0b0001 << 12) + \ - (target_e << 9) + \ - (left_e << 6) + \ - (imm_e << 3) + \ - alu_op_e - return word - -def make_ldr(meta: Meta, labels: Labels, addr_reg: str, to_reg: str) -> int: - """LDR 0010 TTTR RRXX XXXX""" - to_reg_e = eval_expr(labels, to_reg, bits=3) - addr_reg_e = eval_expr(labels, addr_reg, bits=3) - word = (0b0010 << 12) + \ - (to_reg_e << 9) + \ - (addr_reg_e << 6) - return word - -def make_str(meta: Meta, labels: Labels, from_reg: str, addr_reg: str) -> int: - """STR 0011 XXXL LLRR RXXX""" - from_reg_e = eval_expr(labels, from_reg, bits=3) - addr_reg_e = eval_expr(labels, addr_reg, bits=3) - word = (0b0011 << 12) + \ - (addr_reg_e << 6) + \ - (from_reg_e << 3) - return word - -def make_ldi(meta: Meta, labels: Labels, imm: str, to_reg: str) -> int: - """LDI 0100 TTTI IIII IIII""" - to_reg_e = eval_expr(labels, to_reg, bits=3) - imm_e = eval_expr(labels, imm, bits=9) - word = (0b0100 << 12) + \ - (to_reg_e << 9) + \ - imm_e - return word - -def make_jpr(meta: Meta, labels: Labels, addr_reg: str) -> int: - """JPR 0101 XXXR RRXX XXXX""" - addr_reg_e = eval_expr(labels, addr_reg, bits=3) - word = (0b0101 << 12) + \ - (addr_reg_e << 6) - return word - -def make_jpi(meta: Meta, labels: Labels, imm: str) -> int: - """JPI 0110 XXXI IIII IIII""" - imm_e = eval_expr(labels, imm, bits=9) - imm_e = imm_e - meta.address - 1 - imm_e = imm_e & (0b111111111) - word = (0b0110 << 12) + \ - imm_e - return word - -def make_brr(meta: Meta, labels: Labels, flag_s: str, addr_reg: str) -> int: - """brr 0111 XFFR RRXX XXXX""" - flag_s_e = eval_expr(labels, flag_s, bits=2) - addr_reg_e = eval_expr(labels, addr_reg, bits=3) - word = (0b0111 << 12) + \ - (flag_s_e << 9) + \ - (addr_reg_e << 6) - return word - -def make_bri(meta: Meta, labels: Labels, flag_s: str, imm: str) -> int: - """BRI 1000 XFFI IIII IIII""" - flag_s_e = eval_expr(labels, flag_s, bits=2) - imm_e = eval_expr(labels, imm, bits=9) - imm_e = imm_e - meta.address - 1 - imm_e = imm_e & (0b111111111) - word = (0b1000 << 12) + \ - (flag_s_e << 9) + \ - imm_e - return word - -def make_lpc(meta: Meta, labels: Labels, target: str) -> int: - """LPC 1001 TTTX XXXX XXXX""" - target_e = eval_expr(labels, target, bits=3) - word = (0b1001 << 12) + \ - (target_e << 9) - return word - -def make_hlt(meta: Meta, labels: Labels) -> int: - """HLT 1111 XXXX XXXX XXXX""" - word = (0b1111 << 12) - return word - -OpWordDict = dict[str, Callable[..., int]] -operations: OpWordDict = { - "alr": make_alr, - "ali": make_ali, - "ldr": make_ldr, - "str": make_str, - "ldi": make_ldi, - "jpr": make_jpr, - "jpi": make_jpi, - "brr": make_brr, - "bri": make_bri, - "lpc": make_lpc, - "hlt": make_hlt, -} - -ExpandResult = list[list[str]] -ExpandFn = Callable[..., ExpandResult] -OpExpansionDict = dict[str, ExpandFn] - -def expand_id(*parts: str) -> ExpandResult: - return [list(parts)] - -default_expansions: OpExpansionDict = { - "alr": lambda *args: expand_id("alr", *args), - "ali": lambda *args: expand_id("ali", *args), - "ldr": lambda *args: expand_id("ldr", *args), - "str": lambda *args: expand_id("str", *args), - "ldi": lambda *args: expand_id("ldi", *args), - "jpr": lambda *args: expand_id("jpr", *args), - "jpi": lambda *args: expand_id("jpi", *args), - "brr": lambda *args: expand_id("brr", *args), - "bri": lambda *args: expand_id("bri", *args), - "lpc": lambda *args: expand_id("lpc", *args), - "hlt": lambda *args: expand_id("hlt", *args), -} - diff --git a/src/ext_std.py b/src/ext_std.py index 5f41f60..11da8aa 100644 --- a/src/ext_std.py +++ b/src/ext_std.py @@ -1,4 +1,4 @@ -from assembler_ops import * +from asm_ops import * def expand_add(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_plus", left, right, target]] diff --git a/src/test.atk16 b/src/test.atk16 deleted file mode 100644 index 3f2d378..0000000 --- a/src/test.atk16 +++ /dev/null @@ -1,33 +0,0 @@ -; Program: sum two values and store the result in RAM - -@use ext_std:* - -; ROM (and program execution) starts at offset 0x0 -@address 0x0 - jpi program - -@label ram_offset - 0x8000 ; store ram offset for later memory access - -@label program - ldi RA 10 ; RA := 10 - ldi RB 20 ; RB := 20 - add RA RB RC ; RC := RA + RB - ldi RD @ram_offset ; store address of ram_offset in RD - ldr RD RD ; dereference ram_offset address -@label debug - str RD RC ; store RC in RAM - -; Check that 10 + 20 = 30 - mov RC RA ; RA := result of sum - ldi RB 30 ; RB := 30 - sub RA RB RC ; RC := RA - RB - bri zero @success ; if result is zero, jump to success - - ldi RA 2 ; RA := 2 to signal failure - hlt - -; Else -@label success - ldi RA 1 ; RA := 1 to signal success - hlt diff --git a/src/test_alu.py b/src/test_alu.py deleted file mode 100755 index af30443..0000000 --- a/src/test_alu.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -from test_utils import * - -def make_alu_table() -> str: - alu = ALU() - n = 10000 - alu.generate_cases(n) - alu.process() - print(f"[test] running {n} ALU test cases") - return alu.to_table().strip() - -class ALU(TestGroup): - def __init__(self): - TestGroup.__init__(self, [ - Param("A", 0x0, 0xffff), - Param("B", 0x0, 0xffff), - Param("S", 0, 7), - ], [ - "Y", - "FLAGS", - ]) - - def process(self): - new_cases = [] - for kase in self.cases: - S = kase["S"] - A = kase["A"] - B = kase["B"] - kase["FLAGS"] = "x" - - match S: - case 0: Y = 0 - case 1: Y = (B - A) & 0xFFFF - case 2: Y = (A - B) & 0xFFFF - case 3: Y = (A + B) & 0xFFFF - case 4: Y = (A ^ B) & 0xFFFF - case 5: Y = (A | B) & 0xFFFF - case 6: Y = (A & B) & 0xFFFF - case 7: Y = 0xffff - - kase["Y"] = Y - new_cases.append(kase) - - self.cases = new_cases - -table = make_alu_table() -run_test("ALU", table) diff --git a/src/test_fibo.atk16 b/src/test_fibo.atk16 deleted file mode 100644 index 8bb7a6e..0000000 --- a/src/test_fibo.atk16 +++ /dev/null @@ -1,66 +0,0 @@ -@opt stack_pointer RF -@opt csr_scratch RH -@use ext_std:* - -; jump over data segment - jpi program - -; data segment -@label ram_offset - 0x8000 - -@label program -; set up stack pointer to point to beginning of RAM - ldi ram_offset RA - ldr RA RF - -; call fibo subroutine with parameter 10 - ldi 10 RA - csi fibo - hlt - -@label fibo -; function fibo -; parameters: -; RA n : u16 -; return value: -; RA fibo(n) : u16 - -; store RB, RC on stack - spu RB - spu RC -; if n < 2, return n - subi RA 2 RA - bri sign fibo_early -; store also RD on stack - spu RD -; a = 0 - ldi 0 RB -; b = 1 - ldi 1 RC -@label fibo_loop -; v = a + b - add RB RC RD -; a = b - mov RC RB -; b = v - mov RD RC -; n -= 1 - dec RA -; loop while n > 0 - bri zero fibo_done - jpi fibo_loop -@label fibo_early -; restore used registers - spo RC - spo RB -; return from subroutine - rsr -@label fibo_done - mov RD RA -; restore used registers - spo RD - spo RC - spo RB -; return from subroutine - rsr diff --git a/src/test_sum.atk16 b/src/test_sum.atk16 deleted file mode 100644 index 3f69a55..0000000 --- a/src/test_sum.atk16 +++ /dev/null @@ -1,3 +0,0 @@ - ldi RA 10 ; RA := 10 - ldi RB 20 ; RB := 20 - add RA RB RC ; RC := RA + RB diff --git a/src/test_utils.py b/src/test_utils.py deleted file mode 100644 index 1db23b2..0000000 --- a/src/test_utils.py +++ /dev/null @@ -1,93 +0,0 @@ -import random -from dataclasses import dataclass -import tempfile -import sys -import os - -def make_test_file(name: str, table: str) -> str: - return f""" - - 2 - - - - Testcase - - - Label - {name} - - - Testdata - - {table} - - - - - - - - - - """ - -@dataclass -class Param: - name: str - min: int - max: int - -class TestGroup: - def __init__(self, inputs: list[Param], outputs: list[str]): - self.inputs = inputs - self.outputs = outputs - self.cases = [] - - def generate_cases(self, n = 1000): - for _ in range(n): - result = {} - for param in self.inputs: - val = random.randrange(param.min, param.max + 1) - result[param.name] = val - - self.cases.append(result) - - def process(self): - raise NotImplemented() - - def to_table(self) -> str: - names: list[str] = [] - for param in self.inputs: - names.append(param.name) - for output in self.outputs: - names.append(output) - - ret = " ".join(names) - ret += "\n" - - for case in self.cases: - row_vals = [] - for param_name in names: - row_vals.append(str(case[param_name])) - - ret += " ".join(row_vals) - ret += "\n" - - return ret - -def run_test(name: str, table: str): - if len(sys.argv) != 2: - print(f"usage: {sys.argv[0]} ") - sys.exit(1) - - circuit_path = sys.argv[1] - _, test_path = tempfile.mkstemp(".dig") - - fc = make_test_file(name, table) - with open(test_path, "w") as f: - f.write(fc) - - stream = os.popen(f"make run-single-test circ={circuit_path} tests={test_path}") - output = stream.read() - print(output) -- cgit v1.3