data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v
1: b'%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:40: Cannot find include file: openGFX430_defines.v\n`include "openGFX430_defines.v" \n         ^~~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/531094269/verilog/rtl/src,data/full_repos/permissive/531094269/openGFX430_defines.v\n             data/full_repos/permissive/531094269/verilog/rtl/src,data/full_repos/permissive/531094269/openGFX430_defines.v.v\n             data/full_repos/permissive/531094269/verilog/rtl/src,data/full_repos/permissive/531094269/openGFX430_defines.v.sv\n             openGFX430_defines.v\n             openGFX430_defines.v.v\n             openGFX430_defines.v.sv\n             obj_dir/openGFX430_defines.v\n             obj_dir/openGFX430_defines.v.v\n             obj_dir/openGFX430_defines.v.sv\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:560: Cannot find include file: openGFX430_undefines.v\n`include "openGFX430_undefines.v" \n         ^~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:92: Define or directive not defined: \'`VRAM_MSB\'\noutput   [`VRAM_MSB:0] vid_ram_addr_o;             \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:92: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\noutput   [`VRAM_MSB:0] vid_ram_addr_o;             \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:102: Define or directive not defined: \'`APIX_MSB\'\ninput    [`APIX_MSB:0] cfg_dst_px_addr_i;          \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:102: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\ninput    [`APIX_MSB:0] cfg_dst_px_addr_i;          \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:108: Define or directive not defined: \'`LPIX_MSB\'\ninput    [`LPIX_MSB:0] cfg_rec_width_i;            \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:108: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\ninput    [`LPIX_MSB:0] cfg_rec_width_i;            \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:109: Define or directive not defined: \'`LPIX_MSB\'\ninput    [`LPIX_MSB:0] cfg_rec_height_i;           \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:109: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\ninput    [`LPIX_MSB:0] cfg_rec_height_i;           \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:110: Define or directive not defined: \'`APIX_MSB\'\ninput    [`APIX_MSB:0] cfg_src_px_addr_i;          \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:110: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\ninput    [`APIX_MSB:0] cfg_src_px_addr_i;          \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:116: Define or directive not defined: \'`LPIX_MSB\'\ninput    [`LPIX_MSB:0] display_width_i;            \n          ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:116: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\ninput    [`LPIX_MSB:0] display_width_i;            \n                   ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:248: Define or directive not defined: \'`LPIX_MSB\'\nreg [`LPIX_MSB:0] height_cnt;\n     ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:248: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nreg [`LPIX_MSB:0] height_cnt;\n              ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:250: Define or directive not defined: \'`LPIX_MSB\'\nreg [`LPIX_MSB:0] width_cnt;\n     ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:250: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nreg [`LPIX_MSB:0] width_cnt;\n              ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:258: Define or directive not defined: \'`LPIX_MSB\'\n  if (puc_rst)              height_cnt <= {{`LPIX_MSB{1\'h0}},1\'b1};\n                                            ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:260: Define or directive not defined: \'`LPIX_MSB\'\n  else if (height_cnt_dec)  height_cnt <= height_cnt-{{`LPIX_MSB{1\'h0}},1\'b1};\n                                                       ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:262: Define or directive not defined: \'`LPIX_MSB\'\nassign                      height_cnt_done = (height_cnt=={{`LPIX_MSB{1\'h0}}, 1\'b1});\n                                                             ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:269: Define or directive not defined: \'`LPIX_MSB\'\n  if (puc_rst)              width_cnt <= {{`LPIX_MSB{1\'h0}},1\'b1};\n                                           ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:271: Define or directive not defined: \'`LPIX_MSB\'\n  else if (width_cnt_dec)   width_cnt <= width_cnt-{{`LPIX_MSB{1\'h0}},1\'b1};\n                                                     ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:273: Define or directive not defined: \'`LPIX_MSB\'\nassign            width_cnt_done = (width_cnt=={{`LPIX_MSB{1\'h0}}, 1\'b1});\n                                                 ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:283: Define or directive not defined: \'`APIX_MSB\'\nreg  [`APIX_MSB:0] vram_src_addr;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:283: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nreg  [`APIX_MSB:0] vram_src_addr;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:284: Define or directive not defined: \'`APIX_MSB\'\nwire [`APIX_MSB:0] vram_src_addr_calc;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:284: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nwire [`APIX_MSB:0] vram_src_addr_calc;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:287: Define or directive not defined: \'`APIX_MSB\'\nwire [`APIX_MSB:0] vram_src_addr_nxt  = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:287: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nwire [`APIX_MSB:0] vram_src_addr_nxt  = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:290: Define or directive not defined: \'`APIX_MSB\'\n  if (puc_rst)                              vram_src_addr <=  {`APIX_MSB+1{1\'b0}};\n                                                               ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:359: Define or directive not defined: \'`APIX_MSB\'\nreg  [`APIX_MSB:0] vram_dst_addr;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:359: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nreg  [`APIX_MSB:0] vram_dst_addr;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:360: Define or directive not defined: \'`APIX_MSB\'\nwire [`APIX_MSB:0] vram_dst_addr_calc;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:360: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nwire [`APIX_MSB:0] vram_dst_addr_calc;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:363: Define or directive not defined: \'`APIX_MSB\'\nwire [`APIX_MSB:0] vram_dst_addr_nxt  = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc;\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:363: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nwire [`APIX_MSB:0] vram_dst_addr_nxt  = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc;\n               ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:366: Define or directive not defined: \'`APIX_MSB\'\n  if (puc_rst)                              vram_dst_addr <=  {`APIX_MSB+1{1\'b0}};\n                                                               ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:546: Define or directive not defined: \'`APIX_MSB\'\nassign      vid_ram_addr_o =  (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] :\n                                                                    ^~~~~~~~~\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:546: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nassign      vid_ram_addr_o =  (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] :\n                                                                             ^\n%Error: data/full_repos/permissive/531094269/verilog/rtl/src/ogfx_gpu_dma.v:547: Define or directive not defined: \'`APIX_MSB\'\n                                                      vram_dst_addr[`APIX_MSB:4] ;\n                                                                    ^~~~~~~~~\n%Error: Exiting due to 41 error(s)\n'
module  ogfx_gpu_dma (


    gpu_exec_done_o,
    gpu_dma_busy_o,

    vid_ram_addr_o,
    vid_ram_din_o,
    vid_ram_wen_o,
    vid_ram_cen_o,


    mclk,
    puc_rst,

    cfg_dst_px_addr_i,
    cfg_dst_cl_swp_i,
    cfg_dst_x_swp_i,
    cfg_dst_y_swp_i,
    cfg_fill_color_i,
    cfg_pix_op_sel_i,
    cfg_rec_width_i,
    cfg_rec_height_i,
    cfg_src_px_addr_i,
    cfg_src_cl_swp_i,
    cfg_src_x_swp_i,
    cfg_src_y_swp_i,
    cfg_transparent_color_i,

    display_width_i,

    gfx_mode_i,

    gpu_enable_i,

    exec_fill_i,
    exec_copy_i,
    exec_copy_trans_i,
    trig_exec_i,

    vid_ram_dout_i,
    vid_ram_dout_rdy_nxt_i
);



