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

📄 cop2000.vhd

📁 cpu微命令vhdl源代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY COP2000 IS

GENERIC(
  ALL_ZERO : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000000000000"; -- 十六位机
  INT_ENTER: STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000011100000";
  INT_CODE : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000010111000";
  DataWidth: integer := 16
--  ALL_ZERO : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; -- 八位机
--  INT_ENTER: STD_LOGIC_VECTOR(7 DOWNTO 0) := "11100000";
--  INT_CODE : STD_LOGIC_VECTOR(7 DOWNTO 0) := "10111000";
--  DataWidth: integer := 8
);

PORT (
  clk       : IN    STD_LOGIC;                               -- 主时钟输入
  rst       : IN    STD_LOGIC;                               -- 复位输入
  keyin     : IN    STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 键输入
  portout   : OUT   STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 端口输出

  mem_d     : INOUT STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 存贮器数据线
  mem_a     : OUT   STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 存贮器地址线
--  mem_ah    : OUT   STD_LOGIC_VECTOR(15 DOWNTO 8);           -- 八位机时,高8位地址为0

  mem_rd    : OUT   STD_LOGIC;                               -- 存贮器读信号
  mem_wr    : OUT   STD_LOGIC;                               -- 存贮器写信号

  mem_bh    : OUT   STD_LOGIC;                               -- 存贮器高8位选择信号
  mem_bl    : OUT   STD_LOGIC;                               -- 存贮器低8位选择信号
  mem_cs    : OUT   STD_LOGIC;                               -- 存贮器片选信号    

  i_req     : IN    STD_LOGIC                                -- 中断请求信号
);
END COP2000;

ARCHITECTURE behv OF COP2000 IS

-- 寄存器定义
SIGNAL A   : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL W   : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL R0  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL R1  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL R2  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL R3  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL PC  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL MAR : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL ST  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL IA  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);
SIGNAL IR  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);

-- 标志定义
SIGNAL R_CY: STD_LOGIC; -- 进位标志寄存器
SIGNAL R_Z : STD_LOGIC; -- 零标志寄存器
SIGNAL CY  : STD_LOGIC; -- 本次运算进位标志
SIGNAL Z   : STD_LOGIC; -- 本次运算零标志

-- 中断定义
SIGNAL R_REQ: STD_LOGIC; -- 中断请求寄存器
SIGNAL R_ACK: STD_LOGIC; -- 中断响应寄存器
SIGNAL ICEN : STD_LOGIC; -- 取中断指令

-- 24 位微控制信号
SIGNAL S0   : STD_LOGIC;
SIGNAL S1   : STD_LOGIC;
SIGNAL S2   : STD_LOGIC; -- 运算器功能选择
SIGNAL AEN  : STD_LOGIC; -- A写允许
SIGNAL WEN  : STD_LOGIC; -- W写允许
SIGNAL X0   : STD_LOGIC;
SIGNAL X1   : STD_LOGIC;
SIGNAL X2   : STD_LOGIC; -- 寄存器输出控制

SIGNAL FEN  : STD_LOGIC; -- 标志寄存器写允许
SIGNAL CN   : STD_LOGIC; -- 移位时是否带进位
SIGNAL RWR  : STD_LOGIC; -- 寄存器(R0..R3)写允许
SIGNAL RRD  : STD_LOGIC; -- 寄存器(R0..R3)读允许
SIGNAL STEN : STD_LOGIC; -- ST寄存器写允许
SIGNAL OUTEN: STD_LOGIC; -- OUT寄存器写允许
SIGNAL MAROE: STD_LOGIC; -- MAR寄存器地址输出允许
SIGNAL MAREN: STD_LOGIC; -- MAR寄存器写允许

SIGNAL ELP  : STD_LOGIC; -- PC寄存器写允许
SIGNAL EINT : STD_LOGIC; -- 中断结束
SIGNAL IREN : STD_LOGIC; -- IR寄存器写允许
SIGNAL EMEN : STD_LOGIC; -- EM存贮器与数据总线(D_BUS)相通控制位
SIGNAL PCOE : STD_LOGIC; -- PC寄存器地址输出允许
SIGNAL EMRD : STD_LOGIC; -- 主存贮器读允许
SIGNAL EMWR : STD_LOGIC; -- 主存贮器写允许
SIGNAL XRD  : STD_LOGIC; -- 外部I/O读允许

-- ALU运算器定义
SIGNAL T  : STD_LOGIC_VECTOR(DataWidth   DOWNTO 0);  -- 运算结果
SIGNAL D  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 直通门
SIGNAL R  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 右移门
SIGNAL L  : STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0);  -- 左移门

-- 总线定义
SIGNAL D_BUS: STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0); -- 数据总线
SIGNAL I_BUS: STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0); -- 指令总线
SIGNAL A_BUS: STD_LOGIC_VECTOR(DataWidth-1 DOWNTO 0); -- 地址总线

-- 指令周期
SIGNAL RT: STD_LOGIC_VECTOR(1 DOWNTO 0); -- 当前周期数
SIGNAL CT: STD_LOGIC_VECTOR(1 DOWNTO 0); -- 下一条指令总周期数

