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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [core/] [idecode.v] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 69 dgisselq
//
3
// Filename:    idecode.v
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     This RTL file specifies how instructions are to be decoded
8
//              into their underlying meanings.  This is specifically a version
9
//      designed to support a "Next Generation", or "Version 2" instruction
10
//      set as (currently) activated by the OPT_NEW_INSTRUCTION_SET option
11
//      in cpudefs.v.
12
//
13
//      I expect to (eventually) retire the old instruction set, at which point
14
//      this will become the default instruction set decoder.
15
//
16
//
17
// Creator:     Dan Gisselquist, Ph.D.
18
//              Gisselquist Technology, LLC
19
//
20 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
21 69 dgisselq
//
22 209 dgisselq
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
23 69 dgisselq
//
24
// This program is free software (firmware): you can redistribute it and/or
25
// modify it under the terms of  the GNU General Public License as published
26
// by the Free Software Foundation, either version 3 of the License, or (at
27
// your option) any later version.
28
//
29
// This program is distributed in the hope that it will be useful, but WITHOUT
30
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
31
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
32
// for more details.
33
//
34 201 dgisselq
// You should have received a copy of the GNU General Public License along
35
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
36
// target there if the PDF file isn't present.)  If not, see
37
// <http://www.gnu.org/licenses/> for a copy.
38
//
39 69 dgisselq
// License:     GPL, v3, as defined and found on www.gnu.org,
40
//              http://www.gnu.org/licenses/gpl.html
41
//
42
//
43 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
44 69 dgisselq
//
45
//
46 209 dgisselq
`default_nettype        none
47 69 dgisselq
//
48 201 dgisselq
`define CPU_SP_REG      4'hd
49 69 dgisselq
`define CPU_CC_REG      4'he
50
`define CPU_PC_REG      4'hf
51
//
52 209 dgisselq
`define CISBIT          31
53
`define CISIMMSEL       23
54
`define IMMSEL          18
55 69 dgisselq
//
56
//
57
//
58 209 dgisselq
module  idecode(i_clk, i_reset, i_ce, i_stalled,
59 69 dgisselq
                i_instruction, i_gie, i_pc, i_pf_valid,
60
                        i_illegal,
61 205 dgisselq
                o_valid,
62 69 dgisselq
                o_phase, o_illegal,
63 209 dgisselq
                o_pc,
64
                o_dcdR, o_dcdA, o_dcdB,
65
                o_preA, o_preB,
66
                o_I, o_zI,
67 69 dgisselq
                o_cond, o_wF,
68
                o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
69
                o_wR, o_rA, o_rB,
70 209 dgisselq
                o_early_branch, o_early_branch_stb, o_branch_pc, o_ljmp,
71 201 dgisselq
                o_pipe,
72
                o_sim, o_sim_immv
73 209 dgisselq
`ifdef  FORMAL
74
                , f_insn_word, f_insn_gie
75
`endif
76 69 dgisselq
                );
77 209 dgisselq
        parameter               ADDRESS_WIDTH=24;
78
        parameter       [0:0]     OPT_MPY = 1'b1;
79
        parameter       [0:0]     OPT_EARLY_BRANCHING = 1'b1;
80
        parameter       [0:0]     OPT_PIPELINED = 1'b1;
81
        parameter       [0:0]     OPT_DIVIDE = (OPT_PIPELINED);
82
        parameter       [0:0]     OPT_FPU    = 1'b0;
83
        parameter       [0:0]     OPT_CIS    = 1'b1;
84
        parameter       [0:0]     OPT_LOCK   = (OPT_PIPELINED);
85
        parameter       [0:0]     OPT_OPIPE  = (OPT_PIPELINED);
86
        parameter       [0:0]     OPT_SIM    = 1'b0;
87
        parameter       [0:0]     OPT_NO_USERMODE = 1'b0;
88
        localparam              AW = ADDRESS_WIDTH;
89
        //
90
        input   wire            i_clk, i_reset, i_ce, i_stalled;
91
        input   wire [31:0]      i_instruction;
92
        input   wire            i_gie;
93
        input   wire [(AW+1):0]  i_pc;
94
        input   wire            i_pf_valid, i_illegal;
95 205 dgisselq
        output  wire            o_valid, o_phase;
96 69 dgisselq
        output  reg             o_illegal;
97 209 dgisselq
        output  reg     [(AW+1):0]       o_pc;
98 69 dgisselq
        output  reg     [6:0]    o_dcdR, o_dcdA, o_dcdB;
99 209 dgisselq
        output  wire    [4:0]    o_preA, o_preB;
100 69 dgisselq
        output  wire    [31:0]   o_I;
101
        output  reg             o_zI;
102
        output  reg     [3:0]    o_cond;
103
        output  reg             o_wF;
104
        output  reg     [3:0]    o_op;
105 130 dgisselq
        output  reg             o_ALU, o_M, o_DV, o_FP, o_break;
106 209 dgisselq
        output  reg             o_lock;
107 69 dgisselq
        output  reg             o_wR, o_rA, o_rB;
108 209 dgisselq
        output  wire            o_early_branch, o_early_branch_stb;
109
        output  wire    [(AW+1):0]       o_branch_pc;
110 105 dgisselq
        output  wire            o_ljmp;
111 138 dgisselq
        output  wire            o_pipe;
112 201 dgisselq
        output  reg             o_sim           /* verilator public_flat */;
113
        output  reg     [22:0]   o_sim_immv      /* verilator public_flat */;
114 209 dgisselq
`ifdef  FORMAL
115
        output  reg     [31:0]   f_insn_word;
116
        output  reg             f_insn_gie;
117 130 dgisselq
`endif
118 69 dgisselq
 
119
 
120
        wire    [4:0]    w_op;
121 205 dgisselq
        wire            w_ldi, w_mov, w_cmptst, w_ldilo, w_ALU, w_brev,
122 209 dgisselq
                        w_noop, w_lock, w_sim, w_break, w_special, w_add,
123
                        w_mpy;
124 69 dgisselq
        wire    [4:0]    w_dcdR, w_dcdB, w_dcdA;
125
        wire            w_dcdR_pc, w_dcdR_cc;
126
        wire            w_dcdA_pc, w_dcdA_cc;
127
        wire            w_dcdB_pc, w_dcdB_cc;
128
        wire    [3:0]    w_cond;
129 205 dgisselq
        wire            w_wF, w_mem, w_sto, w_div, w_fpu;
130 69 dgisselq
        wire            w_wR, w_rA, w_rB, w_wR_n;
131 201 dgisselq
        wire            w_ljmp, w_ljmp_dly, w_cis_ljmp;
132 118 dgisselq
        wire    [31:0]   iword;
133 209 dgisselq
        wire            pf_valid;
134 69 dgisselq
 
135 209 dgisselq
        assign  pf_valid = (i_pf_valid)&&(!o_early_branch_stb);
136 69 dgisselq
 
137 209 dgisselq
 
138
        reg     [14:0]   r_nxt_half;
139
 
140
        generate if (OPT_CIS)
141
        begin : SET_IWORD
142
 
143
                assign  iword = (o_phase)
144 201 dgisselq
                                // set second half as a NOOP ... but really
145 69 dgisselq
                                // shouldn't matter
146 209 dgisselq
                        ? { 1'b1, r_nxt_half[14:0], i_instruction[15:0] }
147 69 dgisselq
                        : i_instruction;
148 209 dgisselq
        end else begin : CLR_IWORD
149
                assign  iword = { 1'b0, i_instruction[30:0] };
150 69 dgisselq
 
151 209 dgisselq
                // verilator lint_off UNUSED
152
                wire    [14:0]   unused_nxt_half;
153
                assign          unused_nxt_half = r_nxt_half;
154
                // verilator lint_on  UNUSED
155
        end endgenerate
156
 
157 118 dgisselq
        generate
158 209 dgisselq
        if (OPT_EARLY_BRANCHING)
159 201 dgisselq
        begin
160 209 dgisselq
                if (OPT_CIS)
161
                begin : CIS_EARLY_BRANCHING
162 201 dgisselq
 
163 209 dgisselq
                        assign  w_cis_ljmp = (o_phase)&&(iword[31:16] == 16'hfcf8);
164
 
165
                end else begin : NOCIS_EARLY_BRANCH
166
 
167
                        assign  w_cis_ljmp = 1'b0;
168
 
169
                end
170
 
171 118 dgisselq
                assign  w_ljmp = (iword == 32'h7c87c000);
172 209 dgisselq
 
173
        end else begin : NO_EARLY_BRANCHING
174
 
175 201 dgisselq
                assign  w_cis_ljmp = 1'b0;
176 118 dgisselq
                assign  w_ljmp = 1'b0;
177 209 dgisselq
        end endgenerate
178 118 dgisselq
 
179 201 dgisselq
        reg     [4:0]    w_cis_op;
180 209 dgisselq
 
181
        generate if (OPT_CIS)
182
        begin : GEN_CIS_OP
183
 
184
                always @(*)
185
                if (!iword[`CISBIT])
186
                        w_cis_op = iword[26:22];
187 201 dgisselq
                else case(iword[26:24])
188 209 dgisselq
                3'h0: w_cis_op = 5'h00; // ADD
189
                3'h1: w_cis_op = 5'h01; // AND
190
                3'h2: w_cis_op = 5'h02; // SUB
191
                3'h3: w_cis_op = 5'h10; // BREV
192
                3'h4: w_cis_op = 5'h12; // LW
193
                3'h5: w_cis_op = 5'h13; // SW
194
                3'h6: w_cis_op = 5'h18; // LDI
195
                3'h7: w_cis_op = 5'h0d; // MOV
196 201 dgisselq
                endcase
197 118 dgisselq
 
198 209 dgisselq
        end else begin : GEN_NOCIS_OP
199
 
200
                always @(*)
201
                        w_cis_op = w_op;
202
 
203
        end endgenerate
204
 
205
        // Decode instructions
206 69 dgisselq
        assign  w_op= iword[26:22];
