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] - Diff between revs 72 and 87

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 72 Rev 87
`timescale 1ns / 1ps
`timescale 1ns / 1ps
`include "aDefinitions.v"
`include "aDefinitions.v"
/**********************************************************************************
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
 
 
This program is free software; you can redistribute it and/or
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
of the License, or (at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 
***********************************************************************************/
***********************************************************************************/
/**********************************************************************************
/**********************************************************************************
Description:
Description:
 This is the instruction fetch unit.
 This is the instruction fetch unit.
 It gets the next instruction from the IMEM module at the MEM unit.
 It gets the next instruction from the IMEM module at the MEM unit.
 It increments the instruction pointer (IP) in such a way that EXE has always
 It increments the instruction pointer (IP) in such a way that EXE has always
 one instruction per clock cycle (best pipeline performance). In order to achieve this,
 one instruction per clock cycle (best pipeline performance). In order to achieve this,
 IFU has 2 instruction pointers, so that in case of 'branch' instructions,
 IFU has 2 instruction pointers, so that in case of 'branch' instructions,
 two instructions pointer are generated and two different instructions are simultaneously
 two instructions pointer are generated and two different instructions are simultaneously
 fetched from IMEM: the branch-taken and branch-not-taken instructions, so that once the
 fetched from IMEM: the branch-taken and branch-not-taken instructions, so that once the
 branch outcome is calculted in EXE, both possible outcomes are already pre-fetched.
 branch outcome is calculted in EXE, both possible outcomes are already pre-fetched.
**********************************************************************************/
**********************************************************************************/
module InstructionFetch
module InstructionFetch
(
(
input wire Clock,
input wire Clock,
input wire Reset,
input wire Reset,
input wire iTrigger,
input wire iTrigger,
input wire[`ROM_ADDRESS_WIDTH-1:0]               iInitialCodeAddress,
input wire[`ROM_ADDRESS_WIDTH-1:0]               iInitialCodeAddress,
input wire[`INSTRUCTION_WIDTH-1:0]               iInstruction1,                  //Branch not taken instruction
input wire[`INSTRUCTION_WIDTH-1:0]               iInstruction1,                  //Branch not taken instruction
input wire[`INSTRUCTION_WIDTH-1:0]               iInstruction2,                  //Branch taken instruction
input wire[`INSTRUCTION_WIDTH-1:0]               iInstruction2,                  //Branch taken instruction
input   wire                                                                            iBranchTaken,
input   wire                                                                            iBranchTaken,
output wire                                                                             oInstructionAvalable,
output wire                                                                             oInstructionAvalable,
output wire [`ROM_ADDRESS_WIDTH-1:0]     oIP,
output wire [`ROM_ADDRESS_WIDTH-1:0]     oIP,
output wire [`ROM_ADDRESS_WIDTH-1:0]     oIP2, //calcule both decide later
output wire [`ROM_ADDRESS_WIDTH-1:0]     oIP2, //calcule both decide later
output wire[`INSTRUCTION_WIDTH-1:0]              oCurrentInstruction,
output wire[`INSTRUCTION_WIDTH-1:0]              oCurrentInstruction,
input wire                             iEXEDone,
input wire                             iEXEDone,
output wire                                                                             oMicroCodeReturnValue,
output wire                                                                             oMicroCodeReturnValue,
output wire                            oExecutionDone
output wire                            oExecutionDone
);
);
`define INSTRUCTION_OPCODE oCurrentInstruction[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
`define INSTRUCTION_OPCODE oCurrentInstruction[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
//iInstruction1[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
//iInstruction1[`INSTRUCTION_WIDTH-1:`INSTRUCTION_WIDTH-`INSTRUCTION_OP_LENGTH]
 
 
assign oMicroCodeReturnValue = oCurrentInstruction[0];
assign oMicroCodeReturnValue = oCurrentInstruction[0];
assign oIP2 = oCurrentInstruction[47:32];//iInstruction1[47:32];
assign oIP2 = oCurrentInstruction[47:32];//iInstruction1[47:32];
 
 
wire wTriggerDelay1,wTriggerDelay2,wIncrementIP_Delay1,wIncrementIP_Delay2,
wire wTriggerDelay1,wTriggerDelay2,wIncrementIP_Delay1,wIncrementIP_Delay2,
wLastInst_Delay1,wLastInst_Delay2;
wLastInst_Delay1,wLastInst_Delay2;
wire wIncrementIP,wLastInstruction;
wire wIncrementIP,wLastInstruction;
 
 
 
 
assign wLastInstruction = (`INSTRUCTION_OPCODE == `RETURN);
assign wLastInstruction = (`INSTRUCTION_OPCODE == `RETURN);
 
 
//Increment IP 2 cycles after trigger or everytime EXE is done, but stop if we get to the RETURN
//Increment IP 2 cycles after trigger or everytime EXE is done, but stop if we get to the RETURN
assign wIncrementIP =  wTriggerDelay2 | (iEXEDone & ~wLastInstruction);
assign wIncrementIP =  wTriggerDelay2 | (iEXEDone & ~wLastInstruction);
//It takes 1 clock cycle to read the instruction back from IMEM
//It takes 1 clock cycle to read the instruction back from IMEM
assign oInstructionAvalable = wTriggerDelay2 | (iEXEDone & ~wLastInst_Delay2);
assign oInstructionAvalable = wTriggerDelay2 | (iEXEDone & ~wLastInst_Delay2);
//Once we reach the last instruction, wait until EXE says he is done, then assert oExecutionDone
//Once we reach the last instruction, wait until EXE says he is done, then assert oExecutionDone
assign oExecutionDone = (wLastInstruction & iEXEDone);
assign oExecutionDone = (wLastInstruction & iEXEDone);
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(1'b1),
        .Enable(1'b1),
        .D( iTrigger ),
        .D( iTrigger ),
        .Q( wTriggerDelay1 )
        .Q( wTriggerDelay1 )
);
);
 
 
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD3
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD3
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(1'b1),
        .Enable(1'b1),
        .D( wTriggerDelay1 ),
        .D( wTriggerDelay1 ),
        .Q( wTriggerDelay2 )
        .Q( wTriggerDelay2 )
);
);
 
 
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD4
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD4
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(wLastInstruction),
        .Enable(wLastInstruction),
        .D( oInstructionAvalable ),
        .D( oInstructionAvalable ),
        .Q( wLastInst_Delay1 )
        .Q( wLastInst_Delay1 )
);
);
 
 
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD5
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD5
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(1'b1),//wLastInstruction),
        .Enable(1'b1),//wLastInstruction),
        .D( wLastInst_Delay1 ),
        .D( wLastInst_Delay1 ),
        .Q( wLastInst_Delay2 )
        .Q( wLastInst_Delay2 )
);
);
 
 
wire [`ROM_ADDRESS_WIDTH-1:0] oIP2_Next;
wire [`ROM_ADDRESS_WIDTH-1:0] oIP2_Next;
 
 
/*
/*
In case the branch is taken:
In case the branch is taken:
We point current instruction into the iInstruction2 (branch-taken) instruction
We point current instruction into the iInstruction2 (branch-taken) instruction
that corresponds to oIP2.
that corresponds to oIP2.
Then, in the next clock cycle we should use the oIP2 incremented by one,
Then, in the next clock cycle we should use the oIP2 incremented by one,
so we need to load UPCOUNTER_POSEDGE with oIP2+1
so we need to load UPCOUNTER_POSEDGE with oIP2+1
*/
*/
 
 
 
 
//If the branch was taken, then use the pre-fetched instruction (iInstruction2)
//If the branch was taken, then use the pre-fetched instruction (iInstruction2)
wire[`INSTRUCTION_WIDTH-1:0] wCurrentInstruction_Delay1,wCurrentInstruction_BranchTaken;
wire[`INSTRUCTION_WIDTH-1:0] wCurrentInstruction_Delay1,wCurrentInstruction_BranchTaken;
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDX
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDX
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(iBranchTaken),
        .Enable(iBranchTaken),
        .D( oCurrentInstruction ),
        .D( oCurrentInstruction ),
        .Q( wCurrentInstruction_Delay1 )
        .Q( wCurrentInstruction_Delay1 )
);
);
 
 
wire wBranchTaken_Delay1;
wire wBranchTaken_Delay1;
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFDY
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFDY
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .Enable(1'b1),
        .Enable(1'b1),
        .D( iBranchTaken ),
        .D( iBranchTaken ),
        .Q( wBranchTaken_Delay1 )
        .Q( wBranchTaken_Delay1 )
);
);
 
 
 
 
assign wCurrentInstruction_BranchTaken = (iBranchTaken ) ? iInstruction2 : iInstruction1;
assign wCurrentInstruction_BranchTaken = (iBranchTaken ) ? iInstruction2 : iInstruction1;
 
 
assign oCurrentInstruction = (wBranchTaken_Delay1) ?
assign oCurrentInstruction = (wBranchTaken_Delay1) ?
wCurrentInstruction_Delay1 : wCurrentInstruction_BranchTaken;
wCurrentInstruction_Delay1 : wCurrentInstruction_BranchTaken;
 
 
INCREMENT # (`ROM_ADDRESS_WIDTH) INC1
INCREMENT # (`ROM_ADDRESS_WIDTH) INC1
(
(
.Clock( Clock ),
.Clock( Clock ),
.Reset( Reset ),
.Reset( Reset ),
.A( oIP2 ),
.A( oIP2 ),
.R( oIP2_Next )
.R( oIP2_Next )
);
);
 
 
wire[`ROM_ADDRESS_WIDTH-1:0] wIPEntryPoint;
wire[`ROM_ADDRESS_WIDTH-1:0] wIPEntryPoint;
assign wIPEntryPoint = (iBranchTaken) ? oIP2_Next : iInitialCodeAddress;
assign wIPEntryPoint = (iBranchTaken) ? oIP2_Next : iInitialCodeAddress;
 
 
UPCOUNTER_POSEDGE # (`ROM_ADDRESS_WIDTH) InstructionPointer
UPCOUNTER_POSEDGE # (`ROM_ADDRESS_WIDTH) InstructionPointer
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset(iTrigger | iBranchTaken),
        .Reset(iTrigger | iBranchTaken),
        .Enable(wIncrementIP & ~iBranchTaken ),
        .Enable(wIncrementIP & ~iBranchTaken ),
        .Initial( wIPEntryPoint ),
        .Initial( wIPEntryPoint ),
        .Q(oIP)
        .Q(oIP)
);
);
 
 
 
 
endmodule
endmodule
 
 
 
 

powered by: WebSVN 2.1.0

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