BEGIN

  IA <= INT_ENTER; -- 中断向量,定义为 "E0"

  -- 寄存器 A
  PROCESS(clk, rst, AEN)
  BEGIN
    IF rst = '1' THEN
      A <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF AEN = '0' THEN
        A <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 W
  PROCESS(clk, rst, WEN)
  BEGIN
    IF rst = '1' THEN
      W <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF WEN = '0' THEN
        W <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 R0
  PROCESS(clk, rst, RWR, IR)
  BEGIN
    IF rst = '1' THEN
      R0 <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF (RWR = '0') AND (IR(1) = '0') AND (IR(0) = '0') THEN
        R0 <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 R1
  PROCESS(clk, rst, RWR, IR)
  BEGIN
    IF rst = '1' THEN
      R1 <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF (RWR = '0') AND (IR(1) = '0') AND (IR(0) = '1') THEN
        R1 <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 R2
  PROCESS(clk, rst, RWR, IR)
  BEGIN
    IF rst = '1' THEN
      R2 <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF (RWR = '0') AND (IR(1) = '1') AND (IR(0) = '0') THEN
        R2 <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 R3
  PROCESS(clk, rst, RWR, IR)
  BEGIN
    IF rst = '1' THEN
      R3 <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF (RWR = '0') AND (IR(1) = '1') AND (IR(0) = '1') THEN
        R3 <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 OUT
  PROCESS(clk, rst, OUTEN)
  BEGIN
    IF rst = '1' THEN
      portout <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF OUTEN = '0' THEN
        portout <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 ST
  PROCESS(clk, rst, STEN)
  BEGIN
    IF rst = '1' THEN
      ST <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF STEN = '0' THEN
        ST <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 MAR
  PROCESS(clk, rst, MAREN)
  BEGIN
    IF rst = '1' THEN
      MAR <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF MAREN = '0' THEN
        MAR <= D_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 IR
  PROCESS(clk, rst, IREN)
  BEGIN
    IF rst = '1' THEN
      IR <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF IREN = '0' THEN
        IR <= I_BUS;
      END IF;
    END IF;
  END PROCESS;

  -- 寄存器 PC
  PROCESS(clk, rst, IR, R_CY, R_Z, ELP)
  VARIABLE LDPC: STD_LOGIC; -- 转移控制
  BEGIN
    IF rst = '1' THEN
      PC <= (OTHERS=>'0');
    ELSIF clk'EVENT AND clk = '1' THEN
      IF (ELP = '0') AND (
           ( (IR(3) = '0') AND (IR(2) = '0') AND (R_CY = '1') ) OR
           ( (IR(3) = '0') AND (IR(2) = '1') AND (R_Z  = '1') ) OR
           (IR(3) = '1')
         ) THEN LDPC := '0'; ELSE LDPC := '1';
      END IF;

      IF LDPC = '0' THEN
        PC <= D_BUS;
      ELSIF (PCOE = '0') AND (ICEN = '1') THEN  -- 在转入中断时PC不加一
        PC <= PC + 1;
      END IF;
    END IF;
  END PROCESS;

  -- 标志位
  PROCESS(clk, rst, FEN)
  BEGIN
    IF rst = '1' THEN
      R_CY <= '0';
      R_Z  <= '0';
    ELSIF clk'EVENT AND clk = '1' THEN
      IF FEN = '0' THEN
        R_CY <= CY;
        R_Z  <= Z ;
      END IF;
    END IF;
  END PROCESS;

  -- ALU 运算器,第八位为进位标志
  T <= ('0' & A)   + ('0' & W)        WHEN S2 = '0' AND S1 = '0' AND S0 = '0' ELSE
       ('0' & A)   - ('0' & W)        WHEN S2 = '0' AND S1 = '0' AND S0 = '1' ELSE
       ('0' & A)  OR ('0' & W)        WHEN S2 = '0' AND S1 = '1' AND S0 = '0' ELSE
       ('0' & A) AND ('0' & W)        WHEN S2 = '0' AND S1 = '1' AND S0 = '1' ELSE
       ('0' & A)   + ('0' & W) + R_CY WHEN S2 = '1' AND S1 = '0' AND S0 = '0' ELSE
       ('0' & A)   - ('0' & W) - R_CY WHEN S2 = '1' AND S1 = '0' AND S0 = '1' ELSE
       NOT ('0' & A)                  WHEN S2 = '1' AND S1 = '1' AND S0 = '0' ELSE
       '0' & A;

  -- 直通门
  D <= T(DataWidth-1 DOWNTO 0);

  -- 右移门
  R(DataWidth-2 DOWNTO 0) <= T(DataWidth-1 DOWNTO 1);
  R(DataWidth-1)          <= R_CY WHEN CN = '1' ELSE '0';

  -- 左移门
  L(DataWidth-1 DOWNTO 1) <= T(DataWidth-2 DOWNTO 0);
  L(0)                    <= R_CY WHEN CN = '1' ELSE '0';

  CY <= T(0)           WHEN (X1 = '0') AND (X0 = '1') AND (CN = '1') ELSE      -- 不带进位右移
        R_CY           WHEN (X1 = '0') AND (X0 = '1') AND (CN = '0') ELSE      -- 带进位右移
        T(DataWidth-1) WHEN (X1 = '1') AND (X0 = '0') AND (CN = '1') ELSE      -- 不带进位左移
        R_CY           WHEN (X1 = '1') AND (X0 = '0') AND (CN = '0') ELSE      -- 带进位左移
        T(DataWidth);                                                          -- 直通

  Z  <= '1' WHEN (R = ALL_ZERO) AND (X1 = '0') AND (X0 = '1') ELSE -- 右移门
        '1' WHEN (L = ALL_ZERO) AND (X1 = '1') AND (X0 = '0') ELSE -- 左移门
        '1' WHEN (D = ALL_ZERO) ELSE                               -- 直通门
        '0';

  -- 中断处理
  PROCESS(i_req, rst, EINT)

⌨️ 快捷键说明

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