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

📄 cpu01.vhd

📁 一个简单的cpu的VHDL源码描述
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    --
    case alu_ctrl is
  	 when alu_sei =>
		cc_out(IBIT) <= '1';               -- set interrupt mask
  	 when alu_cli =>
		cc_out(IBIT) <= '0';               -- clear interrupt mask
	 when alu_tap =>
      cc_out(IBIT) <= left(IBIT);
  	 when others =>
		cc_out(IBIT) <= cc(IBIT);             -- interrupt mask
    end case;

    --
    -- Half Carry flag
	 --
    case alu_ctrl is
  	 when alu_add8 | alu_adc =>
      cc_out(HBIT) <= (left(3) and right(3)) or
                     (right(3) and not out_alu(3)) or 
                      (left(3) and not out_alu(3));
    when alu_tap =>
      cc_out(HBIT) <= left(HBIT);
  	 when others =>
		cc_out(HBIT) <= cc(HBIT);
    end case;

    --
    -- Overflow flag
	 --
    case alu_ctrl is
  	 when alu_add8 | alu_adc =>
      cc_out(VBIT) <= (left(7)  and      right(7)  and (not out_alu(7))) or
                 ((not left(7)) and (not right(7)) and      out_alu(7));
	 when alu_sub8 | alu_sbc =>
      cc_out(VBIT) <= (left(7)  and (not right(7)) and (not out_alu(7))) or
                 ((not left(7)) and      right(7)  and      out_alu(7));
  	 when alu_add16 =>
      cc_out(VBIT) <= (left(15)  and      right(15)  and (not out_alu(15))) or
                 ((not left(15)) and (not right(15)) and      out_alu(15));
	 when alu_sub16  =>
      cc_out(VBIT) <= (left(15)  and (not right(15)) and (not out_alu(15))) or
                 ((not left(15)) and      right(15) and       out_alu(15));
	 when alu_inc =>
	   cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
		                      left(3)  and left(2) and left(1) and left(0));
	 when alu_dec | alu_neg =>
	   cc_out(VBIT) <= (left(7)  and (not left(6)) and (not left(5)) and (not left(4)) and
		            (not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
	 when alu_asr8 =>
	   cc_out(VBIT) <= left(0) xor left(7);
	 when alu_lsr8 | alu_lsr16 =>
	   cc_out(VBIT) <= left(0);
	 when alu_ror8 =>
      cc_out(VBIT) <= left(0) xor cc(CBIT);
    when alu_lsl16 =>
      cc_out(VBIT) <= left(15) xor left(14);
	 when alu_rol8 | alu_asl8  =>
      cc_out(VBIT) <= left(7) xor left(6);
    when alu_tap =>
      cc_out(VBIT) <= left(VBIT);
	 when alu_and | alu_ora | alu_eor | alu_com |
	      alu_st8 | alu_st16 | alu_ld8 | alu_ld16 |
		   alu_clv =>
      cc_out(VBIT) <= '0';
    when alu_sev =>
	   cc_out(VBIT) <= '1';
  	 when others =>
		cc_out(VBIT) <= cc(VBIT);
    end case;

	 case alu_ctrl is
	 when alu_tap =>
      cc_out(XBIT) <= cc(XBIT) and left(XBIT);
      cc_out(SBIT) <= left(SBIT);
	 when others =>
      cc_out(XBIT) <= cc(XBIT) and left(XBIT);
	   cc_out(SBIT) <= cc(SBIT);
	 end case;

	 test_alu <= out_alu;
	 test_cc  <= cc_out;
end process;

------------------------------------
--
-- Detect Edge of NMI interrupt
--
------------------------------------

nmi_handler : process( clk, rst, nmi, nmi_ack )
begin
  if clk'event and clk = '0' then
    if hold = '1' then
	   nmi_req <= nmi_req;
	 else
    if rst='1' then
	   nmi_req <= '0';
    else
	   if (nmi='1') and (nmi_ack='0') then
	     nmi_req <= '1';
	   else
		  if (nmi='0') and (nmi_ack='1') then
	       nmi_req <= '0';
	     else
	       nmi_req <= nmi_req;
		  end if;
		end if;
	 end if;
	 end if;
  end if;
end process;

------------------------------------
--
-- Nmi mux
--
------------------------------------

nmi_mux: process( clk, nmi_ctrl, nmi_ack, hold )
begin
  if clk'event and clk = '0' then
    if hold = '1' then
	   nmi_ack <= nmi_ack;
	 else
    case nmi_ctrl is
	 when set_nmi =>
      nmi_ack <= '1';
	 when reset_nmi =>
	   nmi_ack <= '0';
	 when others =>
--  when latch_nmi =>
	   nmi_ack <= nmi_ack;
	 end case;
	 end if;
  end if;
end process;

------------------------------------
--
-- state sequencer
--
------------------------------------
process( state, op_code, cc, ea,
         irq, irq_icf, irq_ocf, irq_tof, irq_sci,
		   nmi_req, nmi_ack, hold, halt )
  	begin
		  case state is
          when reset_state =>        --  released from reset
			    -- reset the registers
             op_ctrl    <= reset_op;
				 acca_ctrl  <= reset_acca;
				 accb_ctrl  <= reset_accb;
				 ix_ctrl    <= reset_ix;
		       sp_ctrl    <= reset_sp;
		       pc_ctrl    <= reset_pc;
	 		    ea_ctrl    <= reset_ea;
				 md_ctrl    <= reset_md;
				 iv_ctrl    <= reset_iv;
				 nmi_ctrl   <= reset_nmi;
				 -- idle the ALU
             left_ctrl  <= acca_left;
				 right_ctrl <= zero_right;
				 alu_ctrl   <= alu_nop;
             cc_ctrl    <= reset_cc;
				 -- idle the bus
				 dout_ctrl  <= md_lo_dout;
             addr_ctrl  <= idle_ad;
	 	       next_state <= vect_hi_state;

			 --
			 -- Jump via interrupt vector
			 -- iv holds interrupt type
			 -- fetch PC hi from vector location
			 --
          when vect_hi_state =>
			    -- default the registers
             op_ctrl    <= latch_op;
				 nmi_ctrl   <= latch_nmi;
             acca_ctrl  <= latch_acca;
             accb_ctrl  <= latch_accb;
             ix_ctrl    <= latch_ix;
             sp_ctrl    <= latch_sp;
             md_ctrl    <= latch_md;
             ea_ctrl    <= latch_ea;
             iv_ctrl    <= latch_iv;
				 -- idle the ALU
             left_ctrl  <= acca_left;
             right_ctrl <= zero_right;
             alu_ctrl   <= alu_nop;
             cc_ctrl    <= latch_cc;
				 -- fetch pc low interrupt vector
		       pc_ctrl    <= pull_hi_pc;
             addr_ctrl  <= int_hi_ad;
             dout_ctrl  <= pc_hi_dout;
	 	       next_state <= vect_lo_state;
			 --
			 -- jump via interrupt vector
			 -- iv holds vector type
			 -- fetch PC lo from vector location
			 --
          when vect_lo_state =>
			    -- default the registers
             op_ctrl    <= latch_op;
				 nmi_ctrl   <= latch_nmi;
             acca_ctrl  <= latch_acca;
             accb_ctrl  <= latch_accb;
             ix_ctrl    <= latch_ix;
             sp_ctrl    <= latch_sp;
             md_ctrl    <= latch_md;
             ea_ctrl    <= latch_ea;
             iv_ctrl    <= latch_iv;
				 -- idle the ALU
             left_ctrl  <= acca_left;
             right_ctrl <= zero_right;
             alu_ctrl   <= alu_nop;
             cc_ctrl    <= latch_cc;
				 -- fetch the vector low byte
		       pc_ctrl    <= pull_lo_pc;
             addr_ctrl  <= int_lo_ad;
             dout_ctrl  <= pc_lo_dout;
	 	       next_state <= fetch_state;

			 --
			 -- Here to fetch an instruction
			 -- PC points to opcode
			 -- Should service interrupt requests at this point
			 -- either from the timer
			 -- or from the external input.
			 --
          when fetch_state =>
			      case op_code(7 downto 4) is
				   when "0000" |
	                 "0001" |
	                 "0010" |  -- branch conditional
	                 "0011" |
	                 "0100" |  -- acca single op
	                 "0101" |  -- accb single op
	                 "0110" |  -- indexed single op
	                 "0111" => -- extended single op
					  -- idle ALU
                 left_ctrl  <= acca_left;
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
					  cc_ctrl    <= latch_cc;
                 acca_ctrl  <= latch_acca;
                 accb_ctrl  <= latch_accb;
                 ix_ctrl    <= latch_ix;
                 sp_ctrl    <= latch_sp;

	            when "1000" | -- acca immediate
	                 "1001" | -- acca direct
	                 "1010" | -- acca indexed
                    "1011" => -- acca extended
				     case op_code(3 downto 0) is
					  when "0000" => -- suba
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_sub8;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0001" => -- cmpa
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_sub8;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0010" => -- sbca
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_sbc;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0011" => -- subd
					    left_ctrl   <= accd_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_sub16;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_hi_acca;
						 accb_ctrl   <= load_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0100" => -- anda
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_and;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0101" => -- bita
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_and;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0110" => -- ldaa
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_ld8;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "0111" => -- staa
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_st8;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1000" => -- eora
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_eor;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1001" => -- adca
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_adc;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1010" => -- oraa
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_ora;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1011" => -- adda
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_add8;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= load_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1100" => -- cpx
					    left_ctrl   <= ix_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_sub16;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1101" => -- bsr / jsr
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_nop;
						 cc_ctrl     <= latch_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when "1110" => -- lds
					    left_ctrl   <= sp_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_ld16;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
						 sp_ctrl     <= load_sp;
					  when "1111" => -- sts
					    left_ctrl   <= sp_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_st16;
						 cc_ctrl     <= load_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  when others =>
					    left_ctrl   <= acca_left;
					    right_ctrl  <= md_right;
					    alu_ctrl    <= alu_nop;
						 cc_ctrl     <= latch_cc;
					    acca_ctrl   <= latch_acca;
                   accb_ctrl   <= latch_accb;
                   ix_ctrl     <= latch_ix;
                   sp_ctrl     <= latch_sp;
					  end case;
	            when "1100" | -- accb immediate
	                 "1101" | -- accb direct
	                 "1110" | -- accb indexed
                    "1111" => -- accb extended

⌨️ 快捷键说明

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