URL
https://opencores.org/ocsvn/theia_gpu/theia_gpu/trunk
Subversion Repositories theia_gpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/theia_gpu/branches/beta_1.2/rtl/TOP
- from Rev 82 to Rev 87
- ↔ Reverse comparison
Rev 82 → Rev 87
/Theia_Core.v
0,0 → 1,394
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
/********************************************************************************** |
Description: |
This is the top level block for THEIA. |
THEIA core has 5 main logical blocks called Units. |
This module implements the interconections between the Units. |
|
Units: |
> EXE: Mananges execution logic for the SHADERS. |
> GEO: Manages geometry data structures. |
> IO: Input/Output (Wishbone). |
> MEM: Internal memory, separate for Instructions and data. |
> CONTROL: Main control Finite state machine. |
|
Internal Buses: |
THEIA has separate instruction and data buses. |
THEIA avoids using tri-state buses by having separate input/output |
for each bus. |
There are 2 separate data buses since the Data memory |
has a Dual read channel. |
Please see the MEM unit chapter in the documentation for more details. |
|
External Buses: |
External buses are managed by the IO Unit. |
External buses follow the wishbone protocol. |
Please see the IO unit chapter in the documentation for more details. |
**********************************************************************************/ |
|
`timescale 1ns / 1ps |
`include "aDefinitions.v" |
|
module THEIACORE |
( |
|
input wire CLK_I, //Input clock |
input wire RST_I, //Input reset |
//Theia Interfaces |
input wire MST_I, //Master signal, THEIA enters configuration mode |
//when this gets asserted (see documentation) |
//Wish Bone Interface |
input wire [`WB_WIDTH-1:0] DAT_I, //Input data bus (Wishbone) |
output wire [`WB_WIDTH-1:0] DAT_O, //Output data bus (Wishbone) |
input wire ACK_I, //Input ack |
output wire ACK_O, //Output ack |
output wire [`WB_WIDTH-1:0] ADR_O, //Output address |
input wire [`WB_WIDTH-1:0] ADR_I, //Input address |
output wire WE_O, //Output write enable |
input wire WE_I, //Input write enable |
output wire STB_O, //Strobe signal, see wishbone documentation |
input wire STB_I, //Strobe signal, see wishbone documentation |
output wire CYC_O, //Bus cycle signal, see wishbone documentation |
input wire CYC_I, //Bus cycle signal, see wishbone documentation |
output wire [1:0] TGC_O, //Bus cycle tag, see THEAI documentation |
input wire [1:0] TGA_I, //Input address tag, see THEAI documentation |
output wire [1:0] TGA_O, //Output address tag, see THEAI documentation |
input wire [1:0] TGC_I, //Bus cycle tag, see THEAI documentation |
input wire GNT_I, //Bus arbiter 'Granted' signal, see THEAI documentation |
input wire RENDREN_I, |
|
`ifdef DEBUG |
input wire[`MAX_CORES-1:0] iDebug_CoreID, |
`endif |
//Control Register |
input wire [15:0] CREG_I, |
output wire DONE_O |
|
|
); |
|
//Alias this signals |
wire Clock,Reset; |
assign Clock = CLK_I; |
assign Reset = RST_I; |
|
wire wIO_Busy; |
wire [`DATA_ROW_WIDTH-1:0] wEXE_2__MEM_WriteData; |
wire [`DATA_ROW_WIDTH-1:0] wUCODE_RAMBus; |
wire [`DATA_ADDRESS_WIDTH-1:0] wEXE_2__MEM_wDataWriteAddress; |
wire w2IO__AddrIsImm; |
wire [`DATA_ADDRESS_WIDTH-1:0] wUCODE_RAMAddress; |
wire [`DATA_ADDRESS_WIDTH-1:0] w2IO__Adr_O_Pointer; |
wire [`DATA_ADDRESS_WIDTH-1:0] wGEO2_IO__Adr_O_Pointer; |
wire wEXE_2__DataWriteEnable; |
wire wUCODE_RAMWriteEnable; |
wire [2:0] RamBusOwner; |
//Unit intercoanection wires |
|
wire wCU2__MicrocodeExecutionDone; |
wire [`ROM_ADDRESS_WIDTH-1:0] InitialCodeAddress; |
wire [`ROM_ADDRESS_WIDTH-1:0] wInstructionPointer1,wInstructionPointer2; |
wire [`INSTRUCTION_WIDTH-1:0] wEncodedInstruction1,wEncodedInstruction2,wIO2_MEM__ExternalInstruction; |
wire wCU2__ExecuteMicroCode; |
wire [`ROM_ADDRESS_WIDTH-1:0] wIO2_MEM__InstructionWriteAddr; |
wire [95:0] wMEM_2__EXE_DataRead0, wMEM_2__EXE_DataRead1,wMEM_2__IO_DataRead0, wMEM_2__IO_DataRead1; |
wire [`DATA_ADDRESS_WIDTH-1:0] wEXE_2__MEM_DataReadAddress0,wEXE_2__MEM_DataReadAddress1; |
wire [`DATA_ADDRESS_WIDTH-1:0] wUCODE_RAMReadAddress0,wUCODE_RAMReadAddress1; |
|
|
wire [`WIDTH-1:0] w2IO__AddressOffset; |
wire [`DATA_ADDRESS_WIDTH-1:0] w2IO__DataWriteAddress; |
wire w2IO__Store; |
wire w2IO__EnableWBMaster; |
|
wire [`DATA_ADDRESS_WIDTH-1:0] wIO2_MEM__DataWriteAddress; |
wire [`DATA_ADDRESS_WIDTH-1:0] wIO_2_MEM__DataReadAddress0; |
wire [`DATA_ROW_WIDTH-1:0] wIO2_MEM__Bus; |
wire [`WIDTH-1:0] wIO2_MEM__Data; |
wire [`WIDTH-1:0] wIO2_WBM__Address; |
wire wIO2_MEM__DataWriteEnable; |
wire wIO2__Done; |
wire wCU2_GEO__GeometryFetchEnable; |
wire wIFU2__MicroCodeReturnValue; |
wire wCU2_BCU__ACK; |
wire wGEO2_CU__RequestAABBIU; |
wire wGEO2_CU__RequestBIU; |
wire wGEO2_CU__RequestTCC; |
wire wGEO2_CU__GeometryUnitDone; |
wire wGEO2_CU__Sync; |
wire wEXE2__uCodeDone; |
wire wEXE2_IFU__EXEBusy; |
wire [`DATA_ADDRESS_WIDTH-1:0] wEXE2_IDU_DataFordward_LastDestination; |
wire wALU2_EXE__BranchTaken; |
wire wALU2_IFU_BranchNotTaken; |
wire w2IO__SetAddress; |
wire wIDU2_IFU__IDUBusy; |
//Control Registe wires |
wire[15:0] wCR2_ControlRegister; |
wire wCR2_TextureMappingEnabled; |
wire wGEO2_CU__TFFDone; |
wire wCU2_GEO__TriggerTFF; |
wire wIO2_MEM_InstructionWriteEnable; |
wire wCU2_IO__WritePixel; |
wire wGEO2_IO__AddrIsImm; |
wire[31:0] wGEO2_IO__AddressOffset; |
wire wGEO2_IO__EnableWBMaster; |
wire wGEO2_IO__SetAddress; |
wire[`WIDTH-1:0] wGEO2__CurrentPitch,wCU2_GEO_Pitch; |
wire wCU2_GEO__SetPitch,wCU2_GEO__IncPicth; |
wire wCU2_FlipMemEnabled; |
wire w2MEM_FlipMemory; |
|
`ifdef DEBUG |
wire [`ROM_ADDRESS_WIDTH-1:0] wDEBUG_IDU2_EXE_InstructionPointer; |
`endif |
//-------------------------------------------------------- |
|
|
assign wCR2_TextureMappingEnabled = wCR2_ControlRegister[ `CR_EN_TEXTURE ]; |
wire wCU2_FlipMem; |
//-------------------------------------------------------- |
//Control Unit Instance |
ControlUnit CU |
( |
.Clock(Clock), |
.Reset(Reset), |
.oFlipMemEnabled( wCU2_FlipMemEnabled ), |
.oFlipMem( wCU2_FlipMem ), |
.iControlRegister( wCR2_ControlRegister ), |
.oRamBusOwner( RamBusOwner ), |
.oGFUEnable( wCU2_GEO__GeometryFetchEnable ), |
.iTriggerAABBIURequest( wGEO2_CU__RequestAABBIU ), |
.iTriggerBIURequest( wGEO2_CU__RequestBIU ), |
.iTriggertTCCRequest( wGEO2_CU__RequestTCC ), |
.oUCodeEnable( wCU2__ExecuteMicroCode ), |
.oCodeInstructioPointer( InitialCodeAddress ), |
.iUCodeDone( wCU2__MicrocodeExecutionDone ), |
.iIODone( wIO2__Done ), |
.oIOWritePixel( wCU2_IO__WritePixel ), |
.iUCodeReturnValue( wIFU2__MicroCodeReturnValue ), |
.iGEOSync( wGEO2_CU__Sync ), |
.iTFFDone( wGEO2_CU__TFFDone ), |
.oTriggerTFF( wCU2_GEO__TriggerTFF ), |
.MST_I( MST_I ), |
.oSetCurrentPitch( wCU2_GEO__SetPitch ), |
.iGFUDone( wGEO2_CU__GeometryUnitDone ), |
.iRenderEnable( RENDREN_I ), |
|
`ifdef DEBUG |
.iDebug_CoreID( iDebug_CoreID ), |
`endif |
.oDone( DONE_O ) |
|
); |
|
|
|
|
//-------------------------------------------------------- |
|
//assign w2MEM_FlipMemory = (wCU2__ExecuteMicroCode | wCU2_FlipMem ) & wCU2_FlipMemEnabled; |
assign w2MEM_FlipMemory = wCU2_FlipMem & wCU2_FlipMemEnabled; |
MemoryUnit MEM |
( |
.Clock(Clock), |
.Reset(Reset), |
|
.iFlipMemory( w2MEM_FlipMemory ), |
|
//Data Bus to/from EXE |
.iDataReadAddress1_EXE( wEXE_2__MEM_DataReadAddress0 ), |
.iDataReadAddress2_EXE( wEXE_2__MEM_DataReadAddress1 ), |
.oData1_EXE( wMEM_2__EXE_DataRead0 ), |
.oData2_EXE( wMEM_2__EXE_DataRead1 ), |
.iDataWriteEnable_EXE( wEXE_2__DataWriteEnable ), |
.iDataWriteAddress_EXE( wEXE_2__MEM_wDataWriteAddress ), |
.iData_EXE( wEXE_2__MEM_WriteData ), |
|
//Data Bus to/from IO |
|
.iDataReadAddress1_IO( wIO_2_MEM__DataReadAddress0 ), |
.iDataReadAddress2_IO( wIO_2_MEM__DataReadAddress1 ), |
.oData1_IO( wMEM_2__IO_DataRead0 ), |
.oData2_IO( wMEM_2__IO_DataRead1 ), |
.iDataWriteEnable_IO( wIO2_MEM__DataWriteEnable ), |
.iDataWriteAddress_IO( wIO2_MEM__DataWriteAddress ), |
.iData_IO( wIO2_MEM__Bus ), |
|
|
//Instruction Bus |
.iInstructionReadAddress1( wInstructionPointer1 ), |
.iInstructionReadAddress2( wInstructionPointer2 ), |
.oInstruction1( wEncodedInstruction1 ), |
.oInstruction2( wEncodedInstruction2 ), |
.iInstructionWriteEnable( wIO2_MEM_InstructionWriteEnable ), |
.iInstructionWriteAddress( wIO2_MEM__InstructionWriteAddr ), |
.iInstruction( wIO2_MEM__ExternalInstruction ), |
.iControlRegister( CREG_I ), |
.oControlRegister( wCR2_ControlRegister ) |
|
); |
|
////-------------------------------------------------------- |
|
|
ExecutionUnit EXE |
( |
|
.Clock( Clock), |
.Reset( Reset ), |
.iInitialCodeAddress( InitialCodeAddress ), |
.iInstruction1( wEncodedInstruction1 ), |
.iInstruction2( wEncodedInstruction2 ), |
.oInstructionPointer1( wInstructionPointer1 ), |
.oInstructionPointer2( wInstructionPointer2 ), |
.iDataRead0( wMEM_2__EXE_DataRead0 ), |
.iDataRead1( wMEM_2__EXE_DataRead1 ), |
.iTrigger( wCU2__ExecuteMicroCode ), |
.oDataReadAddress0( wEXE_2__MEM_DataReadAddress0 ), |
.oDataReadAddress1( wEXE_2__MEM_DataReadAddress1 ), |
.oDataWriteEnable( wEXE_2__DataWriteEnable ), |
.oDataWriteAddress( wEXE_2__MEM_wDataWriteAddress ), |
.oDataBus( wEXE_2__MEM_WriteData ), |
.oReturnCode( wIFU2__MicroCodeReturnValue ), |
|
`ifdef DEBUG |
.iDebug_CoreID( iDebug_CoreID ), |
`endif |
.oDone( wCU2__MicrocodeExecutionDone ) |
|
); |
|
////-------------------------------------------------------- |
wire wGEO2__RequestingTextures; |
wire w2IO_WriteBack_Set; |
|
GeometryUnit GEO |
( |
.Clock( Clock ), |
.Reset( Reset ), |
.iEnable( wCU2_GEO__GeometryFetchEnable ), |
.iIOBusy( wIO_Busy ), |
.iTexturingEnable( wCR2_TextureMappingEnabled ), |
//Wires from IO |
.iData_WBM( wIO2_MEM__Data ), |
.iDataReady_WBM( wIO2__Done ), |
//Wires to WBM |
.oAddressWBM_Imm( wGEO2_IO__AddressOffset ), |
.oAddressWBM_fromMEM( wGEO2_IO__Adr_O_Pointer ), |
.oAddressWBM_IsImm( wGEO2_IO__AddrIsImm ), |
.oEnable_WBM( wGEO2_IO__EnableWBMaster ), |
.oSetAddressWBM( wGEO2_IO__SetAddress ), |
.oSetIOWriteBackAddr( w2IO_WriteBack_Set ), |
//Wires to CU |
.oRequest_AABBIU( wGEO2_CU__RequestAABBIU ), |
.oRequest_BIU( wGEO2_CU__RequestBIU ), |
.oRequest_TCC( wGEO2_CU__RequestTCC ), |
.oTFFDone( wGEO2_CU__TFFDone ), |
//Wires to RAM-Bus MUX |
.oRAMWriteAddress( w2IO__DataWriteAddress ), |
.oRAMWriteEnable( w2IO__Store ), |
//Wires from Execution Unit |
.iMicrocodeExecutionDone( wCU2__MicrocodeExecutionDone ), |
.iMicroCodeReturnValue( wIFU2__MicroCodeReturnValue ), |
.oSync( wGEO2_CU__Sync ), |
.iTrigger_TFF( wCU2_GEO__TriggerTFF ), |
.iBIUHit( wIFU2__MicroCodeReturnValue ), |
.oRequestingTextures( wGEO2__RequestingTextures ), |
`ifdef DEBUG |
.iDebug_CoreID( iDebug_CoreID ), |
`endif |
.oDone( wGEO2_CU__GeometryUnitDone ) |
); |
|
|
assign TGA_O = (wGEO2__RequestingTextures) ? 2'b1: 2'b0; |
//--------------------------------------------------------------------------------------------------- |
wire[`DATA_ADDRESS_WIDTH-1:0] wIO_2_MEM__DataReadAddress1; |
assign wEXE_2__MEM_DataReadAddress1 = (wCU2_IO__WritePixel == 0) ? wUCODE_RAMReadAddress1 : wIO_2_MEM__DataReadAddress1; |
assign w2IO__EnableWBMaster = (wCU2_IO__WritePixel == 0 ) ? wGEO2_IO__EnableWBMaster : wCU2_IO__WritePixel; |
assign w2IO__AddrIsImm = (wCU2_IO__WritePixel == 0 ) ? wGEO2_IO__AddrIsImm : 1'b0; |
assign w2IO__AddressOffset = (wCU2_IO__WritePixel == 0 ) ? wGEO2_IO__AddressOffset : 32'b0; |
assign w2IO__Adr_O_Pointer = (wCU2_IO__WritePixel == 0 ) ? wGEO2_IO__Adr_O_Pointer : `OREG_ADDR_O; |
//assign w2IO__Adr_O_Pointer = (wCU2_IO__WritePixel == 0 ) ? wGEO2_IO__Adr_O_Pointer : `CREG_PIXEL_2D_INITIAL_POSITION; |
|
wire w2IO_MasterCycleType; |
assign w2IO_MasterCycleType = (wCU2_IO__WritePixel) ? `WB_SIMPLE_WRITE_CYCLE : `WB_SIMPLE_READ_CYCLE; |
|
|
|
assign w2IO__SetAddress = (wCU2_IO__WritePixel == 0 )? wGEO2_IO__SetAddress : wCU2_GEO__SetPitch; |
|
|
IO_Unit IO |
( |
.Clock( Clock ), |
.Reset( Reset ), |
.iEnable( w2IO__EnableWBMaster ), |
.iBusCyc_Type( w2IO_MasterCycleType ), |
|
.iStore( w2IO__Store ), |
.iAdr_DataWriteBack( w2IO__DataWriteAddress ), |
.iAdr_O_Set( w2IO__SetAddress ), |
.iAdr_O_Imm( w2IO__AddressOffset ), |
.iAdr_O_Type( w2IO__AddrIsImm ), |
.iAdr_O_Pointer( w2IO__Adr_O_Pointer ), |
.iReadDataBus( wMEM_2__IO_DataRead0 ), |
.iReadDataBus2( wMEM_2__IO_DataRead1 ), |
.iDat_O_Pointer( `OREG_PIXEL_COLOR ), |
|
|
.oDataReadAddress( wIO_2_MEM__DataReadAddress0 ), |
.oDataReadAddress2( wIO_2_MEM__DataReadAddress1 ), |
.oDataWriteAddress( wIO2_MEM__DataWriteAddress ), |
.oDataBus( wIO2_MEM__Bus ), |
.oInstructionBus( wIO2_MEM__ExternalInstruction ), |
|
.oDataWriteEnable( wIO2_MEM__DataWriteEnable ), |
.oData( wIO2_MEM__Data ), |
.oInstructionWriteEnable( wIO2_MEM_InstructionWriteEnable ), |
.oInstructionWriteAddress( wIO2_MEM__InstructionWriteAddr ), |
.iWriteBack_Set( w2IO_WriteBack_Set ), |
.oBusy( wIO_Busy ), |
.oDone( wIO2__Done ), |
.MST_I( MST_I ), |
//Wish Bone Interface |
.DAT_I( DAT_I ), |
.DAT_O( DAT_O ), |
.ACK_I( ACK_I & GNT_I ), |
.ACK_O( ACK_O ), |
.ADR_O( ADR_O ), |
.ADR_I( ADR_I ), |
.WE_O( WE_O ), |
.WE_I( WE_I ), |
.STB_O( STB_O ), |
.STB_I( STB_I ), |
.CYC_O( CYC_O ), |
.TGA_I( TGA_I ), |
.CYC_I( CYC_I ), |
.GNT_I( GNT_I ), |
.TGC_O( TGC_O ) |
|
|
); |
//--------------------------------------------------------------------------------------------------- |
endmodule |
/Theia.v
0,0 → 1,301
`timescale 1ns / 1ps |
`include "aDefinitions.v" |
|
//--------------------------------------------------------------------------- |
module THEIA |
( |
|
input wire CLK_I, //Input clock |
input wire RST_I, //Input reset |
//Theia Interfaces |
input wire MST_I, //Master signal, THEIA enters configuration mode |
//when this gets asserted (see documentation) |
//Wish Bone Interface |
input wire [`WB_WIDTH-1:0] DAT_I, //Input data bus (Wishbone) |
output wire [`WB_WIDTH-1:0] DAT_O, //Output data bus (Wishbone) |
input wire ACK_I, //Input ack |
output wire ACK_O, //Output ack |
output wire [`WB_WIDTH-1:0] ADR_O, //Output address |
input wire [`WB_WIDTH-1:0] ADR_I, //Input address |
output wire WE_O, //Output write enable |
input wire WE_I, //Input write enable |
output wire STB_O, //Strobe signal, see wishbone documentation |
input wire STB_I, //Strobe signal, see wishbone documentation |
output wire CYC_O, //Bus cycle signal, see wishbone documentation |
input wire CYC_I, //Bus cycle signal, see wishbone documentation |
output wire [1:0] TGC_O, //Bus cycle tag, see THEAI documentation |
input wire [1:0] TGA_I, //Input address tag, see THEAI documentation |
output wire [1:0] TGA_O, //Output address tag, see THEAI documentation |
input wire [1:0] TGC_I, //Bus cycle tag, see THEAI documentation |
input wire [`MAX_CORES-1:0] SEL_I, //The WishBone Master uses this signal to configure a specific core (TBD, not sure is needed) |
input wire [`MAX_CORES-1:0] RENDREN_I, |
//Control Register |
input wire [15:0] CREG_I, |
output wire DONE_O |
|
); |
|
|
|
|
wire [`MAX_CORES-1:0] wDone; |
wire [`MAX_CORES-1:0] wBusGranted,wBusRequest; |
wire [`WB_WIDTH-1:0] wDAT_O_0,wDAT_O_1,wDAT_O_2,wDAT_O_3; |
wire [`WB_WIDTH-1:0] wADR_O_0,wADR_O_1,wADR_O_2,wADR_O_3; |
wire [1:0] wTGA_O_0,wTGA_O_1,wTGA_O_2,wTGA_O_3; |
wire [1:0] wBusSelect; |
|
//wire wSTB_O_0,wSTB_O_1,wSTB_O_2,wSTB_O_3; |
//wire wWE_O_0,wWE_O_1,wWE_O_2,wWE_O_3; |
|
wire [`MAX_CORES-1:0] wSTB_O,wWE_O,wACK_O; |
|
|
wire [`MAX_CORES-1:0] wSTB_I; |
wire [`MAX_CORES-1:0] wMST_I; |
wire [`MAX_CORES-1:0] wACK_I; |
wire [`MAX_CORES-1:0] wCYC_I; |
wire [1:0] wTGA_I[`MAX_CORES-1:0]; |
|
assign DONE_O = wDone[0] & wDone[1] & wDone[2] & wDone[3]; |
//assign DONE_O = wDone[0]; |
//assign DONE_O = wDone[0] & wDone[1];// & wDone[2]; |
|
//---------------------------------------------------------------- |
// assign wDone[3:1] = 3'b111; |
// assign wBusRequest[3:2] = 0; |
// assign wSTB_O[3:2] = 0; |
// assign wWE_O[3:2] = 0; |
Module_BusArbitrer ARB1 |
( |
.Clock( CLK_I ), |
.Reset( RST_I ), |
.iRequest( wBusRequest ), |
.oGrant( wBusGranted ), |
.oBusSelect( wBusSelect ) |
|
); |
//---------------------------------------------------------------- |
//The Muxes |
//DAT_O Mux |
MUXFULLPARALELL_2SEL_GENERIC # ( `WB_WIDTH ) MUX_DAT_O |
( |
.Sel(wBusSelect), |
.I1(wDAT_O_0), |
.I2(wDAT_O_1), |
.I3(wDAT_O_2), |
.I4(wDAT_O_3), |
.O1( DAT_O ) |
); |
|
MUXFULLPARALELL_2SEL_GENERIC # ( `WB_WIDTH ) MUX_ADR_O |
( |
.Sel(wBusSelect), |
.I1(wADR_O_0), |
.I2(wADR_O_1), |
.I3(wADR_O_2), |
.I4(wADR_O_3), |
.O1( ADR_O ) |
); |
|
|
|
MUXFULLPARALELL_2SEL_GENERIC # ( 1 ) MUX_STB_O |
( |
.Sel(wBusSelect), |
.I1(wSTB_O[0]), |
.I2(wSTB_O[1]), |
.I3(wSTB_O[2]), |
.I4(wSTB_O[3]), |
.O1( STB_O ) |
); |
|
|
MUXFULLPARALELL_2SEL_GENERIC # ( 1 ) MUX_WE_O |
( |
.Sel(wBusSelect), |
.I1(wWE_O[0]), |
.I2(wWE_O[1]), |
.I3(wWE_O[2]), |
.I4(wWE_O[3]), |
.O1( WE_O ) |
); |
|
|
MUXFULLPARALELL_2SEL_GENERIC # ( 2 ) MUX_TGA_O |
( |
.Sel(wBusSelect), |
.I1(wTGA_O_0), |
.I2(wTGA_O_1), |
.I3(wTGA_O_2), |
.I4(wTGA_O_3), |
.O1( TGA_O ) |
); |
|
|
assign ACK_O = (wACK_O[0] | wACK_O[1] | wACK_O[2] | wACK_O[3]); |
|
assign wMST_I[0] = (SEL_I[0]) ? MST_I : 0; |
assign wMST_I[1] = (SEL_I[1]) ? MST_I : 0; |
assign wMST_I[2] = (SEL_I[2]) ? MST_I : 0; |
assign wMST_I[3] = (SEL_I[3]) ? MST_I : 0; |
|
assign wSTB_I[0] = (SEL_I[0]) ? STB_I : 0; |
assign wSTB_I[1] = (SEL_I[1]) ? STB_I : 0; |
assign wSTB_I[2] = (SEL_I[2]) ? STB_I : 0; |
assign wSTB_I[3] = (SEL_I[3]) ? STB_I : 0; |
|
assign wCYC_I[0] = (SEL_I[0]) ? CYC_I : 0; |
assign wCYC_I[1] = (SEL_I[1]) ? CYC_I : 0; |
assign wCYC_I[2] = (SEL_I[2]) ? CYC_I : 0; |
assign wCYC_I[3] = (SEL_I[3]) ? CYC_I : 0; |
|
assign wTGA_I[0] = (SEL_I[0]) ? TGA_I : 0; |
assign wTGA_I[1] = (SEL_I[1]) ? TGA_I : 0; |
assign wTGA_I[2] = (SEL_I[2]) ? TGA_I : 0; |
assign wTGA_I[3] = (SEL_I[3]) ? TGA_I : 0; |
|
//---------------------------------------------------------------- |
|
THEIACORE THEIA_CORE0 |
( |
.CLK_I( CLK_I ), |
.RST_I( RST_I ), |
.RENDREN_I( RENDREN_I[0] ), |
|
//Slave signals |
.ADR_I( ADR_I ), |
.WE_I( WE_I ), |
.STB_I( wSTB_I[0] ), |
//----------------------------------- |
//This signal behaves in a very funny way... |
// |
.ACK_I( ACK_I ), |
//----------------------------------- |
.CYC_I( wCYC_I[0] ), |
.MST_I( wMST_I[0] ), |
.TGA_I( wTGA_I[0] ), |
.CREG_I( CREG_I ), |
|
//Master Signals |
.WE_O ( wWE_O[0] ), |
.STB_O( wSTB_O[0] ), |
.ACK_O( wACK_O[0] ), |
.DAT_O( wDAT_O_0 ), |
.ADR_O( wADR_O_0 ), |
.CYC_O( wBusRequest[0] ), |
.GNT_I( wBusGranted[0] ), |
.TGA_O( wTGA_O_0 ), |
`ifdef DEBUG |
.iDebug_CoreID( `MAX_CORES'd0 ), |
`endif |
//Other |
.DAT_I( DAT_I ), |
.DONE_O( wDone[0] ) |
|
); |
//---------------------------------------------------------------- |
THEIACORE THEIA_CORE1 |
( |
.CLK_I( CLK_I ), |
.RST_I( RST_I ), |
.RENDREN_I( RENDREN_I[1] ), |
|
//Slave signals |
.ADR_I( ADR_I ), |
.WE_I( WE_I ), |
.STB_I( wSTB_I[1] ),//ok |
.ACK_I( ACK_I ), |
.CYC_I( wCYC_I[1] ),//ok |
.MST_I( wMST_I[1] ),//ok |
.TGA_I( wTGA_I[1] ),//ok |
.CREG_I( CREG_I ), |
|
//Master Signals |
.WE_O ( wWE_O[1] ), |
.STB_O( wSTB_O[1] ), |
.ACK_O( wACK_O[1] ), |
.DAT_O( wDAT_O_1 ), |
.ADR_O( wADR_O_1 ), |
.CYC_O( wBusRequest[1] ), |
.GNT_I( wBusGranted[1] ), |
.TGA_O( wTGA_O_1 ), |
`ifdef DEBUG |
.iDebug_CoreID( `MAX_CORES'd1 ), |
`endif |
//Other |
.DAT_I( DAT_I ), |
.DONE_O( wDone[1] ) |
|
); |
//---------------------------------------------------------------- |
THEIACORE THEIA_CORE2 |
( |
.CLK_I( CLK_I ), |
.RST_I( RST_I ), |
.RENDREN_I( RENDREN_I[2] ), |
|
//Slave signals |
.ADR_I( ADR_I ), |
.WE_I( WE_I ), |
.STB_I( wSTB_I[2] ), |
.ACK_I( ACK_I ), |
.CYC_I( wCYC_I[2] ), |
.MST_I( wMST_I[2] ), |
.TGA_I( wTGA_I[2] ), |
.CREG_I( CREG_I ), |
|
//Master Signals |
.WE_O ( wWE_O[2] ), |
.STB_O( wSTB_O[2] ), |
.ACK_O( wACK_O[2] ), |
.DAT_O( wDAT_O_2 ), |
.ADR_O( wADR_O_2 ), |
.CYC_O( wBusRequest[2] ), |
.GNT_I( wBusGranted[2] ), |
.TGA_O( wTGA_O_2 ), |
`ifdef DEBUG |
.iDebug_CoreID( `MAX_CORES'd2 ), |
`endif |
//Other |
.DAT_I( DAT_I ), |
.DONE_O( wDone[2] ) |
|
); |
//---------------------------------------------------------------- |
THEIACORE THEIA_CORE3 |
( |
.CLK_I( CLK_I ), |
.RST_I( RST_I ), |
.RENDREN_I( RENDREN_I[3] ), |
|
//Slave signals |
.ADR_I( ADR_I ), |
.WE_I( WE_I ), |
.STB_I( wSTB_I[3] ), |
.ACK_I( ACK_I ), |
.CYC_I( wCYC_I[3] ), |
.MST_I( wMST_I[3] ), |
.TGA_I( wTGA_I[3] ), |
.CREG_I( CREG_I ), |
|
//Master Signals |
.WE_O ( wWE_O[3] ), |
.STB_O( wSTB_O[3] ), |
.ACK_O( wACK_O[3] ), |
.DAT_O( wDAT_O_3 ), |
.ADR_O( wADR_O_3 ), |
.CYC_O( wBusRequest[3] ), |
.GNT_I( wBusGranted[3] ), |
.TGA_O( wTGA_O_3 ), |
`ifdef DEBUG |
.iDebug_CoreID( `MAX_CORES'd3 ), |
`endif |
//Other |
.DAT_I( DAT_I ), |
.DONE_O( wDone[3] ) |
|
); |
//---------------------------------------------------------------- |
endmodule |
//--------------------------------------------------------------------------- |
/Module_BusArbitrer.v
0,0 → 1,89
`timescale 1ns / 1ps |
`include "aDefinitions.v" |
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
|
|
module Module_BusArbitrer |
( |
input wire Clock, |
input wire Reset, |
|
input wire [`MAX_CORES-1:0] iRequest, |
output wire [`MAX_CORES-1:0] oGrant, |
output wire [1:0] oBusSelect |
); |
|
|
|
|
|
wire wFFMS_connect; |
wire wIncRR_pointer; |
wire[3:0] wCurrentMasterMask; |
reg[3:0] wCurrentBusMaster; |
wire wCurrentRequest; |
|
//Just one requester can have the bus at a given |
//point in time, the mask makes sure this happens |
assign oGrant[0] = iRequest[0] & wCurrentMasterMask[0]; |
assign oGrant[1] = iRequest[1] & wCurrentMasterMask[1]; |
assign oGrant[2] = iRequest[2] & wCurrentMasterMask[2]; |
assign oGrant[3] = iRequest[3] & wCurrentMasterMask[3]; |
|
|
//When a requester relinquishes the bus (by negating its [iRequest] signal), |
//the switch is turned to the next position |
//So while iRequest == 1 the ciruclar list will not move |
CIRCULAR_SHIFTLEFT_POSEDGE_EX # (4) SHL_A |
( |
.Clock( Clock ), |
.Enable( ~wCurrentRequest ), |
.Reset( Reset ), |
.Initial(4'b1), |
.O( wCurrentMasterMask ) |
|
); |
|
assign oBusSelect = wCurrentBusMaster; |
|
MUXFULLPARALELL_2SEL_GENERIC # ( 1 ) MUXA |
( |
.Sel(wCurrentBusMaster[1:0]), |
.I1(iRequest[0]), |
.I2(iRequest[1]), |
.I3(iRequest[2]), |
.I4(iRequest[3]), |
.O1( wCurrentRequest ) |
); |
|
always @ ( * ) |
begin |
case (wCurrentMasterMask) |
4'b0001: wCurrentBusMaster <= 0; |
4'b0010: wCurrentBusMaster <= 1; |
4'b0100: wCurrentBusMaster <= 2; |
4'b1000: wCurrentBusMaster <= 3; |
default: wCurrentBusMaster <= 0; |
endcase |
end |
|
endmodule |