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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [rtl/] [cpu/] [zipcpu.v] - Diff between revs 3 and 30

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

Rev 3 Rev 30
Line 5... Line 5...
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
//
//
// Purpose:     This is the top level module holding the core of the Zip CPU
// Purpose:     This is the top level module holding the core of the Zip CPU
//              together.  The Zip CPU is designed to be as simple as possible.
//              together.  The Zip CPU is designed to be as simple as possible.
//      (actual implementation aside ...)  The instruction set is about as
//      (actual implementation aside ...)  The instruction set is about as
//      RISC as you can get, there are only 16 instruction types supported.
//      RISC as you can get, with only 26 instruction types currently supported.
 
//      (There are still 8-instruction Op-Codes reserved for floating point,
 
//      and 5 which can be used for transactions not requiring registers.)
//      Please see the accompanying spec.pdf file for a description of these
//      Please see the accompanying spec.pdf file for a description of these
//      instructions.
//      instructions.
//
//
//      All instructions are 32-bits wide.  All bus accesses, both address and
//      All instructions are 32-bits wide.  All bus accesses, both address and
//      data, are 32-bits over a wishbone bus.
//      data, are 32-bits over a wishbone bus.
Line 24... Line 26...
//
//
//              4. Apply Instruction
//              4. Apply Instruction
//
//
//              4. Write-back Results
//              4. Write-back Results
//
//
//      Further information about the inner workings of this CPU may be
//      Further information about the inner workings of this CPU, such as
//      found in the spec.pdf file.  (The documentation within this file
//      what causes pipeline stalls, may be found in the spec.pdf file.  (The
//      had become out of date and out of sync with the spec.pdf, so look
//      documentation within this file had become out of date and out of sync
//      to the spec.pdf for accurate and up to date information.)
//      with the spec.pdf, so look to the spec.pdf for accurate and up to date
 
//      information.)
//
//
//
//
//      In general, the pipelining is controlled by three pieces of logic
//      In general, the pipelining is controlled by three pieces of logic
//      per stage: _ce, _stall, and _valid.  _valid means that the stage
//      per stage: _ce, _stall, and _valid.  _valid means that the stage
//      holds a valid instruction.  _ce means that the instruction from the
//      holds a valid instruction.  _ce means that the instruction from the
Line 101... Line 104...
//
//
//
//
//
//
`define CPU_CC_REG      4'he
`define CPU_CC_REG      4'he
`define CPU_PC_REG      4'hf
`define CPU_PC_REG      4'hf
`define CPU_CLRCACHE_BIT 14     // Floating point error flag, set on error
`define CPU_CLRCACHE_BIT 14     // Set to clear the I-cache, automatically clears
`define CPU_PHASE_BIT   13      // Floating point error flag, set on error
`define CPU_PHASE_BIT   13      // Set if we are executing the latter half of a VLIW
`define CPU_FPUERR_BIT  12      // Floating point error flag, set on error
`define CPU_FPUERR_BIT  12      // Floating point error flag, set on error
`define CPU_DIVERR_BIT  11      // Divide error flag, set on divide by zero
`define CPU_DIVERR_BIT  11      // Divide error flag, set on divide by zero
`define CPU_BUSERR_BIT  10      // Bus error flag, set on error
`define CPU_BUSERR_BIT  10      // Bus error flag, set on error
`define CPU_TRAP_BIT    9       // User TRAP has taken place
`define CPU_TRAP_BIT    9       // User TRAP has taken place
`define CPU_ILL_BIT     8       // Illegal instruction
`define CPU_ILL_BIT     8       // Illegal instruction
Line 204... Line 207...
 
 
        // Condition codes
        // Condition codes
        // (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
        // (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
        reg     [3:0]    flags, iflags;
        reg     [3:0]    flags, iflags;
        wire    [14:0]   w_uflags, w_iflags;
        wire    [14:0]   w_uflags, w_iflags;
        reg             trap, break_en, step, gie, sleep, r_halted,
        reg             trap, break_en, step, gie, sleep, r_halted;
                        break_pending;
        wire            break_pending;
        wire            w_clear_icache;
        wire            w_clear_icache;
`ifdef  OPT_ILLEGAL_INSTRUCTION
`ifdef  OPT_ILLEGAL_INSTRUCTION
        reg             ill_err_u, ill_err_i;
        reg             ill_err_u, ill_err_i;
