📄 control_fsm.vhd
字号:
IC_XCH_A_D when s_command = XCH_A_D else
IC_XCH_A_ATRI when s_command(7 downto 1) = XCH_A_ATRI else
IC_XCHD_A_ATRI when s_command(7 downto 1) = XCHD_A_ATRI else
IC_XRL_A_RR when s_command(7 downto 3) = XRL_A_RR else
IC_XRL_A_D when s_command = XRL_A_D else
IC_XRL_A_ATRI when s_command(7 downto 1) = XRL_A_ATRI else
IC_XRL_A_DATA when s_command = XRL_A_DATA else
IC_XRL_D_A when s_command = XRL_D_A else
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_ie0,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_ie0,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,intblock_i)
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;
s_ext0isr_d <= '0';
s_ext1isr_d <= '0';
s_ext0isrh_d <= '0';
s_ext1isrh_d <= '0';
s_ext0isr_en <= '0';
s_ext1isr_en <= '0';
s_ext0isrh_en <= '0';
s_ext1isrh_en <= '0';
if state=STARTUP then
-- Power up wait cycle
NULL;
else
-- begin of starting the interrupt procedure
-- saving the old adress
if intblock_i = '0' and
((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';
s_adr_mux <= "0001";
s_regs_wr_en <= "110"; -- reset IE0
s_ext0isrh_d <= '1';
s_ext0isrh_en <= '1';
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';
s_adr_mux <= "0011";
s_regs_wr_en <= "110"; -- reset IE1
s_ext1isrh_d <= '1';
s_ext1isrh_en <= '1';
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';
s_adr_mux <= "0001";
s_regs_wr_en <= "110"; -- reset IE0
s_ext0isr_d <= '1';
s_ext0isr_en <= '1';
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';
s_adr_mux <= "0011";
s_regs_wr_en <= "110"; -- reset IE1
s_ext1isr_d <= '1';
s_ext1isr_en <= '1';
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -