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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_exec.v] - Diff between revs 32 and 36

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

Rev 32 Rev 36
Line 1... Line 1...
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//                           AltOR32 
//                           AltOR32 
//                Alternative Lightweight OpenRisc 
//                Alternative Lightweight OpenRisc 
//                            V2.0
//                            V2.1
//                     Ultra-Embedded.com
//                     Ultra-Embedded.com
//                   Copyright 2011 - 2013
//                   Copyright 2011 - 2014
//
//
//               Email: admin@ultra-embedded.com
//               Email: admin@ultra-embedded.com
//
//
//                       License: LGPL
//                       License: LGPL
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 37... Line 37...
 
 
//`define CONF_CORE_DEBUG
//`define CONF_CORE_DEBUG
//`define CONF_CORE_TRACE
//`define CONF_CORE_TRACE
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Includes
 
//-----------------------------------------------------------------
 
`include "altor32_defs.v"
 
 
 
//-----------------------------------------------------------------
 
// Module - Instruction Execute
// Module - Instruction Execute
//-----------------------------------------------------------------
//-----------------------------------------------------------------
module altor32_exec
module altor32_exec
(
(
    // General
    // General
Line 111... Line 106...
    input               dmem_stall_i /*verilator public*/,
    input               dmem_stall_i /*verilator public*/,
    input               dmem_ack_i /*verilator public*/
    input               dmem_ack_i /*verilator public*/
);
);
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
// Includes
 
//-----------------------------------------------------------------
 
`include "altor32_defs.v"
 
`include "altor32_funcs.v"
 
 
 
//-----------------------------------------------------------------
// Params
// Params
//-----------------------------------------------------------------
//-----------------------------------------------------------------
parameter           BOOT_VECTOR         = 32'h00000000;
parameter           BOOT_VECTOR         = 32'h00000000;
parameter           ISR_VECTOR          = 32'h00000000;
parameter           ISR_VECTOR          = 32'h00000000;
 
 
Line 123... Line 124...
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
 
// Branch PC
// Branch PC
reg [31:0] r_pc_branch;
reg [31:0] r_pc_branch;
reg        r_pc_fetch;
reg        r_pc_fetch;
reg        r_stall;
 
 
 
// Exception saved program counter
// Exception saved program counter
reg [31:0] r_epc;
reg [31:0] r_epc;
 
 
// Supervisor register
// Supervisor register
Line 153... Line 153...
wire [31:0] r_e_result;
wire [31:0] r_e_result;
 
 
// Resolved RA/RB register contents
// Resolved RA/RB register contents
wire [31:0] ra_value_resolved;
wire [31:0] ra_value_resolved;
wire [31:0] rb_value_resolved;
wire [31:0] rb_value_resolved;
 
wire        operand_resolved;
wire        resolve_failed;
wire        resolve_failed;
 
 
// ALU Carry
// ALU Carry
wire alu_carry_out;
wire alu_carry_out;
wire alu_carry_update;
wire alu_carry_update;
 
wire alu_flag_update;
 
 
 
// ALU Comparisons
 
wire compare_equal_w;
 
wire compare_gts_w;
 
wire compare_gt_w;
 
wire compare_lts_w;
 
wire compare_lt_w;
 
 
// ALU operation selection
// ALU operation selection
reg [3:0] r_e_alu_func;
reg [3:0] r_e_alu_func;
 
 
// Load instruction details
// Load instruction details
Line 211... Line 220...
    // Result
    // Result
    .p_o(r_e_result),
    .p_o(r_e_result),
 
 
    // Carry
    // Carry
    .c_o(alu_carry_out),
    .c_o(alu_carry_out),
    .c_update_o(alu_carry_update)
    .c_update_o(alu_carry_update),
 
 
 
    // Comparisons
 
    .equal_o(compare_equal_w),
 
    .greater_than_signed_o(compare_gts_w),
 
    .greater_than_o(compare_gt_w),
 
    .less_than_signed_o(compare_lts_w),
 
    .less_than_o(compare_lt_w),
 
    .flag_update_o(alu_flag_update)
);
);
 
 
// Load result forwarding
// Load result forwarding
altor32_lfu
altor32_lfu
u_lfu
u_lfu
Line 304... Line 321...
 
 
    // Resolved register values
    // Resolved register values
    .result_ra_o(ra_value_resolved),
    .result_ra_o(ra_value_resolved),
    .result_rb_o(rb_value_resolved),
    .result_rb_o(rb_value_resolved),
 
 
 
    // Operands required forwarding
 
    .resolved_o(operand_resolved),
 
 
    // Stall due to failed resolve
    // Stall due to failed resolve
    .stall_o(resolve_failed)
    .stall_o(resolve_failed)
);
);
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 333... Line 353...
    // Instruction
    // Instruction
    inst_r               = {2'b00,opcode_i[31:26]};
    inst_r               = {2'b00,opcode_i[31:26]};
 
 
    // Sub instructions
    // Sub instructions
    alu_op_r             = {opcode_i[9:6],opcode_i[3:0]};
    alu_op_r             = {opcode_i[9:6],opcode_i[3:0]};
    sfxx_op_r            = {5'b00,opcode_i[31:21]};
    sfxx_op_r            = {5'b00,opcode_i[31:21]} & `INST_OR32_SFMASK;
    shift_op_r           = opcode_i[7:6];
    shift_op_r           = opcode_i[7:6];
 
 
    // Branch target
    // Branch target
    target_int26_r       = sign_extend_imm26(opcode_i[25:0]);
    target_int26_r       = sign_extend_imm26(opcode_i[25:0]);
 
 