`else
`else
        wire            ill_err_u, ill_err_i;
        wire            ill_err_u, ill_err_i;
Line 277... Line 280...
        //
        //
        //
        //
        //
        //
        // Now, let's read our operands
        // Now, let's read our operands
        reg     [4:0]    alu_reg;
        reg     [4:0]    alu_reg;
        reg     [3:0]    opn;
        wire    [3:0]    opn;
        reg     [4:0]    opR;
        wire    [4:0]    opR;
        reg     [31:0]   r_opA, r_opB;
        reg     [31:0]   r_opA, r_opB;
        reg     [(AW-1):0]       op_pc;
        reg     [(AW-1):0]       op_pc;
        wire    [31:0]   w_opA, w_opB;
        wire    [31:0]   w_opA, w_opB;
        wire    [31:0]   opA_nowait, opB_nowait, opA, opB;
        wire    [31:0]   opA_nowait, opB_nowait, opA, opB;
        reg             opR_wr, opR_cc, opF_wr, op_gie;
        reg             opR_wr, opF_wr;
 
        wire            op_gie, opR_cc;
        wire    [14:0]   opFl;
        wire    [14:0]   opFl;
        reg     [5:0]    r_opF;
        reg     [5:0]    r_opF;
        wire    [7:0]    opF;
        wire    [7:0]    opF;
        wire            op_ce, op_phase, op_pipe, op_change_data_ce;
        wire            op_ce, op_phase, op_pipe, op_change_data_ce;
        // Some pipeline control wires
        // Some pipeline control wires
Line 299... Line 303...
        reg     op_illegal;
        reg     op_illegal;
`else
`else
        wire    op_illegal;
        wire    op_illegal;
        assign  op_illegal = 1'b0;
        assign  op_illegal = 1'b0;
`endif
`endif
        reg     op_break;
        wire    op_break;
        wire    op_lock;
        wire    op_lock;
 
 
 
 
        //
        //
        //
        //
        //      PIPELINE STAGE #4 :: ALU / Memory
        //      PIPELINE STAGE #4 :: ALU / Memory
        //              Variable declarations
        //              Variable declarations
        //
        //
        //
        //
        reg     [(AW-1):0]       alu_pc;
        wire    [(AW-1):0]       alu_pc;
        reg             r_alu_pc_valid, mem_pc_valid;
        reg             r_alu_pc_valid, mem_pc_valid;
        wire            alu_pc_valid;
        wire            alu_pc_valid;
        wire            alu_phase;
        wire            alu_phase;
        wire            alu_ce, alu_stall;
        wire            alu_ce, alu_stall;
        wire    [31:0]   alu_result;
        wire    [31:0]   alu_result;
        wire    [3:0]    alu_flags;
        wire    [3:0]    alu_flags;
        wire            alu_valid, alu_busy;
        wire            alu_valid, alu_busy;
        wire            set_cond;
        wire            set_cond;
        reg             alu_wr, alF_wr, alu_gie;
        reg             alu_wr, alF_wr;
        wire            alu_illegal_op;
        wire            alu_gie, alu_illegal_op, alu_illegal;
        wire            alu_illegal;
 
 
 
 
 
 
 
        wire    mem_ce, mem_stalled;
        wire    mem_ce, mem_stalled;
`ifdef  OPT_PIPELINED_BUS_ACCESS
`ifdef  OPT_PIPELINED_BUS_ACCESS
Line 471... Line 474...
        //      through the ALU.  Break instructions are not allowed through
        //      through the ALU.  Break instructions are not allowed through
        //      the ALU.
        //      the ALU.
`ifdef  OPT_PIPELINED
`ifdef  OPT_PIPELINED
        assign  alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2
        assign  alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2
                        ||((opvalid)&&(op_lock)&&(op_lock_stall))
                        ||((opvalid)&&(op_lock)&&(op_lock_stall))
                        ||((opvalid)&&(op_break))
                        ||((opvalid)&&(op_break))       // || op_illegal
                        ||(wr_reg_ce)&&(wr_write_cc)
                        ||(wr_reg_ce)&&(wr_write_cc)
                        ||(div_busy)||(fpu_busy);
                        ||(div_busy)||(fpu_busy);
        assign  alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall)
        assign  alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall)
                                &&(~clear_pipeline);
                                &&(~clear_pipeline);
