设为首页 收藏本站
论坛账号至少一个月登录一次,否则会被自动冻结!论坛全站广告位出租380元一年,有需要联系QQ:3173974412。国内首家由论坛网友持股的IC技术论坛,IC人的乌托邦!
搜索
元器件订购,上立创自营商城。十周年庆典,加入VIP,全场享受98折优惠。现货库存,正品保障。首次购买送现金券。客服QQ:2852512828
EDABOSS嵌入式论坛 嵌入式开发工程师的乐园 【点击查看】
广告位出租:ML03 有需要联系QQ:3173974412
青软IC版图实训——线下授课,赠送线上视频 【点击查看】
明德扬《至简设计法》高端FPGA视频教程【点击免费领取】
查看: 346|回复: 3

[转帖] 一个兼容NIOSII 指令集的微处理器源代码,非常值得参考学习

[复制链接]
发表于 2016-10-12 13:27:29 | 显示全部楼层 |阅读模式
`define   SIM
`define   LOW_POWER
`timescale 1ns/100ps
`include  "../RTL/instruction_opcode.v"
module  Kunlun_r_5c_bus
#(
        //Upon reset, this reset address is loaded into PC
        parameter  RESET_ADDRESS=32'H0  
)
(
        // clock and reset
input         clk,
input         rst_n,
// I master interface
output  logic           i_read,
input   logic           i_waitrequest,
output  logic  [31: 0]  i_address,
input   logic  [31: 0]  i_readdata,
   
// D master interface
output  logic           d_read,
output  logic           d_write,
input   logic           d_waitrequest,
output  logic  [31: 0]  d_address,
input   logic  [31: 0]  d_readdata,
output  logic  [31: 0]  d_writedata,
output  logic  [ 3: 0]  d_byteenable
);
  parameter    DLY = 1;
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
  logic   [31: 0]      PC;
  logic   [31: 0]      IR;
  logic   IR_wr;
  logic   [31: 0]      RFile[0:31];
  logic   [31: 0]      rA,rB,rIMM;
  logic   [31: 0]      rALU;
  wire    [ 5: 0]      IR_op     = IR[ 5: 0];
  wire    [ 4: 0]      IR_a      = IR[31:27];
  wire    [ 4: 0]      IR_b      = IR[26:22];
  wire    [ 4: 0]      IR_c      = IR[21:17];
  wire    [ 5: 0]      IR_opx    = IR[16:11];
  wire    [ 5: 0]      IR_imm5   = IR[10: 6];
  wire    [15: 0]      IR_imm16  = IR[21: 6];
  wire    [25: 0]      IR_imm26  = IR[31: 6];
  logic   [31: 0]      IR_d;
  parameter            ZERO_IDX  =   5'h00;
  parameter            RA_IDX    =   5'h1F;
  
  //flag for R-Type instructions
  wire                 IR_IsRType   = (IR_op==6'h3A);   
  //flag for J-Type instructions
  wire                 IR_IsJType   = ( (IR_op==`IR_J_CALL) ||
                                        (IR_op==`IR_J_JMPI)
                                      ) ;
  //flag for I-Type instructions
  wire                 IR_IsIType   = !(IR_IsRType||IR_IsJType);
  //flag for LDx instructions
  wire                 IR_IsLD      =  ( IR_op==`IR_I_LDB  || IR_op==`IR_I_LDBU   ||
                                         IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO ||
                                         IR_op==`IR_I_LDH  || IR_op==`IR_I_LDHU   ||
                                         IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO ||
                                         IR_op==`IR_I_LDW  || IR_op==`IR_I_LDWIO
           );
  //flag for STx instructions
  wire                 IR_IsST      =  ( IR_op==`IR_I_STB  || IR_op==`IR_I_STBIO   ||
                                         IR_op==`IR_I_STH  || IR_op==`IR_I_STHIO   ||
                                         IR_op==`IR_I_STW  || IR_op==`IR_I_STWIO
           );
  //flag for BRx instructions
  wire                 IR_IsBR      =  ( IR_op==`IR_I_BR   || IR_op==`IR_I_BGE    ||
                                         IR_op==`IR_I_BLT  || IR_op==`IR_I_BNE    ||
                                         IR_op==`IR_I_BEQ  || IR_op==`IR_I_BGEU   ||
                                         IR_op==`IR_I_BLTU
           );

////////////////////////////////////////////////////////////////////////////////
//             1: PC
////////////////////////////////////////////////////////////////////////////////
  logic  [31: 0]           PC_d;
  logic                    PC_wr;
  enum  logic [ 3: 0] {  PC_d_sel_PCP4 = 4'b0001,
                         PC_d_sel_BR   = 4'b0010,
                         PC_d_sel_JMP  = 4'b0100,
                         PC_d_sel_RA   = 4'b1000,
                         PC_d_sel_X    = 4'bxxxx
        } PC_d_sel;
  always_ff @( posedge clk, negedge rst_n )
  begin
      if      (    ~rst_n     )   PC  <=       RESET_ADDRESS;   
      else if (     PC_wr     )   PC  <= #DLY  PC_d;
      //else                        PC  <= #DLY  PC;
  end
  always_comb
  begin
      unique case(  PC_d_sel  )
          PC_d_sel_PCP4  :  PC_d  =   PC + 32'd4;
          PC_d_sel_BR    :  PC_d  =   PC + {{16{IR_imm16[15]}},IR_imm16};
          PC_d_sel_JMP   :  PC_d  =  {PC[31:28], IR_imm26, 2'b00};
          PC_d_sel_RA    :  PC_d  =   rA;
          default        :  PC_d  =   'x;
      endcase
   end

/////////////////////////////////////////////////////////////////////////////   
//           2: I Master Interface
/////////////////////////////////////////////////////////////////////////////   
  logic              is_in_stageF;
  logic              i_fetch_done;
  always_comb
  assign     i_address   =  PC;
  assign     IR_d        =  i_readdata;
  always_comb
  begin: i_read_of_StageF
      if  ( is_in_stageF==1'b1 )
          i_read   =  1'b1;
      else
          i_read   =  1'b0;
  end: i_read_of_StageF
  always_comb
  begin: i_fetch_done_of_StageF
      if  ( (is_in_stageF==1'b1) && (i_waitrequest==1'b0) )
          i_fetch_done   =  1'b1;
      else
          i_fetch_done   =  1'b0;
  end: i_fetch_done_of_StageF
  always_comb
  begin: IR_wr_of_StageF
      if  ( (is_in_stageF==1'b1) && (i_waitrequest==1'b0) )
          IR_wr    =  1'b1;
      else
          IR_wr    =  1'b0;
  end: IR_wr_of_StageF
///////////////////////////////////////////////////////////////////////////////  
//             3:  IR
///////////////////////////////////////////////////////////////////////////////  
  always_ff @(posedge clk, negedge rst_n)
  begin
     if      ( ~rst_n )   IR  <=        32'd0;
     else if ( IR_wr  )   IR  <=  #DLY  i_readdata;
  end
///////////////////////////////////////////////////////////////////////////////  
//             4:  rA, rB, rIMM
///////////////////////////////////////////////////////////////////////////////  
  logic  [ 4: 0]  RFile_Aidx,RFile_Bidx;
  logic  [31: 0]  RFile_Aq,RFile_Bq;
  logic  [31: 0]  rIMM_d;
  logic           rIMM_wr;
  enum  logic [ 3: 0] { rIMM_d_sel_IR_IMM16_SE   =  4'b0001,
                        rIMM_d_sel_IR_IMM16_ZE   =  4'b0010,
                        rIMM_d_sel_IR_IMM16_LS16 =  4'b0100,
                        rIMM_d_sel_IR_IMM5_ZE    =  4'b1000,
                        rIMM_d_sel_X             =  4'bxxxx
        }   rIMM_d_sel;
  assign   RFile_Aidx  =  IR_a;
  assign   RFile_Bidx  =  IR_b;
  assign   RFile_Aq  = (RFile_Aidx==ZERO_IDX) ? 32'd0 : RFile[RFile_Aidx];
  assign   RFile_Bq  = (RFile_Bidx==ZERO_IDX) ? 32'd0 : RFile[RFile_Bidx];
  always_ff @(posedge clk,negedge rst_n)
  begin: update_rA
      if  ( rst_n==1'b0 )
   rA  <= 32'd0;
      else
   rA  <= #DLY RFile_Aq;
  end: update_rA
  always_ff @(posedge clk,negedge rst_n)
  begin: update_rB
      if  ( rst_n==1'b0 )
   rB  <= 32'd0;
      else
   rB  <= #DLY RFile_Bq;
  end: update_rB
  always_ff @(posedge clk,negedge rst_n)
  begin: update_rIMM
      if  ( rst_n==1'b0 )
   rIMM  <= 32'd0;
      else if ( rIMM_wr==1'b1 )
   rIMM  <= #DLY rIMM_d;
  end: update_rIMM
  always_comb
  begin
      unique case ( rIMM_d_sel )
         rIMM_d_sel_IR_IMM16_SE  : rIMM_d = { {16{IR_imm16[15]}}, IR_imm16 };
         rIMM_d_sel_IR_IMM16_ZE  : rIMM_d = { 16'd0, IR_imm16 };
         rIMM_d_sel_IR_IMM16_LS16: rIMM_d = { IR_imm16, 16'd0 };
         rIMM_d_sel_IR_IMM5_ZE   : rIMM_d = { 27'd0, IR_imm5  };
  default                 : rIMM_d = 'x;
      endcase
  end
///////////////////////////////////////////////////////////////////////////////  
//             5:  ALU
///////////////////////////////////////////////////////////////////////////////  
  logic [31: 0]         ALU_a,ALU_b, ALU_q;
  enum  logic [ 1: 0] { ALU_b_sel_rB    = 2'b01,
                        ALU_b_sel_rIMM  = 2'b10,
                        ALU_b_sel_X     = 2'bxx
        }   ALU_b_sel;
  enum  logic [23: 0] {
                       ALU_OP_ADD    =24'h0_0_0_0_0_1,
                       ALU_OP_AND    =24'h0_0_0_0_0_2,
                       ALU_OP_CMPEQ  =24'h0_0_0_0_0_4,
                       ALU_OP_CMPGE  =24'h0_0_0_0_0_8,
                       ALU_OP_CMPGEU =24'h0_0_0_0_1_0,
                       ALU_OP_CMPLT  =24'h0_0_0_0_2_0,
                       ALU_OP_CMPLTU =24'h0_0_0_0_4_0,
                       ALU_OP_CMPNEQ =24'h0_0_0_0_8_0,
                       ALU_OP_MUL    =24'h0_0_0_1_0_0,
                       ALU_OP_NOR    =24'h0_0_0_2_0_0,
                       ALU_OP_OR     =24'h0_0_0_4_0_0,
                       ALU_OP_ROL    =24'h0_0_0_8_0_0,
                       ALU_OP_ROR    =24'h0_0_1_0_0_0,
                       ALU_OP_SLL    =24'h0_0_2_0_0_0,
                       ALU_OP_SRL    =24'h0_0_4_0_0_0,
                       ALU_OP_SRA    =24'h0_0_8_0_0_0,
                       ALU_OP_SUB    =24'h0_1_0_0_0_0,
                       ALU_OP_XOR    =24'h0_2_0_0_0_0,
                       ALU_OP_X      =24'hx_x_x_x_x_x
        }  ALU_op;
  logic               rALU_wr;
  assign    ALU_a   =  rA;
  always_comb
  begin: ALU_b_selection
      unique case  ( ALU_b_sel )
          ALU_b_sel_rB    :   ALU_b  =  rB;
          ALU_b_sel_rIMM  :   ALU_b  =  rIMM;
          default         :   ALU_b  =  'x;
      endcase
  end: ALU_b_selection
  always_comb
  begin: ALU_computation
     case (  ALU_op  )
          ALU_OP_ADD     : ALU_q  =  ALU_a  + ALU_b;   
          ALU_OP_AND     : ALU_q  =  ALU_a  & ALU_b;   
          ALU_OP_CMPEQ   : ALU_q  =  ALU_a == ALU_b;   
          ALU_OP_CMPGE   : ALU_q  =  cmpge( ALU_a, ALU_b );   
          ALU_OP_CMPGEU  : ALU_q  =  ALU_a >= ALU_b;   
          ALU_OP_CMPLT   : ALU_q  =  cmplt( ALU_a, ALU_b );   
          ALU_OP_CMPLTU  : ALU_q  =  ALU_a <  ALU_b;   
          ALU_OP_CMPNEQ  : ALU_q  =  ALU_a != ALU_b;   
          ALU_OP_MUL     : ALU_q  =  ALU_a * ALU_b;   
          ALU_OP_NOR     : ALU_q  =  ~(ALU_a | ALU_b);   
          ALU_OP_OR      : ALU_q  =  ALU_a | ALU_b ;   
          ALU_OP_ROL     : ALU_q  =  rol( ALU_a, ALU_b[4:0] );   
          ALU_OP_ROR     : ALU_q  =  ror( ALU_a, ALU_b[4:0] );   
          ALU_OP_SLL     : ALU_q  =  ALU_a << ALU_b[4:0] ;   
          ALU_OP_SRL     : ALU_q  =  ALU_a >> ALU_b[4:0] ;   
          ALU_OP_SRA     : ALU_q  =  $signed(ALU_a) >>> ALU_b[4:0] ;   
          ALU_OP_SUB     : ALU_q  =  ALU_a - ALU_b ;   
          ALU_OP_XOR     : ALU_q  =  ALU_a ^ ALU_b ;   
          default        : ALU_q  =  'x;   
      endcase
  end: ALU_computation
  always_ff @(posedge clk)
  begin: update_rALU
      if ( rALU_wr==1'b1 )
           rALU  <=  #DLY  ALU_q;
  end: update_rALU
////////////////////////////////////////////////////////////////////////////////  
//            6: D Master Infterface                                          //
////////////////////////////////////////////////////////////////////////////////  
  logic             is_in_stageMEM;
  logic  [31: 0]    data_from_DMaster;
  logic  [31: 0]    rDMasterIn;
  logic             rDMasterIn_wr;
  logic  [ 7: 0]    d_readdata_b;
  logic  [15: 0]    d_readdata_h;
  
  // the address of data bus comes always from rALU, ie. rA + sign(IMM16)
  assign    d_address   =   rALU;
  //-----------store data into memory------------//
  //------ d_writedata ------//
  always_comb
  begin: d_writedata_for_STX
      unique if ( (IR_op==`IR_I_STB)|| (IR_op==`IR_I_STBIO) )
      begin: d_writedata_for_STBx
          d_writedata   =   { 4{rB[ 7: 0]} };
      end: d_writedata_for_STBx
      else  if ( (IR_op==`IR_I_STH)|| (IR_op==`IR_I_STHIO) )
      begin: d_writedata_for_STHx
          d_writedata   =   { 2{rB[15: 0]} };
      end: d_writedata_for_STHx
      else  
      begin: d_writedata_for_STWx
          d_writedata   =    rB;
      end: d_writedata_for_STWx
  end: d_writedata_for_STX
  //------ d_write ------//
  always_comb
  begin: d_write_for_STX
      if ( is_in_stageMEM && IR_IsST )
  d_write   = 1'b1;
      else
  d_write   = 1'b0;
  end: d_write_for_STX
  //-------data_from_DMaster-------//
  always_comb
  begin: d_readdata_b_selection
      if  ( IR_op==`IR_I_LDB  || IR_op==`IR_I_LDBU  ||
            IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO )
      begin
   unique  case( d_address[ 1: 0] )
             2'b00   :   d_readdata_b  =  d_readdata[ 7: 0];
             2'b01   :   d_readdata_b  =  d_readdata[15: 8];
             2'b10   :   d_readdata_b  =  d_readdata[23:16];
             2'b11   :   d_readdata_b  =  d_readdata[31:24];
      default :   d_readdata_b  =  'x;
          endcase
      end
      else
      d_readdata_b  =  'x;
  end: d_readdata_b_selection
  always_comb
  begin: d_readdata_h_selection
      if  ( IR_op==`IR_I_LDH  || IR_op==`IR_I_LDHU  ||
            IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO )
      begin
   unique  case( d_address[ 0] )
             1'b0   :   d_readdata_h  =  d_readdata[15: 0];
             1'b1   :   d_readdata_h  =  d_readdata[31:16];
      default :  d_readdata_h  =  'x;
          endcase
      end
      else
      d_readdata_h  =  'x;
  end: d_readdata_h_selection
  always_comb
  begin: data_from_DMaster_selection
      unique if ( IR_op==`IR_I_LDB|| IR_op==`IR_I_LDBIO )
  data_from_DMaster  =  { {24{d_readdata_b[ 7]}}, d_readdata_b };
      else   if ( IR_op==`IR_I_LDBU|| IR_op==`IR_I_LDBUIO )
  data_from_DMaster  =  { 24'd0, d_readdata_b };
      else   if ( IR_op==`IR_I_LDH|| IR_op==`IR_I_LDHIO )
  data_from_DMaster  =  { {16{d_readdata_h[15]}}, d_readdata_h };
      else   if ( IR_op==`IR_I_LDHU|| IR_op==`IR_I_LDHUIO )
  data_from_DMaster  =  { 16'd0, d_readdata_h };
      else
  data_from_DMaster  =   d_readdata;
  end: data_from_DMaster_selection
  //-------RDMasterIn_wr-------//
  always_comb
  begin
     if ( is_in_stageMEM && !d_waitrequest && IR_IsLD )
  rDMasterIn_wr  = 1'b1;
     else
  rDMasterIn_wr  = 1'b0;
  end
  //-------rDMasterIn------//
  always_ff @( posedge clk, negedge rst_n )
  begin
      if      ( ~rst_n )      
   rDMasterIn  <=  32'd0;
      else if ( rDMasterIn_wr )
   rDMasterIn  <=  data_from_DMaster;
  end
  //------ d_read------//
  always_comb
  begin: d_read_for_LDX
      if ( is_in_stageMEM && IR_IsLD )
  d_read    = 1'b1;
      else
  d_read    = 1'b0;
  end: d_read_for_LDX
  //--------d_byteenable-------//
  always_comb
  begin
      unique if  ( IR_op==`IR_I_LDB  || IR_op==`IR_I_LDBU  ||
            IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO||
            IR_op==`IR_I_STB  || IR_op==`IR_I_STBIO )
      begin
    unique case ( d_address[ 1: 0] )
              2'b00    :   d_byteenable = 4'b0001;
              2'b01    :   d_byteenable = 4'b0010;
              2'b10    :   d_byteenable = 4'b0100;
              2'b11    :   d_byteenable = 4'b1000;
       default  :   d_byteenable = 'x;
           endcase
      end
      else if  ( IR_op==`IR_I_LDH  || IR_op==`IR_I_LDHU  ||
                 IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO||
                 IR_op==`IR_I_STH  || IR_op==`IR_I_STHIO )
      begin
    unique case ( d_address[ 0] )
              1'b0    :   d_byteenable = 4'b0011;
              1'b1    :   d_byteenable = 4'b1100;
       default :   d_byteenable = 'x;
           endcase
      end
      else
          d_byteenable = 4'b1111;
  end
///////////////////////////////////////////////////////////////////////////////  
//             7:  write_back RFile
///////////////////////////////////////////////////////////////////////////////  
  enum  logic [ 2: 0] { RFile_Cidx_sel_IR_B  = 3'b001,
                        RFile_Cidx_sel_IR_C  = 3'b010,
                        RFile_Cidx_sel_RA    = 3'b100,
                        RFile_Cidx_sel_X     = 3'bxxx
        }   RFile_Cidx_sel;
  enum  logic [ 2: 0] { RFile_Cd_sel_rALU    = 3'b001,
                        RFile_Cd_sel_DMaster = 3'b010,
                        RFile_Cd_sel_PC      = 3'b100,
                        RFile_Cd_sel_X       = 3'bxxx
        }   RFile_Cd_sel;
  logic   [ 4: 0]    RFile_Cidx;
  logic   [31: 0]    RFile_Cd;
  logic              RFile_Cwr;

  //------ RFile_Cidx ------//
  always_comb
  begin : RFile_Cidx_Multiplexer
      unique case( RFile_Cidx_sel )
         RFile_Cidx_sel_IR_B:    RFile_Cidx =  IR_b;
         RFile_Cidx_sel_IR_C:    RFile_Cidx =  IR_c;
         RFile_Cidx_sel_RA  :    RFile_Cidx =  RA_IDX;
         default            :    RFile_Cidx =  'x;
      endcase
  end
  //------ RFile_Cd ------//
  always_comb
  begin : RFile_Cd_Multiplexer
      unique case( RFile_Cd_sel )
         RFile_Cd_sel_rALU    :    RFile_Cd =     rALU;
         RFile_Cd_sel_DMaster :    RFile_Cd =     rDMasterIn;
         RFile_Cd_sel_PC      :    RFile_Cd =     PC;
         default              :    RFile_Cd =     'x;
      endcase
  end
  //------ write RFile ------//
  always_ff @(posedge clk)
  begin
      if ( RFile_Cwr )
          RFile[ RFile_Cidx ]  <= #DLY RFile_Cd;
  end
////////////////////////////////////////////////////////////////////////////////  
//            0_A: Main Controller                                            //
////////////////////////////////////////////////////////////////////////////////  
  enum logic [ 5: 0] { S_IDLE=6'd1, S_FETCH=6'd2, S_DECODE=6'd4,
                       S_EXE =6'd8, S_MEM  =6'd16,S_WB    =6'd32
       } cur_stage, next_stage;
  // update current stage
  always_ff @(posedge clk, negedge rst_n)
  begin
      if   ( ~rst_n )   cur_stage <=      S_IDLE;
      else              cur_stage <= #DLY next_stage;
  end
  // next stage
  always_comb
  begin
      unique case( cur_stage )
         S_IDLE  :   next_stage  =  S_FETCH;
  S_FETCH :   begin
                if( i_waitrequest==1'b0 )
                    next_stage  =  S_DECODE;
         else
                    next_stage  =  S_FETCH;
       end
         S_DECODE:   next_stage  =  S_EXE;   
         S_EXE   :   next_stage  =  S_MEM;   
  S_MEM   :   begin
                 if( d_waitrequest==1'b0 )
                     next_stage  =  S_WB;   
   else
                     next_stage  =  S_MEM;   
       end
         S_WB    :   next_stage  =  S_FETCH;
  default :   next_stage  =  S_IDLE;
      endcase
  end  
  //
  assign   is_in_stageF    =  (cur_stage==S_FETCH);
  assign   is_in_stageMEM  =  (cur_stage==S_MEM);
////////////////////////////////////////////////////////////////////////////////  
//            0_B: Control Signals                                            //
////////////////////////////////////////////////////////////////////////////////  
// Control signals: PC_wr, PC_d_sel,
//                  rIMM_d_sel
//                  ALU_b_sel, ALU_op, rALU_wr
//                  RFile_Cwr, RFile_Cidx_sel,RFile_Cd_sel
   always_comb
   begin:  control_signal_gen
       unique if  ( cur_stage == S_FETCH )
       begin: decoding_for_StageF
           // PC
           PC_wr            =  ~i_waitrequest;
           PC_d_sel         =  PC_d_sel_PCP4;
           // rIMM
    rIMM_wr          =  1'b0;
    rIMM_d_sel       =  rIMM_d_sel_X;
           // ALU
    ALU_b_sel        =  ALU_b_sel_X;
           ALU_op           =  ALU_OP_X;
           rALU_wr          =  1'b0;
    // Write back RFile
           RFile_Cwr        =  1'b0;
           RFile_Cidx_sel   =  RFile_Cidx_sel_X;
           RFile_Cd_sel     =  RFile_Cd_sel_X;
       end: decoding_for_StageF
       else if  ( cur_stage == S_DECODE )
       begin: Decoding_for_StageD
           // PC
           PC_wr            =  1'b0;
           PC_d_sel         =  PC_d_sel_X;
           // rIMM
    rIMM_wr          =  1'b1;
           unique if (  
                        IR_op==`IR_I_ADDI   ||
                        IR_op==`IR_I_CMPEQI || IR_op==`IR_I_CMPGEI ||
                        IR_op==`IR_I_CMPLTI || IR_op==`IR_I_CMPNEI ||
                        IR_op==`IR_I_LDB    || IR_op==`IR_I_LDH    ||
                        IR_op==`IR_I_LDW    ||
                        IR_op==`IR_I_LDBU   || IR_op==`IR_I_LDHU   ||
                        IR_op==`IR_I_MULI   ||
                        IR_op==`IR_I_STB    || IR_op==`IR_I_STH    ||
                        IR_op==`IR_I_STW   
                     )
               rIMM_d_sel  =  rIMM_d_sel_IR_IMM16_SE;
           else  if  (
                       IR_op==`IR_I_ANDI    ||
                       IR_op==`IR_I_CMPGEUI || IR_op==`IR_I_CMPLTUI ||
                       IR_op==`IR_I_ORI     || IR_op==`IR_I_XORI
                     )
               rIMM_d_sel  =  rIMM_d_sel_IR_IMM16_ZE;
           else  if  (
                       IR_op==`IR_I_ANDHI  || IR_op==`IR_I_ORHI    ||
                       IR_op==`IR_I_XORHI   
                     )
               rIMM_d_sel  =  rIMM_d_sel_IR_IMM16_LS16;
           else  if  ( (IR_IsRType==1'b1) &&
                ( IR_opx==`IR_R_ROLI  || IR_opx==`IR_R_SLLI  ||
                         IR_opx==`IR_R_SRAI  || IR_opx==`IR_R_SRLI  )
       )
               rIMM_d_sel  =  rIMM_d_sel_IR_IMM5_ZE;
           else
               rIMM_d_sel  =  rIMM_d_sel_X;
           // ALU
           rALU_wr          =  1'b0;
    ALU_b_sel        =  ALU_b_sel_X;
           ALU_op           =  ALU_OP_X;
    // Write back RFile
           RFile_Cwr        =  1'b0;
           RFile_Cidx_sel   =  RFile_Cidx_sel_X;
           RFile_Cd_sel     =  RFile_Cd_sel_X;
       endundefinedecoding_for_StageD
       else if  (  cur_stage == S_EXE  )
       begin: decoding_for_StageExe
           // PC
           PC_wr            =  1'b0;
           PC_d_sel         =  PC_d_sel_X;
           // rIMM
    rIMM_wr          =  1'b0;
    rIMM_d_sel       =  rIMM_d_sel_X;
           // ALU
           rALU_wr          =  1'b1;
    if ( ( (IR_IsRType==1'b1)   &&
           (IR_opx!=`IR_R_ROLI) &&  
    (IR_opx!=`IR_R_SLLI) &&
    (IR_opx!=`IR_R_SRAI) &&
    (IR_opx!=`IR_R_SRLI)         
                ) || IR_IsBR
        )
       ALU_b_sel        =  ALU_b_sel_rB;
           else
       ALU_b_sel        =  ALU_b_sel_rIMM;
           unique if(  (IR_IsRType &&  (IR_opx==`IR_R_ADD ) ) ||
                (IR_op ==`IR_I_ADDI)                   ||
                (IR_op ==`IR_I_LDB )                   ||
                       (IR_op ==`IR_I_LDBU)                   ||
                (IR_op ==`IR_I_LDH )                   ||
                (IR_op ==`IR_I_LDHU)                   ||
                (IR_op ==`IR_I_LDW )                   ||
                (IR_op ==`IR_I_STB )                   ||
                (IR_op ==`IR_I_STH )                   ||
                (IR_op ==`IR_I_STW )
             )
       ALU_op  =  ALU_OP_ADD;
           // and
    else if(
                      (IR_IsRType &&  (IR_opx==`IR_R_AND ) ) ||
               (IR_op ==`IR_I_ANDHI)                  ||
               (IR_op ==`IR_I_ANDI )
           )
       ALU_op  =  ALU_OP_AND;
           // CMPEQ
    else if(
              (IR_IsRType &&  (IR_opx==`IR_R_CMPEQ ) )  ||
              (IR_op ==`IR_I_BEQ   )                    ||
              (IR_op ==`IR_I_CMPEQI)
           )
       ALU_op  =  ALU_OP_CMPEQ;
           // CMPGE
    else if(
              (IR_IsRType &&  (IR_opx==`IR_R_CMPGE ) )  ||
              (IR_op ==`IR_I_BGE     ) ||
              (IR_op ==`IR_I_CMPGEI  )
           )
       ALU_op  =  ALU_OP_CMPGE;
           // CMPGEU
    else if(
              (IR_op ==`IR_I_BGEU    ) ||
              (IR_IsRType && (IR_opx==`IR_R_CMPGEU) )  ||
              (IR_op ==`IR_I_CMPGEUI )
           )
       ALU_op  =  ALU_OP_CMPGEU;
           // CMPLT
    else if(
              (IR_op ==`IR_I_BLT     ) ||
              (IR_IsRType && (IR_opx==`IR_R_CMPLT) )  ||
              (IR_op ==`IR_I_CMPLTI  )
          )
       ALU_op  =  ALU_OP_CMPLT;
           // CMPLTU
    else if(
              (IR_op ==`IR_I_BLTU    ) ||
              (IR_IsRType && (IR_opx==`IR_R_CMPLTU) )  ||
              (IR_op ==`IR_I_CMPLTUI  )
          )
       ALU_op  =  ALU_OP_CMPLTU;
           // CMPNE
    else if(
              (IR_op ==`IR_I_BNE      ) ||
              (IR_IsRType && (IR_opx==`IR_R_CMPNE) )  ||
              (IR_op ==`IR_I_CMPNEI  )
           )
       ALU_op  =  ALU_OP_CMPNEQ;
           // MUL
    else if(
              (IR_IsRType && (IR_opx==`IR_R_MUL) )  ||
              (IR_op ==`IR_I_MULI  )
           )
       ALU_op  =  ALU_OP_MUL;
           // NOR
    else if(
              (IR_IsRType && (IR_opx==`IR_R_NOR) )  
           )
       ALU_op  =  ALU_OP_NOR;
           // OR
    else if(
              (IR_IsRType && (IR_opx==`IR_R_OR) )  ||
              (IR_op ==`IR_I_ORHI  )               ||
              (IR_op ==`IR_I_ORI   )  
           )
       ALU_op  =  ALU_OP_OR;
           // ROL
    else if(
              IR_IsRType && ( (IR_opx==`IR_R_ROL  )  ||
                              (IR_opx==`IR_R_ROLI )               
            )
           )
       ALU_op  =  ALU_OP_ROL;
         
           // ROR
    else if(
              (IR_IsRType && (IR_opx==`IR_R_ROR) )
           )
       ALU_op  =  ALU_OP_ROR;
         
           // SLL
    else if(
              (IR_IsRType && (IR_opx==`IR_R_SLL ) ) ||
              (IR_IsRType && (IR_opx==`IR_R_SLLI) )
           )
       ALU_op  =  ALU_OP_SLL;
         
           // SRA
    else if(
              (IR_IsRType && (IR_opx==`IR_R_SRA ) ) ||
              (IR_IsRType && (IR_opx==`IR_R_SRAI) )
           )
       ALU_op  =  ALU_OP_SRA;
         
           // SRL
    else if(
              (IR_IsRType && (IR_opx==`IR_R_SRL ) ) ||
              (IR_IsRType && (IR_opx==`IR_R_SRLI) )
           )
       ALU_op  =  ALU_OP_SRL;
           // SUB
    else if( IR_IsRType && (IR_opx==`IR_R_SUB )  )
       ALU_op  =  ALU_OP_SUB;
           //  XOR
    else if( (IR_IsRType && (IR_opx==`IR_R_XOR ) )  ||
             (IR_op ==`IR_I_XORHI )  ||              
             (IR_op ==`IR_I_XORI  )
           )
       ALU_op  =  ALU_OP_XOR;
          //
          else
       ALU_op  =  ALU_OP_ADD;   
    // Write back RFile
           RFile_Cwr        =  1'b0;
           RFile_Cidx_sel   =  RFile_Cidx_sel_X;
           RFile_Cd_sel     =  RFile_Cd_sel_X;

       end: decoding_for_StageExe
       else if  (  cur_stage == S_MEM  )
       begin: decoding_for_StageMem
           // PC
           PC_wr            =  1'b0;
           PC_d_sel         =  PC_d_sel_X;
           // rIMM
    rIMM_wr          =  1'b0;
    rIMM_d_sel       =  rIMM_d_sel_X;
           // ALU
    ALU_b_sel        =  ALU_b_sel_X;
           ALU_op           =  ALU_OP_X;
           rALU_wr          =  1'b0;
    // Write back RFile
           RFile_Cwr        =  1'b0;
           RFile_Cidx_sel   =  RFile_Cidx_sel_X;
           RFile_Cd_sel     =  RFile_Cd_sel_X;
       end: decoding_for_StageMem
       else if  (  cur_stage == S_WB  )
       begin: decoding_for_StageWB
           //------ PC ------//
           unique if ( (IR_op==`IR_I_BEQ) || (IR_op==`IR_I_BGE) || (IR_op==`IR_I_BGEU)||
                       (IR_op==`IR_I_BLT) || (IR_op==`IR_I_BLTU)|| (IR_op==`IR_I_BNE )
       )
              PC_wr  =  (rALU[0]==1'b1) ? 1'b1 : 1'b0;
           else if ( (IR_op==`IR_I_BR ) || (IR_op==`IR_J_CALL) || (IR_op==`IR_J_JMPI)  ||
                     ( (IR_IsRType==1'b1)&&( (IR_opx==`IR_R_CALLR)||(IR_opx==`IR_R_JMP)||
                                             (IR_opx==`IR_R_RET) ) )
                   )
              PC_wr  =   1'b1;
           else
              PC_wr  =   1'b0;
           unique if( (IR_op==`IR_I_BEQ )|| (IR_op==`IR_I_BGE )|| (IR_op==`IR_I_BGEU) ||
                      (IR_op==`IR_I_BLT )|| (IR_op==`IR_I_BLTU)|| (IR_op==`IR_I_BNE ) ||
                      (IR_op==`IR_I_BR  ) )
               PC_d_sel  = PC_d_sel_BR;
           else if( IR_IsJType==1'b1 )
               PC_d_sel  = PC_d_sel_JMP;
           else if( (IR_IsRType==1'b1 ) && ( (IR_opx==`IR_R_CALLR)|| (IR_opx==`IR_R_JMP)||
                                             (IR_opx==`IR_R_RET  ) ) )
               PC_d_sel  = PC_d_sel_RA;
           else
               PC_d_sel  = PC_d_sel_X;
           // rIMM
    rIMM_wr          =  1'b0;
    rIMM_d_sel       =  rIMM_d_sel_X;
           // ALU
           rALU_wr          =  1'b0;
    ALU_b_sel        =  ALU_b_sel_X;
           ALU_op           =  ALU_OP_X;
           //------ RFile ------//
    if( is_unkown_instr( IR )==1'b0 )
              begin
              if(   (IR_op == `IR_I_BEQ ) ||
                    (IR_op == `IR_I_BGE ) ||
                    (IR_op == `IR_I_BGEU) ||
                    (IR_op == `IR_I_BLT ) ||
                    (IR_op == `IR_I_BLTU) ||
                    (IR_op == `IR_I_BNE ) ||
                    (IR_op == `IR_I_BR  ) ||
                    (IR_op == `IR_J_JMPI) ||
                    (IR_op == `IR_I_STB ) ||
                    (IR_op == `IR_I_STH ) ||
                    (IR_op == `IR_I_STW ) ||
             ((IR_IsRType==1'b1)&&( (IR_opx==`IR_R_JMP) ||
                                    (IR_opx==`IR_R_RET) ))
                )
                   RFile_Cwr        =  1'b0;
       else
                   RFile_Cwr        =  1'b1;
       end
           else
               RFile_Cwr   =  1'b0;
            // R-type instruction
            unique if( IR_IsRType==1'b1 )
                if( IR_opx == `IR_R_CALLR  )
      RFile_Cidx_sel  =  RFile_Cidx_sel_RA;
         else
      RFile_Cidx_sel  =  RFile_Cidx_sel_IR_C;
            // I-type instruction
            else if( IR_IsIType==1'b1 )
                RFile_Cidx_sel  =  RFile_Cidx_sel_IR_B;
            // J-type instruction
            else if( IR_IsJType==1'b1 )
         RFile_Cidx_sel  =  RFile_Cidx_sel_RA;
            else
         RFile_Cidx_sel  =  RFile_Cidx_sel_IR_C;
            unique if( ( (IR_IsRType==1'b1)&&( (IR_opx==`IR_R_CALLR )     ||
                                               (IR_opx==`IR_R_NEXTPC) ) ) ||
                       (IR_op == `IR_J_CALL  ) )
                 RFile_Cd_sel   =  RFile_Cd_sel_PC;
            else if( IR_op==`IR_I_LDB|| IR_op==`IR_I_LDBU ||
                     IR_op==`IR_I_LDH|| IR_op==`IR_I_LDHU ||
                     IR_op==`IR_I_LDW||
                     IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO ||
                     IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO ||
                     IR_op==`IR_I_LDWIO)
                 RFile_Cd_sel   =  RFile_Cd_sel_DMaster;
            else
                 RFile_Cd_sel   =  RFile_Cd_sel_rALU;
       end: decoding_for_StageWB
       else
       begin :  decoding_for_StageIDLE
           // PC
           PC_wr            =  1'b0;
           PC_d_sel         =  PC_d_sel_X;
           // rIMM
    rIMM_wr          =  1'b0;
    rIMM_d_sel       =  rIMM_d_sel_X;
           // ALU
    ALU_b_sel        =  ALU_b_sel_X;
           ALU_op           =  ALU_OP_X;
           rALU_wr          =  1'b0;
    // Write back RFile
           RFile_Cwr        =  1'b0;
           RFile_Cidx_sel   =  RFile_Cidx_sel_X;
           RFile_Cd_sel     =  RFile_Cd_sel_X;
       end : decoding_for_StageIDLE

   end: control_signal_gen
///////////////////////////////////////////////////////////////////////////////  
//            -1: for Simulation
///////////////////////////////////////////////////////////////////////////////  
`ifdef   SIM
   parameter     STDIN  = 32'H8000_0000;
   parameter     STDOUT = 32'H8000_0001;
   parameter     STDERR = 32'H8000_0002;
   integer           log_fid;
   initial
   begin
      log_fid  =  $fopen("Kunlun_r_sc.log","w");
      if( log_fid==0 )
      begin
          $fwrite(STDERR,"Eror: can not open file Kunlun_r_sc.log!!!\n");
   $finish;
      end
   end
   integer           clk_counter   = 0;
   integer           instr_counter = 0;
   integer           fetch_cycle_count = 0;
   always @( posedge clk, negedge rst_n )
   begin
      if ( ~rst_n )  
         clk_counter <= 0;
      else begin
         clk_counter <= #1 clk_counter+1;
         if ( cur_stage==S_WB && next_stage==S_FETCH )
         begin
             instr_counter <=  instr_counter +1;
         end
         $fwrite(log_fid,"###### clock cycle: %0d  ######\n",clk_counter);
         $fwrite(STDOUT ,"-- %8d, ",clk_counter);
         $fwrite(log_fid,"instruction counter: %0d,  ", instr_counter);
         // cur_stage, next_stage
         $fwrite(log_fid,"current stage: %s, next stage: %s\n", cur_stage.name, next_stage.name );
  // ------ PC ------//
         if( (cur_stage==S_FETCH && next_stage==S_DECODE) || (cur_stage==S_WB) )
         begin
  $fwrite(log_fid,"*" );
         if( PC_wr )
      $fwrite(log_fid,"! " );
         else
      $fwrite(log_fid,"  " );
        
         end
  $fwrite(log_fid,"undefinedC: 32'H%08H, PC_wr: %d, PC_d_sel: %s, PC_d: 32'H%08H \n", PC,PC_wr,PC_d_sel.name, PC_d );

         if( cur_stage==S_FETCH )
         begin
  $fwrite(log_fid,"*! " );
         end
         $fwrite(log_fid,"i_read: %d, i_waitrequest: %d, i_address: 32'H%08H, i_readdata: 32'H%08H\n",
                      i_read, i_waitrequest, i_address, i_readdata );
         // ------ IR ------//
         if( (cur_stage==S_FETCH) && (next_stage==S_DECODE) )
  begin
  $fwrite(log_fid,"*! " );
  end
         $fwrite(log_fid,"IR: 32'H%08H, IR_wr: %d, IR_d: 32'H%08H \n", IR,IR_wr,IR_d);
         if( (cur_stage!=S_FETCH)&&(cur_stage!=S_IDLE) )
         begin
      disAS(log_fid , IR);
         end

  // ------ rA rB, rIMM ------ //
         if( cur_stage==S_DECODE )
         begin
  $fwrite(log_fid,"*! " );
         end
  $fwrite(log_fid,"RFile_Aidx: %0d, RFile_Aq: 32'H%08H, rA: 32'H%08H \n", RFile_Aidx,RFile_Aq,rA);
         if( cur_stage==S_DECODE )
         begin
  $fwrite(log_fid,"*! " );
         end
  $fwrite(log_fid,"RFile_Bidx: %0d, RFile_Bq: 32'H%08H, rB: 32'H%08H \n", RFile_Bidx,RFile_Bq,rB);
         if( cur_stage==S_DECODE )
         begin
  $fwrite(log_fid,"*" );
  if(rIMM_wr) $fwrite(log_fid,"! " );
         else        $fwrite(log_fid,"  " );
         end
  $fwrite(log_fid,"rIMM: 32'H%08H, rIMM_wr: %0d, rIMM_d_sel: %s, rIMM_d: 32'H%08H \n", rIMM,rIMM_wr,rIMM_d_sel.name, rIMM_d);
  // -----------ALU---------------//
         if( cur_stage==S_EXE )
         begin
  $fwrite(log_fid,"*  " );
         end
         $fwrite(log_fid,"ALU_q: 32'H%08H, ALU_op: %s, ALU_a: 32'H%08H, ALU_b: 32'H%08H, ALU_b_sel: %s\n",
                   ALU_q, ALU_op.name, ALU_a, ALU_b, ALU_b_sel.name);
         if( cur_stage==S_EXE )
         begin
  $fwrite(log_fid,"*" );
  if(rALU_wr) $fwrite(log_fid,"! " );
         else        $fwrite(log_fid,"  " );
         end
         $fwrite(log_fid,"rALU_wr: %0d, rALU: 32'H%08H \n", rALU_wr, rALU);
         // -----------MEM----------------//
         if( cur_stage==S_MEM)
         begin
  $fwrite(log_fid,"*" );
  if(d_read || d_write) $fwrite(log_fid,"! " );
         else                  $fwrite(log_fid,"  " );
  
         end
  $fwrite(log_fid,"d_read: %0d, d_readdata: 32'H%08H, d_write: %0d, d_writedata: 32'H%08H, d_address: 32'H%08H, d_byteenable: 4'b%04b, d_waitrequest: %0d\n",
                   d_read, d_readdata,d_write,d_writedata,d_address, d_byteenable, d_waitrequest);
         if( cur_stage==S_MEM)
         begin
  $fwrite(log_fid,"*" );
  if(rDMasterIn_wr) $fwrite(log_fid,"! " );
         else              $fwrite(log_fid,"  " );
         end
  $fwrite(log_fid,"data_from_DMaster: 32'H%08H, rDMasterIn_wr: %0d, rDMasterIn: 32'H%08H \n", data_from_DMaster, rDMasterIn_wr, rDMasterIn);
         // -----------WB----------------//
         if( cur_stage==S_WB )
         begin
  $fwrite(log_fid,"*" );
  if(RFile_Cwr    ) $fwrite(log_fid,"! " );
         else              $fwrite(log_fid,"  " );
         end
  $fwrite(log_fid,"RFile_Cwr: %d, RFile_Cidx_sel: %s, RFile_Cidx: %0d, RFile_Cd_sel: %s, RFile_Cd: 32'H%08H\n",
                   RFile_Cwr, RFile_Cidx_sel.name, RFile_Cidx, RFile_Cd_sel.name, RFile_Cd );
         $fwrite(log_fid,"RFile:\n");
  $fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
            RFile[ 0],RFile[ 1],RFile[ 2],RFile[ 3],
            RFile[ 4],RFile[ 5],RFile[ 6],RFile[ 7]          );
  $fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
            RFile[ 8],RFile[ 9],RFile[10],RFile[11],
            RFile[12],RFile[13],RFile[14],RFile[15]          );
  $fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
            RFile[16],RFile[17],RFile[18],RFile[19],
            RFile[20],RFile[21],RFile[22],RFile[23]          );
  $fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
            RFile[24],RFile[25],RFile[26],RFile[27],
            RFile[28],RFile[29],RFile[30],RFile[31]          );
         
         $fwrite(log_fid,"\n\n");
      end
   end
`endif

   
///////////////////////////////////////////////////////////////////////////////  
//               Functions                                                   //
///////////////////////////////////////////////////////////////////////////////  
function  [31: 0]  cmpge ( input [31: 0] A, input [31: 0] B );
begin
     cmpge =  (A[30: 0]>=B[30: 0]);
     if  ( (~A[31]) &   B[31]  )    cmpge =  32'd1;
     if  ( ( A[31]) & (~B[31]) )    cmpge =  32'd0;
end
endfunction
function       is_unkown_instr( input [31: 0] ir );
begin
    if  (   (ir[5:0] == `IR_J_CALL  )  ||
            (ir[5:0] == `IR_J_JMPI  )  ||
            (ir[5:0] == `IR_I_LDBU  )  ||
            (ir[5:0] == `IR_I_ADDI  )  ||
            (ir[5:0] == `IR_I_STB   )  ||
            (ir[5:0] == `IR_I_BR    )  ||
            (ir[5:0] == `IR_I_LDB   )  ||
            (ir[5:0] == `IR_I_CMPGEI)  ||
            (ir[5:0] == `IR_I_LDHU  )  ||
            (ir[5:0] == `IR_I_ANDI  )  ||
            (ir[5:0] == `IR_I_STH   )  ||
            (ir[5:0] == `IR_I_BGE   )  ||
            (ir[5:0] == `IR_I_LDH   )  ||
            (ir[5:0] == `IR_I_CMPLTI)  ||
            //(ir[5:0] == `IR_I_INITDA)  ||
            (ir[5:0] == `IR_I_ORI   )  ||
            (ir[5:0] == `IR_I_STW   )  ||
            (ir[5:0] == `IR_I_BLT   )  ||
            (ir[5:0] == `IR_I_LDW   )  ||
            (ir[5:0] == `IR_I_CMPNEI)  ||
            //(ir[5:0] == `IR_I_FLUSHDA) ||
            (ir[5:0] == `IR_I_XORI  )  ||
            (ir[5:0] == `IR_I_BNE   )  ||
            (ir[5:0] == `IR_I_CMPEQI)  ||
            //(ir[5:0] == `IR_I_LDBUIO)  ||
            (ir[5:0] == `IR_I_MULI  )  ||
            //(ir[5:0] == `IR_I_STBIO )  ||
            (ir[5:0] == `IR_I_BEQ   )  ||
            //(ir[5:0] == `IR_I_LDBIO )  ||
            (ir[5:0] == `IR_I_CMPGEUI) ||
            //(ir[5:0] == `IR_I_LDHUIO ) ||
            (ir[5:0] == `IR_I_ANDHI  ) ||
            //(ir[5:0] == `IR_I_STHIO  ) ||
            (ir[5:0] == `IR_I_BGEU   ) ||
            //(ir[5:0] == `IR_I_LDHIO  ) ||
            (ir[5:0] == `IR_I_CMPLTUI) ||
            //(ir[5:0] == `IR_I_INITD   )||
            (ir[5:0] == `IR_I_ORHI    )||
            //(ir[5:0] == `IR_I_STWIO   )||
            (ir[5:0] == `IR_I_BLTU    )||
            //(ir[5:0] == `IR_I_LDWIO   )||
            //(ir[5:0] == `IR_I_RDPRS   )||
            //(ir[5:0] == `IR_I_FLUSHD  )||
            (ir[5:0] == `IR_I_XORHI   )||
     ( (ir[5:0]==6'h3A)&&
              (ir[16:11]==`IR_R_ERET  )||
              (ir[16:11]==`IR_R_ROLI  )||
              (ir[16:11]==`IR_R_ROL   )||
              //(ir[16:11]==`IR_R_FLUSHP)||
              (ir[16:11]==`IR_R_RET   )||
              (ir[16:11]==`IR_R_NOR   )||
              //(ir[16:11]==`IR_R_MULXUU)||
              (ir[16:11]==`IR_R_CMPGE )||
              //(ir[16:11]==`IR_R_BRET  )||
              (ir[16:11]==`IR_R_ROR   )||
              //(ir[16:11]==`IR_R_FLUSHI)||
              (ir[16:11]==`IR_R_JMP   )||
              (ir[16:11]==`IR_R_AND   )||
              (ir[16:11]==`IR_R_CMPLT )||
              (ir[16:11]==`IR_R_SLLI  )||
              (ir[16:11]==`IR_R_SLL   )||
              //(ir[16:11]==`IR_R_WRPRS )||
              (ir[16:11]==`IR_R_OR    )||
              //(ir[16:11]==`IR_R_MULXSU)||
              (ir[16:11]==`IR_R_CMPNE )||
              (ir[16:11]==`IR_R_SRLI  )||
              (ir[16:11]==`IR_R_SRL   )||
              (ir[16:11]==`IR_R_NEXTPC)||
              (ir[16:11]==`IR_R_CALLR )||
              (ir[16:11]==`IR_R_XOR   )||
              //(ir[16:11]==`IR_R_MULXSS)||
              (ir[16:11]==`IR_R_CMPEQ )||
              //(ir[16:11]==`IR_R_DIVU  )||
              //(ir[16:11]==`IR_R_DIV   )||
              //(ir[16:11]==`IR_R_RDCTL )||
              (ir[16:11]==`IR_R_MUL   )||
              (ir[16:11]==`IR_R_CMPGEU)||
              //(ir[16:11]==`IR_R_INITI )||
              //(ir[16:11]==`IR_R_TRAP  )||
              //(ir[16:11]==`IR_R_WRCTL )||
              (ir[16:11]==`IR_R_CMPLTU)||
              (ir[16:11]==`IR_R_ADD   )||
              //(ir[16:11]==`IR_R_BREAK )||
              //(ir[16:11]==`IR_R_SYNC  )||
              (ir[16:11]==`IR_R_SUB   )||
              (ir[16:11]==`IR_R_SRAI  )||
              (ir[16:11]==`IR_R_SRA   ) )
   )
       is_unkown_instr = 1'b0;
    else
       is_unkown_instr = 1'b1;
end
endfunction
function  [31: 0]  cmplt ( input [31: 0] A, input [31: 0] B );
begin
     cmplt  =  (A[30: 0]<B[30: 0]);
     if  ( ( A[31]) & (~B[31]) )    cmplt =  32'd1;
     if  ( (~A[31]) &   B[31]  )    cmplt =  32'd0;
end
endfunction
function  [31: 0]  rol   ( input [31: 0] A, input [ 4: 0] B );
begin
    case  (  B  )
       5'h0  :    rol =     A;
       5'h1  :    rol =  { A[30: 0], A[31]    };
       5'h2  :    rol =  { A[29: 0], A[31:30] };
       5'h3  :    rol =  { A[28: 0], A[31:29] };
       5'h4  :    rol =  { A[27: 0], A[31:28] };
       5'h5  :    rol =  { A[26: 0], A[31:27] };
       5'h6  :    rol =  { A[25: 0], A[31:26] };
       5'h7  :    rol =  { A[24: 0], A[31:25] };
       5'h8  :    rol =  { A[23: 0], A[31:24] };
       5'h9  :    rol =  { A[22: 0], A[31:23] };
       5'h10 :    rol =  { A[21: 0], A[31:22] };
       5'h11 :    rol =  { A[20: 0], A[31:21] };
       5'h12 :    rol =  { A[19: 0], A[31:20] };
       5'h13 :    rol =  { A[18: 0], A[31:19] };
       5'h14 :    rol =  { A[17: 0], A[31:18] };
       5'h15 :    rol =  { A[16: 0], A[31:17] };
       5'h16 :    rol =  { A[15: 0], A[31:16] };
       5'h17 :    rol =  { A[14: 0], A[31:15] };
       5'h18 :    rol =  { A[13: 0], A[31:14] };
       5'h19 :    rol =  { A[12: 0], A[31:13] };
       5'h20 :    rol =  { A[11: 0], A[31:12] };
       5'h21 :    rol =  { A[10: 0], A[31:11] };
       5'h22 :    rol =  { A[ 9: 0], A[31:10] };
       5'h23 :    rol =  { A[ 8: 0], A[31: 9] };
       5'h24 :    rol =  { A[ 7: 0], A[31: 8] };
       5'h25 :    rol =  { A[ 6: 0], A[31: 7] };
       5'h26 :    rol =  { A[ 5: 0], A[31: 6] };
       5'h27 :    rol =  { A[ 4: 0], A[31: 5] };
       5'h28 :    rol =  { A[ 3: 0], A[31: 4] };
       5'h29 :    rol =  { A[ 2: 0], A[31: 3] };
       5'h30 :    rol =  { A[ 1: 0], A[31: 2] };
       5'h31 :    rol =  { A[ 0: 0], A[31: 1] };
    endcase
end
endfunction

function  [31: 0]  ror   ( input [31: 0] A, input [ 4: 0] B );
begin
    case  (  B  )
       5'h0  :    ror =     A;
       5'h1  :    ror =  { A[ 0: 0], A[31: 1] };
       5'h2  :    ror =  { A[ 1: 0], A[31: 2] };
       5'h3  :    ror =  { A[ 2: 0], A[31: 3] };
       5'h4  :    ror =  { A[ 3: 0], A[31: 4] };
       5'h5  :    ror =  { A[ 4: 0], A[31: 5] };
       5'h6  :    ror =  { A[ 5: 0], A[31: 6] };
       5'h7  :    ror =  { A[ 6: 0], A[31: 7] };
       5'h8  :    ror =  { A[ 7: 0], A[31: 8] };
       5'h9  :    ror =  { A[ 8: 0], A[31: 9] };
       5'h10 :    ror =  { A[ 9: 0], A[31:10] };
       5'h11 :    ror =  { A[10: 0], A[31:11] };
       5'h12 :    ror =  { A[11: 0], A[31:12] };
       5'h13 :    ror =  { A[12: 0], A[31:13] };
       5'h14 :    ror =  { A[13: 0], A[31:14] };
       5'h15 :    ror =  { A[14: 0], A[31:15] };
       5'h16 :    ror =  { A[15: 0], A[31:16] };
       5'h17 :    ror =  { A[16: 0], A[31:17] };
       5'h18 :    ror =  { A[17: 0], A[31:18] };
       5'h19 :    ror =  { A[18: 0], A[31:19] };
       5'h20 :    ror =  { A[19: 0], A[31:20] };
       5'h21 :    ror =  { A[20: 0], A[31:21] };
       5'h22 :    ror =  { A[21: 0], A[31:22] };
       5'h23 :    ror =  { A[22: 0], A[31:23] };
       5'h24 :    ror =  { A[23: 0], A[31:24] };
       5'h25 :    ror =  { A[24: 0], A[31:25] };
       5'h26 :    ror =  { A[25: 0], A[31:26] };
       5'h27 :    ror =  { A[26: 0], A[31:27] };
       5'h28 :    ror =  { A[27: 0], A[31:28] };
       5'h29 :    ror =  { A[28: 0], A[31:29] };
       5'h30 :    ror =  { A[29: 0], A[31:30] };
       5'h31 :    ror =  { A[30: 0], A[31:31] };
    endcase
end
endfunction
task  disAS( input integer fid, input [31: 0] instr );
   reg  [ 5: 0] i_op;
   reg  [ 5: 0] i_imm5;
   reg  [ 5: 0] i_opx;
   reg  [ 5: 0] i_c;
   reg  [ 5: 0] i_b;
   reg  [ 5: 0] i_a;
   reg  [15: 0] i_imm16;
   reg  [25: 0] i_imm26;
   reg          R_flag;
   reg          I_flag;
   reg          J_flag;
   begin
      i_op   = instr[ 5: 0];
      i_imm5 = instr[10: 6];
      i_opx  = instr[16:11];
      i_c    = instr[21:17];
      i_b    = instr[26:22];
      i_a    = instr[31:27];
      i_imm16= instr[21: 6];
      i_imm26= instr[31: 6];
      R_flag =  ( i_op==6'h3A );
      J_flag =  ( (i_op==`IR_J_CALL) || (i_op==`IR_J_JMPI) );
      I_flag = !( R_flag || J_flag );
      $fwrite( fid, "Instruction:   ");
      if( R_flag==1'b1 ) // R-type Instruction
      begin
          case ( i_opx )
             `IR_R_ROLI   :  $fwrite(fid," roli r%0d, r%0d, %0d\n",
                                            i_c,i_a,i_imm5);
             `IR_R_ROL    :  $fwrite(fid," rol r%0d, r%0d, r%0d\n",
                                            i_c,i_a,i_b[4:0]);
             `IR_R_RET    :  $fwrite(fid," ret \n");
             `IR_R_NOR    :  $fwrite(fid," nor r%0d, r%0d, r%0d\n",
                                               i_c,i_a,i_b);
             `IR_R_CMPGE  :  $fwrite(fid," cmpge r%0d, r%0d, r%0d\n",
                                                i_c,i_a,i_b);
             `IR_R_ROR    :  $fwrite(fid," ror r%0d, r%0d, r%0d\n",
                                          i_c,i_a,i_b[4:0]);
             `IR_R_JMP    :  $fwrite(fid," jmp r%0d\n", i_a);
             `IR_R_AND    :  $fwrite(fid," and r%0d, r%0d, r%0d\n",
                                               i_c,i_a,i_b);
             `IR_R_CMPLT  :  $fwrite(fid," cmplt r%0d, r%0d, r%0d\n",
                                               i_c,i_a,i_b);
             `IR_R_SLLI   :  $fwrite(fid," slli r%0d, r%0d, %0d\n",
                                             i_c,i_a,i_imm5);
             `IR_R_SLL    :  $fwrite(fid," sll r%0d, r%0d, r%0d\n",
                                          i_c,i_a,i_b[4:0]);
             `IR_R_OR     :  $fwrite(fid," or r%0d, r%0d, r%0d\n",
                                               i_c,i_a,i_b);
             `IR_R_CMPNE  :  $fwrite(fid," cmpne r%0d, r%0d, r%0d\n",
                                                i_c,i_a,i_b);
             `IR_R_SRLI   :  $fwrite(fid," srli r%0d, r%0d, %0d\n",
                                            i_c,i_a,i_imm5);
             `IR_R_SRL    :  $fwrite(fid," srl r%0d, r%0d, r%0d\n",
                                          i_c,i_a,i_b[4:0]);
             `IR_R_NEXTPC :  $fwrite(fid," nextpc r%0d\n",i_c);
             `IR_R_CALLR  :  $fwrite(fid," callr r%0d\n",i_a);
             `IR_R_XOR    :  $fwrite(fid," xor r%0d, r%0d, r%0d\n",
                                              i_c,i_a,i_b);
             `IR_R_CMPEQ  :  $fwrite(fid," cmpeq r%0d, r%0d, r%0d\n",
                                                i_c,i_a,i_b);
             `IR_R_MUL    :  $fwrite(fid," mul r%0d, r%0d, r%0d\n",
                                                 i_c,i_a,i_b);
             `IR_R_CMPGEU :  $fwrite(fid," cmpgeu r%0d, r%0d, r%0d\n",
                                                 i_c,i_a,i_b);
             `IR_R_CMPLTU :  $fwrite(fid," cmpltu r%0d, r%0d, r%0d\n",
                                                 i_c,i_a,i_b);
             `IR_R_ADD    :  $fwrite(fid," add r%0d, r%0d, r%0d\n",
                                               i_c,i_a,i_b);
             `IR_R_SUB    :  $fwrite(fid," sub r%0d, r%0d, r%0d\n",
                                              i_c,i_a,i_b);
             `IR_R_SRAI   :  $fwrite(fid," srai r%0d, r%0d, %0d\n",
                                             i_c,i_a,i_imm5);
             `IR_R_SRA    :  $fwrite(fid," sra r%0d, r%0d, r%0d\n",
                                             i_c,i_a,i_b[4:0]);
             `IR_R_DIV    :  $fwrite(fid," div r%0d, r%0d, r%0d\n",
                                             i_c,i_a,i_b[4:0]);
      default      :  $fwrite(fid," Unkown R-type Instruction\n");
   endcase
      end
      else if( I_flag==1'b1 )
      begin
          case ( i_op )
              `IR_I_LDBU   : $fwrite(fid," ldbu r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_ADDI   : $fwrite(fid," addi r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_STB    : $fwrite(fid," stb r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_BR     : $fwrite(fid," br %0d\n", $signed(i_imm16));
              `IR_I_LDB    : $fwrite(fid," ldb r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_CMPGEI : $fwrite(fid," cmpgei r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_LDHU   : $fwrite(fid," ldhu r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_ANDI   : $fwrite(fid," andi r%0d, r%0d, %0d\n",
                                 i_b, i_a, i_imm16 );
              `IR_I_STH    : $fwrite(fid," sth r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_BGE    : $fwrite(fid," bge r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_LDH    : $fwrite(fid," ldh r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_CMPLTI : $fwrite(fid," cmplti r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_ORI    : $fwrite(fid," ori r%0d, r%0d, %0d\n",
                                 i_b, i_a, i_imm16 );
              `IR_I_STW    : $fwrite(fid," stw r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_BLT    : $fwrite(fid," blt r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_LDW    : $fwrite(fid," ldw r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_CMPNEI : $fwrite(fid," cmpnei r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_XORI   : $fwrite(fid," xori r%0d, r%0d, %0d\n",
                                 i_b, i_a, i_imm16 );
              `IR_I_BNE    : $fwrite(fid," bne r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_CMPEQI : $fwrite(fid," cmpeqi r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_LDBUIO : $fwrite(fid," ldbuio r%0d, %0d(r%0d)\n",
                                 i_b, $signed(i_imm16), i_a);
              `IR_I_MULI   : $fwrite(fid," muli  r%0d, r%0d, %0d\n",
                                 i_b,i_a, $signed(i_imm16));
              `IR_I_BEQ    : $fwrite(fid," beq r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_CMPGEUI: $fwrite(fid," cmpgeui r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_ANDHI  : $fwrite(fid," andhi   r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_BGEU   : $fwrite(fid," bgeu r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_CMPLTUI: $fwrite(fid," cmpltui r%0d, r%0d, %0d\n",
                                 i_b, i_a, $signed(i_imm16));
              `IR_I_ORHI   : $fwrite(fid," orhi r%0d, r%0d, %0d\n",
                                 i_b, i_a, i_imm16 );
              `IR_I_BLTU   : $fwrite(fid," bltu r%0d, r%0d, %0d\n",
                                 i_a, i_b, $signed(i_imm16));
              `IR_I_XORHI  : $fwrite(fid," xorhi r%0d, r%0d, %0d\n",
                                 i_b, i_a, i_imm16 );
        default     : $fwrite(fid," Unkown I-type Instruction\n");
   endcase
      end
      else if( J_flag==1'b1 )
      begin
          case  ( i_op )
             `IR_J_CALL   :  $fwrite(fid," call %0d\n", {i_imm26,2'b00} );
             `IR_J_JMPI   :  $fwrite(fid," jmpi %0d\n", {i_imm26,2'b00} );
        default    :  $fwrite(fid," Unkown J-type Instruction\n");
   endcase
      end
      else
      begin
            $fwrite(fid," Unkown J-type Instruction\n");
      end
  end
endtask
endmodule
发表于 2016-12-19 22:49:19 | 显示全部楼层
这个值得阅读思考一下
发表于 2016-12-24 17:27:27 | 显示全部楼层
保存下来,慢慢学习
发表于 2016-12-26 18:42:08 | 显示全部楼层
书和谚语一样,都是从它们经历的年代所留下的印记和评价中获得重要价值的。我必须多知道些
您需要登录后才可以回帖 登录 | 入住IC小镇

本版积分规则

关闭

站长推荐上一条 /1 下一条

星光电子深圳专业单片机IC解密

QQ|Archiver|手机版|小黑屋|IC设计小镇 ( 苏ICP备10008526号  

GMT+8, 2017-4-26 08:25 , Processed in 0.109743 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表