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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [rtl/] [cpu/] [idecode.v] - Diff between revs 2 and 11

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

Rev 2 Rev 11
Line 73... Line 73...
        output  wire    [31:0]   o_I;
        output  wire    [31:0]   o_I;
        output  reg             o_zI;
        output  reg             o_zI;
        output  reg     [3:0]    o_cond;
        output  reg     [3:0]    o_cond;
        output  reg             o_wF;
        output  reg             o_wF;
        output  reg     [3:0]    o_op;
        output  reg     [3:0]    o_op;
        output  reg             o_ALU, o_M, o_DV, o_FP, o_break, o_lock;
        output  reg             o_ALU, o_M, o_DV, o_FP, o_break;
 
        output  wire            o_lock;
        output  reg             o_wR, o_rA, o_rB;
        output  reg             o_wR, o_rA, o_rB;
        output  wire            o_early_branch;
        output  wire            o_early_branch;
        output  wire    [(AW-1):0]       o_branch_pc;
        output  wire    [(AW-1):0]       o_branch_pc;
        output  wire            o_ljmp;
        output  wire            o_ljmp;
        output  reg             o_pipe;
        output  wire            o_pipe;
 
 
        wire    dcdA_stall, dcdB_stall, dcdF_stall;
        wire    dcdA_stall, dcdB_stall, dcdF_stall;
        wire                    o_dcd_early_branch;
        wire                    o_dcd_early_branch;
        wire    [(AW-1):0]       o_dcd_branch_pc;
        wire    [(AW-1):0]       o_dcd_branch_pc;
        reg     o_dcdI, o_dcdIz;
        reg     o_dcdI, o_dcdIz;
 