207 201 dgisselq
        assign  w_mov    = (w_cis_op      == 5'h0d);
208
        assign  w_ldi    = (w_cis_op[4:1] == 4'hc);
209 209 dgisselq
        assign  w_brev   = (w_cis_op      == 5'h08);
210
        assign  w_mpy    = (w_cis_op[4:1] == 4'h5)||(w_cis_op[4:0]==5'h0c);
211 201 dgisselq
        assign  w_cmptst = (w_cis_op[4:1] == 4'h8);
212 209 dgisselq
        assign  w_ldilo  = (w_cis_op[4:0] == 5'h09);
213 201 dgisselq
        assign  w_ALU    = (!w_cis_op[4]) // anything with [4]==0, but ...
214
                                &&(w_cis_op[3:1] != 3'h7); // not the divide
215 209 dgisselq
        assign  w_add    = (w_cis_op[4:0] == 5'h02);
216
        assign  w_mem    = (w_cis_op[4:3] == 2'b10)&&(w_cis_op[2:1] !=2'b00);
217
        assign  w_sto    = (w_mem)&&( w_cis_op[0]);
218
        assign  w_div    = (!iword[`CISBIT])&&(w_op[4:1] == 4'h7);
219
        assign  w_fpu    = (!iword[`CISBIT])&&(w_op[4:3] == 2'b11)
220
                                &&(w_dcdR[3:1] != 3'h7)&&(w_op[2:1] != 2'b00);
221
        // If the result register is either CC or PC, and this would otherwise
222
        // be a floating point instruction with floating point opcode of 0,
223
        // then this is a NOOP.
224
        assign  w_special= (!iword[`CISBIT])&&((!OPT_FPU)||(w_dcdR[3:1]==3'h7))
225
                        &&(w_op[4:2] == 3'b111);
226
        assign  w_break = (w_special)&&(w_op[4:0]==5'h1c);
227
        assign  w_lock  = (w_special)&&(w_op[4:0]==5'h1d);
228
        assign  w_sim   = (w_special)&&(w_op[4:0]==5'h1e);
229
        assign  w_noop  = (w_special)&&(w_op[4:0]==5'h1f);
230 69 dgisselq
 
231 201 dgisselq
 
232
        // w_dcdR (4 LUTs)
233 138 dgisselq
        //
234 201 dgisselq
        // What register will we be placing results into (if at all)?
235
        //
236 138 dgisselq
        // Two parts to the result register: the register set, given for
237 201 dgisselq
        // moves in iword[18] but only for the supervisor, and the other
238 138 dgisselq
        // four bits encoded in the instruction.
239
        //
240 209 dgisselq
        assign  w_dcdR = { ((!iword[`CISBIT])&&(!OPT_NO_USERMODE)&&(w_mov)&&(!i_gie))?iword[`IMMSEL]:i_gie,
241 69 dgisselq
                                iword[30:27] };
242 138 dgisselq
 
243 201 dgisselq
        // dcdB - What register is used in the opB?
244
        //
245 209 dgisselq
        assign w_dcdB[4] = ((!iword[`CISBIT])&&(w_mov)&&(!OPT_NO_USERMODE)&&(!i_gie))?iword[13]:i_gie;
246
        assign w_dcdB[3:0]= (iword[`CISBIT])
247
                                ? (((!iword[`CISIMMSEL])&&(iword[26:25]==2'b10))
248 201 dgisselq
                                        ? `CPU_SP_REG : iword[22:19])
249
                                : iword[17:14];
250 69 dgisselq
 
251
        // 0 LUTs
252 201 dgisselq
        assign  w_dcdA = w_dcdR;        // on ZipCPU, A is always result reg
253 69 dgisselq
        // 2 LUTs, 1 delay each
254 105 dgisselq
        assign  w_dcdR_pc = (w_dcdR == {i_gie, `CPU_PC_REG});
255 69 dgisselq
        assign  w_dcdR_cc = (w_dcdR == {i_gie, `CPU_CC_REG});
256
        // 0 LUTs
257
        assign  w_dcdA_pc = w_dcdR_pc;
258
        assign  w_dcdA_cc = w_dcdR_cc;
259
        // 2 LUTs, 1 delays each
260 201 dgisselq
        assign  w_dcdB_pc = (w_rB)&&(w_dcdB[3:0] == `CPU_PC_REG);
261
        assign  w_dcdB_cc = (w_rB)&&(w_dcdB[3:0] == `CPU_CC_REG);
262 69 dgisselq
 
263
        //
264 209 dgisselq
        // Under what condition will we execute this instruction?  Only the
265
        // load immediate instruction and the CIS instructions are completely
266
        // unconditional.  Well ... not quite.  The BREAK, LOCK, and SIM/NOOP
267
        // instructions are also unconditional.
268
        //
269
        assign  w_cond = ((w_ldi)||(w_special)||(iword[`CISBIT])) ? 4'h8 :
270 201 dgisselq
                        { (iword[21:19]==3'h0), iword[21:19] };
271 69 dgisselq
 
272 201 dgisselq
        // rA - do we need to read register A?
273
        assign  w_rA = // Floating point reads reg A
274 209 dgisselq
                        ((w_fpu)&&(OPT_FPU))
275 201 dgisselq
                        // Divide's read A
276
                        ||(w_div)
277
                        // ALU ops read A,
278
                        //      except for MOV's and BREV's which don't
279
                        ||((w_ALU)&&(!w_brev)&&(!w_mov))
280
                        // STO's read A
281
                        ||(w_sto)
282
                        // Test/compares
283
                        ||(w_cmptst);
284
        // rB -- do we read a register for operand B?  Specifically, do we
285
        // add the registers value to the immediate to create opB?
286
        assign  w_rB     = (w_mov)
287 209 dgisselq
                                ||((!iword[`CISBIT])&&(iword[`IMMSEL])&&(!w_ldi)&&(!w_special))
288
                                ||(( iword[`CISBIT])&&(iword[`CISIMMSEL])&&(!w_ldi))
289 201 dgisselq
                                // If using compressed instruction sets,
290
                                // we *always* read on memory operands.
291 209 dgisselq
                                ||(( iword[`CISBIT])&&(w_mem));
292
 
293 201 dgisselq
        // wR -- will we be writing our result back?
294
        // wR_n = !wR
295 209 dgisselq
        // All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
296 201 dgisselq
        assign  w_wR_n   = (w_sto)
297 209 dgisselq
                                ||(w_special)
298 69 dgisselq
                                ||(w_cmptst);
299 209 dgisselq
        assign  w_wR     = !w_wR_n;
300 90 dgisselq
        //
301 201 dgisselq
        // wF -- do we write flags when we are done?
302
        //
303 69 dgisselq
        assign  w_wF     = (w_cmptst)
304 209 dgisselq
                        ||((w_cond[3])&&(((w_fpu)&&(OPT_FPU))||(w_div)
305 201 dgisselq
                                ||((w_ALU)&&(!w_mov)&&(!w_ldilo)&&(!w_brev)
306
                                        &&(w_dcdR[3:1] != 3'h7))));
307 69 dgisselq
 
308
        // Bottom 13 bits: no LUT's
309
        // w_dcd[12: 0] -- no LUTs
310
        // w_dcd[   13] -- 2 LUTs
311
        // w_dcd[17:14] -- (5+i0+i1) = 3 LUTs, 1 delay
312
        // w_dcd[22:18] : 5 LUTs, 1 delay (assuming high bit is o/w determined)
313
        reg     [22:0]   r_I;
314
        wire    [22:0]   w_I, w_fullI;
315
        wire            w_Iz;
316
 
317
        assign  w_fullI = (w_ldi) ? { iword[22:0] } // LDI
318 201 dgisselq
                        // MOVE immediates have one less bit
319
                        :((w_mov) ?{ {(23-13){iword[12]}}, iword[12:0] }
320
                        // Normal Op-B immediate ... 18 or 14 bits
321 209 dgisselq
                        :((!iword[`IMMSEL]) ? { {(23-18){iword[17]}}, iword[17:0] }
322 69 dgisselq
                        : { {(23-14){iword[13]}}, iword[13:0] }
323
                        ));
324
 
325 209 dgisselq
        generate if (OPT_CIS)
326
        begin : GEN_CIS_IMMEDIATE
327
                wire    [7:0]    w_halfbits;
328
                assign  w_halfbits = iword[`CISIMMSEL:16];
329 201 dgisselq
 
330 209 dgisselq
                wire    [7:0]    w_halfI;
331
                assign  w_halfI = (iword[26:24]==3'h6) ? w_halfbits[7:0] // 8'b for LDI
332
                                :(w_halfbits[7])?
333
                                        { {(6){w_halfbits[2]}}, w_halfbits[1:0]}
334
                                        :{ w_halfbits[6], w_halfbits[6:0] };
335
                assign  w_I  = (iword[`CISBIT])
336
                                ? {{(23-8){w_halfI[7]}}, w_halfI }
337
                                : w_fullI;
338
 
339
        end else begin : GEN_NOCIS_IMMEDIATE
340
 
341
                assign  w_I  = w_fullI;
342
 
343
        end endgenerate
344
 
345 69 dgisselq
        assign  w_Iz = (w_I == 0);
346
 
347
 
348
        //
349
        // The o_phase parameter is special.  It needs to let the software
350
        // following know that it cannot break/interrupt on an o_phase asserted
351
        // instruction, lest the break take place between the first and second
352 201 dgisselq
        // half of a CIS instruction.  To do this, o_phase must be asserted
353 69 dgisselq
        // when the first instruction half is valid, but not asserted on either
354
        // a 32-bit instruction or the second half of a 2x16-bit instruction.
355 209 dgisselq
        generate if (OPT_CIS)
356
        begin : GEN_CIS_PHASE
357
                reg     r_phase;
358
 
359
                // Phase is '1' on the first instruction of a two-part set
360
                // But, due to the delay in processing, it's '1' when our
361
                // output is valid for that first part, but that'll be the
362
                // same time we are processing the second part ... so it may
363
                // look to us like a '1' on the second half of processing.
364
 
365
                // When no instruction is in the pipe, phase is zero
366
                initial r_phase = 1'b0;
367
                always @(posedge i_clk)
368
                if ((i_reset)||(w_ljmp_dly))
369 69 dgisselq
                        r_phase <= 1'b0;
370 209 dgisselq
                else if ((i_ce)&&(pf_valid))
371
                begin
372
                        if (o_phase)
373
                                // CIS instructions only have two parts.  On
374
                                // the second part (o_phase is true), return
375
                                // back to the first
376
                                r_phase <= 0;
377
                        else
378
                                r_phase <= (i_instruction[`CISBIT])&&(!i_illegal);
379
                end else if (i_ce)
380 201 dgisselq
                        r_phase <= 1'b0;
381 69 dgisselq
 
382 209 dgisselq
                assign  o_phase = r_phase;
383
        end else begin
384
                assign  o_phase = 1'b0;
385
        end endgenerate
386 69 dgisselq
 
387
 
388 71 dgisselq
        initial o_illegal = 1'b0;
389 69 dgisselq
        always @(posedge i_clk)
390 209 dgisselq
        if (i_ce)
391
        begin
392
                if (OPT_PIPELINED)
393
                        o_illegal <= ((i_illegal)
394
                                        &&((!o_phase)||(!o_valid)))
395
                                ||((o_illegal)&&(o_phase)&&(o_valid));
396
                else
397
                        o_illegal <= (i_illegal)&&(!o_phase);
398
                if ((!OPT_CIS)&&(i_instruction[`CISBIT]))
399
                        o_illegal <= 1'b1;
400
                if ((!OPT_MPY)&&(w_mpy))
401
                        o_illegal <= 1'b1;
402 69 dgisselq
 
403 209 dgisselq
                if ((!OPT_DIVIDE)&&(w_div))
404
                        o_illegal <= 1'b1;
405
                else if ((OPT_DIVIDE)&&(w_div)&&(w_dcdR[3:1]==3'h7))
406
                        o_illegal <= 1'b1;
407 69 dgisselq
 
408
 
409 209 dgisselq
                if ((!OPT_FPU)&&(w_fpu))
410
                        o_illegal <= 1'b1;
411 69 dgisselq
 
412 209 dgisselq
                if ((!OPT_SIM)&&(w_sim))
413
                // Simulation instructions on real hardware should
414
                // always cause an illegal instruction error
415
                        o_illegal <= 1'b1;
416 71 dgisselq
 
417 209 dgisselq
                // There are two (missing) special instructions
418
                // These should cause an illegal instruction error
419
                if ((w_dcdR[3:1]==3'h7)&&(w_cis_op[4:1]==4'b1101))
420
                        o_illegal <= 1'b1;
421 71 dgisselq
 
422 209 dgisselq
                // If the lock function isn't implemented, this should
423
                // also cause an illegal instruction error
424
                if ((!OPT_LOCK)&&(w_lock))
425
                        o_illegal <= 1'b1;
426
        end
427
 
428
        initial o_pc = 0;
429 71 dgisselq
        always @(posedge i_clk)
430 209 dgisselq
        if ((i_ce)&&((o_phase)||(i_pf_valid)))
431
        begin
432
                o_pc[0] <= 1'b0;
433
 
434
                if (OPT_CIS)
435 71 dgisselq
                begin
436 209 dgisselq
                        if (iword[`CISBIT])
437 205 dgisselq
                        begin
438
                                if (o_phase)
439 209 dgisselq
                                        o_pc[AW+1:1] <= o_pc[AW+1:1] + 1'b1;
440
                                else
441
                                        o_pc <= { i_pc[AW+1:2], 1'b1, 1'b0 };
442 205 dgisselq
                        end else begin
443
                                // The normal, non-CIS case
444 209 dgisselq
                                o_pc <= { i_pc[AW+1:2] + 1'b1, 2'b00 };
445 205 dgisselq
                        end
446 209 dgisselq
                end else begin
447
                        // The normal, non-CIS case
448
                        o_pc <= { i_pc[AW+1:2] + 1'b1, 2'b00 };
449
                end
450
        end
451 71 dgisselq
 
452 209 dgisselq
        initial o_dcdR = 0;
453
        initial o_dcdA = 0;
454
        initial o_dcdB = 0;
455
        initial o_DV   = 0;
456
        initial o_FP   = 0;
457
        initial o_lock = 0;
458
        always @(posedge i_clk)
459
        if (i_ce)
460
        begin
461
                // Under what condition will we execute this
462
                // instruction?  Only the load immediate instruction
463
                // is completely unconditional.
464
                o_cond <= w_cond;
465
                // Don't change the flags on conditional instructions,
466
                // UNLESS: the conditional instruction was a CMP
467
                // or TST instruction.
468
                o_wF <= w_wF;
469 69 dgisselq
 
470 209 dgisselq
                // Record what operation/op-code (4-bits) we are doing
471
                //      Note that LDI magically becomes a MOV
472
                //      instruction here.  That way it's a pass through
473
                //      the ALU.  Likewise, the two compare instructions
474
                //      CMP and TST becomes SUB and AND here as well.
475
                // We keep only the bottom four bits, since we've
476
                // already done the rest of the decode necessary to
477
                // settle between the other instructions.  For example,
478
                // o_FP plus these four bits uniquely defines the FP
479
                // instruction, o_DV plus the bottom of these defines
480
                // the divide, etc.
481
                o_op <= w_cis_op[3:0];
482
                if ((w_ldi)||(w_noop)||(w_lock))
483
                        o_op <= 4'hd;
484 69 dgisselq
 
485 209 dgisselq
                // Default values
486
                o_dcdR <= { w_dcdR_cc, w_dcdR_pc, w_dcdR};
487
                o_dcdA <= { w_dcdA_cc, w_dcdA_pc, w_dcdA};
488
                o_dcdB <= { w_dcdB_cc, w_dcdB_pc, w_dcdB};
489
                o_wR  <= w_wR;
490
                o_rA  <= w_rA;
491
                o_rB  <= w_rB;
492
                r_I    <= w_I;
493
                o_zI   <= w_Iz;
494 69 dgisselq
 
495 209 dgisselq
                // Turn a NOOP into an ALU operation--subtract in
496
                // particular, although it doesn't really matter as long
497
                // as it doesn't take longer than one clock.  Note
498
                // also that this depends upon not setting any registers
499
                // or flags, which should already be true.
500
                o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst)||(w_noop)
501
                                ||((!OPT_LOCK)&&(w_lock));
502
                o_M    <=  w_mem;
503
                o_DV   <=  (OPT_DIVIDE)&&(w_div);
504
                o_FP   <=  (OPT_FPU)&&(w_fpu);
505 201 dgisselq
 
506 209 dgisselq
                o_break <= w_break;
507
                o_lock  <= (OPT_LOCK)&&(w_lock);
508 201 dgisselq
 
509 209 dgisselq
                if (OPT_CIS)
510
                        r_nxt_half <= { iword[14:0] };
511
                else
512
                        r_nxt_half <= 0;
513
 
514
                if (OPT_SIM)
515
                begin
516 201 dgisselq
                        // Support the SIM instruction(s)
517 209 dgisselq
                        o_sim <= (w_sim)||(w_noop);
518
                        o_sim_immv <= iword[22:0];
519
                end else begin
520 201 dgisselq
                        o_sim <= 1'b0;
521 209 dgisselq
                        o_sim_immv <= 0;
522 69 dgisselq
                end
523 209 dgisselq
        end
524 69 dgisselq
 
525 209 dgisselq
        assign  o_preA = w_dcdA;
526
        assign  o_preB = w_dcdB;
527 130 dgisselq
 
528 209 dgisselq
        generate if (OPT_EARLY_BRANCHING)
529
        begin : GEN_EARLY_BRANCH_LOGIC
530
                reg                     r_early_branch,
531
                                        r_early_branch_stb,
532
                                        r_ljmp;
533
                reg     [(AW+1):0]       r_branch_pc;
534 105 dgisselq
 
535
                initial r_ljmp = 1'b0;
536 69 dgisselq
                always @(posedge i_clk)
537 209 dgisselq
                if (i_reset)
538
                        r_ljmp <= 1'b0;
539
                else if (i_ce)
540
                begin
541
                        if ((r_ljmp)&&(pf_valid))
542 105 dgisselq
                                r_ljmp <= 1'b0;
543 209 dgisselq
                        else if (o_early_branch_stb)
544
                                r_ljmp <= 1'b0;
545
                        else if (pf_valid)
546
                        begin
547
                                if ((OPT_CIS)&&(iword[`CISBIT]))
548
                                        r_ljmp <= w_cis_ljmp;
549
                                else
550
                                        r_ljmp <= (w_ljmp);
551
                        end else if ((OPT_CIS)&&(o_phase)&&(iword[`CISBIT]))
552 201 dgisselq
                                r_ljmp <= w_cis_ljmp;
553 209 dgisselq
                end
554 105 dgisselq
                assign  o_ljmp = r_ljmp;
555
 
556 209 dgisselq
                initial r_early_branch     = 1'b0;
557
                initial r_early_branch_stb = 1'b0;
558 105 dgisselq
                always @(posedge i_clk)
559 209 dgisselq
                if (i_reset)
560 90 dgisselq
                begin
561 209 dgisselq
                        r_early_branch     <= 1'b0;
562
                        r_early_branch_stb <= 1'b0;
563
                end else if ((i_ce)&&(pf_valid))
564
                begin
565 105 dgisselq
                        if (r_ljmp)
566 209 dgisselq
                        begin
567
                                // LW (PC),PC
568
                                r_early_branch     <= 1'b1;
569
                                r_early_branch_stb <= 1'b1;
570
                        end else if ((!iword[`CISBIT])&&(iword[30:27]==`CPU_PC_REG)
571 201 dgisselq
                                        &&(w_cond[3]))
572 69 dgisselq
                        begin
573 209 dgisselq
                                if ((w_add)&&(!iword[`IMMSEL]))
574
                                begin
575 105 dgisselq
                                        // Add x,PC
576 69 dgisselq
                                        r_early_branch     <= 1'b1;
577 209 dgisselq
                                        r_early_branch_stb <= 1'b1;
578
                                end else begin
579 69 dgisselq
                                        r_early_branch     <= 1'b0;
580 209 dgisselq
                                        r_early_branch_stb <= 1'b0;
581
                                end
582
                        // LDI #x,PC is no longer supported
583
                        end else begin
584 90 dgisselq
                                r_early_branch <= 1'b0;
585 209 dgisselq
                                r_early_branch_stb <= 1'b0;
586
                        end
587 105 dgisselq
                end else if (i_ce)
588 209 dgisselq
                begin
589
                        r_early_branch     <= 1'b0;
590
                        r_early_branch_stb <= 1'b0;
591
                end else
592
                        r_early_branch_stb <= 1'b0;
593 105 dgisselq
 
594 209 dgisselq
                initial r_branch_pc = 0;
595 69 dgisselq
                always @(posedge i_clk)
596 209 dgisselq
                if (i_ce)
597
                begin
598
                        if (r_ljmp)
599
                                r_branch_pc <= { iword[(AW+1):2],
600
                                                2'b00 };
601
                        else begin
602
                        // Add x,PC
603
                        r_branch_pc[AW+1:2] <= i_pc[AW+1:2]
604
                                + {{(AW-15){iword[17]}},iword[16:2]}
605
                                + {{(AW-1){1'b0}},1'b1};
606
                        r_branch_pc[1:0] <= 2'b00;
607 69 dgisselq
                        end
608 209 dgisselq
                end
609 69 dgisselq
 
610 178 dgisselq
                assign  w_ljmp_dly         = r_ljmp;
611 69 dgisselq
                assign  o_early_branch     = r_early_branch;
612 209 dgisselq
                assign  o_early_branch_stb = r_early_branch_stb;
613 69 dgisselq
                assign  o_branch_pc        = r_branch_pc;
614
        end else begin
615 178 dgisselq
                assign  w_ljmp_dly         = 1'b0;
616 209 dgisselq
                assign  o_early_branch     = 1'b0;
617
                assign  o_early_branch_stb = 1'b0;
618
                assign  o_branch_pc = {(AW+2){1'b0}};
619 105 dgisselq
                assign  o_ljmp = 1'b0;
620 209 dgisselq
 
621
                // verilator lint_off UNUSED
622
                wire    early_branch_unused;
623
                assign  early_branch_unused = w_add;
624
                // verilator lint_on  UNUSED
625 69 dgisselq
        end endgenerate
626
 
627 71 dgisselq
 
628
        // To be a pipeable operation there must be ...
629
        //      1. Two valid adjacent instructions
630
        //      2. Both must be memory operations, of the same time (both lods
631
        //              or both stos)
632
        //      3. Both must use the same register base address
633
        //      4. Both must be to the same address, or the address incremented
634
        //              by one
635
        // Note that we're not using iword here ... there's a lot of logic
636
        // taking place, and it's only valid if the new word is not compressed.
637
        //
638 209 dgisselq
        reg     r_valid, r_insn_is_pipeable;
639
        generate if (OPT_OPIPE)
640
        begin : GEN_OPIPE
641
                reg     r_pipe;
642
 
643
                wire    [13:0]   pipe_addr_diff;
644
                assign          pipe_addr_diff = w_I[13:0] - r_I[13:0];
645
 
646
                // Pipeline logic is too extreme for a single clock.
647
                // Let's break it into two clocks, using r_insn_is_pipeable
648
                // If this function is true, then the instruction associated
649
                // with the current output *may* have a pipeable instruction
650
                // following it.
651
                //
652
                initial r_insn_is_pipeable = 1'b0;
653
                always @(posedge i_clk)
654
                if (i_reset)
655
                        r_insn_is_pipeable <= 1'b0;
656
                else if ((i_ce)&&((!pf_valid)||(i_illegal))&&(!o_phase))
657
                        // Pipeline bubble, can't pipe through it
658
                        r_insn_is_pipeable <= 1'b0;
659
                else if (o_ljmp)
660
                        r_insn_is_pipeable <= 1'b0;
661
                else if ((i_ce)&&((!OPT_CIS)&&(i_instruction[`CISBIT])))
662
                        r_insn_is_pipeable <= 1'b0;
663
                else if (i_ce)
664
                begin   // This is a valid instruction
665
                        r_insn_is_pipeable <= (w_mem)&&(w_rB)
666
                                // PC (and CC) registers can change
667
                                // underneath us.  Therefore they cannot
668
                                // be used as a base register for piped
669
                                // memory ops
670
                                &&(w_dcdB[3:1] != 3'h7)
671
                                // Writes to PC or CC will destroy any
672
                                // possibility of pipeing--since they
673
                                // could create a jump
674
                                &&(w_dcdR[3:1] != 3'h7)
675
                                //
676
                                // Loads landing in the current address
677
                                // pointer register are not allowed,
678
                                // as they could then be used to violate
679
                                // our rule(s)
680
                                &&((w_cis_op[0])||(w_dcdB != w_dcdA));
681
                end // else
682
                        // The pipeline is stalled
683
 
684
 
685
                initial r_pipe = 1'b0;
686
                always @(posedge i_clk)
687
                if (i_reset)
688
                        r_pipe <= 1'b0;
689
                else if (i_ce)
690
                        r_pipe <= ((pf_valid)||(o_phase))
691
                                // The last operation must be capable of
692
                                // being followed by a pipeable memory op
693
                                &&(r_insn_is_pipeable)
694 201 dgisselq
                                // Both must be memory operations
695 209 dgisselq
                                &&(w_mem)
696 201 dgisselq
                                // Both must be writes, or both stores
697
                                &&(o_op[0] == w_cis_op[0])
698
                                // Both must be register ops
699
                                &&(w_rB)
700
                                // Both must use the same register for B
701
                                &&(w_dcdB[3:0] == o_dcdB[3:0])
702 209 dgisselq
                                // CC or PC registers are not valid addresses
703
                                //   Captured above
704 201 dgisselq
                                // But ... the result can never be B
705 209 dgisselq
                                //   Captured above
706
                                //
707
                                // Reads to CC or PC not allowed
708
                                // &&((o_op[0])||(w_dcdR[3:1] != 3'h7))
709
                                // Prior-reads to CC or PC not allowed
710
                                //   Captured above
711 201 dgisselq
                                // Same condition, or no condition before
712 209 dgisselq
                                &&((w_cond[2:0]==o_cond[2:0])
713 71 dgisselq
                                        ||(o_cond[2:0] == 3'h0))
714 209 dgisselq
                                // Same or incrementing immediate
715
                                &&(w_I[13]==r_I[13])
716
                                &&(pipe_addr_diff <= 14'h4);
717
                assign o_pipe = r_pipe;
718
        end else begin
719
                assign o_pipe = 1'b0;
720
                always @(*)
721
                        r_insn_is_pipeable = 1'b0;
722 138 dgisselq
 
723 209 dgisselq
                // verilator lint_off UNUSED
724
                wire    unused_pipable;
725
                assign  unused_pipable = r_insn_is_pipeable;
726
                // verilator lint_on  UNUSED
727
        end endgenerate
728
 
729
        initial r_valid = 1'b0;
730
        generate if (OPT_PIPELINED)
731
        begin : GEN_DCD_VALID
732
 
733
                always @(posedge i_clk)
734
                        if (i_reset)
735
                                r_valid <= 1'b0;
736
                        else if (i_ce)
737
                                r_valid <= ((pf_valid)||(o_phase))&&(!o_ljmp);
738
                        else if (!i_stalled)
739
                                r_valid <= 1'b0;
740
 
741
        end else begin : GEN_DCD_VALID
742
 
743
                always @(posedge i_clk)
744
                if (i_reset)
745 71 dgisselq
                        r_valid <= 1'b0;
746 205 dgisselq
                else if (!i_stalled)
747 209 dgisselq
                        r_valid <= ((pf_valid)||(o_phase))&&(!o_ljmp);
748
                else
749 105 dgisselq
                        r_valid <= 1'b0;
750 71 dgisselq
 
751 209 dgisselq
        end endgenerate
752
 
753 205 dgisselq
        assign  o_valid = r_valid;
754 201 dgisselq
 
755 205 dgisselq
 
756 69 dgisselq
        assign  o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
757
 
758 209 dgisselq
        // Make Verilator happy across all our various options
759
        // verilator lint_off  UNUSED
760
        wire    [5:0] possibly_unused;
761
        assign  possibly_unused = { w_lock, w_ljmp, w_ljmp_dly, w_cis_ljmp, i_pc[1:0] };
762
        // verilator lint_on  UNUSED
763
`ifdef  FORMAL
764
        reg     f_past_valid;
765
 
766
        initial f_past_valid = 1'b0;
767
        always @(posedge i_clk)
768
                f_past_valid <= 1'b1;
769
 
770
`define ASSERT  assert
771
`ifdef  IDECODE
772
`define ASSUME  assume
773
`else
774
`define ASSUME  assert
775
`endif
776
        always @(posedge i_clk)
777
        if ((i_ce)&&(i_pf_valid)&&(!o_phase))
778
                f_insn_word <= i_instruction;
779
        always @(posedge i_clk)
780
        if ((i_ce)&&(i_pf_valid)&&(!o_phase))
781
                f_insn_gie = i_gie;
782
        always @(*)
783
        if (o_phase)
784
                assert(r_nxt_half == f_insn_word[14:0]);
785
 
786
        ////////////////////////////
787
        //
788
        //
789
        // Assumptions about our inputs
790
        //
791
        //
792
        ///////////////////////////
793
        always @(*)
794
        if (OPT_PIPELINED)
795
                `ASSUME(i_ce == ((!o_valid)||(!i_stalled)));
796
        else
797
                `ASSUME(i_ce == !i_stalled);
798
 
799
        always @(posedge i_clk)
800
        if ((!f_past_valid)||($past(i_reset)))
801
        begin
802
                `ASSERT(!o_valid);
803
                // `ASSERT(!o_illegal);
804
                `ASSERT(!o_phase);
805
                `ASSERT(!o_ljmp);
806
                `ASSERT(!o_pipe);
807
 
808
                `ASSUME(!i_pf_valid);
809
        end
810
 
811
        always @(posedge i_clk)
812
        if ((f_past_valid)&&(!i_reset))
813
                `ASSUME(i_gie == $past(i_gie));
814
 
815
`ifdef  IDECODE
816
        always @(posedge i_clk)
817
        if ((f_past_valid)&&(!$past(i_reset))&&(!$past(i_ce))
818
                &&($past(f_past_valid))&&(!$past(i_reset,2))&&(!$past(i_ce,2)))
819
                assume(i_ce);
820
`endif
821
 
822
        reg     f_new_insn, f_last_insn;
823
 
824
        initial f_new_insn = 1'b0;
825
        always @(posedge i_clk)
826
        if (i_reset)
827
                f_new_insn <= 1'b0;
828
        else
829
                f_new_insn <= ((pf_valid)&&(!i_stalled));
830
 
831
        initial f_last_insn = 1'b0;
832
        always @(posedge i_clk)
833
        if (i_reset)
834
                f_last_insn <= 1'b0;
835
        else
836
                f_last_insn <= (o_valid)&&(i_stalled);
837
 
838
        always @(posedge i_clk)
839
        if ((f_past_valid)&&(f_last_insn)&&(!i_reset))
840
        begin
841
                if (($past(pf_valid))&&(pf_valid))
842
                begin
843
                        `ASSUME(i_instruction == $past(i_instruction));
844
                        `ASSUME(i_gie == $past(i_gie));
845
                        `ASSUME(i_pc  == $past(i_pc));
846
                        `ASSUME(i_illegal == $past(i_illegal));
847
                end
848
        end
849
 
850
        always @(posedge i_clk)
851
        if ((f_past_valid)&&(o_early_branch_stb))
852
                `ASSUME(!pf_valid);
853
 
854
        always @(*)
855
                `ASSUME(i_pc[1:0] == 2'b00);
856
        always @(*)
857
        if ((o_valid)&&(!o_early_branch))
858
                `ASSERT((o_illegal)||(o_pc[1] == o_phase));
859
 
860
        wire    [4+21+32+1+4+1+4+11+AW+3+23-1:0] f_result;
861
        assign  f_result = { o_valid, o_phase, o_illegal,
862
                        i_gie, o_dcdR, o_dcdA, o_dcdB, o_I, o_zI, o_cond,
863
                        o_wF, o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
864
                        o_wR, o_rA, o_rB, o_early_branch, o_branch_pc, o_ljmp,
865
                        o_pipe, o_sim, o_sim_immv, o_pc };
866
 
867
        always @(posedge i_clk)
868
        if ((f_past_valid)&&(!$past(i_reset))&&(f_last_insn))
869
                `ASSERT(f_result == $past(f_result));
870
 
871
        always @(posedge i_clk)
872
        if ((f_past_valid)&&(!$past(i_reset))&&($past(pf_valid))
873
                        &&(!$past(o_ljmp)))
874
                `ASSERT((!OPT_PIPELINED)||(o_valid));
875
 
876
        always @(posedge i_clk)
877
        if ((f_past_valid)&&(f_new_insn)
878
                        &&($past(pf_valid))&&($past(i_illegal))&&(!$past(o_phase)))
879
                `ASSERT(o_illegal);
880
 
881
`ifdef  IDECODE
882
        // Let's walk through some basic instructions
883
        // First 8-instructions, SUB - ASR
884
        always @(*)
885
        if ((!iword[`CISBIT])&&(iword[26:25]==2'b00))
886
        begin
887
                `ASSERT(!w_cmptst);
888
                `ASSERT(!w_div);
889
                `ASSERT(!w_mem);
890
                `ASSERT(!w_sto);
891
                `ASSERT(!w_ldi);
892
                `ASSERT(!w_mov);
893
                `ASSERT(!w_brev);
894
                `ASSERT(!w_ldilo);
895
                `ASSERT(!w_special);
896
                `ASSERT(!w_fpu);
897
                `ASSERT(!w_mpy);
898
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
899
                `ASSERT(w_rB == iword[`IMMSEL]);
900
                `ASSERT(w_dcdA[4] == i_gie);
901
                `ASSERT(w_dcdB[4] == i_gie);
902
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
903
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
904
 
905
                `ASSERT(w_cis_op == w_op);
906
 
907
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
908
                `ASSERT(w_cond[2:0] == iword[21:19]);
909
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
910
        end else if ((iword[`CISBIT])&&(iword[26:24]<3'b011))
911
        begin
912
                `ASSERT(!w_cmptst);
913
                `ASSERT(!w_div);
914
                `ASSERT(!w_mem);
915
                `ASSERT(!w_sto);
916
                `ASSERT(!w_ldi);
917
                `ASSERT(!w_mov);
918
                `ASSERT(!w_brev);
919
                `ASSERT(!w_ldilo);
920
                `ASSERT(!w_special);
921
                `ASSERT(!w_fpu);
922
                `ASSERT(!w_mpy);
923
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
924
                `ASSERT(w_rB == iword[`CISIMMSEL]);
925
                `ASSERT(w_dcdA[4] == i_gie);
926
                `ASSERT(w_dcdB[4] == i_gie);
927
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
928
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
929
 
930
                if (iword[26:24] == 3'b000)
931
                        `ASSERT(w_cis_op == 5'h0);
932
                else if (iword[26:24] == 5'h01)
933
                        `ASSERT(w_cis_op == 5'h01);
934
                else // if (iword[26:24] == 3'b010)
935
                        `ASSERT(w_cis_op == 5'h02);
936
 
937
                `ASSERT(w_cond == 4'h8);
938
 
939
                if (iword[`CISIMMSEL])
940
                        `ASSERT(w_I == { {(23-3){iword[18]}}, iword[18:16] });
941
                else
942
                        `ASSERT(w_I == { {(23-7){iword[22]}}, iword[22:16] });
943
        end else
944
                `ASSERT(!w_add);
945
 
946
        // BREV and LDILO
947
        always @(*)
948
        if ((!iword[`CISBIT])&&((w_cis_op == 5'h8)
949
                        ||(w_cis_op == 5'h09)))
950
        begin
951
                `ASSERT(!w_mpy);
952
                `ASSERT(!w_div);
953
                `ASSERT(!w_cmptst);
954
                `ASSERT(!w_mem);
955
                `ASSERT(!w_sto);
956
                `ASSERT(!w_ldi);
957
                `ASSERT(!w_mov);
958
                if (w_cis_op == 5'h8)
959
                begin
960
                        `ASSERT(w_brev);
961
                        `ASSERT(!w_ldilo);
962
                        `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
963
                end else begin// if (w_cis_op == 5'h9)
964
                        `ASSERT(w_ldilo);
965
                        `ASSERT(!w_brev);
966
                        `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
967
                end
968
                `ASSERT(!w_special);
969
                `ASSERT(!w_fpu);
970
                `ASSERT(w_rB == iword[`IMMSEL]);
971
                `ASSERT(w_dcdA[4] == i_gie);
972
                `ASSERT(w_dcdB[4] == i_gie);
973
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
974
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
975
 
976
                `ASSERT(w_cis_op == w_op);
977
 
978
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
979
                `ASSERT(w_cond[2:0] == iword[21:19]);
980
                `ASSERT(!w_wF);
981
        end else begin
982
                `ASSERT(!w_brev);
983
                `ASSERT(!w_ldilo);
984
        end
985
 
986
        //
987
        // Multiply instructions
988
        always @(*)
989
        if ((!iword[`CISBIT])&&((w_cis_op == 5'ha)
990
                        ||(w_cis_op == 5'h0b)
991
                        ||(w_cis_op == 5'h0c)))
992
        begin
993
                `ASSERT(w_mpy);
994
                `ASSERT(!w_div);
995
                `ASSERT(!w_cmptst);
996
                `ASSERT(!w_mem);
997
                `ASSERT(!w_sto);
998
                `ASSERT(!w_ldi);
999
                `ASSERT(!w_mov);
1000
                `ASSERT(!w_brev);
1001
                `ASSERT(!w_ldilo);
1002
                `ASSERT(!w_special);
1003
                `ASSERT(!w_fpu);
1004
                `ASSERT((w_rA)&&(w_wR)&&(w_ALU));
1005
                `ASSERT(w_rB == iword[`IMMSEL]);
1006
                `ASSERT(w_dcdA[4] == i_gie);
1007
                `ASSERT(w_dcdB[4] == i_gie);
1008
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1009
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1010
 
1011
                `ASSERT(w_cis_op == w_op);
1012
 
1013
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1014
                `ASSERT(w_cond[2:0] == iword[21:19]);
1015
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
1016
        end else
1017
                `ASSERT(!w_mpy);
1018
 
1019
        //
1020
        // Move instruction
1021
        always @(*)
1022
        if ((!iword[`CISBIT])&&((w_cis_op == 5'hd)))
1023
        begin
1024
                `ASSERT(w_mov);
1025
                `ASSERT(!w_div);
1026
                `ASSERT(!w_mpy);
1027
                `ASSERT(!w_cmptst);
1028
                `ASSERT(!w_mem);
1029
                `ASSERT(!w_sto);
1030
                `ASSERT(!w_ldi);
1031
                `ASSERT(!w_brev);
1032
                `ASSERT(!w_ldilo);
1033
                `ASSERT(!w_special);
1034
                `ASSERT(!w_fpu);
1035
                `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
1036
                `ASSERT(w_rB);
1037
                `ASSERT(w_dcdA[4] == ((i_gie)||(iword[`IMMSEL])));
1038
                `ASSERT(w_dcdB[4] == ((i_gie)||(iword[13])));
1039
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1040
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1041
 
1042
                `ASSERT(w_cis_op == w_op);
1043
 
1044
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1045
                `ASSERT(w_cond[2:0] == iword[21:19]);
1046
                `ASSERT(!w_wF);
1047
        end else if ((iword[`CISBIT])&&(iword[26:24]==3'b111))
1048
        begin
1049
                `ASSERT(w_mov);
1050
                `ASSERT(!w_div);
1051
                `ASSERT(!w_mpy);
1052
                `ASSERT(!w_cmptst);
1053
                `ASSERT(!w_mem);
1054
                `ASSERT(!w_sto);
1055
                `ASSERT(!w_ldi);
1056
                `ASSERT(!w_brev);
1057
                `ASSERT(!w_ldilo);
1058
                `ASSERT(!w_special);
1059
                `ASSERT(!w_fpu);
1060
                `ASSERT((!w_rA)&&(w_wR)&&(w_ALU));
1061
                `ASSERT(w_rB);
1062
                `ASSERT(w_dcdA[4] == (i_gie));
1063
                `ASSERT(w_dcdB[4] == (i_gie));
1064
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1065
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
1066
 
1067
                `ASSERT(w_cis_op == 5'h0d);
1068
 
1069
                `ASSERT(w_cond == 4'h8);
1070
                `ASSERT(!w_wF);
1071
        end else
1072
                `ASSERT(!w_mov);
1073
 
1074
        //
1075
        // Divide instruction
1076
        always @(*)
1077
        if ((!iword[`CISBIT])&&(iword[26:23]==4'b0111))
1078
        begin
1079
                `ASSERT(w_div);
1080
                `ASSERT(!w_cmptst);
1081
                `ASSERT(!w_mem);
1082
                `ASSERT(!w_sto);
1083
                `ASSERT(!w_ldi);
1084
                `ASSERT(!w_mov);
1085
                `ASSERT(!w_brev);
1086
                `ASSERT(!w_ldilo);
1087
                `ASSERT(!w_special);
1088
                `ASSERT(!w_fpu);
1089
                `ASSERT(!w_mpy);
1090
                `ASSERT((w_rA)&&(w_wR));
1091
                `ASSERT(w_rB == iword[`IMMSEL]);
1092
                `ASSERT(w_dcdA[4] == i_gie);
1093
                `ASSERT(w_dcdB[4] == i_gie);
1094
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1095
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1096
 
1097
                `ASSERT(w_cis_op == w_op);
1098
 
1099
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1100
                `ASSERT(w_cond[2:0] == iword[21:19]);
1101
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
1102
        end else
1103
                `ASSERT(!w_div);
1104
 
1105
        //
1106
        // Comparison instructions
1107
        always @(*)
1108
        if ((!iword[`CISBIT])&&(iword[26:23]==4'b1000))
1109
        begin
1110
                `ASSERT(w_cmptst);
1111
                `ASSERT(!w_div);
1112
                `ASSERT(!w_mem);
1113
                `ASSERT(!w_sto);
1114
                `ASSERT(!w_ldi);
1115
                `ASSERT(!w_mov);
1116
                `ASSERT(!w_brev);
1117
                `ASSERT(!w_ldilo);
1118
                `ASSERT(!w_special);
1119
                `ASSERT(!w_fpu);
1120
                `ASSERT(!w_mpy);
1121
                `ASSERT((w_rA)&&(!w_wR)&&(!w_ALU));
1122
                `ASSERT(w_rB == iword[`IMMSEL]);
1123
                `ASSERT(w_dcdA[4] == i_gie);
1124
                `ASSERT(w_dcdB[4] == i_gie);
1125
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1126
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1127
 
1128
                `ASSERT(w_cis_op == w_op);
1129
 
1130
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1131
                `ASSERT(w_cond[2:0] == iword[21:19]);
1132
                `ASSERT(w_wF);
1133
        end else if ((iword[`CISBIT])&&(iword[26:24]==3'b011))
1134
        begin
1135
                `ASSERT(w_cmptst);
1136
                `ASSERT(!w_div);
1137
                `ASSERT(!w_mem);
1138
                `ASSERT(!w_sto);
1139
                `ASSERT(!w_ldi);
1140
                `ASSERT(!w_mov);
1141
                `ASSERT(!w_brev);
1142
                `ASSERT(!w_ldilo);
1143
                `ASSERT(!w_special);
1144
                `ASSERT(!w_fpu);
1145
                `ASSERT(!w_mpy);
1146
                `ASSERT((w_rA)&&(!w_wR)&&(!w_ALU));
1147
                `ASSERT(w_rB == iword[`CISIMMSEL]);
1148
                `ASSERT(w_dcdA[4] == i_gie);
1149
                `ASSERT(w_dcdB[4] == i_gie);
1150
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1151
                `ASSERT(w_dcdB[3:0] == iword[22:19]);
1152
 
1153
                `ASSERT(w_cis_op == 5'h10);
1154
 
1155
                `ASSERT(w_cond == 4'h8);
1156
                if (iword[`CISIMMSEL])
1157
                        `ASSERT(w_I == { {(23-3){iword[18]}}, iword[18:16] });
1158
                else
1159
                        `ASSERT(w_I == { {(23-7){iword[22]}}, iword[22:16] });
1160
                `ASSERT(w_wF);
1161
        end else
1162
                `ASSERT(!w_cmptst);
1163
 
1164
        always @(posedge i_clk)
1165
        if ((f_new_insn)&&($past(w_cmptst)))
1166
                `ASSERT(o_ALU);
1167
 
1168
        //
1169
        // Memory instructions
1170
        always @(*)
1171
        if ((!iword[`CISBIT])&&(
1172
                (iword[26:23]==4'b1001)         // Word
1173
                ||(iword[26:23]==4'b1010)       // Half-word, or short
1174
                ||(iword[26:23]==4'b1011)))     // Byte ops
1175
        begin
1176
                `ASSERT(w_mem);
1177
                `ASSERT(w_sto == iword[22]);
1178
                `ASSERT(!w_cmptst);
1179
                `ASSERT(!w_div);
1180
                `ASSERT(!w_ldi);
1181
                `ASSERT(!w_mov);
1182
                `ASSERT(!w_brev);
1183
                `ASSERT(!w_ldilo);
1184
                `ASSERT(!w_special);
1185
                `ASSERT(!w_fpu);
1186
                `ASSERT(!w_mpy);
1187
                if (w_sto)
1188
                        `ASSERT((w_rA)&&(!w_wR));
1189
                else
1190
                        `ASSERT((!w_rA)&&(w_wR));
1191
                `ASSERT(!w_ALU);
1192
                `ASSERT(w_rB == iword[`IMMSEL]);
1193
                `ASSERT(w_dcdA[4] == i_gie);
1194
                `ASSERT(w_dcdB[4] == i_gie);
1195
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1196
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1197
 
1198
                `ASSERT(w_cis_op == w_op);
1199
 
1200
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1201
                `ASSERT(w_cond[2:0] == iword[21:19]);
1202
                `ASSERT(!w_wF);
1203
        end else if ((iword[`CISBIT])&&(iword[26:25]==2'b10))
1204
        begin
1205
                `ASSERT(w_mem);
1206
                `ASSERT(w_sto == iword[24]);
1207
                `ASSERT(!w_cmptst);
1208
                `ASSERT(!w_div);
1209
                `ASSERT(!w_ldi);
1210
                `ASSERT(!w_mov);
1211
                `ASSERT(!w_brev);
1212
                `ASSERT(!w_ldilo);
1213
                `ASSERT(!w_special);
1214
                `ASSERT(!w_fpu);
1215
                `ASSERT(!w_mpy);
1216
                if (w_sto)
1217
                        `ASSERT((w_rA)&&(!w_wR));
1218
                else
1219
                        `ASSERT((!w_rA)&&(w_wR));
1220
                `ASSERT(!w_ALU);
1221
                `ASSERT(w_rB);
1222
                `ASSERT(w_dcdA[4] == i_gie);
1223
                `ASSERT(w_dcdB[4] == i_gie);
1224
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1225
                if (iword[`CISIMMSEL])
1226
                        `ASSERT(w_dcdB[3:0] == iword[22:19]);
1227
                else
1228
                        `ASSERT(w_dcdB[3:0] == `CPU_SP_REG);
1229
 
1230
                if (w_sto)
1231
                        `ASSERT(w_cis_op == 5'h13);
1232
                else
1233
                        `ASSERT(w_cis_op == 5'h12);
1234
 
1235
                `ASSERT(w_cond == 4'h8);
1236
                `ASSERT(!w_wF);
1237
        end else begin
1238
                `ASSERT(!w_sto);
1239
                `ASSERT(!w_mem);
1240
        end
1241
 
1242
        always @(*)
1243
        if (w_sto)
1244
                `ASSERT(w_mem);
1245
 
1246
        //
1247
        // LDI -- Load immediate
1248
        always @(*)
1249
        if ((!iword[`CISBIT])&&(w_op[4:1] == 4'hc))
1250
        begin
1251
                `ASSERT(w_ldi);
1252
                `ASSERT(!w_mpy);
1253
                `ASSERT(!w_div);
1254
                `ASSERT(!w_cmptst);
1255
                `ASSERT(!w_mem);
1256
                `ASSERT(!w_sto);
1257
                `ASSERT(!w_mov);
1258
                `ASSERT(!w_brev);
1259
                `ASSERT(!w_ldilo);
1260
                `ASSERT((!w_rA)&&(w_wR)&&(!w_ALU));
1261
                `ASSERT(!w_special);
1262
                `ASSERT(!w_fpu);
1263
                `ASSERT(w_rB == 1'b0);
1264
                `ASSERT(w_dcdA[4] == i_gie);
1265
                `ASSERT(w_dcdB[4] == i_gie);
1266
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1267
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1268
 
1269
                `ASSERT(w_cis_op == w_op);
1270
 
1271
                `ASSERT(w_cond == 4'h8);
1272
                `ASSERT(!w_wF);
1273
 
1274
                `ASSERT(w_Iz == (iword[22:0] == 0));
1275
                `ASSERT(w_I[22:0] == iword[22:0]);
1276
        end else if ((iword[`CISBIT])&&(iword[26:24] == 3'b110))
1277
        begin
1278
                `ASSERT(w_ldi);
1279
                `ASSERT(!w_mpy);
1280
                `ASSERT(!w_div);
1281
                `ASSERT(!w_cmptst);
1282
                `ASSERT(!w_mem);
1283
                `ASSERT(!w_sto);
1284
                `ASSERT(!w_mov);
1285
                `ASSERT(!w_brev);
1286
                `ASSERT(!w_ldilo);
1287
                `ASSERT((!w_rA)&&(w_wR)&&(!w_ALU));
1288
                `ASSERT(!w_special);
1289
                `ASSERT(!w_fpu);
1290
                `ASSERT(w_rB == 1'b0);
1291
                `ASSERT(w_dcdA[4] == i_gie);
1292
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1293
 
1294
                `ASSERT(w_cis_op[4:1] == 4'hc);
1295
 
1296
                `ASSERT(w_cond == 4'h8);
1297
                `ASSERT(!w_wF);
1298
 
1299
                `ASSERT(w_Iz == (iword[23:16] == 0));
1300
                `ASSERT(w_I[22:0] == { {(23-8){iword[23]}}, iword[23:16] });
1301
        end else
1302
                `ASSERT(!w_ldi);
1303
`endif  // IDECODE
1304
 
1305
        always @(posedge i_clk)
1306
        if ((f_new_insn)&&($past(w_ldi)))
1307
                `ASSERT(o_ALU);
1308
 
1309
`ifdef  IDECODE
1310
        always @(*)
1311
        if ((w_break)||(w_lock)||(w_sim)||(w_noop))
1312
                `ASSERT(w_special);
1313
 
1314
 
1315
        //
1316
        // FPU -- Floating point instructions
1317
        always @(*)
1318
        if ((!iword[`CISBIT])&&(OPT_FPU)&&(
1319
                        (w_cis_op[4:1] == 4'hd)
1320
                        ||(w_cis_op[4:1] == 4'he)
1321
                        ||(w_cis_op[4:1] == 4'hf))
1322
                        &&(iword[30:28] != 3'h7))
1323
        begin
1324
                `ASSERT(w_fpu);
1325
                `ASSERT(!w_ldi);
1326
                `ASSERT(!w_mpy);
1327
                `ASSERT(!w_div);
1328
                `ASSERT(!w_cmptst);
1329
                `ASSERT(!w_mem);
1330
                `ASSERT(!w_sto);
1331
                `ASSERT(!w_mov);
1332
                `ASSERT(!w_brev);
1333
                `ASSERT(!w_ldilo);
1334
                `ASSERT((w_wR)&&(!w_ALU));
1335
                if ((w_cis_op == 5'he)||(w_cis_op == 5'hf))
1336
                        `ASSERT(!w_rA);
1337
                else
1338
                        `ASSERT(w_rA);
1339
                `ASSERT(!w_special);
1340
                `ASSERT(w_rB == iword[`IMMSEL]);
1341
                `ASSERT(w_dcdA[4] == i_gie);
1342
                `ASSERT(w_dcdB[4] == i_gie);
1343
                `ASSERT(w_dcdA[3:0] == iword[30:27]);
1344
                `ASSERT(w_dcdB[3:0] == iword[17:14]);
1345
 
1346
                `ASSERT(w_cis_op == w_op);
1347
 
1348
                `ASSERT(w_cond[3] == (iword[21:19] == 3'b000));
1349
                `ASSERT(w_cond[2:0] == iword[21:19]);
1350
                `ASSERT((w_wF == w_cond[3])||(w_dcdA[3:1]==3'b111));
1351
        end else
1352
                `ASSERT((!w_fpu)||(!OPT_FPU));
1353
 
1354
        //
1355
        // Special instructions
1356
        always @(*)
1357
        if ((!iword[`CISBIT])&&(
1358
                        (w_cis_op == 5'h1c)
1359
                        ||(w_cis_op == 5'h1d)
1360
                        ||(w_cis_op == 5'h1e)
1361
                        ||(w_cis_op == 5'h1f))
1362
                        &&((iword[30:28] == 3'h7)||(!OPT_FPU)))
1363
        begin
1364
                `ASSERT(w_special);
1365
                if (w_cis_op == 5'h1c)
1366
                begin
1367
                        `ASSERT(w_break);
1368
                        `ASSERT(!w_lock);
1369
                        `ASSERT(!w_sim);
1370
                        `ASSERT(!w_noop);
1371
                end else if (w_cis_op == 5'h1d)
1372
                begin
1373
                        `ASSERT(!w_break);
1374
                        `ASSERT( w_lock);
1375
                        `ASSERT(!w_sim);
1376
                        `ASSERT(!w_noop);
1377
                end else if (w_cis_op == 5'h1e)
1378
                begin
1379
                        `ASSERT(!w_break);
1380
                        `ASSERT(!w_lock);
1381
                        `ASSERT( w_sim);
1382
                        `ASSERT(!w_noop);
1383
                end else begin
1384
                        `ASSERT(!w_break);
1385
                        `ASSERT(!w_lock);
1386
                        `ASSERT(!w_sim);
1387
                        `ASSERT( w_noop);
1388
                end
1389
                `ASSERT((!w_fpu)||(!OPT_FPU));
1390
                `ASSERT(!w_ldi);
1391
                `ASSERT(!w_mpy);
1392
                `ASSERT(!w_div);
1393
                `ASSERT(!w_cmptst);
1394
                `ASSERT(!w_mem);
1395
                `ASSERT(!w_sto);
1396
                `ASSERT(!w_mov);
1397
                `ASSERT(!w_brev);
1398
                `ASSERT(!w_ldilo);
1399
 
1400
                `ASSERT((!w_rA)&&(!w_rB)&&(!w_wR)&&(!w_ALU));
1401
 
1402
                `ASSERT(w_cis_op == w_op);
1403
 
1404
                `ASSERT(w_cond == 4'h8);
1405
                `ASSERT(!w_wF);
1406
        end else begin
1407
                `ASSERT(!w_special);
1408
                `ASSERT(!w_break);
1409
                `ASSERT(!w_lock);
1410
                `ASSERT(!w_sim);
1411
                `ASSERT(!w_noop);
1412
        end
1413
`endif
1414
 
1415
        generate if (OPT_EARLY_BRANCHING)
1416
        begin
1417
                always @(posedge i_clk)
1418
                if ((f_past_valid)&&($past(i_ce))&&(!$past(i_reset))&&(!i_reset))
1419
                begin
1420
                        if ($past(pf_valid))
1421
                        begin
1422
                                if ($past(o_ljmp))
1423
                                begin
1424
                                        // 2nd half of LW (PC),PC
1425
                                        `ASSERT(o_early_branch);
1426
                                        `ASSERT(o_early_branch_stb);
1427
                                end else if ((!$past(iword[`CISBIT]))&&($past(w_add))
1428
                                        &&(!$past(w_rB))
1429
                                        &&($past(w_cond[3]))
1430
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
1431
                                begin
1432
                                        // ADD #x,PC
1433
                                        `ASSERT(o_early_branch);
1434
                                        `ASSERT(o_early_branch_stb);
1435
                                end else if ((!$past(iword[`CISBIT]))
1436
                                        &&($past(w_cis_op == 5'h12))
1437
                                        &&($past(w_rB))
1438
                                        &&($past(w_cond[3]))
1439
                                        &&(o_zI)
1440
                                        &&(o_dcdB[4:0]=={ i_gie, 4'hf })
1441
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
1442
                                begin
1443
                                        // LW (PC),PC
1444
                                        `ASSERT(!o_early_branch);
1445
                                        `ASSERT(!o_early_branch_stb);
1446
                                end else if ((OPT_CIS)&&($past(o_phase))
1447
                                        &&($past(w_cis_op == 5'h12))
1448
                                        &&($past(w_rB))
1449
                                        &&($past(w_cond[3]))
1450
                                        &&($past(w_Iz))
1451
                                        &&($past(w_dcdB_pc))
1452
                                        &&($past(w_dcdR_pc))
1453
                                        &&(o_dcdR[4:0]=={ i_gie, 4'hf }))
1454
                                begin
1455
                                        // (CIS) LW (PC),PC
1456
                                        `ASSERT(!o_early_branch);
1457
                                        `ASSERT(!o_early_branch_stb);
1458
                                end else begin
1459
                                        `ASSERT(!o_early_branch);
1460
                                end
1461
                        end else if ((OPT_CIS)&&($past(o_phase)))
1462
                        begin
1463
                                if (($past(w_cis_op == 5'h12))
1464
                                        &&($past(w_rB))
1465
                                        &&($past(w_cond[3]))
1466
                                        &&($past(w_Iz))
1467
                                        &&($past(w_dcdB_pc))
1468
                                        &&($past(w_dcdR_pc)))
1469
                                begin
1470
                                // (CIS) LW (PC),PC
1471
                                        `ASSERT(!o_early_branch);
1472
                                        `ASSERT(!o_early_branch_stb);
1473
                                end else begin
1474
                                        `ASSERT(!o_early_branch);
1475
                                        `ASSERT(!o_early_branch_stb);
1476
                                end
1477
                        end
1478
                end else if (!i_reset)
1479
                        `ASSERT(!o_early_branch_stb);
1480
 
1481
//              // CIS instruction 16'hfcf8 decodes into:
1482
//              // 1.1111.100.1.1111.0000
1483
//              // = LW (PC),PC
1484
//              always @(*)
1485
//                      assume(i_instruction[31:16] != 16'hfcf8);
1486
 
1487
        end else begin
1488
                always @(*)
1489
                        `ASSERT(!o_early_branch_stb);
1490
                always @(*)
1491
                        `ASSERT(!o_early_branch);
1492
        end endgenerate
1493
 
1494
        always @(*)
1495
                if (o_early_branch_stb)
1496
                        `ASSERT(o_early_branch);
1497
        always @(posedge i_clk)
1498
        if ((f_past_valid)&&($past(o_early_branch_stb))&&(!$past(pf_valid)))
1499
                        `ASSERT(!o_early_branch_stb);
1500
 
1501
        always @(*)
1502
        if (!OPT_LOCK)
1503
                `ASSERT(!o_lock);
1504
 
1505
        generate if (OPT_CIS)
1506
        begin : F_OPT_CIS
1507
                always @(*)
1508
                if ((OPT_PIPELINED)&&(!o_valid))
1509
                        `ASSERT(!o_phase);
1510
 
1511
                always @(posedge i_clk)
1512
                if ((f_past_valid)&&(!$past(i_reset)))
1513
                begin
1514
                        if ((o_phase)&&($past(i_ce)))
1515
                                `ASSERT((iword[30:16] == $past(i_instruction[14:0]))
1516
                                        &&(iword[`CISBIT]));
1517
                        else if (!o_phase)
1518
                                `ASSERT(iword == i_instruction);
1519
 
1520
                        if ((!$past(o_phase))&&($past(i_ce))
1521
                                        &&($past(pf_valid))
1522
                                        &&(!$past(i_illegal))
1523
                                        &&(!$past(w_ljmp_dly))
1524
                                        &&($past(i_instruction[`CISBIT]))
1525
                                        &&((!$past(w_dcdR_pc))
1526
                                                ||(!$past(w_wR))))
1527
                                `ASSERT(o_phase);
1528
                        else if (($past(o_phase))&&($past(i_ce)))
1529
                                `ASSERT(!o_phase);
1530
                        if (($past(i_ce))&&(!$past(o_phase))
1531
                                &&($past(i_illegal))&&($past(i_pf_valid)))
1532
                                `ASSERT((o_illegal)&&(!o_phase));
1533
 
1534
                        `ASSERT((!o_phase)||(!o_ljmp));
1535
                end
1536
 
1537
                always @(posedge i_clk)
1538
                if ((f_past_valid)&&(!$past(i_stalled))&&($past(pf_valid))
1539
                                &&($past(i_ce)))
1540
                begin
1541
                        `ASSERT(o_pc[0] == 1'b0);
1542
                        if (!$past(iword[`CISBIT]))
1543
                        begin
1544
                                `ASSERT(o_pc[1:0]==2'b00);
1545
                                `ASSERT(o_pc[AW+1:2] == $past(i_pc[AW+1:2])+1'b1);
1546
                        end else if ($past(iword[`CISBIT])&&($past(o_phase)))
1547
                                `ASSERT(o_pc[(AW+1):1] == $past(o_pc[(AW+1):1]) + 1'b1);
1548
                        else if ($past(iword[`CISBIT]))
1549
                        begin
1550
                                `ASSERT(o_pc[(AW+1):1] == { $past(i_pc[(AW+1):2]), 1'b1});
1551
                                if (o_valid)
1552
                                begin
1553
                                        `ASSERT(o_pc[1]);
1554
                                        `ASSERT((o_illegal)||(o_phase));
1555
                                end
1556
                        end
1557
                end
1558
 
1559
 
1560
                always @(*)
1561
                if (iword[`CISBIT])
1562
                begin
1563
                        `ASSERT((!w_ldi)||(w_I == { {(23-8){iword[23]}}, iword[23:16] }));
1564
                        `ASSERT((w_ldi)||(iword[`CISIMMSEL])
1565
                                ||(w_I == { {(23-7){iword[22]}}, iword[22:16] }));
1566
                        `ASSERT((w_ldi)||(!iword[`CISIMMSEL])
1567
                                ||(w_I == { {(23-3){iword[18]}}, iword[18:16] }));
1568
                end else begin
1569
                        `ASSERT((!w_ldi)||(w_I == iword[22:0]));
1570
                        `ASSERT((!w_mov)||(w_I == { {(23-13){iword[12]}}, iword[12:0] }));
1571
                        `ASSERT((w_ldi)||(w_mov)||(iword[`IMMSEL])
1572
                                        ||(w_I == { {(23-18){iword[17]}}, iword[17:0] }));
1573
                        `ASSERT((w_ldi)||(w_mov)||(!iword[`IMMSEL])
1574
                                        ||(w_I == { {(23-14){iword[13]}}, iword[13:0] }));
1575
                end
1576
 
1577
                always @(posedge i_clk)
1578
                if ((f_past_valid)&&(o_phase)&&($past(i_ce)))
1579
                        `ASSERT(($past(i_instruction[`CISBIT]))
1580
                                &&(r_nxt_half[14:0]==$past(i_instruction[14:0])));
1581
        end else begin
1582
 
1583
                always @(*)
1584
                begin
1585
                        `ASSERT((o_phase)||(iword[30:0] == i_instruction[30:0]));
1586
                        `ASSERT(o_phase == 1'b0);
1587
                        `ASSERT(o_pc[0] == 1'b0);
1588
                end
1589
 
1590
                always @(posedge i_clk)
1591
                if ((f_past_valid)&&($past(i_ce))&&($past(i_pf_valid)))
1592
                        `ASSERT(o_pc[AW+1:2] == $past(i_pc[AW+1:2]) + 1'b1);
1593
                else if (f_past_valid)
1594
                        `ASSERT(o_pc == $past(o_pc));
1595
 
1596
                always @(*)
1597
                        `ASSERT(o_pc[1:0] == 2'b00);
1598
 
1599
                always @(*)
1600
                        `ASSERT((!w_ldi)||(w_I == iword[22:0]));
1601
                always @(*)
1602
                        `ASSERT((!w_mov)||(w_I == { {(23-13){iword[12]}}, iword[12:0] }));
1603
                always @(*)
1604
                        `ASSERT((w_ldi)||(w_mov)||(iword[`IMMSEL])
1605
                                        ||(w_I == { {(23-18){iword[17]}}, iword[17:0] }));
1606
                always @(*)
1607
                        `ASSERT((w_ldi)||(w_mov)||(!iword[`IMMSEL])
1608
                                        ||(w_I == { {(23-14){iword[13]}}, iword[13:0] }));
1609
 
1610
                always @(posedge i_clk)
1611
                if ((f_past_valid)&&($past(i_ce))&&(!$past(i_reset)))
1612
                        `ASSERT((!$past(i_instruction[`CISBIT]))
1613
                                ||(!$past(pf_valid))||(o_illegal));
1614
        end endgenerate
1615
 
1616
        always @(posedge i_clk)
1617
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))&&($past(w_fpu)))
1618
        begin
1619
                if (OPT_FPU)
1620
                        `ASSERT(o_FP);
1621
                else if (!$past(w_special))
1622
                        `ASSERT(o_illegal);
1623
        end
1624
        always @(posedge i_clk)
1625
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))&&($past(w_lock)))
1626
        begin
1627
                if (OPT_LOCK)
1628
                        `ASSERT(o_lock);
1629
                else
1630
                        `ASSERT(o_illegal);
1631
        end
1632
 
1633
        wire    [20:0]   f_next_pipe_I, f_this_pipe_I;
1634
        assign  f_this_pipe_I = r_I[22:2];
1635
        assign  f_next_pipe_I = r_I[22:2]+1'b1;
1636
        always @(posedge i_clk)
1637
        if ((f_past_valid)&&(!$past(i_reset)))
1638
        begin
1639
                if (OPT_OPIPE)
1640
                begin
1641
                        if (($past(i_ce))
1642
                                &&(($past(pf_valid))||($past(o_phase))))
1643
                        begin
1644
                                if ((!$past(o_M))||(!o_M))
1645
                                        `ASSERT(!o_pipe);
1646
                                else if ($past(o_op[0])!=o_op[0])
1647
                                        `ASSERT(!o_pipe);
1648
                                else if ($past(o_rB)!=o_rB)
1649
                                        `ASSERT(!o_pipe);
1650
                                else if ((o_rB)&&($past(o_dcdB) != o_dcdB))
1651
                                        `ASSERT(!o_pipe);
1652
                                else if (($past(o_wR))
1653
                                                &&($past(o_dcdR[3:1]) == 3'h7))
1654
                                        `ASSERT(!o_pipe);
1655
                                // else if ((o_wR)&&(o_dcdR[3:1] == 3'h7))
1656
                                //      `ASSERT(!o_pipe);
1657
                                else if (o_wR != $past(o_wR))
1658
                                        `ASSERT(!o_pipe);
1659
                                else if ((o_wR)&&($past(o_dcdR) == o_dcdB))
1660
                                        `ASSERT(!o_pipe);
1661
                                else if ((o_wR)&&(o_dcdB[3:1] == 3'h7))
1662
                                        `ASSERT(!o_pipe);
1663
                                else if (($past(o_cond) != 4'h8)
1664
                                        &&($past(o_cond) != o_cond))
1665
                                        `ASSERT(!o_pipe);
1666
                                else if ($past(r_I[22])!=r_I[22])
1667
                                        `ASSERT(!o_pipe);
1668
                                else if (r_I[22:0] - $past(r_I[22:0])>23'h4)
1669
                                        `ASSERT(!o_pipe);
1670
                                else if (!$past(o_valid))
1671
                                        `ASSERT(!o_pipe);
1672
                                // else
1673
                                        // assert(o_pipe);
1674
                        end else if ($past(i_stalled))
1675
                                `ASSERT(o_pipe == $past(o_pipe));
1676
                end
1677
        end
1678
 
1679
        always @(*)
1680
                `ASSERT((OPT_OPIPE)||(!o_pipe));
1681
        always @(posedge i_clk)
1682
        if ((f_past_valid)&&(!$past(i_reset))&&($past(i_ce))
1683
                        &&($past(i_pf_valid))&&($past(w_mpy)))
1684
                `ASSERT((OPT_MPY)||(o_illegal));
1685
 
1686
        always @(*)
1687
        if (o_valid)
1688
                `ASSERT((!o_phase)||(!o_early_branch));
1689
 
1690
        always @(posedge i_clk)
1691
        if ((f_past_valid)&&($past(o_valid))&&($past(o_ljmp))&&($past(!i_stalled)))
1692
                `ASSERT(!o_valid);
1693
 
1694
        always @(posedge i_clk)
1695
        if ((f_past_valid)&&($past(o_early_branch_stb)))
1696
        begin
1697
                `ASSERT(!o_phase);
1698
                if (!$past(i_stalled))
1699
                        `ASSERT(!o_valid);
1700
                        `ASSERT(!o_ljmp);
1701
        end
1702
 
1703
        // Unless another valid instruction comes along, once o_ljmp is asserted
1704
        // it should stay asserted until either a reset or an early branch
1705
        // strobe.
1706
        always @(posedge i_clk)
1707
        if ((OPT_EARLY_BRANCHING)&&(f_past_valid)
1708
                        &&($past(o_ljmp))&&(!$past(pf_valid))
1709
                        &&(!$past(i_reset))&&(!$past(o_early_branch_stb)))
1710
                `ASSERT(o_ljmp);
1711
 
1712
        // o_ljmp should only ever be asserted following a valid prefetch
1713
        // input.  Hence, if the prefetch input isn't valid, then o_ljmp
1714
        // should be left low
1715
        always @(posedge i_clk)
1716
        if ((f_past_valid)&&(!$past(o_ljmp))
1717
                        &&( (!$past(pf_valid)) || (!$past(i_ce)) )
1718
                        &&( !$past(o_phase) )
1719
                        &&(!$past(i_reset))&&(!$past(o_early_branch_stb)))
1720
                `ASSERT(!o_ljmp);
1721
 
1722
        always @(posedge i_clk)
1723
        if ((OPT_EARLY_BRANCHING)&&(f_past_valid)&&($past(o_ljmp))&&(!o_ljmp)
1724
                        &&(!$past(i_reset)))
1725
                `ASSERT((o_early_branch_stb)&&(!o_valid));
1726
 
1727
        always @(posedge i_clk)
1728
                `ASSERT((!o_early_branch_stb)||(!o_ljmp));
1729
 
1730
        always @(posedge i_clk)
1731
                `ASSERT((!o_valid)||(!o_ljmp)||(o_phase == o_pc[1]));
1732
 
1733
        always @(posedge i_clk)
1734
        if (!OPT_CIS)
1735
                `ASSERT(!o_phase);
1736
        else if (!f_insn_word[31])
1737
                `ASSERT(!o_phase);
1738
        else if (o_phase)
1739
                `ASSERT(o_pc[1]);
1740
 
1741
        always @(*)
1742
        if ((o_early_branch)&&(!o_early_branch_stb))
1743
                `ASSERT(!o_pipe);
1744
 
1745
        always @(*)
1746
        if (o_ljmp)
1747
                `ASSERT(!o_pipe);
1748
 
1749
        always @(*)
1750
        `ASSERT(o_dcdR == o_dcdA);
1751
 
1752
        always @(*)
1753
        if ((o_valid)&&(o_phase))
1754
        begin
1755
                `ASSERT(!o_illegal);
1756
                `ASSERT(o_pc[1]);
1757
                `ASSERT(f_insn_word[31]);
1758
        end
1759
 
1760
        always @(*)
1761
                `ASSERT(o_branch_pc[1:0] == 2'b00);
1762
        always @(*)
1763
                `ASSERT(o_pc[0] == 1'b0);
1764
        always @(posedge i_clk)
1765
        if ((f_past_valid)&&($past(i_pf_valid))&&(i_pf_valid))
1766
                `ASSUME((i_reset)||($stable(i_gie)));
1767
 
1768
        wire    fc_illegal, fc_wF, fc_ALU, fc_M, fc_DV, fc_FP, fc_break,
1769
                fc_lock, fc_wR, fc_rA, fc_rB, fc_prepipe, fc_sim;
1770
        wire    [6:0]    fc_dcdR, fc_dcdA, fc_dcdB;
1771
        wire    [31:0]   fc_I;
1772
        wire    [3:0]    fc_cond;
1773
        wire    [3:0]    fc_op;
1774
        wire    [22:0]   fc_sim_immv;
1775
        f_idecode #(
1776
                .ADDRESS_WIDTH(AW),
1777
                .OPT_MPY(OPT_MPY),
1778
                .OPT_EARLY_BRANCHING(OPT_EARLY_BRANCHING),
1779
                .OPT_DIVIDE(OPT_DIVIDE),
1780
                .OPT_FPU(OPT_FPU),
1781
                .OPT_CIS(OPT_CIS),
1782
                .OPT_LOCK(OPT_LOCK),
1783
                .OPT_OPIPE(OPT_OPIPE),
1784
                .OPT_SIM(OPT_SIM)
1785
                ) formal_decoder(
1786
                        f_insn_word, o_phase, f_insn_gie,
1787
                fc_illegal,
1788
                fc_dcdR, fc_dcdA,fc_dcdB, fc_I, fc_cond, fc_wF, fc_op,
1789
                fc_ALU, fc_M, fc_DV, fc_FP, fc_break, fc_lock,
1790
                fc_wR, fc_rA, fc_rB, fc_prepipe, fc_sim, fc_sim_immv);
1791
 
1792
        always @(posedge i_clk)
1793
        if ((o_valid)&&(fc_illegal))
1794
                assert(o_illegal);
1795
 
1796
        always @(posedge i_clk)
1797
        if ((o_valid)&&(!o_illegal))
1798
        begin
1799
                `ASSERT(fc_dcdR== o_dcdR);      //
1800
                `ASSERT(fc_dcdA== o_dcdA);      //
1801
                `ASSERT(fc_dcdB== o_dcdB);      //
1802
                `ASSERT(fc_I   == o_I);
1803
                `ASSERT(o_zI == (fc_I  == 0));
1804
                `ASSERT(fc_cond== o_cond);
1805
                `ASSERT(fc_wF  == o_wF);
1806
                `ASSERT(fc_op  == o_op);
1807
                `ASSERT(fc_ALU == o_ALU);
1808
                `ASSERT(fc_M   == o_M);
1809
                `ASSERT(fc_DV  == o_DV);
1810
                `ASSERT(fc_FP  == o_FP);
1811
                `ASSERT(fc_break== o_break);
1812
                `ASSERT(fc_lock == o_lock);
1813
                `ASSERT(fc_wR  == o_wR);
1814
                `ASSERT(fc_rA  == o_rA);
1815
                `ASSERT(fc_rB  == o_rB);
1816
                `ASSERT(fc_sim  == o_sim);
1817
                `ASSERT(fc_sim_immv  == o_sim_immv);
1818
                `ASSERT(fc_prepipe == r_insn_is_pipeable);
1819
        end else
1820
                `ASSERT(!r_insn_is_pipeable);
1821
 
1822
        always @(*)
1823
        if (o_phase)
1824
                `ASSERT(r_nxt_half[14:0] == f_insn_word[14:0]);
1825
 
1826
        always @(posedge i_clk)
1827
        if ((f_past_valid)&&($past(i_ce))&&(o_valid)&&(!$past(i_reset)))
1828
        begin
1829
                `ASSERT(((fc_illegal)
1830
                        ||$past((i_illegal)&&(!o_phase))
1831
                        ||$past((o_illegal)&&( o_phase)))== o_illegal);
1832
        end
1833
 
1834
        always @(posedge i_clk)
1835
        if ((!o_valid)||(o_illegal))
1836
                `ASSERT(!r_insn_is_pipeable);
1837
 
1838
        generate if ((OPT_CIS)&&(OPT_EARLY_BRANCHING))
1839
        begin
1840
 
1841
                always @(*)
1842
                if ((o_valid)
1843
                                // LW
1844
                                &&(o_M)&&(o_op[2:0]==3'b010)
1845
                                // Zero immediate
1846
                                &&(o_zI)
1847
                                // Unconditional
1848
                                &&(o_cond[3])
1849
                                // From PC to PC
1850
                                &&(o_dcdR[5])&&(o_dcdB[5]))
1851
                        `ASSERT((o_ljmp)
1852
                                ||((f_insn_word[31])&&(o_phase || o_illegal)));
1853
                else if (o_valid)
1854
                        `ASSERT(!o_ljmp);
1855
 
1856
        end endgenerate
1857
 
1858
`endif // FORMAL
1859 69 dgisselq
endmodule

powered by: WebSVN 2.1.0

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