aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojciech Kosior <kwojtus@protonmail.com>2020-12-24 13:03:25 +0100
committerWojciech Kosior <kwojtus@protonmail.com>2020-12-24 13:03:25 +0100
commit5ed2dafa6910e211cae1d83d364d5c24d3b21b4c (patch)
treeadda605f1895f9287ae45b7a71f0fb037f48631e
parent10392220fd4ed6c9fdbb108260d9fdb6cf5d9d8f (diff)
downloadAGH-engineering-thesis-5ed2dafa6910e211cae1d83d364d5c24d3b21b4c.tar.gz
AGH-engineering-thesis-5ed2dafa6910e211cae1d83d364d5c24d3b21b4c.zip
add example, that measures time and prints it to screen
-rw-r--r--Makefile.example1
-rw-r--r--Makefile.test3
-rw-r--r--Makefile.util3
-rw-r--r--examples/example2a_measure_time_wasm/Makefile3
-rw-r--r--examples/example2a_measure_time_wasm/instructions.wat110
l---------examples/example2b_measure_time_wasm/Makefile1
-rw-r--r--examples/example2b_measure_time_wasm/instructions.wat112
-rw-r--r--examples/example_toplevel.v5
8 files changed, 235 insertions, 3 deletions
diff --git a/Makefile.example b/Makefile.example
index e44cf9c..c85dc8f 100644
--- a/Makefile.example
+++ b/Makefile.example
@@ -26,6 +26,7 @@ example.vvp : $(DESIGN_DIR)/*.v soc_with_peripherals.v flash_memory.v sram.v \
simulate : example.vvp
$(VVP) $<
+ if [ -f VGAdump.mem ]; then $(MAKE) VGAdump.ppm; fi
design.v : instructions.mem $(DESIGN_DIR)/*.v $(FONT)
$(IV) $(IVFLAGS) $(ROM_DEFINES) -E $(filter %.v,$^) -o $@
diff --git a/Makefile.test b/Makefile.test
index d6ac8ab..8427465 100644
--- a/Makefile.test
+++ b/Makefile.test
@@ -53,9 +53,6 @@ endif
report.log VGAdump.mem : test.vvp
$(VVP) $< | $(call DBG&SAVE,report.log)
-VGAdump.ppm : $(PROJ_DIR)/tools/VGAdump2ppm VGAdump.mem
- grep -v // < VGAdump.mem | $< > $@
-
clean :
find . -name "*.vvp" -delete
rm $(call FIND_GENERATED_FILES,.) report.log VGAdump.mem \
diff --git a/Makefile.util b/Makefile.util
index 4abddca..88939b1 100644
--- a/Makefile.util
+++ b/Makefile.util
@@ -67,4 +67,7 @@ FIND_GENERATED_FILES = \
$(call FIND_GENERATED_MEM_FILES,$(1)) \
$(call FIND_GENERATED_WASM_FILES,$(1))
+VGAdump.ppm : $(PROJ_DIR)/tools/VGAdump2ppm VGAdump.mem
+ grep -v // < VGAdump.mem | $< > $@
+
.PHONY : prog
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