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

📄 2interpr.mod

📁 大型risc处理器设计源代码,这是书中的代码 基于流水线的risc cpu设计
💻 MOD
📖 第 1 页 / 共 5 页
字号:
                                                                                 i0298
  //                                                                             i0299
  // Fetch new instruction:                                                      i0300
  //   load instruction register;                                                i0301
  //   update Fetch-PC, Last-PC, and Next-PC                                     i0302
  //                                                                             i0303
  task Fetch_Instruction;                                                        i0304
  begin                                                                          i0305
    IR  = Read_Memory(FPC << 2, `ACC_QBYTE);   // load instruction register      i0306
    LPC = FPC;                                 // set Last-PC                    i0307
    FPC = NPC;                                 // set Fetch-PC to new address    i0308
    NPC = NPC + 1;                             // increment Next-PC              i0309
  end                                                                            i0310
  endtask                                                                        i0311
                                                                                 i0312
  //                                                                             i0313
  // Execute instruction                                                         i0314
  //                                                                             i0315
  task Execute_Instruction;                                                      i0316
  begin                                                                          i0317
    case(`IR_FORMAT)                                                             i0318
      `FORMAT_ALU:  Execute_ALU;                // ALU instruction               i0319
      `FORMAT_MACC: Execute_MACC;               // memory access                 i0320
      `FORMAT_MISC: Execute_MISC;               // miscellaneous                 i0321
      `FORMAT_CALL: Execute_CALL;               // CALL instruction              i0322
      default:      SYSTEM_STATUS = `INS_ERR;   // cannot occur                  i0323
    endcase                                                                      i0324
  end                                                                            i0325
  endtask                                                                        i0326
                                                                                 i0327
  //                                                                             i0328
  // Execute ALU instruction:                                                    i0329
  //   determine operands and extend sign to 33 bits;                            i0330
  //   execute ALU operation                                                     i0331
  //     bit 32 to determine carry                                               i0332
  //     set switches if necessary;                                              i0333
  //   write result to destination register                                      i0334
  //                                                                             i0335
  task Execute_ALU;                                                              i0336
    reg [32:0] ALU_IN1,                                                          i0337
               ALU_IN2,                                                          i0338
               ALU_OUT;                                                          i0339
  begin                                                                          i0340
    ALU_IN1[31:0] = Read_Register(`IR_ALURS1);                                   i0341
    ALU_IN1[32]   = ALU_IN1[31];                                                 i0342
    if (`IR_ALUS2_FORMAT == `ALUS2_IMM) begin                                    i0343
      ALU_IN2[13: 0] = `IR_ALUIS2;                                               i0344
      ALU_IN2[32:14] = {19{ALU_IN2[13]}};                                        i0345
    end                                                                          i0346
    else begin                                                                   i0347
      ALU_IN2[31: 0] = Read_Register(`IR_ALURS2);                                i0348
      ALU_IN2[32]    = ALU_IN2[31];                                              i0349
    end                                                                          i0350
    ALU_OUT = {33{1'bx}};                 // output undefined                    i0351
    case(`IR_ALUOP)                                                              i0352
      `ALU_AND:  ALU_OUT = ALU_IN1 & ALU_IN2;                                    i0353
      `ALU_OR:   ALU_OUT = ALU_IN1 | ALU_IN2;                                    i0354
      `ALU_XOR:  ALU_OUT = ALU_IN1 ^ ALU_IN2;                                    i0355
      `ALU_LSL:  ALU_OUT = {1'b0, ALU_IN1[31:0]} << ALU_IN2[4:0];                i0356
      `ALU_LSR:  begin                                                           i0357
                   ALU_OUT[31:0] = ALU_IN1[31:0] >> ALU_IN2[4:0];                i0358
                   ALU_OUT[32] = ALU_IN2[4:0] ? ALU_IN1[ALU_IN2[4:0] - 1] : 0;   i0359
                 end                                                             i0360
      `ALU_ASR:  begin                                                           i0361
                   ALU_OUT = {33{ALU_IN1[31]}} << (32 - ALU_IN2[4:0]);           i0362
                   ALU_OUT = ALU_OUT | (ALU_IN1[31:0] >> ALU_IN2[4:0]);          i0363
                   ALU_OUT[32] = ALU_IN2[4:0] ? ALU_IN1[ALU_IN2[4:0] - 1] : 0;   i0364
                 end                                                             i0365
      `ALU_ROT:  begin                                                           i0366
                   ALU_OUT = ALU_IN1 << (32 - ALU_IN2[4:0]);                     i0367
                   ALU_OUT = ALU_OUT | (ALU_IN1[31:0] >> ALU_IN2[4:0]);          i0368
                   ALU_OUT[32] = ALU_IN2[4:0] ? ALU_IN1[ALU_IN2[4:0] - 1] : 0;   i0369
                 end                                                             i0370
      `ALU_ADD:  ALU_OUT = ALU_IN1 + ALU_IN2;                                    i0371
      `ALU_ADDC: ALU_OUT = ALU_IN1 + ALU_IN2 + `CFLAG;                           i0372
      `ALU_SUB:  ALU_OUT = ALU_IN1 - ALU_IN2;                                    i0373
      `ALU_SUBC: ALU_OUT = ALU_IN1 - ALU_IN2 - `CFLAG;                           i0374
      `ALU_MUL:  ALU_OUT = ALU_IN1[15:0] * ALU_IN2[15:0];                        i0375
      `ALU_DIV:  if (|ALU_IN2[31:0]) ALU_OUT = ALU_IN1[31:0] / ALU_IN2[31:0];    i0376
      default:   SYSTEM_STATUS = `INS_ERR;                                       i0377
    endcase                                                                      i0378
    if (`IR_ALUFLAGS == `ALUFLAGS_CALC) begin                                    i0379
      `NFLAG = ALU_OUT[31];                       // N-flag                      i0380
      `ZFLAG = ~(|ALU_OUT[31:0]);                 // Z-flag                      i0381
      casez(`IR_ALUOP)                            // C-flag                      i0382
        `ALUF_CSHF: `CFLAG =   ALU_OUT[32];                                      i0383
        `ALUF_CADD: `CFLAG =   ALU_OUT[32] ^ ALU_IN1[32] ^  ALU_IN2[32];         i0384
        `ALUF_CSUB: `CFLAG = ~(ALU_OUT[32] ^ ALU_IN1[32] ^ ~ALU_IN2[32]);        i0385
        default:    `CFLAG = 0;                                                  i0386
      endcase                                                                    i0387
      casez(`IR_ALUOP)                            // V-flag                      i0388
        `ALUF_OVER: `VFLAG = ^ALU_OUT[32:31];                                    i0389
        default:    `VFLAG = 0;                                                  i0390
      endcase                                                                    i0391
    end                                                                          i0392
    Write_Register(`IR_ALURD, ALU_OUT[31:0], `SWIACT);  // result                i0393
    LAST_CTR = 1'b0;                                    // erase CTR status      i0394
  end                                                                            i0395
  endtask                                                                        i0396
                                                                                 i0397
  //                                                                             i0398
  // Execute memory access instructions:                                         i0399
  //   determine data address by adding address operands,                        i0400
  //   consider sign of immediate index;                                         i0401
  //   Load:                                                                     i0402
  //     load data according to access width;                                    i0403
  //     extend sign if necessary;                                               i0404
  //     store result in write delay pipeline and                                i0405
  //     note data read access;                                                  i0406
  //   Store:                                                                    i0407
  //     write register according to access width and                            i0408
  //     note data write access;                                                 i0409
  //   Swap:                                                                     i0410
  //     write register to memory;                                               i0411
  //     write old memory contents delayed into register and                     i0412
  //     note data accesses;                                                     i0413
  //                                                                             i0414
  task Execute_MACC;                                                             i0415
    reg [31:0] ADDR,                                                             i0416
               RDAT,                                                             i0417
               WDAT;                                                             i0418
  begin                                                                          i0419
    if (`IR_MACCS2_FORMAT == `MACCS2_IMM) begin                                  i0420
      ADDR[15: 0] = {`IR_MACC_IS2, 2'b00};        // immediate address           i0421
      ADDR[31:16] = {16{ADDR[15]}};                                              i0422
      casez(`IR_MACC_ALIGN)                                                      i0423
        `MACC_ALIGN_B: ADDR = ADDR + (`IR_MACC_ALIGN & 3);                       i0424
        `MACC_ALIGN_D: ADDR = ADDR + (`IR_MACC_ALIGN & 2);                       i0425
      endcase                                                                    i0426
    end                                                                          i0427
    else ADDR = Read_Register(`IR_MACC_RS2);      // address from register       i0428
    ADDR = ADDR + Read_Register(`IR_MACC_RS1);    // compute address             i0429
    casez(`IR_MACC_ALIGN)                         // note access width           i0430
      `MACC_ALIGN_B: PROTO_SIZE = `ACC_BYTE;      //   8-bit access              i0431
      `MACC_ALIGN_D: PROTO_SIZE = `ACC_DBYTE;     //   16-bit access             i0432
      `MACC_ALIGN_Q: PROTO_SIZE = `ACC_QBYTE;     //   32-bit access             i0433
    endcase                                                                      i0434
    casez(`IR_MACCEP)                                                            i0435
      `MACC_LOAD: begin                                                          i0436
          casez(`IR_MACC_ALIGN)                                                  i0437
            `MACC_ALIGN_B: begin                                                 i0438
                RDAT = Read_Memory(ADDR, `ACC_BYTE);                             i0439
                if (`IR_MACC_SFLAG == `MACC_SIGNED)                              i0440
                  RDAT[31:8] = {24{RDAT[7]}};                                    i0441
                else RDAT[31:8] = 24'b0;                                         i0442
              end                                                                i0443
            `MACC_ALIGN_D: begin                                                 i0444
                RDAT = Read_Memory(ADDR, `ACC_DBYTE);                            i0445
                if (`IR_MACC_SFLAG == `MACC_SIGNED)                              i0446

⌨️ 快捷键说明

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