`else
`else
Line 742... Line 745...
                        opB_rd <= dcdB_rd;
                        opB_rd <= dcdB_rd;
                end
                end
`endif
`endif
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
 
`ifdef  OPT_PIPELINED
                if (op_change_data_ce)
                if (op_change_data_ce)
 
`endif
                begin
                begin
 
`ifdef  OPT_PIPELINED
                        if ((wr_reg_ce)&&(wr_reg_id == dcdA))
                        if ((wr_reg_ce)&&(wr_reg_id == dcdA))
                                r_opA <= wr_gpreg_vl;
                                r_opA <= wr_gpreg_vl;
                        else if (dcdA_pc)
                        else
 
`endif
 
                        if (dcdA_pc)
                                r_opA <= w_pcA_v;
                                r_opA <= w_pcA_v;
                        else if (dcdA_cc)
                        else if (dcdA_cc)
                                r_opA <= { w_cpu_info, w_opA[22:15], (dcdA[4])?w_uflags:w_iflags };
                                r_opA <= { w_cpu_info, w_opA[22:16], 1'b0, (dcdA[4])?w_uflags:w_iflags };
                        else
                        else
                                r_opA <= w_opA;
                                r_opA <= w_opA;
`ifdef  OPT_PIPELINED
`ifdef  OPT_PIPELINED
                end else
                end else
                begin // We were going to pick these up when they became valid,
                begin // We were going to pick these up when they became valid,
Line 773... Line 781...
        else
        else
                assign  w_pcB_v = (dcdB[4] == dcd_gie)?dcd_pc:upc;
                assign  w_pcB_v = (dcdB[4] == dcd_gie)?dcd_pc:upc;
        endgenerate
        endgenerate
 
 
        assign  w_opBnI = (~dcdB_rd) ? 32'h00
        assign  w_opBnI = (~dcdB_rd) ? 32'h00
                : (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl
`ifdef  OPT_PIPELINED
 
                : ((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl
 
`endif
                : ((dcdB_pc) ? w_pcB_v
                : ((dcdB_pc) ? w_pcB_v
                : ((dcdB_cc) ? { w_cpu_info, w_opB[22:15], // w_opB[31:14],
                : ((dcdB_cc) ? { w_cpu_info, w_opB[22:16], // w_opB[31:14],
                        (dcdB[4])?w_uflags:w_iflags}
                        1'b0, (dcdB[4])?w_uflags:w_iflags}
                : w_opB)));
                : w_opB));
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
 
`ifdef  OPT_PIPELINED
                if (op_change_data_ce)
                if (op_change_data_ce)
                        r_opB <= w_opBnI + dcdI;
                        r_opB <= w_opBnI + dcdI;
`ifdef  OPT_PIPELINED
 
                else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
                else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
                        r_opB <= wr_gpreg_vl;
                        r_opB <= wr_gpreg_vl;
 
`else
 
                r_opB <= w_opBnI + dcdI;
`endif
`endif
 
 
        // The logic here has become more complex than it should be, no thanks
        // The logic here has become more complex than it should be, no thanks
        // to Xilinx's Vivado trying to help.  The conditions are supposed to
        // to Xilinx's Vivado trying to help.  The conditions are supposed to
        // be two sets of four bits: the top bits specify what bits matter, the
        // be two sets of four bits: the top bits specify what bits matter, the
Line 797... Line 809...
        // conditions checking those bits.  Therefore, Vivado complains that
        // conditions checking those bits.  Therefore, Vivado complains that
        // these two bits are redundant.  Hence the convoluted expression
        // these two bits are redundant.  Hence the convoluted expression
        // below, arriving at what we finally want in the (now wire net)
        // below, arriving at what we finally want in the (now wire net)
        // opF.
        // opF.
        always @(posedge i_clk)
        always @(posedge i_clk)
 
`ifdef  OPT_PIPELINED
                if (op_ce) // Cannot do op_change_data_ce here since opF depends
                if (op_ce) // Cannot do op_change_data_ce here since opF depends
                        // upon being either correct for a valid op, or correct
                        // upon being either correct for a valid op, or correct
                        // for the last valid op
                        // for the last valid op
 
`endif
                begin // Set the flag condition codes, bit order is [3:0]=VNCZ
                begin // Set the flag condition codes, bit order is [3:0]=VNCZ
                        case(dcdF[2:0])
                        case(dcdF[2:0])
                        3'h0:   r_opF <= 6'h00; // Always
                        3'h0:   r_opF <= 6'h00; // Always
`ifdef  OPT_NEW_INSTRUCTION_SET
`ifdef  OPT_NEW_INSTRUCTION_SET
                        // These were remapped as part of the new instruction
                        // These were remapped as part of the new instruction
Line 834... Line 848...
        initial opvalid_alu = 1'b0;
        initial opvalid_alu = 1'b0;
        initial opvalid_mem = 1'b0;
        initial opvalid_mem = 1'b0;
        initial opvalid_div = 1'b0;
        initial opvalid_div = 1'b0;
        initial opvalid_fpu = 1'b0;
        initial opvalid_fpu = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                if ((i_rst)||(clear_pipeline))
                begin
                begin
                        opvalid     <= 1'b0;
                        opvalid     <= 1'b0;
                        opvalid_alu <= 1'b0;
                        opvalid_alu <= 1'b0;
                        opvalid_mem <= 1'b0;
                        opvalid_mem <= 1'b0;
                        opvalid_div <= 1'b0;
                        opvalid_div <= 1'b0;
Line 863... Line 877...
                        opvalid_alu <= (dcdALU)&&(w_opvalid);
                        opvalid_alu <= (dcdALU)&&(w_opvalid);
                        opvalid_mem <= (dcdM)&&(w_opvalid);
                        opvalid_mem <= (dcdM)&&(w_opvalid);
                        opvalid_div <= (dcdDV)&&(w_opvalid);
                        opvalid_div <= (dcdDV)&&(w_opvalid);
                        opvalid_fpu <= (dcdFP)&&(w_opvalid);
                        opvalid_fpu <= (dcdFP)&&(w_opvalid);
`endif
`endif
                end else if ((clear_pipeline)||(adf_ce_unconditional)||(mem_ce))
                end else if ((adf_ce_unconditional)||(mem_ce))
                begin
                begin
                        opvalid     <= 1'b0;
                        opvalid     <= 1'b0;
                        opvalid_alu <= 1'b0;
                        opvalid_alu <= 1'b0;
                        opvalid_mem <= 1'b0;
                        opvalid_mem <= 1'b0;
                        opvalid_div <= 1'b0;
                        opvalid_div <= 1'b0;
Line 881... Line 895...
        // break to repeat and continue upon return.  To get out of this
        // break to repeat and continue upon return.  To get out of this
        // condition, replace the break instruction with what it is supposed
        // condition, replace the break instruction with what it is supposed
        // to be, step through it, and then replace it back.  In this fashion,
        // to be, step through it, and then replace it back.  In this fashion,
        // a debugger can step through code.
        // a debugger can step through code.
        // assign w_op_break = (dcd_break)&&(r_dcdI[15:0] == 16'h0001);
        // assign w_op_break = (dcd_break)&&(r_dcdI[15:0] == 16'h0001);
        initial op_break = 1'b0;
`ifdef  OPT_PIPELINED
 
        reg     r_op_break;
 
 
 
        initial r_op_break = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)      op_break <= 1'b0;
                if (i_rst)      r_op_break <= 1'b0;
                else if (op_ce) op_break <= (dcd_break); // &&(dcdvalid)
                else if (op_ce) r_op_break <= (dcd_break); //||dcd_illegal &&(dcdvalid)
                else if ((clear_pipeline)||(~opvalid))
                else if ((clear_pipeline)||(~opvalid))
                                op_break <= 1'b0;
                                r_op_break <= 1'b0;
 
        assign  op_break = r_op_break;
 
`else
 
        assign  op_break = dcd_break;
 
`endif
 
 
`ifdef  OPT_PIPELINED
`ifdef  OPT_PIPELINED
        generate
        generate
        if (IMPLEMENT_LOCK != 0)
        if (IMPLEMENT_LOCK != 0)
        begin
        begin
Line 933... Line 954...
`ifdef  OPT_PIPELINED
`ifdef  OPT_PIPELINED
                        op_illegal <= (dcdvalid)&&((dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0)));
                        op_illegal <= (dcdvalid)&&((dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0)));
