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

Subversion Repositories aemb

[/] [aemb/] [trunk/] [rtl/] [verilog/] [aeMB_xecu.v] - Blame information for rev 200

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

Line No. Rev Author Line
1 159 sybreon
/* $Id: aeMB_xecu.v,v 1.12 2008-05-11 13:48:46 sybreon Exp $
2 96 sybreon
**
3
** AEMB MAIN EXECUTION ALU
4
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
5
**
6
** This file is part of AEMB.
7
**
8
** AEMB is free software: you can redistribute it and/or modify it
9
** under the terms of the GNU Lesser General Public License as
10
** published by the Free Software Foundation, either version 3 of the
11
** License, or (at your option) any later version.
12
**
13
** AEMB is distributed in the hope that it will be useful, but WITHOUT
14
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
16
** Public License for more details.
17
**
18
** You should have received a copy of the GNU Lesser General Public
19
** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
20
*/
21 41 sybreon
 
22
module aeMB_xecu (/*AUTOARG*/
23
   // Outputs
24 66 sybreon
   dwb_adr_o, dwb_sel_o, fsl_adr_o, fsl_tag_o, rRESULT, rDWBSEL,
25
   rMSR_IE, rMSR_BIP,
26 41 sybreon
   // Inputs
27 61 sybreon
   rREGA, rREGB, rMXSRC, rMXTGT, rRA, rRB, rMXALU, rBRA, rDLY, rALT,
28 96 sybreon
   rSTALL, rSIMM, rIMM, rOPC, rRD, rDWBDI, rPC, gclk, grst, gena
29 41 sybreon
   );
30
   parameter DW=32;
31 50 sybreon
 
32
   parameter MUL=0;
33
   parameter BSF=0;
34 41 sybreon
 
35
   // DATA WISHBONE
36
   output [DW-1:2] dwb_adr_o;
37
   output [3:0]    dwb_sel_o;
38 53 sybreon
 
39
   // FSL WISHBONE
40 66 sybreon
   output [6:2]   fsl_adr_o;
41
   output [1:0]   fsl_tag_o;
42 41 sybreon
 
43
   // INTERNAL
44
   output [31:0]   rRESULT;
45
   output [3:0]    rDWBSEL;
46 44 sybreon
   output          rMSR_IE;
47
   output          rMSR_BIP;
48 41 sybreon
   input [31:0]    rREGA, rREGB;
49
   input [1:0]      rMXSRC, rMXTGT;
50 53 sybreon
   input [4:0]      rRA, rRB;
51 41 sybreon
   input [2:0]      rMXALU;
52
   input           rBRA, rDLY;
53 50 sybreon
   input [10:0]    rALT;
54 96 sybreon
 
55
   input           rSTALL;
56 41 sybreon
   input [31:0]    rSIMM;
57
   input [15:0]    rIMM;
58
   input [5:0]      rOPC;
59
   input [4:0]      rRD;
60
   input [31:0]    rDWBDI;
61
   input [31:2]    rPC;
62
 
63
   // SYSTEM
64
   input           gclk, grst, gena;
65
 
66
   reg             rMSR_C, xMSR_C;
67
   reg             rMSR_IE, xMSR_IE;
68 44 sybreon
   reg             rMSR_BE, xMSR_BE;
69
   reg             rMSR_BIP, xMSR_BIP;
70 41 sybreon
 
71 44 sybreon
   wire            fSKIP = rBRA & !rDLY;
72
 
73 41 sybreon
   // --- OPERAND SELECT
74
 
75
   reg [31:0]       rOPA, rOPB;
76
   always @(/*AUTOSENSE*/rDWBDI or rMXSRC or rPC or rREGA or rRESULT)
77
     case (rMXSRC)
78
       2'o0: rOPA <= rREGA;
79
       2'o1: rOPA <= rRESULT;
80
       2'o2: rOPA <= rDWBDI;
81
       2'o3: rOPA <= {rPC, 2'o0};
82
     endcase // case (rMXSRC)
83
 
84
   always @(/*AUTOSENSE*/rDWBDI or rMXTGT or rREGB or rRESULT or rSIMM)
85
     case (rMXTGT)
86
       2'o0: rOPB <= rREGB;
87
       2'o1: rOPB <= rRESULT;
88
       2'o2: rOPB <= rDWBDI;
89
       2'o3: rOPB <= rSIMM;
90
     endcase // case (rMXTGT)
91
 
92 44 sybreon
   // --- ADD/SUB SELECTOR ----
93 159 sybreon
 
94
   reg              rRES_ADDC;
95
   reg [31:0]        rRES_ADD;
96 44 sybreon
 
97 159 sybreon
   wire [31:0]           wADD;
98
   wire                 wADC;
99
 
100
   wire                 fCCC = !rOPC[5] & rOPC[1]; // & !rOPC[4]
101
   wire                 fSUB = !rOPC[5] & rOPC[0]; // & !rOPC[4]
102
   wire                 fCMP = !rOPC[3] & rIMM[1]; // unsigned only
103
   wire                 wCMP = (fCMP) ? !wADC : wADD[31]; // cmpu adjust
104 44 sybreon
 
105 159 sybreon
   wire [31:0]           wOPA = (fSUB) ? ~rOPA : rOPA;
106
   wire                 wOPC = (fCCC) ? rMSR_C : fSUB;
107 44 sybreon
 
108 159 sybreon
   assign               {wADC, wADD} = (rOPB + wOPA) + wOPC; // add carry
109 44 sybreon
 
110 159 sybreon
   always @(/*AUTOSENSE*/wADC or wADD or wCMP) begin
111
      {rRES_ADDC, rRES_ADD} <= #1 {wADC, wCMP, wADD[30:0]}; // add with carry
112
   end
113
 
114 50 sybreon
   // --- LOGIC SELECTOR --------------------------------------
115 41 sybreon
 
116
   reg [31:0]        rRES_LOG;
117
   always @(/*AUTOSENSE*/rOPA or rOPB or rOPC)
118
     case (rOPC[1:0])
119
       2'o0: rRES_LOG <= #1 rOPA | rOPB;
120
       2'o1: rRES_LOG <= #1 rOPA & rOPB;
121
       2'o2: rRES_LOG <= #1 rOPA ^ rOPB;
122
       2'o3: rRES_LOG <= #1 rOPA & ~rOPB;
123
     endcase // case (rOPC[1:0])
124
 
125 50 sybreon
   // --- SHIFTER SELECTOR ------------------------------------
126 41 sybreon
 
127
   reg [31:0]        rRES_SFT;
128
   reg              rRES_SFTC;
129
 
130
   always @(/*AUTOSENSE*/rIMM or rMSR_C or rOPA)
131
     case (rIMM[6:5])
132
       2'o0: {rRES_SFT, rRES_SFTC} <= #1 {rOPA[31],rOPA[31:0]};
133
       2'o1: {rRES_SFT, rRES_SFTC} <= #1 {rMSR_C,rOPA[31:0]};
134
       2'o2: {rRES_SFT, rRES_SFTC} <= #1 {1'b0,rOPA[31:0]};
135
       2'o3: {rRES_SFT, rRES_SFTC} <= #1 (rIMM[0]) ? { {(16){rOPA[15]}}, rOPA[15:0], rMSR_C} :
136
                                      { {(24){rOPA[7]}}, rOPA[7:0], rMSR_C};
137
     endcase // case (rIMM[6:5])
138
 
139 50 sybreon
   // --- MOVE SELECTOR ---------------------------------------
140 41 sybreon
 
141 44 sybreon
   wire [31:0]       wMSR = {rMSR_C, 3'o0,
142
                            20'h0ED32,
143
                            4'h0, rMSR_BIP, rMSR_C, rMSR_IE, rMSR_BE};
144 41 sybreon
   wire             fMFSR = (rOPC == 6'o45) & !rIMM[14] & rIMM[0];
145
   wire             fMFPC = (rOPC == 6'o45) & !rIMM[14] & !rIMM[0];
146
   reg [31:0]        rRES_MOV;
147
   always @(/*AUTOSENSE*/fMFPC or fMFSR or rOPA or rOPB or rPC or rRA
148
            or wMSR)
149
     rRES_MOV <= (fMFSR) ? wMSR :
150
                 (fMFPC) ? rPC :
151
                 (rRA[3]) ? rOPB :
152
                 rOPA;
153
 
154 50 sybreon
   // --- MULTIPLIER ------------------------------------------
155 72 sybreon
   // TODO: 2 stage multiplier
156
 
157 96 sybreon
   reg [31:0]        rRES_MUL, rRES_MUL0, xRES_MUL;
158 50 sybreon
   always @(/*AUTOSENSE*/rOPA or rOPB) begin
159 96 sybreon
      xRES_MUL <= (rOPA * rOPB);
160 50 sybreon
   end
161
 
162 96 sybreon
   always @(posedge gclk)
163
     if (grst) begin
164
        /*AUTORESET*/
165
        // Beginning of autoreset for uninitialized flops
166
        rRES_MUL <= 32'h0;
167
        // End of automatics
168
     end else if (rSTALL) begin
169
        rRES_MUL <= #1 xRES_MUL;
170
     end
171
 
172
 
173 50 sybreon
   // --- BARREL SHIFTER --------------------------------------
174
 
175
   reg [31:0]     rRES_BSF;
176
   reg [31:0]     xBSRL, xBSRA, xBSLL;
177 41 sybreon
 
178 50 sybreon
   // Infer a logical left barrel shifter.   
179
   always @(/*AUTOSENSE*/rOPA or rOPB)
180
     xBSLL <= rOPA << rOPB[4:0];
181
 
182
   // Infer a logical right barrel shifter.
183
   always @(/*AUTOSENSE*/rOPA or rOPB)
184
     xBSRL <= rOPA >> rOPB[4:0];
185
 
186
   // Infer a arithmetic right barrel shifter.
187
   always @(/*AUTOSENSE*/rOPA or rOPB)
188
     case (rOPB[4:0])
189
       5'd00: xBSRA <= rOPA;
190
       5'd01: xBSRA <= {{(1){rOPA[31]}}, rOPA[31:1]};
191
       5'd02: xBSRA <= {{(2){rOPA[31]}}, rOPA[31:2]};
192
       5'd03: xBSRA <= {{(3){rOPA[31]}}, rOPA[31:3]};
193
       5'd04: xBSRA <= {{(4){rOPA[31]}}, rOPA[31:4]};
194
       5'd05: xBSRA <= {{(5){rOPA[31]}}, rOPA[31:5]};
195
       5'd06: xBSRA <= {{(6){rOPA[31]}}, rOPA[31:6]};
196
       5'd07: xBSRA <= {{(7){rOPA[31]}}, rOPA[31:7]};
197
       5'd08: xBSRA <= {{(8){rOPA[31]}}, rOPA[31:8]};
198
       5'd09: xBSRA <= {{(9){rOPA[31]}}, rOPA[31:9]};
199
       5'd10: xBSRA <= {{(10){rOPA[31]}}, rOPA[31:10]};
200
       5'd11: xBSRA <= {{(11){rOPA[31]}}, rOPA[31:11]};
201
       5'd12: xBSRA <= {{(12){rOPA[31]}}, rOPA[31:12]};
202
       5'd13: xBSRA <= {{(13){rOPA[31]}}, rOPA[31:13]};
203
       5'd14: xBSRA <= {{(14){rOPA[31]}}, rOPA[31:14]};
204
       5'd15: xBSRA <= {{(15){rOPA[31]}}, rOPA[31:15]};
205
       5'd16: xBSRA <= {{(16){rOPA[31]}}, rOPA[31:16]};
206
       5'd17: xBSRA <= {{(17){rOPA[31]}}, rOPA[31:17]};
207
       5'd18: xBSRA <= {{(18){rOPA[31]}}, rOPA[31:18]};
208
       5'd19: xBSRA <= {{(19){rOPA[31]}}, rOPA[31:19]};
209
       5'd20: xBSRA <= {{(20){rOPA[31]}}, rOPA[31:20]};
210
       5'd21: xBSRA <= {{(21){rOPA[31]}}, rOPA[31:21]};
211
       5'd22: xBSRA <= {{(22){rOPA[31]}}, rOPA[31:22]};
212
       5'd23: xBSRA <= {{(23){rOPA[31]}}, rOPA[31:23]};
213
       5'd24: xBSRA <= {{(24){rOPA[31]}}, rOPA[31:24]};
214
       5'd25: xBSRA <= {{(25){rOPA[31]}}, rOPA[31:25]};
215
       5'd26: xBSRA <= {{(26){rOPA[31]}}, rOPA[31:26]};
216
       5'd27: xBSRA <= {{(27){rOPA[31]}}, rOPA[31:27]};
217
       5'd28: xBSRA <= {{(28){rOPA[31]}}, rOPA[31:28]};
218
       5'd29: xBSRA <= {{(29){rOPA[31]}}, rOPA[31:29]};
219
       5'd30: xBSRA <= {{(30){rOPA[31]}}, rOPA[31:30]};
220
       5'd31: xBSRA <= {{(31){rOPA[31]}}, rOPA[31]};
221
     endcase // case (rOPB[4:0])
222
 
223 96 sybreon
   reg [31:0]     rBSRL, rBSRA, rBSLL;
224
 
225
   always @(posedge gclk)
226
     if (grst) begin
227
        /*AUTORESET*/
228
        // Beginning of autoreset for uninitialized flops
229
        rBSLL <= 32'h0;
230
        rBSRA <= 32'h0;
231
        rBSRL <= 32'h0;
232
        // End of automatics
233
     end else if (rSTALL) begin
234
        rBSRL <= #1 xBSRL;
235
        rBSRA <= #1 xBSRA;
236
        rBSLL <= #1 xBSLL;
237
     end
238
 
239
   always @(/*AUTOSENSE*/rALT or rBSLL or rBSRA or rBSRL)
240 50 sybreon
     case (rALT[10:9])
241 96 sybreon
       2'd0: rRES_BSF <= rBSRL;
242
       2'd1: rRES_BSF <= rBSRA;
243
       2'd2: rRES_BSF <= rBSLL;
244 50 sybreon
       default: rRES_BSF <= 32'hX;
245
     endcase // case (rALT[10:9])
246
 
247
 
248 44 sybreon
   // --- MSR REGISTER -----------------
249 41 sybreon
 
250 44 sybreon
   // C
251 102 sybreon
   wire            fMTS = (rOPC == 6'o45) & rIMM[14] & !fSKIP;
252 44 sybreon
   wire            fADDC = ({rOPC[5:4], rOPC[2]} == 3'o0);
253 41 sybreon
 
254 44 sybreon
   always @(/*AUTOSENSE*/fADDC or fMTS or fSKIP or rMSR_C or rMXALU
255 61 sybreon
            or rOPA or rRES_ADDC or rRES_SFTC)
256
     //if (fSKIP | |rXCE) begin
257
     if (fSKIP) begin
258 44 sybreon
        xMSR_C <= rMSR_C;
259
     end else
260
       case (rMXALU)
261
         3'o0: xMSR_C <= (fADDC) ? rRES_ADDC : rMSR_C;
262
         3'o1: xMSR_C <= rMSR_C; // LOGIC       
263
         3'o2: xMSR_C <= rRES_SFTC; // SHIFT
264
         3'o3: xMSR_C <= (fMTS) ? rOPA[2] : rMSR_C;
265
         3'o4: xMSR_C <= rMSR_C;
266
         3'o5: xMSR_C <= rMSR_C;
267
         default: xMSR_C <= 1'hX;
268 102 sybreon
       endcase // case (rMXALU)
269 44 sybreon
 
270
   // IE/BIP/BE
271 102 sybreon
   wire             fRTID = (rOPC == 6'o55) & rRD[0] & !fSKIP;
272
   wire             fRTBD = (rOPC == 6'o55) & rRD[1] & !fSKIP;
273 61 sybreon
   wire             fBRK = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hC);
274 72 sybreon
   wire             fINT = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hE);
275 41 sybreon
 
276 72 sybreon
   always @(/*AUTOSENSE*/fINT or fMTS or fRTID or rMSR_IE or rOPA)
277
     xMSR_IE <= (fINT) ? 1'b0 :
278 44 sybreon
                (fRTID) ? 1'b1 :
279
                (fMTS) ? rOPA[1] :
280
                rMSR_IE;
281 41 sybreon
 
282 44 sybreon
   always @(/*AUTOSENSE*/fBRK or fMTS or fRTBD or rMSR_BIP or rOPA)
283
     xMSR_BIP <= (fBRK) ? 1'b1 :
284
                 (fRTBD) ? 1'b0 :
285
                 (fMTS) ? rOPA[3] :
286
                 rMSR_BIP;
287
 
288
   always @(/*AUTOSENSE*/fMTS or rMSR_BE or rOPA)
289
     xMSR_BE <= (fMTS) ? rOPA[0] : rMSR_BE;
290
 
291 50 sybreon
   // --- RESULT SELECTOR -------------------------------------------
292
   // Selects results from functional units. 
293 41 sybreon
   reg [31:0]       rRESULT, xRESULT;
294
 
295
   // RESULT
296
   always @(/*AUTOSENSE*/fSKIP or rMXALU or rRES_ADD or rRES_BSF
297
            or rRES_LOG or rRES_MOV or rRES_MUL or rRES_SFT)
298
     if (fSKIP)
299
       /*AUTORESET*/
300
       // Beginning of autoreset for uninitialized flops
301
       xRESULT <= 32'h0;
302
       // End of automatics
303
     else
304
       case (rMXALU)
305
         3'o0: xRESULT <= rRES_ADD;
306
         3'o1: xRESULT <= rRES_LOG;
307
         3'o2: xRESULT <= rRES_SFT;
308
         3'o3: xRESULT <= rRES_MOV;
309 50 sybreon
         3'o4: xRESULT <= (MUL) ? rRES_MUL : 32'hX;
310
         3'o5: xRESULT <= (BSF) ? rRES_BSF : 32'hX;
311 41 sybreon
         default: xRESULT <= 32'hX;
312
       endcase // case (rMXALU)
313
 
314
   // --- DATA WISHBONE -----
315
 
316
   reg [3:0]         rDWBSEL, xDWBSEL;
317
   assign           dwb_adr_o = rRESULT[DW-1:2];
318
   assign           dwb_sel_o = rDWBSEL;
319
 
320
   always @(/*AUTOSENSE*/rOPC or wADD)
321
     case (rOPC[1:0])
322 53 sybreon
       2'o0: case (wADD[1:0]) // 8'bit
323 41 sybreon
               2'o0: xDWBSEL <= 4'h8;
324
               2'o1: xDWBSEL <= 4'h4;
325
               2'o2: xDWBSEL <= 4'h2;
326
               2'o3: xDWBSEL <= 4'h1;
327
             endcase // case (wADD[1:0])
328 53 sybreon
       2'o1: xDWBSEL <= (wADD[1]) ? 4'h3 : 4'hC; // 16'bit
329
       2'o2: xDWBSEL <= 4'hF; // 32'bit
330
       2'o3: xDWBSEL <= 4'h0; // FSL
331 41 sybreon
     endcase // case (rOPC[1:0])
332 53 sybreon
 
333
   // --- FSL WISHBONE --------------------
334
 
335
   reg [14:2]       rFSLADR, xFSLADR;
336 41 sybreon
 
337 66 sybreon
   assign           {fsl_adr_o, fsl_tag_o} = rFSLADR[8:2];
338 53 sybreon
 
339
   always @(/*AUTOSENSE*/rALT or rRB) begin
340
      xFSLADR <= {rALT, rRB[3:2]};
341
   end
342
 
343 41 sybreon
   // --- SYNC ---
344
 
345
   always @(posedge gclk)
346
     if (grst) begin
347
        /*AUTORESET*/
348
        // Beginning of autoreset for uninitialized flops
349
        rDWBSEL <= 4'h0;
350 53 sybreon
        rFSLADR <= 13'h0;
351 44 sybreon
        rMSR_BE <= 1'h0;
352
        rMSR_BIP <= 1'h0;
353 41 sybreon
        rMSR_C <= 1'h0;
354 44 sybreon
        rMSR_IE <= 1'h0;
355 41 sybreon
        rRESULT <= 32'h0;
356
        // End of automatics
357 102 sybreon
     end else if (gena) begin // if (grst)
358 41 sybreon
        rRESULT <= #1 xRESULT;
359
        rDWBSEL <= #1 xDWBSEL;
360
        rMSR_C <= #1 xMSR_C;
361
        rMSR_IE <= #1 xMSR_IE;
362 44 sybreon
        rMSR_BE <= #1 xMSR_BE;
363 53 sybreon
        rMSR_BIP <= #1 xMSR_BIP;
364 96 sybreon
        rFSLADR <= #1 xFSLADR;
365 41 sybreon
     end
366 72 sybreon
 
367 41 sybreon
endmodule // aeMB_xecu
368 96 sybreon
 
369
/*
370
 $Log: not supported by cvs2svn $
371 159 sybreon
 Revision 1.11  2008/01/19 15:57:36  sybreon
372
 Fix MTS during interrupt vectoring bug (reported by M. Ettus).
373
 
374 102 sybreon
 Revision 1.10  2007/12/25 22:15:09  sybreon
375
 Stalls pipeline on MUL/BSF instructions results in minor speed improvements.
376
 
377 96 sybreon
 Revision 1.9  2007/11/30 16:42:51  sybreon
378
 Minor code cleanup.
379
 
380
 Revision 1.8  2007/11/16 21:52:03  sybreon
381
 Added fsl_tag_o to FSL bus (tag either address or data).
382
 
383
 Revision 1.7  2007/11/14 22:14:34  sybreon
384
 Changed interrupt handling system (reported by M. Ettus).
385
 
386
 Revision 1.6  2007/11/10 16:39:38  sybreon
387
 Upgraded license to LGPLv3.
388
 Significant performance optimisations.
389
 
390
 Revision 1.5  2007/11/09 20:51:52  sybreon
391
 Added GET/PUT support through a FSL bus.
392
 
393
 Revision 1.4  2007/11/08 14:17:47  sybreon
394
 Parameterised optional components.
395
 
396
 Revision 1.3  2007/11/03 08:34:55  sybreon
397
 Minor code cleanup.
398
 
399
 Revision 1.2  2007/11/02 19:20:58  sybreon
400
 Added better (beta) interrupt support.
401
 Changed MSR_IE to disabled at reset as per MB docs.
402
 
403
 Revision 1.1  2007/11/02 03:25:41  sybreon
404
 New EDK 3.2 compatible design with optional barrel-shifter and multiplier.
405
 Fixed various minor data hazard bugs.
406
 Code compatible with -O0/1/2/3/s generated code.
407
 
408
*/

powered by: WebSVN 2.1.0

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