diff options
| author | Väinö Kauppila <vaino@vke.fi> | 2026-04-19 19:02:42 +0300 |
|---|---|---|
| committer | Väinö Kauppila <vaino@vke.fi> | 2026-04-19 19:02:42 +0300 |
| commit | 46e1210381106707c2df7f07c56023eb6b760763 (patch) | |
| tree | 6740a17199f76e2965a511dafcbc7ffb61ceafeb /hdl/state_machine.vhd | |
| parent | eb8643ddbef43547eb7bfe58789a3908926c7258 (diff) | |
| download | vhdl_pic-46e1210381106707c2df7f07c56023eb6b760763.tar.gz vhdl_pic-46e1210381106707c2df7f07c56023eb6b760763.zip | |
BSRAM progmem. fix Makefile memory command that does not work. add interrupts, bank 1, timer0. Timer0 not tested.
Diffstat (limited to 'hdl/state_machine.vhd')
| -rw-r--r-- | hdl/state_machine.vhd | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/hdl/state_machine.vhd b/hdl/state_machine.vhd index 5b1c623..1fb5291 100644 --- a/hdl/state_machine.vhd +++ b/hdl/state_machine.vhd @@ -31,7 +31,11 @@ entity state_machine is stack_dout : in std_logic_vector(12 downto 0); alu_skip : in std_logic; - alu_result : in std_logic_vector(7 downto 0) + alu_result : in std_logic_vector(7 downto 0); + + irq_pending : in std_logic; + gie_clear : out std_logic := '0'; + gie_set : out std_logic := '0' ); @@ -67,6 +71,8 @@ begin instr_ret <= '0'; stack_push <= '0'; stack_pop <= '0'; + gie_clear <= '0'; + gie_set <= '0'; if reset = '1' then pc_internal <= (others => '0'); @@ -78,16 +84,30 @@ begin case state is when IFetch => + -- Hardware interrupt: push PC, jump to vector, clear GIE + if irq_pending = '1' and not do_phantom_nop then + stack_din <= pc_internal; + stack_push <= '1'; + pc_internal <= "0000000000100"; -- 0x0004 + gie_clear <= '1'; + instr := instruction_decode((others => '0')); + is_phantom := true; + is_skip_phantom := false; + do_phantom_nop := false; + state <= MRead; + -- if we had a branch before, this cycle is a NOP. - if do_phantom_nop then + elsif do_phantom_nop then instr := instruction_decode((others => '0')); do_phantom_nop := false; is_phantom := true; -- is_skip_phantom carries over from whoever set do_phantom_nop + state <= MRead; else instr := instruction_decode(opcode); is_phantom := false; is_skip_phantom := false; + state <= MRead; end if; -- set use_literal based on decoded instruction, holds through MWrite @@ -106,7 +126,6 @@ begin -- for bit-select operations bit_select <= instr.b; - state <= Mread; when MRead => @@ -145,13 +164,16 @@ begin do_phantom_nop := true; is_skip_phantom := false; - elsif instr.op = RETUR or instr.op = RETLW then + elsif instr.op = RETUR or instr.op = RETLW or instr.op = RETFIE then -- pop the PC from stack. pc_internal <= stack_dout; - stack_pop <= '1'; -- pop deferred to next cycle. + stack_pop <= '1'; do_phantom_nop := true; is_skip_phantom := false; + if instr.op = RETFIE then + gie_set <= '1'; + end if; else pc_internal <= std_logic_vector(unsigned(pc_internal) + 1); |
