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

📄 cpu09.vhd

📁 BurchED B5-X300 Spartan2e using XC2S300e device Top level file for 6809 compatible system on a chi
💻 VHD
📖 第 1 页 / 共 3 页
字号:
    end case;
	 end if;
  end if;
end process;


----------------------------------
--
-- op code register
--
----------------------------------

op_reg: process( clk, op_ctrl, hold, op_code, data_in )
begin
  if clk'event and clk = '0' then
    if hold= '1' then
	   op_code <= op_code;
	 else
    case op_ctrl is
	 when reset_op =>
	   op_code <= "00010010";
  	 when fetch_op =>
      op_code <= data_in;
	 when others =>
--	 when latch_op =>
	   op_code <= op_code;
    end case;
	 end if;
  end if;
end process;


----------------------------------
--
-- pre byte op code register
--
----------------------------------

pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
begin
  if clk'event and clk = '0' then
    if hold= '1' then
	   pre_code <= pre_code;
	 else
    case pre_ctrl is
	 when reset_pre =>
	   pre_code <= "00000000";
  	 when fetch_pre =>
      pre_code <= data_in;
	 when others =>
--	 when latch_pre =>
	   pre_code <= pre_code;
    end case;
	 end if;
  end if;
end process;

--------------------------------
--
-- state machine
--
--------------------------------

change_state: process( clk, rst, state, hold, next_state )
begin
  if clk'event and clk = '0' then
    if rst = '1' then
 	   state <= reset_state;
    else
	   if hold = '1' then
		  state <= state;
		else
        state <= next_state;
		end if;
	 end if;
  end if;
end process;
	-- output
	
------------------------------------
--
-- Nmi register
--
------------------------------------

nmi_reg: process( clk, nmi_ctrl, hold, nmi_ack )
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;

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

nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable )
begin
  if clk'event and clk='0' then
    if rst='1' then
	   nmi_req <= '0';
    else
	   if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') 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 process;


----------------------------------
--
-- Address output multiplexer
--
----------------------------------

addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
begin
  case addr_ctrl is
    when idle_ad =>
	   address <= "1111111111111111";
		vma     <= '0';
		rw      <= '1';
    when fetch_ad =>
	   address <= pc;
		vma     <= '1';
		rw      <= '1';
	 when read_ad =>
	   address <= ea;
		vma     <= '1';
		rw      <= '1';
    when write_ad =>
	   address <= ea;
		vma     <= '1';
		rw      <= '0';
	 when pushs_ad =>
	   address <= sp;
		vma     <= '1';
		rw      <= '0';
    when pulls_ad =>
	   address <= sp;
		vma     <= '1';
		rw      <= '1';
	 when pushu_ad =>
	   address <= up;
		vma     <= '1';
		rw      <= '0';
    when pullu_ad =>
	   address <= up;
		vma     <= '1';
		rw      <= '1';
	 when int_hi_ad =>
	   address <= "111111111111" & iv & "0";
		vma     <= '1';
		rw      <= '1';
    when int_lo_ad =>
	   address <= "111111111111" & iv & "1";
		vma     <= '1';
		rw      <= '1';
	 when others =>
	   address <= "1111111111111111";
		vma     <= '0';
		rw      <= '1';
  end case;
end process;

--------------------------------
--
-- Data Bus output
--
--------------------------------
dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc )
begin
    case dout_ctrl is
	 when md_hi_dout => -- alu output
	   data_out <= md(15 downto 8);
	 when md_lo_dout => -- alu output
	   data_out <= md(7 downto 0);
	 when acca_dout => -- accumulator a
	   data_out <= acca;
	 when accb_dout => -- accumulator b
	   data_out <= accb;
	 when ix_lo_dout => -- index reg
	   data_out <= xreg(7 downto 0);
	 when ix_hi_dout => -- index reg
	   data_out <= xreg(15 downto 8);
	 when iy_lo_dout => -- index reg
	   data_out <= yreg(7 downto 0);
	 when iy_hi_dout => -- index reg
	   data_out <= yreg(15 downto 8);
	 when sp_lo_dout => -- s stack pointer
	   data_out <= sp(7 downto 0);
	 when sp_hi_dout => -- s stack pointer
	   data_out <= sp(15 downto 8);
	 when up_lo_dout => -- u stack pointer
	   data_out <= up(7 downto 0);
	 when up_hi_dout => -- u stack pointer
	   data_out <= up(15 downto 8);
	 when cc_dout => -- condition code register
	   data_out <= cc;
	 when dp_dout => -- direct page register
	   data_out <= dp;
	 when pc_lo_dout => -- low order pc
	   data_out <= pc(7 downto 0);
	 when pc_hi_dout => -- high order pc
	   data_out <= pc(15 downto 8);
	 when others =>
	   data_out <= "00000000";
    end case;
