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

Subversion Repositories aemb

[/] [aemb/] [tags/] [AEMB_7_05/] [rtl/] [verilog/] [aeMB_decode.v] - Blame information for rev 206

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sybreon
/*
2 36 sybreon
 * $Id: aeMB_decode.v,v 1.9 2007-05-17 09:08:21 sybreon Exp $
3 3 sybreon
 *
4 10 sybreon
 * AEMB Instruction Decoder
5 25 sybreon
 * Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
6 3 sybreon
 *
7 25 sybreon
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11 3 sybreon
 *
12 25 sybreon
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 * Lesser General Public License for more details.
16 3 sybreon
 *
17 25 sybreon
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20
 * USA
21 3 sybreon
 *
22
 * DESCRIPTION
23
 * Instruction decoder
24
 *
25
 * HISTORY
26
 * $Log: not supported by cvs2svn $
27 36 sybreon
 * Revision 1.8  2007/04/30 15:58:31  sybreon
28
 * Fixed minor data hazard bug spotted by Matt Ettus.
29
 *
30 33 sybreon
 * Revision 1.7  2007/04/27 04:23:17  sybreon
31
 * Removed some unnecessary bubble control.
32
 *
33 27 sybreon
 * Revision 1.6  2007/04/27 00:23:55  sybreon
34
 * Added code documentation.
35
 * Improved size & speed of rtl/verilog/aeMB_aslu.v
36
 *
37 25 sybreon
 * Revision 1.5  2007/04/25 22:15:04  sybreon
38
 * Added support for 8-bit and 16-bit data types.
39
 *
40 22 sybreon
 * Revision 1.4  2007/04/11 04:30:43  sybreon
41
 * Added pipeline stalling from incomplete bus cycles.
42
 * Separated sync and async portions of code.
43
 *
44 16 sybreon
 * Revision 1.3  2007/04/04 06:12:27  sybreon
45
 * Fixed minor bugs
46
 *
47 10 sybreon
 * Revision 1.2  2007/04/03 14:46:26  sybreon
48
 * Fixed endian correction issues on data bus.
49
 *
50 5 sybreon
 * Revision 1.1  2007/03/09 17:52:17  sybreon
51
 * initial import
52
 *
53 3 sybreon
 */
54
 
55
module aeMB_decode (/*AUTOARG*/
56
   // Outputs
57 25 sybreon
   rSIMM, rMXALU, rMXSRC, rMXTGT, rRA, rRB, rRD, rOPC, rIMM, rDWBSTB,
58
   rDWBWE, rDLY, rLNK, rBRA, rRWE, rMXLDST, dwb_stb_o, dwb_we_o,
59 3 sybreon
   // Inputs
60 36 sybreon
   sDWBDAT, rDWBSEL, rREGA, rRESULT, iwb_dat_i, nclk, prst, drun,
61
   frun, prun
62 3 sybreon
   );
63
   // Internal I/F
64
   output [31:0] rSIMM;
65
   output [1:0]  rMXALU;
66
   output [1:0]  rMXSRC, rMXTGT;
67 25 sybreon
   output [4:0]  rRA, rRB, rRD;
68 3 sybreon
   output [5:0]  rOPC;
69
   output [15:0] rIMM;
70 25 sybreon
   output        rDWBSTB, rDWBWE;
71 10 sybreon
   output        rDLY, rLNK, rBRA, rRWE;
72 22 sybreon
   output [1:0]  rMXLDST;
73
   input [31:0]  sDWBDAT;
74
   input [3:0]    rDWBSEL;
75 3 sybreon
   input [31:0]  rREGA, rRESULT;
76
 
77
   // External I/F
78 22 sybreon
   input [31:0]  iwb_dat_i;
79 3 sybreon
   output        dwb_stb_o, dwb_we_o;
80
 
81
   // System I/F
82 36 sybreon
   input         nclk, prst, drun, frun, prun;
83 3 sybreon
 
84 25 sybreon
   /**
85
    rOPC/rRD/rRA/rRB/rIMM
86
    ---------------------
87
    Instruction latch for the different fields of the instruction
88
    ISA. This part may be changed in the future to incorporate an
89
    instruction cache.
90
 
91
    FIXME: Endian correction!
92
    TODO: Modify this for block RAM based instruction cache.
93
    */
94 22 sybreon
   wire [31:0]    wIREG;
95 33 sybreon
   assign        wIREG = iwb_dat_i;
96 25 sybreon
 
97 3 sybreon
   wire [5:0]     wOPC = wIREG[31:26];
98
   wire [4:0]     wRD = wIREG[25:21];
99
   wire [4:0]     wRA = wIREG[20:16];
100
   wire [4:0]     wRB = wIREG[15:11];
101
   wire [15:0]    wIMM = wIREG[15:0];
102 25 sybreon
 
103 3 sybreon
   reg [5:0]      rOPC;
104 25 sybreon
   reg [4:0]      rRD, rRA, rRB;
105 3 sybreon
   reg [15:0]     rIMM;
106 16 sybreon
   reg [5:0]      xOPC;
107 25 sybreon
   reg [4:0]      xRD, xRA, xRB;
108 16 sybreon
   reg [15:0]     xIMM;
109 36 sybreon
 
110
   /*
111
   assign        rOPC = wOPC;
112
   assign        rRA = wRA;
113
   assign        rRB = wRB;
114
   assign        rRD = wRD;
115
   assign        rIMM = wIMM;
116
   */
117 3 sybreon
 
118 16 sybreon
   always @(/*AUTOSENSE*/frun or wIMM or wOPC or wRA or wRB or wRD)
119
     if (frun) begin
120
        xOPC <= wOPC;
121
        xRD <= wRD;
122
        xRA <= wRA;
123
        xRB <= wRB;
124
        xIMM <= wIMM;
125 3 sybreon
     end else begin
126 16 sybreon
        xOPC <= 6'o40;
127 3 sybreon
        /*AUTORESET*/
128
        // Beginning of autoreset for uninitialized flops
129 16 sybreon
        xIMM <= 16'h0;
130
        xRA <= 5'h0;
131
        xRB <= 5'h0;
132
        xRD <= 5'h0;
133 3 sybreon
        // End of automatics
134 16 sybreon
     end // else: !if(frun)
135 3 sybreon
 
136 25 sybreon
   /**
137
    Opcode Groups
138
    -------------
139
    Start decoding by breaking up the opcode into groups. This should
140
    infer a bunch of decoders on appropriate synthesis tools.
141
    */
142 3 sybreon
 
143
   wire          fGH0 = (wOPC[5:3] == 3'o0);
144
   wire          fGH1 = (wOPC[5:3] == 3'o1);
145
   wire          fGH2 = (wOPC[5:3] == 3'o2);
146
   wire          fGH3 = (wOPC[5:3] == 3'o3);
147
   wire          fGH4 = (wOPC[5:3] == 3'o4);
148
   wire          fGH5 = (wOPC[5:3] == 3'o5);
149
   wire          fGH6 = (wOPC[5:3] == 3'o6);
150
   wire          fGH7 = (wOPC[5:3] == 3'o7);
151
   wire          fGL0 = (wOPC[2:0] == 3'o0);
152
   wire          fGL1 = (wOPC[2:0] == 3'o1);
153
   wire          fGL2 = (wOPC[2:0] == 3'o2);
154
   wire          fGL3 = (wOPC[2:0] == 3'o3);
155
   wire          fGL4 = (wOPC[2:0] == 3'o4);
156
   wire          fGL5 = (wOPC[2:0] == 3'o5);
157
   wire          fGL6 = (wOPC[2:0] == 3'o6);
158
   wire          fGL7 = (wOPC[2:0] == 3'o7);
159
 
160 25 sybreon
   /*
161
    Main Decoder
162
    ------------
163
    As there aren't many instruction groups to decode, we will decode
164
    all the instruction families here.
165
    */
166
 
167 3 sybreon
   wire          fADD = ({wOPC[5:4],wOPC[0]} == 3'o0);
168
   wire          fSUB = ({wOPC[5:4],wOPC[0]} == 3'o1);
169
   wire          fLOGIC = ({wOPC[5:4],wOPC[2]} == 3'o4);
170
   wire          fMUL = ({wOPC[5:4]} == 3'o1);
171
 
172
   wire          fLD = ({wOPC[5:4],wOPC[2]} == 3'o6);
173
   wire          fST = ({wOPC[5:4],wOPC[2]} == 3'o7);
174
 
175
   wire          fBCC = (wOPC[5:4] == 2'b10) & fGL7;
176
   wire          fBRU = (wOPC[5:4] == 2'b10) & fGL6;
177
   wire          fBRA = fBRU & wRA[3];
178
 
179
   wire          fSHIFT = fGH4 & fGL4;
180
   wire          fIMM = fGH5 & fGL4;
181
   wire          fRET = fGH5 & fGL5;
182
   wire          fMISC = fGH4 & fGL5;
183
 
184 25 sybreon
   /**
185
    MXALU
186
    -----
187
    This signal controls the MXALU mux inside the ASLU unit.
188
    */
189
 
190 16 sybreon
   reg [1:0]      rMXALU, xMXALU;
191 27 sybreon
   always @(/*AUTOSENSE*/fBRA or fLOGIC or fSHIFT) begin // frun
192
      xMXALU <= //(!fNBR) ? 2'o0 :
193
                (fSHIFT) ? 2'o2 :
194
                (fLOGIC) ? 2'o1 :
195
                (fBRA) ? 2'o3 :
196
                2'o0;
197
   end
198 3 sybreon
 
199 25 sybreon
   /**
200
    BCC/BRA/RET
201
    -----------
202
    This signal controls the associated muxes for BRANCH, DELAY and
203
    LINK operations.
204
    */
205
 
206 16 sybreon
   reg           rMXDLY,rMXLNK,xMXDLY,xMXLNK;
207
   reg [1:0]      rMXBRA,xMXBRA;
208
   always @(/*AUTOSENSE*/fBCC or fBRU or fRET or frun or wRA or wRD)
209
     if (frun) begin
210
        xMXBRA <=  //(!fNBR) ? 2'o0 :
211 3 sybreon
                  (fBCC) ? 2'o3 :
212
                  (fRET) ? 2'o1 :
213
                  (fBRU) ? 2'o2 :
214
                  2'o0;
215 16 sybreon
        xMXDLY <=  //(!fNBR) ? 1'b0 :
216 3 sybreon
                  (fBCC) ? wRD[4] :
217
                  (fRET) ? 1'b1 :
218
                  (fBRU) ? wRA[4] :
219
                  1'b0;
220
     end else begin // if (frun)
221
        /*AUTORESET*/
222
        // Beginning of autoreset for uninitialized flops
223 16 sybreon
        xMXBRA <= 2'h0;
224
        xMXDLY <= 1'h0;
225 3 sybreon
        // End of automatics
226 16 sybreon
     end // else: !if(frun)
227 27 sybreon
 
228
   always @(/*AUTOSENSE*/fBRU or wRA) begin
229
      xMXLNK <=  //(!fNBR) ? 1'b0 :
230
                 (fBRU) ? wRA[2] : 1'b0;
231
   end
232 3 sybreon
 
233 25 sybreon
   /**
234
    LD/ST
235
    -----
236
    This signal controls the mux that controls the LOAD and STORE
237
    operations.
238
    */
239
 
240 16 sybreon
   reg [1:0]       rMXLDST,xMXLDST;
241
   always @(/*AUTOSENSE*/fLD or fST or frun)
242
     if (frun) begin
243
        xMXLDST <= //(!fNBR) ? 2'o0 :
244 3 sybreon
                   (fLD) ? 2'o2 :
245
                   (fST) ? 2'o3 :
246
                   2'o0;
247
     end else begin
248 27 sybreon
        /*UTORESET*/
249 3 sybreon
        // Beginning of autoreset for uninitialized flops
250 16 sybreon
        xMXLDST <= 2'h0;
251 3 sybreon
        // End of automatics
252 16 sybreon
     end // else: !if(frun)
253 3 sybreon
 
254 25 sybreon
   /**
255
    SRC/TGT
256
    -------
257
    Controls the muxes that select the appropriate sources for the A,
258 27 sybreon
    B and D operands. All data hazards are resolved here.
259 25 sybreon
    */
260
 
261 16 sybreon
   reg [1:0]       rMXSRC, rMXTGT, rMXALT, xMXSRC,xMXTGT,xMXALT;
262 33 sybreon
   wire           fRWE = (|rRD) & !(&rMXBRA) & !(|rMXLDST);
263 27 sybreon
 
264
   always @(/*AUTOSENSE*/fBCC or fBRU or fRWE or rMXLDST or rRD
265
            or wOPC or wRA or wRB) begin // frun
266
      xMXSRC <= //(!fNBR) ? 2'o0 :
267
                (fBRU|fBCC) ? 2'o1 : // PC
268
                ((rRD == wRA) & (rMXLDST == 2'o2)) ? 2'o3 : // DWB
269
                ((rRD == wRA) & fRWE) ? 2'o2 : // FWD
270
                2'o0; // RA
271
      xMXTGT <= //(!fNBR) ? 2'o0 :
272
                (wOPC[3]) ? 2'o1 : // IMM
273
                ((rRD == wRB) & (rMXLDST == 2'o2)) ? 2'o3 : // DWB
274
                ((rRD == wRB) & fRWE) ? 2'o2 : // FWD
275
                2'o0;   // RB
276
      xMXALT <= //(!fNBR) ? 2'o0 :
277
                //(fBRU|fBCC) ? 2'o1 : // PC
278
                ((rRD == wRA) & (rMXLDST == 2'o2)) ? 2'o3 : // DWB
279
                ((rRD == wRA) & fRWE) ? 2'o2 : // FWD
280
                2'o0; // RA
281
   end // always @ (...
282 3 sybreon
 
283 25 sybreon
   /**
284
    IMM Latching
285
    ------------
286
    The logic to generate either a full 32-bit or sign extended 32-bit
287
    immediate is done here.
288
    */
289
 
290 16 sybreon
   reg [31:0]     rSIMM, xSIMM;
291
   reg [15:0]     rIMMHI, xIMMHI;
292
   reg           rFIMM, xFIMM;
293 27 sybreon
 
294
   always @(/*AUTOSENSE*/fIMM or rFIMM or rIMMHI or wIMM) begin // frun
295
      xSIMM <= (rFIMM) ? {rIMMHI,wIMM} : {{(16){wIMM[15]}},wIMM};
296
      xFIMM <= fIMM;
297
      xIMMHI <= (fIMM) ? wIMM : rIMMHI;
298
   end
299 3 sybreon
 
300 25 sybreon
   /**
301
    COMPARATOR
302
    ----------
303
    This performs the comparison for conditional branches. It handles
304
    the necessary data hazards. It generates a branch flag that is
305
    used by the execution stage.
306
    */
307
 
308 3 sybreon
   wire [31:0] wREGA =
309 25 sybreon
               (rMXALT == 2'o3) ? sDWBDAT :
310 3 sybreon
               (rMXALT == 2'o2) ? rRESULT :
311
               rREGA;
312
 
313
   wire        wBEQ = (wREGA == 32'd0);
314
   wire        wBNE = ~wBEQ;
315
   wire        wBLT = wREGA[31];
316
   wire        wBLE = wBLT | wBEQ;
317
   wire        wBGE = ~wBLT;
318
   wire        wBGT = ~wBLE;
319
 
320
   reg         rBCC;
321
   always @(/*AUTOSENSE*/rRD or wBEQ or wBGE or wBGT or wBLE or wBLT
322
            or wBNE)
323
     case (rRD[2:0])
324 16 sybreon
       3'o0: rBCC <= wBEQ;
325
       3'o1: rBCC <= wBNE;
326
       3'o2: rBCC <= wBLT;
327
       3'o3: rBCC <= wBLE;
328
       3'o4: rBCC <= wBGT;
329
       3'o5: rBCC <= wBGE;
330 3 sybreon
       default: rBCC <= 1'b0;
331 16 sybreon
     endcase // case (rRD[2:0])
332 3 sybreon
 
333 25 sybreon
   /**
334
    Branch Signals
335
    --------------
336
    This controls the generation of the BRANCH, DELAY and LINK
337
    signals.
338
    */
339
 
340 16 sybreon
   reg         rBRA, rDLY, rLNK, xBRA, xDLY, xLNK;
341
   always @(/*AUTOSENSE*/drun or rBCC or rMXBRA or rMXDLY or rMXLNK)
342
     if (drun) begin
343 3 sybreon
        case (rMXBRA)
344 16 sybreon
          2'o0: xBRA <= 1'b0;
345
          2'o3: xBRA <= rBCC;
346
          default: xBRA <= 1'b1;
347
        endcase // case (rMXBRA)
348 3 sybreon
 
349
        case (rMXBRA)
350 16 sybreon
          2'o0: xDLY <= 1'b0;
351
          2'o3: xDLY <= rBCC & rMXDLY;
352
          default: xDLY <= rMXDLY;
353
        endcase // case (rMXBRA)
354 3 sybreon
 
355
        case (rMXBRA)
356 16 sybreon
          2'o2: xLNK <= rMXLNK;
357
          default: xLNK <= 1'b0;
358
        endcase // case (rMXBRA)
359 3 sybreon
     end else begin // if (drun)
360
        /*AUTORESET*/
361
        // Beginning of autoreset for uninitialized flops
362 16 sybreon
        xBRA <= 1'h0;
363
        xDLY <= 1'h0;
364
        xLNK <= 1'h0;
365 3 sybreon
        // End of automatics
366 16 sybreon
     end // else: !if(drun)
367 3 sybreon
 
368 25 sybreon
   /**
369
    MXRWE
370
    -----
371
    This signal controls the flag that determines whether a D register
372
    is open for writing.
373
    */
374 27 sybreon
 
375 16 sybreon
   reg           rRWE, xRWE;
376 25 sybreon
   wire          wRWE = |rRD;
377 16 sybreon
   always @(/*AUTOSENSE*/drun or rMXBRA or rMXLDST or wRWE)
378
     if (drun) begin
379 3 sybreon
        case (rMXBRA)
380 16 sybreon
          default: xRWE <= 1'b0;
381
          2'o2: xRWE <= wRWE ^ rMXLDST[0];
382
          2'o0: xRWE <= wRWE;
383
        endcase // case (rMXBRA)
384 3 sybreon
     end else begin
385
        /*AUTORESET*/
386
        // Beginning of autoreset for uninitialized flops
387 16 sybreon
        xRWE <= 1'h0;
388 3 sybreon
        // End of automatics
389 16 sybreon
     end // else: !if(drun)
390 3 sybreon
 
391 25 sybreon
   /**
392
    Data WISHBONE Bus
393
    -----------------
394
    The STB and WE signals for the DWB are decoded here depending on
395
    the LOAD/STORE control signal.
396
    */
397
 
398 16 sybreon
   reg rDWBSTB, rDWBWE, xDWBSTB, xDWBWE;
399 3 sybreon
   assign dwb_stb_o = rDWBSTB;
400
   assign dwb_we_o = rDWBWE;
401
 
402 16 sybreon
   always @(/*AUTOSENSE*/drun or rMXLDST)
403
     if (drun) begin
404
        xDWBSTB <= rMXLDST[1];
405
        xDWBWE <= rMXLDST[0];
406
     end else begin
407 3 sybreon
        /*AUTORESET*/
408
        // Beginning of autoreset for uninitialized flops
409 16 sybreon
        xDWBSTB <= 1'h0;
410
        xDWBWE <= 1'h0;
411 3 sybreon
        // End of automatics
412 16 sybreon
     end
413
 
414
   // PIPELINE REGISTERS ///////////////////////////////////////////////
415
 
416 36 sybreon
   always @(negedge nclk)
417
     if (prst) begin
418 27 sybreon
        //rOPC <= 6'o40;        
419 3 sybreon
        /*AUTORESET*/
420
        // Beginning of autoreset for uninitialized flops
421 25 sybreon
        rBRA <= 1'h0;
422
        rDLY <= 1'h0;
423
        rDWBSTB <= 1'h0;
424
        rDWBWE <= 1'h0;
425 16 sybreon
        rFIMM <= 1'h0;
426
        rIMM <= 16'h0;
427
        rIMMHI <= 16'h0;
428 25 sybreon
        rLNK <= 1'h0;
429 16 sybreon
        rMXALT <= 2'h0;
430
        rMXALU <= 2'h0;
431
        rMXBRA <= 2'h0;
432
        rMXDLY <= 1'h0;
433
        rMXLDST <= 2'h0;
434
        rMXLNK <= 1'h0;
435
        rMXSRC <= 2'h0;
436
        rMXTGT <= 2'h0;
437 27 sybreon
        rOPC <= 6'h0;
438 16 sybreon
        rRA <= 5'h0;
439
        rRB <= 5'h0;
440
        rRD <= 5'h0;
441 25 sybreon
        rRWE <= 1'h0;
442 16 sybreon
        rSIMM <= 32'h0;
443
        // End of automatics
444 36 sybreon
     end else if (prun) begin // if (prst)
445 16 sybreon
        rIMM <= #1 xIMM;
446
        rOPC <= #1 xOPC;
447
        rRA <= #1 xRA;
448
        rRB <= #1 xRB;
449
        rRD <= #1 xRD;
450
 
451
        rMXALU <= #1 xMXALU;
452
        rMXBRA <= #1 xMXBRA;
453
        rMXDLY <= #1 xMXDLY;
454
        rMXLNK <= #1 xMXLNK;
455
        rMXLDST <= #1 xMXLDST;
456
 
457
        rMXSRC <= #1 xMXSRC;
458
        rMXTGT <= #1 xMXTGT;
459
        rMXALT <= #1 xMXALT;
460
 
461
        rSIMM <= #1 xSIMM;
462
        rFIMM <= #1 xFIMM;
463
        rIMMHI <= #1 xIMMHI;
464
 
465
        rBRA <= #1 xBRA;
466
        rDLY <= #1 xDLY;
467
        rLNK <= #1 xLNK;
468
        rRWE <= #1 xRWE;
469
        rDWBSTB <= #1 xDWBSTB;
470
        rDWBWE <= #1 xDWBWE;
471 36 sybreon
     end // if (prun)
472 3 sybreon
 
473
endmodule // aeMB_decode
474
 
475
// Local Variables:
476
// verilog-library-directories:(".")
477
// verilog-library-files:("")
478
// End:

powered by: WebSVN 2.1.0

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