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

Subversion Repositories aemb

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

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

powered by: WebSVN 2.1.0

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