Line 358... Line 378...
 
 
    // Shift ammount (from immediate)
    // Shift ammount (from immediate)
    shift_imm_r          = {26'b00,opcode_i[5:0]};
    shift_imm_r          = {26'b00,opcode_i[5:0]};
 
 
    // MTSPR/MFSPR operand
    // MTSPR/MFSPR operand
    mxspr_uint16_r       = (ra_value_resolved[15:0] | {5'b00000,opcode_i[10:0]});
    // NOTE: Use unresolved register value and stall pipeline if required.
 
    // This is to improve timing.
 
    mxspr_uint16_r       = (reg_ra_value_i[15:0] | {5'b00000,opcode_i[10:0]});
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Instruction Decode
// Instruction Decode
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 373... Line 395...
wire inst_sll_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SLL);  // l.sll
wire inst_sll_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SLL);  // l.sll
wire inst_sra_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRA);  // l.sra
wire inst_sra_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRA);  // l.sra
wire inst_srl_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRL);  // l.srl
wire inst_srl_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRL);  // l.srl
wire inst_sub_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SUB);  // l.sub
wire inst_sub_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SUB);  // l.sub
wire inst_xor_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_XOR);  // l.xor
wire inst_xor_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_XOR);  // l.xor
 
wire inst_mul_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_MUL);  // l.mul
 
wire inst_mulu_w    = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_MULU); // l.mulu
 
 
wire inst_addi_w    = (inst_r == `INST_OR32_ADDI);  // l.addi
wire inst_addi_w    = (inst_r == `INST_OR32_ADDI);  // l.addi
wire inst_andi_w    = (inst_r == `INST_OR32_ANDI);  // l.andi
wire inst_andi_w    = (inst_r == `INST_OR32_ANDI);  // l.andi
wire inst_bf_w      = (inst_r == `INST_OR32_BF);    // l.bf
wire inst_bf_w      = (inst_r == `INST_OR32_BF);    // l.bf
wire inst_bnf_w     = (inst_r == `INST_OR32_BNF);   // l.bnf
wire inst_bnf_w     = (inst_r == `INST_OR32_BNF);   // l.bnf
Line 408... Line 432...
wire inst_xori_w    = (inst_r == `INST_OR32_XORI);   // l.xori
wire inst_xori_w    = (inst_r == `INST_OR32_XORI);   // l.xori
 
 
wire inst_sfxx_w    = (inst_r == `INST_OR32_SFXX);
wire inst_sfxx_w    = (inst_r == `INST_OR32_SFXX);
wire inst_sfxxi_w   = (inst_r == `INST_OR32_SFXXI);
wire inst_sfxxi_w   = (inst_r == `INST_OR32_SFXXI);
 
 
wire inst_sfeq_w    = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFEQ);   // l.sfeq
wire inst_sfeq_w    = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFEQ);   // l.sfeq
wire inst_sfges_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGES);  // l.sfges
wire inst_sfges_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGES);  // l.sfges
 
 
wire inst_sfgeu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGEU);  // l.sfgeu
wire inst_sfgeu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGEU);  // l.sfgeu
wire inst_sfgts_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGTS);  // l.sfgts
wire inst_sfgts_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGTS);  // l.sfgts
wire inst_sfgtu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGTU);  // l.sfgtu
wire inst_sfgtu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGTU);  // l.sfgtu
wire inst_sfles_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLES);  // l.sfles
wire inst_sfles_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLES);  // l.sfles
wire inst_sfleu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLEU);  // l.sfleu
wire inst_sfleu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLEU);  // l.sfleu
wire inst_sflts_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLTS);  // l.sflts
wire inst_sflts_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLTS);  // l.sflts
wire inst_sfltu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLTU);  // l.sfltu
wire inst_sfltu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLTU);  // l.sfltu
wire inst_sfne_w    = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFNE);   // l.sfne
wire inst_sfne_w    = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFNE);   // l.sfne
 
 
wire inst_sfeqi_w   = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFEQI);  // l.sfeqi
 
