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

Subversion Repositories aemb

[/] [aemb/] [trunk/] [rtl/] [verilog/] [aeMB2_intu.v] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 158 sybreon
/* $Id: aeMB2_intu.v,v 1.7 2008-05-01 12:00:18 sybreon Exp $
2 118 sybreon
**
3
** AEMB2 EDK 6.2 COMPATIBLE CORE
4
** Copyright (C) 2004-2008 Shawn Tan <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
/**
22
 * One Cycle Integer Unit
23
 * @file aeMB2_intu.v
24
 
25
 * This implements a single cycle integer unit. It performs all basic
26
   arithmetic, shift, and logic operations.
27
 
28
 */
29
 
30
module aeMB2_intu (/*AUTOARG*/
31
   // Outputs
32
   mem_ex, bpc_ex, alu_ex, alu_mx, msr_ex, sfr_mx,
33
   // Inputs
34 209 sybreon
   exc_dwb, exc_ill, rpc_ex, opc_of, opa_of, opb_of, opd_of, imm_of,
35
   rd_of, ra_of, gclk, grst, dena, gpha
36 118 sybreon
   );
37
   parameter AEMB_DWB = 32;
38
   parameter AEMB_IWB = 32;
39
   parameter AEMB_HTX = 1;
40
 
41
   output [31:2] mem_ex;
42
   output [31:2] bpc_ex;
43
 
44
   output [31:0] alu_ex,
45
                 alu_mx;
46 205 sybreon
 
47 209 sybreon
   input [1:0]    exc_dwb;
48
   input         exc_ill;
49
 
50
   input [31:2]  rpc_ex;
51
 
52 150 sybreon
   //input [2:0]         mux_of;   
53 118 sybreon
   input [5:0]    opc_of;
54
   input [31:0]  opa_of;
55
   input [31:0]  opb_of;
56
   input [31:0]  opd_of;
57
   input [15:0]  imm_of;
58
   input [4:0]    rd_of,
59
                 ra_of;
60 204 sybreon
   output [9:0]  msr_ex;
61 118 sybreon
   output [31:0] sfr_mx;
62
 
63
   // SYS signals
64
   input         gclk,
65
                 grst,
66
                 dena,
67
                 gpha;
68
 
69
   /*AUTOREG*/
70
   // Beginning of automatic regs (for this module's undeclared outputs)
71
   reg [31:0]            alu_ex;
72
   reg [31:0]            alu_mx;
73
   reg [31:2]           bpc_ex;
74
   reg [31:2]           mem_ex;
75
   reg [31:0]            sfr_mx;
76
   // End of automatics
77
 
78 150 sybreon
   localparam [2:0]      MUX_SFR = 3'o7,
79
                        MUX_BSF = 3'o6,
80
                        MUX_MUL = 3'o5,
81
                        MUX_MEM = 3'o4,
82
 
83
                        MUX_RPC = 3'o2,
84
                        MUX_ALU = 3'o1,
85
                        MUX_NOP = 3'o0;
86
 
87 118 sybreon
   reg                  rMSR_C,
88 204 sybreon
                        rMSR_EE,
89
                        rMSR_EIP,
90 118 sybreon
                        rMSR_CC,
91
                        rMSR_MTX,
92 150 sybreon
                        rMSR_DTE,
93
                        rMSR_ITE,
94 118 sybreon
                        rMSR_BIP,
95
                        rMSR_IE,
96
                        rMSR_BE;
97 134 sybreon
 
98 209 sybreon
   reg [31:0]            rEAR,
99
                        rEAR_C;
100
   reg [1:0]             rESR,
101
                        rESR_C;
102
 
103 150 sybreon
   // Infer a ADD with carry cell because ADDSUB cannot be inferred
104
   // across technologies.
105 118 sybreon
 
106
   reg [31:0]            add_ex;
107
   reg                  add_c;
108 131 sybreon
 
109 125 sybreon
   wire [31:0]           wADD;
110
   wire                 wADC;
111 118 sybreon
 
112 150 sybreon
   wire                 fCCC = !opc_of[5] & opc_of[1]; // & !opc_of[4]
113
   wire                 fSUB = !opc_of[5] & opc_of[0]; // & !opc_of[4]
114 158 sybreon
   wire                 fCMP = !opc_of[3] & imm_of[1]; // unsigned only
115
   wire                 wCMP = (fCMP) ? !wADC : wADD[31]; // cmpu adjust
116 118 sybreon
 
117 131 sybreon
   wire [31:0]           wOPA = (fSUB) ? ~opa_of : opa_of;
118 118 sybreon
   wire                 wOPC = (fCCC) ? rMSR_CC : fSUB;
119
 
120 150 sybreon
   assign               {wADC, wADD} = (opb_of + wOPA) + wOPC; // add carry
121 118 sybreon
 
122 150 sybreon
   always @(/*AUTOSENSE*/wADC or wADD or wCMP) begin
123
      {add_c, add_ex} <= #1 {wADC, wCMP, wADD[30:0]}; // add with carry
124 118 sybreon
   end
125
 
126
   // SHIFT/LOGIC/MOVE
127
   reg [31:0]            slm_ex;
128
 
129
   always @(/*AUTOSENSE*/imm_of or opa_of or opb_of or opc_of
130
            or rMSR_CC)
131
     case (opc_of[2:0])
132
       // LOGIC
133
       3'o0: slm_ex <= #1 opa_of | opb_of;
134
       3'o1: slm_ex <= #1 opa_of & opb_of;
135
       3'o2: slm_ex <= #1 opa_of ^ opb_of;
136
       3'o3: slm_ex <= #1 opa_of & ~opb_of;
137
       // SHIFT/SEXT
138
       3'o4: case ({imm_of[6:5],imm_of[0]})
139
               3'o1: slm_ex <= #1 {opa_of[31],opa_of[31:1]}; // SRA
140
               3'o3: slm_ex <= #1 {rMSR_CC,opa_of[31:1]}; // SRC
141
               3'o5: slm_ex <= #1 {1'b0,opa_of[31:1]}; // SRL
142
               3'o6: slm_ex <= #1 {{(24){opa_of[7]}}, opa_of[7:0]}; // SEXT8
143
               3'o7: slm_ex <= #1  {{(16){opa_of[15]}}, opa_of[15:0]}; // SEXT16
144 125 sybreon
               default: slm_ex <= #1 32'hX;
145 118 sybreon
             endcase // case ({imm_of[6:5],imm_of[0]})
146
       // MFS/MTS/MSET/MCLR
147
       //3'o5: slm_ex <= #1 sfr_of;       
148
       // BRL (PC from SFR)
149
       //3'o6: slm_ex <= #1 sfr_of;
150
       default: slm_ex <= #1 32'hX;
151
     endcase // case (opc_of[2:0])
152
 
153
   // ALU RESULT
154
   always @(posedge gclk)
155
     if (grst) begin
156
        /*AUTORESET*/
157
        // Beginning of autoreset for uninitialized flops
158
        alu_ex <= 32'h0;
159
        alu_mx <= 32'h0;
160 131 sybreon
        bpc_ex <= 30'h0;
161 118 sybreon
        mem_ex <= 30'h0;
162
        // End of automatics
163
     end else if (dena) begin
164
        alu_mx <= #1 alu_ex;
165
        alu_ex <= #1 (opc_of[5]) ? slm_ex : add_ex;
166 134 sybreon
        mem_ex <= #1 wADD[AEMB_DWB-1:2]; // LXX/SXX     
167 131 sybreon
        bpc_ex <= #1
168
                  (!opc_of[0] & ra_of[3]) ? // check for BRA
169
                  opb_of[AEMB_IWB-1:2] : // BRA only
170 134 sybreon
                  wADD[AEMB_IWB-1:2]; // RTD/BCC/BR
171 118 sybreon
     end
172
 
173
   // MSR SECTION
174
 
175
   /*
176
    MSR REGISTER
177
 
178
    We should keep common configuration bits in the lower 16-bits of
179
    the MSR in order to avoid using the IMMI instruction.
180
 
181
    MSR bits
182
    31 - CC (carry copy)
183
    30 - HTE (hardware thread enabled)
184
    29 - PHA (current phase)
185
 
186 209 sybreon
    9  - EIP (exception in progress)
187
    8  - EE (exception enable)
188 150 sybreon
    7  - DTE (data cache enable)
189
    5  - ITE (instruction cache enable)
190 125 sybreon
    4  - MTX (hardware mutex bit)
191
    3  - BIP (break in progress)
192
    2  - C (carry flag)
193
    1  - IE (interrupt enable)
194
 
195 118 sybreon
    */
196
 
197
   assign msr_ex = {
198 204 sybreon
                    rMSR_EIP,
199
                    rMSR_EE,
200 150 sybreon
                    rMSR_DTE,
201 118 sybreon
                    1'b0,
202 150 sybreon
                    rMSR_ITE,
203 118 sybreon
                    rMSR_MTX,
204
                    rMSR_BIP,
205
                    rMSR_C,
206
                    rMSR_IE,
207
                    rMSR_BE
208
                    };
