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

📄 mc8051.vhd

📁 Toplevel VHDL Structural model of a system containing 8051
💻 VHD
📖 第 1 页 / 共 5 页
字号:
            -- and the new data come in at s1p1 of next cycle
            pc <= (acc+pc);
            WAIT UNTIL cycle_state = s2p1;
            acc <= pmem_s1_byte;
            pc <= temp1 & temp2 + 1;
     -- MOVX A, @Ri
        WHEN 16#E2# TO 16#E3# =>
            temp1 := get_reg("00"&opcode(0));  -- the addr
            p0_latch <= "11111111";  -- reset the p0 sfr
            p0_addr <= temp1;      -- send out addr when p0_ctrl
            WAIT UNTIL cycle_state = s3p1;
            port_req <= '1';
            WAIT UNTIL cycle_state = s4p2;
            ale_dm <= '1';
            WAIT UNTIL cycle_state = s5p1;
            p0_ctrl <= '1';
            p3_ctrl(7) <= '1';
            WAIT UNTIL cycle_state = s5p2;
            ale_dm <= '0';
            WAIT UNTIL cycle_state = s1p1;
            rd_n_internal <= '0';
            p0_ctrl <= 'Z';
            WAIT UNTIL cycle_state = s3p1;
            -- read into the accumulator
            acc <= bvec(to_X01(P0));
            WAIT UNTIL cycle_state = s4p1;
            rd_n_internal <= '1';
            port_req <= '0';
            p3_ctrl(7) <= 'Z';
            p0_addr <= "ZZZZZZZZ";
            pc <= pc + 1;
     -- MOVX A, @DPTR 
        WHEN 16#E0# => 
            p0_latch <= "11111111";  -- reset the p0 latch
            WAIT UNTIL cycle_state = s3p1;
            port_req <= '1';
            WAIT UNTIL cycle_state = s4p2;
            ale_dm <= '1';
            WAIT UNTIL cycle_state = s5p1;
            p0_addr <= dpl;  -- send out the addr
            p2_addr <= dph;  -- send out the addr
            p0_ctrl <= '1';
            p2_ctrl <= '1';
            p3_ctrl(7) <= '1';
            WAIT UNTIL cycle_state = s5p2;
            ale_dm <= '0';
            WAIT UNTIL cycle_state = s1p1;
            rd_n_internal <= '0';
            p0_ctrl <= 'Z';
            WAIT UNTIL cycle_state = s3p1;
            -- read into the accumulator
            acc <= bvec(to_X01(P0));
            WAIT UNTIL cycle_state = s4p1;
            rd_n_internal <= '1';
            port_req <= '0';
            p0_addr <= "ZZZZZZZZ";
            p2_ctrl <= 'Z';
            p3_ctrl(7) <= 'Z';
            pc <= pc + 1;
     -- MOVX @Ri, A
        WHEN 16#F2# TO 16#F3# =>
            temp1 := get_reg("00"&opcode(0));  -- the addr
            p0_latch <= "11111111";  -- reset the p0 latch
            WAIT UNTIL cycle_state = s3p1;
            port_req <= '1';
            WAIT UNTIL cycle_state = s4p2;
            ale_dm <= '1';
            WAIT UNTIL cycle_state = s5p1;
            p0_addr <= temp1;  -- send out the addr
            p0_ctrl <= '1';
            p3_ctrl(6) <= '1';
            WAIT UNTIL cycle_state = s5p2;
            ale_dm <= '0';
            WAIT UNTIL cycle_state = s6p2;
            p0_addr <= acc;  -- output the data
            WAIT UNTIL cycle_state = s1p1;
            wr_n_internal <= '0';
            WAIT UNTIL cycle_state = s4p1;
            wr_n_internal <= '1';
            port_req <= '0';   -- shouldn't have any effect until s4p2 
            p0_ctrl <= 'Z';
            p3_ctrl(6) <= 'Z';
            p0_addr <= "ZZZZZZZZ";
            pc <= pc + 1;
     -- MOVX @DPTR, A
        WHEN 16#F0# =>
            p0_latch <= "11111111";  -- reset the p0 latch
            WAIT UNTIL cycle_state = s3p1;
            port_req <= '1';
            WAIT UNTIL cycle_state = s4p2;
            ale_dm <= '1';
            WAIT UNTIL cycle_state = s5p1;
            p0_addr <= dpl;  -- send out the addr
            p2_addr <= dph;  -- send out the addr
            p0_ctrl <= '1';
            p2_ctrl <= '1';
            p3_ctrl(6) <= '1';
            WAIT UNTIL cycle_state = s5p2;
            ale_dm <= '0';
            WAIT UNTIL cycle_state = s6p2;
            p0_addr <= acc;  -- output the data
            WAIT UNTIL cycle_state = s1p1;
            wr_n_internal <= '0';
            WAIT UNTIL cycle_state = s4p1;
            wr_n_internal <= '1';
            port_req <= '0';   -- shouldn't have any effect until s4p2 
            p0_ctrl <= 'Z';
            p2_ctrl <= 'Z';
            p3_ctrl(6) <= 'Z';
            p0_addr <= "ZZZZZZZZ";
            p2_addr <= "ZZZZZZZZ";
            pc <= pc + 1;
     -- LJMP: Long Jump
        WHEN 16#02# => 
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for the next cycle
            pc <= pmem_s4_byte & pmem_s1_byte;
     -- RR: Rotate acc right
        WHEN 16#03# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= acc(0) & acc(7 DOWNTO 1);
     -- INC: Acc
        WHEN 16#04# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= acc + 1;
     -- INC: direct address
        WHEN 16#05# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
            set_byte_dmem(pmem_s4_byte, temp1 + 1, direct);
     -- INC: @Ri
        WHEN 16#06# TO 16#07# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            temp1 := get_reg("00"&opcode(0));         -- the indirect address
            temp2 := get_byte_dmem(temp1, indirect);  -- the data at indirect addr
            set_byte_dmem(temp1, temp2 + 1, indirect);
     -- INC: Reg
        WHEN 16#08# TO 16#0F# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            set_reg(opcode(2 DOWNTO 0), get_reg(opcode(2 DOWNTO 0)) + 1);
     -- JBC: Jump if Bit set and Clear bit
        WHEN 16#10# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for the next cycle
            IF get_bit_dmem(pmem_s4_byte, read_latch => TRUE) = '1' THEN
                temp_int := conv_signed_to_int(pmem_s1_byte);
                pc <= pc + 3 + temp_int;
            ELSE
                pc <= pc + 3;
            END IF;
            set_bit_dmem(pmem_s4_byte, '0');
     -- LCALL: long call
        WHEN 16#12# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
            temp_pc := pc + 3;
            set_byte_dmem(sp + 1, temp_pc(7 DOWNTO 0), indirect);
            set_byte_dmem(sp + 2, temp_pc(15 DOWNTO 8), indirect);
            sp <= sp + 2;  -- update stack pointer to point to the new data
            pc <= pmem_s4_byte & pmem_s1_byte;
     -- RRC: Rotate acc right through carry flag
        WHEN 16#13# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= cy & acc(7 DOWNTO 1);
            cy <= acc(0);
     -- DEC: Acc
        WHEN 16#14# => 
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= acc - 1;
     -- DEC: direct address
        WHEN 16#15# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
            set_byte_dmem(pmem_s4_byte, temp1 - 1, direct);
     -- DEC: @Ri
        WHEN 16#16# TO 16#17# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            temp1 := get_reg("00"&opcode(0));  -- indirect addr
            temp2 := get_byte_dmem(temp1, indirect);
            set_byte_dmem(temp1, temp2 - 1, indirect);
     -- DEC: Reg
        WHEN 16#18# TO 16#1F# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            set_reg(opcode(2 DOWNTO 0), get_reg(opcode(2 DOWNTO 0)) - 1);
     -- JB: Jump if bit set
        WHEN 16#20# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
            IF get_bit_dmem(pmem_s4_byte) = '1' THEN
                temp_int := conv_signed_to_int(pmem_s1_byte);
                pc <= pc + 3 + temp_int;
            ELSE
                pc <= pc + 3;
            END IF;
     -- RET: Return from subroutine
        WHEN 16#22# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
            pc(15 DOWNTO 8) <= get_byte_dmem(sp, indirect);  -- Take from the stack
            pc(7 DOWNTO 0) <= get_byte_dmem(sp-1, indirect);
            sp <= sp - 2;  -- Update stack pointer to point to the new data
     -- RL: Rotate accumulator left
        WHEN 16#23# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= acc(6 DOWNTO 0) & acc(7);
     -- ADD Acc
        WHEN 16#24# TO 16#2F# =>
            --cycle  cycles := 1;
            handle_add(opcode,'0');  -- Use a separate procedure, ignoring cy bit
     -- JNB: Jump if bit not set
        WHEN 16#30# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
            IF get_bit_dmem(pmem_s4_byte) = '0' THEN
                temp_int := conv_signed_to_int(pmem_s1_byte);
                pc <= pc + 3 + temp_int;
            ELSE
                pc <= pc + 3;
            END IF;
     -- RETI: Return from interrupt
        WHEN 16#32# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
            pc(15 DOWNTO 8) <= get_byte_dmem(sp, indirect);  -- Take from the stack
            pc(7 DOWNTO 0) <= get_byte_dmem(sp-1, indirect);
            sp <= sp - 2;  -- Update stack pointer to point to the new data
            -- ALSO NEEDS TO TURN INTERRUPTS BACK ON
            -- If the micro is at low priority, then it must go back
            -- to no priority, otherwise, it needs to go back to whatever
            -- was previous.
            IF current_priority = "01" THEN
               current_priority <= "00";
            ELSE 
               current_priority <= previous_priority; 
            END IF;
     -- RLC Acc: Rotate Left through Carry
        WHEN 16#33# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= acc(6 DOWNTO 0) & cy;
            cy <= acc(7);
     -- ADDC:  Add to the acc with carry
        WHEN 16#34# TO 16#3F# =>
            --cycle  cycles := 1;
            handle_add(opcode,cy);  -- Use a separate procedure, using cy bit
     -- JC: Jump if carry is set
        WHEN 16#40# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
            IF cy='1' THEN
                temp_int := conv_signed_to_int(pmem_s4_byte);
                pc <= pc + 2 + temp_int;
            ELSE
                pc <= pc + 2;
            END IF;
     -- ORL to data mem from acc
        WHEN 16#42# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
            set_byte_dmem(pmem_s4_byte, temp1 OR acc, direct);
     -- ORL to data mem from immediate data
        WHEN 16#43# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
            temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);  -- the data value
            set_byte_dmem(pmem_s4_byte, temp1 OR pmem_s1_byte, direct);
            pc <= pc + 3;
     -- ORL to acc
        WHEN 16#44#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -