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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [rtl/] [cpu/] [idecode.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 46 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 2 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 46 dgisselq
////////////////////////////////////////////////////////////////////////////////
21 2 dgisselq
//
22 46 dgisselq
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
23 2 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 46 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 2 dgisselq
// License:     GPL, v3, as defined and found on www.gnu.org,
40
//              http://www.gnu.org/licenses/gpl.html
41
//
42
//
43 46 dgisselq
////////////////////////////////////////////////////////////////////////////////
44 2 dgisselq
//
45
//
46
//
47 46 dgisselq
`define CPU_SP_REG      4'hd
48 2 dgisselq
`define CPU_CC_REG      4'he
49
`define CPU_PC_REG      4'hf
50
//
51
`include "cpudefs.v"
52
//
53
//
54
//
55
module  idecode(i_clk, i_rst, i_ce, i_stalled,
56
                i_instruction, i_gie, i_pc, i_pf_valid,
57
                        i_illegal,
58 51 dgisselq
                o_valid,
59 2 dgisselq
                o_phase, o_illegal,
60
                o_pc, o_gie,
61
                o_dcdR, o_dcdA, o_dcdB, o_I, o_zI,
62
                o_cond, o_wF,
63
                o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
64
                o_wR, o_rA, o_rB,
65
                o_early_branch, o_branch_pc, o_ljmp,
66 46 dgisselq
                o_pipe,
67
                o_sim, o_sim_immv
68 2 dgisselq
                );
69
        parameter       ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
70
                        IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
71
        input                   i_clk, i_rst, i_ce, i_stalled;
72
        input   [31:0]           i_instruction;
73
        input                   i_gie;
74
        input   [(AW-1):0]       i_pc;
75
        input                   i_pf_valid, i_illegal;
76 51 dgisselq
        output  wire            o_valid, o_phase;
77 2 dgisselq
        output  reg             o_illegal;
78 46 dgisselq
        output  reg     [AW:0]   o_pc;
79 2 dgisselq
        output  reg             o_gie;
80
        output  reg     [6:0]    o_dcdR, o_dcdA, o_dcdB;
81
        output  wire    [31:0]   o_I;
82 46 dgisselq
        output  reg             o_zI;
83 2 dgisselq
        output  reg     [3:0]    o_cond;
84
        output  reg             o_wF;
85
        output  reg     [3:0]    o_op;
86 11 dgisselq
        output  reg             o_ALU, o_M, o_DV, o_FP, o_break;
87
        output  wire            o_lock;
88 2 dgisselq
        output  reg             o_wR, o_rA, o_rB;
89
        output  wire            o_early_branch;
90
        output  wire    [(AW-1):0]       o_branch_pc;
91
        output  wire            o_ljmp;
92 11 dgisselq
        output  wire            o_pipe;
93 46 dgisselq
        output  reg             o_sim           /* verilator public_flat */;
94
        output  reg     [22:0]   o_sim_immv      /* verilator public_flat */;
95 2 dgisselq
 
96
        wire    dcdA_stall, dcdB_stall, dcdF_stall;
97
        wire                    o_dcd_early_branch;
98
        wire    [(AW-1):0]       o_dcd_branch_pc;
99 46 dgisselq
        reg     o_dcdI, o_dcdIz;
100 11 dgisselq
`ifdef  OPT_PIPELINED
101 46 dgisselq
        reg     r_lock;
102 11 dgisselq
`endif
103 46 dgisselq
`ifdef  OPT_PIPELINED_BUS_ACCESS
104
        reg     r_pipe;
105
`endif
106 2 dgisselq
 
107
 
108
        wire    [4:0]    w_op;
109 51 dgisselq
        wire            w_ldi, w_mov, w_cmptst, w_ldilo, w_ALU, w_brev,
110
                        w_noop, w_lock;
111 2 dgisselq
        wire    [4:0]    w_dcdR, w_dcdB, w_dcdA;
112
        wire            w_dcdR_pc, w_dcdR_cc;
113
        wire            w_dcdA_pc, w_dcdA_cc;
114
        wire            w_dcdB_pc, w_dcdB_cc;
115
        wire    [3:0]    w_cond;
116 51 dgisselq
        wire            w_wF, w_mem, w_sto, w_div, w_fpu;
117 2 dgisselq
        wire            w_wR, w_rA, w_rB, w_wR_n;
118 46 dgisselq
        wire            w_ljmp, w_ljmp_dly, w_cis_ljmp;
119 11 dgisselq
        wire    [31:0]   iword;
120 2 dgisselq
 
121
 
122 46 dgisselq
`ifdef  OPT_CIS
123
        reg     [15:0]   r_nxt_half;
124 2 dgisselq
        assign  iword = (o_phase)
125 46 dgisselq
                                // set second half as a NOOP ... but really
126 2 dgisselq
                                // shouldn't matter
127 46 dgisselq
                        ? { r_nxt_half[15:0], i_instruction[15:0] }
128 2 dgisselq
                        : i_instruction;
129
`else
130
        assign  iword = { 1'b0, i_instruction[30:0] };
131
`endif
132
 
133 11 dgisselq
        generate
134
        if (EARLY_BRANCHING != 0)
135 46 dgisselq
        begin
136
`ifdef  OPT_CIS
137
                reg     r_pre_ljmp;
138
                always @(posedge i_clk)
139
                if ((i_rst)||(o_early_branch))
140
                        r_pre_ljmp <= 1'b0;
141
                else if ((i_ce)&&(i_pf_valid))
142
                        r_pre_ljmp <= (!o_phase)&&(i_instruction[31])
143
                                &&(i_instruction[14:0] == 15'h7cf8);
144
                else if (i_ce)
145
                        r_pre_ljmp <= 1'b0;
146
 
147
                assign  w_cis_ljmp = r_pre_ljmp;
148
`else
149
                assign  w_cis_ljmp = 1'b0;
150
`endif
151
                // 0.1111.10010.000.1.1111.000000000...
152
                // 0111.1100.1000.0111.11000....
153 11 dgisselq
                assign  w_ljmp = (iword == 32'h7c87c000);
154 46 dgisselq
        end else begin
155
                assign  w_cis_ljmp = 1'b0;
156 11 dgisselq
                assign  w_ljmp = 1'b0;
157 46 dgisselq
        end
158 11 dgisselq
        endgenerate
159
 
160 46 dgisselq
`ifdef  OPT_CIS
161
`ifdef  VERILATOR
162
        wire    [4:0]    w_cis_op;
163
        always @(iword)
164
                if (!iword[31])
165
                        w_cis_op = w_op;
166
                else case(iword[26:24])
167
                3'h0: w_cis_op = 5'h00;
168
                3'h1: w_cis_op = 5'h01;
169
                3'h2: w_cis_op = 5'h02;
170
                3'h3: w_cis_op = 5'h10;
171
                3'h4: w_cis_op = 5'h12;
172
                3'h5: w_cis_op = 5'h13;
173
                3'h6: w_cis_op = 5'h18;
174
                3'h7: w_cis_op = 5'h0d;
175
                endcase
176
`else
177
        reg     [4:0]    w_cis_op;
178
        always @(iword,w_op)
179
                if (!iword[31])
180
                        w_cis_op <= w_op;
181
                else case(iword[26:24])
182
                3'h0: w_cis_op <= 5'h00;
183
                3'h1: w_cis_op <= 5'h01;
184
                3'h2: w_cis_op <= 5'h02;
185
                3'h3: w_cis_op <= 5'h10;
186
                3'h4: w_cis_op <= 5'h12;
187
                3'h5: w_cis_op <= 5'h13;
188
                3'h6: w_cis_op <= 5'h18;
189
                3'h7: w_cis_op <= 5'h0d;
190
                endcase
191
`endif
192
`else
193
        wire    [4:0]    w_cis_op;
194
        assign  w_cis_op = w_op;
195
`endif
196 11 dgisselq
 
197 2 dgisselq
        assign  w_op= iword[26:22];
198 46 dgisselq
        assign  w_mov    = (w_cis_op      == 5'h0d);
199
        assign  w_ldi    = (w_cis_op[4:1] == 4'hc);
200
        assign  w_brev   = (w_cis_op      == 5'h8);
201
        assign  w_cmptst = (w_cis_op[4:1] == 4'h8);
202
        assign  w_ldilo  = (w_cis_op[4:0] == 5'h9);
203
        assign  w_ALU    = (!w_cis_op[4]) // anything with [4]==0, but ...
204
                                &&(w_cis_op[3:1] != 3'h7); // not the divide
205 2 dgisselq
 
206 46 dgisselq
 
207
        // w_dcdR (4 LUTs)
208 11 dgisselq
        //
209 46 dgisselq
        // What register will we be placing results into (if at all)?
210
        //
211 11 dgisselq
        // Two parts to the result register: the register set, given for
212 46 dgisselq
        // moves in iword[18] but only for the supervisor, and the other
213 11 dgisselq
        // four bits encoded in the instruction.
214
        //
215 46 dgisselq
        assign  w_dcdR = { ((!iword[31])&&(w_mov)&&(~i_gie))?iword[18]:i_gie,
216 2 dgisselq
                                iword[30:27] };
217 11 dgisselq
        // 2 LUTs
218
        //
219
        // If the result register is either CC or PC, and this would otherwise
220
        // be a floating point instruction with floating point opcode of 0,
221
        // then this is a NOOP.
222 51 dgisselq
        assign  w_lock   = (!iword[31])&&(w_op[4:0]==5'h1d)&&(
223
                                ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7))
224
                                ||(IMPLEMENT_FPU==0));
225
`ifdef  OPT_PIPELINED
226 46 dgisselq
        assign  w_noop   = (!iword[31])&&(w_op[4:0] == 5'h1f)&&(
227
                        ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1] == 3'h7))
228
                        ||(IMPLEMENT_FPU==0));
229 51 dgisselq
`else
230
        // Allow w_lock's to set the w_noop bit in the case of no pipelining
231
        assign  w_noop   = (!iword[31])
232
                        &&((w_op[4:0] == 5'h1f)||(w_op[4:0]==5'h1d))
233
                        &&(
234
                                ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1] == 3'h7))
235
                                ||(IMPLEMENT_FPU==0));
236
`endif
237 11 dgisselq
 
238 46 dgisselq
        // dcdB - What register is used in the opB?
239
        //
240
        assign w_dcdB[4] = ((!iword[31])&&(w_mov)&&(~i_gie))?iword[13]:i_gie;
241
        assign w_dcdB[3:0]= (iword[31])
242
                                ? (((!iword[23])&&(iword[26:25]==2'b10))
243
                                        ? `CPU_SP_REG : iword[22:19])
244
                                : iword[17:14];
245 2 dgisselq
 
246
        // 0 LUTs
247 46 dgisselq
        assign  w_dcdA = w_dcdR;        // on ZipCPU, A is always result reg
248 2 dgisselq
        // 2 LUTs, 1 delay each
249
        assign  w_dcdR_pc = (w_dcdR == {i_gie, `CPU_PC_REG});
250
        assign  w_dcdR_cc = (w_dcdR == {i_gie, `CPU_CC_REG});
251
        // 0 LUTs
252
        assign  w_dcdA_pc = w_dcdR_pc;
253
        assign  w_dcdA_cc = w_dcdR_cc;
254
        // 2 LUTs, 1 delays each
255 46 dgisselq
        assign  w_dcdB_pc = (w_rB)&&(w_dcdB[3:0] == `CPU_PC_REG);
256
        assign  w_dcdB_cc = (w_rB)&&(w_dcdB[3:0] == `CPU_CC_REG);
257 2 dgisselq
 
258
        // Under what condition will we execute this
259
        // instruction?  Only the load immediate instruction
260
        // is completely unconditional.
261
        //
262
        // 3+4 LUTs
263 46 dgisselq
        assign  w_cond = ((w_ldi)||(iword[31])) ? 4'h8 :
264
                        { (iword[21:19]==3'h0), iword[21:19] };
265 2 dgisselq
 
266
        // 1 LUT
267 46 dgisselq
        assign  w_mem    = (w_cis_op[4:3] == 2'b10)&&(w_cis_op[2:1] !=2'b00);
268
        assign  w_sto     = (w_mem)&&( w_cis_op[0]);
269 2 dgisselq
        // 1 LUT
270 46 dgisselq
        assign  w_div     = (!iword[31])&&(w_op[4:1] == 4'h7);
271
        // 2 LUTs
272
        assign  w_fpu   = (!iword[31])&&(w_op[4:3] == 2'b11)
273
                                &&(w_dcdR[3:1] != 3'h7)&&(w_op[2:1] != 2'b00);
274
        //
275
        // rA - do we need to read register A?
276
        assign  w_rA = // Floating point reads reg A
277
                        ((w_fpu)&&(w_cis_op[4:1] != 4'hf))
278
                        // Divide's read A
279
                        ||(w_div)
280
                        // ALU ops read A,
281
                        //      except for MOV's and BREV's which don't
282
                        ||((w_ALU)&&(!w_brev)&&(!w_mov))
283
                        // STO's read A
284
                        ||(w_sto)
285
                        // Test/compares
286
                        ||(w_cmptst);
287
        // rB -- do we read a register for operand B?  Specifically, do we
288
        // add the registers value to the immediate to create opB?
289
        assign  w_rB     = (w_mov)
290
                                ||((!iword[31])&&(iword[18])&&(!w_ldi))
291
                                ||(( iword[31])&&(iword[23])&&(!w_ldi))
292
                                // If using compressed instruction sets,
293
                                // we *always* read on memory operands.
294
                                ||(( iword[31])&&(w_mem));
295
        // wR -- will we be writing our result back?
296
        // wR_n = !wR
297 2 dgisselq
        // 1 LUT: All but STO, NOOP/BREAK/LOCK, and CMP/TST write back to w_dcdR
298 46 dgisselq
        assign  w_wR_n   = (w_sto)
299
                                ||((!iword[31])&&(w_cis_op[4:3]==2'b11)
300
                                        &&(w_cis_op[2:1]!=2'b00)
301
                                        &&(w_dcdR[3:1]==3'h7))
302 2 dgisselq
                                ||(w_cmptst);
303
        assign  w_wR     = ~w_wR_n;
304
        //
305 46 dgisselq
        // wF -- do we write flags when we are done?
306
        //
307 2 dgisselq
        assign  w_wF     = (w_cmptst)
308 46 dgisselq
                        ||((w_cond[3])&&((w_fpu)||(w_div)
309
                                ||((w_ALU)&&(!w_mov)&&(!w_ldilo)&&(!w_brev)
310
                                        &&(w_dcdR[3:1] != 3'h7))));
311 2 dgisselq
 
312
        // Bottom 13 bits: no LUT's
313
        // w_dcd[12: 0] -- no LUTs
314
        // w_dcd[   13] -- 2 LUTs
315
        // w_dcd[17:14] -- (5+i0+i1) = 3 LUTs, 1 delay
316
        // w_dcd[22:18] : 5 LUTs, 1 delay (assuming high bit is o/w determined)
317
        reg     [22:0]   r_I;
318
        wire    [22:0]   w_I, w_fullI;
319
        wire            w_Iz;
320
 
321
        assign  w_fullI = (w_ldi) ? { iword[22:0] } // LDI
322 46 dgisselq
                        // MOVE immediates have one less bit
323
                        :((w_mov) ?{ {(23-13){iword[12]}}, iword[12:0] }
324
                        // Normal Op-B immediate ... 18 or 14 bits
325 2 dgisselq
                        :((~iword[18]) ? { {(23-18){iword[17]}}, iword[17:0] }
326
                        : { {(23-14){iword[13]}}, iword[13:0] }
327
                        ));
328
 
329 46 dgisselq
`ifdef  OPT_CIS
330
        wire    [7:0]    w_halfbits;
331
        assign  w_halfbits = iword[23:16];
332
 
333
        wire    [7:0]    w_halfI;
334
        assign  w_halfI = (iword[26:24]==3'h6) ? w_halfbits[7:0]
335
                        :(w_halfbits[7])?
336
                                { {(6){w_halfbits[2]}}, w_halfbits[1:0]}
337
                                :{ w_halfbits[6], w_halfbits[6:0] };
338
        assign  w_I  = (iword[31])?{{(23-8){w_halfI[7]}}, w_halfI }:w_fullI;
339 2 dgisselq
`else
340
        assign  w_I  = w_fullI;
341
`endif
342
        assign  w_Iz = (w_I == 0);
343
 
344
 
345 46 dgisselq
`ifdef  OPT_CIS
346 2 dgisselq
        //
347
        // The o_phase parameter is special.  It needs to let the software
348
        // following know that it cannot break/interrupt on an o_phase asserted
349
        // instruction, lest the break take place between the first and second
350 46 dgisselq
        // half of a CIS instruction.  To do this, o_phase must be asserted
351 2 dgisselq
        // when the first instruction half is valid, but not asserted on either
352
        // a 32-bit instruction or the second half of a 2x16-bit instruction.
353
        reg     r_phase;
354
        initial r_phase = 1'b0;
355
        always @(posedge i_clk)
356 46 dgisselq
                if ((i_rst) // When no instruction is in the pipe, phase is zero
357
                        ||(o_early_branch)||(w_ljmp_dly))
358 2 dgisselq
                        r_phase <= 1'b0;
359 46 dgisselq
                else if ((i_ce)&&(i_pf_valid))
360
                        r_phase <= (o_phase)? 1'b0
361
                                : ((i_instruction[31])&&(i_pf_valid));
362 2 dgisselq
                else if (i_ce)
363 46 dgisselq
                        r_phase <= 1'b0;
364 2 dgisselq
        // Phase is '1' on the first instruction of a two-part set
365
        // But, due to the delay in processing, it's '1' when our output is
366
        // valid for that first part, but that'll be the same time we
367
        // are processing the second part ... so it may look to us like a '1'
368
        // on the second half of processing.
369
 
370
        assign  o_phase = r_phase;
371
`else
372
        assign  o_phase = 1'b0;
373
`endif
374
 
375
 
376
        initial o_illegal = 1'b0;
377
        always @(posedge i_clk)
378
                if (i_rst)
379
                        o_illegal <= 1'b0;
380
                else if (i_ce)
381
                begin
382 46 dgisselq
`ifdef  OPT_CIS
383 2 dgisselq
                        o_illegal <= (i_illegal);
384
`else
385
                        o_illegal <= ((i_illegal) || (i_instruction[31]));
386
`endif
387 46 dgisselq
                        if ((IMPLEMENT_MPY==0)&&((w_cis_op[4:1]==4'h5)||(w_cis_op[4:0]==5'h0c)))
388 2 dgisselq
                                o_illegal <= 1'b1;
389
 
390 46 dgisselq
                        if ((IMPLEMENT_DIVIDE==0)&&(w_div))
391 2 dgisselq
                                o_illegal <= 1'b1;
392 46 dgisselq
                        else if ((IMPLEMENT_DIVIDE!=0)&&(w_div)&&(w_dcdR[3:1]==3'h7))
393 2 dgisselq
                                o_illegal <= 1'b1;
394
 
395
 
396 46 dgisselq
                        if ((IMPLEMENT_FPU==0)&&(w_fpu))
397 2 dgisselq
                                o_illegal <= 1'b1;
398
 
399 46 dgisselq
                        if ((w_cis_op[4:3]==2'b11)&&(w_cis_op[2:1]!=2'b00)
400
                                &&(w_dcdR[3:1]==3'h7)
401 2 dgisselq
                                &&(
402 46 dgisselq
                                        (w_cis_op[2:0] != 3'h4)  // BREAK
403 51 dgisselq
// `ifdef       OPT_PIPELINED
404 46 dgisselq
                                        &&(w_cis_op[2:0] != 3'h5)        // LOCK
405 51 dgisselq
// `endif
406 46 dgisselq
                                        // SIM instructions are always illegal
407
                                        &&(w_cis_op[2:0] != 3'h7)))      // NOOP
408 2 dgisselq
                                o_illegal <= 1'b1;
409
                end
410
 
411
 
412
        always @(posedge i_clk)
413
                if (i_ce)
414
                begin
415 46 dgisselq
`ifdef  OPT_CIS
416
                        if (!o_phase)
417 2 dgisselq
                                o_gie<= i_gie;
418 46 dgisselq
 
419 51 dgisselq
                        if (iword[31])
420
                        begin
421
                                if (o_phase)
422
                                        o_pc <= o_pc + 1'b1;
423
                                else if (i_pf_valid)
424
                                        o_pc <= { i_pc, 1'b1 };
425
                        end else begin
426
                                // The normal, non-CIS case
427 46 dgisselq
                                o_pc <= { i_pc + 1'b1, 1'b0 };
428 51 dgisselq
                        end
429 2 dgisselq
`else
430
                        o_gie<= i_gie;
431 46 dgisselq
                        o_pc <= { i_pc + 1'b1, 1'b0 };
432 2 dgisselq
`endif
433
 
434
                        // Under what condition will we execute this
435
                        // instruction?  Only the load immediate instruction
436
                        // is completely unconditional.
437
                        o_cond <= w_cond;
438
                        // Don't change the flags on conditional instructions,
439
                        // UNLESS: the conditional instruction was a CMP
440
                        // or TST instruction.
441
                        o_wF <= w_wF;
442
 
443
                        // Record what operation/op-code (4-bits) we are doing
444
                        //      Note that LDI magically becomes a MOV
445
                        //      instruction here.  That way it's a pass through
446
                        //      the ALU.  Likewise, the two compare instructions
447
                        //      CMP and TST becomes SUB and AND here as well.
448
                        // We keep only the bottom four bits, since we've
449 46 dgisselq
                        // already done the rest of the decode necessary to
450 2 dgisselq
                        // settle between the other instructions.  For example,
451
                        // o_FP plus these four bits uniquely defines the FP
452
                        // instruction, o_DV plus the bottom of these defines
453
                        // the divide, etc.
454 46 dgisselq
                        o_op <= ((w_ldi)||(w_noop))? 4'hd : w_cis_op[3:0];
455 2 dgisselq
 
456
                        // Default values
457
                        o_dcdR <= { w_dcdR_cc, w_dcdR_pc, w_dcdR};
458
                        o_dcdA <= { w_dcdA_cc, w_dcdA_pc, w_dcdA};
459
                        o_dcdB <= { w_dcdB_cc, w_dcdB_pc, w_dcdB};
460
                        o_wR  <= w_wR;
461
                        o_rA  <= w_rA;
462
                        o_rB  <= w_rB;
463
                        r_I    <= w_I;
464 46 dgisselq
                        o_zI   <= w_Iz;
465 2 dgisselq
 
466 46 dgisselq
                        // Turn a NOOP into an ALU operation--subtract in
467 11 dgisselq
                        // particular, although it doesn't really matter as long
468
                        // as it doesn't take longer than one clock.  Note
469
                        // also that this depends upon not setting any registers
470
                        // or flags, which should already be true.
471 46 dgisselq
                        o_ALU  <=  (w_ALU)||(w_ldi)||(w_cmptst)||(w_noop);
472
                        o_M    <=  w_mem;
473
                        o_DV   <=  w_div;
474
                        o_FP   <=  w_fpu;
475 2 dgisselq
 
476 46 dgisselq
                        o_break <= (!iword[31])&&(w_op[4:0]==5'h1c)&&(
477
                                ((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7))
478
                                ||(IMPLEMENT_FPU==0));
479 11 dgisselq
`ifdef  OPT_PIPELINED
480 51 dgisselq
                        r_lock  <= w_lock;
481 11 dgisselq
`endif
482 46 dgisselq
`ifdef  OPT_CIS
483
                        r_nxt_half <= { iword[31], iword[14:0] };
484 2 dgisselq
`endif
485 46 dgisselq
 
486
`ifdef  VERILATOR
487
                        // Support the SIM instruction(s)
488
                        o_sim <= (!iword[31])&&(w_op[4:1] == 4'hf)
489
                                &&(w_dcdR[3:1] == 3'h7);
490
`else
491
                        o_sim <= 1'b0;
492
`endif
493
                        o_sim_immv <= iword[22:0];
494 2 dgisselq
                end
495
 
496 11 dgisselq
`ifdef  OPT_PIPELINED
497
        assign  o_lock = r_lock;
498
`else
499
        assign  o_lock = 1'b0;
500
`endif
501
 
502 2 dgisselq
        generate
503
        if (EARLY_BRANCHING!=0)
504
        begin
505
                reg                     r_early_branch, r_ljmp;
506
                reg     [(AW-1):0]       r_branch_pc;
507
 
508
                initial r_ljmp = 1'b0;
509
                always @(posedge i_clk)
510
                        if (i_rst)
511
                                r_ljmp <= 1'b0;
512 46 dgisselq
`ifdef  OPT_CIS
513
                        else if ((i_ce)&&(o_phase))
514
                                r_ljmp <= w_cis_ljmp;
515
`endif
516 2 dgisselq
                        else if ((i_ce)&&(i_pf_valid))
517
                                r_ljmp <= (w_ljmp);
518
                assign  o_ljmp = r_ljmp;
519
 
520
                always @(posedge i_clk)
521
                if (i_rst)
522
                        r_early_branch <= 1'b0;
523
                else if ((i_ce)&&(i_pf_valid))
524
                begin
525
                        if (r_ljmp)
526
                                // LOD (PC),PC
527
                                r_early_branch <= 1'b1;
528 46 dgisselq
                        else if ((!iword[31])&&(iword[30:27]==`CPU_PC_REG)
529
                                        &&(w_cond[3]))
530 2 dgisselq
                        begin
531 46 dgisselq
                                if ((w_op[4:0]==5'h02)&&(!iword[18]))
532 2 dgisselq
                                        // Add x,PC
533
                                        r_early_branch     <= 1'b1;
534 46 dgisselq
                                else
535 2 dgisselq
                                        r_early_branch     <= 1'b0;
536
                        end else
537
                                r_early_branch <= 1'b0;
538
                end else if (i_ce)
539
                        r_early_branch <= 1'b0;
540
 
541
                always @(posedge i_clk)
542
                        if (i_ce)
543
                        begin
544
                                if (r_ljmp)
545 46 dgisselq
                                        r_branch_pc <= iword[(AW+1):2];
546 2 dgisselq
                                else // Add x,PC
547
                                r_branch_pc <= i_pc
548 46 dgisselq
                                        + {{(AW-15){iword[17]}},iword[16:2]}
549 2 dgisselq
                                        + {{(AW-1){1'b0}},1'b1};
550
                        end
551
 
552 46 dgisselq
                assign  w_ljmp_dly         = r_ljmp;
553 2 dgisselq
                assign  o_early_branch     = r_early_branch;
554
                assign  o_branch_pc        = r_branch_pc;
555
        end else begin
556 46 dgisselq
                assign  w_ljmp_dly         = 1'b0;
557 2 dgisselq
                assign  o_early_branch = 1'b0;
558
                assign  o_branch_pc = {(AW){1'b0}};
559
                assign  o_ljmp = 1'b0;
560
        end endgenerate
561
 
562
 
563
        // To be a pipeable operation there must be ...
564
        //      1. Two valid adjacent instructions
565
        //      2. Both must be memory operations, of the same time (both lods
566
        //              or both stos)
567
        //      3. Both must use the same register base address
568
        //      4. Both must be to the same address, or the address incremented
569
        //              by one
570
        // Note that we're not using iword here ... there's a lot of logic
571
        // taking place, and it's only valid if the new word is not compressed.
572
        //
573
        reg     r_valid;
574 46 dgisselq
`ifdef  OPT_PIPELINED_BUS_ACCESS
575 11 dgisselq
        initial r_pipe = 1'b0;
576 2 dgisselq
        always @(posedge i_clk)
577
                if (i_ce)
578 46 dgisselq
                        r_pipe <= (r_valid)&&((i_pf_valid)||(o_phase))
579
                                // Both must be memory operations
580
                                &&(w_mem)&&(o_M)
581
                                // Both must be writes, or both stores
582
                                &&(o_op[0] == w_cis_op[0])
583
                                // Both must be register ops
584
                                &&(w_rB)
585
                                // Both must use the same register for B
586
                                &&(w_dcdB[3:0] == o_dcdB[3:0])
587
                                // But ... the result can never be B
588
                                &&((o_op[0])
589
                                        ||(w_dcdB[3:0] != o_dcdA[3:0]))
590
                                // Needs to be to the mode, supervisor or user
591 2 dgisselq
                                &&(i_gie == o_gie)
592 46 dgisselq
                                // Same condition, or no condition before
593 2 dgisselq
                                &&((i_instruction[21:19]==o_cond[2:0])
594
                                        ||(o_cond[2:0] == 3'h0))
595 46 dgisselq
                                // Same immediate
596
                                &&((w_I[13:2]==r_I[13:2])
597
                                        ||({1'b0, w_I[13:2]}==(r_I[13:2]+12'h1)));
598 11 dgisselq
        assign o_pipe = r_pipe;
599 46 dgisselq
`else
600
        assign o_pipe = 1'b0;
601
`endif
602 11 dgisselq
 
603 2 dgisselq
        always @(posedge i_clk)
604
                if (i_rst)
605
                        r_valid <= 1'b0;
606 51 dgisselq
                else if (i_ce)
607
                        r_valid <= ((i_pf_valid)||(o_phase)||(i_illegal))
608
                                        &&(!o_ljmp)&&(!o_early_branch);
609
                else if (!i_stalled)
610 2 dgisselq
                        r_valid <= 1'b0;
611
 
612 51 dgisselq
        assign  o_valid = r_valid;
613 46 dgisselq
 
614 51 dgisselq
 
615 2 dgisselq
        assign  o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
616
 
617
endmodule

powered by: WebSVN 2.1.0

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