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

Subversion Repositories aemb

[/] [aemb/] [branches/] [DEV_SYBREON/] [rtl/] [verilog/] [aeMB2_ofid.v] - Blame information for rev 195

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

Line No. Rev Author Line
1 88 sybreon
/* $Id: aeMB2_ofid.v,v 1.2 2007-12-16 20:38:06 sybreon Exp $
2 83 sybreon
**
3
** AEMB2 COMBINED OPERAND FETCH & INSTRUCTION DECODE
4
**
5
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
6
**
7
** This file is part of AEMB.
8
**
9
** 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
** You should have received a copy of the GNU Lesser General Public
20
** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
21
*/
22
 
23
module aeMB2_ofid (/*AUTOARG*/
24
   // Outputs
25
   rOPM_OF, rOPX_OF, rOPA_OF, rOPB_OF, rIMM_OF, rOPC_OF, rRA_OF,
26
   rRD_OF, rRD_EX, rRD_MA, rOPD_EX, rOPD_MA, rALU_OF,
27
   // Inputs
28
   rRES_EX, rREGD_OF, rREGA_OF, rREGB_OF, rBRA, rXCE, rINT, rPC_IF,
29
   rIMM_IF, rALT_IF, rOPC_IF, rRA_IF, rRB_IF, rRD_IF, pha_i, clk_i,
30
   rst_i, ena_i
31
   );
32
   parameter TXE = 1;
33
 
34
   parameter MUL = 1;
35
   parameter BSF = 1;
36
   parameter FSL = 1;
37
 
38
   output [31:0] rOPM_OF, // used for store
39
                 rOPX_OF, // used for BCC checking
40
                 rOPA_OF, // OPA as per ISA
41
                 rOPB_OF; // OPB as per ISA
42
 
43
   output [15:0] rIMM_OF;
44
   output [5:0]  rOPC_OF;
45
   output [4:0]  rRA_OF,
46
                 rRD_OF;
47
 
48
   output [4:0]  rRD_EX,
49
                 rRD_MA;
50
   output [2:0]  rOPD_EX,
51
                 rOPD_MA;
52
 
53
   output [2:0]  rALU_OF; // addsub, logic, bshift, sext, mul, mov, ldst
54
 
55
 
56
   input [31:0]  rRES_EX;
57
 
58
 
59
   input [31:0]  rREGD_OF,
60
                 rREGA_OF,
61
                 rREGB_OF;
62
 
63
   input [1:0]    rBRA;
64
   input         rXCE,
65
                 rINT;
66
 
67
   input [31:2]  rPC_IF;
68
   input [15:0]  rIMM_IF;
69
   input [10:0]  rALT_IF;
70
   input [5:0]    rOPC_IF;
71
   input [4:0]    rRA_IF,
72
                 rRB_IF,
73
                 rRD_IF;
74
 
75
   input         pha_i,
76
                 clk_i,
77
                 rst_i,
78
                 ena_i;
79
 
80
   /*AUTOREG*/
81
   // Beginning of automatic regs (for this module's undeclared outputs)
82
   reg [2:0]             rALU_OF;
83
   reg [15:0]            rIMM_OF;
84
   reg [31:0]            rOPA_OF;
85
   reg [31:0]            rOPB_OF;
86
   reg [5:0]             rOPC_OF;
87
   reg [2:0]             rOPD_EX;
88
   reg [2:0]             rOPD_MA;
89
   reg [31:0]            rOPM_OF;
90
   reg [31:0]            rOPX_OF;
91
   reg [4:0]             rRA_OF;
92
   reg [4:0]             rRD_EX;
93
   reg [4:0]             rRD_MA;
94
   reg [4:0]             rRD_OF;
95
   // End of automatics
96
 
97
   wire [31:0]           wXCEOP = 32'hBA2D0020; // Vector 0x20
98
   wire [31:0]           wINTOP = 32'hB9CE0010; // Vector 0x10   
99
   wire [31:0]           wNOPOP = 32'h88000000; // branch-no-delay/stall
100
 
101
   wire                 fSKP = (rBRA == 2'b10); // branch without delay
102
 
103
   /* Partial decoding */
104
   wire [5:0]            rOPC = rOPC_IF;
105
   wire [4:0]            rRA = rRA_IF;
106
   wire [4:0]            rRB = rRB_IF;
107
   wire                 fSFT = (rOPC == 6'o44);
108
   wire                 fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);
109
   wire                 fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
110
   wire                 fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
111
   wire                 fDIV = (rOPC == 6'o22);
112
   wire                 fRTD = (rOPC == 6'o55);
113
   wire                 fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
114
   wire                 fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
115
   wire                 fBRA = fBRU & rRA[3];
116
   wire                 fIMM = (rOPC == 6'o54);
117
   wire                 fMOV = (rOPC == 6'o45);
118
   wire                 fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
119
   wire                 fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
120
   wire                 fLDST = (rOPC[5:4] == 2'o3);
121
   wire                 fPUT = (rOPC == 6'o33) & rRB[4];
122
   wire                 fGET = (rOPC == 6'o33) & !rRB[4];
123
 
124
   /*
125
    IMMI TRAP
126
 
127
    This executes the IMMI instruction in the OF stage. This is not a
128
    problem if the flow doesn't get interrupted. */
129
 
130
   reg [15:0]            rIMM0, rIMM1, rIMML[0:1];
131
   reg                  rFIM0, rFIM1, rFIML[0:1];
132
   wire [15:0]           wIMM = rIMML[!pha_i];
133
   wire [31:0]           wSIMM;
134
 
135
   wire                 rFIM = (pha_i) ? rFIM0 : rFIM1;
136
   wire [15:0]           rIMM = (pha_i) ? rIMM0 : rIMM1;
137
 
138
   assign               wSIMM[15:0] = rIMM_IF[15:0];
139
   assign               wSIMM[31:16] = (rFIM) ?
140
                                       {rIMM} :
141
                                       {(16){rIMM_IF[15]}};
142
 
143
   always @(posedge clk_i)
144
     if (rst_i) begin
145
        /*AUTORESET*/
146
        // Beginning of autoreset for uninitialized flops
147
        rFIM0 <= 1'h0;
148
        rFIM1 <= 1'h0;
149
        rIMM0 <= 16'h0;
150
        rIMM1 <= 16'h0;
151
        // End of automatics
152
     end else if (ena_i) begin
153
        if (pha_i) begin
154
           rFIM0 <= #1 fIMM & !fSKP;
155
           rIMM0 <= #1 rIMM_IF;
156
        end else begin
157
           rFIM1 <= #1 fIMM & !fSKP;
158
           rIMM1 <= #1 rIMM_IF;
159
        end
160
     end // else: !if(rst_i)
161
 
162
   /*
163
    IINTERCEPT FLAG
164
 
165
    Presently, only interrupts are intercepted. There is no reason why
166
    it would be difficult to intercept exceptions in the same manner.
167
 
168
    All interrupts are presently handled by T0 to simplify software
169
    synchronisation and compatibility with single threaded apps. There
170
    isn't a reason why it needs to stay this way if things change. */
171
 
172 88 sybreon
   wire fINT =!rFIM & !rBRA[1] & rINT & pha_i;
173 83 sybreon
 
174
   /* Latch onto the operand */
175
   // TODO: Optimise
176
 
177
   wire                 fALU = (rOPD_EX == 3'o0);
178
   wire                 fOWRE = |rRD_EX;
179
   wire                 wOPBFWD = !rOPC_IF[3] & (rRB_IF == rRD_EX) & fALU & !fMOV & fOWRE;
180
   wire                 wOPAFWD = !(fBRU|fBCC) & (rRA_IF == rRD_EX) & fALU & fOWRE;
181
   wire                 wOPXFWD = (fBCC) & (rRA_IF == rRD_EX) & fALU & fOWRE;
182
   wire                 wOPMFWD = (rRD_IF == rRD_EX) & fALU & fOWRE;
183
 
184
   wire [1:0]            wOPB_MX = {rOPC_IF[3]|fINT, wOPBFWD|fINT};
185
   wire [1:0]            wOPA_MX = {fBRU|fBCC| (fMOV & !rRB[3]) , wOPAFWD};
186
   wire [1:0]            wOPX_MX = {fBCC, wOPXFWD};
187
   wire [1:0]            wOPM_MX = {fSTR, wOPMFWD};
188
 
189
   always @(posedge clk_i)
190
     if (rst_i) begin
191
        /*AUTORESET*/
192
        // Beginning of autoreset for uninitialized flops
193
        rOPA_OF <= 32'h0;
194
        rOPB_OF <= 32'h0;
195
        rOPM_OF <= 32'h0;
196
        rOPX_OF <= 32'h0;
197
        // End of automatics
198
     end else if (ena_i) begin
199
 
200
        case (wOPX_MX)
201
          // BCC
202
          2'o2: rOPX_OF <= #1 rREGA_OF; // reg  
203
          2'o3: rOPX_OF <= #1 rRES_EX; // forward
204
          default: rOPX_OF <= #1 32'hX;
205
        endcase // case (wOPX_MX)
206
 
207
        case (wOPM_MX)
208
          2'o2: rOPM_OF <= #1 rREGD_OF; // reg
209
          2'o3: rOPM_OF <= #1 rRES_EX; // forward
210
          default: rOPM_OF <= #1 32'hX;
211
        endcase // case (wOPM_MX)
212
 
213
        // OP B
214
        case (wOPB_MX)
215
          2'o0: rOPB_OF <= #1 rREGB_OF; // reg
216
          2'o1: rOPB_OF <= #1 rRES_EX; // forward
217
          2'o2: rOPB_OF <= #1 wSIMM; // immediate
218
          2'o3: rOPB_OF <= #1 { {(16){1'b0}}, wINTOP[15:0] };
219
          default: rOPB_OF <= #1 32'hX;
220
        endcase // case (wOPB_MX)
221
 
222
        case (wOPA_MX)
223
          2'o0: rOPA_OF <= #1 rREGA_OF; // reg
224
          2'o1: rOPA_OF <= #1 rRES_EX; // forward
225
          2'o2: rOPA_OF <= #1 {rPC_IF, 2'd0}; // pc 
226
          default: rOPA_OF <= #1 32'hX;
227
        endcase // case (wOPA_MX)
228
 
229
     end // if (ena_i)
230
 
231
   /* Hazard detection */
232
 
233
   wire                 fLOAD = (rOPD_EX == 3'o2);
234
   wire                 fMULT = (rOPD_EX == 3'o3);
235
   wire                 fWRE = |rRD_EX;
236
   wire                 fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV & !rOPC_IF[3] & fWRE;
237
   wire                 fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU & fWRE;
238
   wire                 fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & fWRE;
239
   wire                 fHAZARD = fOPBHZD | fOPAHZD | fOPDHZD;
240
 
241
   wire                 fSKIP = (rBRA == 2'o2) | // non-delay branch
242
                        !(TXE | pha_i) | // disabled thread
243
                        fOPBHZD | fOPAHZD; // hazards
244
 
245
   /* ALU Selector */
246
 
247
   always @(posedge clk_i)
248
     if (rst_i) begin
249
        /*AUTORESET*/
250
        // Beginning of autoreset for uninitialized flops
251
        rALU_OF <= 3'h0;
252
        // End of automatics
253
     end else if (ena_i) begin
254
        /*
255
        rALU_OF <= #1
256
                   (fSKIP) ? 3'o1 : // NOP
257
                   (fBRA | fMOV) ? 3'o3 :
258
                   (fSFT) ? 3'o2 :
259
                   (fLOG) ? 3'o1 :
260
                   (fMUL) ? 3'o4 :
261
                   (fBSF) ? 3'o5 :
262
                   3'o0;
263
         */
264
        rALU_OF <= #1
265
                   (fINT) ? 3'o2 :
266
                   (fSKIP) ? 3'o2 : // NOP
267
                   (fBRA | fMOV) ? 3'o2 :
268
                   (fSFT) ? 3'o2 :
269
                   (fLOG) ? 3'o2 :
270
                   (fBSF) ? 3'o1 :
271
                   3'o0;
272
     end // if (ena_i)
273
 
274
   /* WB Selector */
275
 
276
   reg [2:0] rOPD_OF;
277
 
278
   always @(posedge clk_i)
279
     if (rst_i) begin
280
        /*AUTORESET*/
281
        // Beginning of autoreset for uninitialized flops
282
        rOPD_EX <= 3'h0;
283
        rOPD_MA <= 3'h0;
284
        rOPD_OF <= 3'h0;
285
        // End of automatics
286
     end else if (ena_i) begin
287
        rOPD_MA <= #1 rOPD_EX;
288
        rOPD_EX <= #1 rOPD_OF;
289
        rOPD_OF <= #1
290
                   (fINT) ? 3'o1 :
291
                   (fSKIP) ? 3'o7: // NOP
292
                   (fSTR | fRTD | fBCC) ? 3'o7 : // STR/RTD/BCC            
293
                   (fLOD | fGET) ? 3'o2 : // RAM/FSL
294
                   (fBRU) ? 3'o1 : // PCLNK
295
                   (fMUL) ? 3'o3 : // MUL
296
                   (|rRD_IF) ? 3'o0 : // ALU
297
                   3'o7; // NOP
298
     end // if (ena_i)
299
 
300
   /* Pass Through */
301
 
302
   always @(posedge clk_i)
303
     if (rst_i) begin
304
        /*AUTORESET*/
305
        // Beginning of autoreset for uninitialized flops
306
        rIMM_OF <= 16'h0;
307
        rOPC_OF <= 6'h0;
308
        rRA_OF <= 5'h0;
309
        rRD_EX <= 5'h0;
310
        rRD_MA <= 5'h0;
311
        rRD_OF <= 5'h0;
312
        // End of automatics
313
     end else if (ena_i) begin // if (rst_i)
314
        rRD_MA <= #1 rRD_EX;
315
        rRD_EX <= #1 rRD_OF;
316
 
317
        // TODO: Interrrupt
318
        case ({fINT, fSKIP})
319
          2'o0: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF};
320
          2'o1: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wNOPOP; // delay/stall
321
          2'o3,
322
          2'o2: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wINTOP; // interrupt
323
          default: {rOPC_OF, rRD_OF, rRA_OF} <= #1 16'hX;
324
        endcase // case (fSKIP)
325
 
326
     end // if (ena_i)
327
 
328
 
329
endmodule // aeMB2_ofid
330
 
331 88 sybreon
/* $Log: not supported by cvs2svn $
332
/* Revision 1.1  2007/12/16 03:24:20  sybreon
333
/* Combined ID/OF blocks.
334
/* */

powered by: WebSVN 2.1.0

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