`else
`else
                        op_illegal <= (dcdvalid)&&((dcd_illegal)||(dcd_lock));
                        op_illegal <= (dcdvalid)&&((dcd_illegal)||(dcd_lock));
`endif
`endif
`endif
 
                else if(alu_ce)
                else if(alu_ce)
                        op_illegal <= 1'b0;
                        op_illegal <= 1'b0;
 
`endif
 
 
        // No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not
        // No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not
        // set, dcd_early_branch will simply be a wire connected to zero and
        // set, dcd_early_branch will simply be a wire connected to zero and
        // this logic should just optimize.
        // this logic should just optimize.
 
`ifdef  OPT_PIPELINED
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (op_ce)
                if (op_ce)
                begin
                begin
                        opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))
                        opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))
                                &&(~dcd_early_branch)&&(~dcd_illegal);
                                &&(~dcd_early_branch)&&(~dcd_illegal);
                        opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
                        opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
                end
                end
 
`else
 
        always @(posedge i_clk)
 
        begin
 
                opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))
 
                        &&(~dcd_early_branch)&&(~dcd_illegal);
 
                opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
 
        end
 
`endif
 
 
 
`ifdef  OPT_PIPELINED
 
        reg     [3:0]    r_opn;
 
        reg     [4:0]    r_opR;
 
        reg             r_opR_cc;
 
        reg             r_op_gie;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (op_change_data_ce)
                if (op_change_data_ce)
                begin
                begin
                        opn    <= dcdOp;        // Which ALU operation?
                        r_opn    <= dcdOp;      // Which ALU operation?
                        // opM  <= dcdM;        // Is this a memory operation?
                        // opM  <= dcdM;        // Is this a memory operation?
                        // What register will these results be written into?
                        // What register will these results be written into?
                        opR    <= dcdR;
                        r_opR    <= dcdR;
                        opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie);
                        r_opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie);
                        // User level (1), vs supervisor (0)/interrupts disabled
                        // User level (1), vs supervisor (0)/interrupts disabled
                        op_gie <= dcd_gie;
                        r_op_gie <= dcd_gie;
 
 
 
 
                        //
                        //
                        op_pc  <= (dcd_early_branch)?dcd_branch_pc:dcd_pc;
                        op_pc  <= (dcd_early_branch)?dcd_branch_pc:dcd_pc;
                end
                end
 
        assign  opn = r_opn;
 
        assign  opR = r_opR;
 
        assign  op_gie = r_op_gie;
 
        assign  opR_cc = r_opR_cc;
 
