OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_exec.v] - Diff between revs 37 and 39

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 37 Rev 39
Line 196... Line 196...
reg         d_mem_load_q;
reg         d_mem_load_q;
 
 
// Delayed NMI
// Delayed NMI
reg         nmi_q;
reg         nmi_q;
 
 
 
// Exception/Interrupt was last instruction
 
reg         exc_last_q;
 
 
// SIM PUTC
// SIM PUTC
`ifdef SIM_EXT_PUTC
`ifdef SIM_EXT_PUTC
    reg [7:0] putc_q;
    reg [7:0] putc_q;
`endif
`endif
 
 
Line 212... Line 215...
    .op_i(ex_alu_func_q),
    .op_i(ex_alu_func_q),
 
 
    // Operands
    // Operands
    .a_i(ex_alu_a_q),
    .a_i(ex_alu_a_q),
    .b_i(ex_alu_b_q),
    .b_i(ex_alu_b_q),
    .c_i(sr_q[`OR32_SR_CY]),
    .c_i(sr_q[`SR_CY]),
 
 
    // Result
    // Result
    .p_o(ex_result_w),
    .p_o(ex_result_w),
 
 
    // Carry
    // Carry
Line 494... Line 497...
begin
begin
    next_sr_r = sr_q;
    next_sr_r = sr_q;
 
 
    // Update SR.F
    // Update SR.F
    if (alu_flag_update_w)
    if (alu_flag_update_w)
        next_sr_r[`OR32_SR_F] = compare_result_r;
        next_sr_r[`SR_F] = compare_result_r;
 
 
    // Latch carry if updated
    // Latch carry if updated
    if (alu_carry_update_w)
    if (alu_carry_update_w)
        next_sr_r[`OR32_SR_CY] = alu_carry_out_w;
        next_sr_r[`SR_CY] = alu_carry_out_w;
 
 
    // If valid instruction, check if SR needs updating
    // If valid instruction, check if SR needs updating
    if (execute_inst_r & ~stall_inst_r)
    if (execute_inst_r & ~stall_inst_r)
    begin
    begin
      case (1'b1)
      case (1'b1)
Line 513... Line 516...
          `SPR_REG_SR:
          `SPR_REG_SR:
          begin
          begin
              next_sr_r = reg_rb_r;
              next_sr_r = reg_rb_r;
 
 
              // Don't store cache flush requests
              // Don't store cache flush requests
              next_sr_r[`OR32_SR_ICACHE_FLUSH] = 1'b0;
              next_sr_r[`SR_ICACHE_FLUSH] = 1'b0;
              next_sr_r[`OR32_SR_DCACHE_FLUSH] = 1'b0;
              next_sr_r[`SR_DCACHE_FLUSH] = 1'b0;
          end
          end
          default:
          default:
            ;
            ;
          endcase
          endcase
      end
      end
Line 538... Line 541...
 
 
always @ *
always @ *
begin
begin
    next_epc_r = epc_q;
    next_epc_r = epc_q;
    next_esr_r = esr_q;
    next_esr_r = esr_q;
 
    // Instruction after interrupt, update SR.F
 
    if (exc_last_q && alu_flag_update_w)
 
        next_esr_r[`SR_F] = compare_result_r;
 
 
 
    //  Instruction after interrupt, latch carry if updated
 
    if (exc_last_q && alu_carry_update_w)
 
        next_esr_r[`SR_CY] = alu_carry_out_w;
 
 
 
    if (execute_inst_r & ~stall_inst_r)
 
    begin
    case (1'b1)
    case (1'b1)
    inst_mtspr_w: // l.mtspr
    inst_mtspr_w: // l.mtspr
    begin
    begin
       case (mxspr_uint16_r)
       case (mxspr_uint16_r)
           // EPCR - EPC Exception saved PC
           // EPCR - EPC Exception saved PC
Line 554... Line 566...
    end
    end
    default:
    default:
      ;
      ;
    endcase
    endcase
end
end
 
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// ALU inputs
// ALU inputs
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
 
Line 956... Line 969...
    // Default branch target is relative to current PC
    // Default branch target is relative to current PC
    branch_target_r = (opcode_pc_i + {target_int26_r[29:0],2'b00});
    branch_target_r = (opcode_pc_i + {target_int26_r[29:0],2'b00});
 
 
    case (1'b1)
    case (1'b1)
    inst_bf_w: // l.bf
    inst_bf_w: // l.bf
        branch_r      = next_sr_r[`OR32_SR_F];
        branch_r      = next_sr_r[`SR_F];
 
 
    inst_bnf_w: // l.bnf
    inst_bnf_w: // l.bnf
        branch_r      = ~next_sr_r[`OR32_SR_F];
        branch_r      = ~next_sr_r[`SR_F];
 
 
    inst_j_w: // l.j
    inst_j_w: // l.j
        branch_r      = 1'b1;
        branch_r      = 1'b1;
 
 
    inst_jal_w: // l.jal
    inst_jal_w: // l.jal
Line 1175... Line 1188...
begin
begin
   if (rst_i == 1'b1)
   if (rst_i == 1'b1)
   begin
   begin
       pc_branch_q          <= 32'h00000000;
       pc_branch_q          <= 32'h00000000;
       pc_fetch_q           <= 1'b0;
       pc_fetch_q           <= 1'b0;
 
       exc_last_q           <= 1'b0;
 
 
       // Status registers
       // Status registers
       epc_q                <= 32'h00000000;
       epc_q                <= 32'h00000000;
       sr_q                 <= 32'h00000000;
       sr_q                 <= 32'h00000000;
       esr_q                <= 32'h00000000;
       esr_q                <= 32'h00000000;
Line 1193... Line 1207...
      if (nmi_i)
      if (nmi_i)
          nmi_q             <= 1'b1;
          nmi_q             <= 1'b1;
 
 
       // Reset branch request
       // Reset branch request
       pc_fetch_q           <= 1'b0;
       pc_fetch_q           <= 1'b0;
 
       exc_last_q           <= 1'b0;
 
 
       // Update SR
       // Update SR
       sr_q                 <= next_sr_r;
       sr_q                 <= next_sr_r;
 
 
 
       // Update EPC / ESR which may have been updated by an 
 
       // MTSPR write / flag update in instruction after interrupt
 
       epc_q                <= next_epc_r;
 
       esr_q                <= next_esr_r;
 
 
       // Instruction ready
       // Instruction ready
       if (execute_inst_r & ~stall_inst_r)
       if (execute_inst_r & ~stall_inst_r)
       begin
       begin
           // Exception: Instruction opcode not valid / supported, invalid PC
           // Exception: Instruction opcode not valid / supported, invalid PC
           if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
           if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
Line 1216... Line 1236...
                if (invalid_inst_r)
                if (invalid_inst_r)
                    pc_branch_q <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
                    pc_branch_q <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
                else
                else
                    pc_branch_q <= ISR_VECTOR + `VECTOR_BUS_ERROR;
                    pc_branch_q <= ISR_VECTOR + `VECTOR_BUS_ERROR;
                pc_fetch_q  <= 1'b1;
                pc_fetch_q  <= 1'b1;
 
                exc_last_q  <= 1'b1;
 
 
                fault_o     <= 1'b1;
                fault_o     <= 1'b1;
           end
           end
           // Exception: Syscall / Break
           // Exception: Syscall / Break
           else if (branch_except_r)
           else if (branch_except_r)
Line 1232... Line 1253...
                sr_q        <= 32'b0;
                sr_q        <= 32'b0;
 
 
                // Set PC to exception vector
                // Set PC to exception vector
                pc_branch_q <= branch_target_r;
                pc_branch_q <= branch_target_r;
                pc_fetch_q  <= 1'b1;
                pc_fetch_q  <= 1'b1;
 
                exc_last_q  <= 1'b1;
 
 
    `ifdef CONF_CORE_DEBUG
    `ifdef CONF_CORE_DEBUG
               $display(" Exception 0x%08x", branch_target_r);
               $display(" Exception 0x%08x", branch_target_r);
    `endif
    `endif
           end
           end
Line 1257... Line 1279...
                sr_q        <= 32'b0;
                sr_q        <= 32'b0;
 
 
                // Set PC to exception vector
                // Set PC to exception vector
                pc_branch_q <= ISR_VECTOR + `VECTOR_NMI;
                pc_branch_q <= ISR_VECTOR + `VECTOR_NMI;
                pc_fetch_q  <= 1'b1;
                pc_fetch_q  <= 1'b1;
 
                exc_last_q  <= 1'b1;
 
 
    `ifdef CONF_CORE_DEBUG
    `ifdef CONF_CORE_DEBUG
               $display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
               $display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
    `endif
    `endif
           end
           end
           // External interrupt
           // External interrupt
           else if (intr_i && next_sr_r[`OR32_SR_IEE])
           else if (intr_i && next_sr_r[`SR_IEE])
           begin
           begin
                // Save PC of next instruction & SR
                // Save PC of next instruction & SR
                if (branch_r)
                if (branch_r)
                    epc_q <= branch_target_r;
                    epc_q <= branch_target_r;
                // Next expected PC (current PC + 4)
                // Next expected PC (current PC + 4)
Line 1280... Line 1303...
                sr_q        <= 32'b0;
                sr_q        <= 32'b0;
 
 
                // Set PC to external interrupt vector
                // Set PC to external interrupt vector
                pc_branch_q <= ISR_VECTOR + `VECTOR_EXTINT;
                pc_branch_q <= ISR_VECTOR + `VECTOR_EXTINT;
                pc_fetch_q  <= 1'b1;
                pc_fetch_q  <= 1'b1;
 
                exc_last_q  <= 1'b1;
 
 
    `ifdef CONF_CORE_DEBUG
    `ifdef CONF_CORE_DEBUG
               $display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
               $display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
    `endif
    `endif
           end
           end
Line 1296... Line 1320...
 
 
    `ifdef CONF_CORE_DEBUG
    `ifdef CONF_CORE_DEBUG
               $display(" Branch to 0x%08x", branch_target_r);
               $display(" Branch to 0x%08x", branch_target_r);
    `endif
    `endif
           end
           end
           // Non branch
 
           else
 
           begin
 
                // Update EPC / ESR which may have been updated
 
                // by an MTSPR write
 
                epc_q          <= next_epc_r;
 
                esr_q          <= next_esr_r;
 
           end
 
      end
      end
   end
   end
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 1526... Line 1542...
               case (mxspr_uint16_r)
               case (mxspr_uint16_r)
                   // SR - Supervision register
                   // SR - Supervision register
                   `SPR_REG_SR:
                   `SPR_REG_SR:
                   begin
                   begin
                       // Cache flush request?
                       // Cache flush request?
                       icache_flush_o <= reg_rb_r[`OR32_SR_ICACHE_FLUSH];
                       icache_flush_o <= reg_rb_r[`SR_ICACHE_FLUSH];
                       dcache_flush_o <= reg_rb_r[`OR32_SR_DCACHE_FLUSH];
                       dcache_flush_o <= reg_rb_r[`SR_DCACHE_FLUSH];
                   end
                   end
               endcase
               endcase
          end
          end
 
 
          inst_trap_w: // l.trap
          inst_trap_w: // l.trap

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.