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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [beta_1.1/] [rtl/] [EXE/] [Module_InstructionDecode.v] - Blame information for rev 93

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

Line No. Rev Author Line
1 24 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
`define IDU_AFTER_RESET 0
23
`define IDU_WAIT_FOR_NEXT_INSTRUCTION   1
24
`define IDU_WAIT_FOR_RAM        2
25
`define IDU_DISPATCH_DECODE_INSTRUCTION 3
26
`define IDU_LATCH_RAM_VALUES    4
27
`define IDU_WAIT_FOR_FIRST_INTRUCTION 5
28
`define IDU_INITIAL_DELAY       6
29
 
30
 
31
 
32
module InstructionDecode
33
(
34
input wire                                                                                      Clock,
35
input wire                                                                                      Reset,
36
input wire                                                                                      iTrigger,
37
input   wire[`INSTRUCTION_WIDTH-1:0]                     iEncodedInstruction,
38
input wire                                                                                      iExecutioUnitLatchedValues,
39
input   wire                                                                                    iInstructionAvailable,
40
output reg                                                                                      oBusy,
41
input   wire[`DATA_ROW_WIDTH-1:0]                                        iRamValue0,
42
input   wire[`DATA_ROW_WIDTH-1:0]                                        iRamValue1,
43
output  wire[`DATA_ADDRESS_WIDTH-1:0]            oRamAddress0,oRamAddress1,
44
 
45
output  wire[`INSTRUCTION_OP_LENGTH-1:0] oOperation,
46
output  wire [`DATA_ROW_WIDTH-1:0]                               oSource0,oSource1,
47
 
48
output reg oInputsLatched,
49
//output reg oBusBusy,
50
output reg oDataReadyForExe,
51
//input wire iExecutionReady,
52
 
53
 
54
output  wire [`DATA_ADDRESS_WIDTH-1:0]   oDestination,
55
 
56
`ifdef DEBUG
57
        input wire [`ROM_ADDRESS_WIDTH-1:0] iDebug_CurrentIP,
58
        output wire [`ROM_ADDRESS_WIDTH-1:0] oDebug_CurrentIP,
59
`endif
60
 
61
input wire [`DATA_ROW_WIDTH-1:0] iDataForward,
62
input wire [`DATA_ADDRESS_WIDTH-1:0] iLastDestination
63
);
64
 
65
 
66
`ifdef DEBUG
67
assign oDebug_CurrentIP = iDebug_CurrentIP;
68
 
69
`endif
70
 
71
 
