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

📄 cu.v

📁 这个是用可编程器件进行仿真CPU的程序
💻 V
📖 第 1 页 / 共 2 页
字号:
//**************************************************
//** Revision    :  0.2
//** File name   :  CU.v
//** Module name :  CU
//** Discription :  This is the Taocore's Control Unit
//** Simulator   :  Quartus II 5.1 web edition
//** Synthesizer :  Quartus II 5.1 web edition
//** Author      :  IamFree
//** Last modified:    @ 2006///
//** Created date:  2006/03/13
//**************************************************

module CU(
//inputs
opcode,
flags,
sel_flags,
sys_clk,
sys_rst,

//outputs
alu_func,

LD_acc,
LD_arl,
LD_pcl,
LD_ir,
LD_spl,
LD_sph,
LD_arh,
LD_pch,
LD_psw,
LD_gr6,


SEL_arh,
SEL_gr_addr,
SEL_psw,
SEL_alu,
SEL_sp,
SEL_databus,
SEL_pc,
SEL_address,

//data bus control
rom_cs,
ram_cs,
mem_wr,
mem_rd,
data_out_enable
         );

//Parameter define
//Opcode define
parameter ADDI=5'b00001;
parameter SUBI=5'b00010;
parameter ANDI=5'b00011;
parameter ORI =5'b00100;
parameter XORI=5'b00101;

parameter ADDR=5'b01001;
parameter SUBR=5'b01010;
parameter ANDR=5'b01011;
parameter ORR =5'b01100;
parameter XORR=5'b01101;

parameter JZ  =5'b10000;
parameter JP  =5'b10001;
parameter JC  =5'b10010;
parameter JMP =5'b10011;

parameter SHL =5'b00110;
parameter SHR =5'b00111;

parameter NOTA=5'b01000;

parameter LDV =5'b01110;
parameter STV =5'b01111;

parameter STR  =5'b10100;
parameter STSPH=5'b10101;
parameter STSPL=5'b10110;

parameter LDI  =5'b10111;

parameter LDA  =5'b11000;
parameter STA  =5'b11001;

parameter LDR =5'b11010;

parameter CALL=5'b11011;
parameter RET =5'b11100;

parameter PUSH=5'b11101;
parameter POP =5'b11110;

parameter NOP =5'b00000;

//CU parameter define(ALL these parameters are
//relate to the datapath,don't edit them seperately!
parameter flag_acc_sel=1'b1;
parameter flag_psw_sel=1'b0;
parameter SEL_ALU_MEM  =2'b00;
parameter SEL_ALU_GR6  =2'b01;
parameter SEL_ALU_FLAGS=2'b10;
parameter SEL_ARH_RRR =1'b0;
parameter SEL_ARH_DATA=1'b1;
parameter SEL_GR_ADDR_RRR=1'b0;
parameter SEL_GR_ADDR_BX =1'b1;
parameter SEL_PSW_ALU =1'b0;
parameter SEL_PSW_DATA=1'b1;
parameter SEL_SP_S1  =2'b00;
parameter SEL_SP_A1  =2'b01;
parameter SEL_SP_DATA=2'b10;
parameter SEL_DATABUS_ALU=2'b10;
parameter SEL_DATABUS_PCH=2'b01;
parameter SEL_DATABUS_PCL=2'b00;
parameter SEL_PC_AR=1'b1;
parameter SEL_PC_A1=1'b0;
parameter SEL_ADDRESS_PC=2'b00;
parameter SEL_ADDRESS_AR=2'b01;
parameter SEL_ADDRESS_SP=2'b10;

parameter ENABLE =1'b0; //For WR,RD,ROM_CS,RAM_CS
parameter DISABLE=1'b1;
parameter LDEN   =1'b1; //For register's Load enable singal
parameter LDDIS  =1'b0;
parameter OUTEN  =1'b1; //For data_out_enable
parameter OUTDIS =1'b0;

//ALU opcode define
/* Defined but never used
parameter ALU_ADD=5'b00001;
parameter ALU_SUB=5'b00010;
parameter ALU_AND=5'b00011;
parameter ALU_OR =5'b00100;
parameter ALU_XOR=5'b00101;
*/
parameter ALU_SHL=5'b00110;
parameter ALU_SHR=5'b00111;
parameter ALU_NOT=5'b01000;
parameter ALU_TA =5'b01001;
parameter ALU_TB =5'b01010;
parameter ALU_NOP=5'b00000;  //A invalid statement of ALU

