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

📄 mc8051.vhd

📁 Toplevel VHDL Structural model of a system containing 8051
💻 VHD
📖 第 1 页 / 共 5 页
字号:
            pc <= "0000000000000000";
            -- Set any signals driven from this process to 'Z'
            p0_addr <= "ZZZZZZZZ";
            p2_addr <= "ZZZZZZZZ";
            p0_ctrl <= 'Z';
            p2_ctrl <= 'Z';
            rd_n_internal <= '1';
            wr_n_internal <= '1';
            WAIT UNTIL cycle_state = s4p1;
            init_done := TRUE;
            reset_pmem <= '0';
        END IF;

        WAIT UNTIL cycle_state = s2p1;

        -- When a data / addr value is written to P0, then it is
        -- reset to all 1's.  The get_pmem process cannot do that
        -- by itself, so we will implement that here.
        IF p0_reset = '1' THEN
            p0_latch <= "11111111";
            p0_reset_ack <= '1';
        END IF;

        IF p0_reset = '0' THEN
            p0_reset_ack <= '0';
        END IF;

        -- The parity bit (bit 0 of PSW) is automatically set / cleared
        -- to indicate an odd / even number of 1's in acc
        temp_int := 0;
        FOR k IN acc'RANGE LOOP
           temp_int := conv_integer(acc(k)) + temp_int;
        END LOOP;
        IF (temp_int MOD 2 = 1) THEN
            PSW(0) <= '1';
        ELSE
            PSW(0) <= '0';
        END IF;
 
        ------------INTERRUPTS------------------
        -- Check to see if an interrupt needs to be processed
        -- Only check for serial at the moment

            -- determine the new PC in order of same-level priority
            -- and set the new processor priority depending upon
            -- IP register setting
            IF ea = '1' AND (en_x0    = '1' AND int1_n_internal = '0') AND   -- ext 0
                  (current_priority = "00" OR 
                  (current_priority = "01" AND IP(0) = '1')) THEN
                   -- LCALL
                   WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
                   temp_pc := pc;
                   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
                   previous_priority <= current_priority;
                   current_priority(1) <= IP(0);
                   current_priority(0) <= '1';
                   pc <= "0000000000000011";   -- 03
                   WAIT UNTIL cycle_state = s4p1;
            ELSIF ea = '1' AND (en_t0     = '1' AND timer0_int = '1')   AND  -- timer 0
                  (current_priority = "00" OR 
                  (current_priority = "01" AND IP(1) = '1')) THEN
                   -- LCALL
                   WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
                   temp_pc := pc;
                   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
                   previous_priority <= current_priority;
                   current_priority(1) <= IP(1);
                   current_priority(0) <= '1';
                   pc <= "0000000000001011";   -- 0B
                   WAIT UNTIL cycle_state = s4p1;
            ELSIF ea = '1' AND (en_x1     = '1' AND int0_n_internal = '0') AND  -- ext 1
                  (current_priority = "00" OR 
                  (current_priority = "01" AND IP(2) = '1')) THEN
                   -- LCALL
                   WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
                   temp_pc := pc;
                   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
                   previous_priority <= current_priority;
                   current_priority(1) <= IP(2);
                   current_priority(0) <= '1';
                   pc <= "0000000000010011";   -- 13
                   WAIT UNTIL cycle_state = s4p1;
            ELSIF ea = '1' AND (en_t1     = '1' AND timer1_int = '1') AND   -- timer 1
                  (current_priority = "00" OR 
                  (current_priority = "01" AND IP(3) = '1')) THEN
                   -- LCALL
                   WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
                   temp_pc := pc;
                   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
                   previous_priority <= current_priority;
                   current_priority(1) <= IP(3);
                   current_priority(0) <= '1';
                   pc <= "0000000000011011";   -- 1B
                   WAIT UNTIL cycle_state = s4p1;
            ELSIF ea = '1' AND (en_serial = '1' AND (trans_int = '1' OR recv_int = '1')) AND
                  (current_priority = "00" OR 
                  (current_priority = "01" AND IP(4) = '1')) THEN
                   -- LCALL
                   WAIT UNTIL cycle_state = s2p1;   -- wait for next cycle
                   temp_pc := pc;
                   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
                   previous_priority <= current_priority;
                   current_priority(1) <= IP(4);
                   current_priority(0) <= '1';
                   pc <= "0000000000100011";   -- 23
                   WAIT UNTIL cycle_state = s4p1;

          ELSE -- NO INTERRUPTS

            -- Read in the next opcode (at s2p1)
            opcode := pmem_s1_byte;
 
            IF bad_data = '1' THEN
                pc_int := conv_integer(pc);
                REPORT "ERROR: COULD NOT READ OPCODE - X's read from memory.  PC is " &
                    integer'image(pc_int) & "d"
                    SEVERITY error;
            END IF;

        -- The opcode is converted to an 8bit integer
        CASE smallint(conv_integer(opcode)) IS
     -- ACALL: absolute call
        WHEN 16#11# | 16#31# | 16#51# | 16#71# | 16#91# | 16#B1# | 16#D1# | 16#F1# =>
            --cycle  cycles := 2;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for next cycle
            set_byte_dmem(sp + 1, pc(7 DOWNTO 0), indirect);
            set_byte_dmem(sp + 2, pc(15 DOWNTO 8), indirect);
            sp <= sp + 2;
            pc <= pc(15 DOWNTO 11) &  opcode(7 DOWNTO 5) & pmem_s4_byte;
     -- AJMP: Absolute Jump
        WHEN 16#01# | 16#21# | 16#41# | 16#61# | 16#81# | 16#A1# | 16#C1# | 16#E1# =>
            --cycle  cycles := 2;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for the next cycle
            pc <= pc(15 DOWNTO 11) &
                  opcode(7 DOWNTO 5) & pmem_s4_byte;
     -- NOP: No operation
        WHEN 16#00# =>      
            --cycle  cycles := 1;
            pc <= pc + 1;
     -- MOV A, Rn
        WHEN 16#E8# to 16#EF# => 
            --cycle  cycles := 1;
            pc <= pc + 1;
            acc <= get_reg(opcode(2 DOWNTO 0));
     -- MOV A, data addr
        WHEN 16#E5# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            acc <= get_byte_dmem(pmem_s4_byte, direct);
     -- MOV A, @Ri
        WHEN 16#E6# TO 16#E7# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            temp1 := get_reg("00"&opcode(0));            -- indirect src addr
            acc <= get_byte_dmem(temp1, indirect);
     -- MOV A, #data
        WHEN 16#74# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            acc <= pmem_s4_byte;
     -- MOV Rn, A
        WHEN 16#F8# TO 16#FF# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            set_reg(opcode(2 DOWNTO 0), acc);
     -- MOV Rn, data addr
        WHEN 16#A8# TO 16#AF# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait to next cycle
            pc <= pc + 2;
            temp1 := get_byte_dmem(pmem_s4_byte, direct);      -- src data
            set_reg(opcode(2 DOWNTO 0), temp1);         -- set to reg.
     -- MOV Rn, #data
        WHEN 16#78# TO 16#7F# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            set_reg(opcode(2 DOWNTO 0), pmem_s4_byte);
     -- MOV data addr, A
        WHEN 16#F5# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            set_byte_dmem(pmem_s4_byte, acc, direct);
     -- MOV data addr, Rn
        WHEN 16#88# TO 16#8F# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait to next cycle
            pc <= pc + 2;
            temp1 := get_reg(opcode(2 DOWNTO 0));       -- src data from Rn
            set_byte_dmem(pmem_s4_byte, temp1, direct);
     -- MOV direct, direct
        WHEN 16#85# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for next cycle
            pc <= pc + 3;
            temp1 := get_byte_dmem(pmem_s4_byte, direct);  -- the data at source addr
            set_byte_dmem(pmem_s1_byte, temp1, direct);    -- set to dest addr
     -- MOV direct, @Ri
        WHEN 16#86# TO 16#87# => 
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
            pc <= pc + 2;
            temp1 := get_reg("00" & opcode(0));       -- indirect src addr
            temp2 := get_byte_dmem(temp1, indirect);  -- src data at addr @Ri
            set_byte_dmem(pmem_s4_byte, temp2, direct);
     -- MOV direct, #data
        WHEN 16#75# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
            pc <= pc + 3;
            set_byte_dmem(pmem_s4_byte, pmem_s1_byte, direct);
     -- MOV @Ri, A
        WHEN 16#F6# TO 16#F7# =>
            --cycle  cycles := 1;
            pc <= pc + 1;
            temp1 := get_reg("00"&opcode(0));   -- indirect dest addr
            set_byte_dmem(temp1, acc, indirect);
     -- MOV @Ri, direct
        WHEN 16#A6# TO 16#A7# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for the next cycle
            pc <= pc + 2;
            temp1 := get_reg("00"&opcode(0));         -- the indirect dest addr
            temp2 := get_byte_dmem(pmem_s4_byte, direct); -- the src byte
            set_byte_dmem(temp1, temp2, indirect);
     -- MOV @Ri, #data
        WHEN 16#76# TO 16#77# =>
            --cycle  cycles := 1;
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;        -- wait for data
            temp1 := get_reg("00"&opcode(0));     -- the indirect dest addr
            set_byte_dmem(temp1, pmem_s4_byte, indirect);
     -- MOV DPTR, #data16
        WHEN 16#90# =>
            --cycle  cycles := 2;
            WAIT UNTIL cycle_state = s2p1;  -- wait for next cycle
            pc <= pc + 3;
            dph <= pmem_s4_byte;
            dpl <= pmem_s1_byte;
     -- MOV bit addr, C
        WHEN 16#92# =>
            --cycle  cycles := 2
            WAIT UNTIL cycle_state = s2p1;  -- wait for next cycle
            pc <= pc + 2;
            set_bit_dmem(pmem_s4_byte,cy); 
     -- MOV C, bit addr
        WHEN 16#A2# =>
            --cycle  cycles := 1
            pc <= pc + 2;
            WAIT UNTIL cycle_state = s5p1;
            cy <= get_bit_dmem(pmem_s4_byte);
     -- MOVC A, @A + DPTR
        WHEN 16#93# =>
            --cycle  cycles := 2;
            temp1 := PC(15 DOWNTO 8);
            temp2 := PC(7 DOWNTO 0);
            -- Set the program counter, so that the addr will go out at s4p2,
            -- and the new data come in at s1p1 of next cycle
            pc(7 DOWNTO 0) <= acc + dpl;
            IF conv_integer(acc)+conv_integer(dpl) > 255 THEN
                pc(15 DOWNTO 8) <= dph + 1;
            ELSE
                pc(15 DOWNTO 8) <= dph;
            END IF;
            WAIT UNTIL cycle_state = s2p1;
            acc <= pmem_s1_byte;
            pc <= temp1 & temp2 + 1;
     -- MOVC A, @A + PC
        WHEN 16#83# =>
            --cycle  cycles := 2;
            temp1 := PC(15 DOWNTO 8);
            temp2 := PC(7 DOWNTO 0);
            -- Set the program counter, so that the addr will go out at s4p2,

⌨️ 快捷键说明

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