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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [beta_1.2/] [rtl/] [EXE/] [Module_InstructionFetch.v] - Blame information for rev 23

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

Line No. Rev Author Line
1 23 diegovalve
`timescale 1ns / 1ps
2
`include "aDefinitions.v"
3
/**********************************************************************************
4
Theia, Ray Cast Programable graphic Processing Unit.
5
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
6
 
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 
21
***********************************************************************************/
22
 
23
`define IFU_AFTER_RESET                         0
24
`define IFU_INITIAL_STATE                                       1
25
`define IFU_WAIT_FOR_LAST_INSTRUCTION_LATCHED_BY_IDU                                            2
26
`define IFU_STALLED             3
27
`define IFU_FETCH_NEXT                          4
28
`define FU_WAIT_FOR_EXE_UNIT            5
29
`define IFU_DONE                                                6
30
`define IFU_CHECK_FOR_JUMP_PENDING                      7
31
 
32
 
33
`define IP_SET_VALUE_INITIAL_ADDRESS 0
34
`define IP_SET_VALUE_BRANCH_ADDRESS 1
35
 
36
//-----------------------------------------------------------------------------
37
module InstructionFetchUnit
38
(
39
        input wire                                                                              Clock,
40
        input wire                                                                              Reset,
41
        input   wire                                                                            iBranchTaken,
42
        input wire                                                                              iBranchNotTaken,
43
        input wire[`ROM_ADDRESS_WIDTH-1:0]               iJumpIp,
44
        input   wire                                                                            iTrigger,
45
        input   wire                                                                            iIDUBusy,
46
        input   wire                                                                            iExeBusy,
47
        input wire[`INSTRUCTION_WIDTH-1:0]               iEncodedInstruction,
48
        input wire[`ROM_ADDRESS_WIDTH-1:0]               iInitialCodeAddress,
49
        input wire                                                                              iDecodeUnitLatchedValues,
50
        output reg                                                                              oExecutionDone,
51
        output wire                                                                             oMicroCodeReturnValue,
52
        output wire                                                                             oInstructionAvalable,
53
        output wire [`ROM_ADDRESS_WIDTH-1:0]     oInstructionPointer,
54
        output wire[`INSTRUCTION_WIDTH-1:0]              oCurrentInstruction
55
 
56
 
57
);
58
 
59
//Alling the Jump Signal to the negedge of Clock,
60
//I do this because I finded out the simulator
61
//behaves funny if you change a value at the edge
62
//of the clock and read from a bus that has changed
63
wire rJumpNow;
64
 
65
assign oCurrentInstruction = iEncodedInstruction;
66
 
67
assign oMicroCodeReturnValue = iEncodedInstruction[0];
68
 
69
wire [`ROM_ADDRESS_WIDTH-1:0] wInstructionPointer;
70
reg rEnable;
71
 
72
assign oInstructionPointer = wInstructionPointer;
73
 
74
reg rPreviousInstructionIsJump;
75
 
76
`define INSTRUCTION_OPCODE iEncodedInstruction[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
77
 
78
wire wLastInstruction;
79
assign wLastInstruction =
80
(`INSTRUCTION_OPCODE == 0) ? 1'b1 : 1'b0;
81
 
82
wire rInstructionAvalable;
83
assign rInstructionAvalable = (iTrigger || iDecodeUnitLatchedValues) && rEnable;
84
 
85
 
86
//if it is jump delay 1 cycle
87
wire wInstructionAvalableDelayed_1Cycle;
88
wire wInstructionAvalableDelayed_2Cycle;
89
wire wInstructionAvalableDelayed_3Cycle;
90
wire wInstructionAvalableDelayed_4Cycle;
91
wire wJumpNow_Delayed_1Cycle,wJumpNow_Delayed_2Cycle,wJumpNow_Delayed_3Cycle;
92
 
93
 
94
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelayJump
95
(
96
        .Clock( Clock ),
97
        .Clear( Reset ),
98
        .D( rJumpNow ),
99
        .Q( wJumpNow_Delayed_1Cycle )
100
);
101
 
102
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelayJump2
103
(
104
        .Clock( Clock ),
105
        .Clear( Reset ),
106
        .D( wJumpNow_Delayed_1Cycle ),
107
        .Q( wJumpNow_Delayed_2Cycle )
108
);
109
 
110
 
111
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelayJump3
112
(
113
        .Clock( Clock ),
114
        .Clear( Reset ),
115
        .D( wJumpNow_Delayed_2Cycle ),
116
        .Q( wJumpNow_Delayed_3Cycle )
117
);
118
 