output                 gpu_exec_done_o;
output                 gpu_dma_busy_o;

output   [`VRAM_MSB:0] vid_ram_addr_o;
output          [15:0] vid_ram_din_o;
output                 vid_ram_wen_o;
output                 vid_ram_cen_o;



input                  mclk;
input                  puc_rst;

input    [`APIX_MSB:0] cfg_dst_px_addr_i;
input                  cfg_dst_cl_swp_i;
input                  cfg_dst_x_swp_i;
input                  cfg_dst_y_swp_i;
input           [15:0] cfg_fill_color_i;
input            [3:0] cfg_pix_op_sel_i;
input    [`LPIX_MSB:0] cfg_rec_width_i;
input    [`LPIX_MSB:0] cfg_rec_height_i;
input    [`APIX_MSB:0] cfg_src_px_addr_i;
input                  cfg_src_cl_swp_i;
input                  cfg_src_x_swp_i;
input                  cfg_src_y_swp_i;
input           [15:0] cfg_transparent_color_i;

input    [`LPIX_MSB:0] display_width_i;

input            [2:0] gfx_mode_i;

input                  gpu_enable_i;

input                  exec_fill_i;
input                  exec_copy_i;
input                  exec_copy_trans_i;
input                  trig_exec_i;

input           [15:0] vid_ram_dout_i;
input                  vid_ram_dout_rdy_nxt_i;