wire inst_sfgesi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGESI); // l.sfgesi
 
wire inst_sfgeui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGEUI); // l.sfgeui
 
wire inst_sfgtsi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGTSI); // l.sfgtsi
 
wire inst_sfgtui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGTUI); // l.sfgtui
 
wire inst_sflesi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLESI); // l.sflesi
 
 
 
wire inst_sfleui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLEUI); // l.sfleui
 
wire inst_sfltsi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLTSI); // l.sfltsi
 
wire inst_sfltui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLTUI); // l.sfltui
 
wire inst_sfnei_w   = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFNEI);  // l.sfnei
 
 
 
wire inst_sys_w     = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_SYS);  // l.sys
wire inst_sys_w     = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_SYS);  // l.sys
wire inst_trap_w    = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_TRAP); // l.trap
wire inst_trap_w    = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_TRAP); // l.trap
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
Line 450... Line 462...
 
 
    // No opcode ready or branch delay slot
    // No opcode ready or branch delay slot
    if (~opcode_valid_i | r_pc_fetch)
    if (~opcode_valid_i | r_pc_fetch)
        execute_inst_r  = 1'b0;
        execute_inst_r  = 1'b0;
    // Valid instruction, but load result / operand not ready
    // Valid instruction, but load result / operand not ready
    else if (resolve_failed | load_stall)
    else if (resolve_failed | load_stall |
 
            (operand_resolved & (inst_mfspr_w | inst_mtspr_w)))
        stall_inst_r    = 1'b1;
        stall_inst_r    = 1'b1;
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Next PC
// Next PC
Line 474... Line 487...
reg         compare_result_r;
reg         compare_result_r;
always @ *
always @ *
begin
begin
    next_sr_r = r_sr;
    next_sr_r = r_sr;
 
 
 
    // Update SR.F
 
    if (alu_flag_update)
 
        next_sr_r[`OR32_SR_F] = compare_result_r;
 
 
    // Latch carry if updated
    // Latch carry if updated
    if (alu_carry_update)
    if (alu_carry_update)
        next_sr_r[`OR32_SR_CY] = alu_carry_out;
        next_sr_r[`OR32_SR_CY] = alu_carry_out;
 
 
    // If valid instruction, check if SR needs updating
    // If valid instruction, check if SR needs updating
Line 500... Line 517...
            ;
            ;
          endcase
          endcase
      end
      end
      inst_rfe_w:
      inst_rfe_w:
          next_sr_r = r_esr;
          next_sr_r = r_esr;
      inst_sfxx_w,
 
      inst_sfxxi_w:
 
           next_sr_r[`OR32_SR_F] = compare_result_r;
 
      default:
      default:
        ;
        ;
      endcase
      endcase
    end
    end
end
end
Line 629... Line 643...
         alu_input_a_r  = reg_ra_r;
         alu_input_a_r  = reg_ra_r;
         alu_input_b_r  = reg_rb_r;
         alu_input_b_r  = reg_rb_r;
         write_rd_r     = 1'b1;
         write_rd_r     = 1'b1;
     end
     end
 
 
 
     inst_mul_w,   // l.mul
 
     inst_mulu_w:  // l.mulu
 
     begin
 
         write_rd_r     = 1'b1;
 
     end
 
 
     inst_addi_w: // l.addi
     inst_addi_w: // l.addi
     begin
     begin
         alu_func_r     = `ALU_ADD;
         alu_func_r     = `ALU_ADD;
         alu_input_a_r  = reg_ra_r;
         alu_input_a_r  = reg_ra_r;
         alu_input_b_r  = int32_r;
         alu_input_b_r  = int32_r;