119
 
120
 
121
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelay1
122
(
123
        .Clock( Clock ),
124
        .Clear( Reset ),
125
        .D( rInstructionAvalable ),
126
        .Q( wInstructionAvalableDelayed_1Cycle )
127
);
128
 
129
 
130
 
131
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelay2
132
(
133
        .Clock( Clock ),
134
        .Clear( Reset ),
135
        .D( wInstructionAvalableDelayed_1Cycle ),
136
        .Q( wInstructionAvalableDelayed_2Cycle )
137
);
138
 
139
 
140
 
141
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelay3
142
(
143
        .Clock( Clock ),
144
        .Clear( Reset ),
145
        .D( wInstructionAvalableDelayed_2Cycle ),
146
        .Q( wInstructionAvalableDelayed_3Cycle )
147
);
148
 
149
 
150
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelay4A
151
(
152
        .Clock( Clock ),
153
        .Clear( Reset ),
154
        .D( wInstructionAvalableDelayed_3Cycle ),
155
        .Q( wInstructionAvalableDelayed_4Cycle )
156
);
157
 
158
 
159
assign oInstructionAvalable = (wInstructionAvalableDelayed_1Cycle && !rJumpNow) ||
160
                                                                (wInstructionAvalableDelayed_3Cycle && wJumpNow_Delayed_2Cycle);
161
 
162
wire wInstructionAvalableDelayed;
163
 
164
FFD_POSEDGE_ASYNC_RESET # ( 1 ) FFDelay4
165
(
166
        .Clock( Clock ),
167
        .Clear( Reset ),
168
        .D( oInstructionAvalable ),
169
        .Q( wInstructionAvalableDelayed )
170
);
171
 
172
 
173
//----------------------------------------------
174
assign rJumpNow = iBranchTaken && !iBranchNotTaken;
175
//This sucks, should be improved
176
 
177
wire JumpInstructinDetected;
178
assign JumpInstructinDetected =
179
        (
180
         `INSTRUCTION_OPCODE == `JGEX || `INSTRUCTION_OPCODE == `JLEX ||
181
         `INSTRUCTION_OPCODE == `JGEY || `INSTRUCTION_OPCODE == `JLEY ||
182
         `INSTRUCTION_OPCODE == `JGEZ || `INSTRUCTION_OPCODE == `JLEZ ||
183
         `INSTRUCTION_OPCODE == `JEQX || `INSTRUCTION_OPCODE == `JNEX ||
184
         `INSTRUCTION_OPCODE == `JEQY || `INSTRUCTION_OPCODE == `JNEY ||
185
         `INSTRUCTION_OPCODE == `JEQZ || `INSTRUCTION_OPCODE == `JNEZ
186
         ) ;
187
 
188
 
189
//Stall logic. 
190
//it basically tells IFU to stall on Branches. 
191
//The Stall begins when a Branch instruction
192
//is detected, the Stall ends when EXE tells us it made
193
//a branch taken or branch not taken decision
194
 
195
wire wStall;
196
assign wStall = JumpInstructinDetected && !iBranchTaken && !iBranchNotTaken;
197
 
198
//Increment the IP everytime IDU tells us it has Latched the previous I we gave him,
199
//except when we reached the last instruction in the flow, or we are in a Stall
200
 
201
wire wIncrementInstructionPointer;
202
assign wIncrementInstructionPointer = (wStall || wLastInstruction) ?  1'b0 : iDecodeUnitLatchedValues;
203
 
204
 
