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

📄 cpu86.vhd

📁 关于8086的软核fpga代码
💻 VHD
📖 第 1 页 / 共 5 页
字号:
-------------------------------------------------------------------------------
--                                                                           --
--  CPU86 - VHDL CPU8088 IP core                                             --
--  Copyright (C) 2005-2006 HT-LAB                                           --
--                                                                           --
--  Contact/bugs : cpu86@ht-lab.com                                          --
--  Web          : http://www.ht-lab.com                                     --
--                                                                           --
--  CPU86 is released as open-source under the Aladdin Free Public License.  --
--  Contact HT-Lab for commercial applications and/or support contracts.     --
--                                                                           --
-------------------------------------------------------------------------------
--  Aladdin Free Public License                                              --
--  (Version 9, September 18, 2000)                                          --
--  Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000 Aladdin Enterprises,    --
--  Menlo Park, California, U.S.A. All rights reserved.                      --
--                                                                           --
--  NOTE: This License is not the same as any of the  GNU Licenses published --
--  by the Free Software Foundation. Its  terms are substantially  different --
--  from those of the GNU Licenses.If you are familiar with the GNU Licenses --
--  please read this license with extra care.                                --
--  Aladdin Enterprises hereby grants to anyone the permission to apply this --
--  License to their own work, as long as the entire License ( including the --
--  above notices  and this paragraph) is copied with no changes, additions, --
--  or deletions except for changing the first paragraph of Section 0 to     --
--  include a suitable description of the work to which the license is being --
--  applied and of the person or entity that holds the copyright in the work,--
--  and,if the License is being applied to a work created in a country other --
--  than the United States, replacing the first paragraph of  Section 6 with --
--  an appropriate reference to the laws of the appropriate country.         --
--                                                                           --
--  This License is not an Open Source license: among other things,it places --
--  restrictions on distribution of the Program, specifically including sale --
--  of the Program.  While  Aladdin Enterprises  respects  and  supports the --
--  philosophy of the Open Source Definition, and  shares  the desire of the --
--  GNU project to keep  licensed  software freely  redistributable in  both --
--  source  and  object form,  we feel that  Open Source  licenses  unfairly --
--  prevent  developers of useful  software  from  being compensated propor- --
--  tionately when others  profit  financially from their work. This License --
--  attempts to ensure that those who receive, redistribute, and  contribute --
--  to the licensed Program according  to the Open Source and  Free Software --
--  philosophies have the right to do so, while retaining for the developers --
--  of the Program the power to make those who  use the Program  to  enhance --
--  the value of commercial products pay for the privilege of doing so.      --
--                                                                           --
-------------------------------------------------------------------------------
--  0. Subject Matter                                                        --
--                                                                           --
--  This License applies to the intellectual property core known as "CPU86". --
--  The "Program", below, refers to such a core.The Program is a copyrighted --
--  work whose copyright is held  by Hans Tiggeler of  HT-Lab located in the --
--  United Kingdom (the "Licensor").                                         --
--                                                                           --
--  A "work based on the Program" means either the Program or any derivative --
--  work of  the  Program, as  defined in the United States Copyright Act of --
--  1976, such as a translation or a modification.                           --
--                                                                           --  
--  BY  MODIFYING OR  DISTRIBUTING  THE  PROGRAM (OR ANY  WORK  BASED ON THE --
--  PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL --
--  ITS  TERMS AND  CONDITIONS FOR COPYING,  DISTRIBUTING OR  MODIFYING  THE --
--  PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU --
--  PERMISSION TO MODIFY OR  DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. --
--  THESE ACTIONS ARE PROHIBITED BY LAW.IF YOU DO NOT ACCEPT THESE TERMS AND --
--  CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.                     --
--                                                                           --
--  Full details of the license can be found in the file "cpu86_license.txt"  --
--  which is included in the distribution zip file.                          --
-------------------------------------------------------------------------------
--  Revision History:                                                        --
--                                                                           --
--  Date:        Revision  Author                                            --
--  07 Oct 2006  0.69	   H. Tiggeler   Fixed INTA/SHL logic as reported by --
--                                       R. Kilgore                          --
--  07 Oct 2006  0.69      R. Kilgore    Fixed RD strobe during INTA         --
--  23 Nov 2006  0.68      H. Tiggeler   Fixed INTA vector read              --
--  29 Dec 2005  0.67      H. Tiggeler   First web version                   --
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
--
-- VHDL Package Header cpu.cpupack
--
-- Created:
--          by - Administrator.UNKNOWN (ACHILLES)
--          at - 17:06:15 31/12/2001
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2001.5a (Build 18)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

PACKAGE cpu86pack IS

constant RESET_CS_C : std_logic_vector(15 downto 0) := (others => '1'); -- FFFF:0000
constant RESET_IP_C : std_logic_vector(15 downto 0) := (others => '0'); 
constant RESET_ES_C : std_logic_vector(15 downto 0) := (others => '0');
constant RESET_SS_C : std_logic_vector(15 downto 0) := (others => '0');
constant RESET_DS_C : std_logic_vector(15 downto 0) := (others => '0');

constant RESET_VECTOR_C : std_logic_vector(19 downto 0) := (RESET_CS_C & X"0") + (X"0" & RESET_IP_C);

-- Multiplier Multi-Cycle path delay. Specify the number of wait states
constant MUL_MCD_C	: std_logic_vector(4 downto 0) := "00010";	-- mul MCP, check!!!!!!!11
-- Serial Divider delay
-- changed later to done signal
-- You can gain 1 clk cycle, done can be asserted 1 cycle earlier
constant DIV_MCD_C	: std_logic_vector(4 downto 0) := "10011";	-- div waitstates 19!

constant ONE			: std_logic := '1';
constant ZERO			: std_logic := '0';
constant ZEROVECTOR_C	: std_logic_vector(31 downto 0) := X"00000000";  


-- Hardware Monitor (HWMON) transmit clock divider (write only)
-- bitrate=clk/(HWM_DIV_C+1)
-- Example, clk=4.9152MHz -> 38400->HWM_DEFAULT=127
--constant HWM_DIV_C      : std_logic_vector(11 downto 0) :=  X"07F"; -- 127
-- clk=19.6608 MHz -> 38400->=511
-- clk=32.692308MHz/38400 -> 0x352(851) -> BITHIGH="11", BIT_LOW="01010011"
constant HWM_DIV_C      : std_logic_vector(11 downto 0) :=  X"352"; -- 851
constant HWMON_C		: boolean := FALSE; --FALSE/TRUE to Include Hardware Monitor
-- Hardware Monitor Base address
-- 0x0362 & 0x363 bitrate low, high
-- 0x0360 & 0x360 configreg  
constant HWM_BASEADDR_C  : std_logic_vector(15 downto 2) :="00000011011000"; -- 0x362/0x363


-- Minimum value for MAX_WS="000", this result in a 2 cycle rd/wr strobe
-- Total Read cycle is 1 cycle for address setup + 2 cycles for rd/wr strobe, thus
-- minimum bus cycle is 3 clk cycles. 
-- Minimum CPU cycle is 3 clk cycles (Fetch Opcode, decode, execute)
constant WS_WIDTH : integer := 3;		-- 2^WS_WIDTH=MAX Waitstates
constant MAX_WS   : std_logic_vector(WS_WIDTH-1 downto 0) := "000"; -- 3 clk RD/WR strobe  

constant DONTCARE : std_logic_vector(31 downto 0):=X"FFFFFFFF";


-- Status record containing some data and flag register
type instruction_type is record
  ireg		: std_logic_vector(7 downto 0);    	-- Instruction register
  xmod		: std_logic_vector(1 downto 0);    	-- mod is a reserved word
  reg		: std_logic_vector(2 downto 0);    	-- between mode and rm
  rm		: std_logic_vector(2 downto 0);
  data		: std_logic_vector(15 downto 0);
  disp		: std_logic_vector(15 downto 0);
  nb		: std_logic_vector(2 downto 0); 	-- Number of bytes
end record;


-- Status record containing some data and flag register
type status_out_type is record
  ax		: std_logic_vector(15 downto 0); 
  cx_one	: std_logic; 						-- '1' if CX=0001
  cx_zero   : std_logic;						-- '1' if CX=0000	
  cl5       : std_logic_vector(4 downto 0);		-- 5 bits shift/rotate counter
  flag		: std_logic_vector(15 downto 0); 
  div_err	: std_logic;						-- Divider overflow
end record;

--------------------------------------------------------------------------------------
-- Data Path Records
--------------------------------------------------------------------------------------
type path_in_type is record
  datareg_input	: std_logic_vector(6 downto 0);	-- dimux(3) & w & seldreg(3)
  alu_operation	: std_logic_vector(14 downto 0);-- selalua(4) & selalub(4) & aluopr(7) 
  dbus_output	: std_logic_vector(1 downto 0); -- (Odd/Even) domux setting
  segreg_input	: std_logic_vector(3 downto 0);	-- simux & selsreg 
  ea_output		: std_logic_vector(9 downto 0); -- dispmux(3) & eamux(4) & [flag]&segop(2)  
end record;

-- Write Strobe Record for Data Path
type write_in_type is record
  wrd	: std_logic;							-- Write datareg
  wralu	: std_logic;							-- Write ALU result
  wrcc	: std_logic;							-- Write Flag register
  wrs	: std_logic;							-- Write Segment register
  wrip	: std_logic;							-- Write Instruction Pointer
  wrop  : std_logic;							-- Write Segment Prefix register, Set Prefix Flag
end record; 


constant SET_OPFLAG		: std_logic:='1';	  -- Override Prefix Flag
constant CLR_OPFLAG		: std_logic:='0';

-- DIMUX    
constant DATAIN_IN		: std_logic_vector(2 downto 0) := "000"; 
constant EABUS_IN		: std_logic_vector(2 downto 0) := "001";
constant ALUBUS_IN		: std_logic_vector(2 downto 0) := "010";
constant MDBUS_IN 		: std_logic_vector(2 downto 0) := "011";
constant ES_IN  		: std_logic_vector(2 downto 0) := "100";
constant CS_IN  		: std_logic_vector(2 downto 0) := "101";
constant SS_IN  		: std_logic_vector(2 downto 0) := "110";
constant DS_IN  		: std_logic_vector(2 downto 0) := "111";

-- SIMUX   Segment Register input Mux
constant SDATAIN_IN		: std_logic_vector(1 downto 0) := "00";
constant SEABUS_IN		: std_logic_vector(1 downto 0) := "01";	 -- Effective Address
constant SALUBUS_IN   	: std_logic_vector(1 downto 0) := "10";
constant SMDBUS_IN  	: std_logic_vector(1 downto 0) := "11";

-- DOMUX   (Note bit 2=odd/even) 
constant ALUBUS_OUT		: std_logic_vector(1 downto 0) := "00";
constant CCBUS_OUT		: std_logic_vector(1 downto 0) := "01";
constant DIBUS_OUT 		: std_logic_vector(1 downto 0) := "10";
constant IPBUS_OUT 		: std_logic_vector(1 downto 0) := "11";


-- dispmux(3) & eamux(4) & poflag & segop[1:0]
-- note some bits may be dontcare!
constant NB_ES_IP		: std_logic_vector(9 downto 0) := "0000000000";		-- IPREG+NB ADDR=ES:IP 
constant NB_CS_IP		: std_logic_vector(9 downto 0) := "0000000001";
constant NB_SS_IP		: std_logic_vector(9 downto 0) := "0000000010";
constant NB_DS_IP		: std_logic_vector(9 downto 0) := "0000000011";	 

constant NB_ES_EA		: std_logic_vector(9 downto 0) := "0000001000";		-- IPREG+NB ADDR=EA
constant NB_CS_EA		: std_logic_vector(9 downto 0) := "0000001001";
constant NB_SS_EA		: std_logic_vector(9 downto 0) := "0000001010";
constant NB_DS_EA		: std_logic_vector(9 downto 0) := "0000001011";
constant DISP_ES_EA		: std_logic_vector(9 downto 0) := "0010001000";		-- IPREG+DISP ADDR=EA
constant DISP_CS_EA		: std_logic_vector(9 downto 0) := "0010001001";
constant DISP_SS_EA		: std_logic_vector(9 downto 0) := "0010001010";
constant DISP_DS_EA		: std_logic_vector(9 downto 0) := "0010001011";

constant DISP_CS_IP		: std_logic_vector(9 downto 0) := "0010000001";		-- Used for Jx instructions

constant PORT_00_DX		: std_logic_vector(6 downto 0) := "0000010";		-- EAMUX IN/OUT instruction
constant PORT_00_EA		: std_logic_vector(6 downto 0) := "0000001";		-- EAMUX Segm=00 00:IP or 00:DISP

constant NB_SS_SP		: std_logic_vector(6 downto 0) := "0000100";		-- IP=IP+NBREQ, EAMUX=SS:SP , 100, 101, 110 unused
constant LD_SS_SP		: std_logic_vector(6 downto 0) := "0100100"; 		-- Load new IP from MDBUS & out=SS:SP	

constant LD_MD_IP		: std_logic_vector(9 downto 0) := "0100000001"; 	-- Load new IP from MDBUS (e.g. RET instruction)	
constant LD_CS_IP		: std_logic_vector(9 downto 0) := "0110000001"; 	-- Load new IP (e.g. RET instruction)	
constant EA_CS_IP		: std_logic_vector(9 downto 0) := "1000001001"; 	-- Load new IP (e.g. RET instruction)	
constant IPB_CS_IP		: std_logic_vector(9 downto 0) := "1110000001"; 	-- Select IPBUS=IPREG	

constant MD_EA2_DS		: std_logic_vector(9 downto 0) := "0100011011";		-- IP<-MD, addr=DS:EA2

-- SELALUA/B or SELDREG(2 downto 0)
constant REG_AX		: std_logic_vector(3 downto 0) := "0000";   			-- W=1 Into ALUBUS A or B
constant REG_CX		: std_logic_vector(3 downto 0) := "0001";
constant REG_DX		: std_logic_vector(3 downto 0) := "0010";
constant REG_BX		: std_logic_vector(3 downto 0) := "0011";
constant REG_SP		: std_logic_vector(3 downto 0) := "0100";
constant REG_BP		: std_logic_vector(3 downto 0) := "0101";
constant REG_SI		: std_logic_vector(3 downto 0) := "0110";
constant REG_DI		: std_logic_vector(3 downto 0) := "0111";
constant REG_DATAIN	: std_logic_vector(3 downto 0) := "1000";				-- Pass data_in to ALU
constant REG_MDBUS	: std_logic_vector(3 downto 0) := "1111";				-- Pass memory bus (mdbus) to ALU

-- Only for SELALUB
constant REG_CONST1	: std_logic_vector(3 downto 0) := "1001";				-- Used for INC/DEC function, W=0/1
constant REG_CONST2	: std_logic_vector(3 downto 0) := "1010";				-- Used for POP/PUSH function W=1

-- W+SELDREG 
constant REG_AH		: std_logic_vector(3 downto 0) := "0100";   			-- W=1 SELDREG=AH


---------------------------------------------------------------
-- ALU Operations 
-- Use ireg(5 downto 3) / modrm(5 downto 3) / ireg(3 downto 0)
-- Constants for 
---------------------------------------------------------------
-- CONSTANT & ireg(7) & ireg(5 downto 3)
-- CONSTANT=000  
constant ALU_ADD	: std_logic_vector(6 downto 0) := "0000000";
constant ALU_OR 	: std_logic_vector(6 downto 0) := "0000001";		
constant ALU_ADC	: std_logic_vector(6 downto 0) := "0000010";		
constant ALU_SBB	: std_logic_vector(6 downto 0) := "0000011";
constant ALU_AND	: std_logic_vector(6 downto 0) := "0000100";
constant ALU_SUB	: std_logic_vector(6 downto 0) := "0000101";
constant ALU_XOR	: std_logic_vector(6 downto 0) := "0000110";
constant ALU_CMP	: std_logic_vector(6 downto 0) := "0000111";	    -- See also ALU_CMPS
constant ALU_TEST0	: std_logic_vector(6 downto 0) := "0001000";			 
constant ALU_TEST1	: std_logic_vector(6 downto 0) := "0001101";			 

-- Random assignment, these can be changed.
constant ALU_PUSH	: std_logic_vector(6 downto 0) := "0001001";	 	-- Used for PUSH (SUB)
constant ALU_POP	: std_logic_vector(6 downto 0) := "0001010";	 	-- Used for POP	 (ADD)

⌨️ 快捷键说明

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