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/trunk/test_bench
- from Rev 84 to Rev 111
- ↔ Reverse comparison
Rev 84 → Rev 111
/TestBench_THEIA.v
1,1210 → 1,346
|
/********************************************************************************** |
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: |
|
This is the Main test bench of the GPU. It simulates the behavior of |
an external control unit or CPU that sends configuration information into DUT. |
It also implements a second processs that simulates a Wishbone slave that sends |
data from an external memory. These blocks are just behavioral CTE and therefore |
are not meant to be synthethized. |
|
*******************************************************************************/ |
|
|
`timescale 1ns / 1ps |
`include "aDefinitions.v" |
`define CONFIGURATION_PHASE 0 |
`define CTE_INITIAL_STATE 0 |
`define CTE_IDLE 1 |
`define CTE_START_EU_CONFIGURATION_SEQUENCE 2 |
`define CTE_SEND_CONFIGURATION_PACKET 3 |
`define CTE_ACK_CONFIGURATION_PACKET 8 |
`define CTE_SEND_LIGHT_PACKET 13 |
`define CTE_ACK_LIGTH_PACKET 14 |
`define CTE_SEND_RAY_I_TASK 15 |
`define CTE_WAIT_FOR_TASK_ACK 16 |
`define WAIT_FOR_TASK_COMPLETE 17 |
`define CTE_PREPARE_NEW_TASK 18 |
`define CTE_RENDER_DONE 19 |
`define CTE_READ_COLOR_DATA 20 |
`define CTE_GRANT_BUS_WRITE_PERMISION 21 |
`define CTE_ACK_GRANT_BUS_PERMISION 22 |
`define CTE_ACK_READ_COLOR_DATA 23 |
`define CTE_SEND_TEXTURE_DIMENSIONS 24 |
`define CTE_ACK_TEXTURE_DIMENSIONS 25 |
|
|
|
|
`define RESOLUTION_WIDTH (rSceneParameters[12] >> `SCALE) |
`define RESOLUTION_HEIGHT (rSceneParameters[13] >> `SCALE) |
`define RAYI_TASK 1 |
`define DELTA_ROW (32'h1 << `SCALE) |
`define DELTA_COL (32'h1 << `SCALE) |
|
`define SELECT_ALL_CORES `MAX_CORES'b1111; |
module TestBench_Theia; |
|
|
//------------------------------------------------------------------------ |
//**WARNING: Declare all of your varaibles at the begining |
//of the file. I hve noticed that sometimes the verilog |
//simulator allows you to use some regs even if they have not been |
//previously declared, leadeing to crahses or unexpected behavior |
// Inputs |
reg Clock; |
reg Reset; |
reg ExternalBus_DataReady; |
|
// Outputs |
wire ExternalBus_Acknowledge; |
wire TaskCompleted; |
|
//CTE state machin logic |
|
reg[31:0] CurrentState,NextState; |
reg[3:0] LightCount; |
reg[31:0] rLaneA,rLaneB,rLaneC,rLaneD; |
reg[16:0] CurrentTaskId; |
reg[31:0] CurrentPixelRow, CurrentPixelCol,CurrentRayType; |
|
reg CTE_WriteEnable; |
wire [`WB_WIDTH-1:0] DAT_O; |
|
reg ACK_O; |
wire ACK_I; |
wire [`WB_WIDTH-1:0] ADR_I,ADR_O; |
wire WE_I,STB_I; |
reg CYC_O,WE_O,TGC_O,STB_O; |
wire [1:0] TGC_I; |
reg [1:0] TGA_O; |
wire [1:0] TGA_I; |
wire [31:0] DAT_I; |
integer ucode_file; |
|
|
reg [31:0] rInitialCol,rInitialRow; |
reg [31:0] rControlRegister[2:0]; |
|
|
integer file, log, r, a, b; |
|
|
reg [31:0] rSceneParameters[64:0]; |
reg [31:0] rVertexBuffer[6000:0]; |
reg [31:0] rInstructionBuffer[512:0]; |
`define TEXTURE_BUFFER_SIZE (256*256*3) |
reg [31:0] rTextures[`TEXTURE_BUFFER_SIZE:0]; //Lets asume we use 256*256 textures |
|
integer i,j; |
`define MAX_WIDTH 200 |
`define MAX_SCREENBUFFER (`MAX_WIDTH*`MAX_WIDTH*3) |
reg [7:0] rScreen[`MAX_SCREENBUFFER-1:0]; |
|
//------------------------------------------------------------------------ |
//Debug registers |
`define TASK_TIMEOUTMAX 150000//50000 |
|
|
|
//------------------------------------------------------------------------ |
|
|
|
reg MST_O; |
//--------------------------------------------------------------- |
reg rIncCoreSelect; |
wire [`MAX_CORES-1:0] wCoreSelect; |
CIRCULAR_SHIFTLEFT_POSEDGE_EX # (`MAX_CORES ) SHF1 |
( |
.Clock( Clock ), |
.Reset( Reset ), |
.Initial(`MAX_CORES'b1), |
.Enable(rIncCoreSelect), |
.O(wCoreSelect) |
); |
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com) |
|
wire [3:0] CYC_I,GNT_O; |
wire wDone; |
reg [`MAX_CORES-1:0] rCoreSelectMask,rRenderEnable; |
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. |
|
THEIA GPU |
( |
.CLK_I( Clock ), |
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: |
|
This is the Main test bench of the GPU. It simulates the behavior of |
an external control unit or CPU that sends configuration information into DUT. |
It also implements a second processs that simulates a Wishbone slave that sends |
data from an external memory. These blocks are just behavioral CTE and therefore |
are not meant to be synthethized. |
|
*******************************************************************************/ |
|
|
|
`timescale 1ns / 1ps |
`include "aDefinitions.v" |
`define RESOLUTION_WIDTH (rSceneParameters[13] >> `SCALE) |
`define RESOLUTION_HEIGHT (rSceneParameters[14] >> `SCALE) |
`define DELTA_ROW (32'h1 << `SCALE) |
`define DELTA_COL (32'h1 << `SCALE) |
`define TEXTURE_BUFFER_SIZE (256*256*3) |
`define MAX_WIDTH 200 |
`define MAX_SCREENBUFFER (`MAX_WIDTH*`MAX_WIDTH*3) |
module TestBench_Theia; |
|
|
//------------------------------------------------------------------------ |
//**WARNING: Declare all of your varaibles at the begining |
//of the file. I hve noticed that sometimes the verilog |
//simulator allows you to use some regs even if they have not been |
//previously declared, leadeing to crahses or unexpected behavior |
// Inputs |
reg Clock; |
reg Reset; |
wire [`WB_WIDTH-1:0] DAT_O; |
reg ACK_O; |
wire ACK_I; |
wire [`WB_WIDTH-1:0] ADR_I,ADR_O; |
wire WE_I,STB_I; |
wire CYC_O,WE_O,TGC_O,STB_O; |
//wire [1:0] TGC_I; |
wire [1:0] TGA_O; |
wire [1:0] TGA_I; |
//wire [`WB_WIDTH-1:0] DAT_I; |
reg [`WB_WIDTH-1:0] TMADR_O,TMDAT_O; |
reg [`MAX_TMEM_BANKS-1:0] TMSEL_O; |
reg TMWE_O; |
reg [31:0] rControlRegister[2:0]; |
integer file, log; |
reg [31:0] rSceneParameters[64:0]; |
reg [31:0] rVertexBuffer[6000:0]; |
reg [31:0] rInstructionBuffer[512:0]; |
reg [31:0] rTextures[`TEXTURE_BUFFER_SIZE:0]; //Lets asume we use 256*256 textures |
reg [7:0] rScreen[`MAX_SCREENBUFFER-1:0]; |
wire [`MAX_CORES-1:0] wCoreSelect; |
wire [3:0] CYC_I,GNT_O; |
wire MST_O; |
wire wDone; |
wire [`MAX_CORES-1:0] RENDREN_O; |
reg [`MAX_CORE_BITS-1:0] wOMEMBankSelect; |
reg [`WB_WIDTH-1:0] wOMEMReadAddr; //Output adress (relative to current bank) |
wire [`WB_WIDTH-1:0] wOMEMData; //Output data bus (Wishbone) |
reg rHostEnable; |
integer k,out2; |
wire GRDY_I; |
wire GACK_O; |
wire STDONE_O; |
wire wGPUCommitedResults; |
wire wHostDataAvailable; |
|
|
THEIA GPU |
( |
.CLK_I( Clock ), |
.RST_I( Reset ), |
.RENDREN_I( rRenderEnable ), |
.DAT_I( DAT_O ), |
.ADR_O( ADR_I ), |
.ACK_I( ACK_O ), |
.WE_O ( WE_I ), |
.STB_O( STB_I ), |
|
.CYC_I( CYC_O ), |
.TGC_O( TGC_I ), |
.MST_I( MST_O ), |
.TGA_I( TGA_O ), |
.ACK_O( ACK_I ), |
.ADR_I( ADR_O ), |
.DAT_O( DAT_I ), |
.RENDREN_I( RENDREN_O ), |
.DAT_I( DAT_O ), |
// .ADR_O( ADR_I ), |
.ACK_I( ACK_O ), |
//.WE_O ( WE_I ), |
//.STB_O( STB_I ), |
|
.CYC_I( CYC_O ), |
// .TGC_O( TGC_I ), |
.MST_I( MST_O ), |
.TGA_I( TGA_O ), |
.ACK_O( ACK_I ), |
.ADR_I( ADR_O ), |
// .DAT_O( DAT_I ), |
.WE_I( WE_O ), |
.SEL_I( wCoreSelect | rCoreSelectMask),//4'b0001 ), |
.STB_I( STB_O ), |
.TGA_O(TGA_I), |
|
//Control register |
.CREG_I( rControlRegister[0][15:0] ), |
.SEL_I( wCoreSelect ), |
.STB_I( STB_O ), |
// .TGA_O(TGA_I), |
|
//Output memory |
.OMBSEL_I( wOMEMBankSelect ), |
.OMADR_I( wOMEMReadAddr ), |
.OMEM_O( wOMEMData ), |
.TMDAT_I( TMDAT_O ), |
.TMADR_I( TMADR_O ), |
.TMWE_I( TMWE_O ), |
.TMSEL_I( TMSEL_O ), |
|
.GRDY_O( GRDY_I ), |
.GACK_I( GACK_O ), |
.STDONE_I( STDONE_O ), |
.RCOMMIT_O( wGPUCommitedResults ), |
.HDA_I( wHostDataAvailable ), |
|
//Control register |
.CREG_I( rControlRegister[0][15:0] ), |
//Other stuff |
.DONE_O( wDone ) |
|
); |
.DONE_O( wDone ) |
|
); |
|
wire[`WB_WIDTH-1:0] wHostReadAddress; |
wire[`WB_WIDTH-1:0] wHostReadData; |
wire[`WB_WIDTH-1:0] wMemorySize; |
wire[1:0] wMemSelect; |
|
|
//--------------------------------------------- |
//generate the clock signal here |
always begin |
#`CLOCK_CYCLE Clock = ! Clock; |
|
end |
//--------------------------------------------- |
|
reg [15:0] rTimeOut; |
|
`define MAX_INSTRUCTIONS 2 |
|
initial begin |
// Initialize Inputs |
|
|
Clock = 0; |
Reset = 0; |
CTE_WriteEnable = 0; |
rLaneA = 32'b0; |
rLaneB = 32'b0; |
rLaneC = 32'b0; |
rLaneD = 32'b0; |
ExternalBus_DataReady = 0; |
rTimeOut = 0; |
|
|
|
`ifdef DUMP_CODE |
$write("Opening TestBench.log.... "); |
ucode_file = $fopen("TestBench.log","w"); |
$display("Done"); |
`endif |
|
//Read Config register values |
$write("Loading control register.... "); |
$readmemh("Creg.mem",rControlRegister); |
$display("Done"); |
|
|
|
//Read configuration Data |
$write("Loading scene parameters.... "); |
$readmemh("Params.mem", rSceneParameters ); |
$display("Done"); |
|
rInitialRow = rSceneParameters[18]; |
rInitialCol = rSceneParameters[19]; |
|
//Read Scene Data |
$write("Loading scene geometry.... "); |
$readmemh("Vertex.mem",rVertexBuffer); |
$display("Done"); |
|
//Read Texture Data |
$write("Loading scene texture.... "); |
$readmemh("Textures.mem",rTextures); |
$display("Done"); |
|
|
//Read instruction data |
$write("Loading code allocation table and user shaders.... "); |
$readmemh("Instructions.mem",rInstructionBuffer); |
$display("Done"); |
|
$display("Control Register : %b",rControlRegister[0]); |
$display("Initial Row : %h",rInitialRow); |
$display("Initial Column : %h",rInitialCol); |
$display("Resolution : %d X %d",`RESOLUTION_WIDTH, `RESOLUTION_HEIGHT ); |
|
//Open output file |
file = $fopen("Output.ppm"); |
log = $fopen("Simulation.log"); |
$fwrite(log, "Simulation start time : %dns\n",$time); |
$fwrite(log, "Width : %d\n",`RESOLUTION_WIDTH); |
$fwrite(log, "Height : %d\n",`RESOLUTION_HEIGHT); |
|
$fwrite(file,"P3\n"); |
$fwrite(file,"#This file was generated by Theia's RTL simulation\n"); |
$fwrite(file,"%d %d\n",`RESOLUTION_WIDTH, `RESOLUTION_HEIGHT ); |
$fwrite(file,"255\n"); |
|
CurrentPixelRow = 0; |
CurrentPixelCol = 0; |
#10 |
Reset = 1; |
ExternalBus_DataReady = 0; |
|
// Wait 100 ns for global reset to finish |
#100 Reset = 0; |
|
end |
|
reg [5:0] DataIndex; |
reg [31:0] ConfigurationPacketSize; |
|
reg [7:0] R,G,B; |
|
|
//--------------------------------------------- |
|
always @ (posedge Clock) |
begin |
rTimeOut = rTimeOut+1'b1; |
if (rTimeOut > `TASK_TIMEOUTMAX) |
begin |
$display("%dns ERROR: THEIA Timed out after %d of inactivity\n", |
$time(),rTimeOut); |
$stop(); |
end |
end |
|
reg [31:0] rSlaveData_O; |
//reg [31:0] rOutputFrameBuffer[39000:0]; |
reg [31:0] rColor; |
|
reg [7:0] Thingy; |
//Wish-Bone Slave logic. |
// |
//This logic represents a WBS FSM. It will provide |
//the memory for Vertex and Texture data. |
//Vertex/Tetxure data is stored in a 4GB RAM. |
//Vertex data starts at address 0 and ends at address 0x80_000_000. |
//Texture data starts at address 0x80_000_000 and ends at address |
//0xFFFFFFFF. |
//The Bit 31, indcates wheather we look for vertex (b=0) |
//or texture (b=1) |
|
`define WBS_AFTER_RESET 0 |
`define WBS_MOINTOR_STB_I 1 |
`define WBS_ACK_O 2 |
`define WBS_MOINTOR_STB_I_NEG 3 |
`define WBS_DONE 4 |
|
reg [7:0] WBSCurrentState,WBSNextState; |
reg [31:0] rAddress; |
|
always @(negedge Clock) |
begin |
if( Reset!=1 ) |
WBSCurrentState = WBSNextState; |
else |
WBSCurrentState = `WBS_AFTER_RESET; |
end |
|
|
|
reg [31:0] rConvertedTextureAddress; |
//---------------------------------------------------------- |
always @(posedge Clock) |
begin |
case (WBSCurrentState) |
//---------------------------------------- |
`WBS_AFTER_RESET: |
begin |
ACK_O = 0; |
rSlaveData_O = 32'b0; |
|
WBSNextState = `WBS_MOINTOR_STB_I; |
end |
//---------------------------------------- |
`WBS_MOINTOR_STB_I: |
begin |
if ( STB_I == 1 && wDone == 0) |
WBSNextState = `WBS_ACK_O; |
else if (STB_I == 0 && wDone == 0) |
WBSNextState = `WBS_MOINTOR_STB_I; |
else |
WBSNextState = `WBS_DONE; |
end |
//---------------------------------------- |
`WBS_ACK_O: |
begin |
if (WE_I == 0) |
begin |
|
rAddress = ADR_I; |
if (TGA_I == 2'b01) //replace this by TGA_I |
begin |
//Multiply pithc (3), Add 2 because the first 2 bytes are text Width, Height |
rConvertedTextureAddress = {1'b0,rAddress[30:0]} + 2; |
if (rConvertedTextureAddress >= `TEXTURE_BUFFER_SIZE) |
rConvertedTextureAddress = `TEXTURE_BUFFER_SIZE-1; |
|
|
rSlaveData_O = rTextures[ rConvertedTextureAddress ]; |
`ifdef DEBUG_WBM |
|
`LOGME"WB SLAVE: MASTER Requested read from texture address: %h (%d)Data = %h \n",rAddress, rConvertedTextureAddress,DAT_O ); |
`endif |
end |
else |
begin |
// Thingy = 0; //THIS IS NOT RE-ENTRANT!!! |
rSlaveData_O = rVertexBuffer[ rAddress ]; |
`ifdef DEBUG_WBM |
`LOGME"WB SLAVE: MASTER Requested read from vertex address: %h Data = %h\n",rAddress,DAT_O); |
`endif |
end |
|
end |
else |
begin |
// $display("%d Theia Writes value: %h @ %d (Time to process pixel %d Clock cycle)",$time, DAT_I,ADR_I,rTimeOut); |
|
|
// if (Thingy == 0) |
// begin |
|
// end |
|
// Thingy = Thingy + 1; |
if (CurrentPixelCol >= (`RESOLUTION_WIDTH*3)) |
begin |
CurrentPixelCol = 0; |
CurrentPixelRow = CurrentPixelRow + 1; |
$display("]- %d (%d)",CurrentPixelRow,ADR_I); |
$write("["); |
end |
|
// if (Thingy == 3) |
// begin |
CurrentPixelCol = CurrentPixelCol + 1; |
if ( CurrentPixelCol % 3 == 0) |
begin |
// $fwrite(file,"\n# %d %d\n",CurrentPixelRow,CurrentPixelCol); |
$write("."); |
end |
//Thingy = 0; |
// end |
rTimeOut = 0; |
R = ((DAT_I >> (`SCALE-8)) > 255) ? 255 : (DAT_I >> (`SCALE-8)); |
rScreen[ ADR_I ] = R; |
// $fwrite(file,"%d " , R ); |
|
end |
|
|
ACK_O = 1; |
|
// if (CurrentPixelRow >= `RESOLUTION_HEIGHT) |
if (wDone) |
WBSNextState = `WBS_DONE; |
else |
WBSNextState = `WBS_MOINTOR_STB_I_NEG; |
end |
//---------------------------------------- |
`WBS_MOINTOR_STB_I_NEG: |
begin |
if ( STB_I == 0 ) |
begin |
ACK_O = 0; |
WBSNextState = `WBS_MOINTOR_STB_I; |
end |
else |
WBSNextState = `WBS_MOINTOR_STB_I_NEG; |
end |
//---------------------------------------- |
`WBS_DONE: |
begin |
for (j = 0; j < `RESOLUTION_WIDTH; j = j+1) |
begin |
|
for (i = 0; i < `RESOLUTION_HEIGHT*3; i = i +1) |
begin |
|
$fwrite(file,"%d " , rScreen[i+j*`RESOLUTION_WIDTH*3] ); |
if ((i %3) == 0) |
$fwrite(file,"\n# %d %d\n",i,j); |
|
end |
end |
$display("RESOLUTION_WIDTH = %d,RESOLUTION_HEIGHT= %d", |
`RESOLUTION_WIDTH,`RESOLUTION_HEIGHT); |
$display("ADR_I = %d\n",ADR_I); |
`LOGME"RENDER COMPLETE"); |
`LOGME"Closing File"); |
$fclose(file); |
$fwrite(log, "Simulation end time : %dns\n",$time); |
$fclose(log); |
`LOGME"File Closed"); |
$stop(); |
$fclose(ucode_file); |
end |
//---------------------------------------- |
default: |
begin |
$display("WBS Undefined state"); |
end |
endcase |
end //end always |
//---------------------------------------------------------- |
|
|
|
|
`define TAG_BLOCK_WRITE_CYCLE 2'b01 |
`define TAG_INSTRUCTION_ADDRESS_TYPE 2'b01 |
`define TAG_DATA_ADDRESS_TYPE 2'b10 |
|
`define WBM_AFTER_RESET 0 |
`define WBM_WRITE_INSTRUCTION_PHASE1 1 |
`define WBM_ACK_INSTRUCTION_PHASE1 2 |
`define WBM_WRITE_INSTRUCTION_PHASE2 3 |
`define WBM_ACK_INSTRUCTION_PHASE2 4 |
`define WBM_END_INSTRUCTION_WRITE_CYCLE 5 |
`define WBM_SEND_DATA_PHASE1 6 |
`define WBM_ACK_DATA_PHASE1 7 |
`define WBM_SEND_DATA_PHASE2 8 |
`define WBM_ACK_DATA_PHASE2 9 |
`define WBM_SEND_DATA_PHASE3 10 |
`define WBM_ACK_DATA_PHASE3 11 |
`define WBM_END_DATA_WRITE_CYCLE 12 |
`define WBM_DONE 13 |
`define WBM_CONFIGURE_CORE0_PHASE1 14 |
`define WBM_ACK_CONFIGURE_CORE0_PHASE1 15 |
`define WBM_CONFIGURE_CORE0_PHASE2 16 |
`define WBM_ACK_CONFIGURE_CORE0_PHASE2 17 |
`define WBM_CONFIGURE_CORE0_PHASE3 18 |
`define WBM_ACK_CONFIGURE_CORE0_PHASE3 19 |
`define WBM_CONFIGURE_CORE1_PHASE1 20 |
`define WBM_ACK_CONFIGURE_CORE1_PHASE1 21 |
`define WBM_CONFIGURE_CORE1_PHASE2 22 |
`define WBM_ACK_CONFIGURE_CORE1_PHASE2 23 |
`define WBM_CONFIGURE_CORE1_PHASE3 24 |
`define WBM_ACK_CONFIGURE_CORE1_PHASE3 25 |
`define WBM_END_CORE0_WRITE_CYCLE 26 |
`define WBM_END_CORE1_WRITE_CYCLE 27 |
MUXFULLPARALELL_2SEL_GENERIC # ( `WB_WIDTH ) MUX1 |
( |
.Sel( wMemSelect ), |
.I1( rInstructionBuffer[wHostReadAddress] ), |
.I2( rSceneParameters[wHostReadAddress] ), |
.I3( rVertexBuffer[wHostReadAddress] ), |
.I4(0), |
.O1(wHostReadData) |
); |
|
`define WBM_CONFIGURE_CORE2_PHASE1 28 |
`define WBM_ACK_CONFIGURE_CORE2_PHASE1 29 |
`define WBM_CONFIGURE_CORE2_PHASE2 30 |
`define WBM_ACK_CONFIGURE_CORE2_PHASE2 31 |
`define WBM_CONFIGURE_CORE2_PHASE3 32 |
`define WBM_ACK_CONFIGURE_CORE2_PHASE3 33 |
`define WBM_CONFIGURE_CORE3_PHASE1 34 |
`define WBM_ACK_CONFIGURE_CORE3_PHASE1 35 |
`define WBM_CONFIGURE_CORE3_PHASE2 36 |
`define WBM_ACK_CONFIGURE_CORE3_PHASE2 37 |
`define WBM_CONFIGURE_CORE3_PHASE3 38 |
`define WBM_ACK_CONFIGURE_CORE3_PHASE3 39 |
`define WBM_END_CORE2_WRITE_CYCLE 40 |
`define WBM_END_CORE3_WRITE_CYCLE 41 |
`define WBM_CONFIGURE_NEXT_CORE 42 |
|
|
reg[31:0] rInstructionPointer; |
reg[31:0] rAddressToSend; |
reg[31:0] rDataAddress; |
reg[31:0] rDataPointer; |
|
reg IncIP,IncIA,IncDP; |
reg rPrepateWriteAddressForNextCore; |
reg rClearOutAddress; |
//----------------------------------------------------- |
always @ (posedge Clock or posedge rClearOutAddress) |
begin |
|
if ( IncIA && ~rClearOutAddress) |
rAddressToSend = rAddressToSend + 1; |
else if (rClearOutAddress) |
begin |
if (TGA_O == `TAG_INSTRUCTION_ADDRESS_TYPE) |
rAddressToSend = {16'd1,16'd0}; |
else if (rPrepateWriteAddressForNextCore) |
rAddressToSend = `CREG_PIXEL_2D_INITIAL_POSITION; |
else |
rAddressToSend = 0; |
end |
|
|
end |
//----------------------------------------------------- |
always @ (posedge ACK_I or posedge Reset ) |
begin |
|
if ( ACK_I && ~Reset) |
rInstructionPointer = rInstructionPointer + 1; |
else if (Reset) |
rInstructionPointer = 0; |
|
|
|
end |
//----------------------------------------------------- |
reg rResetDp; |
|
always @ (posedge Clock or posedge rResetDp ) |
begin |
|
if ( ACK_I && ~rResetDp)//IncDP && ~Reset) |
rDataPointer = rDataPointer + 1; |
else if (rResetDp) |
rDataPointer = 32'b0; |
|
|
end |
MUXFULLPARALELL_2SEL_GENERIC # ( `WB_WIDTH ) MUX2 |
( |
.Sel( wMemSelect ), |
.I1( rInstructionBuffer[0] ), |
.I2( rSceneParameters[0] ), |
.I3( rVertexBuffer[0] ), |
.I4(0), |
.O1(wMemorySize) |
); |
|
reg rIncPacketCount; |
reg [`WIDTH-1:0] rPacketCount; |
Module_Host HOST |
( |
.Clock( Clock ), |
.Reset( Reset ), |
.iEnable( rHostEnable ), |
.oHostDataAvailable( wHostDataAvailable ), |
.iHostDataReadConfirmed( GRDY_I ), |
.iMemorySize( wMemorySize ), |
.iPrimitiveCount( (rVertexBuffer[6]+1) *7 ), |
.iGPUCommitedResults( wGPUCommitedResults ), |
.STDONE_O( STDONE_O ), |
.iGPUDone( wDone ), |
|
always @ (posedge Clock) |
begin |
if (Reset) |
rPacketCount = 0; |
else |
begin |
if ( rIncPacketCount ) |
rPacketCount = rPacketCount + 1; |
end |
end |
//----------------------------------------------------- |
|
|
|
|
assign DAT_O = ( MST_O == 1'b1 ) ? wMasteData_O : rSlaveData_O; |
|
wire[31:0] wMasteData_O; |
|
|
|
assign wMasteData_O = (TGA_O == `TAG_INSTRUCTION_ADDRESS_TYPE) ? rInstructionBuffer[rInstructionPointer+1] : rSceneParameters[ rDataPointer ]; |
|
|
always @ (posedge STB_O) |
begin |
if (TGA_O == `TAG_INSTRUCTION_ADDRESS_TYPE) |
begin |
//$display("-- %x\n",wMasteData_O); |
end |
end |
assign ADR_O = rAddressToSend; |
|
reg [7:0] WBMCurrentState,WBMNextState; |
reg [31:0] rWriteAddress; |
|
always @(posedge Clock or posedge Reset) |
begin |
if( Reset!=1 ) |
WBMCurrentState = WBMNextState; |
else |
WBMCurrentState = `WBM_AFTER_RESET; |
end |
|
wire[31:0] wConfigurationPacketSize; |
assign wConfigurationPacketSize = rSceneParameters[2]; |
|
reg [31:0] InstructionIndex; |
reg [31:0] InstructionWriteAddress; |
//Send the instructions now... |
//---------------------------------------------------------- |
always @(posedge Clock) |
begin |
case (WBMCurrentState) |
//---------------------------------------- |
|
//Wait until the reset secuence is complete to |
//begin sending stuff. |
|
`WBM_AFTER_RESET: |
begin |
WE_O <= 0; |
CYC_O <= 0; |
TGC_O <= 0; |
TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; |
STB_O <= 0; |
// IncIP <= 0; |
IncIA <= 0; |
MST_O <= 0; |
IncDP <= 0; |
rResetDp <= 1; |
rClearOutAddress <= 1; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if (Reset == 0) |
WBMNextState <= `WBM_WRITE_INSTRUCTION_PHASE1; |
else |
WBMNextState <= `WBM_AFTER_RESET; |
end |
//---------------------------------------- |
|
//CLOCK EDGE 0: MASTER presents a valid address on [ADR_O()] |
//MASTER presents valid data on [DAT_O()] |
//MASTER asserts [WE_O] to indicate a WRITE cycle. |
//MASTER asserts [CYC_O] and [TGC_O()] to indicate the start of the cycle. |
//MASTER asserts [STB_O] to indicate the start of the phase. |
|
`WBM_WRITE_INSTRUCTION_PHASE1: |
begin |
WE_O <= 1; //Indicate write cycle |
CYC_O <= 1; //Start of the cycle |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; //TAG CYCLE: 10 indicated multiple write Cycle |
TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; //TAG Address: 01 means instruction address type. |
STB_O <= ~ACK_I; //Start of phase (you put this in zero to introduce wait cycles) |
// IncIP <= 0; |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 1; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_INSTRUCTION_PHASE1; |
else |
WBMNextState <= `WBM_WRITE_INSTRUCTION_PHASE1; |
|
end |
//---------------------------------------- |
`WBM_ACK_INSTRUCTION_PHASE1: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; |
STB_O <= 0; //* //Negate STB_O in response to ACK_I |
// IncIP <= 1; //* //Increment local inst pointer to send the next 32 bits |
IncIA <= 0; //leave the instruction write address the same |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 1; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if (ACK_I == 0) |
WBMNextState <= `WBM_WRITE_INSTRUCTION_PHASE2; |
else |
WBMNextState <= `WBM_ACK_INSTRUCTION_PHASE1; |
end |
//---------------------------------------- |
`WBM_WRITE_INSTRUCTION_PHASE2: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; |
STB_O <= ~ACK_I; |
// IncIP <= 0; |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 1; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_INSTRUCTION_PHASE2; |
else |
WBMNextState <= `WBM_WRITE_INSTRUCTION_PHASE2; |
|
end |
//---------------------------------------- |
`WBM_ACK_INSTRUCTION_PHASE2: |
begin |
WE_O <= 1; |
CYC_O <= 0; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_INSTRUCTION_ADDRESS_TYPE; |
STB_O <= 0; //* |
|
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 1; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
if (rInstructionPointer >= rInstructionBuffer[0]) |
begin |
IncIA <= 0;//* |
rClearOutAddress <= 1; |
WBMNextState <= `WBM_SEND_DATA_PHASE1; |
end |
else |
begin |
IncIA <= 1;//* |
rClearOutAddress <= 0; |
WBMNextState <= `WBM_WRITE_INSTRUCTION_PHASE1; |
end |
|
end |
//**************************************** |
`WBM_SEND_DATA_PHASE1: |
begin |
WE_O <= 1; //Indicate write cycle |
CYC_O <= 1; //Start of the cycle |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; //TAG CYCLE: 10 indicated multiple write Cycle |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; //TAG Address: 01 means instruction address type. |
STB_O <= ~ACK_I; //Start of phase (you put this in zero to introduce wait cycles) |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_DATA_PHASE1; |
else |
WBMNextState <= `WBM_SEND_DATA_PHASE1; |
|
end |
//---------------------------------------- |
`WBM_ACK_DATA_PHASE1: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* //Negate STB_O in response to ACK_I |
// IncIP <= 1; //* //Increment local inst pointer to send the next 32 bits |
IncIA <= 0; //leave the instruction write address the same |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
|
if (ACK_I == 0) |
WBMNextState <= `WBM_SEND_DATA_PHASE2; |
else |
WBMNextState <= `WBM_ACK_DATA_PHASE1; |
end |
//---------------------------------------- |
`WBM_SEND_DATA_PHASE2: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= ~ACK_I; |
// IncIP <= 0; |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_DATA_PHASE2; |
else |
WBMNextState <= `WBM_SEND_DATA_PHASE2; |
|
end |
//---------------------------------------- |
`WBM_ACK_DATA_PHASE2: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0;//* |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
|
if (ACK_I == 0) |
WBMNextState <= `WBM_SEND_DATA_PHASE3; |
else |
WBMNextState <= `WBM_ACK_DATA_PHASE2; |
|
end |
//---------------------------------------- |
`WBM_SEND_DATA_PHASE3: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= ~ACK_I; |
// IncIP <= 0; |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_DATA_PHASE3; |
else |
WBMNextState <= `WBM_SEND_DATA_PHASE3; |
|
end |
//---------------------------------------- |
`WBM_ACK_DATA_PHASE3: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 1;//* |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
|
WBMNextState <= `WBM_END_DATA_WRITE_CYCLE; |
|
end |
//---------------------------------------- |
`WBM_END_DATA_WRITE_CYCLE: |
begin |
WE_O <= 0; |
CYC_O <= 0; //* |
TGC_O <= 0; |
TGA_O <= 0; |
STB_O <= 0; |
IncIA <= 1;//* |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rCoreSelectMask <= `SELECT_ALL_CORES; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
|
if (rDataPointer > 3*5)//wConfigurationPacketSize*3) |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE1; |
else |
WBMNextState <= `WBM_SEND_DATA_PHASE1; |
|
end |
//---------------------------------------- |
`WBM_CONFIGURE_CORE0_PHASE1: |
begin |
|
WE_O <= 1; //Indicate write cycle |
CYC_O <= 1; //Start of the cycle |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; //TAG CYCLE: 10 indicated multiple write Cycle |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; //TAG Address: 01 means instruction address type. |
STB_O <= ~ACK_I; //Start of phase (you put this in zero to introduce wait cycles) |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
//To Memory |
.oReadAddress( wHostReadAddress ), |
.iReadData( wHostReadData ), |
|
//To Hub/Switch |
.oCoreSelectMask( wCoreSelect ), |
.oMemSelect( wMemSelect ), |
.DAT_O( DAT_O), |
.ADR_O( ADR_O ), |
.TGA_O( TGA_O ), |
.RENDREN_O( RENDREN_O ), |
.CYC_O( CYC_O ), |
.STB_O( STB_O ), |
.MST_O( MST_O ), |
|
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE1; |
else |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE1; |
end |
//---------------------------------------- |
`WBM_ACK_CONFIGURE_CORE0_PHASE1: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* //Negate STB_O in response to ACK_I |
IncIA <= 0; //leave the instruction write address the same |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
|
if (ACK_I == 0) |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE2; |
else |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE1; |
end |
//---------------------------------------- |
`WBM_CONFIGURE_CORE0_PHASE2: |
begin |
WE_O <= 1; //Indicate write cycle |
CYC_O <= 1; //Start of the cycle |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; //TAG CYCLE: 10 indicated multiple write Cycle |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; //TAG Address: 01 means instruction address type. |
STB_O <= ~ACK_I; //Start of phase (you put this in zero to introduce wait cycles) |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
.GRDY_I( GRDY_I ), |
.GACK_O( GACK_O ), |
|
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE2; |
else |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE2; |
end |
//---------------------------------------- |
`WBM_ACK_CONFIGURE_CORE0_PHASE2: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* //Negate STB_O in response to ACK_I |
IncIA <= 0; //leave the instruction write address the same |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
|
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 0; |
|
if (ACK_I == 0) |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE3; |
else |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE2; |
end |
//---------------------------------------- |
`WBM_CONFIGURE_CORE0_PHASE3: |
begin |
WE_O <= 1; //Indicate write cycle |
CYC_O <= 1; //Start of the cycle |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; //TAG CYCLE: 10 indicated multiple write Cycle |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; //TAG Address: 01 means instruction address type. |
STB_O <= ~ACK_I; //Start of phase (you put this in zero to introduce wait cycles) |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
rIncPacketCount <= 0; |
.WE_O( WE_O ), |
|
|
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
|
if ( ACK_I ) |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE3; |
else |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE3; |
end |
//---------------------------------------- |
`WBM_ACK_CONFIGURE_CORE0_PHASE3: |
begin |
WE_O <= 1; |
CYC_O <= 1; |
TGC_O <= `TAG_BLOCK_WRITE_CYCLE; |
TGA_O <= `TAG_DATA_ADDRESS_TYPE; |
STB_O <= 0; //* //Negate STB_O in response to ACK_I |
IncIA <= 0; //leave the instruction write address the same |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rClearOutAddress <= 0; |
|
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
rIncPacketCount <= 1; |
|
if (ACK_I == 0) |
WBMNextState <= `WBM_END_CORE0_WRITE_CYCLE; |
else |
WBMNextState <= `WBM_ACK_CONFIGURE_CORE0_PHASE3; |
end |
//---------------------------------------- |
`WBM_END_CORE0_WRITE_CYCLE: |
begin |
WE_O <= 0; |
CYC_O <= 0; //* |
TGC_O <= 0; |
TGA_O <= 0; |
STB_O <= 0; |
IncIA <= 1;//* |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
rIncCoreSelect <= 0; |
rCoreSelectMask <= 0; |
rRenderEnable <= 0; |
rIncPacketCount <= 0; |
.ACK_I( ACK_I ) |
); |
//--------------------------------------------- |
//generate the clock signal here |
always begin |
#`CLOCK_CYCLE Clock = ! Clock; |
|
end |
//--------------------------------------------- |
|
|
if ((rPacketCount %2) == 0) //Two packets per Core |
|
`define PARTITION_SIZE `RESOLUTION_HEIGHT/`MAX_CORES |
integer i,j,kk; |
reg [31:0] R; |
always @ ( * ) |
begin |
|
|
if (wDone == 1'b1) |
begin |
|
$display("Partition Size = %d",`PARTITION_SIZE); |
for (kk = 0; kk < 4; kk = kk+1) |
begin |
rClearOutAddress <= 1; |
rPrepateWriteAddressForNextCore <= 1; |
WBMNextState <= `WBM_CONFIGURE_NEXT_CORE; |
end |
else |
begin |
rClearOutAddress <= 0; |
rPrepateWriteAddressForNextCore <= 0; |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE1; |
end |
|
end |
wOMEMBankSelect = kk; |
$display("wOMEMBankSelect = %d\n",wOMEMBankSelect); |
for (j=0; j < `PARTITION_SIZE; j=j+1)//for (j = 0; j < 15; j = j+1) //LOOK OUT 15 is hardcoded!!!!!!!! |
begin |
|
for (i = 0; i < `RESOLUTION_HEIGHT*3; i = i +1) |
begin |
wOMEMReadAddr = i+j*`RESOLUTION_WIDTH*3; |
#`CLOCK_PERIOD; |
#1; |
R = ((wOMEMData >> (`SCALE-8)) > 255) ? 255 : (wOMEMData >> (`SCALE-8)); |
$fwrite(out2,"%d " , R ); |
|
//------------------------------------------ |
if ((i %3) == 0) |
$fwrite(out2,"\n# %d %d\n",i/3,j); |
|
end |
end |
end |
|
|
`WBM_CONFIGURE_NEXT_CORE: |
begin |
WE_O <= 0; |
CYC_O <= 0; |
TGC_O <= 0; |
TGA_O <= 0; |
STB_O <= 0; |
IncIA <= 0; |
MST_O <= 1; |
IncDP <= 0; |
rResetDp <= 0; |
|
rCoreSelectMask <= 0; |
rIncCoreSelect <= 1; |
rRenderEnable <= 0; |
rIncPacketCount <= 0; |
|
$fclose(out2); |
$fwrite(log, "Simulation end time : %dns\n",$time); |
$fclose(log); |
|
if (wCoreSelect[`MAX_CORES-1] == 1) |
WBMNextState <= `WBM_DONE; |
else |
WBMNextState <= `WBM_CONFIGURE_CORE0_PHASE1; |
|
$stop(); |
|
|
end |
end |
|
|
reg [15:0] rTimeOut; |
|
`define MAX_INSTRUCTIONS 2 |
|
//---------------------------------------- |
//Here everything is ready so just start! |
|
`WBM_DONE: |
begin |
WE_O <= 0; |
CYC_O <= 0; |
TGC_O <= 0; |
TGA_O <= 0; |
STB_O <= 0; |
IncIA <= 0; |
MST_O <= 0; |
IncDP <= 0; |
rResetDp <= 1; |
rClearOutAddress <= 1; |
rCoreSelectMask <= 0; |
rRenderEnable <= 4'b1111; |
rPrepateWriteAddressForNextCore <= 0; |
|
WBMNextState <= `WBM_DONE; |
end |
//---------------------------------------- |
|
|
endcase |
end //end always |
//---------------------------------------------------------- |
|
|
|
|
|
endmodule |
|
initial begin |
// Initialize Inputs |
|
|
Clock = 0; |
Reset = 0; |
rTimeOut = 0; |
rHostEnable = 0; |
//Read Config register values |
$write("Loading control register.... "); |
$readmemh("Creg.mem",rControlRegister); |
$display("Done"); |
|
|
|
//Read configuration Data |
$write("Loading scene parameters.... "); |
$readmemh("Params.mem", rSceneParameters ); |
$display("Done"); |
|
|
//Read Scene Data |
$write("Loading scene geometry.... "); |
$readmemh("Vertex.mem",rVertexBuffer); |
$display("Done"); |
|
//Read Texture Data |
$write("Loading scene texture.... "); |
$readmemh("Textures.mem",rTextures); |
$display("Done"); |
|
|
//Read instruction data |
$write("Loading code allocation table and user shaders.... "); |
$readmemh("Instructions.mem",rInstructionBuffer); |
$display("Done"); |
|
$display("Control Register : %b",rControlRegister[0]); |
$display("Resolution : %d X %d",`RESOLUTION_WIDTH, `RESOLUTION_HEIGHT ); |
|
//Open output file |
// file = $fopen("Output.ppm"); |
log = $fopen("Simulation.log"); |
$fwrite(log, "Simulation start time : %dns\n",$time); |
$fwrite(log, "Width : %d\n",`RESOLUTION_WIDTH); |
$fwrite(log, "Height : %d\n",`RESOLUTION_HEIGHT); |
|
// $fwrite(file,"P3\n"); |
// $fwrite(file,"#This file was generated by Theia's RTL simulation\n"); |
// $fwrite(file,"%d %d\n",`RESOLUTION_WIDTH, `RESOLUTION_HEIGHT ); |
// $fwrite(file,"255\n"); |
|
//Open output file |
out2 = $fopen("Output.ppm"); |
|
$fwrite(out2,"P3\n"); |
$fwrite(out2,"#This file was generated by Theia's RTL simulation\n"); |
$fwrite(out2,"%d %d\n",`RESOLUTION_WIDTH, `RESOLUTION_HEIGHT ); |
$fwrite(out2,"255\n"); |
|
#10 |
Reset = 1; |
|
|
// Wait 100 ns for global reset to finish |
TMWE_O = 1; |
#100 Reset = 0; |
TMWE_O = 1; |
|
$display("Intilializing TMEM @ %dns",$time); |
//starts in 2 to skip Width and Height |
for (k = 0;k < `TEXTURE_BUFFER_SIZE; k = k + 1) |
begin |
|
TMADR_O <= (k >> (`MAX_TMEM_BANKS/2)); |
TMSEL_O <= (k & (`MAX_TMEM_BANKS-1)); |
TMDAT_O <= rTextures[k]; |
#10; |
end |
$display("Done Intilializing TMEM @ %dns",$time); |
TMWE_O = 0; |
rHostEnable = 1; |
|
end |
|
|
endmodule |