diff options
author | Wojciech Kosior <kwojtus@protonmail.com> | 2020-12-24 13:03:25 +0100 |
---|---|---|
committer | Wojciech Kosior <kwojtus@protonmail.com> | 2020-12-24 13:03:25 +0100 |
commit | 5ed2dafa6910e211cae1d83d364d5c24d3b21b4c (patch) | |
tree | adda605f1895f9287ae45b7a71f0fb037f48631e /examples | |
parent | 10392220fd4ed6c9fdbb108260d9fdb6cf5d9d8f (diff) | |
download | AGH-engineering-thesis-5ed2dafa6910e211cae1d83d364d5c24d3b21b4c.tar.gz AGH-engineering-thesis-5ed2dafa6910e211cae1d83d364d5c24d3b21b4c.zip |
add example, that measures time and prints it to screen
Diffstat (limited to 'examples')
-rw-r--r-- | examples/example2a_measure_time_wasm/Makefile | 3 | ||||
-rw-r--r-- | examples/example2a_measure_time_wasm/instructions.wat | 110 | ||||
l--------- | examples/example2b_measure_time_wasm/Makefile | 1 | ||||
-rw-r--r-- | examples/example2b_measure_time_wasm/instructions.wat | 112 | ||||
-rw-r--r-- | examples/example_toplevel.v | 5 |
5 files changed, 231 insertions, 0 deletions
diff --git a/examples/example2a_measure_time_wasm/Makefile b/examples/example2a_measure_time_wasm/Makefile new file mode 100644 index 0000000..a454260 --- /dev/null +++ b/examples/example2a_measure_time_wasm/Makefile @@ -0,0 +1,3 @@ +SIMFLAGS += -DFINISH_ON_LED1=1 -DFINISH_ON_LED2=1 -DFINISH_ON_IMAGE_WRITES=1 + +include ../../Makefile.example diff --git a/examples/example2a_measure_time_wasm/instructions.wat b/examples/example2a_measure_time_wasm/instructions.wat new file mode 100644 index 0000000..3a6be34 --- /dev/null +++ b/examples/example2a_measure_time_wasm/instructions.wat @@ -0,0 +1,110 @@ +;; See instructions.wat of soc_print_number test. A lot has been taken from +;; there. +;; Relevant addresses are VGA text memory (0xFFC00), VGA regs (0x100600), +;; lower half of timer reg (0x1BFC08) and led2 reg (0x1BFC06). + +(module + (memory 0 2) + ;; print number in decimal at address $dest, return address after + ;; the last digit + (func $print (param $number i32) (param $dest i32) (result i32) + (local $adr1 i32) + (local $adr2 i32) + ;; remember the initial address to write at + (set_local $adr1 (get_local $dest)) + (loop $again + ;; prepare address for store operation later + (get_local $dest) + ;; compute the last digit of number + (i32.rem_u (get_local $number) + (i32.const 10)) + ;; 0x30 is ASCII encoding of digit 0 + (i32.add (i32.const 0x30)) + ;; write digit's ASCII char to memory + (i32.store8 offset=0x0 align=1) + ;; increment the pointer + (set_local $dest (i32.add (i32.const 1) + (get_local $dest))) + ;; divide our number by 10 + (set_local $number (i32.div_u (get_local $number) + (i32.const 10))) + ;; break the loop, if number is 0 + (br_if $again (get_local $number))) + + ;; digit chars are now in the reverse order - swap them in a loop + (set_local $adr2 (i32.sub (get_local $dest) + (i32.const 1))) + (loop $again + ;; prepare address for later store operation + (get_local $adr2) + ;; load value on the left + (i32.load8_u offset=0x0 align=1 + (get_local $adr1)) + ;; prepare address for later store operation + (get_local $adr1) + ;; load value on the right + (i32.load8_u offset=0x0 align=1 + (get_local $adr2)) + ;; write value on the left + (i32.store8 offset=0x0 align=1) + ;; write value on the right + (i32.store8 offset=0x0 align=1) + + ;; increase $adr1 + (set_local $adr1 (i32.add (get_local $adr1) + (i32.const 1))) + ;; decrease $adr2 + (set_local $adr2 (i32.sub (get_local $adr2) + (i32.const 1))) + ;; loop until adr1 and adr2 cross/meet + (br_if $again (i32.lt_u (get_local $adr1) + (get_local $adr2)))) + ;; return the address we finished at + (get_local $dest)) + (func $main + (local $counter i32) + (local $adr i32) + + ;; reset the timer (although it should already be resetted, anyway...) + (i32.store16 offset=0x1BFC08 align=1 + (i32.const 0x0) (i32.const 0x0)) + + ;; initialize counter + (set_local $counter (i32.const 0)) + + ;; add numbers from 1 to 100 + (i32.const 0) + (loop $again (param i32) (result i32) + (set_local $counter (i32.add + (get_local $counter) + (i32.const 1))) + (i32.add (get_local $counter)) + (br_if $again (i32.lt_u + (get_local $counter) + (i32.const 100)))) + ;; we now leave sum on the stack for later + + ;; light led2 + (i32.store16 offset=0x1BFC06 align=1 + (i32.const 0x0) (i32.const 0x1)) + + ;; print timer value + (set_local $adr (call $print + ;; read timer value + (i32.load16_u offset=0x1BFC08 align=1 + (i32.const 0x0)) + (i32.const 0xFFC00))) + + ;; print ascii underscore '_' + (i32.store8 offset=0x0 align=1 + (get_local $adr) (i32.const 0x5F)) + + ;; print computed sum + (set_local $adr (call $print + ;; sum's already on the stack + (i32.add (get_local $adr) (i32.const 1)))) + + ;; write a non-zero value to the VGA power-on reg at 0x100600 (0x100A00) + (i32.store16 offset=0x100600 align=2 + (i32.const 0) (i32.const 1))) + (export "main" (func $main))) diff --git a/examples/example2b_measure_time_wasm/Makefile b/examples/example2b_measure_time_wasm/Makefile new file mode 120000 index 0000000..1dcc8e9 --- /dev/null +++ b/examples/example2b_measure_time_wasm/Makefile @@ -0,0 +1 @@ +../example2a_measure_time_wasm/Makefile
\ No newline at end of file diff --git a/examples/example2b_measure_time_wasm/instructions.wat b/examples/example2b_measure_time_wasm/instructions.wat new file mode 100644 index 0000000..6107b30 --- /dev/null +++ b/examples/example2b_measure_time_wasm/instructions.wat @@ -0,0 +1,112 @@ +;; See instructions.wat of soc_print_number test. A lot has been taken from +;; there. +;; Relevant addresses are VGA text memory (0xFFC00), VGA regs (0x100600), +;; lower half of timer reg (0x1BFC08) and led2 reg (0x1BFC06). + +(module + (memory 0 2) + ;; print number in decimal at address $dest, return address after + ;; the last digit + (func $print (param $number i32) (param $dest i32) (result i32) + (local $adr1 i32) + (local $adr2 i32) + ;; remember the initial address to write at + (set_local $adr1 (get_local $dest)) + (loop $again + ;; prepare address for store operation later + (get_local $dest) + ;; compute the last digit of number + (i32.rem_u (get_local $number) + (i32.const 10)) + ;; 0x30 is ASCII encoding of digit 0 + (i32.add (i32.const 0x30)) + ;; write digit's ASCII char to memory + (i32.store8 offset=0x0 align=1) + ;; increment the pointer + (set_local $dest (i32.add (i32.const 1) + (get_local $dest))) + ;; divide our number by 10 + (set_local $number (i32.div_u (get_local $number) + (i32.const 10))) + ;; break the loop, if number is 0 + (br_if $again (get_local $number))) + + ;; digit chars are now in the reverse order - swap them in a loop + (set_local $adr2 (i32.sub (get_local $dest) + (i32.const 1))) + (loop $again + ;; prepare address for later store operation + (get_local $adr2) + ;; load value on the left + (i32.load8_u offset=0x0 align=1 + (get_local $adr1)) + ;; prepare address for later store operation + (get_local $adr1) + ;; load value on the right + (i32.load8_u offset=0x0 align=1 + (get_local $adr2)) + ;; write value on the left + (i32.store8 offset=0x0 align=1) + ;; write value on the right + (i32.store8 offset=0x0 align=1) + + ;; increase $adr1 + (set_local $adr1 (i32.add (get_local $adr1) + (i32.const 1))) + ;; decrease $adr2 + (set_local $adr2 (i32.sub (get_local $adr2) + (i32.const 1))) + ;; loop until adr1 and adr2 cross/meet + (br_if $again (i32.lt_u (get_local $adr1) + (get_local $adr2)))) + ;; return the address we finished at + (get_local $dest)) + (func $add (param $number1 i32) (param $number2 i32) (result i32) + (i32.add (get_local $number1) (get_local $number2))) + (func $main + (local $counter i32) + (local $adr i32) + + ;; reset the timer (although it should already be resetted, anyway...) + (i32.store16 offset=0x1BFC08 align=1 + (i32.const 0x0) (i32.const 0x0)) + + ;; initialize counter + (set_local $counter (i32.const 0)) + + ;; add numbers from 1 to 100 + (i32.const 0) + (loop $again (param i32) (result i32) + (set_local $counter (call $add + (get_local $counter) + (i32.const 1))) + (i32.add (get_local $counter)) + (br_if $again (i32.lt_u + (get_local $counter) + (i32.const 100)))) + ;; we now leave sum on the stack for later + + ;; light led2 + (i32.store16 offset=0x1BFC06 align=1 + (i32.const 0x0) (i32.const 0x1)) + + ;; print timer value + (set_local $adr (call $print + ;; read timer value + (i32.load16_u offset=0x1BFC08 align=1 + (i32.const 0x0)) + (i32.const 0xFFC00))) + + ;; print ascii underscore '_' + (i32.store8 offset=0x0 align=1 + (get_local $adr) (i32.const 0x5F)) + + ;; print computed sum + (set_local $adr (call $print + ;; sum's already on the stack + (i32.add (get_local $adr) (i32.const 1)))) + + ;; write a non-zero value to the VGA power-on reg at 0x100600 (0x100A00) + (i32.store16 offset=0x100600 align=2 + (i32.const 0) (i32.const 1))) + (export "main" (func $main))) diff --git a/examples/example_toplevel.v b/examples/example_toplevel.v index 1da1750..3359bb3 100644 --- a/examples/example_toplevel.v +++ b/examples/example_toplevel.v @@ -125,6 +125,11 @@ module example(); end end + always @ (image_writes) begin + if (image_writes) + `MSG(("Display refreshed %0d times", image_writes)); + end + generate if (`FINISH_RULE_PROVIDED) begin always @ (image_writes or led1 or led2 or can_finish) begin |