Line 732... Line 752...
     inst_lbz_w,
     inst_lbz_w,
     inst_lhz_w,
     inst_lhz_w,
     inst_lwz_w:
     inst_lwz_w:
          write_rd_r    = 1'b1;
          write_rd_r    = 1'b1;
 
 
 
     // l.sf*i
 
     inst_sfxxi_w:
 
     begin
 
         alu_func_r     = `ALU_COMPARE;
 
         alu_input_a_r  = reg_ra_r;
 
         alu_input_b_r  = int32_r;
 
     end
 
 
 
     // l.sf*
 
     inst_sfxx_w:
 
     begin
 
         alu_func_r     = `ALU_COMPARE;
 
         alu_input_a_r  = reg_ra_r;
 
         alu_input_b_r  = reg_rb_r;
 
     end
 
 
     inst_xori_w: // l.xori
     inst_xori_w: // l.xori
     begin
     begin
         alu_func_r     = `ALU_XOR;
         alu_func_r     = `ALU_XOR;
         alu_input_a_r  = reg_ra_r;
         alu_input_a_r  = reg_ra_r;
         alu_input_b_r  = int32_r;
         alu_input_b_r  = int32_r;
Line 745... Line 781...
        ;
        ;
   endcase
   endcase
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Comparisons
// Comparisons (from ALU outputs)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg [31:0] compare_a_r;
reg inst_sfges_r;
reg [31:0] compare_b_r;
reg inst_sfgeu_r;
 
reg inst_sfgts_r;
 
reg inst_sfgtu_r;
 
reg inst_sfles_r;
 
reg inst_sfleu_r;
 
reg inst_sflts_r;
 
reg inst_sfltu_r;
 
reg inst_sfne_r;
 
reg inst_sfges_q;
 
reg inst_sfgeu_q;
 
reg inst_sfgts_q;
 
reg inst_sfgtu_q;
 
reg inst_sfles_q;
 
reg inst_sfleu_q;
 
reg inst_sflts_q;
 
reg inst_sfltu_q;
 
