From 797b5825d2179e3bab22643a6873dc29800e79eb Mon Sep 17 00:00:00 2001 From: Wojciech Kosior Date: Tue, 6 Oct 2020 13:49:30 +0200 Subject: add relational operations to stack machine --- design/stack_machine.v | 70 +++++++- tclasm.tcl | 45 +++++ tests/stack_machine_relop/Makefile | 1 + tests/stack_machine_relop/instructions.s.tcl | 235 ++++++++++++++++++++++++++ tests/stack_machine_relop/test.v | 1 + tests/stack_machine_relop/words_to_verify.mem | 40 +++++ tests/stack_machine_store/test.v | 6 +- 7 files changed, 394 insertions(+), 4 deletions(-) create mode 120000 tests/stack_machine_relop/Makefile create mode 100644 tests/stack_machine_relop/instructions.s.tcl create mode 120000 tests/stack_machine_relop/test.v create mode 100644 tests/stack_machine_relop/words_to_verify.mem diff --git a/design/stack_machine.v b/design/stack_machine.v index b5c56e6..687168a 100644 --- a/design/stack_machine.v +++ b/design/stack_machine.v @@ -54,8 +54,13 @@ module stack_machine_new reg [31:0] r0; reg [31:0] r1; - reg [31:0] im; + wire signed [31:0] r0s; + wire signed [31:0] r1s; + assign r0s = r0; + assign r1s = r1; + + reg [31:0] im; reg im_initialized; parameter STEP_LOADING_INSTRUCTION = 1'b0; @@ -243,6 +248,42 @@ module stack_machine_new assign instr_drop = !set_im && !use_im && stack_shrinks_by_1 && instruction[11:0] == 12'd4; + wire instr_eq; + assign instr_eq = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd7; + + wire instr_lt; + assign instr_lt = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd8; + + wire instr_ult; + assign instr_ult = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd9; + + wire instr_le; + assign instr_le = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd10; + + wire instr_ule; + assign instr_ule = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd11; + + wire instr_gt; + assign instr_gt = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd12; + + wire instr_ugt; + assign instr_ugt = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd13; + + wire instr_ge; + assign instr_ge = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd14; + + wire instr_uge; + assign instr_uge = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd15; + wire instr_ret; assign instr_ret = !set_im && !use_im && stack_shrinks_by_1 && instruction[11:0] == 12'b000010000000; @@ -583,6 +624,33 @@ module stack_machine_new `SET_PC(im_effective); end + if (instr_eq && arithmetic_uncompleted) + r1 <= r0 == r1; + + if (instr_lt && arithmetic_uncompleted) + r1 <= r0s < r1s; + + if (instr_ult && arithmetic_uncompleted) + r1 <= r0 < r1; + + if (instr_le && arithmetic_uncompleted) + r1 <= r0s <= r1s; + + if (instr_ule && arithmetic_uncompleted) + r1 <= r0 <= r1; + + if (instr_gt && arithmetic_uncompleted) + r1 <= r0s > r1s; + + if (instr_ugt && arithmetic_uncompleted) + r1 <= r0 > r1; + + if (instr_ge && arithmetic_uncompleted) + r1 <= r0s >= r1s; + + if (instr_uge && arithmetic_uncompleted) + r1 <= r0 >= r1; + if (instr_ret && arithmetic_uncompleted) begin r1 <= r0; `SET_PC(r1); diff --git a/tclasm.tcl b/tclasm.tcl index 6a97b1f..90adda5 100755 --- a/tclasm.tcl +++ b/tclasm.tcl @@ -332,6 +332,51 @@ proc drop {} { } +proc eq {} { + puts 0011000000000111 +} + + +proc lt {} { + puts 0011000000001000 +} + + +proc ult {} { + puts 0011000000001001 +} + + +proc le {} { + puts 0011000000001010 +} + + +proc ule {} { + puts 0011000000001011 +} + + +proc gt {} { + puts 0011000000001100 +} + + +proc ugt {} { + puts 0011000000001101 +} + + +proc ge {} { + puts 0011000000001110 +} + + +proc uge {} { + puts 0011000000001111 +} + + proc ret {} { puts 0011000010000000 } diff --git a/tests/stack_machine_relop/Makefile b/tests/stack_machine_relop/Makefile new file mode 120000 index 0000000..2c3c770 --- /dev/null +++ b/tests/stack_machine_relop/Makefile @@ -0,0 +1 @@ +../stack_machine_store/Makefile \ No newline at end of file diff --git a/tests/stack_machine_relop/instructions.s.tcl b/tests/stack_machine_relop/instructions.s.tcl new file mode 100644 index 0000000..5a83b53 --- /dev/null +++ b/tests/stack_machine_relop/instructions.s.tcl @@ -0,0 +1,235 @@ +### store 2 values to memory, load them back, add them and store the result + +set_sp 0 + +## compare 1234567890 to itself + +const 1234567890 +const 1234567890 +# yields 1 +eq +store h1EEE0 + +const 1234567890 +const 1234567890 +# yields 0 +lt +store h1EEE4 + +const 1234567890 +const 1234567890 +# yields 0 +ult +store h1EEE8 + +const 1234567890 +const 1234567890 +# yields 1 +le +store h1EEEC + +const 1234567890 +const 1234567890 +# yields 1 +ule +store h1EEF0 + +const 1234567890 +const 1234567890 +# yields 0 +gt +store h1EEF4 + +const 1234567890 +const 1234567890 +# yields 0 +ugt +store h1EEF8 + +const 1234567890 +const 1234567890 +# yields 1 +ge +store h1EEFC + +const 1234567890 +const 1234567890 +# yields 1 +uge +store h1EF00 + + +## compare hFFFFFFFF to h7FFFFFFF +## hFFFFFFFF will be treated as negative for signed operations + +const hFFFFFFFF +const h7FFFFFFF +# yields 0 +eq +store h1F0E0 + +const hFFFFFFFF +const h7FFFFFFF +# yields 1 +lt +store h1F0E4 + +const hFFFFFFFF +const h7FFFFFFF +# yields 0 +ult +store h1F0E8 + +const hFFFFFFFF +const h7FFFFFFF +# yields 1 +le +store h1F0EC + +const hFFFFFFFF +const h7FFFFFFF +# yields 0 +ule +store h1F0F0 + +const hFFFFFFFF +const h7FFFFFFF +# yields 0 +gt +store h1F0F4 + +const hFFFFFFFF +const h7FFFFFFF +# yields 1 +ugt +store h1F0F8 + +const hFFFFFFFF +const h7FFFFFFF +# yields 0 +ge +store h1F0FC + +const hFFFFFFFF +const h7FFFFFFF +# yields 1 +uge +store h1F100 + + +## compare 18532 to 234, no signedness magic here + +const 18532 +const 234 +# yields 0 +eq +store h1F2E0 + +const 18532 +const 234 +# yields 0 +lt +store h1F2E4 + +const 18532 +const 234 +# yields 0 +ult +store h1F2E8 + +const 18532 +const 234 +# yields 0 +le +store h1F2EC + +const 18532 +const 234 +# yields 0 +ule +store h1F2F0 + +const 18532 +const 234 +# yields 1 +gt +store h1F2F4 + +const 18532 +const 234 +# yields 1 +ugt +store h1F2F8 + +const 18532 +const 234 +# yields 1 +ge +store h1F2FC + +const 18532 +const 234 +# yields 1 +uge +store h1F300 + + +## compare 123 to -1294081 +## -1294081 will be interpreted as big positive number for unsigned operations + +const 123 +const -1294081 +# yields 0 +eq +store h1F4E0 + +const 123 +const -1294081 +# yields 0 +lt +store h1F4E4 + +const 123 +const -1294081 +# yields 1 +ult +store h1F4E8 + +const 123 +const -1294081 +# yields 0 +le +store h1F4EC + +const 123 +const -1294081 +# yields 1 +ule +store h1F4F0 + +const 123 +const -1294081 +# yields 1 +gt +store h1F4F4 + +const 123 +const -1294081 +# yields 0 +ugt +store h1F4F8 + +const 123 +const -1294081 +# yields 1 +ge +store h1F4FC + +const 123 +const -1294081 +# yields 0 +uge +store h1F500 + + +halt diff --git a/tests/stack_machine_relop/test.v b/tests/stack_machine_relop/test.v new file mode 120000 index 0000000..f5b6a59 --- /dev/null +++ b/tests/stack_machine_relop/test.v @@ -0,0 +1 @@ +../stack_machine_store/test.v \ No newline at end of file diff --git a/tests/stack_machine_relop/words_to_verify.mem b/tests/stack_machine_relop/words_to_verify.mem new file mode 100644 index 0000000..b0564a3 --- /dev/null +++ b/tests/stack_machine_relop/words_to_verify.mem @@ -0,0 +1,40 @@ +// address value + 1EEE0 1 + 1EEE4 0 + 1EEE8 0 + 1EEEC 1 + 1EEF0 1 + 1EEF4 0 + 1EEF8 0 + 1EEFC 1 + 1EF00 1 + + 1F0E0 0 + 1F0E4 1 + 1F0E8 0 + 1F0EC 1 + 1F0F0 0 + 1F0F4 0 + 1F0F8 1 + 1F0FC 0 + 1F100 1 + + 1F2E0 0 + 1F2E4 0 + 1F2E8 0 + 1F2EC 0 + 1F2F0 0 + 1F2F4 1 + 1F2F8 1 + 1F2FC 1 + 1F300 1 + + 1F4E0 0 + 1F4E4 0 + 1F4E8 1 + 1F4EC 0 + 1F4F0 1 + 1F4F4 1 + 1F4F8 0 + 1F4FC 1 + 1F500 0 diff --git a/tests/stack_machine_store/test.v b/tests/stack_machine_store/test.v index 98ea2dc..61b80c8 100644 --- a/tests/stack_machine_store/test.v +++ b/tests/stack_machine_store/test.v @@ -184,7 +184,7 @@ module stack_machine_test(); CLK <= 0; RST <= 1; - for (i = 0; i < 3500; i++) begin + for (i = 0; i < 7500; i++) begin #1; CLK <= ~CLK; @@ -211,9 +211,9 @@ module stack_machine_test(); $finish; end // if (M_finished) - end // for (i = 0; i < 3500; i++) + end // for (i = 0; i < 7500; i++) - $display("error: cpu hasn't finished its operations in 1750 ticks"); + $display("error: cpu hasn't finished its operations in 3750 ticks"); $finish; end // initial begin endmodule // stack_machine_test -- cgit v1.2.3