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

📄 dataregfile_rtl.vhd

📁 Intel微处理器8088的VHDL实现
💻 VHD
字号:
-------------------------------------------------------------------------------
--  CPU86 - VHDL CPU8088 IP core                                             --
--  Copyright (C) 2005-2008 HT-LAB                                           --
--                                                                           --
--  Contact/bugs : http://www.ht-lab.com/misc/feedback.html                  --
--  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.     --
--                                                                           --
--  Full details of the license can be found in the file "cpu86_license.txt" --
--  which is included in the distribution zip file.                          --
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;

USE work.cpu86pack.ALL;

ENTITY dataregfile IS
   PORT( 
      dibus      : IN     std_logic_vector (15 DOWNTO 0);
      selalua    : IN     std_logic_vector (3 DOWNTO 0);
      selalub    : IN     std_logic_vector (3 DOWNTO 0);
      seldreg    : IN     std_logic_vector (2 DOWNTO 0);
      w          : IN     std_logic;
      wrd        : IN     std_logic;
      alu_inbusa : OUT    std_logic_vector (15 DOWNTO 0);
      alu_inbusb : OUT    std_logic_vector (15 DOWNTO 0);
      bp_s       : OUT    std_logic_vector (15 DOWNTO 0);
      bx_s       : OUT    std_logic_vector (15 DOWNTO 0);
      di_s       : OUT    std_logic_vector (15 DOWNTO 0);
      si_s       : OUT    std_logic_vector (15 DOWNTO 0);
      reset      : IN     std_logic;
      clk        : IN     std_logic;
      data_in    : IN     std_logic_vector (15 DOWNTO 0);
      mdbus_in   : IN     std_logic_vector (15 DOWNTO 0);
      sp_s       : OUT    std_logic_vector (15 DOWNTO 0);
      ax_s       : OUT    std_logic_vector (15 DOWNTO 0);
      cx_s       : OUT    std_logic_vector (15 DOWNTO 0);
      dx_s       : OUT    std_logic_vector (15 DOWNTO 0)
   );

-- Declarations

END dataregfile ;

architecture rtl of dataregfile is
 
signal  axreg_s : std_logic_vector(15 downto 0);
signal  cxreg_s : std_logic_vector(15 downto 0);
signal  dxreg_s : std_logic_vector(15 downto 0);
signal  bxreg_s : std_logic_vector(15 downto 0);
signal  spreg_s : std_logic_vector(15 downto 0);
signal  bpreg_s : std_logic_vector(15 downto 0);
signal  sireg_s : std_logic_vector(15 downto 0);
signal  direg_s : std_logic_vector(15 downto 0);

signal  seldreg_s   : std_logic_vector(3 downto 0); -- w & seldreg
signal  selalua_s   : std_logic_vector(4 downto 0); -- w & dibus & selalua
signal  selalub_s   : std_logic_vector(4 downto 0); -- w & dibus & selalub

signal  alu_inbusb_s: std_logic_vector (15 downto 0);

begin

----------------------------------------------------------------------------
-- 8 registers of 16 bits each
----------------------------------------------------------------------------
  seldreg_s <= w & seldreg;

  process (clk,reset)
    begin
        if reset='1' then
            axreg_s <= (others => '0');
            cxreg_s <= (others => '0');
            dxreg_s <= (others => '0');
            bxreg_s <= (others => '0');
            spreg_s <= (others => '0');
            bpreg_s <= (others => '0');
            sireg_s <= (others => '0');
            direg_s <= (others => '0');
        elsif rising_edge(clk) then        
            if (wrd='1') then     
                case seldreg_s is 
                    when "0000" => axreg_s(7 downto 0)  <= dibus(7 downto 0);     -- w=0 8 bits write
                    when "0001" => cxreg_s(7 downto 0)  <= dibus(7 downto 0);
                    when "0010" => dxreg_s(7 downto 0)  <= dibus(7 downto 0);
                    when "0011" => bxreg_s(7 downto 0)  <= dibus(7 downto 0);
                    when "0100" => axreg_s(15 downto 8) <= dibus(7 downto 0);
                    when "0101" => cxreg_s(15 downto 8) <= dibus(7 downto 0);
                    when "0110" => dxreg_s(15 downto 8) <= dibus(7 downto 0);
                    when "0111" => bxreg_s(15 downto 8) <= dibus(7 downto 0); 

                    when "1000" => axreg_s <= dibus;      -- w=1 16 bits write
                    when "1001" => cxreg_s <= dibus;
                    when "1010" => dxreg_s <= dibus;
                    when "1011" => bxreg_s <= dibus;
                    when "1100" => spreg_s <= dibus;
                    when "1101" => bpreg_s <= dibus;
                    when "1110" => sireg_s <= dibus;
                    when others => direg_s <= dibus; 
                end case;                                                                                                                     
            end if;
        end if;   
    end process;  

