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

Subversion Repositories aemb

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

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

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

powered by: WebSVN 2.1.0

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