data/full_repos/permissive/48192473/rtl/gpu.v
1: b'%Error: data/full_repos/permissive/48192473/rtl/gpu.v:2: Cannot find include file: gpu_definitions.v\n`include "gpu_definitions.v" \n         ^~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/48192473/rtl,data/full_repos/permissive/48192473/gpu_definitions.v\n             data/full_repos/permissive/48192473/rtl,data/full_repos/permissive/48192473/gpu_definitions.v.v\n             data/full_repos/permissive/48192473/rtl,data/full_repos/permissive/48192473/gpu_definitions.v.sv\n             gpu_definitions.v\n             gpu_definitions.v.v\n             gpu_definitions.v.sv\n             obj_dir/gpu_definitions.v\n             obj_dir/gpu_definitions.v.v\n             obj_dir/gpu_definitions.v.sv\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:70: Define or directive not defined: \'`GPU_UOP_SZ\'\nwire [`GPU_UOP_SZ-1:0] wUop;\n      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:94: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel0 = ({wSh[0],wSl[0]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel0 : wSprtPixel0;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:94: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel0 = ({wSh[0],wSl[0]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel0 : wSprtPixel0;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:95: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel1 = ({wSh[1],wSl[1]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel1 : wSprtPixel1;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:95: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel1 = ({wSh[1],wSl[1]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel1 : wSprtPixel1;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:96: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel2 = ({wSh[2],wSl[2]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel2 : wSprtPixel2;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:96: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel2 = ({wSh[2],wSl[2]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel2 : wSprtPixel2;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:97: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel3 = ({wSh[3],wSl[3]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel3 : wSprtPixel3;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:97: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel3 = ({wSh[3],wSl[3]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel3 : wSprtPixel3;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:98: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel4 = ({wSh[4],wSl[4]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel4 : wSprtPixel4;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:98: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel4 = ({wSh[4],wSl[4]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel4 : wSprtPixel4;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:99: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel5 = ({wSh[5],wSl[5]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel5 : wSprtPixel5;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:99: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel5 = ({wSh[5],wSl[5]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel5 : wSprtPixel5;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:100: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel6 = ({wSh[6],wSl[6]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel6 : wSprtPixel6;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:100: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel6 = ({wSh[6],wSl[6]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel6 : wSprtPixel6;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:101: Define or directive not defined: \'`SPRITE_COLOR_TRANSPARENT\'\nassign wPixel7 = ({wSh[7],wSl[7]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel7 : wSprtPixel7;\n                                     ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:101: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nassign wPixel7 = ({wSh[7],wSl[7]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel7 : wSprtPixel7;\n                                                              ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:302: Define or directive not defined: \'`GPU_DST_RNG\'\nassign wGpuRegWriteSelect = (1 << wUop[`GPU_DST_RNG]);\n                                       ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:302: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign wGpuRegWriteSelect = (1 << wUop[`GPU_DST_RNG]);\n                                                   ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:306: Define or directive not defined: \'`GPU_S0_RNG_SEL_BIT\'\nassign wOp0 = (wUop[`GPU_S0_RNG_SEL_BIT] == 1\'b1) ? wOp0_Pre_A : wOp0_Pre_B;\n                    ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:306: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign wOp0 = (wUop[`GPU_S0_RNG_SEL_BIT] == 1\'b1) ? wOp0_Pre_A : wOp0_Pre_B;\n                                       ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:310: Define or directive not defined: \'`GPU_S0_RNG_L\'\n  .Sel( wUop[ `GPU_S0_RNG_L]     ),\n              ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:310: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n  .Sel( wUop[ `GPU_S0_RNG_L]     ),\n                           ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:334: Define or directive not defined: \'`GPU_S0_RNG_H\'\n  .Sel( wUop[ `GPU_S0_RNG_H ] ),\n              ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:334: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n  .Sel( wUop[ `GPU_S0_RNG_H ] ),\n                            ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`GPU_OP_RNG\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                       ^~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                  ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`gaddl\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                       ^~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`GPU_OP_RNG\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                                      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`gsubl\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                                                      ^~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`GPU_DST_RNG\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                                                                      ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:379: Define or directive not defined: \'`GPU_S1_RNG\'\nassign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];\n                                                                                                           ^~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:520: Define or directive not defined: \'`GPU_OP_RNG\'\n  case (wUop[`GPU_OP_RNG])\n             ^~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:520: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n  case (wUop[`GPU_OP_RNG])\n                        ^\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:521: Define or directive not defined: \'`gnop\'\n   `gnop:\n   ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:531: Define or directive not defined: \'`gwfbuffer\'\n    `gwfbuffer:  \n    ^~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:532: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:541: Define or directive not defined: \'`ginfbaddr\'\n    `ginfbaddr:\n    ^~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:542: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:551: Define or directive not defined: \'`gwrr\'\n    `gwrr: \n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:552: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:561: Define or directive not defined: \'`gwrl\'\n    `gwrl: \n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:562: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:563: Define or directive not defined: \'`GPU_LIT_RNG\'\n      rResult     = wUop[`GPU_LIT_RNG];\n                         ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:571: Define or directive not defined: \'`grvmem\'\n    `grvmem: \n    ^~~~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:572: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:581: Define or directive not defined: \'`gadd\'\n    `gadd: \n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:582: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n    begin\n    ^~~~~\n%Error: data/full_repos/permissive/48192473/rtl/gpu.v:592: Define or directive not defined: \'`gshl\'\n    `gshl: \n    ^~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module gpu
(
  input wire iClock,
  input wire iReset,

  output wire         oFramBufferWe,
  output wire [15:0]  oFramBufferData,
  output wire [15:0]  oFramBufferAddr,

  output wire [15:0] oMcuAddr,
  output reg        oMcuReadRequest,
  input wire [3:0]  iMcuRegSelect,
  input wire [7:0]  iMcuWriteData,
  input wire [7:0]  iMcuReadData,
  input wire        iMcuWe,


  output wire [7:0]  oSTAT,
  output wire [7:0]  oLCDC,
  output wire [7:0]  oSCY,
  output wire [7:0]  oSCX,
  output wire [7:0]  oLY,
  output wire [7:0]  oLYC,
  output wire [7:0]  oDMA,
  output wire [7:0]  oBGP,
  output wire [7:0]  oOBP0,
  output wire [7:0]  oOBP1,
  output wire [7:0]  oWY,
  output wire [7:0]  oWX

);


wire [20:0] wMcuRegWriteSelect;
wire [31:0] wGpuRegWriteSelect;
wire [15:0] wOp0, wOp1, wR0, wR1, wR3,wR4, wR5, wR6,  wSpriteCoordX,wSpriteCoordY, wOp0_Pre_B, wOp0_Pre_A, wOp1_Pre_B, wOp1_Pre_A;
wire [7:0] wR2;
wire [15:0]  wCurrentTile,wWinTile;
wire [7:0] wBh, wBl, wState, wIp, wInitialPc, wSC_Tile_Row;
wire [15:0] wBGTileOffset, wBGTileMapOffset, wBGRowOffset, wFrameBufferAddress, wCurrentTileRow,wOAMOffset;
wire [15:0] wTile1_Bg_Offset, wTile0_Bg_Offset,wWinTileMapOffset;
wire [15:0] wSC_Tile,wWinTileindex;
wire [7:0] wRegSelect, wSh, wSl;
wire [1:0] wPixel0,wPixel1,wPixel2,wPixel3,wPixel4,wPixel5,wPixel6,wPixel7;
wire [1:0] wBgPixel0,wBgPixel1,wBgPixel2,wBgPixel3,wBgPixel4,wBgPixel5,wBgPixel6,wBgPixel7;
wire [1:0] wSprtPixel0,wSprtPixel1,wSprtPixel2,wSprtPixel3,wSprtPixel4,wSprtPixel5,wSprtPixel6,wSprtPixel7;
wire [`GPU_UOP_SZ-1:0] wUop;
wire [5:0] wOp1Sel;
wire wZ, wRegWe, wGpuActive, wIsSpriteInCurrentTile,wIsSpriteInCurrentRow,wIsWyOnScreen,wIsWxOnScreen,wWinEnabled, wIsWininBG;
wire [15:0] wSpriteWidth, wSpriteHeight, wTileCoordX, wTileCoordY,wSprite_tile_offset,wSprite_info;
reg [15:0] rResult;
reg rRegWe, rBgBufferWe, rJump, rIncFBufferAddr;

wire[15:0] wSpriteTopLeftX     ;
wire[15:0] wSpriteTopLeftY     ;
wire[15:0] wSpriteTopRightX    ;
wire[15:0] wSpriteTopRightY    ;
wire[15:0] wSpriteBottomLeftX  ;
wire[15:0] wSpriteBottomLeftY  ;
wire[15:0] wSpriteBottomRightX ;
wire[15:0] wSpriteBottomRightY ;
wire[15:0] wTileLeft   ;
wire[15:0] wTileRight  ;
wire[15:0] wTileTop    ;
wire[15:0] wTileBottom ;




assign oFramBufferData = {wPixel7,wPixel6,wPixel5,wPixel4,wPixel3,wPixel2,wPixel1,wPixel0};
assign wPixel0 = ({wSh[0],wSl[0]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel0 : wSprtPixel0;
assign wPixel1 = ({wSh[1],wSl[1]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel1 : wSprtPixel1;
assign wPixel2 = ({wSh[2],wSl[2]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel2 : wSprtPixel2;
assign wPixel3 = ({wSh[3],wSl[3]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel3 : wSprtPixel3;
assign wPixel4 = ({wSh[4],wSl[4]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel4 : wSprtPixel4;
assign wPixel5 = ({wSh[5],wSl[5]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel5 : wSprtPixel5;
assign wPixel6 = ({wSh[6],wSl[6]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel6 : wSprtPixel6;
assign wPixel7 = ({wSh[7],wSl[7]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel7 : wSprtPixel7;





assign oFramBufferAddr = {2'b0,wFrameBufferAddress};
assign oFramBufferWe   = rBgBufferWe;


assign wSpriteWidth  = 16'h8;
assign wSpriteHeight = ( oLCDC[2] == 1'b1) ? 16'd16 : 16'd8;


assign wTileCoordX =  wCurrentTile[4:0] << 3;


assign wTileCoordY = (wCurrentTile >>5) << 3;



assign wSpriteTopLeftX     = wSpriteCoordX;
assign wSpriteTopLeftY     = wSpriteCoordY;

assign wSpriteTopRightX    = wSpriteCoordX + wSpriteWidth;
assign wSpriteTopRightY    = wSpriteCoordY;

assign wSpriteBottomLeftX  = wSpriteCoordX;
assign wSpriteBottomLeftY  = wSpriteCoordY + wSpriteHeight;

assign wSpriteBottomRightX = wSpriteTopRightX;
assign wSpriteBottomRightY = wSpriteBottomLeftY;

assign wTileLeft   = wTileCoordX;
assign wTileRight  = wTileCoordX + 8'd8;
assign wTileTop    = wTileCoordY;
assign wTileBottom = wTileCoordY + 16'd8;


assign wIsSpriteInCurrentTile =
   (


    ((wSpriteTopLeftX >= wTileLeft && wSpriteTopLeftX < wTileRight ) &&
    (wSpriteTopLeftY  >= wTileTop  && wSpriteTopLeftY < wTileBottom))
    ||

     ((wSpriteTopRightX >  wTileLeft && wSpriteTopRightX < wTileRight ) &&
     (wSpriteTopRightY  >  wTileTop  && wSpriteTopRightY < wTileBottom))
    ||
    ((wSpriteBottomRightX > wTileLeft && wSpriteBottomRightX < wTileRight ) &&
    (wSpriteBottomRightY  > wTileTop  && wSpriteBottomRightY < wTileBottom))
    ||
    ((wSpriteBottomLeftX > wTileLeft && wSpriteBottomLeftX < wTileRight ) &&
    (wSpriteBottomLeftY  > wTileTop  && wSpriteBottomLeftY < wTileBottom))
   ) ? 1'b1 : 1'b0;

assign wIsSpriteInCurrentRow = (wCurrentTileRow + wTileCoordY >= wSpriteCoordY &&
wCurrentTileRow + wTileCoordY <= wSpriteCoordY + wSpriteHeight) ? 1'b1 : 1'b0;

assign wIsWyOnScreen = (0 <= oWY <= 8'd143) ? 1'b1:1'b0;

assign wIsWxOnScreen = (0 <= oWX <= 8'd166) ? 1'b1:1'b0;

assign oSTAT = { 6'b0, wState };



FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LCDC( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[0], iMcuWriteData, oLCDC );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FFX_STAT(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[1], rResult[7:0], wState );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_SCY(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[2], iMcuWriteData, oSCY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_SCX(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[3], iMcuWriteData, oSCX );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LY(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[4], rResult[7:0], oLY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LYC(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[5], iMcuWriteData, oLYC );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_DMA(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[6], iMcuWriteData, oDMA );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_BGP(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[7], iMcuWriteData, oBGP );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_OBP0( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[8], iMcuWriteData, oOBP0 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_OBP1( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[9], iMcuWriteData, oOBP1 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_WY(   iClock, iReset, iMcuWe  & wMcuRegWriteSelect[10],iMcuWriteData, oWY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_WX(   iClock, iReset, iMcuWe  & wMcuRegWriteSelect[11],iMcuWriteData, oWX );




FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_12(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[12], rResult,      oMcuAddr );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_13(    iClock, iReset, wRegWe  & wGpuRegWriteSelect[13], rResult[7:0], wBh );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_14(    iClock, iReset, wRegWe  & wGpuRegWriteSelect[14], rResult[7:0], wBl );
UPCOUNTER_POSEDGE            # ( 16 )UP_15(    iClock, iReset,  13'b0, wGpuActive  & rIncFBufferAddr,          wFrameBufferAddress );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_16(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[16], rResult,      wCurrentTile );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_17(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[17], rResult,      wSprite_tile_offset );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_18(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[18], rResult,      wSpriteCoordX );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_19(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[19], rResult,      wSpriteCoordY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_20(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[20], rResult,      wCurrentTileRow );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_21(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[21], rResult[7:0],  wSh );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_22(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[22], rResult[7:0],  wSl );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_23(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[23], rResult,      wR0 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_24(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[24], rResult,      wR1 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_25(   iClock, iReset,  wRegWe  & wGpuRegWriteSelect[25], rResult[7:0], wR2 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_26(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[26], rResult,      wR3 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_27(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[27], rResult,      wR4 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_28(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[28], rResult,      wR5 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_29(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[29], rResult,      wR6 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_30(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[30], rResult,      wWinTile );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16  )FFX_31(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[31], rResult,      wSprite_info );














FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 )FFX_Z(   iClock, iReset, wRegWe, (rResult == 8'b0) ? 1'b1 : 1'b0, wZ );



assign wInitialPc = ( rJump ) ? wUop[7:0]: 8'b0;

UPCOUNTER_POSEDGE # (8) PC
(
  .Clock(   iClock                ),
  .Reset(   iReset | rJump        ),
  .Initial( wInitialPc            ),
  .Enable(  ~iReset & wGpuActive  ),
  .Q(       wIp                   )
);


assign wGpuActive = (oLCDC[7]) ? 1'b1 : 1'b0;
assign wRegSelect = ( wGpuActive ) ? wUop[14:10] : iMcuRegSelect ;
assign wRegWe     = ( wGpuActive ) ? rRegWe : iMcuWe ;































assign wTile1_Bg_Offset = (iMcuReadData[7] == 1'b1) ? 16'h8000 : 16'h8000;


assign wTile0_Bg_Offset = (iMcuReadData[7] == 1'b1) ? 16'h8000 : 16'h9000;

assign wBGTileOffset    = ( oLCDC[4] ) ? wTile1_Bg_Offset : wTile0_Bg_Offset;
assign wBGTileMapOffset = ( oLCDC[3] ) ? 16'h9c00 : 16'h9800;
assign wWinTileMapOffset = ( oLCDC[5] ) ? 16'h9c00 : 16'h9800;
assign wBGRowOffset     = wCurrentTileRow;

assign wOAMOffset = 16'hFE00;

assign wWinTileindex = ((oWY >> 3) << 5) + (oWX -3'd6) ;
assign wWinEnabled = (oLCDC[0]  &  oLCDC[5]);
assign wIsWininBG = ((wWinTile == wCurrentTile) && wWinEnabled == 1)? 1'b1: 1'b0;




`ifdef LCD_SCXY_DISABLED
  assign wSC_Tile = 16'b0;
`else




  assign wSC_Tile = ((oSCY >> 3) << 5) + oSCX;
`endif

assign wSC_Tile_Row = 8'b0;


assign wMcuRegWriteSelect = (1 << iMcuRegSelect);
assign wGpuRegWriteSelect = (1 << wUop[`GPU_DST_RNG]);



assign wOp0 = (wUop[`GPU_S0_RNG_SEL_BIT] == 1'b1) ? wOp0_Pre_A : wOp0_Pre_B;

MUXFULLPARALELL_4SEL_GENERIC # (16) MUX_REG0_A
(
  .Sel( wUop[ `GPU_S0_RNG_L]     ),
  .I0( wBGTileMapOffset          ),
  .I1( wBGTileOffset             ),
  .I2( {8'h0,iMcuReadData}       ),
  .I3( wBGRowOffset              ),
  .I4( {8'h0,6'h0,oLY[1:0]}      ),
  .I5( 16'd8191                  ),
  .I6( wOAMOffset                ),
  .I7( {4'b0,iMcuReadData,4'b0}  ),
  .I8( wSC_Tile                  ),
  .I9( {8'b0,wSC_Tile_Row}       ),
  .I10( {15'b0,wIsWininBG}       ),
  .I11( wWinTileindex            ),
  .I12(wWinTileMapOffset         ),
  .I13( 16'b0    ),
  .I14( 16'h0                    ),
  .I15( 16'h0                    ),

  .O( wOp0_Pre_A )
);


MUXFULLPARALELL_5SEL_GENERIC # (16) MUX_REG0_B
(
  .Sel( wUop[ `GPU_S0_RNG_H ] ),

  .I0( {8'h0,oLCDC} ),
  .I1( {8'h0,oSTAT} ),
  .I2( {8'h0,oSCY}  ),
  .I3( {8'h0,oSCX}  ),
  .I4( {8'h0,oLY}   ),
  .I5( {8'h0,oLYC}  ),
  .I6( {8'h0,oDMA}  ),
  .I7( {8'h0,oBGP}  ),
  .I8( {8'h0,oOBP0} ),
  .I9( {8'h0,oOBP1} ),
  .I10({8'h0,oWY}   ),
  .I11({8'h0,oWX}   ),
  .I12( oMcuAddr            ),
  .I13( {8'b0,wBh}          ),
  .I14( {8'b0,wBl}          ),
  .I15( wFrameBufferAddress ),
  .I16( wCurrentTile        ),
  .I17( wSprite_tile_offset ),
  .I18( wSpriteCoordX       ),
  .I19( wSpriteCoordY       ),
  .I20( wCurrentTileRow     ),
  .I21( {8'b0,wSh}          ),
  .I22( {8'b0,wSl}          ),
  .I23( wR0 ),
  .I24( wR1 ),
  .I25( {8'b0,wR2} ),
  .I26( wR3 ),
  .I27( wR4 ),
  .I28( wR5 ),
  .I29( wR6 ),
  .I30( wWinTile ),
  .I31( wSprite_info  ),

  .O( wOp0_Pre_B )
);






assign wOp1 = (wOp1Sel[5] == 1'b1) ? wOp1_Pre_A : wOp1_Pre_B;

assign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];

MUXFULLPARALELL_4SEL_GENERIC # (16) MUX_REG1_A
(
  .Sel( wOp1Sel[3:0]     ),
  .I0( wBGTileMapOffset          ),
  .I1( wBGTileOffset             ),
  .I2( {8'h0,iMcuReadData}       ),
  .I3( wBGRowOffset              ),
  .I4( {8'h0,6'h0,oLY[1:0]}      ),
  .I5( 16'd8191                  ),
  .I6( wOAMOffset                ),
  .I7( {4'b0,iMcuReadData,4'b0}  ),
  .I8( wSC_Tile                  ),
  .I9( {8'b0,wSC_Tile_Row}       ),
  .I10( {14'b0,wIsWininBG}       ),
  .I11( wWinTileindex            ),
  .I12( wWinTileMapOffset        ),
  .I13( 16'b0      ),
  .I14( 16'h0                    ),
  .I15( 16'h0                    ),

  .O( wOp1_Pre_A )
);


MUXFULLPARALELL_5SEL_GENERIC # (16) MUX_REG1_B
(
  .Sel( wOp1Sel[4:0] ),

  .I0( {8'h0,oLCDC} ),
  .I1( {8'h0,oSTAT} ),
  .I2( {8'h0,oSCY}  ),
  .I3( {8'h0,oSCX}  ),
  .I4( {8'h0,oLY}   ),
  .I5( {8'h0,oLYC}  ),
  .I6( {8'h0,oDMA}  ),
  .I7( {8'h0,oBGP}  ),
  .I8( {8'h0,oOBP0} ),
  .I9( {8'h0,oOBP1} ),
  .I10({8'h0,oWY}   ),
  .I11({8'h0,oWX}   ),
  .I12( oMcuAddr            ),
  .I13( {8'b0,wBh}          ),
  .I14( {8'b0,wBl}          ),
  .I15( wFrameBufferAddress ),
  .I16( wCurrentTile        ),
  .I17( wSprite_tile_offset ),
  .I18( wSpriteCoordX       ),
  .I19( wSpriteCoordY       ),
  .I20( wCurrentTileRow     ),
  .I21( {8'b0,wSh}          ),
  .I22( {8'b0,wSl}          ),
  .I23( wR0 ),
  .I24( wR1 ),
  .I25( {8'b0,wR2} ),
  .I26( wR3 ),
  .I27( wR4 ),
  .I28( wR5 ),
  .I29( wR6 ),
  .I30( wWinTile ),
  .I31( wSprite_info  ),

  .O( wOp1_Pre_B )
);




MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP0 (   .Sel( {wBh[0], wBl[0]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel0)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP1 (   .Sel( {wBh[1], wBl[1]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel1)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP2 (   .Sel( {wBh[2], wBl[2]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel2)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP3 (   .Sel( {wBh[3], wBl[3]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel3)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP4 (   .Sel( {wBh[4], wBl[4]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel4)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP5 (   .Sel( {wBh[5], wBl[5]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel5)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP6 (   .Sel( {wBh[6], wBl[6]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel6)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP7 (   .Sel( {wBh[7], wBl[7]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel7)  );



MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP0 ( .Sel( {wSprite_info[4],wSh[0], wSl[0]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel0));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP1 (.Sel( {wSprite_info[4],wSh[1], wSl[1]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel1));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP2 (.Sel( {wSprite_info[4],wSh[2], wSl[2]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel2));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP3 (.Sel( {wSprite_info[4],wSh[3], wSl[3]} ),

  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]),.I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),

  .O( wSprtPixel3));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP4 ( .Sel( {wSprite_info[4],wSh[4], wSl[4]} ),

  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel4));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP5 (.Sel( {wSprite_info[4],wSh[5], wSl[5]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel5));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP6 (.Sel( {wSprite_info[4],wSh[6], wSl[6]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel6));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP7 (.Sel( {wSprite_info[4],wSh[7], wSl[7]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel7));


always @ ( * )
begin
  case (wUop[`GPU_OP_RNG])
   `gnop:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwfbuffer:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b1;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `ginfbaddr:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b1;
    end

    `gwrr:
    begin
      rResult     = wOp1;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwrl:
    begin
      rResult     = wUop[`GPU_LIT_RNG];
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `grvmem:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b1;
      rIncFBufferAddr = 1'b0;
    end

    `gadd:
    begin
      rResult     = wOp1 + wOp0 ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end


    `gshl:
    begin
      rResult     = wOp1 << wUop[5:0]  ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gaddl:
    begin
      rResult     = wOp1 + {6'b0,wUop[`GPU_LIT_RNG]} ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gsubl:
    begin
      rResult     = wOp1 - {6'b0,wUop[`GPU_LIT_RNG]} ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end


    `gsub:
    begin
      rResult     = wOp1 - wOp0;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gjnz:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = ~wZ;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gjz:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = wZ;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `ggoto:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b1;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

  `gand:
    begin
      rResult     = wOp1 & wOp0 ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gsprtt:
    begin
      rResult     = {15'b0,wIsSpriteInCurrentTile};
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

   `gwx:
    begin
      rResult     = {15'b0,wIsWyOnScreen};
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwy:
     begin
       rResult     = {15'b0,wIsWyOnScreen};
       rRegWe      = 1'b1;
       rBgBufferWe = 1'b0;
       rJump       = 1'b0;
       oMcuReadRequest = 1'b0;
       rIncFBufferAddr = 1'b0;
     end

    default:
    begin
      rResult     = 16'hdead ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

  endcase
end

gpu_ucode_rom UCODE_ROM
(
  .iAddr( wIp ),
  .oUop(  wUop)
);

endmodule
module gpu
(
  input wire iClock,
  input wire iReset,

  output wire         oFramBufferWe,
  output wire [15:0]  oFramBufferData,
  output wire [15:0]  oFramBufferAddr,

  output wire [15:0] oMcuAddr,
  output reg        oMcuReadRequest,
  input wire [3:0]  iMcuRegSelect,
  input wire [7:0]  iMcuWriteData,
  input wire [7:0]  iMcuReadData,
  input wire        iMcuWe,


  output wire [7:0]  oSTAT,
  output wire [7:0]  oLCDC,
  output wire [7:0]  oSCY,
  output wire [7:0]  oSCX,
  output wire [7:0]  oLY,
  output wire [7:0]  oLYC,
  output wire [7:0]  oDMA,
  output wire [7:0]  oBGP,
  output wire [7:0]  oOBP0,
  output wire [7:0]  oOBP1,
  output wire [7:0]  oWY,
  output wire [7:0]  oWX

);



wire [20:0] wMcuRegWriteSelect;
wire [31:0] wGpuRegWriteSelect;
wire [15:0] wOp0, wOp1, wR0, wR1, wR3,wR4, wR5, wR6,  wSpriteCoordX,wSpriteCoordY, wOp0_Pre_B, wOp0_Pre_A, wOp1_Pre_B, wOp1_Pre_A;
wire [7:0] wR2;
wire [15:0]  wCurrentTile,wWinTile;
wire [7:0] wBh, wBl, wState, wIp, wInitialPc, wSC_Tile_Row;
wire [15:0] wBGTileOffset, wBGTileMapOffset, wBGRowOffset, wFrameBufferAddress, wCurrentTileRow,wOAMOffset;
wire [15:0] wTile1_Bg_Offset, wTile0_Bg_Offset,wWinTileMapOffset;
wire [15:0] wSC_Tile,wWinTileindex;
wire [7:0] wRegSelect, wSh, wSl;
wire [1:0] wPixel0,wPixel1,wPixel2,wPixel3,wPixel4,wPixel5,wPixel6,wPixel7;
wire [1:0] wBgPixel0,wBgPixel1,wBgPixel2,wBgPixel3,wBgPixel4,wBgPixel5,wBgPixel6,wBgPixel7;
wire [1:0] wSprtPixel0,wSprtPixel1,wSprtPixel2,wSprtPixel3,wSprtPixel4,wSprtPixel5,wSprtPixel6,wSprtPixel7;
wire [`GPU_UOP_SZ-1:0] wUop;
wire [5:0] wOp1Sel;
wire wZ, wRegWe, wGpuActive, wIsSpriteInCurrentTile,wIsSpriteInCurrentRow,wIsWyOnScreen,wIsWxOnScreen,wWinEnabled, wIsWininBG;
wire [15:0] wSpriteWidth, wSpriteHeight, wTileCoordX, wTileCoordY,wSprite_tile_offset,wSprite_info;
reg [15:0] rResult;
reg rRegWe, rBgBufferWe, rJump, rIncFBufferAddr;

wire[15:0] wSpriteTopLeftX     ;
wire[15:0] wSpriteTopLeftY     ;
wire[15:0] wSpriteTopRightX    ;
wire[15:0] wSpriteTopRightY    ;
wire[15:0] wSpriteBottomLeftX  ;
wire[15:0] wSpriteBottomLeftY  ;
wire[15:0] wSpriteBottomRightX ;
wire[15:0] wSpriteBottomRightY ;
wire[15:0] wTileLeft   ;
wire[15:0] wTileRight  ;
wire[15:0] wTileTop    ;
wire[15:0] wTileBottom ;




assign oFramBufferData = {wPixel7,wPixel6,wPixel5,wPixel4,wPixel3,wPixel2,wPixel1,wPixel0};
assign wPixel0 = ({wSh[0],wSl[0]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel0 : wSprtPixel0;
assign wPixel1 = ({wSh[1],wSl[1]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel1 : wSprtPixel1;
assign wPixel2 = ({wSh[2],wSl[2]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel2 : wSprtPixel2;
assign wPixel3 = ({wSh[3],wSl[3]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel3 : wSprtPixel3;
assign wPixel4 = ({wSh[4],wSl[4]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel4 : wSprtPixel4;
assign wPixel5 = ({wSh[5],wSl[5]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel5 : wSprtPixel5;
assign wPixel6 = ({wSh[6],wSl[6]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel6 : wSprtPixel6;
assign wPixel7 = ({wSh[7],wSl[7]} == `SPRITE_COLOR_TRANSPARENT)? wBgPixel7 : wSprtPixel7;





assign oFramBufferAddr = {2'b0,wFrameBufferAddress};
assign oFramBufferWe   = rBgBufferWe;


assign wSpriteWidth  = 16'h8;
assign wSpriteHeight = ( oLCDC[2] == 1'b1) ? 16'd16 : 16'd8;


assign wTileCoordX =  wCurrentTile[4:0] << 3;


assign wTileCoordY = (wCurrentTile >>5) << 3;



assign wSpriteTopLeftX     = wSpriteCoordX;
assign wSpriteTopLeftY     = wSpriteCoordY;

assign wSpriteTopRightX    = wSpriteCoordX + wSpriteWidth;
assign wSpriteTopRightY    = wSpriteCoordY;

assign wSpriteBottomLeftX  = wSpriteCoordX;
assign wSpriteBottomLeftY  = wSpriteCoordY + wSpriteHeight;

assign wSpriteBottomRightX = wSpriteTopRightX;
assign wSpriteBottomRightY = wSpriteBottomLeftY;

assign wTileLeft   = wTileCoordX;
assign wTileRight  = wTileCoordX + 8'd8;
assign wTileTop    = wTileCoordY;
assign wTileBottom = wTileCoordY + 16'd8;


assign wIsSpriteInCurrentTile =
   (


    ((wSpriteTopLeftX >= wTileLeft && wSpriteTopLeftX < wTileRight ) &&
    (wSpriteTopLeftY  >= wTileTop  && wSpriteTopLeftY < wTileBottom))
    ||

     ((wSpriteTopRightX >  wTileLeft && wSpriteTopRightX < wTileRight ) &&
     (wSpriteTopRightY  >  wTileTop  && wSpriteTopRightY < wTileBottom))
    ||
    ((wSpriteBottomRightX > wTileLeft && wSpriteBottomRightX < wTileRight ) &&
    (wSpriteBottomRightY  > wTileTop  && wSpriteBottomRightY < wTileBottom))
    ||
    ((wSpriteBottomLeftX > wTileLeft && wSpriteBottomLeftX < wTileRight ) &&
    (wSpriteBottomLeftY  > wTileTop  && wSpriteBottomLeftY < wTileBottom))
   ) ? 1'b1 : 1'b0;

assign wIsSpriteInCurrentRow = (wCurrentTileRow + wTileCoordY >= wSpriteCoordY &&
wCurrentTileRow + wTileCoordY <= wSpriteCoordY + wSpriteHeight) ? 1'b1 : 1'b0;

assign wIsWyOnScreen = (0 <= oWY <= 8'd143) ? 1'b1:1'b0;

assign wIsWxOnScreen = (0 <= oWX <= 8'd166) ? 1'b1:1'b0;

assign oSTAT = { 6'b0, wState };



FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LCDC( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[0], iMcuWriteData, oLCDC );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FFX_STAT(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[1], rResult[7:0], wState );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_SCY(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[2], iMcuWriteData, oSCY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_SCX(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[3], iMcuWriteData, oSCX );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LY(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[4], rResult[7:0], oLY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_LYC(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[5], iMcuWriteData, oLYC );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 ) FF_DMA(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[6], iMcuWriteData, oDMA );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_BGP(  iClock, iReset, iMcuWe  & wMcuRegWriteSelect[7], iMcuWriteData, oBGP );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_OBP0( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[8], iMcuWriteData, oOBP0 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_OBP1( iClock, iReset, iMcuWe  & wMcuRegWriteSelect[9], iMcuWriteData, oOBP1 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFS_WY(   iClock, iReset, iMcuWe  & wMcuRegWriteSelect[10],iMcuWriteData, oWY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_WX(   iClock, iReset, iMcuWe  & wMcuRegWriteSelect[11],iMcuWriteData, oWX );




FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_12(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[12], rResult,      oMcuAddr );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_13(    iClock, iReset, wRegWe  & wGpuRegWriteSelect[13], rResult[7:0], wBh );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_14(    iClock, iReset, wRegWe  & wGpuRegWriteSelect[14], rResult[7:0], wBl );
UPCOUNTER_POSEDGE            # ( 16 )UP_15(    iClock, iReset,  13'b0, wGpuActive  & rIncFBufferAddr,          wFrameBufferAddress );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_16(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[16], rResult,      wCurrentTile );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_17(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[17], rResult,      wSprite_tile_offset );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_18(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[18], rResult,      wSpriteCoordX );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_19(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[19], rResult,      wSpriteCoordY );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_20(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[20], rResult,      wCurrentTileRow );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_21(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[21], rResult[7:0],  wSh );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_22(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[22], rResult[7:0],  wSl );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_23(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[23], rResult,      wR0 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_24(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[24], rResult,      wR1 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 8 )FFX_25(   iClock, iReset,  wRegWe  & wGpuRegWriteSelect[25], rResult[7:0], wR2 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_26(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[26], rResult,      wR3 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_27(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[27], rResult,      wR4 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_28(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[28], rResult,      wR5 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_29(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[29], rResult,      wR6 );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16 )FFX_30(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[30], rResult,      wWinTile );
FFD_POSEDGE_SYNCRONOUS_RESET # ( 16  )FFX_31(   iClock, iReset, wRegWe  & wGpuRegWriteSelect[31], rResult,      wSprite_info );














FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 )FFX_Z(   iClock, iReset, wRegWe, (rResult == 8'b0) ? 1'b1 : 1'b0, wZ );



assign wInitialPc = ( rJump ) ? wUop[7:0]: 8'b0;

UPCOUNTER_POSEDGE # (8) PC
(
  .Clock(   iClock                ),
  .Reset(   iReset | rJump        ),
  .Initial( wInitialPc            ),
  .Enable(  ~iReset & wGpuActive  ),
  .Q(       wIp                   )
);


assign wGpuActive = (oLCDC[7]) ? 1'b1 : 1'b0;
assign wRegSelect = ( wGpuActive ) ? wUop[14:10] : iMcuRegSelect ;
assign wRegWe     = ( wGpuActive ) ? rRegWe : iMcuWe ;































assign wTile1_Bg_Offset = (iMcuReadData[7] == 1'b1) ? 16'h8000 : 16'h8000;


assign wTile0_Bg_Offset = (iMcuReadData[7] == 1'b1) ? 16'h8000 : 16'h9000;

assign wBGTileOffset    = ( oLCDC[4] ) ? wTile1_Bg_Offset : wTile0_Bg_Offset;
assign wBGTileMapOffset = ( oLCDC[3] ) ? 16'h9c00 : 16'h9800;
assign wWinTileMapOffset = ( oLCDC[5] ) ? 16'h9c00 : 16'h9800;
assign wBGRowOffset     = wCurrentTileRow;

assign wOAMOffset = 16'hFE00;

assign wWinTileindex = ((oWY >> 3) << 5) + (oWX -3'd6) ;
assign wWinEnabled = (oLCDC[0]  &  oLCDC[5]);
assign wIsWininBG = ((wWinTile == wCurrentTile) && wWinEnabled == 1)? 1'b1: 1'b0;




`ifdef LCD_SCXY_DISABLED
  assign wSC_Tile = 16'b0;
`else




  assign wSC_Tile = ((oSCY >> 3) << 5) + oSCX;
`endif

assign wSC_Tile_Row = 8'b0;


assign wMcuRegWriteSelect = (1 << iMcuRegSelect);
assign wGpuRegWriteSelect = (1 << wUop[`GPU_DST_RNG]);



assign wOp0 = (wUop[`GPU_S0_RNG_SEL_BIT] == 1'b1) ? wOp0_Pre_A : wOp0_Pre_B;

MUXFULLPARALELL_4SEL_GENERIC # (16) MUX_REG0_A
(
  .Sel( wUop[ `GPU_S0_RNG_L]     ),
  .I0( wBGTileMapOffset          ),
  .I1( wBGTileOffset             ),
  .I2( {8'h0,iMcuReadData}       ),
  .I3( wBGRowOffset              ),
  .I4( {8'h0,6'h0,oLY[1:0]}      ),
  .I5( 16'd8191                  ),
  .I6( wOAMOffset                ),
  .I7( {4'b0,iMcuReadData,4'b0}  ),
  .I8( wSC_Tile                  ),
  .I9( {8'b0,wSC_Tile_Row}       ),
  .I10( {15'b0,wIsWininBG}       ),
  .I11( wWinTileindex            ),
  .I12(wWinTileMapOffset         ),
  .I13( 16'b0    ),
  .I14( 16'h0                    ),
  .I15( 16'h0                    ),

  .O( wOp0_Pre_A )
);


MUXFULLPARALELL_5SEL_GENERIC # (16) MUX_REG0_B
(
  .Sel( wUop[ `GPU_S0_RNG_H ] ),

  .I0( {8'h0,oLCDC} ),
  .I1( {8'h0,oSTAT} ),
  .I2( {8'h0,oSCY}  ),
  .I3( {8'h0,oSCX}  ),
  .I4( {8'h0,oLY}   ),
  .I5( {8'h0,oLYC}  ),
  .I6( {8'h0,oDMA}  ),
  .I7( {8'h0,oBGP}  ),
  .I8( {8'h0,oOBP0} ),
  .I9( {8'h0,oOBP1} ),
  .I10({8'h0,oWY}   ),
  .I11({8'h0,oWX}   ),
  .I12( oMcuAddr            ),
  .I13( {8'b0,wBh}          ),
  .I14( {8'b0,wBl}          ),
  .I15( wFrameBufferAddress ),
  .I16( wCurrentTile        ),
  .I17( wSprite_tile_offset ),
  .I18( wSpriteCoordX       ),
  .I19( wSpriteCoordY       ),
  .I20( wCurrentTileRow     ),
  .I21( {8'b0,wSh}          ),
  .I22( {8'b0,wSl}          ),
  .I23( wR0 ),
  .I24( wR1 ),
  .I25( {8'b0,wR2} ),
  .I26( wR3 ),
  .I27( wR4 ),
  .I28( wR5 ),
  .I29( wR6 ),
  .I30( wWinTile ),
  .I31( wSprite_info  ),

  .O( wOp0_Pre_B )
);






assign wOp1 = (wOp1Sel[5] == 1'b1) ? wOp1_Pre_A : wOp1_Pre_B;

assign wOp1Sel = (wUop[`GPU_OP_RNG] == `gaddl || wUop[`GPU_OP_RNG] == `gsubl ) ? wUop[`GPU_DST_RNG] : wUop[`GPU_S1_RNG];

MUXFULLPARALELL_4SEL_GENERIC # (16) MUX_REG1_A
(
  .Sel( wOp1Sel[3:0]     ),
  .I0( wBGTileMapOffset          ),
  .I1( wBGTileOffset             ),
  .I2( {8'h0,iMcuReadData}       ),
  .I3( wBGRowOffset              ),
  .I4( {8'h0,6'h0,oLY[1:0]}      ),
  .I5( 16'd8191                  ),
  .I6( wOAMOffset                ),
  .I7( {4'b0,iMcuReadData,4'b0}  ),
  .I8( wSC_Tile                  ),
  .I9( {8'b0,wSC_Tile_Row}       ),
  .I10( {14'b0,wIsWininBG}       ),
  .I11( wWinTileindex            ),
  .I12( wWinTileMapOffset        ),
  .I13( 16'b0      ),
  .I14( 16'h0                    ),
  .I15( 16'h0                    ),

  .O( wOp1_Pre_A )
);


MUXFULLPARALELL_5SEL_GENERIC # (16) MUX_REG1_B
(
  .Sel( wOp1Sel[4:0] ),

  .I0( {8'h0,oLCDC} ),
  .I1( {8'h0,oSTAT} ),
  .I2( {8'h0,oSCY}  ),
  .I3( {8'h0,oSCX}  ),
  .I4( {8'h0,oLY}   ),
  .I5( {8'h0,oLYC}  ),
  .I6( {8'h0,oDMA}  ),
  .I7( {8'h0,oBGP}  ),
  .I8( {8'h0,oOBP0} ),
  .I9( {8'h0,oOBP1} ),
  .I10({8'h0,oWY}   ),
  .I11({8'h0,oWX}   ),
  .I12( oMcuAddr            ),
  .I13( {8'b0,wBh}          ),
  .I14( {8'b0,wBl}          ),
  .I15( wFrameBufferAddress ),
  .I16( wCurrentTile        ),
  .I17( wSprite_tile_offset ),
  .I18( wSpriteCoordX       ),
  .I19( wSpriteCoordY       ),
  .I20( wCurrentTileRow     ),
  .I21( {8'b0,wSh}          ),
  .I22( {8'b0,wSl}          ),
  .I23( wR0 ),
  .I24( wR1 ),
  .I25( {8'b0,wR2} ),
  .I26( wR3 ),
  .I27( wR4 ),
  .I28( wR5 ),
  .I29( wR6 ),
  .I30( wWinTile ),
  .I31( wSprite_info  ),

  .O( wOp1_Pre_B )
);




MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP0 (   .Sel( {wBh[0], wBl[0]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel0)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP1 (   .Sel( {wBh[1], wBl[1]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel1)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP2 (   .Sel( {wBh[2], wBl[2]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel2)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP3 (   .Sel( {wBh[3], wBl[3]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel3)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP4 (   .Sel( {wBh[4], wBl[4]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel4)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP5 (   .Sel( {wBh[5], wBl[5]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel5)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP6 (   .Sel( {wBh[6], wBl[6]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel6)  );

MUXFULLPARALELL_2SEL_GENERIC # (2) MUX_BGP7 (   .Sel( {wBh[7], wBl[7]} ),
  .I0( oBGP[1:0]), .I1( oBGP[3:2]), .I2( oBGP[5:4]), .I3( oBGP[7:6]) , .O( wBgPixel7)  );



MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP0 ( .Sel( {wSprite_info[4],wSh[0], wSl[0]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel0));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP1 (.Sel( {wSprite_info[4],wSh[1], wSl[1]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel1));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP2 (.Sel( {wSprite_info[4],wSh[2], wSl[2]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel2));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP3 (.Sel( {wSprite_info[4],wSh[3], wSl[3]} ),

  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]),.I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),

  .O( wSprtPixel3));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP4 ( .Sel( {wSprite_info[4],wSh[4], wSl[4]} ),

  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel4));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP5 (.Sel( {wSprite_info[4],wSh[5], wSl[5]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel5));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP6 (.Sel( {wSprite_info[4],wSh[6], wSl[6]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel6));

MUXFULLPARALELL_3SEL_GENERIC # (2) MUX_SprtP7 (.Sel( {wSprite_info[4],wSh[7], wSl[7]} ),
  .I3( oOBP0[1:0]), .I2( oOBP0[3:2]), .I1( oOBP0[5:4]), .I0( oOBP0[7:6]) ,
  .I4( oOBP1[1:0]), .I5( oOBP1[3:2]), .I6( oOBP1[5:4]), .I7( oOBP1[7:6]),
  .O( wSprtPixel7));


always @ ( * )
begin
  case (wUop[`GPU_OP_RNG])
   `gnop:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwfbuffer:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b1;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `ginfbaddr:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b1;
    end

    `gwrr:
    begin
      rResult     = wOp1;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwrl:
    begin
      rResult     = wUop[`GPU_LIT_RNG];
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `grvmem:
    begin
      rResult     = wUop[7:0];
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b1;
      rIncFBufferAddr = 1'b0;
    end

    `gadd:
    begin
      rResult     = wOp1 + wOp0 ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end


    `gshl:
    begin
      rResult     = wOp1 << wUop[5:0]  ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gaddl:
    begin
      rResult     = wOp1 + {6'b0,wUop[`GPU_LIT_RNG]} ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gsubl:
    begin
      rResult     = wOp1 - {6'b0,wUop[`GPU_LIT_RNG]} ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end


    `gsub:
    begin
      rResult     = wOp1 - wOp0;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gjnz:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = ~wZ;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gjz:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = wZ;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `ggoto:
    begin
      rResult     = wOp1 ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b1;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

  `gand:
    begin
      rResult     = wOp1 & wOp0 ;
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gsprtt:
    begin
      rResult     = {15'b0,wIsSpriteInCurrentTile};
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

   `gwx:
    begin
      rResult     = {15'b0,wIsWyOnScreen};
      rRegWe      = 1'b1;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

    `gwy:
     begin
       rResult     = {15'b0,wIsWyOnScreen};
       rRegWe      = 1'b1;
       rBgBufferWe = 1'b0;
       rJump       = 1'b0;
       oMcuReadRequest = 1'b0;
       rIncFBufferAddr = 1'b0;
     end

    default:
    begin
      rResult     = 16'hdead ;
      rRegWe      = 1'b0;
      rBgBufferWe = 1'b0;
      rJump       = 1'b0;
      oMcuReadRequest = 1'b0;
      rIncFBufferAddr = 1'b0;
    end

  endcase
end

gpu_ucode_rom UCODE_ROM
(
  .iAddr( wIp ),
  .oUop(  wUop)
);

endmodule