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

📄 mc8051.vhd

📁 8051的VHDL IP核
💻 VHD
📖 第 1 页 / 共 5 页
字号:
         IF rst = '1' THEN            init_done := FALSE;            WAIT UNTIL rst = '0';        END IF;        -- set init values        IF NOT init_done THEN            set_sfr;            reset_pmem <= '1';            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

⌨️ 快捷键说明

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