`else
 
        assign  opn = dcdOp;
 
        assign  opR = dcdR;
 
        assign  op_gie = dcd_gie;
 
        // With no pipelining, there is no early branching.  We keep it
 
        always @(posedge i_clk)
 
                op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc;
 
`endif
        assign  opFl = (op_gie)?(w_uflags):(w_iflags);
        assign  opFl = (op_gie)?(w_uflags):(w_iflags);
 
 
`ifdef  OPT_VLIW
`ifdef  OPT_VLIW
        reg     r_op_phase;
        reg     r_op_phase;
        initial r_op_phase = 1'b0;
        initial r_op_phase = 1'b0;
Line 1164... Line 1211...
        assign  alu_phase = r_alu_phase;
        assign  alu_phase = r_alu_phase;
`else
`else
        assign  alu_phase = 1'b0;
        assign  alu_phase = 1'b0;
`endif
`endif
 
 
 
`ifdef  OPT_PIPELINED
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (adf_ce_unconditional)
                if (adf_ce_unconditional)
                        alu_reg <= opR;
                        alu_reg <= opR;
                else if ((i_halt)&&(i_dbg_we))
                else if ((i_halt)&&(i_dbg_we))
                        alu_reg <= i_dbg_reg;
                        alu_reg <= i_dbg_reg;
 
`else
 
        always @(posedge i_clk)
 
                if ((i_halt)&&(i_dbg_we))
 
                        alu_reg <= i_dbg_reg;
 
                else
 
                        alu_reg <= opR;
 