end process;

----------------------------------
--
-- Left Mux
--
----------------------------------

left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md )
begin
  case left_ctrl is
	 when cc_left =>
	   left(15 downto 8) <= "00000000";
		left(7 downto 0)  <= cc;
	 when acca_left =>
	   left(15 downto 8) <= "00000000";
		left(7 downto 0)  <= acca;
	 when accb_left =>
	   left(15 downto 8) <= "00000000";
		left(7 downto 0)  <= accb;
	 when dp_left =>
	   left(15 downto 8) <= "00000000";
		left(7 downto 0)  <= dp;
	 when accd_left =>
	   left(15 downto 8) <= acca;
		left(7 downto 0)  <= accb;
	 when md_left =>
	   left <= md;
	 when ix_left =>
	   left <= xreg;
	 when iy_left =>
	   left <= yreg;
	 when sp_left =>
	   left <= sp;
	 when up_left =>
	   left <= up;
	 when pc_left =>
	   left <= pc;
	 when others =>
--	 when ea_left =>
	   left <= ea;
    end case;
end process;

----------------------------------
--
-- Right Mux
--
----------------------------------

right_mux: process( right_ctrl, md, acca, accb, ea )
begin
  case right_ctrl is
	 when ea_right =>
	   right <= ea;
	 when zero_right =>
	   right <= "0000000000000000";
	 when one_right =>
	   right <= "0000000000000001";
	 when two_right =>
	   right <= "0000000000000010";
	 when acca_right =>
	   if acca(7) = '0' then
	     right <= "00000000" & acca(7 downto 0);
		else
		  right <= "11111111" & acca(7 downto 0);
		end if;
	 when accb_right =>
	   if accb(7) = '0' then
	     right <= "00000000" & accb(7 downto 0);
		else
		  right <= "11111111" & accb(7 downto 0);
		end if;
	 when accd_right =>
	   right <= acca & accb;
	 when md_sign5_right =>
	   if md(4) = '0' then
	     right <= "00000000000" & md(4 downto 0);
		else
		  right <= "11111111111" & md(4 downto 0);
		end if;
	 when md_sign8_right =>
	   if md(7) = '0' then
	     right <= "00000000" & md(7 downto 0);
		else
		  right <= "11111111" & md(7 downto 0);
		end if;
	 when others =>
--	 when md_right =>
	   right <= md;
    end case;
end process;

----------------------------------
--
-- Arithmetic Logic Unit
--
----------------------------------

alu: process( alu_ctrl, cc, left, right, out_alu, cc_out )
variable valid_lo, valid_hi : boolean;
variable carry_in : std_logic;
variable daa_reg : std_logic_vector(7 downto 0);
begin

  case alu_ctrl is
  	 when alu_adc | alu_sbc |
  	      alu_rol8 | alu_ror8 =>
	   carry_in := cc(CBIT);
    when alu_asr8 =>
	   carry_in := left(7);
  	 when others =>
	   carry_in := '0';
  end case;

  valid_lo := left(3 downto 0) <= 9;
  valid_hi := left(7 downto 4) <= 9;

  if (cc(CBIT) = '0') then
    if( cc(HBIT) = '1' ) then
		if valid_hi then
		  daa_reg := "00000110";
		else
		  daa_reg := "01100110";
	   end if;
    else
		if valid_lo then
		  if valid_hi then
		    daa_reg := "00000000";
		  else
		    daa_reg := "01100000";
		  end if;
		else
	     if( left(7 downto 4) <= 8 ) then
		    daa_reg := "00000110";
		  else
			 daa_reg := "01100110";
		  end if;
		end if;
	 end if;
  else
    if ( cc(HBIT) = '1' )then
		daa_reg := "01100110";
 	 else
		if valid_lo then
		  daa_reg := "01100000";
	   else
		  daa_reg := "01100110";
		end if;
	 end i

⌨️ 快捷键说明

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