//Port define
//outputs
output rom_cs;
output ram_cs;
output mem_wr;
output mem_rd;
output [4:0] alu_func;

output LD_acc;
output LD_arl;
output LD_pcl;
output LD_ir;
output LD_spl;
output LD_sph;
output LD_arh;
output LD_pch;
output LD_psw;
output LD_gr6;

//Selection signals
output SEL_gr_addr;
output SEL_psw;
output SEL_arh;
output [1:0] SEL_alu;
output [1:0] SEL_sp;
output [1:0] SEL_databus;
output SEL_pc;
output [1:0] SEL_address;

//data bus control
output data_out_enable;

//inputs
input [4:0] opcode;
input [2:0] flags;
input [1:0] sel_flags;
input sys_clk;
input sys_rst;

//Port type
reg rom_cs;
reg ram_cs;
reg mem_wr;
reg mem_rd;
reg [4:0] alu_func;

reg LD_acc;
reg LD_arl;
reg LD_pcl;
reg LD_ir;
reg LD_spl;
reg LD_sph;
reg LD_arh;
reg LD_pch;
reg LD_psw;
reg LD_gr6;

reg SEL_arh;
reg SEL_gr_addr;
reg SEL_psw;
reg [1:0] SEL_alu;
reg [1:0] SEL_sp;
reg [1:0] SEL_databus;
reg SEL_pc;
reg [1:0] SEL_address;
reg data_out_enable;

//Variable define
reg [2:0] Op_state;

//Statement const define
parameter FETCH=3'b000;
parameter S1=3'b001;
parameter S2=3'b010;
parameter S3=3'b011;
parameter S4=3'b100;
parameter S5=3'b101;
parameter S6=3'b110;
//parameter OP_RST=3'b111;

//Body
//Statement conter(SC)
//v.1
reg SC_clr_n;   //SC同步清零端
reg SC_inc;     //SC递增使能端

always @(posedge sys_clk or negedge sys_rst)
begin
 if(!sys_rst)   //指令同步/系统异步清零
  Op_state<=FETCH;
 else if(!SC_clr_n)
  Op_state<=FETCH;
 else if(SC_inc)
  Op_state<=Op_state+3'b001;
end

//指令译码器
always @(Op_state or opcode or flags or sel_flags)
begin

 //防止生成不可预知的锁存器
 rom_cs=DISABLE;
 ram_cs=DISABLE;
 mem_wr=DISABLE;
 mem_rd=DISABLE;
 alu_func=ALU_NOP;

 LD_acc=LDDIS;
 LD_ir =LDDIS;
 LD_spl=LDDIS;
 LD_sph=LDDIS;
 LD_arl=LDDIS;
 LD_arh=LDDIS;
 LD_pcl=LDDIS;
 LD_pch=LDDIS;
 LD_psw=LDDIS;
 LD_gr6=LDDIS;

 SEL_arh=SEL_ARH_RRR;
 SEL_gr_addr=SEL_GR_ADDR_RRR;
 SEL_psw=SEL_PSW_ALU;
 SEL_alu=SEL_ALU_MEM;
 SEL_sp=SEL_SP_S1;
 SEL_databus=SEL_DATABUS_ALU;
 SEL_pc=SEL_PC_A1;
 SEL_address=SEL_ADDRESS_PC;
 data_out_enable=OUTDIS;

 SC_clr_n=1'b1;
 SC_inc=1'b0;

 //根据状态计数器和指令进行指令译码
 if(Op_state==FETCH)
  begin
   SEL_pc=SEL_PC_A1;   //PC<-PC+1
   LD_pch=LDEN;LD_pcl=LDEN;
   //IR<-DATA
   LD_ir=LDEN;
   //MEM type
   ram_cs=DISABLE;
   rom_cs=ENABLE;
   mem_rd=ENABLE;
   mem_wr=DISABLE;
   SEL_address=SEL_ADDRESS_PC;
   data_out_enable=OUTDIS;
   //将所有与FETCH无关控制信号置为合适的初始值
   LD_acc=LDDIS; //ACC
   LD_arl=LDDIS; //AR
   LD_arh=LDDIS;
   LD_spl=LDDIS; //SP
   LD_sph=LDDIS;
   LD_psw=LDDIS; //PSW
   LD_gr6=LDDIS; //GR6

   alu_func=ALU_NOP; //At this time ALU is free
   SEL_gr_addr=SEL_GR_ADDR_RRR;
   SEL_psw    =SEL_PSW_ALU;
   SEL_alu    =SEL_ALU_MEM;
   SEL_sp     =SEL_SP_S1;
   SEL_databus=SEL_DATABUS_ALU;
   SEL_pc     =SEL_PC_A1;
   SEL_arh    =SEL_ARH_RRR;
   //Goto next statemet
   SC_clr_n=1'b1;
   SC_inc=1'b1;
  end