`endif
 
 
        //
        //
        // DEBUG Register write access starts here
        // DEBUG Register write access starts here
        //
        //
        reg             dbgv;
        reg             dbgv;
Line 1180... Line 1235...
        always @(posedge i_clk)
        always @(posedge i_clk)
                dbgv <= (~i_rst)&&(i_halt)&&(i_dbg_we)&&(r_halted);
                dbgv <= (~i_rst)&&(i_halt)&&(i_dbg_we)&&(r_halted);
        reg     [31:0]   dbg_val;
        reg     [31:0]   dbg_val;
        always @(posedge i_clk)
        always @(posedge i_clk)
                dbg_val <= i_dbg_data;
                dbg_val <= i_dbg_data;
 
`ifdef  OPT_PIPELINED
 
        reg     r_alu_gie;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((adf_ce_unconditional)||(mem_ce))
                if ((adf_ce_unconditional)||(mem_ce))
                        alu_gie  <= op_gie;
                        r_alu_gie  <= op_gie;
 
        assign  alu_gie = r_alu_gie;
 
 
 
        reg     [(AW-1):0]       r_alu_pc;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((adf_ce_unconditional)
                if ((adf_ce_unconditional)
                        ||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
                        ||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
                                &&(~mem_stalled)))
                                &&(~mem_stalled)))
                        alu_pc  <= op_pc;
                        r_alu_pc  <= op_pc;
 
        assign  alu_pc = r_alu_pc;
 
`else
 
        assign  alu_gie = op_gie;
 
        assign  alu_pc = op_pc;
 
`endif
 
 
`ifdef  OPT_ILLEGAL_INSTRUCTION
`ifdef  OPT_ILLEGAL_INSTRUCTION
        reg     r_alu_illegal;
        reg     r_alu_illegal;
        initial r_alu_illegal = 0;
        initial r_alu_illegal = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
Line 1393... Line 1459...
                if ((i_rst)||(i_halt))
                if ((i_rst)||(i_halt))
                        break_en <= 1'b0;
                        break_en <= 1'b0;
                else if ((wr_reg_ce)&&(wr_write_scc))
                else if ((wr_reg_ce)&&(wr_write_scc))
                        break_en <= wr_spreg_vl[`CPU_BREAK_BIT];
                        break_en <= wr_spreg_vl[`CPU_BREAK_BIT];
 
 
        initial break_pending = 1'b0;
`ifdef  OPT_PIPELINED
 
        reg     r_break_pending;
 
 
 
        initial r_break_pending = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((i_rst)||(clear_pipeline)||(~opvalid))
                if ((i_rst)||(clear_pipeline)||(~opvalid))
                        break_pending <= 1'b0;
                        r_break_pending <= 1'b0;
                else if (op_break)
                else if (op_break)
                        break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy);
                        r_break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy);
                else
                else
                        break_pending <= 1'b0;
                        r_break_pending <= 1'b0;
 
        assign  break_pending = r_break_pending;
 
`else
 
        assign  break_pending = op_break;
 
