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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [core/] [idecode.v] - Diff between revs 205 and 209

Show entire file | Details | Blame | View Log

Rev 205 Rev 209
Line 17... Line 17...
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 41... Line 41...
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
 
`default_nettype        none
//
//
`define CPU_SP_REG      4'hd
`define CPU_SP_REG      4'hd
`define CPU_CC_REG      4'he
`define CPU_CC_REG      4'he
`define CPU_PC_REG      4'hf
`define CPU_PC_REG      4'hf
//
//
`include "cpudefs.v"
`define CISBIT          31
 
`define CISIMMSEL       23
 
`define IMMSEL          18
//
//
//
//
//
//
module  idecode(i_clk, i_rst, i_ce, i_stalled,
module  idecode(i_clk, i_reset, i_ce, i_stalled,
                i_instruction, i_gie, i_pc, i_pf_valid,
                i_instruction, i_gie, i_pc, i_pf_valid,
                        i_illegal,
                        i_illegal,
                o_valid,
                o_valid,
                o_phase, o_illegal,
                o_phase, o_illegal,
                o_pc, o_gie,
                o_pc,
                o_dcdR, o_dcdA, o_dcdB, o_I, o_zI,
                o_dcdR, o_dcdA, o_dcdB,
 
                o_preA, o_preB,
 
                o_I, o_zI,
                o_cond, o_wF,
                o_cond, o_wF,
                o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
                o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
                o_wR, o_rA, o_rB,
                o_wR, o_rA, o_rB,
                o_early_branch, o_branch_pc, o_ljmp,
                o_early_branch, o_early_branch_stb, o_branch_pc, o_ljmp,
                o_pipe,
                o_pipe,
                o_sim, o_sim_immv
                o_sim, o_sim_immv
 
`ifdef  FORMAL
 
                , f_insn_word, f_insn_gie
 
`endif
                );
                );
        parameter       ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
        parameter               ADDRESS_WIDTH=24;
                        IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
        parameter       [0:0]     OPT_MPY = 1'b1;
        input                   i_clk, i_rst, i_ce, i_stalled;
        parameter       [0:0]     OPT_EARLY_BRANCHING = 1'b1;
        input   [31:0]           i_instruction;
        parameter       [0:0]     OPT_PIPELINED = 1'b1;
        input                   i_gie;
        parameter       [0:0]     OPT_DIVIDE = (OPT_PIPELINED);
        input   [(AW-1):0]       i_pc;
        parameter       [0:0]     OPT_FPU    = 1'b0;
        input                   i_pf_valid, i_illegal;
        parameter       [0:0]     OPT_CIS    = 1'b1;
 
        parameter       [0:0]     OPT_LOCK   = (OPT_PIPELINED);
 
        parameter       [0:0]     OPT_OPIPE  = (OPT_PIPELINED);
 
        parameter       [0:0]     OPT_SIM    = 1'b0;
 
        parameter       [0:0]     OPT_NO_USERMODE = 1'b0;
 
        localparam              AW = ADDRESS_WIDTH;
 
        //
 
        input   wire            i_clk, i_reset, i_ce, i_stalled;
 
        input   wire [31:0]      i_instruction;
 
        input   wire            i_gie;
 
        input   wire [(AW+1):0]  i_pc;
 
        input   wire            i_pf_valid, i_illegal;
        output  wire            o_valid, o_phase;
        output  wire            o_valid, o_phase;
        output  reg             o_illegal;
        output  reg             o_illegal;
        output  reg     [AW:0]   o_pc;
        output  reg     [(AW+1):0]       o_pc;
        output  reg             o_gie;
 
        output  reg     [6:0]    o_dcdR, o_dcdA, o_dcdB;
        output  reg     [6:0]    o_dcdR, o_dcdA, o_dcdB;
 
        output  wire    [4:0]    o_preA, o_preB;
        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;
        output  reg             o_ALU, o_M, o_DV, o_FP, o_break;
        output  wire            o_lock;
        output  reg             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, o_early_branch_stb;
        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  wire            o_pipe;
        output  wire            o_pipe;
        output  reg             o_sim           /* verilator public_flat */;
        output  reg             o_sim           /* verilator public_flat */;
        output  reg     [22:0]   o_sim_immv      /* verilator public_flat */;
        output  reg     [22:0]   o_sim_immv      /* verilator public_flat */;
 
`ifdef  FORMAL
        wire    dcdA_stall, dcdB_stall, dcdF_stall;
        output  reg     [31:0]   f_insn_word;
        wire                    o_dcd_early_branch;
        output  reg             f_insn_gie;
        wire    [(AW-1):0]       o_dcd_branch_pc;
 
        reg     o_dcdI, o_dcdIz;
 
`ifdef  OPT_PIPELINED
 
        reg     r_lock;
 
`endif
 