else
 begin
  case(opcode)//synthesis parallel_case
   ADDI,
   SUBI,    //DDDebugging...(ADDI SUBI debugged,)
   ANDI,
   ORI ,
   XORI :
    begin
     case(Op_state)//synthesis parallel_case
      S1 :   
       begin
        //MEM type
        rom_cs=ENABLE;
        mem_rd=ENABLE;
        //ACC<-ACC opcode MEM(code)
        alu_func={2'b00,opcode[2:0]};
        SEL_databus=SEL_DATABUS_ALU;
        SEL_address=SEL_ADDRESS_PC;   //<-Where is the data come from
        SEL_alu=SEL_ALU_MEM;    //<-Where are the results going
        LD_acc=LDEN;
        SEL_psw=SEL_PSW_ALU;    //PSW<-ALU_flags
        LD_psw=LDEN;
        SC_inc=1'b1;            //Goto next state
       end
      S2 :  
       begin
        //PC<-PC+1
        SEL_pc=SEL_PC_A1;
        LD_pch=LDEN;LD_pcl=LDEN;

        SC_clr_n=1'b0;          //End of these opcode
       end
      default:SC_clr_n=1'b0;    //Program may out of control from here,
                                //As the error already happened,nothing we should do but let it go!
     endcase
    end

   ADDR ,
   SUBR ,
   ANDR ,   //DDDebugging...(ADDR debugged,)
   ORR  ,
   XORR:
    case(Op_state)
    S1 :
     begin
      //ACC<-ACC opcode reg[rrr] (NOTE: rrr can't be PSW or ACC)
      SEL_gr_addr=SEL_GR_ADDR_RRR;  //Where is the data come from
      SEL_alu=SEL_ALU_GR6;
      alu_func={2'b00,opcode[2:0]}; //What the alu should do
      SEL_databus=SEL_DATABUS_ALU;  //Where is the result going
      LD_acc=LDEN;
      SEL_psw=SEL_PSW_ALU;
      LD_psw=LDEN;

      SC_inc=1'b1;                //End of these opcode
     end
    S2 :
      SC_clr_n=1'b0;
    default:SC_clr_n=1'b0;
    endcase

   SHL  ,
   SHR  ,   //Debugged
   NOTA :
    begin
      //ALU<-ALU sl or sr or not
      case(opcode)//synthesis parallel_case
        //Use the data source defined by the opcode
        SHL: alu_func=ALU_SHL; //What the alu should do
        SHR: alu_func=ALU_SHR;
        NOTA:alu_func=ALU_NOT;
        default:alu_func=ALU_NOP;
      endcase
      //Where the results going
      SEL_databus=SEL_DATABUS_ALU;
      LD_acc=LDEN;
      SEL_psw=SEL_PSW_ALU;
      LD_psw=LDEN;
      SC_clr_n=1'b0;        //End of these opcode
    end

   JZ ,  //DDDebugging...(JMP debugged,)
   JP ,
   JC ,
   JMP :
    begin
     if((opcode==JZ && flags[1]==1'b1)||(opcode==JC && flags[0]==1'b1)||
        (opcode==JP && flags[2]==1'b1)||(opcode==JMP))
      begin
       case(Op_state) //synthesis parallel_case
        S1 :
         begin
          SEL_arh=SEL_ARH_RRR; //ARH<-RRR
          LD_arh=LDEN;
         
           //ARL<-MEM(code)
          SEL_address=SEL_ADDRESS_PC;

⌨️ 快捷键说明

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