`endif
 
 
 
 
        assign  o_break = ((break_en)||(~op_gie))&&(break_pending)
        assign  o_break = ((break_en)||(~op_gie))&&(break_pending)
                                &&(~clear_pipeline)
                                &&(~clear_pipeline)
                        ||((~alu_gie)&&(bus_err))
                        ||((~alu_gie)&&(bus_err))
Line 1735... Line 1808...
                        if (i_dbg_reg[3:0] == `CPU_PC_REG)
                        if (i_dbg_reg[3:0] == `CPU_PC_REG)
                                o_dbg_reg <= {{(32-AW){1'b0}},(i_dbg_reg[4])?upc:ipc};
                                o_dbg_reg <= {{(32-AW){1'b0}},(i_dbg_reg[4])?upc:ipc};
                        else if (i_dbg_reg[3:0] == `CPU_CC_REG)
                        else if (i_dbg_reg[3:0] == `CPU_CC_REG)
                        begin
                        begin
                                o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
                                o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
 
                                o_dbg_reg[15] <= 1'b0;
                                o_dbg_reg[31:23] <= w_cpu_info;
                                o_dbg_reg[31:23] <= w_cpu_info;
                                o_dbg_reg[`CPU_GIE_BIT] <= gie;
                                o_dbg_reg[`CPU_GIE_BIT] <= gie;
                        end
                        end
                end
                end
        end else begin
        end else begin
Line 1748... Line 1822...
                        if (i_dbg_reg[3:0] == `CPU_PC_REG)
                        if (i_dbg_reg[3:0] == `CPU_PC_REG)
                                o_dbg_reg <= (i_dbg_reg[4])?upc:ipc;
                                o_dbg_reg <= (i_dbg_reg[4])?upc:ipc;
                        else if (i_dbg_reg[3:0] == `CPU_CC_REG)
                        else if (i_dbg_reg[3:0] == `CPU_CC_REG)
                        begin
                        begin
                                o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
                                o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
 
                                o_dbg_reg[15] <= 1'b0;
                                o_dbg_reg[31:23] <= w_cpu_info;
                                o_dbg_reg[31:23] <= w_cpu_info;
                                o_dbg_reg[`CPU_GIE_BIT] <= gie;
                                o_dbg_reg[`CPU_GIE_BIT] <= gie;
                        end
                        end
                end
                end
        end endgenerate
        end endgenerate
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_dbg_cc <= { o_break, bus_err, gie, sleep };
                o_dbg_cc <= { o_break, bus_err, gie, sleep };
 
 
 
`ifdef  OPT_PIPELINED
        always @(posedge i_clk)
        always @(posedge i_clk)
                r_halted <= (i_halt)&&(
                r_halted <= (i_halt)&&(
                        // To be halted, any long lasting instruction must
                        // To be halted, any long lasting instruction must
                        // be completed.
                        // be completed.
                        (~pf_cyc)&&(~mem_busy)&&(~alu_busy)
                        (~pf_cyc)&&(~mem_busy)&&(~alu_busy)
                                &&(~div_busy)&&(~fpu_busy)
                                &&(~div_busy)&&(~fpu_busy)
                        // Operations must either be valid, or illegal
                        // Operations must either be valid, or illegal
                        &&((opvalid)||(i_rst)||(dcd_illegal))
                        &&((opvalid)||(i_rst)||(dcd_illegal))
                        // Decode stage must be either valid, in reset, or ill
                        // Decode stage must be either valid, in reset, or ill
                        &&((dcdvalid)||(i_rst)||(pf_illegal)));
                        &&((dcdvalid)||(i_rst)||(pf_illegal)));
 
`else
 
        always @(posedge i_clk)
 
                r_halted <= (i_halt)&&((opvalid)||(i_rst));
 
`endif
        assign  o_dbg_stall = ~r_halted;
        assign  o_dbg_stall = ~r_halted;
 
 
        //
        //
        //
        //
        // Produce accounting outputs: Account for any CPU stalls, so we can
        // Produce accounting outputs: Account for any CPU stalls, so we can
Line 1780... Line 1860...
        assign  o_op_stall = (master_ce)&&(op_stall);
        assign  o_op_stall = (master_ce)&&(op_stall);
        assign  o_pf_stall = (master_ce)&&(~pf_valid);
        assign  o_pf_stall = (master_ce)&&(~pf_valid);
        assign  o_i_count  = (alu_pc_valid)&&(~clear_pipeline);
        assign  o_i_count  = (alu_pc_valid)&&(~clear_pipeline);
 
 
`ifdef  DEBUG_SCOPE
`ifdef  DEBUG_SCOPE
        reg     [31:0]   r_stack;
        // CLRPIP: If clear_pipeline, produce address ... can be 28 bits
        always @(posedge i_clk)
        // DATWR:  If write value, produce 4-bits of register ID, 27 bits of value
                if ((wr_reg_ce)&&(wr_reg_id == 5'h0d))
        // STALL:  If neither, produce pipeline stall information
                        r_stack <= wr_gpreg_vl;
        // ADDR:   If bus is valid, no ack, return the bus address
        reg     r_stack_pre, r_stack_post;
        reg             debug_trigger;
        always @(posedge i_clk)
        initial debug_trigger = 1'b0;
                r_stack_pre  <= (r_stack == 32'h03fff);
        always @(posedge i_clk)
        always @(posedge i_clk)
                debug_trigger <= (!i_halt)&&(o_break);
                r_stack_post <= (r_stack == 32'h03eeb);
 
 
        wire    [31:0]   debug_flags;
        always @(posedge i_clk)
        assign debug_flags = { debug_trigger, 3'b101,
                o_debug <= {
                                master_ce, i_halt, o_break, sleep,
                /*
                                gie, ibus_err_flag, trap, ill_err_i,
                        o_break, i_wb_err, pf_pc[1:0],
                                r_clear_icache, pf_valid, pf_illegal, dcd_ce,
                        flags,
                                dcdvalid, dcd_stalled, op_ce, opvalid,
                        pf_valid, dcdvalid, opvalid, alu_valid, mem_valid,
                                op_pipe, alu_ce, alu_busy, alu_wr,
                        op_ce, alu_ce, mem_ce,
                                alu_illegal, alF_wr, mem_ce, mem_we,
                        //
                                mem_busy, mem_pipe_stalled, (new_pc), (dcd_early_branch) };
                        master_ce, opvalid_alu, opvalid_mem,
 
                        //
 
                        alu_stall, mem_busy, op_pipe, mem_pipe_stalled,
 
                        mem_we,
 
                        // ((opvalid_alu)&&(alu_stall))
 
                        // ||((opvalid_mem)&&(~op_pipe)&&(mem_busy))
 
                        // ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
 
                        // opA[23:20], opA[3:0],
 
                        gie, sleep, wr_reg_ce, wr_gpreg_vl[4:0]
 
                */
 
                /*
 
                        i_rst, master_ce, (new_pc),
 
                        ((dcd_early_branch)&&(dcdvalid)),
 
                        pf_valid, pf_illegal,
 
                        op_ce, dcd_ce, dcdvalid, dcd_stalled,
 
                        pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
 
                        pf_pc[7:0], pf_addr[7:0]
 
                */
 
 
 
                        (i_wb_err)||(r_stack_post), (gie)||(r_stack_pre), (alu_illegal)||(r_stack_post),
        always @(posedge i_clk)
                              (new_pc)||((dcd_early_branch)&&(~clear_pipeline)),
        begin
                        mem_busy,
                if ((i_halt)||(!master_ce)||(debug_trigger)||(o_break))
                                (mem_busy)?{ (o_wb_gbl_stb|o_wb_lcl_stb), o_wb_we,
                        o_debug <= debug_flags;
                                        o_wb_addr[8:0] }
                else if ((mem_valid)||((~clear_pipeline)&&(~alu_illegal)
                                        : { instruction[31:21] },
                                        &&(((alu_wr)&&(alu_valid))
                        pf_valid, (pf_valid) ? alu_pc[14:0]
                                                ||(div_valid)||(fpu_valid))))
                                :{ pf_cyc, pf_stb, pf_pc[12:0] }
                        o_debug <= { debug_trigger, 1'b0, wr_reg_id[3:0], wr_gpreg_vl[25:0]};
 
                else if (clear_pipeline)
                /*
                        o_debug <= { debug_trigger, 3'b100, pf_pc[27:0] };
                        i_wb_err, gie, new_pc, dcd_early_branch,        // 4
                else if ((o_wb_gbl_stb)|(o_wb_lcl_stb))
                        pf_valid, pf_cyc, pf_stb, instruction_pc[0],    // 4
                        o_debug <= {debug_trigger,  2'b11, o_wb_gbl_stb, o_wb_we,
                        instruction[30:27],                             // 4
                                (o_wb_we)?o_wb_data[26:0] : o_wb_addr[26:0] };
                        dcd_gie, mem_busy, o_wb_gbl_cyc, o_wb_gbl_stb,  // 4
                else
                        dcdvalid,
                        o_debug <= debug_flags;
                        ((dcd_early_branch)&&(~clear_pipeline))         // 15
        end
                                        ? dcd_branch_pc[14:0]:pf_pc[14:0]
 
                */
 
                        };
 
`endif
`endif
 
 
/*
 
always  @(posedge i_clk)
 
        o_debug <= {
 
                // External control interaction (4b)
 
                i_halt, i_rst, i_clear_cache, o_break,
 
                // Bus interaction (8b)
 
                pf_cyc,(o_wb_gbl_cyc|o_wb_lcl_cyc), o_wb_gbl_stb, o_wb_lcl_stb,
 
                        o_wb_we, i_wb_ack, i_wb_stall, i_wb_err,
 
                // PC control (4b)
 
                gie, new_pc, dcd_early_branch, 1'b0,
 
                // Our list of pipeline stage values (8b)
 
                pf_valid, pf_illegal, dcdvalid, opvalid, alu_valid, mem_valid,
 
                        alu_pc_valid, mem_pc_valid,
 
                // Our list of circuit enables ... (8b)
 
                (new_pc)||((dcd_early_branch)&&(~clear_pipeline)),
 
                        dcd_ce, op_ce, alu_ce, mem_ce, wr_reg_ce, wr_flags_ce,
 
                        1'b0,
 
                // Useful PC values (64b)
 
                ((dcd_early_branch)&&(~clear_pipeline))
 
                                        ? dcd_branch_pc[15:0]:pf_pc[15:0],
 
                (gie)?upc[15:0]:ipc[15:0], instruction_pc[15:0], instruction[31:16] };
 
*/
 
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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