@@ -263,6 +263,11 @@ module ARM7TMDI (
263263 instr_boundary <= control_signals.pipeline_advance;
264264 end
265265
266+
267+ wire pc_modified = (control_signals.ALU_writeback == ALU_WB_REG_RD && decoder_bus.decoded_regs.Rd == 4'd15 ) ||
268+ (control_signals.ALU_writeback == ALU_WB_REG_RN && decoder_bus.decoded_regs.Rn == 4'd15 ) ||
269+ (control_signals.ALU_writeback == ALU_WB_REG_RP && control_signals.Rp_imm == 4'd15 );
270+
266271 // ======================================================
267272 // Memory Module
268273 // ======================================================
@@ -369,9 +374,7 @@ module ARM7TMDI (
369374 flush_req <= 1'b1 ;
370375 end
371376
372- if ((control_signals.ALU_writeback == ALU_WB_REG_RD && decoder_bus.decoded_regs.Rd == 4'd15 ) ||
373- (control_signals.ALU_writeback == ALU_WB_REG_RN && decoder_bus.decoded_regs.Rn == 4'd15 ) ||
374- (control_signals.ALU_writeback == ALU_WB_REG_RP && control_signals.Rp_imm == 4'd15 )) begin
377+ if (pc_modified) begin
375378
376379 $display (" ALU writeback to PC (R15) detected. ALU_writeback=%0d , Rd=%0d , Rn=%0d " ,
377380 control_signals.ALU_writeback, decoder_bus.decoded_regs.Rd,
@@ -388,9 +391,8 @@ module ARM7TMDI (
388391 unique case (execution_mode)
389392 MODE_ARM : begin
390393 // PC = PC + 4
391- `WRITE_REG (regs, cpu_mode, 15 , read_reg (regs, cpu_mode, 15 ) + 32'd4 , execution_mode,
392- 1'b0 )
393- $display (" Incrementing PC to: %0d " , read_reg (regs, cpu_mode, 15 ) + 32'd4 );
394+ `WRITE_REG (regs, cpu_mode, 15 , bus.addr + 32'd4 , execution_mode, 1'b0 )
395+ $display (" Incrementing PC to: %0d " , bus.addr + 32'd4 );
394396 $fflush ();
395397 end
396398 MODE_THUMB : begin
@@ -492,36 +494,57 @@ module ARM7TMDI (
492494 end else begin
493495 $display (" [CPU] addr=%0d " , bus.addr);
494496
495- unique case (control_signals.addr_bus_src)
496- ADDR_SRC_NONE : begin
497- // bus.addr <= 32'd0;
498- end
499-
500- ADDR_SRC_ALU : begin
501- $display (" [CPU] Driving address bus with ALU result: %0d " , alu_bus.result);
497+ if (control_signals.pipeline_advance) begin
498+ bus.addr <= bus.addr + 32'd4 ;
499+ if (pc_modified) begin
502500 bus.addr <= alu_bus.result;
501+ end else if (flush_req_pending) begin
502+ bus.addr <= read_reg (regs, cpu_mode, 15 );
503+ $display (
504+ " Pipeline advance with pending flush request, setting address bus to PC value: 0x%08x " ,
505+ read_reg (regs, cpu_mode, 15 ));
503506 end
507+ end else begin
504508
505- ADDR_SRC_PC : begin
506- $display (" Setting address bus to PC value: 0x%08x " , read_reg (regs, cpu_mode, 15 ));
507- unique case (execution_mode)
508- MODE_ARM : bus.addr <= read_reg (regs, cpu_mode, 15 ) & ~ 32'd3 ;
509- MODE_THUMB : bus.addr <= read_reg (regs, cpu_mode, 15 ) & ~ 32'd1 ;
510- endcase
511- end
509+ unique case (control_signals.addr_bus_src)
510+ ADDR_SRC_NONE : begin
511+ // bus.addr <= 32'd0;
512+ end
512513
513- ADDR_SRC_INCR : begin
514- unique case (execution_mode)
515- MODE_ARM : begin
516- bus.addr <= bus.addr + 32'd4 ;
517- end
518- MODE_THUMB : begin
519- bus.addr <= bus.addr + 32'd4 ;
520- $display (" Incrementing address bus for Thumb mode: new addr=%0d " , bus.addr);
521- end
522- endcase
523- end
524- endcase
514+ ADDR_SRC_ALU : begin
515+ $display (" [CPU] Driving address bus with ALU result: %0d " , alu_bus.result);
516+ bus.addr <= alu_bus.result;
517+ end
518+
519+ ADDR_SRC_PC : begin
520+ $display (" Setting address bus to PC value: 0x%08x " , read_reg (regs, cpu_mode, 15 ));
521+ unique case (execution_mode)
522+ MODE_ARM : bus.addr <= read_reg (regs, cpu_mode, 15 ) & ~ 32'd3 ;
523+ MODE_THUMB : bus.addr <= read_reg (regs, cpu_mode, 15 ) & ~ 32'd1 ;
524+ endcase
525+ end
526+
527+ ADDR_SRC_PC_RESTORE : begin
528+ $display (" Restoring address bus from PC value: 0x%08x " , read_reg (regs, cpu_mode, 15 ));
529+ unique case (execution_mode)
530+ MODE_ARM : bus.addr <= read_reg (regs, cpu_mode, 15 ) - 32'd4 & ~ 32'd3 ;
531+ MODE_THUMB : bus.addr <= read_reg (regs, cpu_mode, 15 ) - 32'd4 & ~ 32'd1 ;
532+ endcase
533+ end
534+
535+ ADDR_SRC_INCR : begin
536+ unique case (execution_mode)
537+ MODE_ARM : begin
538+ bus.addr <= bus.addr + 32'd4 ;
539+ end
540+ MODE_THUMB : begin
541+ bus.addr <= bus.addr + 32'd4 ;
542+ $display (" Incrementing address bus for Thumb mode: new addr=%0d " , bus.addr);
543+ end
544+ endcase
545+ end
546+ endcase
547+ end
525548 end
526549 end
527550
0 commit comments