----------------------------------------------------------------------------
-- Output Port A
-- selalua="x1xxx" selects mdbus (use 11111)
----------------------------------------------------------------------------  
  selalua_s <= w & selalua;  

  process (selalua_s,axreg_s,cxreg_s,dxreg_s,bxreg_s,spreg_s,bpreg_s,sireg_s,direg_s,mdbus_in)
    begin
      case selalua_s is                  
            when "00000"    => alu_inbusa <= X"00" & axreg_s(7 downto 0);    -- Select 8 bits MSB=0
            when "00001"    => alu_inbusa <= X"00" & cxreg_s(7 downto 0);
            when "00010"    => alu_inbusa <= X"00" & dxreg_s(7 downto 0);
            when "00011"    => alu_inbusa <= X"00" & bxreg_s(7 downto 0);
            when "00100"    => alu_inbusa <= X"00" & axreg_s(15 downto 8);   -- AH
            when "00101"    => alu_inbusa <= X"00" & cxreg_s(15 downto 8);   -- CH
            when "00110"    => alu_inbusa <= X"00" & dxreg_s(15 downto 8);   -- DH
            when "00111"    => alu_inbusa <= X"00" & bxreg_s(15 downto 8);   -- BH
            when "10000"    => alu_inbusa <= axreg_s;
            when "10001"    => alu_inbusa <= cxreg_s;
            when "10010"    => alu_inbusa <= dxreg_s;
            when "10011"    => alu_inbusa <= bxreg_s;
            when "10100"    => alu_inbusa <= spreg_s;
            when "10101"    => alu_inbusa <= bpreg_s;
            when "10110"    => alu_inbusa <= sireg_s;
            when "10111"    => alu_inbusa <= direg_s; 
            when others     => alu_inbusa <= mdbus_in(15 downto 0);     -- Pass through
      end case;     
  end process;

----------------------------------------------------------------------------
-- Output Port B                                       data_in
-- Modified to let Serial Monitor control the mux
-- selalub="x1xxx" selects mdbus (use 11111)
-- selalub="01xxx" selects data_in byte
-- selalub="11xxx" selects data_in word
----------------------------------------------------------------------------  
  selalub_s <= w & selalub;
  --selalub_s <= (w & selalub) when enshift='0' else ("10" & sercnt_s(6 downto 4));

  process (selalub_s,axreg_s,cxreg_s,dxreg_s,bxreg_s,spreg_s,bpreg_s,sireg_s,direg_s,mdbus_in,data_in)
    begin
      case selalub_s is                  
            when "00000"    => alu_inbusb_s <= X"00" & axreg_s(7 downto 0);
            when "00001"    => alu_inbusb_s <= X"00" & cxreg_s(7 downto 0);
            when "00010"    => alu_inbusb_s <= X"00" & dxreg_s(7 downto 0);
            when "00011"    => alu_inbusb_s <= X"00" & bxreg_s(7 downto 0);
            when "00100"    => alu_inbusb_s <= X"00" & axreg_s(15 downto 8);
            when "00101"    => alu_inbusb_s <= X"00" & cxreg_s(15 downto 8);
            when "00110"    => alu_inbusb_s <= X"00" & dxreg_s(15 downto 8);
            when "00111"    => alu_inbusb_s <= X"00" & bxreg_s(15 downto 8); 
            when "10000"    => alu_inbusb_s <= axreg_s;
            when "10001"    => alu_inbusb_s <= cxreg_s;
            when "10010"    => alu_inbusb_s <= dxreg_s;
            when "10011"    => alu_inbusb_s <= bxreg_s;
            when "10100"    => alu_inbusb_s <= spreg_s;
            when "10101"    => alu_inbusb_s <= bpreg_s;
            when "10110"    => alu_inbusb_s <= sireg_s;
            when "10111"    => alu_inbusb_s <= direg_s;
            when "01000"    => alu_inbusb_s <= X"00"& data_in(7 downto 0);  -- Pass data_in to ALU (port B only) 
            when "11000"    => alu_inbusb_s <= data_in;                     -- Pass data_in to ALU (port B only)
            when "01001"    => alu_inbusb_s <= X"0001";     -- Used for INC/DEC byte function
            when "11001"    => alu_inbusb_s <= X"0001";     -- Used for INC/DEC word function
            when "11010"    => alu_inbusb_s <= X"0002";     -- Used for POP/PUSH function
            when others     => alu_inbusb_s <= mdbus_in(15 downto 0);   -- Pass through 
      end case;     
  end process;

  alu_inbusb <= alu_inbusb_s;      -- connect to entity

  bx_s <= bxreg_s;  -- Used for EA calculation
  bp_s <= bpreg_s;
  si_s <= sireg_s;
  di_s <= direg_s;

  sp_s <= spreg_s; -- Used for eamux, PUSH and POP instructions

  ax_s <= axreg_s; -- Used for datapath FSM
  cx_s <= cxreg_s;
  dx_s <= dxreg_s; -- Used for IN/OUT instructions & Divider

end rtl;

⌨️ 快捷键说明

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