?? control_fsm_rtl.vhd
字號:
IC_XRL_D_DATA when s_command = XRL_D_DATA else IC_NOP; -------------------------------------------------------------------------------- purpose: main-process to control the mcu-- includes the interupt-handling and the state machine-- inputs: state,s_help,s_ti,s_ri,s_it0,s_ie0,s_it1,s_ie1,s_tf0,s_tf1,-- s_bit_data,aludata_i,s_command,s_inthigh,-- s_intlow,acc,psw,s_intpre,s_intpre2,ie,ip-- outputs: pc_inc_en_o,s_nextstate_o,adr_mux_o,data_mux_o,bdata_mux_o-- regs_wr_en_o,help_en_o,help16_en_o,helpb_en_o,inthigh_en_o-- intlow_en_o,intpre2_en_o,inthigh_d_o,intlow_d_o,intpre2_d_o------------------------------------------------------------------------------ p_state: process (state,s_help,s_ti,s_ri,s_it0,s_ie0,s_it1,s_ie1,s_tf0,s_tf1, s_bit_data,aludata_i,s_instr_category,s_inthigh, s_intlow,acc,psw,s_intpre,s_intpre2,ie,ip) begin s_data_mux <= "0000"; -- default values s_adr_mux <= "0000"; s_bdata_mux <= "0000"; alu_cmd_o <= OFF; s_regs_wr_en <= "000"; s_help_en <= "0000"; s_help16_en <= "00"; s_helpb_en <= '0'; s_pc_inc_en <= "0000"; s_inthigh_en <= '0'; s_intlow_en <= '0'; s_intpre2_en <= '0'; s_inthigh_d <= '0'; s_intlow_d <= '0'; s_intpre2_d <= '0'; s_adrx_mux <= "00"; s_wrx_mux <= '0'; s_nextstate <= FETCH; if state=STARTUP then -- Power up wait cycle NULL; else -- begin of starting the interrupt procedure -- saving the old adress if (s_intpre='1' and state=FETCH) or s_intpre2='1' then if state=FETCH then s_intpre2_en <= '1'; s_intpre2_d <= '1'; s_regs_wr_en <= "001"; -- increment stackpointer s_nextstate <= EXEC1; elsif state=EXEC1 then if (PX0 and EX0 and s_ie0)='1' then -- external interrupt 0 s_help_en <= "0101"; -- interruptvector 0003h s_inthigh_d <= '1'; s_inthigh_en <= '1'; if s_it0='1' then -- interrupt is edge-sensitive s_adr_mux <= "0001"; s_regs_wr_en <= "110"; -- reset IE0 else NULL; end if; elsif (PT0 and ET0 and s_tf0)='1' then -- timer interrupt 0 s_help_en <= "0110"; -- interruptvector 000Bh s_inthigh_d <= '1'; s_inthigh_en <= '1'; s_adr_mux <= "0010"; s_regs_wr_en <= "110"; -- reset TF0 elsif (PX1 and EX1 and s_ie1)='1' then -- external interrupt 1 s_help_en <= "0111"; -- interruptvector 0013h s_inthigh_d <= '1'; s_inthigh_en <= '1'; if s_it1='1' then -- interrupt is edge-sensitive s_adr_mux <= "0011"; s_regs_wr_en <= "110"; -- reset IE1 else NULL; end if; elsif (PT1 and ET1 and s_tf1)='1' then -- timer interrupt 1 s_help_en <= "1000"; -- interruptvector 001Bh s_inthigh_d <= '1'; s_inthigh_en <= '1'; s_adr_mux <= "0100"; s_regs_wr_en <= "110"; -- reset TF1 elsif (PS0 and ES and (s_ri or s_ti))='1' then -- serial interrupt 0 s_help_en <= "1001"; -- interruptvector 0023h s_inthigh_d <= '1'; s_inthigh_en <= '1'; elsif (EX0 and s_ie0)='1' then -- external interrupt 0 low priority s_help_en <= "0101"; -- interruptvector 0003h s_intlow_d <= '1'; s_intlow_en <= '1'; if s_it0='1' then -- interrupt is edge-sensitive s_adr_mux <= "0001"; s_regs_wr_en <= "110"; -- reset IE0 else NULL; end if; elsif (ET0 and s_tf0)='1' then -- timer interrupt 0 low priority s_help_en <= "0110"; -- interruptvector 000Bh s_intlow_d <= '1'; s_intlow_en <= '1'; s_adr_mux <= "0010"; s_regs_wr_en <= "110"; -- reset TF0 elsif (EX1 and s_ie1)='1' then -- external interrupt 1 low priority s_help_en <= "0111"; -- interruptvector 0013h s_intlow_d <= '1'; s_intlow_en <= '1'; if s_it0='1' then -- interrupt is edge-sensitive s_adr_mux <= "0011"; s_regs_wr_en <= "110"; -- reset IE1 else NULL; end if; elsif (ET1 and s_tf1)='1' then -- timer interrupt 1 low priority s_help_en <= "1000"; -- interruptvector 001Bh s_intlow_d <= '1'; s_intlow_en <= '1'; s_adr_mux <= "0100"; s_regs_wr_en <= "110"; -- reset TF1 elsif (ES and (s_ri or s_ti))='1' then -- serial int 0 low priority s_help_en <= "1001"; -- interruptvector 0023h s_intlow_d <= '1'; s_intlow_en <= '1'; else NULL; end if; s_nextstate <= EXEC2; elsif state=EXEC2 then s_adr_mux <= "0101"; s_data_mux <= "0001"; -- data = pc(7 downto 0) s_regs_wr_en <= "101"; -- write one byte and increment SP s_nextstate <= EXEC3; elsif state=EXEC3 then s_intpre2_d <= '0'; s_intpre2_en <= '1'; s_adr_mux <= "0101"; s_data_mux <= "0010"; -- data = pc(15 downto 8) s_regs_wr_en <= "100"; -- write one byte s_pc_inc_en <= "0011"; -- load program counter s_nextstate <= FETCH; else s_nextstate <= FETCH; end if; -- end of starting interrupt procedure else case s_instr_category is --------------------------------------------------------------------- when IC_ACALL => -- ACALL addr11 if state=FETCH then s_adr_mux <= "1111"; -- adress = sp + 1 s_data_mux <= "1110"; -- data = (pc+2)(7 downto 0) s_regs_wr_en <= "101"; -- write one byte and increment SP s_help16_en <= "10"; -- s_help16 = pc+2 s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= EXEC1; elsif state=EXEC1 then s_adr_mux <= "1111"; -- adress = sp + 1 s_data_mux <= "1101"; -- data = s_help16(15 downto 8) s_regs_wr_en <= "101"; -- write one byte and increment SP s_pc_inc_en <= "0100"; -- load PC with 11 bits (2k block) s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADD_A_RR => -- ADD A,Rr if state=FETCH then s_adr_mux <= "0110"; -- adress = RR-adress s_nextstate <= EXEC1; elsif state=EXEC1 then alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADD_A_D => -- ADD A, direct if state=FETCH then s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= EXEC1; elsif state=EXEC1 then s_adr_mux <= "1000"; -- adress = rom_data_i s_nextstate <= EXEC2; elsif state=EXEC2 then alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADD_A_ATRI => -- ADD A,@Ri if state=FETCH then s_adr_mux <= "0111"; -- address = Ri-register s_nextstate <= EXEC1; elsif state=EXEC1 then alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADD_A_DATA => -- ADD A, DATA if state=FETCH then s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= EXEC1; elsif state=EXEC1 then alu_cmd_o <= ADD_ACC_ROM; -- addition command (ACC + ROM_DATA_I) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADDC_A_RR => -- ADDC A,Rr if state=FETCH then s_adr_mux <= "0110"; -- adress = RR-adress s_nextstate <= EXEC1; elsif state=EXEC1 then alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADDC_A_D => -- ADDC A, direct if state=FETCH then s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= EXEC1; elsif state=EXEC1 then s_adr_mux <= "1000"; -- adress = rom_data_i s_nextstate <= EXEC2; elsif state=EXEC2 then alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADDC_A_ATRI => -- ADDC A,@Ri if state=FETCH then s_adr_mux <= "0111"; -- address = Ri-register s_nextstate <= EXEC1; elsif state=EXEC1 then alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY) s_data_mux <= "0011"; -- data = aludata_i s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC s_pc_inc_en <= "0001"; -- increment program-counter s_nextstate <= FETCH; end if; --------------------------------------------------------------------- when IC_ADDC_A_DATA => -- ADDC A, data if state=FETCH then s_pc_inc_en <= "0001"; -- increment program-counter
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -