⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control_fsm.vhd

📁 8051VHDL原代码
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    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 + -