205
//-------------------------------------------------
206
wire wIP_AlternateValue;
207
wire wIP_SetValueSelector;
208
wire [`ROM_ADDRESS_WIDTH-1:0] wInstructionPointerAlternateValue;
209
 
210
MUXFULLPARALELL_16bits_2SEL InstructionPointerSetValueMUX
211
 (
212
  .Sel( wIP_SetValueSelector ),
213
  .I1( iInitialCodeAddress    ),
214
  .I2(  iJumpIp ),
215
  .O1( wInstructionPointerAlternateValue )
216
 );
217
 
218
reg rIpControl;
219
MUXFULLPARALELL_1Bit_1SEL InstructionPointerControlMUX
220
 (
221
  .Sel( rIpControl ),
222
  .I1(  1'b0   ),
223
  .I2(  iBranchTaken  ),
224
  .O1( wIP_SetValueSelector )
225
 );
226
 
227
 
228
 
229
UPCOUNTER_POSEDGE # (16) InstructionPointer
230
(
231
        .Clock(wIncrementInstructionPointer || wJumpNow_Delayed_1Cycle || iTrigger),
232
        .Reset(iTrigger ||  wJumpNow_Delayed_1Cycle ),
233
        .Enable(1'b1),
234
        .Initial(wInstructionPointerAlternateValue),
235
        .Q(wInstructionPointer)
236
);
237
 
238
 
239
reg     [5:0]    CurrentState,   NextState;
240
 
241
//------------------------------------------------
242
always @(posedge Clock or posedge Reset)
243
begin
244
 
245
 
246
    if (Reset)
247
                CurrentState <= `IFU_AFTER_RESET;
248
    else
249
                CurrentState <= NextState;
250
 
251
end
252
//------------------------------------------------
253
always @ ( * )
254
begin
255
        case ( CurrentState )
256
        //------------------------------------
257
        `IFU_AFTER_RESET:
258
        begin
259
 
260
                 rEnable                <= iTrigger;
261
                 rIpControl <= `IP_SET_VALUE_INITIAL_ADDRESS;//0;
262
                 oExecutionDone <= 0;
263
 
264
                if (iTrigger)
265
                        NextState <= `IFU_INITIAL_STATE;
266
                else
267
                        NextState <= `IFU_AFTER_RESET;
268
        end
269
        //------------------------------------
270
        `IFU_INITIAL_STATE:
271
        begin
272
 
273
                rEnable   <= 1;
274
                rIpControl <= `IP_SET_VALUE_BRANCH_ADDRESS; //1;
275
                oExecutionDone <= 0;
276
 
277
                //We reached last instrcution (RETURN), and IDU latched the one before that
278
                if ( wLastInstruction && iDecodeUnitLatchedValues && !rJumpNow )
279
                        NextState <= `IFU_WAIT_FOR_LAST_INSTRUCTION_LATCHED_BY_IDU;
280
                else
281
                        NextState <= `IFU_INITIAL_STATE;
282
 
283
        end
284
 
285
        //------------------------------------  
286
        //Here, we wait until IDU latches the last
287
        //instruction, ie. the RETURN instruction
288
        `IFU_WAIT_FOR_LAST_INSTRUCTION_LATCHED_BY_IDU:
289
        begin
290
                rEnable   <= ~iDecodeUnitLatchedValues;
291
                rIpControl <= `IP_SET_VALUE_BRANCH_ADDRESS;
292
                oExecutionDone <= 0;
293
 
294
                if ( iDecodeUnitLatchedValues && !rJumpNow)//&& !iExeBusy && !iIDUBusy )
295
                        NextState <= `IFU_DONE;
296
                else if ( rJumpNow )
297
                        NextState <= `IFU_INITIAL_STATE;
298
                else
299
                        NextState <= `IFU_WAIT_FOR_LAST_INSTRUCTION_LATCHED_BY_IDU;
300
        end
301
        //------------------------------------
302
        `IFU_DONE:
303
        begin
304
                rEnable   <= 0;
305
                rIpControl <= `IP_SET_VALUE_BRANCH_ADDRESS;
306
                oExecutionDone <= !iExeBusy && !iIDUBusy;//1'b1;
307
 
308
 
309
                if (!iExeBusy && !iIDUBusy)
310
                        NextState <= `IFU_AFTER_RESET;
311
                else
312
                        NextState <= `IFU_DONE;
313
 
314
        end
315
        //------------------------------------
316
        default:
317
        begin
318
                rEnable  <= 0;
319
                rIpControl <= `IP_SET_VALUE_INITIAL_ADDRESS; //0;
320
                oExecutionDone <= 0;
321
 
322
                NextState <= `IFU_AFTER_RESET;
323
        end
324
        //------------------------------------  
325
        endcase
326
end// always    
327
 
328
 
329
//------------------------------------------------------
330
//
331
//
332
`ifdef DEBUG2
333
        always @ ( negedge iTrigger or negedge iDecodeUnitLatchedValues )
334
        begin
335
                $write("(%dns %d)",$time,oInstructionPointer);
336
        end
337
 
338
 
339
        always @ ( negedge wLastInstruction )
340
        begin
341
                $display(" %dns RETURN %d",$time,oMicroCodeReturnValue);
342
        end
343
`endif
344
 
345
`ifdef DEBUG2
346
        always @ (posedge wStall)
347
        begin
348
                $write("<S>");
349
        end
350
`endif
351
 
352
 
353
 
354
 
355
endmodule
356
//-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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