72
reg rFirstInstruction;
73
wire wLatchNow;
74
wire[`DATA_ADDRESS_WIDTH-1:0] wFF16_2_SourceAddress0;
75
 
76
 
77
 
78
`define IFU_WAIT_FOR_FIRST_INSTRUCTION          0
79
`define IFU_WAIT_FOR_EXE_TO_LATCH                               1
80
`define IFU_WAIT_FOR_INSTRUCTION_AVAILABLE      2
81
`define SELECT_ZERO                     1'd0
82
`define SELECT_IAVAILABLE       1'd1
83
 
84
`define INSTRUCTION_OPCODE iEncodedInstruction[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
85
 
86
//The next logic is to control when to latch incoming values.
87
//Values coming from IFU will be latched by IDU everytime the
88
//'wLatchNow' signal is set to 1. We need to garanteed that the wLatchNow is set only if: 
89
// 1) There is a instruction available from IFU. ie 'iInstructionAvailable' is set.
90
// 2) EXE unit already latched the decoded values we provided from the previous cycle.
91
// ie. we won't read new values until we are sure EXE latched the previous values
92
//Since the previous 2 conditions don't necesarily happens cocurrently and the pipeline
93
//is asynchronous, a FSM is implemented to correctly represent this behavior.
94
//This FSM has only 2 states and also controls the 'oBusy' signal, the 'oDataReadyForExe'
95
//signal and the 'oInputsLatched' signal.
96
 
97
reg rLatchNowSelector;
98
 
99
MUXFULLPARALELL_1Bit_1SEL iInstructionAvailable_MUX
100
 (
101
 .Sel( rLatchNowSelector ),
102
 .I1( 1'b0 ),
103
 .I2( iInstructionAvailable ),
104
 .O1( wLatchNow )
105
 );
106
 
107
 
108
 
109
reg[1:0] rLatchNow_CurrentState;
110
reg[1:0] rLatchNow_NextState;
111
 
112
//Next State logic for the LatchNow signal
113
always @ (posedge Clock)
114
begin
115
        if (Reset)
116
                rLatchNow_CurrentState <= `IFU_WAIT_FOR_INSTRUCTION_AVAILABLE;
117
        else
118
                rLatchNow_CurrentState <= rLatchNow_NextState;
119
end
120
 
121
always @ ( * )
122
begin
123
        case ( rLatchNow_CurrentState )
124
                //--------------------------------------
125
                `IFU_WAIT_FOR_INSTRUCTION_AVAILABLE:
126
                begin
127
                        rLatchNowSelector <= `SELECT_IAVAILABLE;
128
                        oDataReadyForExe  <= 0;
129
                        oBusy                                   <= 0;
130
                        oInputsLatched          <= 0;
131
 
132
                        if ( iInstructionAvailable )
133
                                rLatchNow_NextState <= `IFU_WAIT_FOR_EXE_TO_LATCH;
134
                        else
135
                                rLatchNow_NextState <= `IFU_WAIT_FOR_INSTRUCTION_AVAILABLE;
136
                end
137
                //--------------------------------------
138
                `IFU_WAIT_FOR_EXE_TO_LATCH:
139
                begin
140
                        rLatchNowSelector <= `SELECT_ZERO;
141
                        oDataReadyForExe  <= 1;
142
                        oBusy                                   <= 1;
143
                        oInputsLatched          <= 1;
144
 
145
                        if ( iExecutioUnitLatchedValues )
146
                                rLatchNow_NextState <= `IFU_WAIT_FOR_INSTRUCTION_AVAILABLE;
147
                        else
148
                                rLatchNow_NextState <= `IFU_WAIT_FOR_EXE_TO_LATCH;
149
                end
150
                //--------------------------------------
151
        endcase
152
end
153
 
154
 
155
//There are 2 types of operations to be decoded:
156
//1) Operations that read thier parameters from memory locations. 
157
//2) Operations that use inmediate values instead of address locations.
158
//The way IDU distinguishes between both is via the wInmediateOperand bit.
159
//This is bit 5 of the operation part of the instruction.
160
 
161
wire wInmediateOperand;
162
assign wInmediateOperand = (oOperation[`INSTRUCTION_IMM_BIT ] == 1 || oOperation == `INSTRUCTION_OP_LENGTH'b0) ? 1 : 0;
163
 
164
//Here we decode the 2 Data sources for the instruction: wSource0 and wSource1.
165
//wSource0 will always be assigned to the contents of memory address location,
166
//however wSource1 can either the contents of a memory location or inmediate 
167
//operand.
168
 
169
wire[`DATA_ROW_WIDTH-1:0] wSource0,wSource1;
170
 
171
assign wSource0 = iRamValue0;
172
assign wSource1 = ( wInmediateOperand ) ? {oRamAddress1,wFF16_2_SourceAddress0,32'b0,32'b0} : iRamValue1;
173
 
174
//Since we are implementing a pipeline, data hazards such as RAW may arise.
175
//in order to avoid such race conditions without inserting aditional stall cycles,
176
//a data forward approach has been taken. 2 separe data forwarding signals are available
177
//to indicate weather fordwarding is needed on either of the Source ports.
178
 
179
wire rTriggerSource0DataForward,rTriggerSource1DataForward;
180
wire wSource0AddrssEqualsLastDestination,wSource1AddrssEqualsLastDestination;
181
 
182
assign wSource0AddrssEqualsLastDestination = (oRamAddress0 == iLastDestination) ? 1'b1: 1'b0;
183
assign wSource1AddrssEqualsLastDestination = (oRamAddress1 == iLastDestination) ? 1'b1: 1'b0;
184
assign rTriggerSource0DataForward = wSource0AddrssEqualsLastDestination;
185
assign rTriggerSource1DataForward = wSource1AddrssEqualsLastDestination && !wInmediateOperand;
186
 
187
//Once we made a decicions on weather the Sources must be forwarded or not, a series of muxes
188
//are used to routed the correct data into the decoded Source outputs
189
 
190
MUXFULLPARALELL_96bits_2SEL Source0_Mux
191
(
192
        .Sel( rTriggerSource0DataForward ),
193
        .I1( wSource0  ),
194
        .I2( iDataForward ),
195
        .O1( oSource0 )
196
);
197
 
198
MUXFULLPARALELL_96bits_2SEL Source1_Mux
199
(
200
        .Sel( rTriggerSource1DataForward ),
201
        .I1( wSource1  ),
202
        .I2( iDataForward ),
203
        .O1( oSource1 )
204
);
205
 
206
//Next we instance the pipestage Flip Flops to store the stage's data
207
FF16_POSEDGE_SYNCRONOUS_RESET PSRegSource0Address
208
(
209
        .Clock( wLatchNow ),
210
        .Clear( Reset ),
211
        .D( iEncodedInstruction[15:0] ),
212
        .Q( wFF16_2_SourceAddress0 )
213
 
214
);
215
 
216
 
217
MUXFULLPARALELL_16bits_2SEL RAMAddr0MUX
218
 (
219
  .Sel( wInmediateOperand ),
220
  .I1( wFF16_2_SourceAddress0 ),
221
  .I2( oDestination ),
222
  .O1( oRamAddress0 )
223
 );
224
 
225
FF16_POSEDGE_SYNCRONOUS_RESET PSRegSource1Address
226
(
227
        .Clock( wLatchNow ),
228
        .Clear( Reset ),
229
        .D( iEncodedInstruction[31:16] ),
230
        .Q( oRamAddress1 )
231
);
232
 
233
 
234
FFD16_POSEDGE PSRegDestination
235
(
236
        .Clock( wLatchNow ),
237
        .D( iEncodedInstruction[47:32]  ),
238
        .Q( oDestination )
239
 
240
);
241
 
242
/*
243
FFD6_POSEDGE PSRegOperation
244
(
245
        .Clock( wLatchNow ),
246
        .D( `INSTRUCTION_OPCODE  ),
247
        .Q( oOperation )
248
 
249
);
250
*/
251
FFD_OPCODE_POSEDGE PSRegOperation
252
(
253
        .Clock( wLatchNow ),
254
        .D( `INSTRUCTION_OPCODE  ),
255
        .Q( oOperation )
256
 
257
);
258
//------------------------------------------------
259
 
260
 
261
`ifdef DEBUG2
262
always @ ( negedge Clock  )
263
begin
264
        if ( iInstructionAvailable )
265
        begin
266
 
267
                if ( oRamAddress0 == iLastDestination || oRamAddress1 == iLastDestination)
268
                        $display("%d Data Forward %h ",$time, iDataForward);
269
        end
270
end
271
`endif
272
 
273
 
274
//------------------------------------------------
275
 
276
 
277
 
278
reg     [6:0]    CurrentState,   NextState;
279
//------------------------------------------------
280
  always @(posedge Clock or posedge Reset)
281
  begin
282
 
283
    if (Reset)// || iTrigger )  
284
                CurrentState <= `IDU_AFTER_RESET;
285
    else
286
                CurrentState <= NextState;
287
 
288
  end
289
//------------------------------------------------
290
 
291
always @ ( * )
292
begin
293
        case ( CurrentState )
294
        //------------------------------------
295
        /*
296
                By the time the trigger gets to 1,
297
                there will be data already waiting..
298
 
299
        */
300
        `IDU_AFTER_RESET:
301
        begin
302
 
303
        //      oBusBusy                                <= 0;
304
                rFirstInstruction <= 1;
305
 
306
                if (iInstructionAvailable)
307
                        NextState <= `IDU_WAIT_FOR_NEXT_INSTRUCTION;
308
                else
309
                        NextState <= `IDU_AFTER_RESET;
310
        end
311
                //------------------------------------
312
        `IDU_WAIT_FOR_NEXT_INSTRUCTION:
313
        begin
314
 
315
                //oBusBusy                              <= 0;
316
                rFirstInstruction <= 0;
317
 
318
                if ( iExecutioUnitLatchedValues )
319
                        NextState <= `IDU_WAIT_FOR_RAM;
320
                else
321
                        NextState <= `IDU_WAIT_FOR_NEXT_INSTRUCTION;
322
 
323
        end
324
        //------------------------------------
325
        `IDU_WAIT_FOR_RAM:
326
        begin
327
                //oBusBusy                              <= 1;
328
                rFirstInstruction <= 0;
329
 
330
                if (iInstructionAvailable ||  oOperation == `INSTRUCTION_OP_LENGTH'd0)
331
                        NextState <= `IDU_WAIT_FOR_NEXT_INSTRUCTION;
332
                else
333
                        NextState <= `IDU_WAIT_FOR_RAM;
334
 
335
        end
336
 
337
        //------------------------------------
338
        default:
339
        begin
340
                //oBusBusy                              <= 0;
341
                rFirstInstruction <= 0;
342
 
343
                NextState <= `IDU_WAIT_FOR_NEXT_INSTRUCTION;
344
 
345
        end
346
        //------------------------------------
347
        endcase
348
end
349
 
350
 
351
 
352
 
353
 
354
`ifdef DEBUG2
355
always @ ( posedge wLatchNow )
356
begin
357
 
358
                $display("( %d %d [%d %d] - %d)",
359
                iEncodedInstruction[53:48],iEncodedInstruction[47:32],
360
                iEncodedInstruction[31:16],iEncodedInstruction[15:0], $time );
361
 
362
end
363
`endif
364
 
365
 
366
endmodule

powered by: WebSVN 2.1.0

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