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

📄 cpu09.vhd

📁 BurchED B5-X300 Spartan2e using XC2S300e device Top level file for 6809 compatible system on a chi
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-- $Id: cpu09.vhd,v 1.4 2006/07/16 17:44:23 dilbert57 Exp $
--===========================================================================----
--
--  S Y N T H E Z I A B L E    CPU09 - 6809 compatible CPU Core
--
--  www.OpenCores.Org - September 2003
--  This core adheres to the GNU public license  
--
-- File name      : cpu09.vhd
--
-- Purpose        : 6809 CPU core
--
-- Dependencies   : ieee.Std_Logic_1164
--                  ieee.std_logic_unsigned
--
-- Uses           : None
--
-- Author         : John E. Kent
--                  dilbert57@opencores.org      
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 26 June 2003 - John Kent
-- Added extra level in state stack
-- fixed some calls to the extended addressing state
--
-- Version 0.2 - 5 Sept 2003 - John Kent
-- Fixed 16 bit indexed offset (was doing read rather than fetch)
-- Added/Fixed STY and STS instructions.
-- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
-- CMPX Loaded ACCA and ACCB - Now fixed 
--
-- Version 1.0 - 6 Sep 2003 - John Kent 
-- Initial release to Open Cores
-- reversed clock edge
--
-- Version 1.1 - 29 November 2003 John kent
--	ACCA and ACCB indexed offsets are 2's complement.
-- ALU Right Mux now sign extends ACCA & ACCB offsets
-- Absolute Indirect addressing performed a read on the
-- second byte of the address rather than a fetch
-- so it formed an incorrect address. Now fixed. 
--
-- Version 1.2 - 29 November 2003 John Kent
-- LEAX and LEAY affect the Z bit only
--	LEAS and LEAU do not affect any condition codes
-- added an extra ALU control for LEA.
--
-- Version 1.3 - 12 December 2003 John Kent
-- CWAI did not work, was missed a PUSH_ST on calling
-- the ANDCC_STATE. Thanks go to Ghassan Kraidy for
-- finding this fault.
--
-- Version 1.4 - 12 December 2003 John Kent
-- Missing cc_ctrl assignment in otherwise case of 
-- lea_state resulted in cc_ctrl being latched in
-- that state.	
-- The otherwise statement should never be reached,
-- and has been fixed simply to resolve synthesis warnings.
--
-- Version 1.5 - 17 january 2004 John kent
-- The clear instruction used "alu_ld8" to control the ALU
-- rather than "alu_clr". This mean the Carry was not being
-- cleared correctly.
--
-- Version 1.6 - 24 January 2004 John Kent
-- Fixed problems in PSHU instruction
--
-- Version 1.7 - 25 January 2004 John Kent
-- removed redundant "alu_inx" and "alu_dex'
-- Removed "test_alu" and "test_cc"
-- STD instruction did not set condition codes
-- JMP direct was not decoded properly
-- CLR direct performed an unwanted read cycle
-- Bogus "latch_md" in Page2 indexed addressing
--
-- Version 1.8 - 27 January 2004 John Kent
-- CWAI in decode1_state should increment the PC.
-- ABX is supposed to be an unsigned addition.
-- Added extra ALU function
-- ASR8 slightly changed in the ALU.
--
--	Version 1.9 - 20 August 2005
-- LSR8 is now handled in ASR8 and ROR8 case in the ALU,
-- rather than LSR16. There was a problem with single 
-- operand instructions using the MD register which is
-- sign extended on the first 8 bit fetch.
--
-- Version 1.10 - 13 September 2005
-- TFR & EXG instructions did not work for the Condition Code Register
-- An extra case has been added to the ALU for the alu_tfr control 
-- to assign the left ALU input (alu_left) to the condition code
-- outputs (cc_out). 
--
-- Version 1.11 - 16 September 2005
-- JSR ,X should not predecrement S before calculating the jump address.
-- The reason is that JSR [0,S] needs S to point to the top of the stack
-- to fetch a valid vector address. The solution is to have the addressing
-- mode microcode called before decrementing S and then decrementing S in
-- JSR_STATE. JSR_STATE in turn calls PUSH_RETURN_LO_STATE rather than
-- PUSH_RETURN_HI_STATE so that both the High & Low halves of the PC are
-- pushed on the stack. This adds one extra bus cycle, but resolves the
-- addressing conflict. I've also removed the pre-decement S in 
-- JSR EXTENDED as it also calls JSR_STATE.
--
-- Version 1.12 - 6th June 2006
-- 6809 Programming reference manual says V is not affected by ASR, LSR and ROR
-- This is different to the 6800. CLR should reset the V bit.
--
-- Version 1.13 - 7th July 2006
-- Disable NMI on reset until S Stack pointer has been loaded.
-- Added nmi_enable signal in sp_reg process and nmi_handler process.
--
-- Version 1.4 - 11th July 2006
-- 1. Added new state to RTI called rti_entire_state.
-- This state tests the CC register after it has been loaded
-- from the stack. Previously the current CC was tested which
-- was incorrect. The Entire Flag should be set before the
-- interrupt stacks the CC.
-- 2. On bogus Interrupts, int_cc_state went to rti_state,
-- which was an enumerated state, but not defined anywhere.
-- rti_state has been changed to rti_cc_state so that bogus interrupt
-- will perform an RTI after entering that state.
-- 3. Sync should generate an interrupt if the interrupt masks
-- are cleared. If the interrupt masks are set, then an interrupt
-- will cause the the PC to advance to the next instruction.
-- Note that I don't wait for an interrupt to be asserted for
-- three clock cycles.
-- 4. Added new ALU control state "alu_mul". "alu_mul" is used in
-- the Multiply instruction replacing "alu_add16". This is similar 
-- to "alu_add16" except it sets the Carry bit to B7 of the result
-- in ACCB, sets the Zero bit if the 16 bit result is zero, but
-- does not affect The Half carry (H), Negative (N) or Overflow (V)
-- flags. The logic was re-arranged so that it adds md or zero so 
-- that the Carry condition code is set on zero multiplicands.
-- 5. DAA (Decimal Adjust Accumulator) should set the Negative (N)
-- and Zero Flags. It will also affect the Overflow (V) flag although
-- the operation is undefined. It's anyones guess what DAA does to V.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity cpu09 is
	port (	
		clk:	    in  std_logic;
		rst:	    in  std_logic;
		rw:	    out std_logic;
		vma:	    out std_logic;
		address:	 out std_logic_vector(15 downto 0);
	   data_in:	 in  std_logic_vector(7 downto 0);
	   data_out: out std_logic_vector(7 downto 0);
		halt:     in  std_logic;
		hold:     in  std_logic;
		irq:      in  std_logic;
		firq:     in  std_logic;
		nmi:      in  std_logic
		);
