URL
https://opencores.org/ocsvn/theia_gpu/theia_gpu/trunk
Subversion Repositories theia_gpu
[/] [theia_gpu/] [branches/] [gpu_16_cores/] [rtl/] [GPU/] [HOST/] [Module_Host.v] - Rev 135
Compare with Previous | Blame | View Log
`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 Description: WIP *******************************************************************************/ `define MAX_VERTEX_IN_FRAME 8'd7 // WAS 8'd6 `define TAG_INSTRUCTION_ADDRESS_TYPE 2'b01 `define TAG_DATA_ADDRESS_TYPE 2'b10 `define SELECT_INST_MEM 3'b00 `define SELECT_SCENE_MEM 3'b01 `define SELECT_GEO_MEM 3'b10 `define SELECT_ALL_CORES `MAX_CORES'b1111 //XXX: Change for more cores `define HOST_IDLE 0 `define HOST_WRITE_INSTRUCTION 1 `define HOST_WAIT_INSTRUCTION 2 `define HOST_WRITE_SCENE_PARAMS 3 `define HOST_WAIT_SCENE_PARAMS 4 `define HOST_PREPARE_CORE_CONFIG 5 `define HOST_UNICAST_CORE_CONFIG 6 `define HOST_WAIT_CORE_CONFIG 7 `define HOST_PREPARE_NEXT_CORE_CONFIG 8 `define HOST_WAIT_DATA_READ_CONFIRMATION 10 `define HOST_BROADCAST_NEXT_VERTEX 11 `define HOST_WAIT_FOR_VERTEX 12 `define HOST_INITIAL_SCENE_PARAMS_STAGE 13 `define HOST_PREPARE_FOR_GEO_REQUESTS 14 `define HOST_ACK_GEO_REQUEST 15 `define HOST_GET_PRIMITIVE_COUNT 16 `define HOST_LAST_PRIMITIVE_REACHED 17 `define HOST_GPU_EXECUTION_DONE 18 //--------------------------------------------------------------- module Module_Host ( input wire Clock, input wire Reset, input wire iEnable, input wire iHostDataReadConfirmed, input wire [`WB_WIDTH-1:0] iMemorySize, input wire [`WB_WIDTH-1:0] iPrimitiveCount, //To Memory output wire [`WB_WIDTH-1:0] oReadAddress, input wire [`WB_WIDTH-1:0] iReadData, input wire iGPUCommitedResults, //To Hub/Switch output wire [`MAX_CORES-1:0] oCoreSelectMask, output reg [2:0] oMemSelect, output wire [`WB_WIDTH-1:0] DAT_O, output wire [`WB_WIDTH-1:0] ADR_O, output reg[1:0] TGA_O, output reg[`MAX_CORES-1:0] RENDREN_O, output wire CYC_O, output wire STB_O, output reg MST_O, output wire WE_O, input wire GRDY_I, //This means all the cores are done rading the primitive we send output reg GACK_O, //We set this to ACK that the cored read the primitive output wire STDONE_O, output reg oHostDataAvailable, input wire iGPUDone, input wire ACK_I ); //--------------------------------------------------------------- wire wLastPrimitive; assign wLastPrimitive = (wVertexCount >= iPrimitiveCount) ? 1'b1 : 1'b0; assign STDONE_O = wLastPrimitive; wire wWBMDone; reg rWBMEnable,rWBMReset,rCoreBroadCast; reg [`WB_WIDTH-1:0] rInitiaReadAddr; wire [`MAX_CORES-1:0] wCoreSelect; wire wLastValidReadAddress; wire [`WB_WIDTH-1:0] wWriteAddress; wire [7:0] wVertexCount; reg [`WB_WIDTH-1:0] rInitialWriteAddress; reg rSetWriteAddr; reg rIncCoreSelect,rResetVertexCount; //-------------------------------------------------------- assign WE_O = MST_O; assign oCoreSelectMask = (rCoreBroadCast) ? `SELECT_ALL_CORES : wCoreSelect; assign wLastValidReadAddress = (oReadAddress >= iMemorySize) ? 1'b1 : 1'b0; wire wLastParameter; assign wLastParameter = (oReadAddress >= 32'h12) ? 1'b1 : 1'b0; //-------------------------------------------------------- UPCOUNTER_POSEDGE # (`WB_WIDTH ) UPWADDR ( .Clock( Clock ), .Reset( Reset | rSetWriteAddr ), .Enable( iEnable & wWBMDone ), .Initial( rInitialWriteAddress ), .Q( wWriteAddress ) ); UPCOUNTER_POSEDGE # (8 ) PRIMCOUNT ( .Clock( Clock ), .Reset( Reset | rResetVertexCount ), .Enable( iEnable & wWBMDone ), .Initial( 8'b1 ), //WAS 0 .Q( wVertexCount ) ); //-------------------------------------------------------- CIRCULAR_SHIFTLEFT_POSEDGE_EX # (`MAX_CORES ) SHF1 ( .Clock( Clock ), .Reset( Reset ), .Initial( `MAX_CORES'b1 ), .Enable( rIncCoreSelect ), .O( wCoreSelect ) ); //-------------------------------------------------------- wire wShortCycle; //For instruction we send 2 packets per cycle //for the other we send 3 packets per cycle assign wShortCycle = (oMemSelect == `SELECT_INST_MEM) ? 1'b1 : 1'b0; WBMaster WBM ( .Clock( Clock ), .Reset( Reset | rWBMReset ), .iEnable( rWBMEnable ), .iInitialReadAddr( rInitiaReadAddr ), .iWriteAddr( wWriteAddress ), .oReadAddress( oReadAddress ), .iReadData( iReadData ), .iShortFlow( wShortCycle ), .STB_O( STB_O ), .ACK_I( ACK_I ), .CYC_O( CYC_O ), .DAT_O( DAT_O ), .ADR_O( ADR_O ), .oDone( wWBMDone ) ); //-------------------------------------------------------- // Current State Logic // reg [7:0] rHostCurrentState,rHostNextState; always @(posedge Clock or posedge Reset) begin if( Reset!=1 ) rHostCurrentState <= rHostNextState; else rHostCurrentState <= `HOST_IDLE; end //-------------------------------------------------------- wire wLastVertexInFrame; assign wLastVertexInFrame = (wVertexCount % `MAX_VERTEX_IN_FRAME == 1'b0 ) ? 1'b1 : 1'b0; // WAS ((wVertexCount % `MAX_VERTEX_IN_FRAME) == 1'b0 && wVertexCount != 0) ? 1'b1 : 1'b0; reg [31:0] StartTime; // Host Finite State Machine // always @( * ) begin case (rHostCurrentState) //---------------------------------------- //Wait for reset sequence to complete, //Or until we are enabled `HOST_IDLE: begin rWBMEnable <= 0; rInitiaReadAddr <= 1; //Start reading from 1, because 0 is the size rWBMReset <= 0; oMemSelect <= 0; TGA_O <= 0; MST_O <= 0; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 0; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if ( ~Reset & iEnable ) rHostNextState <= `HOST_WRITE_INSTRUCTION; else rHostNextState <= `HOST_IDLE; end //---------------------------------------- //Broadcast the instructions to all the cores `HOST_WRITE_INSTRUCTION: begin StartTime <= $time; rWBMEnable <= 1; //Enable Wish bone master rInitiaReadAddr <= 1; //Start reading from 1, because 0 is the size rWBMReset <= 0; //No need to reset since we just came from reset oMemSelect <= `SELECT_INST_MEM; //Start by sending the instructions TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_WAIT_INSTRUCTION; end //---------------------------------------- `HOST_WAIT_INSTRUCTION: begin rWBMEnable <= ~wWBMDone; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_INST_MEM; TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if ( wWBMDone && ~wLastValidReadAddress ) rHostNextState <= `HOST_WRITE_INSTRUCTION; else if (wWBMDone && wLastValidReadAddress ) rHostNextState <= `HOST_INITIAL_SCENE_PARAMS_STAGE; else rHostNextState <= `HOST_WAIT_INSTRUCTION; end //---------------------------------------- /* Make sure to read-pointer points to the first memory address at te params memory */ `HOST_INITIAL_SCENE_PARAMS_STAGE: begin rWBMEnable <= 0; rInitiaReadAddr <= 1; //Start reading from 1, because 0 is the size rWBMReset <= 1; oMemSelect <= `SELECT_SCENE_MEM; //We are reading from the scene memory TGA_O <= `TAG_DATA_ADDRESS_TYPE; //We will write to the DATA section of the core MEM MST_O <= 1; //Keep master signal in 1 for now rInitialWriteAddress <= 0; //We start writing from address zero now rSetWriteAddr <= 1; rCoreBroadCast <= 1; //Set to zero to unicast, starting from core 0 rIncCoreSelect <= 0; //Set to unicast to the next core RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_WRITE_SCENE_PARAMS; end //---------------------------------------- //Broadcast the instructions to all the cores `HOST_WRITE_SCENE_PARAMS: begin rWBMEnable <= 1; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_SCENE_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_WAIT_SCENE_PARAMS; end //---------------------------------------- `HOST_WAIT_SCENE_PARAMS: begin rWBMEnable <= ~wWBMDone; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_SCENE_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if ( wWBMDone && ~wLastParameter ) rHostNextState <= `HOST_WRITE_SCENE_PARAMS; else if (wWBMDone && wLastParameter ) rHostNextState <= `HOST_PREPARE_CORE_CONFIG; else rHostNextState <= `HOST_WAIT_SCENE_PARAMS; end //---------------------------------------- /* This state set the read Write Address pointer to CREG_PIXEL_2D_INITIAL_POSITION memory position, also selects the scene MEM from the external MEM MUX. */ `HOST_PREPARE_CORE_CONFIG: begin rWBMEnable <= 0; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_SCENE_MEM; //We are reading from the scene memory TGA_O <= `TAG_DATA_ADDRESS_TYPE; //We will write to the DATA section of the core MEM MST_O <= 1; //Keep master signal in 1 for now rInitialWriteAddress <= `CREG_PIXEL_2D_INITIAL_POSITION; //The address from which to start wrting @ the cores rSetWriteAddr <= 1; //Set to use the initial write address bellow rCoreBroadCast <= 0; //Set to zero to unicast, starting from core 0 rIncCoreSelect <= 0; //Set to unicast to the next core RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_UNICAST_CORE_CONFIG; end //---------------------------------------- `HOST_UNICAST_CORE_CONFIG: begin rWBMEnable <= 1; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_SCENE_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 0; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_WAIT_CORE_CONFIG; end //---------------------------------------- `HOST_WAIT_CORE_CONFIG: begin rWBMEnable <= ~wWBMDone; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_SCENE_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 0; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if (wWBMDone && !(oReadAddress % 2)) rHostNextState <= `HOST_UNICAST_CORE_CONFIG; else if (wWBMDone && (oReadAddress % 2) ) rHostNextState <= `HOST_PREPARE_NEXT_CORE_CONFIG; else rHostNextState <= `HOST_WAIT_CORE_CONFIG; end //---------------------------------------- /* Reset the WBM to tell it to start reading from address 0 at the Geometry memory. */ `HOST_PREPARE_NEXT_CORE_CONFIG: begin rWBMEnable <= 0; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_GEO_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 0; //The master signal goes to zero until request rInitialWriteAddress <= `CREG_PIXEL_2D_INITIAL_POSITION; //Write starting from this location on the cores rSetWriteAddr <= 1; //Set to use the initial write address bellow rCoreBroadCast <= 0; rIncCoreSelect <= 1; //Moving to configure the next core now RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if (wCoreSelect[`MAX_CORES-1] == 1) rHostNextState <= `HOST_PREPARE_FOR_GEO_REQUESTS; else rHostNextState <= `HOST_UNICAST_CORE_CONFIG; end //---------------------------------------- /* Prepare the write address for the next primitive. */ `HOST_PREPARE_FOR_GEO_REQUESTS: begin rWBMEnable <= 0; //Do not enable until we are resquested rInitiaReadAddr <= 32'hA; //Start reading from addr 0 @ GEO MEM rWBMReset <= 1; //Tell WBM to start reading from the addr bellow oMemSelect <= `SELECT_GEO_MEM; //Use external GEO mem for reading TGA_O <= `TAG_DATA_ADDRESS_TYPE; //We write to the data MEM @ the cores MST_O <= 0; //The master signal goes to zero until request rInitialWriteAddress <= `CREG_V0; //Write starting from this location on the cores rSetWriteAddr <= 1; //Set to use the initial write address bellow rCoreBroadCast <= 1; //From now on we only broadcast rIncCoreSelect <= 0; //Ignored during broadcasts RENDREN_O <= 0; rResetVertexCount <= 1; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if (iGPUDone) rHostNextState <= `HOST_GPU_EXECUTION_DONE; else rHostNextState <= `HOST_BROADCAST_NEXT_VERTEX; end //---------------------------------------- `HOST_ACK_GEO_REQUEST: begin rWBMEnable <= 0; //Do not enable until we are resquested rInitiaReadAddr <= 0; //Ignored rWBMReset <= 0; //Ignored oMemSelect <= `SELECT_GEO_MEM; //Use external GEO mem for reading TGA_O <= `TAG_DATA_ADDRESS_TYPE; //We write to the data MEM @ the cores MST_O <= 0; //The master signal goes to zero until request rInitialWriteAddress <= `CREG_V0; //Write starting from this location on the cores rSetWriteAddr <= 1; //Set to use the initial write address bellow rCoreBroadCast <= 1; //From now on we only broadcast rIncCoreSelect <= 0; //Ignored during broadcasts RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 1; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_BROADCAST_NEXT_VERTEX; end //---------------------------------------- /* Send the next primitive to the HUB/SWITCH unit so that it gets broadcasted to all the cores */ `HOST_BROADCAST_NEXT_VERTEX: begin rWBMEnable <= 1; //Start the Transmition rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_GEO_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; //Start the Transmition rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= `SELECT_ALL_CORES; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_WAIT_FOR_VERTEX; end //---------------------------------------- `HOST_WAIT_FOR_VERTEX: begin rWBMEnable <= ~wWBMDone; //Disable WBM when it is donw rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_GEO_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; //Start the Transmition rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= `SELECT_ALL_CORES; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; if (wWBMDone & ~wLastVertexInFrame ) rHostNextState <= `HOST_BROADCAST_NEXT_VERTEX; else if (wWBMDone & wLastVertexInFrame ) rHostNextState <= `HOST_GET_PRIMITIVE_COUNT; else rHostNextState <= `HOST_WAIT_FOR_VERTEX; /* if (wWBMDone) rHostNextState <= `HOST_WAIT_DATA_READ_CONFIRMATION; else rHostNextState <= `HOST_WAIT_FOR_VERTEX; */ end //---------------------------------------- `HOST_GET_PRIMITIVE_COUNT: begin rWBMEnable <= 0; //Disable WBM when it is donw rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= `SELECT_GEO_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; //Start the Transmition rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= `SELECT_ALL_CORES; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0;//1; if (wVertexCount >= iPrimitiveCount) rHostNextState <= `HOST_LAST_PRIMITIVE_REACHED; else rHostNextState <= `HOST_WAIT_DATA_READ_CONFIRMATION; end //---------------------------------------- /* we wait until all the cores are ready for the next primitive, this happens when the iHostDataReadConfirmed signal gets asserted */ `HOST_WAIT_DATA_READ_CONFIRMATION: begin rWBMEnable <= 0; //Do not enable until we are resquested rInitiaReadAddr <= 0; //Ignored rWBMReset <= 0; //Continue from previous read address oMemSelect <= `SELECT_GEO_MEM; //Use external GEO mem for reading TGA_O <= `TAG_DATA_ADDRESS_TYPE; //We write to the data MEM @ the cores MST_O <= 0; //The master signal goes to zero until request rInitialWriteAddress <= `CREG_V0; //Write starting from this location on the cores rSetWriteAddr <= 1; //Set to use the initial write address bellow rCoreBroadCast <= 1; //From now on we only broadcast rIncCoreSelect <= 0; //Ignored during broadcasts RENDREN_O <= `SELECT_ALL_CORES; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 1; if ( iHostDataReadConfirmed ) rHostNextState <= `HOST_ACK_GEO_REQUEST; else rHostNextState <= `HOST_WAIT_DATA_READ_CONFIRMATION; end //---------------------------------------- `HOST_LAST_PRIMITIVE_REACHED: begin rWBMEnable <= 0; //Disable WBM when it is donw rInitiaReadAddr <= 32'hA; //Reset primitive counter to first primitive rWBMReset <= 1; //Reset primitive counter to first primitive oMemSelect <= `SELECT_GEO_MEM; TGA_O <= `TAG_DATA_ADDRESS_TYPE; MST_O <= 1; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 1; rIncCoreSelect <= 0; RENDREN_O <= `SELECT_ALL_CORES; rResetVertexCount <= 0; //Reset the vertex count to zero GACK_O <= 0; //STDONE_O <= 1; oHostDataAvailable <= 0; if (iGPUCommitedResults) rHostNextState <= `HOST_PREPARE_FOR_GEO_REQUESTS; else rHostNextState <= `HOST_LAST_PRIMITIVE_REACHED; end //---------------------------------------- `HOST_GPU_EXECUTION_DONE: begin $display("THEIA Execution done in %dns\n",$time-StartTime); rWBMEnable <= 0; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= 0; TGA_O <= 0; MST_O <= 0; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 0; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_GPU_EXECUTION_DONE; end //---------------------------------------- default: begin rWBMEnable <= 0; rInitiaReadAddr <= 0; rWBMReset <= 0; oMemSelect <= 0; TGA_O <= 0; MST_O <= 0; rInitialWriteAddress <= 0; rSetWriteAddr <= 0; rCoreBroadCast <= 0; rIncCoreSelect <= 0; RENDREN_O <= 0; rResetVertexCount <= 0; GACK_O <= 0; //STDONE_O <= 0; oHostDataAvailable <= 0; rHostNextState <= `HOST_IDLE; end //---------------------------------------- endcase end endmodule