wire       gfx_mode_1_bpp    =  (gfx_mode_i == 3'b000);
wire       gfx_mode_2_bpp    =  (gfx_mode_i == 3'b001);
wire       gfx_mode_4_bpp    =  (gfx_mode_i == 3'b010);
wire       gfx_mode_8_bpp    =  (gfx_mode_i == 3'b011);
wire       gfx_mode_16_bpp   = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp);



wire       pix_op_00         =  (cfg_pix_op_sel_i == 4'b0000);
wire       pix_op_01         =  (cfg_pix_op_sel_i == 4'b0001);
wire       pix_op_02         =  (cfg_pix_op_sel_i == 4'b0010);

wire       pix_op_03         =  (cfg_pix_op_sel_i == 4'b0011);
wire       pix_op_04         =  (cfg_pix_op_sel_i == 4'b0100);
wire       pix_op_05         =  (cfg_pix_op_sel_i == 4'b0101);

wire       pix_op_06         =  (cfg_pix_op_sel_i == 4'b0110);
wire       pix_op_07         =  (cfg_pix_op_sel_i == 4'b0111);
wire       pix_op_08         =  (cfg_pix_op_sel_i == 4'b1000);

wire       pix_op_09         =  (cfg_pix_op_sel_i == 4'b1001);
wire       pix_op_10         =  (cfg_pix_op_sel_i == 4'b1010);
wire       pix_op_11         =  (cfg_pix_op_sel_i == 4'b1011);
wire       pix_op_12         =  (cfg_pix_op_sel_i == 4'b1100);

wire       pix_op_13         =  (cfg_pix_op_sel_i == 4'b1101);
wire       pix_op_14         =  (cfg_pix_op_sel_i == 4'b1110);
wire       pix_op_15         =  (cfg_pix_op_sel_i == 4'b1111);

wire       dma_done;
wire       pixel_is_transparent;


function [15:0] one_hot16;
   input  [3:0] binary;
   begin
      one_hot16         = 16'h0000;
      one_hot16[binary] =  1'b1;
   end
endfunction







parameter  IDLE           = 3'h0;
parameter  INIT           = 3'h1;
parameter  SKIP           = 3'h2;
parameter  SRC_READ       = 3'h3;
parameter  DST_READ       = 3'h4;
parameter  DST_WRITE      = 3'h5;


reg  [2:0] dma_state;
reg  [2:0] dma_state_nxt;


wire       needs_src_read    = (exec_copy_i & ~pix_op_02) | exec_copy_trans_i;
wire       needs_dst_read    = (exec_fill_i | exec_copy_trans_i | exec_copy_i) & (~(pix_op_00 | pix_op_01 | pix_op_13 | pix_op_14 | pix_op_15) | ~gfx_mode_16_bpp);
wire       needs_dst_write   = (exec_fill_i | exec_copy_trans_i | exec_copy_i) &  ~pixel_is_transparent;

wire       data_ready_nxt    =   (dma_state==SRC_READ) |
                               (((dma_state==DST_READ) |
                                 (dma_state==DST_WRITE)) & ~pixel_is_transparent) ? vid_ram_dout_rdy_nxt_i : 1'b1;


always @(dma_state or trig_exec_i or needs_src_read or needs_dst_read or data_ready_nxt or dma_done or needs_dst_write)
  case (dma_state)
    IDLE           : dma_state_nxt = ~trig_exec_i       ?  IDLE	     :	INIT      ;

    INIT	   : dma_state_nxt =  needs_src_read	?  SRC_READ  :
				      needs_dst_read	?  DST_READ  :
				      needs_dst_write   ?  DST_WRITE :  SKIP      ;

    SKIP           : dma_state_nxt =  dma_done          ?  IDLE      :  SKIP      ;

    SRC_READ       : dma_state_nxt = ~data_ready_nxt    ?  SRC_READ  :
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;

    DST_READ       : dma_state_nxt = ~data_ready_nxt    ?  DST_READ  :
                                      needs_dst_write   ?  DST_WRITE :
                                      dma_done          ?  IDLE      :  SRC_READ  ;

    DST_WRITE      : dma_state_nxt = ~data_ready_nxt    ?  DST_WRITE :
                                      dma_done          ?  IDLE      :
                                      needs_src_read    ?  SRC_READ  :
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;

    default        : dma_state_nxt =  IDLE;

  endcase


always @(posedge mclk or posedge puc_rst)
  if (puc_rst)            dma_state <= IDLE;
  else if (~gpu_enable_i) dma_state <= IDLE;
  else                    dma_state <= dma_state_nxt;



wire   dma_init        = (dma_state==INIT);
wire   dma_pixel_done  = (dma_state==SKIP) | ((dma_state==DST_READ)  & pixel_is_transparent) |
                                             ((dma_state==DST_WRITE) & data_ready_nxt      ) ;
assign gpu_exec_done_o = (dma_state==IDLE) & ~trig_exec_i;
assign gpu_dma_busy_o  = (dma_state!=IDLE);





reg [`LPIX_MSB:0] height_cnt;
wire              height_cnt_done;
reg [`LPIX_MSB:0] width_cnt;
wire              width_cnt_done;


wire              height_cnt_init = dma_init;
wire              height_cnt_dec  = dma_pixel_done & width_cnt_done & ~height_cnt_done;

always @(posedge mclk or posedge puc_rst)
  if (puc_rst)              height_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
  else if (height_cnt_init) height_cnt <= cfg_rec_height_i;
  else if (height_cnt_dec)  height_cnt <= height_cnt-{{`LPIX_MSB{1'h0}},1'b1};

assign                      height_cnt_done = (height_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});


wire              width_cnt_init = dma_init | height_cnt_dec;
wire              width_cnt_dec  = dma_pixel_done & ~width_cnt_done;

always @(posedge mclk or posedge puc_rst)
  if (puc_rst)              width_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
  else if (width_cnt_init)  width_cnt <= cfg_rec_width_i;
  else if (width_cnt_dec)   width_cnt <= width_cnt-{{`LPIX_MSB{1'h0}},1'b1};

assign            width_cnt_done = (width_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});


assign            dma_done       = height_cnt_done & width_cnt_done;






reg  [`APIX_MSB:0] vram_src_addr;
wire [`APIX_MSB:0] vram_src_addr_calc;

wire               vram_src_addr_inc  = dma_pixel_done & needs_src_read;
wire [`APIX_MSB:0] vram_src_addr_nxt  = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                              vram_src_addr <=  {`APIX_MSB+1{1'b0}};
  else if (trig_exec_i | vram_src_addr_inc) vram_src_addr <=  vram_src_addr_nxt;



ogfx_gpu_dma_addr ogfx_gpu_dma_src_addr_inst (


    .vid_ram_addr_nxt_o      ( vram_src_addr_calc      ),


    .mclk                    ( mclk                    ),
    .puc_rst                 ( puc_rst                 ),
    .display_width_i         ( display_width_i         ),
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),
    .vid_ram_addr_i          ( vram_src_addr           ),
    .vid_ram_addr_init_i     ( dma_init                ),
    .vid_ram_addr_step_i     ( vram_src_addr_inc       ),
    .vid_ram_width_i         ( cfg_rec_width_i         ),
    .vid_ram_win_x_swap_i    ( cfg_src_x_swp_i         ),
    .vid_ram_win_y_swap_i    ( cfg_src_y_swp_i         ),
    .vid_ram_win_cl_swap_i   ( cfg_src_cl_swp_i        )
);





reg  [15:0] vram_src_mask;
wire [15:0] vram_src_mask_shift    = one_hot16(vram_src_addr_nxt[3:0]);
wire [15:0] vram_src_mask_vram_nxt = ({16{gfx_mode_1_bpp }} &     vram_src_mask_shift       ) |
                                     ({16{gfx_mode_2_bpp }} & {{2{vram_src_mask_shift[14]}},
                                                               {2{vram_src_mask_shift[12]}},
                                                               {2{vram_src_mask_shift[10]}},
                                                               {2{vram_src_mask_shift[8] }},
                                                               {2{vram_src_mask_shift[6] }},
                                                               {2{vram_src_mask_shift[4] }},
                                                               {2{vram_src_mask_shift[2] }},
                                                               {2{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_4_bpp }} & {{4{vram_src_mask_shift[12]}},
                                                               {4{vram_src_mask_shift[8] }},
                                                               {4{vram_src_mask_shift[4] }},
                                                               {4{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_8_bpp }} & {{8{vram_src_mask_shift[8] }},
                                                               {8{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;

wire [15:0] vram_src_mask_fill_nxt = ({16{gfx_mode_1_bpp }} &  16'h0001) |
                                     ({16{gfx_mode_2_bpp }} &  16'h0003) |
                                     ({16{gfx_mode_4_bpp }} &  16'h000f) |
                                     ({16{gfx_mode_8_bpp }} &  16'h00ff) |
                                     ({16{gfx_mode_16_bpp}} &  16'hffff) ;

wire [15:0] vram_src_mask_nxt      = exec_fill_i ? vram_src_mask_fill_nxt :
                                                   vram_src_mask_vram_nxt ;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                               vram_src_mask <=  16'h0000;
  else if (trig_exec_i | vram_src_addr_inc)  vram_src_mask <=  vram_src_mask_nxt;






reg  [`APIX_MSB:0] vram_dst_addr;
wire [`APIX_MSB:0] vram_dst_addr_calc;

wire               vram_dst_addr_inc  = dma_pixel_done;
wire [`APIX_MSB:0] vram_dst_addr_nxt  = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                              vram_dst_addr <=  {`APIX_MSB+1{1'b0}};
  else if (trig_exec_i | vram_dst_addr_inc) vram_dst_addr <=  vram_dst_addr_nxt;



ogfx_gpu_dma_addr ogfx_gpu_dma_dst_addr_inst (


    .vid_ram_addr_nxt_o      ( vram_dst_addr_calc      ),


    .mclk                    ( mclk                    ),
    .puc_rst                 ( puc_rst                 ),
    .display_width_i         ( display_width_i         ),
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),
    .vid_ram_addr_i          ( vram_dst_addr           ),
    .vid_ram_addr_init_i     ( dma_init                ),
    .vid_ram_addr_step_i     ( vram_dst_addr_inc       ),
    .vid_ram_width_i         ( cfg_rec_width_i         ),
    .vid_ram_win_x_swap_i    ( cfg_dst_x_swp_i         ),
    .vid_ram_win_y_swap_i    ( cfg_dst_y_swp_i         ),
    .vid_ram_win_cl_swap_i   ( cfg_dst_cl_swp_i        )
);





reg  [15:0] vram_dst_mask;
wire [15:0] vram_dst_mask_shift = one_hot16(vram_dst_addr_nxt[3:0]);
wire [15:0] vram_dst_mask_nxt   = ({16{gfx_mode_1_bpp }} &     vram_dst_mask_shift       ) |
                                  ({16{gfx_mode_2_bpp }} & {{2{vram_dst_mask_shift[14]}},
                                                            {2{vram_dst_mask_shift[12]}},
                                                            {2{vram_dst_mask_shift[10]}},
                                                            {2{vram_dst_mask_shift[8] }},
                                                            {2{vram_dst_mask_shift[6] }},
                                                            {2{vram_dst_mask_shift[4] }},
                                                            {2{vram_dst_mask_shift[2] }},
                                                            {2{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_4_bpp }} & {{4{vram_dst_mask_shift[12]}},
                                                            {4{vram_dst_mask_shift[8] }},
                                                            {4{vram_dst_mask_shift[4] }},
                                                            {4{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_8_bpp }} & {{8{vram_dst_mask_shift[8] }},
                                                            {8{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                               vram_dst_mask <=  16'h0000;
  else if (trig_exec_i | vram_dst_addr_inc)  vram_dst_mask <=  vram_dst_mask_nxt;











wire [15:0] src_data_mask        = ((exec_fill_i ? cfg_fill_color_i : vid_ram_dout_i) & vram_src_mask);
wire        src_data_mask_1_bpp  =  (|src_data_mask);
wire  [1:0] src_data_mask_2_bpp  = {(|{src_data_mask[15], src_data_mask[13], src_data_mask[11], src_data_mask[9], src_data_mask[7], src_data_mask[5], src_data_mask[3], src_data_mask[1]}),
                                    (|{src_data_mask[14], src_data_mask[12], src_data_mask[10], src_data_mask[8], src_data_mask[6], src_data_mask[4], src_data_mask[2], src_data_mask[0]})};
wire  [3:0] src_data_mask_4_bpp  = {(|{src_data_mask[15], src_data_mask[11], src_data_mask[7] , src_data_mask[3]}),
                                    (|{src_data_mask[14], src_data_mask[10], src_data_mask[6] , src_data_mask[2]}),
                                    (|{src_data_mask[13], src_data_mask[9] , src_data_mask[5] , src_data_mask[1]}),
                                    (|{src_data_mask[12], src_data_mask[8] , src_data_mask[4] , src_data_mask[0]})};
wire  [7:0] src_data_mask_8_bpp  = {(|{src_data_mask[15], src_data_mask[7]}),
                                    (|{src_data_mask[14], src_data_mask[6]}),
                                    (|{src_data_mask[13], src_data_mask[5]}),
                                    (|{src_data_mask[12], src_data_mask[4]}),
                                    (|{src_data_mask[11], src_data_mask[3]}),
                                    (|{src_data_mask[10], src_data_mask[2]}),
                                    (|{src_data_mask[9] , src_data_mask[1]}),
                                    (|{src_data_mask[8] , src_data_mask[0]})};
wire [15:0] src_data_mask_16_bpp =     src_data_mask;

wire [15:0] src_data_align       =  ({16{gfx_mode_1_bpp }} & {16{src_data_mask_1_bpp}}) |
                                    ({16{gfx_mode_2_bpp }} &  {8{src_data_mask_2_bpp}}) |
                                    ({16{gfx_mode_4_bpp }} &  {4{src_data_mask_4_bpp}}) |
                                    ({16{gfx_mode_8_bpp }} &  {2{src_data_mask_8_bpp}}) |
                                    ({16{gfx_mode_16_bpp}} &     src_data_mask_16_bpp ) ;


reg         src_data_ready;
wire        src_data_ready_nxt = ((dma_state==SRC_READ) & data_ready_nxt) | (exec_fill_i & dma_init);
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst) src_data_ready <=  1'b0;
  else         src_data_ready <=  src_data_ready_nxt;


reg  [15:0] src_data_buf;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)              src_data_buf <=  16'h0000;
  else if (src_data_ready)  src_data_buf <=  src_data_align;


wire [15:0] src_data =  src_data_ready ? src_data_align : src_data_buf;






reg         dst_data_ready;
wire        dst_data_ready_nxt = ((dma_state==DST_READ) & data_ready_nxt);
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst) dst_data_ready <=  1'b0;
  else         dst_data_ready <=  dst_data_ready_nxt;


reg  [15:0] dst_data_buf;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)              dst_data_buf <=  16'h0000;
  else if (dst_data_ready)  dst_data_buf <=  vid_ram_dout_i;


wire [15:0] dst_data =  dst_data_ready ? vid_ram_dout_i : dst_data_buf;




wire [15:0] transparent_color_align  = ({16{gfx_mode_1_bpp }} & {16{cfg_transparent_color_i[0]  }}) |
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_transparent_color_i[1:0]}}) |
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_transparent_color_i[3:0]}}) |
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_transparent_color_i[7:0]}}) |
                                       ({16{gfx_mode_16_bpp}} &     cfg_transparent_color_i       ) ;

wire        pixel_is_transparent_nxt = ((exec_copy_trans_i & src_data_ready                                      ) |
                                        (exec_copy_i       & src_data_ready & (pix_op_13 | pix_op_14 | pix_op_15)) |
                                        (exec_fill_i       &                  (pix_op_13 | pix_op_14 | pix_op_15)) ) & (src_data_align==transparent_color_align);
reg         pixel_is_transparent_reg;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                                 pixel_is_transparent_reg <=  1'b0;
  else if (dma_pixel_done | (dma_state==IDLE)) pixel_is_transparent_reg <=  1'b0;
  else if (pixel_is_transparent_nxt)           pixel_is_transparent_reg <=  1'b1;

assign      pixel_is_transparent     = (pixel_is_transparent_nxt | pixel_is_transparent_reg);




wire [15:0] fill_color_align         = ({16{gfx_mode_1_bpp }} & {16{cfg_fill_color_i[0]  }}) |
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_fill_color_i[1:0]}}) |
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_fill_color_i[3:0]}}) |
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_fill_color_i[7:0]}}) |
                                       ({16{gfx_mode_16_bpp}} &     cfg_fill_color_i       ) ;

wire [15:0] pixel_data               = ({16{pix_op_00}} &  ( src_data             )) |
                                       ({16{pix_op_01}} &  (~src_data             )) |
                                       ({16{pix_op_02}} &  (             ~dst_data)) |

                                       ({16{pix_op_03}} &  ( src_data  &  dst_data)) |
                                       ({16{pix_op_04}} &  ( src_data  |  dst_data)) |
                                       ({16{pix_op_05}} &  ( src_data  ^  dst_data)) |

                                       ({16{pix_op_06}} & ~( src_data  &  dst_data)) |
                                       ({16{pix_op_07}} & ~( src_data  |  dst_data)) |
                                       ({16{pix_op_08}} & ~( src_data  ^  dst_data)) |

                                       ({16{pix_op_09}} &  (~src_data  &  dst_data)) |
                                       ({16{pix_op_10}} &  ( src_data  & ~dst_data)) |
                                       ({16{pix_op_11}} &  (~src_data  |  dst_data)) |
                                       ({16{pix_op_12}} &  ( src_data  | ~dst_data)) |

                                       ({16{pix_op_13}} &  ( 16'h0000             )) |
                                       ({16{pix_op_14}} &  ( 16'hffff             )) |
                                       ({16{pix_op_15}} &  ( fill_color_align     )) ;




assign      vid_ram_din_o  =  (pixel_data & vram_dst_mask) | (dst_data & ~vram_dst_mask);

assign      vid_ram_addr_o =  (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] :
                                                      vram_dst_addr[`APIX_MSB:4] ;

assign      vid_ram_wen_o  = ~( (dma_state==DST_WRITE) & ~pixel_is_transparent) ;

assign      vid_ram_cen_o  = ~( (dma_state==SRC_READ)                           |
                               ((dma_state==DST_READ)  & ~pixel_is_transparent) |
                               ((dma_state==DST_WRITE) & ~pixel_is_transparent));


endmodule
module  ogfx_gpu_dma (


    gpu_exec_done_o,
    gpu_dma_busy_o,

    vid_ram_addr_o,
    vid_ram_din_o,
    vid_ram_wen_o,
    vid_ram_cen_o,


    mclk,
    puc_rst,

    cfg_dst_px_addr_i,
    cfg_dst_cl_swp_i,
    cfg_dst_x_swp_i,
    cfg_dst_y_swp_i,
    cfg_fill_color_i,
    cfg_pix_op_sel_i,
    cfg_rec_width_i,
    cfg_rec_height_i,
    cfg_src_px_addr_i,
    cfg_src_cl_swp_i,
    cfg_src_x_swp_i,
    cfg_src_y_swp_i,
    cfg_transparent_color_i,

    display_width_i,

    gfx_mode_i,

    gpu_enable_i,

    exec_fill_i,
    exec_copy_i,
    exec_copy_trans_i,
    trig_exec_i,

    vid_ram_dout_i,
    vid_ram_dout_rdy_nxt_i
);




output                 gpu_exec_done_o;
output                 gpu_dma_busy_o;

output   [`VRAM_MSB:0] vid_ram_addr_o;
output          [15:0] vid_ram_din_o;
output                 vid_ram_wen_o;
output                 vid_ram_cen_o;



input                  mclk;
input                  puc_rst;

input    [`APIX_MSB:0] cfg_dst_px_addr_i;
input                  cfg_dst_cl_swp_i;
input                  cfg_dst_x_swp_i;
input                  cfg_dst_y_swp_i;
input           [15:0] cfg_fill_color_i;
input            [3:0] cfg_pix_op_sel_i;
input    [`LPIX_MSB:0] cfg_rec_width_i;
input    [`LPIX_MSB:0] cfg_rec_height_i;
input    [`APIX_MSB:0] cfg_src_px_addr_i;
input                  cfg_src_cl_swp_i;
input                  cfg_src_x_swp_i;
input                  cfg_src_y_swp_i;
input           [15:0] cfg_transparent_color_i;

input    [`LPIX_MSB:0] display_width_i;

input            [2:0] gfx_mode_i;

input                  gpu_enable_i;

input                  exec_fill_i;
input                  exec_copy_i;
input                  exec_copy_trans_i;
input                  trig_exec_i;

input           [15:0] vid_ram_dout_i;
input                  vid_ram_dout_rdy_nxt_i;







wire       gfx_mode_1_bpp    =  (gfx_mode_i == 3'b000);
wire       gfx_mode_2_bpp    =  (gfx_mode_i == 3'b001);
wire       gfx_mode_4_bpp    =  (gfx_mode_i == 3'b010);
wire       gfx_mode_8_bpp    =  (gfx_mode_i == 3'b011);
wire       gfx_mode_16_bpp   = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp);



wire       pix_op_00         =  (cfg_pix_op_sel_i == 4'b0000);
wire       pix_op_01         =  (cfg_pix_op_sel_i == 4'b0001);
wire       pix_op_02         =  (cfg_pix_op_sel_i == 4'b0010);

wire       pix_op_03         =  (cfg_pix_op_sel_i == 4'b0011);
wire       pix_op_04         =  (cfg_pix_op_sel_i == 4'b0100);
wire       pix_op_05         =  (cfg_pix_op_sel_i == 4'b0101);

wire       pix_op_06         =  (cfg_pix_op_sel_i == 4'b0110);
wire       pix_op_07         =  (cfg_pix_op_sel_i == 4'b0111);
wire       pix_op_08         =  (cfg_pix_op_sel_i == 4'b1000);

wire       pix_op_09         =  (cfg_pix_op_sel_i == 4'b1001);
wire       pix_op_10         =  (cfg_pix_op_sel_i == 4'b1010);
wire       pix_op_11         =  (cfg_pix_op_sel_i == 4'b1011);
wire       pix_op_12         =  (cfg_pix_op_sel_i == 4'b1100);

wire       pix_op_13         =  (cfg_pix_op_sel_i == 4'b1101);
wire       pix_op_14         =  (cfg_pix_op_sel_i == 4'b1110);
wire       pix_op_15         =  (cfg_pix_op_sel_i == 4'b1111);

wire       dma_done;
wire       pixel_is_transparent;


function [15:0] one_hot16;
   input  [3:0] binary;
   begin
      one_hot16         = 16'h0000;
      one_hot16[binary] =  1'b1;
   end
endfunction







parameter  IDLE           = 3'h0;
parameter  INIT           = 3'h1;
parameter  SKIP           = 3'h2;
parameter  SRC_READ       = 3'h3;
parameter  DST_READ       = 3'h4;
parameter  DST_WRITE      = 3'h5;


reg  [2:0] dma_state;
reg  [2:0] dma_state_nxt;


wire       needs_src_read    = (exec_copy_i & ~pix_op_02) | exec_copy_trans_i;
wire       needs_dst_read    = (exec_fill_i | exec_copy_trans_i | exec_copy_i) & (~(pix_op_00 | pix_op_01 | pix_op_13 | pix_op_14 | pix_op_15) | ~gfx_mode_16_bpp);
wire       needs_dst_write   = (exec_fill_i | exec_copy_trans_i | exec_copy_i) &  ~pixel_is_transparent;

wire       data_ready_nxt    =   (dma_state==SRC_READ) |
                               (((dma_state==DST_READ) |
                                 (dma_state==DST_WRITE)) & ~pixel_is_transparent) ? vid_ram_dout_rdy_nxt_i : 1'b1;


always @(dma_state or trig_exec_i or needs_src_read or needs_dst_read or data_ready_nxt or dma_done or needs_dst_write)
  case (dma_state)
    IDLE           : dma_state_nxt = ~trig_exec_i       ?  IDLE	     :	INIT      ;

    INIT	   : dma_state_nxt =  needs_src_read	?  SRC_READ  :
				      needs_dst_read	?  DST_READ  :
				      needs_dst_write   ?  DST_WRITE :  SKIP      ;

    SKIP           : dma_state_nxt =  dma_done          ?  IDLE      :  SKIP      ;

    SRC_READ       : dma_state_nxt = ~data_ready_nxt    ?  SRC_READ  :
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;

    DST_READ       : dma_state_nxt = ~data_ready_nxt    ?  DST_READ  :
                                      needs_dst_write   ?  DST_WRITE :
                                      dma_done          ?  IDLE      :  SRC_READ  ;

    DST_WRITE      : dma_state_nxt = ~data_ready_nxt    ?  DST_WRITE :
                                      dma_done          ?  IDLE      :
                                      needs_src_read    ?  SRC_READ  :
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;

    default        : dma_state_nxt =  IDLE;

  endcase


always @(posedge mclk or posedge puc_rst)
  if (puc_rst)            dma_state <= IDLE;
  else if (~gpu_enable_i) dma_state <= IDLE;
  else                    dma_state <= dma_state_nxt;



wire   dma_init        = (dma_state==INIT);
wire   dma_pixel_done  = (dma_state==SKIP) | ((dma_state==DST_READ)  & pixel_is_transparent) |
                                             ((dma_state==DST_WRITE) & data_ready_nxt      ) ;
assign gpu_exec_done_o = (dma_state==IDLE) & ~trig_exec_i;
assign gpu_dma_busy_o  = (dma_state!=IDLE);





reg [`LPIX_MSB:0] height_cnt;
wire              height_cnt_done;
reg [`LPIX_MSB:0] width_cnt;
wire              width_cnt_done;


wire              height_cnt_init = dma_init;
wire              height_cnt_dec  = dma_pixel_done & width_cnt_done & ~height_cnt_done;

always @(posedge mclk or posedge puc_rst)
  if (puc_rst)              height_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
  else if (height_cnt_init) height_cnt <= cfg_rec_height_i;
  else if (height_cnt_dec)  height_cnt <= height_cnt-{{`LPIX_MSB{1'h0}},1'b1};

assign                      height_cnt_done = (height_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});


wire              width_cnt_init = dma_init | height_cnt_dec;
wire              width_cnt_dec  = dma_pixel_done & ~width_cnt_done;

always @(posedge mclk or posedge puc_rst)
  if (puc_rst)              width_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
  else if (width_cnt_init)  width_cnt <= cfg_rec_width_i;
  else if (width_cnt_dec)   width_cnt <= width_cnt-{{`LPIX_MSB{1'h0}},1'b1};

assign            width_cnt_done = (width_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});


assign            dma_done       = height_cnt_done & width_cnt_done;






reg  [`APIX_MSB:0] vram_src_addr;
wire [`APIX_MSB:0] vram_src_addr_calc;

wire               vram_src_addr_inc  = dma_pixel_done & needs_src_read;
wire [`APIX_MSB:0] vram_src_addr_nxt  = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                              vram_src_addr <=  {`APIX_MSB+1{1'b0}};
  else if (trig_exec_i | vram_src_addr_inc) vram_src_addr <=  vram_src_addr_nxt;



ogfx_gpu_dma_addr ogfx_gpu_dma_src_addr_inst (


    .vid_ram_addr_nxt_o      ( vram_src_addr_calc      ),


    .mclk                    ( mclk                    ),
    .puc_rst                 ( puc_rst                 ),
    .display_width_i         ( display_width_i         ),
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),
    .vid_ram_addr_i          ( vram_src_addr           ),
    .vid_ram_addr_init_i     ( dma_init                ),
    .vid_ram_addr_step_i     ( vram_src_addr_inc       ),
    .vid_ram_width_i         ( cfg_rec_width_i         ),
    .vid_ram_win_x_swap_i    ( cfg_src_x_swp_i         ),
    .vid_ram_win_y_swap_i    ( cfg_src_y_swp_i         ),
    .vid_ram_win_cl_swap_i   ( cfg_src_cl_swp_i        )
);





reg  [15:0] vram_src_mask;
wire [15:0] vram_src_mask_shift    = one_hot16(vram_src_addr_nxt[3:0]);
wire [15:0] vram_src_mask_vram_nxt = ({16{gfx_mode_1_bpp }} &     vram_src_mask_shift       ) |
                                     ({16{gfx_mode_2_bpp }} & {{2{vram_src_mask_shift[14]}},
                                                               {2{vram_src_mask_shift[12]}},
                                                               {2{vram_src_mask_shift[10]}},
                                                               {2{vram_src_mask_shift[8] }},
                                                               {2{vram_src_mask_shift[6] }},
                                                               {2{vram_src_mask_shift[4] }},
                                                               {2{vram_src_mask_shift[2] }},
                                                               {2{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_4_bpp }} & {{4{vram_src_mask_shift[12]}},
                                                               {4{vram_src_mask_shift[8] }},
                                                               {4{vram_src_mask_shift[4] }},
                                                               {4{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_8_bpp }} & {{8{vram_src_mask_shift[8] }},
                                                               {8{vram_src_mask_shift[0] }}}) |
                                     ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;

wire [15:0] vram_src_mask_fill_nxt = ({16{gfx_mode_1_bpp }} &  16'h0001) |
                                     ({16{gfx_mode_2_bpp }} &  16'h0003) |
                                     ({16{gfx_mode_4_bpp }} &  16'h000f) |
                                     ({16{gfx_mode_8_bpp }} &  16'h00ff) |
                                     ({16{gfx_mode_16_bpp}} &  16'hffff) ;

wire [15:0] vram_src_mask_nxt      = exec_fill_i ? vram_src_mask_fill_nxt :
                                                   vram_src_mask_vram_nxt ;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                               vram_src_mask <=  16'h0000;
  else if (trig_exec_i | vram_src_addr_inc)  vram_src_mask <=  vram_src_mask_nxt;






reg  [`APIX_MSB:0] vram_dst_addr;
wire [`APIX_MSB:0] vram_dst_addr_calc;

wire               vram_dst_addr_inc  = dma_pixel_done;
wire [`APIX_MSB:0] vram_dst_addr_nxt  = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                              vram_dst_addr <=  {`APIX_MSB+1{1'b0}};
  else if (trig_exec_i | vram_dst_addr_inc) vram_dst_addr <=  vram_dst_addr_nxt;



ogfx_gpu_dma_addr ogfx_gpu_dma_dst_addr_inst (


    .vid_ram_addr_nxt_o      ( vram_dst_addr_calc      ),


    .mclk                    ( mclk                    ),
    .puc_rst                 ( puc_rst                 ),
    .display_width_i         ( display_width_i         ),
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),
    .vid_ram_addr_i          ( vram_dst_addr           ),
    .vid_ram_addr_init_i     ( dma_init                ),
    .vid_ram_addr_step_i     ( vram_dst_addr_inc       ),
    .vid_ram_width_i         ( cfg_rec_width_i         ),
    .vid_ram_win_x_swap_i    ( cfg_dst_x_swp_i         ),
    .vid_ram_win_y_swap_i    ( cfg_dst_y_swp_i         ),
    .vid_ram_win_cl_swap_i   ( cfg_dst_cl_swp_i        )
);





reg  [15:0] vram_dst_mask;
wire [15:0] vram_dst_mask_shift = one_hot16(vram_dst_addr_nxt[3:0]);
wire [15:0] vram_dst_mask_nxt   = ({16{gfx_mode_1_bpp }} &     vram_dst_mask_shift       ) |
                                  ({16{gfx_mode_2_bpp }} & {{2{vram_dst_mask_shift[14]}},
                                                            {2{vram_dst_mask_shift[12]}},
                                                            {2{vram_dst_mask_shift[10]}},
                                                            {2{vram_dst_mask_shift[8] }},
                                                            {2{vram_dst_mask_shift[6] }},
                                                            {2{vram_dst_mask_shift[4] }},
                                                            {2{vram_dst_mask_shift[2] }},
                                                            {2{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_4_bpp }} & {{4{vram_dst_mask_shift[12]}},
                                                            {4{vram_dst_mask_shift[8] }},
                                                            {4{vram_dst_mask_shift[4] }},
                                                            {4{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_8_bpp }} & {{8{vram_dst_mask_shift[8] }},
                                                            {8{vram_dst_mask_shift[0] }}}) |
                                  ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;

always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                               vram_dst_mask <=  16'h0000;
  else if (trig_exec_i | vram_dst_addr_inc)  vram_dst_mask <=  vram_dst_mask_nxt;











wire [15:0] src_data_mask        = ((exec_fill_i ? cfg_fill_color_i : vid_ram_dout_i) & vram_src_mask);
wire        src_data_mask_1_bpp  =  (|src_data_mask);
wire  [1:0] src_data_mask_2_bpp  = {(|{src_data_mask[15], src_data_mask[13], src_data_mask[11], src_data_mask[9], src_data_mask[7], src_data_mask[5], src_data_mask[3], src_data_mask[1]}),
                                    (|{src_data_mask[14], src_data_mask[12], src_data_mask[10], src_data_mask[8], src_data_mask[6], src_data_mask[4], src_data_mask[2], src_data_mask[0]})};
wire  [3:0] src_data_mask_4_bpp  = {(|{src_data_mask[15], src_data_mask[11], src_data_mask[7] , src_data_mask[3]}),
                                    (|{src_data_mask[14], src_data_mask[10], src_data_mask[6] , src_data_mask[2]}),
                                    (|{src_data_mask[13], src_data_mask[9] , src_data_mask[5] , src_data_mask[1]}),
                                    (|{src_data_mask[12], src_data_mask[8] , src_data_mask[4] , src_data_mask[0]})};
wire  [7:0] src_data_mask_8_bpp  = {(|{src_data_mask[15], src_data_mask[7]}),
                                    (|{src_data_mask[14], src_data_mask[6]}),
                                    (|{src_data_mask[13], src_data_mask[5]}),
                                    (|{src_data_mask[12], src_data_mask[4]}),
                                    (|{src_data_mask[11], src_data_mask[3]}),
                                    (|{src_data_mask[10], src_data_mask[2]}),
                                    (|{src_data_mask[9] , src_data_mask[1]}),
                                    (|{src_data_mask[8] , src_data_mask[0]})};
wire [15:0] src_data_mask_16_bpp =     src_data_mask;

wire [15:0] src_data_align       =  ({16{gfx_mode_1_bpp }} & {16{src_data_mask_1_bpp}}) |
                                    ({16{gfx_mode_2_bpp }} &  {8{src_data_mask_2_bpp}}) |
                                    ({16{gfx_mode_4_bpp }} &  {4{src_data_mask_4_bpp}}) |
                                    ({16{gfx_mode_8_bpp }} &  {2{src_data_mask_8_bpp}}) |
                                    ({16{gfx_mode_16_bpp}} &     src_data_mask_16_bpp ) ;


reg         src_data_ready;
wire        src_data_ready_nxt = ((dma_state==SRC_READ) & data_ready_nxt) | (exec_fill_i & dma_init);
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst) src_data_ready <=  1'b0;
  else         src_data_ready <=  src_data_ready_nxt;


reg  [15:0] src_data_buf;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)              src_data_buf <=  16'h0000;
  else if (src_data_ready)  src_data_buf <=  src_data_align;


wire [15:0] src_data =  src_data_ready ? src_data_align : src_data_buf;






reg         dst_data_ready;
wire        dst_data_ready_nxt = ((dma_state==DST_READ) & data_ready_nxt);
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst) dst_data_ready <=  1'b0;
  else         dst_data_ready <=  dst_data_ready_nxt;


reg  [15:0] dst_data_buf;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)              dst_data_buf <=  16'h0000;
  else if (dst_data_ready)  dst_data_buf <=  vid_ram_dout_i;


wire [15:0] dst_data =  dst_data_ready ? vid_ram_dout_i : dst_data_buf;




wire [15:0] transparent_color_align  = ({16{gfx_mode_1_bpp }} & {16{cfg_transparent_color_i[0]  }}) |
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_transparent_color_i[1:0]}}) |
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_transparent_color_i[3:0]}}) |
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_transparent_color_i[7:0]}}) |
                                       ({16{gfx_mode_16_bpp}} &     cfg_transparent_color_i       ) ;

wire        pixel_is_transparent_nxt = ((exec_copy_trans_i & src_data_ready                                      ) |
                                        (exec_copy_i       & src_data_ready & (pix_op_13 | pix_op_14 | pix_op_15)) |
                                        (exec_fill_i       &                  (pix_op_13 | pix_op_14 | pix_op_15)) ) & (src_data_align==transparent_color_align);
reg         pixel_is_transparent_reg;
always @ (posedge mclk or posedge puc_rst)
  if (puc_rst)                                 pixel_is_transparent_reg <=  1'b0;
  else if (dma_pixel_done | (dma_state==IDLE)) pixel_is_transparent_reg <=  1'b0;
  else if (pixel_is_transparent_nxt)           pixel_is_transparent_reg <=  1'b1;

assign      pixel_is_transparent     = (pixel_is_transparent_nxt | pixel_is_transparent_reg);




wire [15:0] fill_color_align         = ({16{gfx_mode_1_bpp }} & {16{cfg_fill_color_i[0]  }}) |
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_fill_color_i[1:0]}}) |
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_fill_color_i[3:0]}}) |
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_fill_color_i[7:0]}}) |
                                       ({16{gfx_mode_16_bpp}} &     cfg_fill_color_i       ) ;

wire [15:0] pixel_data               = ({16{pix_op_00}} &  ( src_data             )) |
                                       ({16{pix_op_01}} &  (~src_data             )) |
                                       ({16{pix_op_02}} &  (             ~dst_data)) |

                                       ({16{pix_op_03}} &  ( src_data  &  dst_data)) |
                                       ({16{pix_op_04}} &  ( src_data  |  dst_data)) |
                                       ({16{pix_op_05}} &  ( src_data  ^  dst_data)) |

                                       ({16{pix_op_06}} & ~( src_data  &  dst_data)) |
                                       ({16{pix_op_07}} & ~( src_data  |  dst_data)) |
                                       ({16{pix_op_08}} & ~( src_data  ^  dst_data)) |

                                       ({16{pix_op_09}} &  (~src_data  &  dst_data)) |
                                       ({16{pix_op_10}} &  ( src_data  & ~dst_data)) |
                                       ({16{pix_op_11}} &  (~src_data  |  dst_data)) |
                                       ({16{pix_op_12}} &  ( src_data  | ~dst_data)) |

                                       ({16{pix_op_13}} &  ( 16'h0000             )) |
                                       ({16{pix_op_14}} &  ( 16'hffff             )) |
                                       ({16{pix_op_15}} &  ( fill_color_align     )) ;




assign      vid_ram_din_o  =  (pixel_data & vram_dst_mask) | (dst_data & ~vram_dst_mask);

assign      vid_ram_addr_o =  (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] :
                                                      vram_dst_addr[`APIX_MSB:4] ;

assign      vid_ram_wen_o  = ~( (dma_state==DST_WRITE) & ~pixel_is_transparent) ;

assign      vid_ram_cen_o  = ~( (dma_state==SRC_READ)                           |
                               ((dma_state==DST_READ)  & ~pixel_is_transparent) |
                               ((dma_state==DST_WRITE) & ~pixel_is_transparent));


endmodule