reg inst_sfne_q;
 
 
always @ *
always @ *
begin
begin
    compare_a_r = reg_ra_r;
    inst_sfges_r = 1'b0;
    compare_b_r = reg_rb_r;
    inst_sfgeu_r = 1'b0;
 
    inst_sfgts_r = 1'b0;
 
    inst_sfgtu_r = 1'b0;
 
    inst_sfles_r = 1'b0;
 
    inst_sfleu_r = 1'b0;
 
    inst_sflts_r = 1'b0;
 
    inst_sfltu_r = 1'b0;
 
    inst_sfne_r  = 1'b0;
 
 
 
    // Valid instruction
 
    if (execute_inst_r && ~stall_inst_r)
 
    begin
 
 
    case (1'b1)
    case (1'b1)
    inst_sfeqi_w,  // l.sfeqi
        inst_sfges_w:  // l.sfges
    inst_sfgesi_w, // l.sfgesi
            inst_sfges_r = 1'b1;
    inst_sfgeui_w, // l.sfgeui
 
    inst_sfgtsi_w, // l.sfgtsi
        inst_sfgeu_w:  // l.sfgeu
    inst_sfgtui_w, // l.sfgtui
            inst_sfgeu_r = 1'b1;
    inst_sflesi_w, // l.sflesi
 
    inst_sfleui_w, // l.sfleui
        inst_sfgts_w:  // l.sfgts
    inst_sfltsi_w, // l.sfltsi
            inst_sfgts_r = 1'b1;
    inst_sfltui_w, // l.sfltui
 
    inst_sfnei_w:  // l.sfnei
        inst_sfgtu_w:  // l.sfgtu
        compare_b_r = int32_r;
            inst_sfgtu_r = 1'b1;
 
 
 
        inst_sfles_w:  // l.sfles
 
            inst_sfles_r = 1'b1;
 
 
 
        inst_sfleu_w:  // l.sfleu
 
            inst_sfleu_r = 1'b1;
 
 
 
        inst_sflts_w:  // l.sflts
 
            inst_sflts_r = 1'b1;
 
 
 
        inst_sfltu_w:  // l.sfltu
 
            inst_sfltu_r = 1'b1;
 
 
 
        inst_sfne_w:  // l.sfne
 
            inst_sfne_r  = 1'b1;
 
 
    default:
    default:
        ;
        ;
    endcase
    endcase
end
end
 
end
 
 
reg compare_equal_r;
always @ (posedge clk_i or posedge rst_i)
reg compare_gts_r;
 
reg compare_gt_r;
 
reg compare_lts_r;
 
reg compare_lt_r;
 
always @ *
 
begin
begin
    if (compare_a_r == compare_b_r)
   if (rst_i == 1'b1)
        compare_equal_r = 1'b1;
   begin
    else
        inst_sfges_q <= 1'b0;
        compare_equal_r = 1'b0;
        inst_sfgeu_q <= 1'b0;
 
        inst_sfgts_q <= 1'b0;
    compare_lts_r = less_than_signed(compare_a_r, compare_b_r);
        inst_sfgtu_q <= 1'b0;
 
        inst_sfles_q <= 1'b0;
    if (compare_a_r < compare_b_r)
        inst_sfleu_q <= 1'b0;
        compare_lt_r = 1'b1;
        inst_sflts_q <= 1'b0;
    else
        inst_sfltu_q <= 1'b0;
        compare_lt_r = 1'b0;
        inst_sfne_q <= 1'b0;
 
   end
    // Greater than (signed)
 
    compare_gts_r = ~(compare_lts_r | compare_equal_r);
 
 
 
    if (compare_a_r > compare_b_r)
 
        compare_gt_r = 1'b1;
 
    else
    else
        compare_gt_r = 1'b0;
   begin
 
        inst_sfges_q <= inst_sfges_r;
 
        inst_sfgeu_q <= inst_sfgeu_r;
 
        inst_sfgts_q <= inst_sfgts_r;
 
        inst_sfgtu_q <= inst_sfgtu_r;
 
        inst_sfles_q <= inst_sfles_r;
 
        inst_sfleu_q <= inst_sfleu_r;
 
        inst_sflts_q <= inst_sflts_r;
 
        inst_sfltu_q <= inst_sfltu_r;
 
        inst_sfne_q  <= inst_sfne_r;
 
   end
end
end
 
 
always @ *
always @ *
begin
begin
    compare_result_r = 1'b0;
 
 
 
    case (1'b1)
    case (1'b1)
    inst_sfeq_w, // l.sfeq
    inst_sfges_q: // l.sfges
    inst_sfeqi_w: // l.sfeqi
        compare_result_r = compare_gts_w | compare_equal_w;
        compare_result_r = compare_equal_r;
 
 
 
    inst_sfges_w,  // l.sfges
 
    inst_sfgesi_w: // l.sfgesi
 
        compare_result_r = compare_gts_r | compare_equal_r;
 
 
 
    inst_sfgeu_w,  // l.sfgeu
 
    inst_sfgeui_w: // l.sfgeui
 
        compare_result_r = compare_gt_r | compare_equal_r;
 
 
 
    inst_sfgts_w,  // l.sfgts
    inst_sfgeu_q: // l.sfgeu
    inst_sfgtsi_w: // l.sfgtsi
        compare_result_r = compare_gt_w | compare_equal_w;
        compare_result_r = compare_gts_r;
 
 
 
    inst_sfgtu_w,  // l.sfgtu
    inst_sfgts_q: // l.sfgts
    inst_sfgtui_w: // l.sfgtui
        compare_result_r = compare_gts_w;
        compare_result_r = compare_gt_r;
 
 
 
    inst_sfles_w,  // l.sfles
    inst_sfgtu_q: // l.sfgtu
    inst_sflesi_w: // l.sflesi
        compare_result_r = compare_gt_w;
        compare_result_r = compare_lts_r | compare_equal_r;
 
 
 
    inst_sfleu_w,  // l.sfleu
    inst_sfles_q: // l.sfles
 
        compare_result_r = compare_lts_w | compare_equal_w;
 
 
    inst_sfleui_w: // l.sfleui
    inst_sfleu_q: // l.sfleu
        compare_result_r = compare_lt_r | compare_equal_r;
        compare_result_r = compare_lt_w | compare_equal_w;
 
 
    inst_sflts_w,  // l.sflts
    inst_sflts_q: // l.sflts
 
        compare_result_r = compare_lts_w;
 
 
    inst_sfltsi_w: // l.sfltsi
    inst_sfltu_q: // l.sfltu
        compare_result_r = compare_lts_r;
        compare_result_r = compare_lt_w;
 
 
    inst_sfltu_w,  // l.sfltu
    inst_sfne_q: // l.sfne
 
        compare_result_r = ~compare_equal_w;
 
 
    inst_sfltui_w: // l.sfltui
    default: // l.sfeq
        compare_result_r = compare_lt_r;
        compare_result_r = compare_equal_w;
 
 
    inst_sfne_w,  // l.sfne
 
 
 
    inst_sfnei_w: // l.sfnei
 
        compare_result_r = ~compare_equal_r;
 
    default:
 
        ;
 
    endcase
    endcase
end
end
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Load/Store operation?
// Load/Store operation?
Line 888... Line 951...
    // 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      = r_sr[`OR32_SR_F];
        branch_r      = next_sr_r[`OR32_SR_F];
 
 
    inst_bnf_w: // l.bnf
    inst_bnf_w: // l.bnf
        branch_r      = ~r_sr[`OR32_SR_F];
        branch_r      = ~next_sr_r[`OR32_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 987... Line 1050...
       inst_xori_w,
       inst_xori_w,
       inst_slli_w,
       inst_slli_w,
       inst_srai_w,
       inst_srai_w,
       inst_srli_w,
       inst_srli_w,
       inst_sfeq_w,
       inst_sfeq_w,
       inst_sfeqi_w,
 
       inst_sfges_w,
       inst_sfges_w,
       inst_sfgesi_w,
 
       inst_sfgeu_w,
       inst_sfgeu_w,
       inst_sfgeui_w,
 
       inst_sfgts_w,
       inst_sfgts_w,
       inst_sfgtsi_w,
 
       inst_sfgtu_w,
       inst_sfgtu_w,
       inst_sfgtui_w,
 
       inst_sfles_w,
       inst_sfles_w,
       inst_sflesi_w,
 
       inst_sfleu_w,
       inst_sfleu_w,
       inst_sfleui_w,
 
       inst_sflts_w,
       inst_sflts_w,
       inst_sfltsi_w,
 
       inst_sfltu_w,
       inst_sfltu_w,
       inst_sfltui_w,
 
       inst_sfne_w,
       inst_sfne_w,
       inst_sfnei_w,
 
       inst_sys_w,
       inst_sys_w,
       inst_trap_w:
       inst_trap_w:
          invalid_inst_r = 1'b0;
          invalid_inst_r = 1'b0;
       default:
       default:
          invalid_inst_r = 1'b1;
          invalid_inst_r = 1'b1;
Line 1054... Line 1107...
           end
           end
       end
       end
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       // Valid instruction
       // Valid instruction
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       else if (~invalid_inst_r)
       else
       begin
       begin
           // Update ALU input flops
           // Update ALU input flops
           r_e_alu_func         <= alu_func_r;
           r_e_alu_func         <= alu_func_r;
           r_e_alu_a            <= alu_input_a_r;
           r_e_alu_a            <= alu_input_a_r;
           r_e_alu_b            <= alu_input_b_r;
           r_e_alu_b            <= alu_input_b_r;
Line 1082... Line 1135...
begin
begin
   if (rst_i == 1'b1)
   if (rst_i == 1'b1)
   begin
   begin
       r_e_opcode           <= 32'h00000000;
       r_e_opcode           <= 32'h00000000;
       r_e_opcode_pc        <= 32'h00000000;
       r_e_opcode_pc        <= 32'h00000000;
 
 
       r_stall              <= 1'b0;
 
   end
   end
   else
   else
   begin
   begin
       r_stall              <= stall_inst_r;
 
 
 
       // Instruction not ready
       // Instruction not ready
       if (~execute_inst_r | stall_inst_r)
       if (~execute_inst_r | stall_inst_r)
       begin
       begin
           // Store bubble opcode
           // Store bubble opcode
           r_e_opcode            <= `OPCODE_INST_BUBBLE;
           r_e_opcode            <= `OPCODE_INST_BUBBLE;
           r_e_opcode_pc         <= opcode_pc_i;
           r_e_opcode_pc         <= opcode_pc_i;
       end
       end
       // Valid instruction
       // Valid instruction
       else if (~invalid_inst_r)
       else
       begin
       begin
           // Store opcode
           // Store opcode
           r_e_opcode            <= opcode_i;
           r_e_opcode            <= opcode_i;
           r_e_opcode_pc         <= opcode_pc_i;
           r_e_opcode_pc         <= opcode_pc_i;
 
 
Line 1288... Line 1337...
       if (~dmem_stall_i)
       if (~dmem_stall_i)
           dmem_stb_o   <= 1'b0;
           dmem_stb_o   <= 1'b0;
 
 
       if (dmem_ack_i)
       if (dmem_ack_i)
            dmem_cyc_o  <= 1'b0;
            dmem_cyc_o  <= 1'b0;
 
 
       r_mem_access     <= 1'b0;
       r_mem_access     <= 1'b0;
       d_mem_load       <= r_mem_access & r_mem_load;
       d_mem_load       <= r_mem_access & r_mem_load;
 
 
       // Pending accesses
       // Pending accesses
       r_mem_load   <= load_pending;
       r_mem_load   <= load_pending;
       r_mem_store  <= store_pending;
       r_mem_store  <= store_pending;
 
 
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       // Valid instruction
       // Valid instruction
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
       if (execute_inst_r & ~stall_inst_r)
       begin
       begin
           // Branch and link (Rd = LR/R9)
           // Branch and link (Rd = LR/R9)
           if (branch_link_r)
           if (branch_link_r)
           begin
           begin
              // Load outstanding, check if result target is being
              // Load outstanding, check if result target is being
Line 1461... Line 1511...
       dcache_flush_o       <= 1'b0;
       dcache_flush_o       <= 1'b0;
 
 
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       // Valid instruction
       // Valid instruction
       //---------------------------------------------------------------
       //---------------------------------------------------------------
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
       if (execute_inst_r & ~stall_inst_r)
       begin
       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)
Line 1506... Line 1556...
          r_putc                <= 8'b0;
          r_putc                <= 8'b0;
    `endif
    `endif
           //---------------------------------------------------------------
           //---------------------------------------------------------------
           // Valid instruction
           // Valid instruction
           //---------------------------------------------------------------
           //---------------------------------------------------------------
           if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
           if (execute_inst_r & ~stall_inst_r)
           begin
           begin
 
 
               case (1'b1)
               case (1'b1)
               inst_nop_w: // l.nop
               inst_nop_w: // l.nop
                begin
                begin
Line 1540... Line 1590...
// Assignments
// Assignments
//-------------------------------------------------------------------
//-------------------------------------------------------------------
 
 
assign branch_pc_o          = r_pc_branch;
assign branch_pc_o          = r_pc_branch;
assign branch_o             = r_pc_fetch;
assign branch_o             = r_pc_fetch;
assign stall_o              = r_stall;
assign stall_o              = stall_inst_r;
 
 
assign opcode_o             = r_e_opcode;
assign opcode_o             = r_e_opcode;
 
 
assign reg_rd_o             = r_e_rd;
assign reg_rd_o             = r_e_rd;
assign reg_rd_value_o       = r_e_result;
assign reg_rd_value_o       = r_e_result;
 
 
assign mult_o               = 1'b0;
assign mult_o               = 1'b0;
assign mult_res_o           = 32'b0;
assign mult_res_o           = 32'b0;
 
 
`include "altor32_funcs.v"
 
 
 
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// Hooks for debug
// Hooks for debug
//-------------------------------------------------------------------
//-------------------------------------------------------------------
`ifdef verilator
`ifdef verilator
   function [31:0] get_opcode_ex;
   function [31:0] get_opcode_ex;
Line 1574... Line 1622...
      get_putc = 8'b0;
      get_putc = 8'b0;
   `endif
   `endif
   endfunction
   endfunction
   function [0:0] get_reg_valid;
   function [0:0] get_reg_valid;
      // verilator public
      // verilator public
      get_reg_valid = ~(resolve_failed | load_stall);
      get_reg_valid = ~(resolve_failed | load_stall | ~opcode_valid_i);
   endfunction
   endfunction
   function [4:0] get_reg_ra;
   function [4:0] get_reg_ra;
      // verilator public
      // verilator public
      get_reg_ra = reg_ra_i;
      get_reg_ra = reg_ra_i;
   endfunction
   endfunction

powered by: WebSVN 2.1.0

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