209
 
210
   // MSRSET/MSRCLR (small ALU)
211 204 sybreon
   wire [9:0] wRES = (ra_of[0]) ?
212
              (msr_ex[9:0]) & ~imm_of[9:0] : // MSRCLR
213
              (msr_ex[9:0]) | imm_of[9:0]; // MSRSET      
214 118 sybreon
 
215
   // 0 - Break
216
   // 1 - Interrupt
217
   // 2 - Exception
218
   // 3 - Reserved
219 204 sybreon
 
220
   // break
221
   wire       fRTBD = (opc_of == 6'o55) & rd_of[1];
222
   wire       fBRKB = ((opc_of == 6'o46) | (opc_of == 6'o56)) & (ra_of[4:0] == 5'hC);
223
 
224
   // interrupt
225 150 sybreon
   wire       fRTID = (opc_of == 6'o55) & rd_of[0];
226
   wire       fBRKI = (opc_of == 6'o56) & (ra_of[4:0] == 5'hD);
227 204 sybreon
 
228
   // exception
229
   wire       fRTED = (opc_of == 6'o55) & rd_of[2];
230
   wire       fBRKE = (opc_of == 6'o56) & (ra_of[4:0] == 5'hE);
231 125 sybreon
 
232 150 sybreon
   wire       fMOV = (opc_of == 6'o45);
233
   wire       fMTS = fMOV & &imm_of[15:14];
234 209 sybreon
   wire       fMOP = fMOV & ~|imm_of[15:14];
235
   wire       fMFS = fMOV & imm_of[15] & !imm_of[14];
236 118 sybreon
 
237 209 sybreon
   reg [31:0] sfr_ex;
238
   reg [2:0]  sfr_sel;
239
 
240 118 sybreon
   always @(posedge gclk)
241
     if (grst) begin
242
        /*AUTORESET*/
243
        // Beginning of autoreset for uninitialized flops
244
        sfr_ex <= 32'h0;
245
        sfr_mx <= 32'h0;
246 209 sybreon
        sfr_sel <= 3'h0;
247 118 sybreon
        // End of automatics
248 209 sybreon
     end else if (dena) begin
249
 
250
        case (sfr_sel[2:0])
251
          //3'o0: sfr_mx <= #1 {rpc_ex[31:2], 2'o0};
252
          3'o5: sfr_mx <= #1 {30'd0, rESR_C};
253
          3'o3: sfr_mx <= #1 rEAR_C;
254
          3'o1: sfr_mx <= #1 {rMSR_C,
255
                              AEMB_HTX[0],
256
                              gpha,
257
                              19'd0,
258
                              rMSR_EIP,
259
                              rMSR_EE,
260
                              rMSR_DTE,
261
                              1'b0,
262
                              rMSR_ITE,
263
                              rMSR_MTX,
264
                              rMSR_BIP,
265
                              rMSR_C,
266
                              rMSR_IE,
267
                              rMSR_BE
268
                              };
269
          default: sfr_mx <= #1 sfr_ex;
270
        endcase // case (imm_of[2:0])   
271
 
272 118 sybreon
        sfr_ex <= #1
273
                  {rMSR_CC,
274
                   AEMB_HTX[0],
275 126 sybreon
                   gpha,
276 209 sybreon
                   19'd0,
277
                   rMSR_EIP,
278
                   rMSR_EE,
279 150 sybreon
                   rMSR_DTE,
280 118 sybreon
                   1'b0,
281 150 sybreon
                   rMSR_ITE,
282 118 sybreon
                   rMSR_MTX,
283
                   rMSR_BIP,
284
                   rMSR_CC,
285
                   rMSR_IE,
286
                   rMSR_BE
287
                   };
288 209 sybreon
 
289
        sfr_sel <= #1 imm_of[2:0];
290
 
291
     end
292
 
293
   always @(posedge gclk)
294
     if (grst) begin
295
        /*AUTORESET*/
296
        // Beginning of autoreset for uninitialized flops
297
        rMSR_BE <= 1'h0;
298
        rMSR_BIP <= 1'h0;
299
        rMSR_DTE <= 1'h0;
300
        rMSR_EE <= 1'h0;
301
        rMSR_EIP <= 1'h0;
302
        rMSR_IE <= 1'h0;
303
        rMSR_ITE <= 1'h0;
304
        rMSR_MTX <= 1'h0;
305
        // End of automatics
306
     end else if (dena) begin // if (grst)              
307 150 sybreon
        rMSR_DTE <= #1
308 118 sybreon
                   (fMTS) ? opa_of[7] :
309
                   (fMOP) ? wRES[7] :
310 150 sybreon
                   rMSR_DTE;
311 134 sybreon
 
312 150 sybreon
        rMSR_ITE <= #1
313 118 sybreon
                   (fMTS) ? opa_of[5] :
314
                   (fMOP) ? wRES[5] :
315 150 sybreon
                   rMSR_ITE;
316 118 sybreon
 
317
        rMSR_MTX <= #1
318
                   (fMTS) ? opa_of[4] :
319
                   (fMOP) ? wRES[4] :
320
                   rMSR_MTX;
321
 
322
        rMSR_BE <= #1
323
                   (fMTS) ? opa_of[0] :
324
                   (fMOP) ? wRES[0] :
325
                   rMSR_BE;
326
 
327 158 sybreon
        rMSR_IE <= #1
328
                   (fBRKI) ? 1'b0 :
329
                   (fRTID) ? 1'b1 :
330
                   (fMTS) ? opa_of[1] :
331
                   (fMOP) ? wRES[1] :
332
                   rMSR_IE;
333
 
334
        rMSR_BIP <= #1
335
                    (fBRKB) ? 1'b1 :
336
                    (fRTBD) ? 1'b0 :
337
                    (fMTS) ? opa_of[3] :
338
                    (fMOP) ? wRES[3] :
339
                    rMSR_BIP;
340 204 sybreon
 
341
        rMSR_EE <= #1
342
                   (fBRKE) ? 1'b0 :
343
                   (fRTED) ? 1'b1 :
344
                   (fMTS) ? opa_of[8] :
345
                   (fMOP) ? wRES[8] :
346
                   rMSR_EE;
347
 
348
        rMSR_EIP <= #1
349
                    (fBRKE) ? 1'b1 :
350
                    (fRTED) ? 1'b0 :
351
                    (fMTS) ? opa_of[9] :
352
                    (fMOP) ? wRES[9] :
353
                    rMSR_EIP;
354
 
355 125 sybreon
     end // if (dena)
356 118 sybreon
 
357
   // BARREL C
358 158 sybreon
   wire fADDSUB = !opc_of[5] & !opc_of[4] & !opc_of[2];
359
   // (opc_of[5:2] == 4'h0) | (opc_of[5:2] == 4'h2);
360
   wire fSHIFT  = (opc_of == 6'o44) & &imm_of[6:5];
361 125 sybreon
 
362 118 sybreon
   always @(posedge gclk)
363
     if (grst) begin
364
        /*AUTORESET*/
365 209 sybreon
        // Beginning of autoreset for uninitialized flops
366
        rEAR_C <= 32'h0;
367
        rESR_C <= 2'h0;
368
        rMSR_CC <= 1'h0;
369
        // End of automatics
370 118 sybreon
     end else if (dena) begin
371 209 sybreon
        rEAR_C <= #1 rEAR;
372
        rESR_C <= #1 rESR;
373
        rMSR_CC <= #1 rMSR_C;
374
        //sfr_mx <= #1 sfr_ex;
375 118 sybreon
     end
376 125 sybreon
 
377 118 sybreon
   always @(posedge gclk)
378
     if (grst) begin
379
        /*AUTORESET*/
380
        // Beginning of autoreset for uninitialized flops
381 209 sybreon
        rEAR <= 32'h0;
382
        rESR <= 2'h0;
383 118 sybreon
        rMSR_C <= 1'h0;
384
        // End of automatics
385
     end else if (dena) begin
386 209 sybreon
        rEAR <= #1 (exc_dwb[1]) ? {mem_ex, 2'o0} : rEAR_C; // LXX/SXX
387 158 sybreon
 
388 209 sybreon
        rESR <= #1 (exc_ill | exc_dwb[1]) ?
389
                {exc_ill, exc_dwb[1]} : rESR_C; // ESR  
390
 
391 118 sybreon
        rMSR_C <= #1
392
                  (fMTS) ? opa_of[2] :
393
                  (fMOP) ? wRES[2] :
394
                  (fSHIFT) ? opa_of[0] : // SRA/SRL/SRC
395
                  (fADDSUB) ? add_c : // ADD/SUB/ADDC/SUBC
396
                  rMSR_CC;
397 158 sybreon
 
398 209 sybreon
     end // if (dena)
399 118 sybreon
 
400
endmodule // aeMB2_intu
401
 

powered by: WebSVN 2.1.0

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