From 2c528314ebe29a1c94b6c03fd1b0e2668ee25dff Mon Sep 17 00:00:00 2001 From: Wojciech Kosior Date: Sat, 5 Sep 2020 17:58:56 +0200 Subject: add div instruction together with bench --- Makefile | 5 +-- design/stack_machine.v | 49 +++++++++++++++++++++++++++-- tclasm.tcl | 5 +++ tests/stack_machine_div/instructions.s.tcl | 21 +++++++++++++ tests/stack_machine_div/test.v | 1 + tests/stack_machine_div/words_to_verify.mem | 6 ++++ 6 files changed, 82 insertions(+), 5 deletions(-) create mode 100755 tests/stack_machine_div/instructions.s.tcl create mode 120000 tests/stack_machine_div/test.v create mode 100644 tests/stack_machine_div/words_to_verify.mem diff --git a/Makefile b/Makefile index dfeb4f9..c7ab240 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,8 @@ STACK_MACHINE_TESTS := \ tee \ swap \ add \ - sub + sub \ + div # Add other tests here if You need TESTS := \ @@ -168,7 +169,7 @@ tests/stack_machine_%/test.vvp : \ tests/stack_machine_%/words_to_verify.mem \ tests/stack_machine_%/instructions.mem \ tests/stack_machine_%/test.v models/slave.v \ - design/stack_machine.v include/messages.vh + design/stack_machine.v design/div.v include/messages.vh $(IV) $(IVFLAGS) -s stack_machine_test \ -DINSTRUCTIONS_COUNT=$(call FILE_LINES,$(filter %ions.mem,$^)) \ -DWORDS_TO_VERIFY_COUNT=$(call FILE_LINES,$<) \ diff --git a/design/stack_machine.v b/design/stack_machine.v index 0ccc1c6..4313713 100644 --- a/design/stack_machine.v +++ b/design/stack_machine.v @@ -208,10 +208,43 @@ module stack_machine_new assign instr_sub = !set_im && !use_im && stack_shrinks_by_1 && instruction[11:0] == 12'd1; + wire instr_udiv; + assign instr_udiv = !set_im && !use_im && stack_shrinks_by_1 && + instruction[11:0] == 12'd2; + reg halt; /* Set once a halt instruction is encountered */ assign finished = halt; + + /* module for division */ + wire [31:0] div_quotient; + wire [31:0] div_remainder; + wire div_done; + + div + #( + .WIDTH(32) + ) div + ( + .clock(CLK_I), + .start(step == STEP_EXECUTING && first_execution_tick), + .dividend(r0), + .divisor(r1), + + .quotient(div_quotient), + .remainder(div_remainder), + .done(div_done) + ); + + + reg arithmetic_uncompleted; + wire arithmetic_completes; + assign arithmetic_completes = instr_udiv ? div_done : + instr_halt ? 0 : + 1; + + always @* I_ADR_O = pc / 2; @@ -284,6 +317,8 @@ module stack_machine_new I_CYC_O <= 0; end + arithmetic_uncompleted <= 1; + first_execution_tick <= 1; load_store_unrequested <= 0; stack_transfer_unrequested <= 2'b0; @@ -293,12 +328,17 @@ module stack_machine_new STEP_EXECUTING : begin first_execution_tick <= 0; + if (arithmetic_completes) + arithmetic_uncompleted <= 0; + if (((stack_grows || stack_shrinks || load || store) && first_execution_tick) || (load_store_uncompleted && !data_command_completes) || (stack_transfer_uncompleted[1] && - !stack_transfer_completes[1]) || halt) begin + !stack_transfer_completes[1]) || + (arithmetic_uncompleted && + !arithmetic_completes)) begin step <= STEP_EXECUTING; /* Remain where we are */ end else begin step <= STEP_LOADING_INSTRUCTION; @@ -457,11 +497,14 @@ module stack_machine_new r1 <= im_effective; /* Instructions, that shrink stack */ - if (instr_add && first_execution_tick) + if (instr_add && arithmetic_uncompleted) r1 <= r0 + r1; - if (instr_sub && first_execution_tick) + if (instr_sub && arithmetic_uncompleted) r1 <= r0 - r1; + + if (instr_udiv && arithmetic_uncompleted) + r1 <= div_quotient; end // case: STEP_EXECUTING endcase // case (step) end // else: !if(RST_I) diff --git a/tclasm.tcl b/tclasm.tcl index 17aa8aa..4293441 100644 --- a/tclasm.tcl +++ b/tclasm.tcl @@ -176,3 +176,8 @@ proc add {} { proc sub {} { puts 0011000000000001 } + + +proc div {} { + puts 0011000000000010 +} diff --git a/tests/stack_machine_div/instructions.s.tcl b/tests/stack_machine_div/instructions.s.tcl new file mode 100755 index 0000000..7f09f20 --- /dev/null +++ b/tests/stack_machine_div/instructions.s.tcl @@ -0,0 +1,21 @@ +#!/usr/bin/env tclsh + +source tclasm.tcl + +### store 2 values to memory, load them back, divide one by another and store +### the result (quotient); this is analogous to addition and substraction tests + +set_sp 0 + +const 777681520 +store h1EEE0 +const 3721 +store h1EEE4 + +load h1EEE0 +load h1EEE4 +# dividing 777681520 by 3721 should yield 208997 r 3683 +div +store h1EEE8 + +halt diff --git a/tests/stack_machine_div/test.v b/tests/stack_machine_div/test.v new file mode 120000 index 0000000..f5b6a59 --- /dev/null +++ b/tests/stack_machine_div/test.v @@ -0,0 +1 @@ +../stack_machine_store/test.v \ No newline at end of file diff --git a/tests/stack_machine_div/words_to_verify.mem b/tests/stack_machine_div/words_to_verify.mem new file mode 100644 index 0000000..2e6c6fa --- /dev/null +++ b/tests/stack_machine_div/words_to_verify.mem @@ -0,0 +1,6 @@ +// address value + 1EEE0 2E5A7A70 // 777681520 in hex is 2E5A7A70 + + 1EEE4 E89 // 3721 in hex is E89 + + 1EEE8 33065 // 208997 in hex is 33065 -- cgit v1.2.3