📄 2interpr.mod
字号:
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 + -