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

📄 control.vhd

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 VHD
📖 第 1 页 / 共 2 页
字号:
----------------------------------------------------------------------- TITLE: Controller / Opcode Decoder-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)-- DATE CREATED: 2/8/01-- FILENAME: control.vhd-- PROJECT: Plasma CPU core-- COPYRIGHT: Software placed into the public domain by the author.--    Software 'as is' without warranty.  Author liable for nothing.-- NOTE:  MIPS(tm) is a registered trademark of MIPS Technologies.--    MIPS Technologies does not endorse and is not associated with--    this project.-- DESCRIPTION:--    Controls the CPU by decoding the opcode and generating control --    signals to the rest of the CPU.--    This entity decodes the MIPS(tm) opcode into a --    Very-Long-Word-Instruction.  --    The 32-bit opcode is converted to a --       6+6+6+16+4+2+4+3+2+2+3+2+4 = 60 bit VLWI opcode.--    Based on information found in:--       "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich--       and "The Designer's Guide to VHDL" by Peter J. Ashenden---------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;use work.mlite_pack.all;entity control is   port(opcode       : in  std_logic_vector(31 downto 0);        intr_signal  : in  std_logic;        rs_index     : out std_logic_vector(5 downto 0);        rt_index     : out std_logic_vector(5 downto 0);        rd_index     : out std_logic_vector(5 downto 0);        imm_out      : out std_logic_vector(15 downto 0);        alu_func     : out alu_function_type;        shift_func   : out shift_function_type;        mult_func    : out mult_function_type;        branch_func  : out branch_function_type;        a_source_out : out a_source_type;        b_source_out : out b_source_type;        c_source_out : out c_source_type;        pc_source_out: out pc_source_type;        mem_source_out:out mem_source_type;        exception_out: out std_logic);end; --entity controlarchitecture logic of control isbegincontrol_proc: process(opcode, intr_signal)    variable op, func       : std_logic_vector(5 downto 0);   variable rs, rt, rd     : std_logic_vector(5 downto 0);   variable rtx            : std_logic_vector(4 downto 0);   variable imm            : std_logic_vector(15 downto 0);   variable alu_function   : alu_function_type;   variable shift_function : shift_function_type;   variable mult_function  : mult_function_type;   variable a_source       : a_source_type;   variable b_source       : b_source_type;   variable c_source       : c_source_type;   variable pc_source      : pc_source_type;   variable branch_function: branch_function_type;   variable mem_source     : mem_source_type;   variable is_syscall     : std_logic;begin   alu_function := ALU_NOTHING;   shift_function := SHIFT_NOTHING;   mult_function := MULT_NOTHING;   a_source := A_FROM_REG_SOURCE;   b_source := B_FROM_REG_TARGET;   c_source := C_FROM_NULL;   pc_source := FROM_INC4;   branch_function := BRANCH_EQ;   mem_source := MEM_FETCH;   op := opcode(31 downto 26);   rs := '0' & opcode(25 downto 21);   rt := '0' & opcode(20 downto 16);   rtx := opcode(20 downto 16);   rd := '0' & opcode(15 downto 11);   func := opcode(5 downto 0);   imm := opcode(15 downto 0);   is_syscall := '0';   case op is   when "000000" =>   --SPECIAL      case func is      when "000000" =>   --SLL   r[rd]=r[rt]<<re;         a_source := A_FROM_IMM10_6;         c_source := C_FROM_SHIFT;         shift_function := SHIFT_LEFT_UNSIGNED;      when "000010" =>   --SRL   r[rd]=u[rt]>>re;         a_source := A_FROM_IMM10_6;         c_source := C_FROM_shift;         shift_function := SHIFT_RIGHT_UNSIGNED;      when "000011" =>   --SRA   r[rd]=r[rt]>>re;         a_source := A_FROM_IMM10_6;         c_source := C_FROM_SHIFT;         shift_function := SHIFT_RIGHT_SIGNED;      when "000100" =>   --SLLV  r[rd]=r[rt]<<r[rs];         c_source := C_FROM_SHIFT;         shift_function := SHIFT_LEFT_UNSIGNED;      when "000110" =>   --SRLV  r[rd]=u[rt]>>r[rs];         c_source := C_FROM_SHIFT;         shift_function := SHIFT_RIGHT_UNSIGNED;      when "000111" =>   --SRAV  r[rd]=r[rt]>>r[rs];         c_source := C_FROM_SHIFT;         shift_function := SHIFT_RIGHT_SIGNED;      when "001000" =>   --JR    s->pc_next=r[rs];         pc_source := FROM_BRANCH;         alu_function := ALU_ADD;         branch_function := BRANCH_YES;      when "001001" =>   --JALR  r[rd]=s->pc_next; s->pc_next=r[rs];         c_source := C_FROM_PC_PLUS4;         pc_source := FROM_BRANCH;         alu_function := ALU_ADD;         branch_function := BRANCH_YES;      when "001010" =>   --MOVZ  if(!r[rt]) r[rd]=r[rs]; /*IV*/--         c_source := C_FROM_REG_SOURCE_EQZ;      when "001011" =>   --MOVN  if(r[rt]) r[rd]=r[rs];  /*IV*/--         c_source := FROM_REG_SOURCE_NEZ;      when "001100" =>   --SYSCALL         is_syscall := '1';      when "001101" =>   --BREAK s->wakeup=1;         is_syscall := '1';      when "001111" =>   --SYNC  s->wakeup=1;      when "010000" =>   --MFHI  r[rd]=s->hi;         c_source := C_FROM_MULT;         mult_function := MULT_READ_HI;      when "010001" =>   --FTHI  s->hi=r[rs];         mult_function := MULT_WRITE_HI;      when "010010" =>   --MFLO  r[rd]=s->lo;         c_source := C_FROM_MULT;         mult_function := MULT_READ_LO;      when "010011" =>   --MTLO  s->lo=r[rs];         mult_function := MULT_WRITE_LO;      when "011000" =>   --MULT  s->lo=r[rs]*r[rt]; s->hi=0;         mult_function := MULT_SIGNED_MULT;      when "011001" =>   --MULTU s->lo=r[rs]*r[rt]; s->hi=0;         mult_function := MULT_MULT;      when "011010" =>   --DIV   s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];         mult_function := MULT_SIGNED_DIVIDE;      when "011011" =>   --DIVU  s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];         mult_function := MULT_DIVIDE;      when "100000" =>   --ADD   r[rd]=r[rs]+r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_ADD;      when "100001" =>   --ADDU  r[rd]=r[rs]+r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_ADD;      when "100010" =>   --SUB   r[rd]=r[rs]-r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_SUBTRACT;      when "100011" =>   --SUBU  r[rd]=r[rs]-r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_SUBTRACT;      when "100100" =>   --AND   r[rd]=r[rs]&r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_AND;      when "100101" =>   --OR    r[rd]=r[rs]|r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_OR;      when "100110" =>   --XOR   r[rd]=r[rs]^r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_XOR;      when "100111" =>   --NOR   r[rd]=~(r[rs]|r[rt]);         c_source := C_FROM_ALU;         alu_function := ALU_NOR;      when "101010" =>   --SLT   r[rd]=r[rs]<r[rt];         c_source := C_FROM_ALU;         alu_function := ALU_LESS_THAN_SIGNED;      when "101011" =>   --SLTU  r[rd]=u[rs]<u[rt];         c_source := C_FROM_ALU;         alu_function := ALU_LESS_THAN;      when "101101" =>   --DADDU r[rd]=r[rs]+u[rt];         c_source := C_FROM_ALU;         alu_function := ALU_ADD;      when "110001" =>   --TGEU      when "110010" =>   --TLT      when "110011" =>   --TLTU      when "110100" =>   --TEQ       when "110110" =>   --TNE       when others =>      end case;   when "000001" =>   --REGIMM      rt := "000000";      rd := "011111";      a_source := A_FROM_PC;      b_source := B_FROM_IMMX4;      alu_function := ALU_ADD;      pc_source := FROM_BRANCH;      branch_function := BRANCH_GTZ;      --if(test) pc=pc+imm*4      case rtx is      when "10000" =>   --BLTZAL  r[31]=s->pc_next; branch=r[rs]<0;         c_source := C_FROM_PC_PLUS4;         branch_function := BRANCH_LTZ;      when "00000" =>   --BLTZ    branch=r[rs]<0;         branch_function := BRANCH_LTZ;      when "10001" =>   --BGEZAL  r[31]=s->pc_next; branch=r[rs]>=0;         c_source := C_FROM_PC_PLUS4;         branch_function := BRANCH_GEZ;      when "00001" =>   --BGEZ    branch=r[rs]>=0;         branch_function := BRANCH_GEZ;      when "10010" =>   --BLTZALL r[31]=s->pc_next; lbranch=r[rs]<0;         c_source := C_FROM_PC_PLUS4;         pc_source := FROM_LBRANCH;         branch_function := BRANCH_LTZ;      when "00010" =>   --BLTZL   lbranch=r[rs]<0;         pc_source := FROM_LBRANCH;         branch_function := BRANCH_LTZ;      when "10011" =>   --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0;         c_source := C_FROM_PC_PLUS4;         pc_source := FROM_LBRANCH;         branch_function := BRANCH_GEZ;      when "00011" =>   --BGEZL   lbranch=r[rs]>=0;         pc_source := FROM_LBRANCH;         branch_function := BRANCH_GEZ;	  when others =>	  end case;

⌨️ 快捷键说明

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