end;

architecture CPU_ARCH of cpu09 is

  constant EBIT : integer := 7;
  constant FBIT : integer := 6;
  constant HBIT : integer := 5;
  constant IBIT : integer := 4;
  constant NBIT : integer := 3;
  constant ZBIT : integer := 2;
  constant VBIT : integer := 1;
  constant CBIT : integer := 0;

  --
  -- Interrupt vector modifiers
  --
  constant RST_VEC  : std_logic_vector(2 downto 0) := "111";
  constant NMI_VEC  : std_logic_vector(2 downto 0) := "110";
  constant SWI_VEC  : std_logic_vector(2 downto 0) := "101";
  constant IRQ_VEC  : std_logic_vector(2 downto 0) := "100";
  constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011";
  constant SWI2_VEC : std_logic_vector(2 downto 0) := "010";
  constant SWI3_VEC : std_logic_vector(2 downto 0) := "001";
  constant RESV_VEC : std_logic_vector(2 downto 0) := "000";

	type state_type is (-- Start off in Reset
	                    reset_state,
							  -- Fetch Interrupt Vectors (including reset)
							  vect_lo_state, vect_hi_state,
                       -- Fetch Instruction Cycle
                       fetch_state,
							  -- Decode Instruction Cycles
                       decode1_state, decode2_state, decode3_state,
							  -- Calculate Effective Address
						     imm16_state,
		                 indexed_state, index8_state, index16_state, index16_2_state,
							  pcrel8_state, pcrel16_state, pcrel16_2_state,
							  indexaddr_state, indexaddr2_state,
						     postincr1_state, postincr2_state,
							  indirect_state, indirect2_state, indirect3_state,
                       extended_state,
							  -- single ops
							  single_op_read_state,
						     single_op_exec_state,
	                    single_op_write_state,
							  -- Dual op states
							  dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
						     dual_op_write8_state, dual_op_write16_state,
                       -- 
						     sync_state, halt_state, error_state,
							  --
							  andcc_state, orcc_state,
							  tfr_state, exg_state, exg1_state,
							  lea_state,
							  -- Multiplication
						     mul_state, mulea_state, muld_state,
						     mul0_state, mul1_state, mul2_state, mul3_state,
						     mul4_state, mul5_state, mul6_state, mul7_state,
							  --  Branches
							  lbranch_state, sbranch_state,
							  -- Jumps, Subroutine Calls and Returns
                       jsr_state, jmp_state,
                       push_return_hi_state, push_return_lo_state,
                       pull_return_hi_state, pull_return_lo_state,
							  -- Interrupt cycles
							  int_decr_state,
							  int_entire_state,
							  int_pcl_state,  int_pch_state,
						     int_upl_state,  int_uph_state,
						     int_iyl_state,  int_iyh_state,
						     int_ixl_state,  int_ixh_state,
						     int_cc_state,
				           int_acca_state, int_accb_state,
						     int_dp_state,
						     int_cwai_state,  int_mask_state,
							  -- Return From Interrupt
						     rti_cc_state,   rti_entire_state,
							  rti_acca_state, rti_accb_state,
						     rti_dp_state,
						     rti_ixl_state,  rti_ixh_state,
						     rti_iyl_state,  rti_iyh_state,
						     rti_upl_state,  rti_uph_state,
						     rti_pcl_state,  rti_pch_state,
							  -- Push Registers using SP
							  pshs_state,
						     pshs_pcl_state,  pshs_pch_state,
						     pshs_upl_state,  pshs_uph_state,
						     pshs_iyl_state,  pshs_iyh_state,
						     pshs_ixl_state,  pshs_ixh_state,
						     pshs_dp_state,
						     pshs_acca_state, pshs_accb_state,
						     pshs_cc_state,
							  -- Pull Registers using SP
							  puls_state,
							  puls_cc_state,
							  puls_acca_state, puls_accb_state,
							  puls_dp_state,
						     puls_ixl_state,  puls_ixh_state,
						     puls_iyl_state,  puls_iyh_state,
						     puls_upl_state,  puls_uph_state,
						     puls_pcl_state,  puls_pch_state,
							  -- Push Registers using UP
							  pshu_state,
						     pshu_pcl_state,  pshu_pch_state,
						     pshu_spl_state,  pshu_sph_state,
						     pshu_iyl_state,  pshu_iyh_state,
						     pshu_ixl_state,  pshu_ixh_state,
						     pshu_dp_state,
						     pshu_acca_state, pshu_accb_state,
						     pshu_cc_state,
							  -- Pull Registers using UP
							  pulu_state,
							  pulu_cc_state,
							  pulu_acca_state, pulu_accb_state,
							  pulu_dp_state,
						     pulu_ixl_state,  pulu_ixh_state,
						     pulu_iyl_state,  pulu_iyh_state,
						     pulu_spl_state,  pulu_sph_state,
						     pulu_pcl_state,  pulu_pch_state );

	type stack_type is array(2 downto 0) of state_type;
	type st_type    is (idle_st, push_st, pull_st );
	type addr_type  is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
	type dout_type  is (cc_dout, acca_dout, accb_dout, dp_dout,
                       ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
                       up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
                       pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
   type op_type    is (reset_op, fetch_op, latch_op );
   type pre_type   is (reset_pre, fetch_pre, latch_pre );
   type cc_type    is (reset_cc, load_cc, pull_cc, latch_cc );
   type acca_type  is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca );
   type accb_type  is (reset_accb, load_accb, pull_accb, latch_accb );
   type dp_type    is (reset_dp, load_dp, pull_dp, latch_dp );
	type ix_type    is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
	type iy_type    is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy );
	type sp_type    is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
	type up_type    is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
	type pc_type    is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
   type md_type    is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
   type ea_type    is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
	type iv_type    is (reset_iv, latch_iv, nmi_iv, irq_iv, firq_iv, swi_iv, swi2_iv, swi3_iv, resv_iv);
	type nmi_type   is (reset_nmi, set_nmi, latch_nmi );
	type left_type  is (cc_left, acca_left, accb_left, dp_left,
							  ix_left, iy_left, up_left, sp_left,
                       accd_left, md_left, pc_left, ea_left );
	type right_type is (ea_right, zero_right, one_right, two_right,
                       acca_right, accb_right, accd_right,
							  md_right, md_sign5_right, md_sign8_right );
   type alu_type   is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc, 
                       alu_and, alu_ora, alu_eor,
                       alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
						     alu_lsr16, alu_lsl16,
						     alu_ror8, alu_rol8, alu_mul,
						     alu_asr8, alu_asl8, alu_lsr8,
						     alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx,
							  alu_seif, alu_sei, alu_see, alu_cle,
						     alu_ld8, alu_st8, alu_ld16, alu_st16, alu_lea, alu_nop, alu_daa );

	signal op_code:     std_logic_vector(7 downto 0);
	signal pre_code:    std_logic_vector(7 downto 0);
  	signal acca:        std_logic_vector(7 downto 0);
  	signal accb:        std_logic_vector(7 downto 0);
   signal cc:          std_logic_vector(7 downto 0);
	signal cc_out:      std_logic_vector(7 downto 0);
	signal dp:          std_logic_vector(7 downto 0);
	signal xreg:        std_logic_vector(15 downto 0);
	signal yreg:        std_logic_vector(15 downto 0);
	signal sp:          std_logic_vector(15 downto 0);
	signal up:          std_logic_vector(15 downto 0);
	signal ea:          std_logic_vector(15 downto 0);
	signal pc:	        std_logic_vector(15 downto 0);
	signal md:          std_logic_vector(15 downto 0);
   signal left:        std_logic_vector(15 downto 0);
   signal right:       std_logic_vector(15 downto 0);
	signal out_alu:     std_logic_vector(15 downto 0);
	signal iv:          std_logic_vector(2 downto 0);
	signal nmi_req:     std_logic;
	signal nmi_ack:     std_logic;
	signal nmi_enable:  std_logic;

	signal state:        state_type;
	signal next_state:   state_type;
	signal saved_state:  state_type;
	signal return_state: state_type;
	signal state_stack:  stack_type;
	signal st_ctrl:      st_type;
   signal pc_ctrl:      pc_type;
   signal ea_ctrl:      ea_type; 
   signal op_ctrl:      op_type;
	signal pre_ctrl:     pre_type;
	signal md_ctrl:      md_type;
	signal acca_ctrl:    acca_type;
	signal accb_ctrl:    accb_type;
	signal ix_ctrl:      ix_type;
	signal iy_ctrl:      iy_type;
	signal cc_ctrl:      cc_type;
	signal dp_ctrl:      dp_type;
	signal sp_ctrl:      sp_type;
	signal up_ctrl:      up_type;
	signal iv_ctrl:      iv_type;
	signal left_ctrl:    left_type;
	signal right_ctrl:   right_type;
   signal alu_ctrl:     alu_type;
   signal addr_ctrl:    addr_type;
   signal dout_ctrl:    dout_type;
   signal nmi_ctrl:     nmi_type;


begin

----------------------------------
--
-- State machine stack
--
----------------------------------
state_stack_proc: process( clk, st_ctrl, state_stack, return_state, hold )
begin
  if clk'event and clk = '0' then
    if hold= '1' then
	   state_stack(0) <= state_stack(0); 

⌨️ 快捷键说明

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