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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [icarus_version/] [rtl/] [Module_Host.v] - Rev 214

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

`timescale 1ns / 1ps
`include "aDefinitions.v"
`ifdef VERILATOR
`include "Module_HostWBM.v"
`endif
 
 
/**********************************************************************************
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      `WIDTH'd7 // WAS 8'd6
`define TAG_INSTRUCTION_ADDRESS_TYPE 2'b01
`define TAG_DATA_ADDRESS_TYPE        2'b10
`define SELECT_INST_MEM              2'b00
`define SELECT_SCENE_MEM             2'b01
`define SELECT_GEO_MEM               2'b10
 
 
`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
`define HOST_PREPARE_BROADCAST_CREG_MAX_PRIMITIVES  19
`define HOST_BROADCAST_CREG_MAX_PRIMITIVES    20
`define HOST_WAIT_CREG_MAX_PRIMITIVES     21
 
//---------------------------------------------------------------
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 reg [`MAX_CORES-1:0]      oCoreSelectMask,
 output reg [1: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,
 output reg                       oRenderDone,
 
 input wire [`WIDTH-1:0] iWidth,iHeight,
 
 
 input wire                       ACK_I
);
wire wGPUDone;
 
//Need this flop to break combinatorial loop asserted by verilator!
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD_DONE
        (
	      .Clock(Clock),
	      .Reset(Reset),
	      .Enable( 1'b1 ),
	      .D(iGPUDone),
	      .Q(wGPUDone)
        );
 
 
//---------------------------------------------------------------
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 [`WIDTH-1: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;
 
 
wire wLastCoreSelected;
assign wLastCoreSelected = wCoreSelect[`MAX_CORES-1];
 
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 # ( 32 ) PRIMCOUNT
 (
 .Clock(  Clock                   ), 
 .Reset(   Reset | rResetVertexCount  ),
 .Enable(  iEnable & wWBMDone     ),
 .Initial( `WIDTH'b1   ), 
 .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 HOST_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
//--------------------------------------------------------
 
reg [63:0] i;
reg [63:0] RenderedPixels;
wire wLastVertexInFrame;
assign wLastVertexInFrame = 
(wVertexCount % `MAX_VERTEX_IN_FRAME == 32'b0 ) ? 1'b1 : 1'b0;
 
 
reg [63:0] StartTime;
 
// Host Finite State Machine //
always @( * )
 begin
 
  case (rHostCurrentState)
  //----------------------------------------
  //Wait for reset sequence to complete,
  //Or until we are enabled
  `HOST_IDLE:
  begin
//  `ifndef VERILATOR
   RenderedPixels = 0;
 // `endif 
 
   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;
   oCoreSelectMask       = wCoreSelect;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
   if ( ~Reset & iEnable )
   begin
    $display("-I- HOST: Broadcasting User code to all Cores\n"); 
    `ifndef VERILATOR
    $fflush;
    `endif
 
    rHostNextState = `HOST_WRITE_INSTRUCTION;
   end 
   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;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
   oRenderDone           = 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;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0; 
   oHostDataAvailable    = 0;
	oRenderDone           = 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
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;                       //Set to unicast to the next core
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0; 
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
   $display("-I- HOST: Configuring Core Mask %b\n",oCoreSelectMask); 
   `ifndef VERILATOR
   $fflush;
   `endif
 
 
   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;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 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;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 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  = {16'b0,`CREG_PIXEL_2D_INITIAL_POSITION}; //The address from which to start wrting @ the cores
   rSetWriteAddr         = 1;                                       //Set to use the initial write address bellow
   oCoreSelectMask       = wCoreSelect;
   rIncCoreSelect        = 0;                                       //Set to unicast to the next core
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 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;
   oCoreSelectMask       = wCoreSelect;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 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;
   oCoreSelectMask       = wCoreSelect;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
 
   if (wWBMDone && ((oReadAddress % 2) == `WB_WIDTH'b0))
    rHostNextState = `HOST_UNICAST_CORE_CONFIG;
   else if (wWBMDone && ((oReadAddress % 2) != `WB_WIDTH'b0)) 
    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  = {16'b0,`CREG_PIXEL_2D_INITIAL_POSITION}; //Write starting from this location on the cores
   rSetWriteAddr         = 1;                                       //Set to use the initial write address bellow
   oCoreSelectMask       = wCoreSelect;   
   rIncCoreSelect        = 1;                                       //Moving to configure the next core now
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
   if (wLastCoreSelected)
    rHostNextState = `HOST_PREPARE_BROADCAST_CREG_MAX_PRIMITIVES;
   else
    rHostNextState = `HOST_UNICAST_CORE_CONFIG;
  end
  //----------------------------------------
  `HOST_PREPARE_BROADCAST_CREG_MAX_PRIMITIVES:
  begin
   rWBMEnable            = 0;                                       //Do not enable until we are resquested
   rInitiaReadAddr       = 32'd6;											  //Start reading from here, it has the # of primites
   rWBMReset             = 1;                                       //Tell WBM to start reading from the addr bellow
   oMemSelect            = `SELECT_GEO_MEM;                         //We are reading from the geometry memory
   TGA_O                 = `TAG_DATA_ADDRESS_TYPE;                  //We will write to the DATA section of the core MEM
   MST_O                 = 0;                                       //Keep master signal in 0 for now
   rInitialWriteAddress  = {16'b0,`CREG_MAX_PRIMITIVES};            //The address from which to start wrting @ the cores
   rSetWriteAddr         = 1;                                       //Set to use the initial write address bellow
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;                                       //Set to unicast to the next core
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
 
   rHostNextState = `HOST_BROADCAST_CREG_MAX_PRIMITIVES;
	end
	//----------------------------------------
	`HOST_BROADCAST_CREG_MAX_PRIMITIVES:
	begin
	rWBMEnable            = 1;
   rInitiaReadAddr       = 0;
   rWBMReset             = 0;
   oMemSelect            = `SELECT_GEO_MEM;
   TGA_O                 = `TAG_DATA_ADDRESS_TYPE;
   MST_O                 = 1;
   rInitialWriteAddress  = 0;
   rSetWriteAddr         = 0;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
   rHostNextState = `HOST_WAIT_CREG_MAX_PRIMITIVES;
  end
  //----------------------------------------
  `HOST_WAIT_CREG_MAX_PRIMITIVES:
  begin
   rWBMEnable            = ~wWBMDone;
   rInitiaReadAddr       = 0;
   rWBMReset             = 0;
   oMemSelect            = `SELECT_GEO_MEM;
   TGA_O                 = `TAG_DATA_ADDRESS_TYPE;
   MST_O                 = 1;
   rInitialWriteAddress  = 0;
   rSetWriteAddr         = 0;
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
 
   if (wWBMDone )
	 rHostNextState = `HOST_PREPARE_FOR_GEO_REQUESTS;
   else
    rHostNextState = `HOST_WAIT_CREG_MAX_PRIMITIVES;
 
  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  = {16'b0,`CREG_V0};       //Write starting from this location on the cores
   rSetWriteAddr         = 1;                      //Set to use the initial write address bellow
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;                      //Ignored during broadcasts 
   RENDREN_O             = 0;
   rResetVertexCount     = 1;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
   if (RenderedPixels >= (iWidth*iHeight))//(wGPUDone)
    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  = {16'b0,`CREG_V0};       //Write starting from this location on the cores
   rSetWriteAddr         = 1;                      //Set to use the initial write address bellow
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;                      //Ignored during broadcasts 
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 1;
   oHostDataAvailable    = 0;
	oRenderDone           = 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;        
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0; 
   RENDREN_O             = `SELECT_ALL_CORES;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 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; 
   oCoreSelectMask       = `SELECT_ALL_CORES;   
   rIncCoreSelect        = 0;
   RENDREN_O             = `SELECT_ALL_CORES;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 0;
 
 
   if (wWBMDone & ~wLastVertexInFrame )
    rHostNextState = `HOST_BROADCAST_NEXT_VERTEX;
   else if (wWBMDone & wLastVertexInFrame )
    rHostNextState = `HOST_GET_PRIMITIVE_COUNT;
   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;        
   oCoreSelectMask       = `SELECT_ALL_CORES;   
   rIncCoreSelect        = 0;
   RENDREN_O             = `SELECT_ALL_CORES;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;//1;
	oRenderDone           = 0;
 
   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  = {16'b0,`CREG_V0};       //Write starting from this location on the cores
   rSetWriteAddr         = 1;                      //Set to use the initial write address bellow
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;                      //Ignored during broadcasts 
   RENDREN_O             = `SELECT_ALL_CORES;
   rResetVertexCount     = 0;
   GACK_O                = 0;
    oHostDataAvailable   = 1;
	 oRenderDone           = 0;
 
   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;        
   oCoreSelectMask       = `SELECT_ALL_CORES;
   rIncCoreSelect        = 0;
   RENDREN_O             = `SELECT_ALL_CORES;
   rResetVertexCount     = 0;                  //Reset the vertex count to zero
   GACK_O                = 0;
   oHostDataAvailable    = 0;   
	oRenderDone           = 0;
 
 
 
   if (iGPUCommitedResults)
   begin
  // `ifndef VERILATOR
   `ifndef NO_DISPLAY_STATS
   for (i = 0; i < `MAX_CORES; i = i + 1)
   begin
    $write(".");
    `ifndef VERILATOR
    $fflush;
    `endif
   end
 
    RenderedPixels = RenderedPixels + `MAX_CORES;
	/* verilator lint_off WIDTH */
    if ( RenderedPixels % iWidth == 0)
	begin
 
     $write("]%d\n[",RenderedPixels / iWidth);
 
     `ifndef VERILATOR
     $fflush;
     `endif
	end
	/* verilator lint_on WIDTH */
 
    `endif
  // `endif 
 
    rHostNextState = `HOST_PREPARE_FOR_GEO_REQUESTS;
   end 
   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;        
   oCoreSelectMask       = wCoreSelect;   
   rIncCoreSelect        = 0;
   RENDREN_O             = 0;
   rResetVertexCount     = 0;
   GACK_O                = 0;
   oHostDataAvailable    = 0;
	oRenderDone           = 1;
 
   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;        
   oCoreSelectMask       = wCoreSelect;   
   rIncCoreSelect         = 0;
   RENDREN_O              = 0;
   rResetVertexCount      = 0;
   GACK_O                 = 0;
   oHostDataAvailable     = 0;
	oRenderDone           = 0;
 
   rHostNextState = `HOST_IDLE;
  end
  //----------------------------------------
  endcase
end  
 
endmodule
 

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

powered by: WebSVN 2.1.0

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