`ifdef  OPT_PIPELINED_BUS_ACCESS
 
        reg     r_pipe;
 
`endif
`endif
 
 
 
 
        wire    [4:0]    w_op;
        wire    [4:0]    w_op;
        wire            w_ldi, w_mov, w_cmptst, w_ldilo, w_ALU, w_brev,
        wire            w_ldi, w_mov, w_cmptst, w_ldilo, w_ALU, w_brev,
                        w_noop, w_lock;
                        w_noop, w_lock, w_sim, w_break, w_special, w_add,
 
                        w_mpy;
        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_mem, w_sto, w_div, w_fpu;
        wire            w_wF, w_mem, w_sto, w_div, w_fpu;
        wire            w_wR, w_rA, w_rB, w_wR_n;
        wire            w_wR, w_rA, w_rB, w_wR_n;
        wire            w_ljmp, w_ljmp_dly, w_cis_ljmp;
        wire            w_ljmp, w_ljmp_dly, w_cis_ljmp;
        wire    [31:0]   iword;
        wire    [31:0]   iword;
 
        wire            pf_valid;
 
 
 
        assign  pf_valid = (i_pf_valid)&&(!o_early_branch_stb);
 
 
 
 
 
        reg     [14:0]   r_nxt_half;
 
 
 
        generate if (OPT_CIS)
 
        begin : SET_IWORD
 
 
`ifdef  OPT_CIS
 
        reg     [15: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
                        ? { r_nxt_half[15:0], i_instruction[15:0] }
                        ? { 1'b1, r_nxt_half[14:0], i_instruction[15:0] }
                        : i_instruction;
                        : i_instruction;
`else
        end else begin : CLR_IWORD
        assign  iword = { 1'b0, i_instruction[30:0] };
        assign  iword = { 1'b0, i_instruction[30:0] };
`endif
 
 
                // verilator lint_off UNUSED
 
                wire    [14:0]   unused_nxt_half;
 
                assign          unused_nxt_half = r_nxt_half;
 
                // verilator lint_on  UNUSED
 
        end endgenerate
 
 
        generate
        generate
        if (EARLY_BRANCHING != 0)
        if (OPT_EARLY_BRANCHING)
        begin
        begin
`ifdef  OPT_CIS
                if (OPT_CIS)
                reg     r_pre_ljmp;
                begin : CIS_EARLY_BRANCHING
                always @(posedge i_clk)
 
                if ((i_rst)||(o_early_branch))
                        assign  w_cis_ljmp = (o_phase)&&(iword[31:16] == 16'hfcf8);
                        r_pre_ljmp <= 1'b0;
 
                else if ((i_ce)&&(i_pf_valid))
                end else begin : NOCIS_EARLY_BRANCH
                        r_pre_ljmp <= (!o_phase)&&(i_instruction[31])
 
                                &&(i_instruction[14:0] == 15'h7cf8);
 
                else if (i_ce)
 
                        r_pre_ljmp <= 1'b0;
 
 
 
                assign  w_cis_ljmp = r_pre_ljmp;
 
`else
 
                assign  w_cis_ljmp = 1'b0;
                assign  w_cis_ljmp = 1'b0;
`endif
 
                // 0.1111.10010.000.1.1111.000000000...
                end
                // 0111.1100.1000.0111.11000....
 
                assign  w_ljmp = (iword == 32'h7c87c000);
                assign  w_ljmp = (iword == 32'h7c87c000);
        end else begin
 
 
        end else begin : NO_EARLY_BRANCHING
 
 
                assign  w_cis_ljmp = 1'b0;
                assign  w_cis_ljmp = 1'b0;
                assign  w_ljmp = 1'b0;
                assign  w_ljmp = 1'b0;
        end
        end endgenerate
        endgenerate
 
 
 
`ifdef  OPT_CIS
 
`ifdef  VERILATOR
 
        wire    [4:0]    w_cis_op;
 
        always @(iword)
 
                if (!iword[31])
 
                        w_cis_op = w_op;
 
                else case(iword[26:24])
 
                3'h0: w_cis_op = 5'h00;
 
                3'h1: w_cis_op = 5'h01;
 
                3'h2: w_cis_op = 5'h02;
 
                3'h3: w_cis_op = 5'h10;
 
                3'h4: w_cis_op = 5'h12;
 
                3'h5: w_cis_op = 5'h13;
 
                3'h6: w_cis_op = 5'h18;
 
                3'h7: w_cis_op = 5'h0d;
 
                endcase
 
`else
 
        reg     [4:0]    w_cis_op;
        reg     [4:0]    w_cis_op;
        always @(iword,w_op)
 
                if (!iword[31])
        generate if (OPT_CIS)
                        w_cis_op <= w_op;
        begin : GEN_CIS_OP
 
 
 
                always @(*)
 
                if (!iword[`CISBIT])
 
                        w_cis_op = iword[26:22];
                else case(iword[26:24])
                else case(iword[26:24])
                3'h0: w_cis_op <= 5'h00;
                3'h0: w_cis_op = 5'h00; // ADD
                3'h1: w_cis_op <= 5'h01;
                3'h1: w_cis_op = 5'h01; // AND
                3'h2: w_cis_op <= 5'h02;
                3'h2: w_cis_op = 5'h02; // SUB
                3'h3: w_cis_op <= 5'h10;
                3'h3: w_cis_op = 5'h10; // BREV
                3'h4: w_cis_op <= 5'h12;
                3'h4: w_cis_op = 5'h12; // LW
                3'h5: w_cis_op <= 5'h13;
                3'h5: w_cis_op = 5'h13; // SW
                3'h6: w_cis_op <= 5'h18;
                3'h6: w_cis_op = 5'h18; // LDI
                3'h7: w_cis_op <= 5'h0d;
                3'h7: w_cis_op = 5'h0d; // MOV
                endcase
                endcase
`endif
 
`else
 
        wire    [4:0]    w_cis_op;
 
        assign  w_cis_op = w_op;
 
`endif
 
 
 
 
        end else begin : GEN_NOCIS_OP
 
 
 
                always @(*)
 
                        w_cis_op = w_op;
 
 
 
        end endgenerate
 
 
 
        // Decode instructions
        assign  w_op= iword[26:22];
        assign  w_op= iword[26:22];
        assign  w_mov    = (w_cis_op      == 5'h0d);
        assign  w_mov    = (w_cis_op      == 5'h0d);
        assign  w_ldi    = (w_cis_op[4:1] == 4'hc);
        assign  w_ldi    = (w_cis_op[4:1] == 4'hc);
        assign  w_brev   = (w_cis_op      == 5'h8);
        assign  w_brev   = (w_cis_op      == 5'h08);
 
        assign  w_mpy    = (w_cis_op[4:1] == 4'h5)||(w_cis_op[4:0]==5'h0c);
        assign  w_cmptst = (w_cis_op[4:1] == 4'h8);
        assign  w_cmptst = (w_cis_op[4:1] == 4'h8);
        assign  w_ldilo  = (w_cis_op[4:0] == 5'h9);
        assign  w_ldilo  = (w_cis_op[4:0] == 5'h09);
        assign  w_ALU    = (!w_cis_op[4]) // anything with [4]==0, but ...
        assign  w_ALU    = (!w_cis_op[4]) // anything with [4]==0, but ...
                                &&(w_cis_op[3:1] != 3'h7); // not the divide
                                &&(w_cis_op[3:1] != 3'h7); // not the divide
 
        assign  w_add    = (w_cis_op[4:0] == 5'h02);
 
        assign  w_mem    = (w_cis_op[4:3] == 2'b10)&&(w_cis_op[2:1] !=2'b00);
 
        assign  w_sto    = (w_mem)&&( w_cis_op[0]);
 
        assign  w_div    = (!iword[`CISBIT])&&(w_op[4:1] == 4'h7);
 
        assign  w_fpu    = (!iword[`CISBIT])&&(w_op[4:3] == 2'b11)
 
                                &&(w_dcdR[3:1] != 3'h7)&&(w_op[2:1] != 2'b00);
 
        // 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_special= (!iword[`CISBIT])&&((!OPT_FPU)||(w_dcdR[3:1]==3'h7))
 
                        &&(w_op[4:2] == 3'b111);
 
        assign  w_break = (w_special)&&(w_op[4:0]==5'h1c);
 
        assign  w_lock  = (w_special)&&(w_op[4:0]==5'h1d);
 
        assign  w_sim   = (w_special)&&(w_op[4:0]==5'h1e);
 
        assign  w_noop  = (w_special)&&(w_op[4:0]==5'h1f);
 
 
 
 
        // w_dcdR (4 LUTs)
        // w_dcdR (4 LUTs)
        //
        //
        // What register will we be placing results into (if at all)?
        // What register will we be placing results into (if at all)?
        //
        //
        // Two parts to the result register: the register set, given for
        // Two parts to the result register: the register set, given for
        // moves in iword[18] but only for the supervisor, and the other
        // moves in iword[18] but only for the supervisor, and the other
        // four bits encoded in the instruction.
        // four bits encoded in the instruction.
        //
        //
        assign  w_dcdR = { ((!iword[31])&&(w_mov)&&(~i_gie))?iword[18]:i_gie,
        assign  w_dcdR = { ((!iword[`CISBIT])&&(!OPT_NO_USERMODE)&&(w_mov)&&(!i_gie))?iword[`IMMSEL]: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_lock   = (!iword[31])&&(w_op[4:0]==5'h1d)&&(
 
                                ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7))
 
                                ||(IMPLEMENT_FPU==0));
 
        assign  w_noop   = (!iword[31])&&(w_op[4:0] == 5'h1f)&&(
 
                        ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1] == 3'h7))
 
                        ||(IMPLEMENT_FPU==0));
 
 
 
        // dcdB - What register is used in the opB?
        // dcdB - What register is used in the opB?
        //
        //
        assign w_dcdB[4] = ((!iword[31])&&(w_mov)&&(~i_gie))?iword[13]:i_gie;
        assign w_dcdB[4] = ((!iword[`CISBIT])&&(w_mov)&&(!OPT_NO_USERMODE)&&(!i_gie))?iword[13]:i_gie;
        assign w_dcdB[3:0]= (iword[31])
        assign w_dcdB[3:0]= (iword[`CISBIT])
                                ? (((!iword[23])&&(iword[26:25]==2'b10))
                                ? (((!iword[`CISIMMSEL])&&(iword[26:25]==2'b10))
                                        ? `CPU_SP_REG : iword[22:19])
                                        ? `CPU_SP_REG : iword[22:19])
                                : iword[17:14];
                                : iword[17:14];
 
 
        // 0 LUTs
        // 0 LUTs
        assign  w_dcdA = w_dcdR;        // on ZipCPU, A is always result reg
        assign  w_dcdA = w_dcdR;        // on ZipCPU, A is always result reg
Line 244... Line 258...
        assign  w_dcdA_cc = w_dcdR_cc;
        assign  w_dcdA_cc = w_dcdR_cc;
        // 2 LUTs, 1 delays each
        // 2 LUTs, 1 delays each
        assign  w_dcdB_pc = (w_rB)&&(w_dcdB[3:0] == `CPU_PC_REG);
        assign  w_dcdB_pc = (w_rB)&&(w_dcdB[3:0] == `CPU_PC_REG);
        assign  w_dcdB_cc = (w_rB)&&(w_dcdB[3:0] == `CPU_CC_REG);
        assign  w_dcdB_cc = (w_rB)&&(w_dcdB[3:0] == `CPU_CC_REG);
 
 
        // Under what condition will we execute this
 
        // instruction?  Only the load immediate instruction
 
        // is completely unconditional.
 
        //
        //
        // 3+4 LUTs
        // Under what condition will we execute this instruction?  Only the
        assign  w_cond = ((w_ldi)||(iword[31])) ? 4'h8 :
        // load immediate instruction and the CIS instructions are completely
 
        // unconditional.  Well ... not quite.  The BREAK, LOCK, and SIM/NOOP
 
        // instructions are also unconditional.
 
        //
 
        assign  w_cond = ((w_ldi)||(w_special)||(iword[`CISBIT])) ? 4'h8 :
                        { (iword[21:19]==3'h0), iword[21:19] };
                        { (iword[21:19]==3'h0), iword[21:19] };
 
 
        // 1 LUT
 
        assign  w_mem    = (w_cis_op[4:3] == 2'b10)&&(w_cis_op[2:1] !=2'b00);
 
        assign  w_sto     = (w_mem)&&( w_cis_op[0]);
 
        // 1 LUT
 
        assign  w_div     = (!iword[31])&&(w_op[4:1] == 4'h7);
 
        // 2 LUTs
 
        assign  w_fpu   = (!iword[31])&&(w_op[4:3] == 2'b11)
 
                                &&(w_dcdR[3:1] != 3'h7)&&(w_op[2:1] != 2'b00);
 
        //
 
        // rA - do we need to read register A?
        // rA - do we need to read register A?
        assign  w_rA = // Floating point reads reg A
        assign  w_rA = // Floating point reads reg A
                        ((w_fpu)&&(w_cis_op[4:1] != 4'hf))
                        ((w_fpu)&&(OPT_FPU))
                        // Divide's read A
                        // Divide's read A
                        ||(w_div)
                        ||(w_div)
                        // ALU ops read A,
                        // ALU ops read A,
                        //      except for MOV's and BREV's which don't
                        //      except for MOV's and BREV's which don't
                        ||((w_ALU)&&(!w_brev)&&(!w_mov))
                        ||((w_ALU)&&(!w_brev)&&(!w_mov))
Line 276... Line 282...
                        // Test/compares
                        // Test/compares
                        ||(w_cmptst);
                        ||(w_cmptst);
        // rB -- do we read a register for operand B?  Specifically, do we
        // rB -- do we read a register for operand B?  Specifically, do we
        // add the registers value to the immediate to create opB?
        // add the registers value to the immediate to create opB?
        assign  w_rB     = (w_mov)
        assign  w_rB     = (w_mov)
                                ||((!iword[31])&&(iword[18])&&(!w_ldi))
                                ||((!iword[`CISBIT])&&(iword[`IMMSEL])&&(!w_ldi)&&(!w_special))
                                ||(( iword[31])&&(iword[23])&&(!w_ldi))
                                ||(( iword[`CISBIT])&&(iword[`CISIMMSEL])&&(!w_ldi))
                                // If using compressed instruction sets,
                                // If using compressed instruction sets,
                                // we *always* read on memory operands.
                                // we *always* read on memory operands.
                                ||(( iword[31])&&(w_mem));
                                ||(( iword[`CISBIT])&&(w_mem));
 
 
        // wR -- will we be writing our result back?
        // wR -- will we be writing our result back?
        // wR_n = !wR
        // wR_n = !wR
        // 1 LUT: All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
        // All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
        assign  w_wR_n   = (w_sto)
        assign  w_wR_n   = (w_sto)
                                ||((!iword[31])&&(w_cis_op[4:3]==2'b11)
                                ||(w_special)
                                        &&(w_cis_op[2:1]!=2'b00)
 
                                        &&(w_dcdR[3:1]==3'h7))
 
                                ||(w_cmptst);
                                ||(w_cmptst);
        assign  w_wR     = ~w_wR_n;
        assign  w_wR     = !w_wR_n;
        //
        //
        // wF -- do we write flags when we are done?
        // wF -- do we write flags when we are done?
        //
        //
        assign  w_wF     = (w_cmptst)
        assign  w_wF     = (w_cmptst)
                        ||((w_cond[3])&&((w_fpu)||(w_div)
                        ||((w_cond[3])&&(((w_fpu)&&(OPT_FPU))||(w_div)
                                ||((w_ALU)&&(!w_mov)&&(!w_ldilo)&&(!w_brev)
                                ||((w_ALU)&&(!w_mov)&&(!w_ldilo)&&(!w_brev)
                                        &&(w_dcdR[3:1] != 3'h7))));
                                        &&(w_dcdR[3:1] != 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
Line 311... Line 316...
 
 
        assign  w_fullI = (w_ldi) ? { iword[22:0] } // LDI
        assign  w_fullI = (w_ldi) ? { iword[22:0] } // LDI
                        // MOVE immediates have one less bit
                        // MOVE immediates have one less bit
                        :((w_mov) ?{ {(23-13){iword[12]}}, iword[12:0] }
                        :((w_mov) ?{ {(23-13){iword[12]}}, iword[12:0] }
                        // Normal Op-B immediate ... 18 or 14 bits
                        // Normal Op-B immediate ... 18 or 14 bits
                        :((~iword[18]) ? { {(23-18){iword[17]}}, iword[17:0] }
                        :((!iword[`IMMSEL]) ? { {(23-18){iword[17]}}, iword[17:0] }
                        : { {(23-14){iword[13]}}, iword[13:0] }
                        : { {(23-14){iword[13]}}, iword[13:0] }
                        ));
                        ));
 
 
`ifdef  OPT_CIS
        generate if (OPT_CIS)
 
        begin : GEN_CIS_IMMEDIATE
        wire    [7:0]    w_halfbits;
        wire    [7:0]    w_halfbits;
        assign  w_halfbits = iword[23:16];
                assign  w_halfbits = iword[`CISIMMSEL:16];
 
 
        wire    [7:0]    w_halfI;
        wire    [7:0]    w_halfI;
        assign  w_halfI = (iword[26:24]==3'h6) ? w_halfbits[7:0]
                assign  w_halfI = (iword[26:24]==3'h6) ? w_halfbits[7:0] // 8'b for LDI
                        :(w_halfbits[7])?
                        :(w_halfbits[7])?
                                { {(6){w_halfbits[2]}}, w_halfbits[1:0]}
                                { {(6){w_halfbits[2]}}, w_halfbits[1:0]}
                                :{ w_halfbits[6], w_halfbits[6:0] };
                                :{ w_halfbits[6], w_halfbits[6:0] };
        assign  w_I  = (iword[31])?{{(23-8){w_halfI[7]}}, w_halfI }:w_fullI;
                assign  w_I  = (iword[`CISBIT])
`else
                                ? {{(23-8){w_halfI[7]}}, w_halfI }
 
                                : w_fullI;
 
 
 
        end else begin : GEN_NOCIS_IMMEDIATE
 
 
        assign  w_I  = w_fullI;
        assign  w_I  = w_fullI;
`endif
 
 
        end endgenerate
 
 
        assign  w_Iz = (w_I == 0);
        assign  w_Iz = (w_I == 0);
 
 
 
 
`ifdef  OPT_CIS
 
        //
        //
        // The o_phase parameter is special.  It needs to let the software
        // The o_phase parameter is special.  It needs to let the software
        // following know that it cannot break/interrupt on an o_phase asserted
        // following know that it cannot break/interrupt on an o_phase asserted
        // instruction, lest the break take place between the first and second
        // instruction, lest the break take place between the first and second
        // half of a CIS instruction.  To do this, o_phase must be asserted
        // half of a CIS instruction.  To do this, o_phase must be asserted
        // when the first instruction half is valid, but not asserted on either
        // when the first instruction half is valid, but not asserted on either
        // a 32-bit instruction or the second half of a 2x16-bit instruction.
        // a 32-bit instruction or the second half of a 2x16-bit instruction.
 
        generate if (OPT_CIS)
 
        begin : GEN_CIS_PHASE
        reg     r_phase;
        reg     r_phase;
 
 
 
                // Phase is '1' on the first instruction of a two-part set
 
                // But, due to the delay in processing, it's '1' when our
 
                // output is valid for that first part, but that'll be the
 
                // same time we are processing the second part ... so it may
 
                // look to us like a '1' on the second half of processing.
 
 
 
                // When no instruction is in the pipe, phase is zero
        initial r_phase = 1'b0;
        initial r_phase = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((i_rst) // When no instruction is in the pipe, phase is zero
                if ((i_reset)||(w_ljmp_dly))
                        ||(o_early_branch)||(w_ljmp_dly))
 
                        r_phase <= 1'b0;
                        r_phase <= 1'b0;
                else if ((i_ce)&&(i_pf_valid))
                else if ((i_ce)&&(pf_valid))
                        r_phase <= (o_phase)? 1'b0
                begin
                                : ((i_instruction[31])&&(i_pf_valid));
                        if (o_phase)
                else if (i_ce)
                                // CIS instructions only have two parts.  On
 
                                // the second part (o_phase is true), return
 
                                // back to the first
 
                                r_phase <= 0;
 
                        else
 
                                r_phase <= (i_instruction[`CISBIT])&&(!i_illegal);
 
                end else if (i_ce)
                        r_phase <= 1'b0;
                        r_phase <= 1'b0;
        // Phase is '1' on the first instruction of a two-part set
 
        // But, due to the delay in processing, it's '1' when our output is
 
        // valid for that first part, but that'll be the same time we
 
        // are processing the second part ... so it may look to us like a '1'
 
        // on the second half of processing.
 
 
 
        assign  o_phase = r_phase;
        assign  o_phase = r_phase;
`else
        end else begin
        assign  o_phase = 1'b0;
        assign  o_phase = 1'b0;
`endif
        end endgenerate
 
 
 
 
        initial o_illegal = 1'b0;
        initial o_illegal = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
        if (i_ce)
                        o_illegal <= 1'b0;
 
                else if (i_ce)
 
                begin
                begin
`ifdef  OPT_CIS
                if (OPT_PIPELINED)
                        o_illegal <= (i_illegal);
                        o_illegal <= ((i_illegal)
`else
                                        &&((!o_phase)||(!o_valid)))
                        o_illegal <= ((i_illegal) || (i_instruction[31]));
                                ||((o_illegal)&&(o_phase)&&(o_valid));
`endif
                else
                        if ((IMPLEMENT_MPY==0)&&((w_cis_op[4:1]==4'h5)||(w_cis_op[4:0]==5'h0c)))
                        o_illegal <= (i_illegal)&&(!o_phase);
 
                if ((!OPT_CIS)&&(i_instruction[`CISBIT]))
 
                        o_illegal <= 1'b1;
 
                if ((!OPT_MPY)&&(w_mpy))
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
 
 
                        if ((IMPLEMENT_DIVIDE==0)&&(w_div))
                if ((!OPT_DIVIDE)&&(w_div))
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
                        else if ((IMPLEMENT_DIVIDE!=0)&&(w_div)&&(w_dcdR[3:1]==3'h7))
                else if ((OPT_DIVIDE)&&(w_div)&&(w_dcdR[3:1]==3'h7))
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
 
 
 
 
                        if ((IMPLEMENT_FPU==0)&&(w_fpu))
                if ((!OPT_FPU)&&(w_fpu))
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
 
 
                        if ((w_cis_op[4:3]==2'b11)&&(w_cis_op[2:1]!=2'b00)
                if ((!OPT_SIM)&&(w_sim))
                                &&(w_dcdR[3:1]==3'h7)
                // Simulation instructions on real hardware should
                                &&(
                // always cause an illegal instruction error
                                        (w_cis_op[2:0] != 3'h4)  // BREAK
                        o_illegal <= 1'b1;
`ifdef  OPT_PIPELINED
 
                                        &&(w_cis_op[2:0] != 3'h5)        // LOCK
                // There are two (missing) special instructions
`endif
                // These should cause an illegal instruction error
                                        // SIM instructions are always illegal
                if ((w_dcdR[3:1]==3'h7)&&(w_cis_op[4:1]==4'b1101))
                                        &&(w_cis_op[2:0] != 3'h7)))      // NOOP
 
                                o_illegal <= 1'b1;
                                o_illegal <= 1'b1;
                end
 
 
 
 
                // If the lock function isn't implemented, this should
 
                // also cause an illegal instruction error
 
                if ((!OPT_LOCK)&&(w_lock))
 
                        o_illegal <= 1'b1;
 
        end
 
 
 
        initial o_pc = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_ce)
        if ((i_ce)&&((o_phase)||(i_pf_valid)))
                begin
                begin
`ifdef  OPT_CIS
                o_pc[0] <= 1'b0;
                        if (!o_phase)
 
                                o_gie<= i_gie;
 
 
 
                        if (iword[31])
                if (OPT_CIS)
 
                begin
 
                        if (iword[`CISBIT])
                        begin
                        begin
                                if (o_phase)
                                if (o_phase)
                                        o_pc <= o_pc + 1'b1;
                                        o_pc[AW+1:1] <= o_pc[AW+1:1] + 1'b1;
                                else if (i_pf_valid)
                                else
                                        o_pc <= { i_pc, 1'b1 };
                                        o_pc <= { i_pc[AW+1:2], 1'b1, 1'b0 };
                        end else begin
                        end else begin
                                // The normal, non-CIS case
                                // The normal, non-CIS case
                                o_pc <= { i_pc + 1'b1, 1'b0 };
                                o_pc <= { i_pc[AW+1:2] + 1'b1, 2'b00 };
 
                        end
 
                end else begin
 
                        // The normal, non-CIS case
 
                        o_pc <= { i_pc[AW+1:2] + 1'b1, 2'b00 };
 
                end
                        end
                        end
`else
 
                        o_gie<= i_gie;
 
                        o_pc <= { i_pc + 1'b1, 1'b0 };
 
`endif
 
 
 
 
        initial o_dcdR = 0;
 
        initial o_dcdA = 0;
 
        initial o_dcdB = 0;
 
        initial o_DV   = 0;
 
        initial o_FP   = 0;
 
        initial o_lock = 0;
 
        always @(posedge i_clk)
 
        if (i_ce)
 
        begin
                        // Under what condition will we execute this
                        // Under what condition will we execute this
                        // instruction?  Only the load immediate instruction
                        // instruction?  Only the load immediate instruction
                        // is completely unconditional.
                        // is completely unconditional.
                        o_cond <= w_cond;
                        o_cond <= w_cond;
                        // Don't change the flags on conditional instructions,
                        // Don't change the flags on conditional instructions,
Line 440... Line 476...
                        // 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)||(w_noop))? 4'hd : w_cis_op[3:0];
                o_op <= w_cis_op[3:0];
 
                if ((w_ldi)||(w_noop)||(w_lock))
 
                        o_op <= 4'hd;
 
 
                        // 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 457... Line 495...
                        // Turn a NOOP into an ALU operation--subtract in
                        // Turn a NOOP into an ALU operation--subtract in
                        // particular, although it doesn't really matter as long
                        // particular, although it doesn't really matter as long
                        // as it doesn't take longer than one clock.  Note
                        // as it doesn't take longer than one clock.  Note
                        // also that this depends upon not setting any registers
                        // also that this depends upon not setting any registers
                        // or flags, which should already be true.
                        // or flags, which should already be true.
                        o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst)||(w_noop);
                o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst)||(w_noop)
 
                                ||((!OPT_LOCK)&&(w_lock));
                        o_M    <=  w_mem;
                        o_M    <=  w_mem;
                        o_DV   <=  w_div;
                o_DV   <=  (OPT_DIVIDE)&&(w_div);
                        o_FP   <=  w_fpu;
                o_FP   <=  (OPT_FPU)&&(w_fpu);
 
 
                        o_break <= (!iword[31])&&(w_op[4:0]==5'h1c)&&(
                o_break <= w_break;
                                ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7))
                o_lock  <= (OPT_LOCK)&&(w_lock);
                                ||(IMPLEMENT_FPU==0));
 
`ifdef  OPT_PIPELINED
                if (OPT_CIS)
                        r_lock  <= w_lock;
                        r_nxt_half <= { iword[14:0] };
`endif
                else
`ifdef  OPT_CIS
                        r_nxt_half <= 0;
                        r_nxt_half <= { iword[31], iword[14:0] };
 
`endif
 
 
 
`ifdef  VERILATOR
                if (OPT_SIM)
 
                begin
                        // Support the SIM instruction(s)
                        // Support the SIM instruction(s)
                        o_sim <= (!iword[31])&&(w_op[4:1] == 4'hf)
                        o_sim <= (w_sim)||(w_noop);
                                &&(w_dcdR[3:1] == 3'h7);
 
`else
 
                        o_sim <= 1'b0;
 
`endif
 
                        o_sim_immv <= iword[22:0];
                        o_sim_immv <= iword[22:0];
 
                end else begin
 
                        o_sim <= 1'b0;
 
                        o_sim_immv <= 0;
 
                end
                end
                end
 
 
`ifdef  OPT_PIPELINED
        assign  o_preA = w_dcdA;
        assign  o_lock = r_lock;
        assign  o_preB = w_dcdB;
`else
 
        assign  o_lock = 1'b0;
 
`endif
 
 
 
        generate
        generate if (OPT_EARLY_BRANCHING)
        if (EARLY_BRANCHING!=0)
        begin : GEN_EARLY_BRANCH_LOGIC
        begin
                reg                     r_early_branch,
                reg                     r_early_branch, r_ljmp;
                                        r_early_branch_stb,
                reg     [(AW-1):0]       r_branch_pc;
                                        r_ljmp;
 
                reg     [(AW+1):0]       r_branch_pc;
 
 
                initial r_ljmp = 1'b0;
                initial r_ljmp = 1'b0;
                always @(posedge i_clk)
                always @(posedge i_clk)
                        if (i_rst)
                if (i_reset)
                                r_ljmp <= 1'b0;
                                r_ljmp <= 1'b0;
`ifdef  OPT_CIS
                else if (i_ce)
                        else if ((i_ce)&&(o_phase))
                begin
 
                        if ((r_ljmp)&&(pf_valid))
 
                                r_ljmp <= 1'b0;
 
                        else if (o_early_branch_stb)
 
                                r_ljmp <= 1'b0;
 
                        else if (pf_valid)
 
                        begin
 
                                if ((OPT_CIS)&&(iword[`CISBIT]))
                                r_ljmp <= w_cis_ljmp;
                                r_ljmp <= w_cis_ljmp;
`endif
                                else
                        else if ((i_ce)&&(i_pf_valid))
 
                                r_ljmp <= (w_ljmp);
                                r_ljmp <= (w_ljmp);
 
                        end else if ((OPT_CIS)&&(o_phase)&&(iword[`CISBIT]))
 
                                r_ljmp <= w_cis_ljmp;
 
                end
                assign  o_ljmp = r_ljmp;
                assign  o_ljmp = r_ljmp;
 
 
 
                initial r_early_branch     = 1'b0;
 
                initial r_early_branch_stb = 1'b0;
                always @(posedge i_clk)
                always @(posedge i_clk)
                if (i_rst)
                if (i_reset)
 
                begin
                        r_early_branch <= 1'b0;
                        r_early_branch <= 1'b0;
                else if ((i_ce)&&(i_pf_valid))
                        r_early_branch_stb <= 1'b0;
 
                end else if ((i_ce)&&(pf_valid))
                begin
                begin
                        if (r_ljmp)
                        if (r_ljmp)
                                // LOD (PC),PC
                        begin
 
                                // LW (PC),PC
                                r_early_branch <= 1'b1;
                                r_early_branch <= 1'b1;
                        else if ((!iword[31])&&(iword[30:27]==`CPU_PC_REG)
                                r_early_branch_stb <= 1'b1;
 
                        end else if ((!iword[`CISBIT])&&(iword[30:27]==`CPU_PC_REG)
                                        &&(w_cond[3]))
                                        &&(w_cond[3]))
                        begin
                        begin
                                if ((w_op[4:0]==5'h02)&&(!iword[18]))
                                if ((w_add)&&(!iword[`IMMSEL]))
 
                                begin
                                        // Add x,PC
                                        // Add x,PC
                                        r_early_branch     <= 1'b1;
                                        r_early_branch     <= 1'b1;
                                else
                                        r_early_branch_stb <= 1'b1;
 
                                end else begin
                                        r_early_branch     <= 1'b0;
                                        r_early_branch     <= 1'b0;
                        end else
                                        r_early_branch_stb <= 1'b0;
 
                                end
 
                        // LDI #x,PC is no longer supported
 
                        end else begin
                                r_early_branch <= 1'b0;
                                r_early_branch <= 1'b0;
 
                                r_early_branch_stb <= 1'b0;
 
                        end
                end else if (i_ce)
                end else if (i_ce)
 
                begin
                        r_early_branch <= 1'b0;
                        r_early_branch <= 1'b0;
 
                        r_early_branch_stb <= 1'b0;
 
                end else
 
                        r_early_branch_stb <= 1'b0;
 
 
 
                initial r_branch_pc = 0;
                always @(posedge i_clk)
                always @(posedge i_clk)
                        if (i_ce)
                        if (i_ce)
                        begin
                        begin
                                if (r_ljmp)
                                if (r_ljmp)
                                        r_branch_pc <= iword[(AW+1):2];
                                r_branch_pc <= { iword[(AW+1):2],
                                else // Add x,PC
                                                2'b00 };
                                r_branch_pc <= i_pc
                        else begin
 
                        // Add x,PC
 
                        r_branch_pc[AW+1:2] <= i_pc[AW+1:2]
                                        + {{(AW-15){iword[17]}},iword[16:2]}
                                        + {{(AW-15){iword[17]}},iword[16:2]}
                                        + {{(AW-1){1'b0}},1'b1};
                                        + {{(AW-1){1'b0}},1'b1};
 
                        r_branch_pc[1:0] <= 2'b00;
 
                        end
                        end
                        end
 
 
                assign  w_ljmp_dly         = r_ljmp;
                assign  w_ljmp_dly         = r_ljmp;
                assign  o_early_branch     = r_early_branch;
                assign  o_early_branch     = r_early_branch;
 
                assign  o_early_branch_stb = r_early_branch_stb;
                assign  o_branch_pc        = r_branch_pc;
                assign  o_branch_pc        = r_branch_pc;
        end else begin
        end else begin
                assign  w_ljmp_dly         = 1'b0;
                assign  w_ljmp_dly         = 1'b0;
                assign  o_early_branch = 1'b0;
                assign  o_early_branch = 1'b0;
                assign  o_branch_pc = {(AW){1'b0}};
                assign  o_early_branch_stb = 1'b0;
 
                assign  o_branch_pc = {(AW+2){1'b0}};
                assign  o_ljmp = 1'b0;
                assign  o_ljmp = 1'b0;
 
 
 
                // verilator lint_off UNUSED
 
                wire    early_branch_unused;
 
                assign  early_branch_unused = w_add;
 
                // verilator lint_on  UNUSED
        end endgenerate
        end endgenerate
 
 
 
 
        // To be a pipeable operation there must be ...
        // To be a pipeable operation there must be ...
        //      1. Two valid adjacent instructions
        //      1. Two valid adjacent instructions
Line 559... Line 633...
        //      4. Both must be to the same address, or the address incremented
        //      4. Both must be to the same address, or the address incremented
        //              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, r_insn_is_pipeable;
`ifdef  OPT_PIPELINED_BUS_ACCESS
        generate if (OPT_OPIPE)
 
        begin : GEN_OPIPE
 
                reg     r_pipe;
 
 
 
                wire    [13:0]   pipe_addr_diff;
 
                assign          pipe_addr_diff = w_I[13:0] - r_I[13:0];
 
 
 
                // Pipeline logic is too extreme for a single clock.
 
                // Let's break it into two clocks, using r_insn_is_pipeable
 
                // If this function is true, then the instruction associated
 
                // with the current output *may* have a pipeable instruction
 
                // following it.
 
                //
 
                initial r_insn_is_pipeable = 1'b0;
 
                always @(posedge i_clk)
 
                if (i_reset)
 
                        r_insn_is_pipeable <= 1'b0;
 
                else if ((i_ce)&&((!pf_valid)||(i_illegal))&&(!o_phase))
 
                        // Pipeline bubble, can't pipe through it
 
                        r_insn_is_pipeable <= 1'b0;
 
                else if (o_ljmp)
 
                        r_insn_is_pipeable <= 1'b0;
 
                else if ((i_ce)&&((!OPT_CIS)&&(i_instruction[`CISBIT])))
 
                        r_insn_is_pipeable <= 1'b0;
 
                else if (i_ce)
 
                begin   // This is a valid instruction
 
                        r_insn_is_pipeable <= (w_mem)&&(w_rB)
 
                                // PC (and CC) registers can change
 
                                // underneath us.  Therefore they cannot
 
                                // be used as a base register for piped
 
                                // memory ops
 
                                &&(w_dcdB[3:1] != 3'h7)
 
                                // Writes to PC or CC will destroy any
 
                                // possibility of pipeing--since they
 
                                // could create a jump
 
                                &&(w_dcdR[3:1] != 3'h7)
 
                                //
 
                                // Loads landing in the current address
 
                                // pointer register are not allowed,
 
                                // as they could then be used to violate
 
                                // our rule(s)
 
                                &&((w_cis_op[0])||(w_dcdB != w_dcdA));
 
                end // else
 
                        // The pipeline is stalled
 
 
 
 
        initial r_pipe = 1'b0;
        initial r_pipe = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_ce)
                if (i_reset)
                        r_pipe <= (r_valid)&&((i_pf_valid)||(o_phase))
                        r_pipe <= 1'b0;
 
                else if (i_ce)
 
                        r_pipe <= ((pf_valid)||(o_phase))
 
                                // The last operation must be capable of
 
                                // being followed by a pipeable memory op
 
                                &&(r_insn_is_pipeable)
                                // Both must be memory operations
                                // Both must be memory operations
                                &&(w_mem)&&(o_M)
                                &&(w_mem)
                                // Both must be writes, or both stores
                                // Both must be writes, or both stores
                                &&(o_op[0] == w_cis_op[0])
                                &&(o_op[0] == w_cis_op[0])
                                // Both must be register ops
                                // Both must be register ops
                                &&(w_rB)
                                &&(w_rB)
                                // Both must use the same register for B
                                // Both must use the same register for B
                                &&(w_dcdB[3:0] == o_dcdB[3:0])
                                &&(w_dcdB[3:0] == o_dcdB[3:0])
 
                                // CC or PC registers are not valid addresses
 
                                //   Captured above
                                // But ... the result can never be B
                                // But ... the result can never be B
                                &&((o_op[0])
                                //   Captured above
                                        ||(w_dcdB[3:0] != o_dcdA[3:0]))
                                //
                                // Needs to be to the mode, supervisor or user
                                // Reads to CC or PC not allowed
                                &&(i_gie == o_gie)
                                // &&((o_op[0])||(w_dcdR[3:1] != 3'h7))
 
                                // Prior-reads to CC or PC not allowed
 
                                //   Captured above
                                // Same condition, or no condition before
                                // Same condition, or no condition before
                                &&((i_instruction[21:19]==o_cond[2:0])
                                &&((w_cond[2:0]==o_cond[2:0])
                                        ||(o_cond[2:0] == 3'h0))
                                        ||(o_cond[2:0] == 3'h0))
                                // Same immediate
                                // Same or incrementing immediate
                                &&((w_I[13:2]==r_I[13:2])
                                &&(w_I[13]==r_I[13])
                                        ||({1'b0, w_I[13:2]}==(r_I[13:2]+12'h1)));
                                &&(pipe_addr_diff <= 14'h4);
        assign o_pipe = r_pipe;
        assign o_pipe = r_pipe;
`else
        end else begin
        assign o_pipe = 1'b0;
        assign o_pipe = 1'b0;
`endif
                always @(*)
 
                        r_insn_is_pipeable = 1'b0;
 
 
 
                // verilator lint_off UNUSED
 
                wire    unused_pipable;
 
                assign  unused_pipable = r_insn_is_pipeable;
 
                // verilator lint_on  UNUSED
 
        end endgenerate
 
 
 
        initial r_valid = 1'b0;
 
        generate if (OPT_PIPELINED)
 
        begin : GEN_DCD_VALID
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                        if (i_reset)
                        r_valid <= 1'b0;
                        r_valid <= 1'b0;
                else if (i_ce)
                else if (i_ce)
                        r_valid <= ((i_pf_valid)||(o_phase)||(i_illegal))
                                r_valid <= ((pf_valid)||(o_phase))&&(!o_ljmp);
                                        &&(!o_ljmp)&&(!o_early_branch);
 
                else if (!i_stalled)
                else if (!i_stalled)
                        r_valid <= 1'b0;
                        r_valid <= 1'b0;
 
 
 
        end else begin : GEN_DCD_VALID
 
 
 
                always @(posedge i_clk)
 
                if (i_reset)
 
                        r_valid <= 1'b0;
 
                else if (!i_stalled)
 
                        r_valid <= ((pf_valid)||(o_phase))&&(!o_ljmp);
 
                else
 
                        r_valid <= 1'b0;
 
 
 
        end endgenerate
 
 
        assign  o_valid = r_valid;
        assign  o_valid = r_valid;
 
 
 
 
        assign  o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
        assign  o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
 
 
 
        // Make Verilator happy across all our various options
 
        // verilator lint_off  UNUSED
 
        wire    [5:0] possibly_unused;
 
        assign  possibly_unused = { w_lock, w_ljmp, w_ljmp_dly, w_cis_ljmp, i_pc[1:0] };
 
        // verilator lint_on  UNUSED
 
`ifdef  FORMAL
 
        reg     f_past_valid;
 
 
 
        initial f_past_valid = 1'b0;
 
        always @(posedge i_clk)
 
                f_past_valid <= 1'b1;
 
 
 
`define ASSERT  assert
 
`ifdef  IDECODE
 
`define ASSUME  assume
 
`else
 
`define ASSUME  assert
 
`endif
 
        always @(posedge i_clk)
 
        if ((i_ce)&&(i_pf_valid)&&(!o_phase))
 
                f_insn_word <= i_instruction;
 
        always @(posedge i_clk)
 
        if ((i_ce)&&(i_pf_valid)&&(!o_phase))
 
                f_insn_gie = i_gie;
 
        always @(*)
 
        if (o_phase)
 
                assert(r_nxt_half == f_insn_word[14:0]);
 
 
 
        ////////////////////////////
 
        //
 
        //
 
        // Assumptions about our inputs
 
        //
 
        //
 
        ///////////////////////////
 
        always @(*)
 
        if (OPT_PIPELINED)
 
                `ASSUME(i_ce == ((!o_valid)||(!i_stalled)));
 
        else
 
                `ASSUME(i_ce == !i_stalled);
 
 
 
        always @(posedge i_clk)
 
        if ((!f_past_valid)||($past(i_reset)))
 
        begin
 
                `ASSERT(!o_valid);
 
                // `ASSERT(!o_illegal);
 
                `ASSERT(!o_phase);
 
                `ASSERT(!o_ljmp);
 
                `ASSERT(!o_pipe);
 
 
 
                `ASSUME(!i_pf_valid);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!i_reset))
 
                `ASSUME(i_gie == $past(i_gie));
 
 
 
`ifdef  IDECODE
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&(!$past(i_ce))
 
                &&($past(f_past_valid))&&(!$past(i_reset,2))&&(!$past(i_ce,2)))
 
                assume(i_ce);
 
`endif
 
 
 
        reg     f_new_insn, f_last_insn;
 
 
 
        initial f_new_insn = 1'b0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
                f_new_insn <= 1'b0;
 
        else
 
                f_new_insn <= ((pf_valid)&&(!i_stalled));
 
 
 
        initial f_last_insn = 1'b0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
                f_last_insn <= 1'b0;
 
        else
 
                f_last_insn <= (o_valid)&&(i_stalled);
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(f_last_insn)&&(!i_reset))
 
        begin
 
                if (($past(pf_valid))&&(pf_valid))
 
                begin
 
                        `ASSUME(i_instruction == $past(i_instruction));
 
                        `ASSUME(i_gie == $past(i_gie));
 
                        `ASSUME(i_pc  == $past(i_pc));
 
                        `ASSUME(i_illegal == $past(i_illegal));
 
                end
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(o_early_branch_stb))
 
                `ASSUME(!pf_valid);
 
 
 
        always @(*)
 
                `ASSUME(i_pc[1:0] == 2'b00);
 
        always @(*)
 
        if ((o_valid)&&(!o_early_branch))
 
                `ASSERT((o_illegal)||(o_pc[1] == o_phase));
 
 
 
        wire    [4+21+32+1+4+1+4+11+AW+3+23-1:0] f_result;
 
        assign  f_result = { o_valid, o_phase, o_illegal,
 
                        i_gie, o_dcdR, o_dcdA, o_dcdB, o_I, o_zI, o_cond,
 
                        o_wF, o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
 
                        o_wR, o_rA, o_rB, o_early_branch, o_branch_pc, o_ljmp,
 
                        o_pipe, o_sim, o_sim_immv, o_pc };
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&(f_last_insn))
 
                `ASSERT(f_result == $past(f_result));
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&($past(pf_valid))
 
                        &&(!$past(o_ljmp)))
 
                `ASSERT((!OPT_PIPELINED)||(o_valid));
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(f_new_insn)
 
                        &&($past(pf_valid))&&($past(i_illegal))&&(!$past(o_phase)))
 
                `ASSERT(o_illegal);
 
 
 
`ifdef  IDECODE
 
        // Let's walk through some basic instructions
 
        // First 8-instructions, SUB - ASR
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(iword[26:25]==2'b00))
 
        begin
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
 
        end else if ((iword[`CISBIT])&&(iword[26:24]<3'b011))
 
        begin
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
 
                `ASSERT(w_rB == iword[`CISIMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
 
 
 
                if (iword[26:24] == 3'b000)
 
                        `ASSERT(w_cis_op == 5'h0);
 
                else if (iword[26:24] == 5'h01)
 
                        `ASSERT(w_cis_op == 5'h01);
 
                else // if (iword[26:24] == 3'b010)
 
                        `ASSERT(w_cis_op == 5'h02);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
 
 
                if (iword[`CISIMMSEL])
 
                        `ASSERT(w_I == { {(23-3){iword[18]}}, iword[18:16] });
 
                else
 
                        `ASSERT(w_I == { {(23-7){iword[22]}}, iword[22:16] });
 
        end else
 
                `ASSERT(!w_add);
 
 
 
        // BREV and LDILO
 
        always @(*)
 
        if ((!iword[`CISBIT])&&((w_cis_op == 5'h8)
 
                        ||(w_cis_op == 5'h09)))
 
        begin
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                if (w_cis_op == 5'h8)
 
                begin
 
                        `ASSERT(w_brev);
 
                        `ASSERT(!w_ldilo);
 
                        `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
 
                end else begin// if (w_cis_op == 5'h9)
 
                        `ASSERT(w_ldilo);
 
                        `ASSERT(!w_brev);
 
                        `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
 
                end
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT(!w_wF);
 
        end else begin
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
        end
 
 
 
        //
 
        // Multiply instructions
 
        always @(*)
 
        if ((!iword[`CISBIT])&&((w_cis_op == 5'ha)
 
                        ||(w_cis_op == 5'h0b)
 
                        ||(w_cis_op == 5'h0c)))
 
        begin
 
                `ASSERT(w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
 
        end else
 
                `ASSERT(!w_mpy);
 
 
 
        //
 
        // Move instruction
 
        always @(*)
 
        if ((!iword[`CISBIT])&&((w_cis_op == 5'hd)))
 
        begin
 
                `ASSERT(w_mov);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
 
                `ASSERT(w_rB);
 
                `ASSERT(w_dcdA[4] == ((i_gie)||(iword[`IMMSEL])));
 
                `ASSERT(w_dcdB[4] == ((i_gie)||(iword[13])));
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT(!w_wF);
 
        end else if ((iword[`CISBIT])&&(iword[26:24]==3'b111))
 
        begin
 
                `ASSERT(w_mov);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
 
                `ASSERT(w_rB);
 
                `ASSERT(w_dcdA[4] == (i_gie));
 
                `ASSERT(w_dcdB[4] == (i_gie));
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
 
 
 
                `ASSERT(w_cis_op == 5'h0d);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                `ASSERT(!w_wF);
 
        end else
 
                `ASSERT(!w_mov);
 
 
 
        //
 
        // Divide instruction
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(iword[26:23]==4'b0111))
 
        begin
 
                `ASSERT(w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                `ASSERT((w_rA)&&(w_wR));
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
 
        end else
 
                `ASSERT(!w_div);
 
 
 
        //
 
        // Comparison instructions
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(iword[26:23]==4'b1000))
 
        begin
 
                `ASSERT(w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                `ASSERT((w_rA)&&(!w_wR)&&(!w_ALU));
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT(w_wF);
 
        end else if ((iword[`CISBIT])&&(iword[26:24]==3'b011))
 
        begin
 
                `ASSERT(w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                `ASSERT((w_rA)&&(!w_wR)&&(!w_ALU));
 
                `ASSERT(w_rB == iword[`CISIMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
 
 
 
                `ASSERT(w_cis_op == 5'h10);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                if (iword[`CISIMMSEL])
 
                        `ASSERT(w_I == { {(23-3){iword[18]}}, iword[18:16] });
 
                else
 
                        `ASSERT(w_I == { {(23-7){iword[22]}}, iword[22:16] });
 
                `ASSERT(w_wF);
 
        end else
 
                `ASSERT(!w_cmptst);
 
 
 
        always @(posedge i_clk)
 
        if ((f_new_insn)&&($past(w_cmptst)))
 
                `ASSERT(o_ALU);
 
 
 
        //
 
        // Memory instructions
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(
 
                (iword[26:23]==4'b1001)         // Word
 
                ||(iword[26:23]==4'b1010)       // Half-word, or short
 
                ||(iword[26:23]==4'b1011)))     // Byte ops
 
        begin
 
                `ASSERT(w_mem);
 
                `ASSERT(w_sto == iword[22]);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                if (w_sto)
 
                        `ASSERT((w_rA)&&(!w_wR));
 
                else
 
                        `ASSERT((!w_rA)&&(w_wR));
 
                `ASSERT(!w_ALU);
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT(!w_wF);
 
        end else if ((iword[`CISBIT])&&(iword[26:25]==2'b10))
 
        begin
 
                `ASSERT(w_mem);
 
                `ASSERT(w_sto == iword[24]);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(!w_mpy);
 
                if (w_sto)
 
                        `ASSERT((w_rA)&&(!w_wR));
 
                else
 
                        `ASSERT((!w_rA)&&(w_wR));
 
                `ASSERT(!w_ALU);
 
                `ASSERT(w_rB);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                if (iword[`CISIMMSEL])
 
                        `ASSERT(w_dcdB[3:0] == iword[22:19]);
 
                else
 
                        `ASSERT(w_dcdB[3:0] == `CPU_SP_REG);
 
 
 
                if (w_sto)
 
                        `ASSERT(w_cis_op == 5'h13);
 
                else
 
                        `ASSERT(w_cis_op == 5'h12);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                `ASSERT(!w_wF);
 
        end else begin
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_mem);
 
        end
 
 
 
        always @(*)
 
        if (w_sto)
 
                `ASSERT(w_mem);
 
 
 
        //
 
        // LDI -- Load immediate
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(w_op[4:1] == 4'hc))
 
        begin
 
                `ASSERT(w_ldi);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT((!w_rA)&&(w_wR)&&(!w_ALU));
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(w_rB == 1'b0);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                `ASSERT(!w_wF);
 
 
 
                `ASSERT(w_Iz == (iword[22:0] == 0));
 
                `ASSERT(w_I[22:0] == iword[22:0]);
 
        end else if ((iword[`CISBIT])&&(iword[26:24] == 3'b110))
 
        begin
 
                `ASSERT(w_ldi);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT((!w_rA)&&(w_wR)&&(!w_ALU));
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_fpu);
 
                `ASSERT(w_rB == 1'b0);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
 
 
                `ASSERT(w_cis_op[4:1] == 4'hc);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                `ASSERT(!w_wF);
 
 
 
                `ASSERT(w_Iz == (iword[23:16] == 0));
 
                `ASSERT(w_I[22:0] == { {(23-8){iword[23]}}, iword[23:16] });
 
        end else
 
                `ASSERT(!w_ldi);
 
`endif  // IDECODE
 
 
 
        always @(posedge i_clk)
 
        if ((f_new_insn)&&($past(w_ldi)))
 
                `ASSERT(o_ALU);
 
 
 
`ifdef  IDECODE
 
        always @(*)
 
        if ((w_break)||(w_lock)||(w_sim)||(w_noop))
 
                `ASSERT(w_special);
 
 
 
 
 
        //
 
        // FPU -- Floating point instructions
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(OPT_FPU)&&(
 
                        (w_cis_op[4:1] == 4'hd)
 
                        ||(w_cis_op[4:1] == 4'he)
 
                        ||(w_cis_op[4:1] == 4'hf))
 
                        &&(iword[30:28] != 3'h7))
 
        begin
 
                `ASSERT(w_fpu);
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
                `ASSERT((w_wR)&&(!w_ALU));
 
                if ((w_cis_op == 5'he)||(w_cis_op == 5'hf))
 
                        `ASSERT(!w_rA);
 
                else
 
                        `ASSERT(w_rA);
 
                `ASSERT(!w_special);
 
                `ASSERT(w_rB == iword[`IMMSEL]);
 
                `ASSERT(w_dcdA[4] == i_gie);
 
                `ASSERT(w_dcdB[4] == i_gie);
 
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
 
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
 
                `ASSERT(w_cond[2:0] == iword[21:19]);
 
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
 
        end else
 
                `ASSERT((!w_fpu)||(!OPT_FPU));
 
 
 
        //
 
        // Special instructions
 
        always @(*)
 
        if ((!iword[`CISBIT])&&(
 
                        (w_cis_op == 5'h1c)
 
                        ||(w_cis_op == 5'h1d)
 
                        ||(w_cis_op == 5'h1e)
 
                        ||(w_cis_op == 5'h1f))
 
                        &&((iword[30:28] == 3'h7)||(!OPT_FPU)))
 
        begin
 
                `ASSERT(w_special);
 
                if (w_cis_op == 5'h1c)
 
                begin
 
                        `ASSERT(w_break);
 
                        `ASSERT(!w_lock);
 
                        `ASSERT(!w_sim);
 
                        `ASSERT(!w_noop);
 
                end else if (w_cis_op == 5'h1d)
 
                begin
 
                        `ASSERT(!w_break);
 
                        `ASSERT( w_lock);
 
                        `ASSERT(!w_sim);
 
                        `ASSERT(!w_noop);
 
                end else if (w_cis_op == 5'h1e)
 
                begin
 
                        `ASSERT(!w_break);
 
                        `ASSERT(!w_lock);
 
                        `ASSERT( w_sim);
 
                        `ASSERT(!w_noop);
 
                end else begin
 
                        `ASSERT(!w_break);
 
                        `ASSERT(!w_lock);
 
                        `ASSERT(!w_sim);
 
                        `ASSERT( w_noop);
 
                end
 
                `ASSERT((!w_fpu)||(!OPT_FPU));
 
                `ASSERT(!w_ldi);
 
                `ASSERT(!w_mpy);
 
                `ASSERT(!w_div);
 
                `ASSERT(!w_cmptst);
 
                `ASSERT(!w_mem);
 
                `ASSERT(!w_sto);
 
                `ASSERT(!w_mov);
 
                `ASSERT(!w_brev);
 
                `ASSERT(!w_ldilo);
 
 
 
                `ASSERT((!w_rA)&&(!w_rB)&&(!w_wR)&&(!w_ALU));
 
 
 
                `ASSERT(w_cis_op == w_op);
 
 
 
                `ASSERT(w_cond == 4'h8);
 
                `ASSERT(!w_wF);
 
        end else begin
 
                `ASSERT(!w_special);
 
                `ASSERT(!w_break);
 
                `ASSERT(!w_lock);
 
                `ASSERT(!w_sim);
 
                `ASSERT(!w_noop);
 
        end
 
`endif
 
 
 
        generate if (OPT_EARLY_BRANCHING)
 
        begin
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&($past(i_ce))&&(!$past(i_reset))&&(!i_reset))
 
                begin
 
                        if ($past(pf_valid))
 
                        begin
 
                                if ($past(o_ljmp))
 
                                begin
 
                                        // 2nd half of LW (PC),PC
 
                                        `ASSERT(o_early_branch);
 
                                        `ASSERT(o_early_branch_stb);
 
                                end else if ((!$past(iword[`CISBIT]))&&($past(w_add))
 
                                        &&(!$past(w_rB))
 
                                        &&($past(w_cond[3]))
 
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
 
                                begin
 
                                        // ADD #x,PC
 
                                        `ASSERT(o_early_branch);
 
                                        `ASSERT(o_early_branch_stb);
 
                                end else if ((!$past(iword[`CISBIT]))
 
                                        &&($past(w_cis_op == 5'h12))
 
                                        &&($past(w_rB))
 
                                        &&($past(w_cond[3]))
 
                                        &&(o_zI)
 
                                        &&(o_dcdB[4:0]=={ i_gie, 4'hf })
 
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
 
                                begin
 
                                        // LW (PC),PC
 
                                        `ASSERT(!o_early_branch);
 
                                        `ASSERT(!o_early_branch_stb);
 
                                end else if ((OPT_CIS)&&($past(o_phase))
 
                                        &&($past(w_cis_op == 5'h12))
 
                                        &&($past(w_rB))
 
                                        &&($past(w_cond[3]))
 
                                        &&($past(w_Iz))
 
                                        &&($past(w_dcdB_pc))
 
                                        &&($past(w_dcdR_pc))
 
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
 
                                begin
 
                                        // (CIS) LW (PC),PC
 
                                        `ASSERT(!o_early_branch);
 
                                        `ASSERT(!o_early_branch_stb);
 
                                end else begin
 
                                        `ASSERT(!o_early_branch);
 
                                end
 
                        end else if ((OPT_CIS)&&($past(o_phase)))
 
                        begin
 
                                if (($past(w_cis_op == 5'h12))
 
                                        &&($past(w_rB))
 
                                        &&($past(w_cond[3]))
 
                                        &&($past(w_Iz))
 
                                        &&($past(w_dcdB_pc))
 
                                        &&($past(w_dcdR_pc)))
 
                                begin
 
                                // (CIS) LW (PC),PC
 
                                        `ASSERT(!o_early_branch);
 
                                        `ASSERT(!o_early_branch_stb);
 
                                end else begin
 
                                        `ASSERT(!o_early_branch);
 
                                        `ASSERT(!o_early_branch_stb);
 
                                end
 
                        end
 
                end else if (!i_reset)
 
                        `ASSERT(!o_early_branch_stb);
 
 
 
//              // CIS instruction 16'hfcf8 decodes into:
 
//              // 1.1111.100.1.1111.0000
 
//              // = LW (PC),PC
 
//              always @(*)
 
//                      assume(i_instruction[31:16] != 16'hfcf8);
 
 
 
        end else begin
 
                always @(*)
 
                        `ASSERT(!o_early_branch_stb);
 
                always @(*)
 
                        `ASSERT(!o_early_branch);
 
        end endgenerate
 
 
 
        always @(*)
 
                if (o_early_branch_stb)
 
                        `ASSERT(o_early_branch);
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(o_early_branch_stb))&&(!$past(pf_valid)))
 
                        `ASSERT(!o_early_branch_stb);
 
 
 
        always @(*)
 
        if (!OPT_LOCK)
 
                `ASSERT(!o_lock);
 
 
 
        generate if (OPT_CIS)
 
        begin : F_OPT_CIS
 
                always @(*)
 
                if ((OPT_PIPELINED)&&(!o_valid))
 
                        `ASSERT(!o_phase);
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&(!$past(i_reset)))
 
                begin
 
                        if ((o_phase)&&($past(i_ce)))
 
                                `ASSERT((iword[30:16] == $past(i_instruction[14:0]))
 
                                        &&(iword[`CISBIT]));
 
                        else if (!o_phase)
 
                                `ASSERT(iword == i_instruction);
 
 
 
                        if ((!$past(o_phase))&&($past(i_ce))
 
                                        &&($past(pf_valid))
 
                                        &&(!$past(i_illegal))
 
                                        &&(!$past(w_ljmp_dly))
 
                                        &&($past(i_instruction[`CISBIT]))
 
                                        &&((!$past(w_dcdR_pc))
 
                                                ||(!$past(w_wR))))
 
                                `ASSERT(o_phase);
 
                        else if (($past(o_phase))&&($past(i_ce)))
 
                                `ASSERT(!o_phase);
 
                        if (($past(i_ce))&&(!$past(o_phase))
 
                                &&($past(i_illegal))&&($past(i_pf_valid)))
 
                                `ASSERT((o_illegal)&&(!o_phase));
 
 
 
                        `ASSERT((!o_phase)||(!o_ljmp));
 
                end
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&(!$past(i_stalled))&&($past(pf_valid))
 
                                &&($past(i_ce)))
 
                begin
 
                        `ASSERT(o_pc[0] == 1'b0);
 
                        if (!$past(iword[`CISBIT]))
 
                        begin
 
                                `ASSERT(o_pc[1:0]==2'b00);
 
                                `ASSERT(o_pc[AW+1:2] == $past(i_pc[AW+1:2])+1'b1);
 
                        end else if ($past(iword[`CISBIT])&&($past(o_phase)))
 
                                `ASSERT(o_pc[(AW+1):1] == $past(o_pc[(AW+1):1]) + 1'b1);
 
                        else if ($past(iword[`CISBIT]))
 
                        begin
 
                                `ASSERT(o_pc[(AW+1):1] == { $past(i_pc[(AW+1):2]), 1'b1});
 
                                if (o_valid)
 
                                begin
 
                                        `ASSERT(o_pc[1]);
 
                                        `ASSERT((o_illegal)||(o_phase));
 
                                end
 
                        end
 
                end
 
 
 
 
 
                always @(*)
 
                if (iword[`CISBIT])
 
                begin
 
                        `ASSERT((!w_ldi)||(w_I == { {(23-8){iword[23]}}, iword[23:16] }));
 
                        `ASSERT((w_ldi)||(iword[`CISIMMSEL])
 
                                ||(w_I == { {(23-7){iword[22]}}, iword[22:16] }));
 
                        `ASSERT((w_ldi)||(!iword[`CISIMMSEL])
 
                                ||(w_I == { {(23-3){iword[18]}}, iword[18:16] }));
 
                end else begin
 
                        `ASSERT((!w_ldi)||(w_I == iword[22:0]));
 
                        `ASSERT((!w_mov)||(w_I == { {(23-13){iword[12]}}, iword[12:0] }));
 
                        `ASSERT((w_ldi)||(w_mov)||(iword[`IMMSEL])
 
                                        ||(w_I == { {(23-18){iword[17]}}, iword[17:0] }));
 
                        `ASSERT((w_ldi)||(w_mov)||(!iword[`IMMSEL])
 
                                        ||(w_I == { {(23-14){iword[13]}}, iword[13:0] }));
 
                end
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&(o_phase)&&($past(i_ce)))
 
                        `ASSERT(($past(i_instruction[`CISBIT]))
 
                                &&(r_nxt_half[14:0]==$past(i_instruction[14:0])));
 
        end else begin
 
 
 
                always @(*)
 
                begin
 
                        `ASSERT((o_phase)||(iword[30:0] == i_instruction[30:0]));
 
                        `ASSERT(o_phase == 1'b0);
 
                        `ASSERT(o_pc[0] == 1'b0);
 
                end
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&($past(i_ce))&&($past(i_pf_valid)))
 
                        `ASSERT(o_pc[AW+1:2] == $past(i_pc[AW+1:2]) + 1'b1);
 
                else if (f_past_valid)
 
                        `ASSERT(o_pc == $past(o_pc));
 
 
 
                always @(*)
 
                        `ASSERT(o_pc[1:0] == 2'b00);
 
 
 
                always @(*)
 
                        `ASSERT((!w_ldi)||(w_I == iword[22:0]));
 
                always @(*)
 
                        `ASSERT((!w_mov)||(w_I == { {(23-13){iword[12]}}, iword[12:0] }));
 
                always @(*)
 
                        `ASSERT((w_ldi)||(w_mov)||(iword[`IMMSEL])
 
                                        ||(w_I == { {(23-18){iword[17]}}, iword[17:0] }));
 
                always @(*)
 
                        `ASSERT((w_ldi)||(w_mov)||(!iword[`IMMSEL])
 
                                        ||(w_I == { {(23-14){iword[13]}}, iword[13:0] }));
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&($past(i_ce))&&(!$past(i_reset)))
 
                        `ASSERT((!$past(i_instruction[`CISBIT]))
 
                                ||(!$past(pf_valid))||(o_illegal));
 
        end endgenerate
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))&&($past(w_fpu)))
 
        begin
 
                if (OPT_FPU)
 
                        `ASSERT(o_FP);
 
                else if (!$past(w_special))
 
                        `ASSERT(o_illegal);
 
        end
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))&&($past(w_lock)))
 
        begin
 
                if (OPT_LOCK)
 
                        `ASSERT(o_lock);
 
                else
 
                        `ASSERT(o_illegal);
 
        end
 
 
 
        wire    [20:0]   f_next_pipe_I, f_this_pipe_I;
 
        assign  f_this_pipe_I = r_I[22:2];
 
        assign  f_next_pipe_I = r_I[22:2]+1'b1;
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset)))
 
        begin
 
                if (OPT_OPIPE)
 
                begin
 
                        if (($past(i_ce))
 
                                &&(($past(pf_valid))||($past(o_phase))))
 
                        begin
 
                                if ((!$past(o_M))||(!o_M))
 
                                        `ASSERT(!o_pipe);
 
                                else if ($past(o_op[0])!=o_op[0])
 
                                        `ASSERT(!o_pipe);
 
                                else if ($past(o_rB)!=o_rB)
 
                                        `ASSERT(!o_pipe);
 
                                else if ((o_rB)&&($past(o_dcdB) != o_dcdB))
 
                                        `ASSERT(!o_pipe);
 
                                else if (($past(o_wR))
 
                                                &&($past(o_dcdR[3:1]) == 3'h7))
 
                                        `ASSERT(!o_pipe);
 
                                // else if ((o_wR)&&(o_dcdR[3:1] == 3'h7))
 
                                //      `ASSERT(!o_pipe);
 
                                else if (o_wR != $past(o_wR))
 
                                        `ASSERT(!o_pipe);
 
                                else if ((o_wR)&&($past(o_dcdR) == o_dcdB))
 
                                        `ASSERT(!o_pipe);
 
                                else if ((o_wR)&&(o_dcdB[3:1] == 3'h7))
 
                                        `ASSERT(!o_pipe);
 
                                else if (($past(o_cond) != 4'h8)
 
                                        &&($past(o_cond) != o_cond))
 
                                        `ASSERT(!o_pipe);
 
                                else if ($past(r_I[22])!=r_I[22])
 
                                        `ASSERT(!o_pipe);
 
                                else if (r_I[22:0] - $past(r_I[22:0])>23'h4)
 
                                        `ASSERT(!o_pipe);
 
                                else if (!$past(o_valid))
 
                                        `ASSERT(!o_pipe);
 
                                // else
 
                                        // assert(o_pipe);
 
                        end else if ($past(i_stalled))
 
                                `ASSERT(o_pipe == $past(o_pipe));
 
                end
 
        end
 
 
 
        always @(*)
 
                `ASSERT((OPT_OPIPE)||(!o_pipe));
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))
 
                        &&($past(i_pf_valid))&&($past(w_mpy)))
 
                `ASSERT((OPT_MPY)||(o_illegal));
 
 
 
        always @(*)
 
        if (o_valid)
 
                `ASSERT((!o_phase)||(!o_early_branch));
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(o_valid))&&($past(o_ljmp))&&($past(!i_stalled)))
 
                `ASSERT(!o_valid);
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(o_early_branch_stb)))
 
        begin
 
                `ASSERT(!o_phase);
 
                if (!$past(i_stalled))
 
                        `ASSERT(!o_valid);
 
                        `ASSERT(!o_ljmp);
 
        end
 
 
 
        // Unless another valid instruction comes along, once o_ljmp is asserted
 
        // it should stay asserted until either a reset or an early branch
 
        // strobe.
 
        always @(posedge i_clk)
 
        if ((OPT_EARLY_BRANCHING)&&(f_past_valid)
 
                        &&($past(o_ljmp))&&(!$past(pf_valid))
 
                        &&(!$past(i_reset))&&(!$past(o_early_branch_stb)))
 
                `ASSERT(o_ljmp);
 
 
 
        // o_ljmp should only ever be asserted following a valid prefetch
 
        // input.  Hence, if the prefetch input isn't valid, then o_ljmp
 
        // should be left low
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(o_ljmp))
 
                        &&( (!$past(pf_valid)) || (!$past(i_ce)) )
 
                        &&( !$past(o_phase) )
 
                        &&(!$past(i_reset))&&(!$past(o_early_branch_stb)))
 
                `ASSERT(!o_ljmp);
 
 
 
        always @(posedge i_clk)
 
        if ((OPT_EARLY_BRANCHING)&&(f_past_valid)&&($past(o_ljmp))&&(!o_ljmp)
 
                        &&(!$past(i_reset)))
 
                `ASSERT((o_early_branch_stb)&&(!o_valid));
 
 
 
        always @(posedge i_clk)
 
                `ASSERT((!o_early_branch_stb)||(!o_ljmp));
 
 
 
        always @(posedge i_clk)
 
                `ASSERT((!o_valid)||(!o_ljmp)||(o_phase == o_pc[1]));
 
 
 
        always @(posedge i_clk)
 
        if (!OPT_CIS)
 
                `ASSERT(!o_phase);
 
        else if (!f_insn_word[31])
 
                `ASSERT(!o_phase);
 
        else if (o_phase)
 
                `ASSERT(o_pc[1]);
 
 
 
        always @(*)
 
        if ((o_early_branch)&&(!o_early_branch_stb))
 
                `ASSERT(!o_pipe);
 
 
 
        always @(*)
 
        if (o_ljmp)
 
                `ASSERT(!o_pipe);
 
 
 
        always @(*)
 
        `ASSERT(o_dcdR == o_dcdA);
 
 
 
        always @(*)
 
        if ((o_valid)&&(o_phase))
 
        begin
 
                `ASSERT(!o_illegal);
 
                `ASSERT(o_pc[1]);
 
                `ASSERT(f_insn_word[31]);
 
        end
 
 
 
        always @(*)
 
                `ASSERT(o_branch_pc[1:0] == 2'b00);
 
        always @(*)
 
                `ASSERT(o_pc[0] == 1'b0);
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(i_pf_valid))&&(i_pf_valid))
 
                `ASSUME((i_reset)||($stable(i_gie)));
 
 
 
        wire    fc_illegal, fc_wF, fc_ALU, fc_M, fc_DV, fc_FP, fc_break,
 
                fc_lock, fc_wR, fc_rA, fc_rB, fc_prepipe, fc_sim;
 
        wire    [6:0]    fc_dcdR, fc_dcdA, fc_dcdB;
 
        wire    [31:0]   fc_I;
 
        wire    [3:0]    fc_cond;
 
        wire    [3:0]    fc_op;
 
        wire    [22:0]   fc_sim_immv;
 
        f_idecode #(
 
                .ADDRESS_WIDTH(AW),
 
                .OPT_MPY(OPT_MPY),
 
                .OPT_EARLY_BRANCHING(OPT_EARLY_BRANCHING),
 
                .OPT_DIVIDE(OPT_DIVIDE),
 
                .OPT_FPU(OPT_FPU),
 
                .OPT_CIS(OPT_CIS),
 
                .OPT_LOCK(OPT_LOCK),
 
                .OPT_OPIPE(OPT_OPIPE),
 
                .OPT_SIM(OPT_SIM)
 
                ) formal_decoder(
 
                        f_insn_word, o_phase, f_insn_gie,
 
                fc_illegal,
 
                fc_dcdR, fc_dcdA,fc_dcdB, fc_I, fc_cond, fc_wF, fc_op,
 
                fc_ALU, fc_M, fc_DV, fc_FP, fc_break, fc_lock,
 
                fc_wR, fc_rA, fc_rB, fc_prepipe, fc_sim, fc_sim_immv);
 
 
 
        always @(posedge i_clk)
 
        if ((o_valid)&&(fc_illegal))
 
                assert(o_illegal);
 
 
 
        always @(posedge i_clk)
 
        if ((o_valid)&&(!o_illegal))
 
        begin
 
                `ASSERT(fc_dcdR== o_dcdR);      //
 
                `ASSERT(fc_dcdA== o_dcdA);      //
 
                `ASSERT(fc_dcdB== o_dcdB);      //
 
                `ASSERT(fc_I   == o_I);
 
                `ASSERT(o_zI == (fc_I  == 0));
 
                `ASSERT(fc_cond== o_cond);
 
                `ASSERT(fc_wF  == o_wF);
 
                `ASSERT(fc_op  == o_op);
 
                `ASSERT(fc_ALU == o_ALU);
 
                `ASSERT(fc_M   == o_M);
 
                `ASSERT(fc_DV  == o_DV);
 
                `ASSERT(fc_FP  == o_FP);
 
                `ASSERT(fc_break== o_break);
 
                `ASSERT(fc_lock == o_lock);
 
                `ASSERT(fc_wR  == o_wR);
 
                `ASSERT(fc_rA  == o_rA);
 
                `ASSERT(fc_rB  == o_rB);
 
                `ASSERT(fc_sim  == o_sim);
 
                `ASSERT(fc_sim_immv  == o_sim_immv);
 
                `ASSERT(fc_prepipe == r_insn_is_pipeable);
 
        end else
 
                `ASSERT(!r_insn_is_pipeable);
 
 
 
        always @(*)
 
        if (o_phase)
 
                `ASSERT(r_nxt_half[14:0] == f_insn_word[14:0]);
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(i_ce))&&(o_valid)&&(!$past(i_reset)))
 
        begin
 
                `ASSERT(((fc_illegal)
 
                        ||$past((i_illegal)&&(!o_phase))
 
                        ||$past((o_illegal)&&( o_phase)))== o_illegal);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((!o_valid)||(o_illegal))
 
                `ASSERT(!r_insn_is_pipeable);
 
 
 
        generate if ((OPT_CIS)&&(OPT_EARLY_BRANCHING))
 
        begin
 
 
 
                always @(*)
 
                if ((o_valid)
 
                                // LW
 
                                &&(o_M)&&(o_op[2:0]==3'b010)
 
                                // Zero immediate
 
                                &&(o_zI)
 
                                // Unconditional
 
                                &&(o_cond[3])
 
                                // From PC to PC
 
                                &&(o_dcdR[5])&&(o_dcdB[5]))
 
                        `ASSERT((o_ljmp)
 
                                ||((f_insn_word[31])&&(o_phase || o_illegal)));
 
                else if (o_valid)
 
                        `ASSERT(!o_ljmp);
 
 
 
        end endgenerate
 
 
 
`endif // FORMAL
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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