📄 pic_ctrl.vhd
字号:
zero_wen <= '1'; -- Update the ZERO flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 5) = CLRF THEN const_oen <= '1'; const_01 <= '0'; -- "0" on the B bus. alu_op <= ALUOP_PASSB; -- Copy B to the output. file_mwen <= '1'; -- Store in the register file. zero_wen <= '1'; -- Update the ZERO flag. ELSIF inst(11 DOWNTO 5) = CLRW THEN const_oen <= '1'; const_01 <= '0'; -- "0" on the B bus. alu_op <= ALUOP_PASSB; -- Copy B to the output. w_wen <= '1'; -- Store in W. zero_wen <= '1'; -- Update the ZERO flag. ELSIF inst(11 DOWNTO 6) = COMF THEN file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_COM; -- Invert. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; zero_wen <= '1'; -- Update the ZERO flag. ELSIF inst(11 DOWNTO 6) = DECF THEN file_moen <= '1'; -- FILE on the A bus. const_oen <= '1'; const_01 <= '1'; -- "1" on the B bus. alu_op <= ALUOP_SUB; -- Subtract. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; zero_wen <= '1'; -- Update the ZERO flag. ELSIF inst(11 DOWNTO 6) = DECFSZ THEN file_moen <= '1'; -- FILE on the A bus. const_oen <= '1'; const_01 <= '1'; -- "1" on the B bus. alu_op <= ALUOP_SUB; -- Perform a substraction. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; IF zero = '1' THEN inst_skip <= '1'; -- Skip next instruction if result is ZERO. END IF; ELSIF inst(11 DOWNTO 6) = INCF THEN file_moen <= '1'; -- FILE on the A bus. const_oen <= '1'; const_01 <= '1'; -- "1" on the B bus. alu_op <= ALUOP_ADD; -- Add. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; zero_wen <= '1'; -- Update the ZERO flag. ELSIF inst(11 DOWNTO 6) = INCFSZ THEN file_moen <= '1'; -- FILE on the A bus. const_oen <= '1'; const_01 <= '1'; -- "1" on the B bus. alu_op <= ALUOP_ADD; -- Add. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; IF zero = '1' THEN inst_skip <= '1'; -- Skip next instruction if result is ZERO flag. END IF; ELSIF inst(11 DOWNTO 6) = IORWF THEN w_b_oen <= '1'; -- W on the B bus. file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_OR; -- Perform a logical OR. zero_wen <= '1'; -- Update the ZERO flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 6) = MOVF THEN file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_PASSA; -- Copy A to the output. zero_wen <= '1'; -- Update the ZERO flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 5) = MOVWF THEN w_a_oen <= '1'; -- W on the A bus. alu_op <= ALUOP_PASSA; -- Copy A to the output. file_mwen <= '1'; -- Store the result in the register file. ELSIF inst(11 DOWNTO 6) = RLF THEN file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_ROL; -- Shift left. carry_wen <= '1'; -- Update the CARRY flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 6) = RRF THEN file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_ROR; -- Shift right. carry_wen <= '1'; -- Update the CARRY flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 6) = SUBWF THEN w_b_oen <= '1'; -- W on the B bus. file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_SUB; -- Perform a SUBTRACTION. carry_wen <= '1'; -- Update the CARRY flag. zero_wen <= '1'; -- Update the ZERO flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 6) = SWAPF THEN file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_SWAP; -- Swap the upper and lower nibbles. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 6) = XORWF THEN w_b_oen <= '1'; -- W on the B bus. file_moen <= '1'; -- FILE on the A bus. alu_op <= ALUOP_XOR; -- Perform a logical XOR. zero_wen <= '1'; -- Update the ZERO flag. IF dest = '0' THEN w_wen <= '1'; -- Store the result in W. ELSE file_mwen <= '1'; -- Store the result in the register file. END IF; ELSIF inst(11 DOWNTO 8) = BCF THEN file_moen <= '1'; -- FILE on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_BITCLR; -- Bit clear. file_mwen <= '1'; -- Store the result in the register file. ELSIF inst(11 DOWNTO 8) = BSF THEN file_moen <= '1'; -- FILE on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_BITSET; -- Bit set. file_mwen <= '1'; -- Store the result in the register file. ELSIF inst(11 DOWNTO 8) = BTFSC THEN file_moen <= '1'; -- FILE on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_BITTESTCLR; -- Test if the bit is clear. IF zero = '1' THEN inst_skip <= '1'; -- Skip next instruction if bit is clear. END IF; ELSIF inst(11 DOWNTO 8) = BTFSS THEN file_moen <= '1'; -- FILE on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_BITTESTSET; -- Test if the bit is set. IF zero = '1' THEN inst_skip <= '1'; -- Skip next instruction if bit is set. END IF; ELSIF inst(11 DOWNTO 8) = ANDLW THEN w_a_oen <= '1'; -- W on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_AND; -- Perform a logical AND. zero_wen <= '1'; -- Update the ZERO flag. w_wen <= '1'; -- Store the result in W. ELSIF inst(11 DOWNTO 8) = IORLW THEN w_a_oen <= '1'; -- W on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_OR; -- Perform a logical OR. zero_wen <= '1'; -- Update the ZERO flag. w_wen <= '1'; -- Store the result in W. ELSIF inst(11 DOWNTO 8) = XORLW THEN w_a_oen <= '1'; -- W on the A bus. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_XOR; -- Perform a logical XOR. zero_wen <= '1'; -- Update the ZERO flag. w_wen <= '1'; -- Store the result in W. ELSIF inst(11 DOWNTO 8) = MOVLW THEN imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_PASSB; -- Copy B to the output. w_wen <= '1'; -- Store the result in W. ELSIF inst(11 DOWNTO 9) = GOTO THEN pc_load <= '1'; inst_skip <= '1'; -- Force a NOP in the instruction register. ELSIF inst(11 DOWNTO 8) = CALL THEN imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_PASSB; -- Copy B to the output. pc_push <= '1'; -- Push the PC on the stack & load new value. inst_skip <= '1'; -- Force a NOP in the instruction register. ELSIF inst(11 DOWNTO 8) = RETLW THEN pc_pop <= '1'; -- Pop the PC from the stack. imm_oen <= '1'; -- IMMEDIATE on the B bus. alu_op <= ALUOP_PASSB; -- Copy B to the output. w_wen <= '1'; -- Store the result in W. inst_skip <= '1'; -- Force a NOP in the instruction register. ELSIF inst(11 DOWNTO 2) = TRIS THEN w_a_oen <= '1'; -- W on the A bus. alu_op <= ALUOP_PASSA; -- Copy A to the output. CASE tris_sel IS WHEN "01" => tris_a_wen <= '1'; -- Store in the appropriate TRIS register. WHEN "10" => tris_b_wen <= '1'; WHEN "11" => tris_c_wen <= '1'; WHEN OTHERS => NULL; END CASE; ELSIF inst(11 DOWNTO 0) = OPTION THEN -- Not implemented. ELSIF inst(11 DOWNTO 0) = SLEEP THEN -- Not implemented. ELSIF inst(11 DOWNTO 0) = CLRWDT THEN -- Not implemented. END IF; END PROCESS;END mixed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -