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

Subversion Repositories aemb

[/] [aemb/] [tags/] [AEMB_711/] [rtl/] [verilog/] [aeMB_xecu.v] - Blame information for rev 191

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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