From c35376833f7866685aa72dd5cc1cf4c9e35a74da Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Sun, 6 Nov 2022 19:28:36 +0100 Subject: [PATCH] Blinky program with timer interrupts --- programs/timer_blinky.prog | 97 ++++++++++++++++++++++++++ programs/timer_test.prog | 4 +- soc/peripheral/timer.vhd | 2 +- soc/testbench/warmup2_timer_blinky.vhd | 59 ++++++++++++++++ 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 programs/timer_blinky.prog create mode 100644 soc/testbench/warmup2_timer_blinky.vhd diff --git a/programs/timer_blinky.prog b/programs/timer_blinky.prog new file mode 100644 index 0000000..490c91f --- /dev/null +++ b/programs/timer_blinky.prog @@ -0,0 +1,97 @@ +reset: + br always >main + nop + +hardfault: + reti + nop + +memfault: + reti + nop + +timer_interrupt: + br >timer_interrupt_handler + nop + +.align +led_addr: .word 0x000F0000 +timer_counter_addr: .word 0x000F0008 +timer_status_addr: .word 0x000F000C +dmem_start_addr: .word 0x00000400 +dmem_end_addr: .word 0x000004FC +priority_mask: .word 0xFFFFFF03 +xor_mask: .word 0xFFFFFFFF + +main: + // Initialize stack pointer to the end of the data memory + ldr r12, >dmem_end_addr + + // Set runtime priority + ldr r0, >priority_mask + and r14, r0, r14 + + ldr r0,>led_addr // LED addr + ldr r1,>timer_status_addr // Timer addr + + // Init + clr r9 // 0 if we are currently filling, 1 if we are currently flushing + clr r8 // shift register + clr r5 // shift counter + clr r4 // shift counter top constant + addi r4, 10 + + // Enable the timer... + clr r2 + addi r2, 0x3 // enable and repeat bit set + st32 r1, r2 + +loop: + br >loop + nop + +timer_interrupt_handler: + clr r10 + addi r10, 1 + cmp eq r9, r10 + br true >flush + nop + br always >fill + nop + +rst_fill: + clr r5 +fill: + clr r9 + + // When shift register full, jump to flush + addi r5, 1 + cmp eq r5, r4 + br true >rst_flush + nop + + lsh r8, r8, 1 + addi r8, 1 + st08 r0, r8 + + reti + nop + +rst_flush: + clr r5 +flush: + clr r9 + addi r9, 1 + + // When shift register empty, jump to fill + addi r5, 1 + cmp eq r5, r4 + br true >rst_fill + nop + + lsh r8, r8, 1 + st08 r0, r8 + + reti + nop + diff --git a/programs/timer_test.prog b/programs/timer_test.prog index 6c6e731..aa04c0d 100644 --- a/programs/timer_test.prog +++ b/programs/timer_test.prog @@ -19,7 +19,7 @@ led_addr: .word 0x000F0000 timer_counter_addr: .word 0x000F0008 timer_status_addr: .word 0x000F000C dmem_start_addr: .word 0x00000400 -dmem_end_addr: .word 0x000004FF +dmem_end_addr: .word 0x000004FC priority_mask: .word 0xFFFFFF03 main: @@ -44,7 +44,7 @@ main: st08 r1, r2 loop: - call >loop + br >loop nop diff --git a/soc/peripheral/timer.vhd b/soc/peripheral/timer.vhd index ac7f829..d6f2e32 100644 --- a/soc/peripheral/timer.vhd +++ b/soc/peripheral/timer.vhd @@ -23,7 +23,7 @@ entity wb_timer is end wb_timer; architecture Behavioral of wb_timer is - constant COUNT_MAX : integer := 32 - 1; + constant COUNT_MAX : integer := 128 - 1; signal ack : std_logic; diff --git a/soc/testbench/warmup2_timer_blinky.vhd b/soc/testbench/warmup2_timer_blinky.vhd new file mode 100644 index 0000000..6e96ffe --- /dev/null +++ b/soc/testbench/warmup2_timer_blinky.vhd @@ -0,0 +1,59 @@ +-- See the file "LICENSE" for the full license governing this code. -- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY warmup2_timer_blinky_tb IS +END ENTITY; + +ARCHITECTURE sim OF warmup2_timer_blinky_tb IS + + constant CLK_PERIOD : time := 10 ns; + + signal clk : std_logic := '0'; + signal rst : std_logic; + + signal led : std_logic_vector(7 downto 0); + signal btn : std_logic_vector(4 downto 0) := (others => '0'); + signal sw : std_logic_vector(15 downto 0) := (others => '0'); + + COMPONENT lt16soc_top IS + generic( + programfilename : string := "../../programs/timer_blinky.ram" + ); + port( + clk : in std_logic; + rst : in std_logic; + led : out std_logic_vector(7 downto 0); + btn : in std_logic_vector(4 downto 0); + sw : in std_logic_vector(15 downto 0) + ); + END COMPONENT; + +BEGIN + + dut: lt16soc_top port map( + clk=>clk, + rst=>rst, + led=>led, + btn=>btn, + sw=>sw + ); + + clk_gen: process + begin + clk <= not clk; + wait for CLK_PERIOD/2; + end process clk_gen; + + stimuli: process + begin + rst <= '0'; + wait for CLK_PERIOD; + rst <= '1'; + wait for 20000*CLK_PERIOD; + assert false report "Simulation terminated!" severity failure; + end process stimuli; + + +END ARCHITECTURE;