`ifdef  OPT_PIPELINED
 
        reg     r_lock, r_pipe;
 
`endif
 
 
 
 
        wire    [4:0]    w_op;
        wire    [4:0]    w_op;
        wire            w_ldi, w_mov, w_cmptst, w_ldixx, w_ALU;
        wire            w_ldi, w_mov, w_cmptst, w_ldilo, w_ALU, w_brev, w_noop;
        wire    [4:0]    w_dcdR, w_dcdB, w_dcdA;
        wire    [4:0]    w_dcdR, w_dcdB, w_dcdA;
        wire            w_dcdR_pc, w_dcdR_cc;
        wire            w_dcdR_pc, w_dcdR_cc;
        wire            w_dcdA_pc, w_dcdA_cc;
        wire            w_dcdA_pc, w_dcdA_cc;
        wire            w_dcdB_pc, w_dcdB_cc;
        wire            w_dcdB_pc, w_dcdB_cc;
        wire    [3:0]    w_cond;
        wire    [3:0]    w_cond;
        wire            w_wF, w_dcdM, w_dcdDV, w_dcdFP;
        wire            w_wF, w_dcdM, w_dcdDV, w_dcdFP;
        wire            w_wR, w_rA, w_rB, w_wR_n;
        wire            w_wR, w_rA, w_rB, w_wR_n;
        wire            w_ljmp;
        wire            w_ljmp;
 
        wire    [31:0]   iword;
        generate
 
        if (EARLY_BRANCHING != 0)
 
                assign  w_ljmp = (iword == 32'h7c87c000);
 
        else
 
                assign  w_ljmp = 1'b0;
 
        endgenerate
 
 
 
 
 
        wire    [31:0]   iword;
 
`ifdef  OPT_VLIW
`ifdef  OPT_VLIW
        reg     [16:0]   r_nxt_half;
        reg     [16:0]   r_nxt_half;
        assign  iword = (o_phase)
        assign  iword = (o_phase)
                                // set second half as a NOOP ... but really 
                                // set second half as a NOOP ... but really 
                                // shouldn't matter
                                // shouldn't matter
Line 117... Line 114...
                        : i_instruction;
                        : i_instruction;
`else
`else
        assign  iword = { 1'b0, i_instruction[30:0] };
        assign  iword = { 1'b0, i_instruction[30:0] };
`endif
`endif
 
 
 
        generate
 
        if (EARLY_BRANCHING != 0)
 
                assign  w_ljmp = (iword == 32'h7c87c000);
 
        else
 
                assign  w_ljmp = 1'b0;
 
        endgenerate
 
 
 
 
        assign  w_op= iword[26:22];
        assign  w_op= iword[26:22];
        assign  w_mov    = (w_op      == 5'h0f);
        assign  w_mov    = (w_op      == 5'h0f);
        assign  w_ldi    = (w_op[4:1] == 4'hb);
        assign  w_ldi    = (w_op[4:1] == 4'hb);
 
        assign  w_brev   = (w_op      == 5'hc);
        assign  w_cmptst = (w_op[4:1] == 4'h8);
        assign  w_cmptst = (w_op[4:1] == 4'h8);
        assign  w_ldixx  = (w_op[4:1] == 4'h4);
        assign  w_ldilo  = (w_op[4:0] == 5'h9);
        assign  w_ALU    = (~w_op[4]);
        assign  w_ALU    = (~w_op[4]);
 
 
        // 4 LUTs
        // 4 LUTs
 
        //
 
        // Two parts to the result register: the register set, given for
 
        // moves in i_word[18] but only for the supervisor, and the other
 
        // four bits encoded in the instruction.
 
        //
        assign  w_dcdR = { ((~iword[31])&&(w_mov)&&(~i_gie))?iword[18]:i_gie,
        assign  w_dcdR = { ((~iword[31])&&(w_mov)&&(~i_gie))?iword[18]:i_gie,
                                iword[30:27] };
                                iword[30:27] };
 
        // 2 LUTs
 
        //
 
        // If the result register is either CC or PC, and this would otherwise
 
        // be a floating point instruction with floating point opcode of 0,
 
        // then this is a NOOP.
 
        assign  w_noop   = (w_op[4:0] == 5'h18)&&(w_dcdR[3:1] == 3'h7);
 
 
        // 4 LUTs
        // 4 LUTs
        assign  w_dcdB = { ((~iword[31])&&(w_mov)&&(~i_gie))?iword[13]:i_gie,
        assign  w_dcdB = { ((~iword[31])&&(w_mov)&&(~i_gie))?iword[13]:i_gie,
                                iword[17:14] };
                                iword[17:14] };
 
 
        // 0 LUTs
        // 0 LUTs
Line 173... Line 191...
                                ||((w_dcdM)&&(w_op[0]))
                                ||((w_dcdM)&&(w_op[0]))
                                // Test/compares
                                // Test/compares
                                ||(w_op[4:1]== 4'h8);
                                ||(w_op[4:1]== 4'h8);
        // 1 LUTs -- do we read a register for operand B?  Specifically, do
        // 1 LUTs -- do we read a register for operand B?  Specifically, do
        // we need to stall if the register is not (yet) ready?
        // we need to stall if the register is not (yet) ready?
        assign  w_rB     = (w_mov)||((iword[18])&&((~w_ldi)&&(~w_ldixx)));
        assign  w_rB     = (w_mov)||((iword[18])&&(~w_ldi));
        // 1 LUT: All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
        // 1 LUT: All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
        assign  w_wR_n   = ((w_dcdM)&&(w_op[0]))
        assign  w_wR_n   = ((w_dcdM)&&(w_op[0]))
                                ||((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7))
                                ||((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7))
                                ||(w_cmptst);
                                ||(w_cmptst);
        assign  w_wR     = ~w_wR_n;
        assign  w_wR     = ~w_wR_n;
Line 186... Line 204...
        //      
        //      
        //      This'd be 4 LUTs, save that we have the carve out for NOOPs
        //      This'd be 4 LUTs, save that we have the carve out for NOOPs
        //      and writes to the PC/CC register(s).
        //      and writes to the PC/CC register(s).
        assign  w_wF     = (w_cmptst)
        assign  w_wF     = (w_cmptst)
                        ||((w_cond[3])&&((w_dcdFP)||(w_dcdDV)
                        ||((w_cond[3])&&((w_dcdFP)||(w_dcdDV)
                                ||((w_ALU)&&(~w_mov)&&(~w_ldixx)
                                ||((w_ALU)&&(~w_mov)&&(~w_ldilo)&&(~w_brev)
                                        &&(iword[30:28] != 3'h7))));
                                        &&(iword[30:28] != 3'h7))));
 
 
        // Bottom 13 bits: no LUT's
        // Bottom 13 bits: no LUT's
        // w_dcd[12: 0] -- no LUTs
        // w_dcd[12: 0] -- no LUTs
        // w_dcd[   13] -- 2 LUTs
        // w_dcd[   13] -- 2 LUTs
Line 269... Line 287...
                        else if ((IMPLEMENT_FPU==0)&&(w_dcdFP))
                        else if ((IMPLEMENT_FPU==0)&&(w_dcdFP))
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
 
 
                        if ((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)
                        if ((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)
                                &&(
                                &&(
                                        (w_op[2:0] != 3'h2)      // LOCK
                                        (w_op[2:0] != 3'h1)      // BREAK
                                        &&(w_op[2:0] != 3'h1)    // BREAK
`ifdef  OPT_PIPELINED
 
                                        &&(w_op[2:0] != 3'h2)    // LOCK
 
`endif
                                        &&(w_op[2:0] != 3'h0)))  // NOOP
                                        &&(w_op[2:0] != 3'h0)))  // NOOP
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
                end
                end
 
 
 
 
Line 311... Line 331...
                        // already done the rest of the decode necessary to 
                        // already done the rest of the decode necessary to 
                        // settle between the other instructions.  For example,
                        // settle between the other instructions.  For example,
                        // o_FP plus these four bits uniquely defines the FP
                        // o_FP plus these four bits uniquely defines the FP
                        // instruction, o_DV plus the bottom of these defines
                        // instruction, o_DV plus the bottom of these defines
                        // the divide, etc.
                        // the divide, etc.
                        o_op <= (w_ldi)? 4'hf:w_op[3:0];
                        o_op <= (w_ldi)||(w_noop)? 4'hf:w_op[3:0];
 
 
                        // Default values
                        // Default values
                        o_dcdR <= { w_dcdR_cc, w_dcdR_pc, w_dcdR};
                        o_dcdR <= { w_dcdR_cc, w_dcdR_pc, w_dcdR};
                        o_dcdA <= { w_dcdA_cc, w_dcdA_pc, w_dcdA};
                        o_dcdA <= { w_dcdA_cc, w_dcdA_pc, w_dcdA};
                        o_dcdB <= { w_dcdB_cc, w_dcdB_pc, w_dcdB};
                        o_dcdB <= { w_dcdB_cc, w_dcdB_pc, w_dcdB};
Line 323... Line 343...
                        o_rA  <= w_rA;
                        o_rA  <= w_rA;
                        o_rB  <= w_rB;
                        o_rB  <= w_rB;
                        r_I    <= w_I;
                        r_I    <= w_I;
                        o_zI   <= w_Iz;
                        o_zI   <= w_Iz;
 
 
                        o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst); // 1 LUT
                        // Turn a NOOP into an ALU operation--subtract in 
 
                        // particular, although it doesn't really matter as long
 
                        // as it doesn't take longer than one clock.  Note
 
                        // also that this depends upon not setting any registers
 
                        // or flags, which should already be true.
 
                        o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst)||(w_noop); // 2 LUT
                        o_M    <=  w_dcdM;
                        o_M    <=  w_dcdM;
                        o_DV   <=  w_dcdDV;
                        o_DV   <=  w_dcdDV;
                        o_FP   <=  w_dcdFP;
                        o_FP   <=  w_dcdFP;
 
 
                        o_break <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b001);
                        o_break <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b001);
                        o_lock  <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b010);
`ifdef  OPT_PIPELINED
 
                        r_lock  <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b010);
 
`endif
`ifdef  OPT_VLIW
`ifdef  OPT_VLIW
                        r_nxt_half <= { iword[31], iword[13:5],
                        r_nxt_half <= { iword[31], iword[13:5],
                                ((iword[21])? iword[20:19] : 2'h0),
                                ((iword[21])? iword[20:19] : 2'h0),
                                iword[4:0] };
                                iword[4:0] };
`endif
`endif
                end
                end
 
 
 
`ifdef  OPT_PIPELINED
 
        assign  o_lock = r_lock;
 
`else
 
        assign  o_lock = 1'b0;
 
`endif
 
 
        generate
        generate
        if (EARLY_BRANCHING!=0)
        if (EARLY_BRANCHING!=0)
        begin
        begin
                reg                     r_early_branch, r_ljmp;
                reg                     r_early_branch, r_ljmp;
                reg     [(AW-1):0]       r_branch_pc;
                reg     [(AW-1):0]       r_branch_pc;
Line 408... Line 441...
        //              by one
        //              by one
        // Note that we're not using iword here ... there's a lot of logic
        // Note that we're not using iword here ... there's a lot of logic
        // taking place, and it's only valid if the new word is not compressed.
        // taking place, and it's only valid if the new word is not compressed.
        //
        //
        reg     r_valid;
        reg     r_valid;
 
`ifdef  OPT_PIPELINED
 
        reg     r_pipe;
 
        initial r_pipe = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_ce)
                if (i_ce)
                        o_pipe <= (r_valid)&&(i_pf_valid)&&(~i_instruction[31])
                        r_pipe <= (r_valid)&&(i_pf_valid)&&(~i_instruction[31])
                                &&(w_dcdM)&&(o_M)&&(o_op[0] ==i_instruction[22])
                                &&(w_dcdM)&&(o_M)&&(o_op[0] ==i_instruction[22])
                                &&(i_instruction[17:14] == o_dcdB[3:0])
                                &&(i_instruction[17:14] == o_dcdB[3:0])
 
                                &&(i_instruction[17:14] != o_dcdA[3:0])
                                &&(i_gie == o_gie)
                                &&(i_gie == o_gie)
                                &&((i_instruction[21:19]==o_cond[2:0])
                                &&((i_instruction[21:19]==o_cond[2:0])
                                        ||(o_cond[2:0] == 3'h0))
                                        ||(o_cond[2:0] == 3'h0))
                                &&((i_instruction[13:0]==r_I[13:0])
                                &&((i_instruction[13:0]==r_I[13:0])
                                        ||({1'b0, i_instruction[13:0]}==(r_I[13:0]+14'h1)));
                                        ||({1'b0, i_instruction[13:0]}==(r_I[13:0]+14'h1)));
 
        assign o_pipe = r_pipe;
 
`else
 
        assign o_pipe = 1'b0;
 
`endif
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                if (i_rst)
                        r_valid <= 1'b0;
                        r_valid <= 1'b0;
                else if ((i_ce)&&(o_ljmp))
                else if ((i_ce)&&(o_ljmp))
                        r_valid <= 1'b0;
                        r_valid <= 1'b0;

powered by: WebSVN 2.1.0

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