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

Subversion Repositories opengfx430

[/] [opengfx430/] [trunk/] [core/] [rtl/] [verilog/] [ogfx_gpu_dma.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2015 Authors
3
//
4
// This source file may be used and distributed without restriction provided
5
// that this copyright statement is not removed from the file and that any
6
// derivative work contains the original copyright notice and the associated
7
// disclaimer.
8
//
9
// This source file is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation; either version 2.1 of the License, or
12
// (at your option) any later version.
13
//
14
// This source is distributed in the hope that it will be useful, but WITHOUT
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
// License for more details.
18
//
19
// You should have received a copy of the GNU Lesser General Public License
20
// along with this source; if not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
//
23
//----------------------------------------------------------------------------
24
//
25
// *File Name: ogfx_gpu_dma.v
26
//
27
// *Module Description:
28
//                      Graphic-Processing unit 2D-DMA.
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34
// $Rev$
35
// $LastChangedBy$
36
// $LastChangedDate$
37
//----------------------------------------------------------------------------
38
`ifdef OGFX_NO_INCLUDE
39
`else
40
`include "openGFX430_defines.v"
41
`endif
42
 
43
module  ogfx_gpu_dma (
44
 
45
// OUTPUTs
46
    gpu_exec_done_o,                              // GPU execution done
47 6 olivier.gi
    gpu_dma_busy_o,                               // GPU DMA execution on going
48 3 olivier.gi
 
49
    vid_ram_addr_o,                               // Video-RAM address
50
    vid_ram_din_o,                                // Video-RAM data
51
    vid_ram_wen_o,                                // Video-RAM write strobe (active low)
52
    vid_ram_cen_o,                                // Video-RAM chip enable (active low)
53
 
54
// INPUTs
55
    mclk,                                         // Main system clock
56
    puc_rst,                                      // Main system reset
57
 
58
    cfg_dst_px_addr_i,                            // Destination pixel address configuration
59
    cfg_dst_cl_swp_i,                             // Destination Column/Line-Swap configuration
60
    cfg_dst_x_swp_i,                              // Destination X-Swap configuration
61
    cfg_dst_y_swp_i,                              // Destination Y-Swap configuration
62
    cfg_fill_color_i,                             // Fill color (for rectangle fill operation)
63
    cfg_pix_op_sel_i,                             // Pixel operation to be performed during the copy
64
    cfg_rec_width_i,                              // Rectangle width configuration
65
    cfg_rec_height_i,                             // Rectangle height configuration
66
    cfg_src_px_addr_i,                            // Source pixel address configuration
67
    cfg_src_cl_swp_i,                             // Source Column/Line-Swap configuration
68
    cfg_src_x_swp_i,                              // Source X-Swap configuration
69
    cfg_src_y_swp_i,                              // Source Y-Swap configuration
70
    cfg_transparent_color_i,                      // Transparent color (for rectangle transparent copy operation)
71
 
72
    display_width_i,                              // Display width
73
 
74
    gfx_mode_i,                                   // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp)
75
 
76
    gpu_enable_i,                                 // GPU enable
77
 
78
    exec_fill_i,                                  // Rectangle fill on going
79
    exec_copy_i,                                  // Rectangle copy on going
80
    exec_copy_trans_i,                            // Rectangle transparent copy on going
81
    trig_exec_i,                                  // Trigger rectangle execution
82
 
83
    vid_ram_dout_i,                               // Video-RAM data input
84
    vid_ram_dout_rdy_nxt_i                        // Video-RAM data output ready during next cycle
85
);
86
 
87
// OUTPUTs
88
//=========
89
output                 gpu_exec_done_o;           // GPU execution done
90 6 olivier.gi
output                 gpu_dma_busy_o;            // GPU DMA execution on going
91 3 olivier.gi
 
92
output   [`VRAM_MSB:0] vid_ram_addr_o;            // Video-RAM address
93
output          [15:0] vid_ram_din_o;             // Video-RAM data
94
output                 vid_ram_wen_o;             // Video-RAM write strobe (active low)
95
output                 vid_ram_cen_o;             // Video-RAM chip enable (active low)
96
 
97
// INPUTs
98
//=========
99
input                  mclk;                      // Main system clock
100
input                  puc_rst;                   // Main system reset
101
 
102
input    [`APIX_MSB:0] cfg_dst_px_addr_i;         // Destination pixel address configuration
103
input                  cfg_dst_cl_swp_i;          // Destination Column/Line-Swap configuration
104
input                  cfg_dst_x_swp_i;           // Destination X-Swap configuration
105
input                  cfg_dst_y_swp_i;           // Destination Y-Swap configuration
106
input           [15:0] cfg_fill_color_i;          // Fill color (for rectangle fill operation)
107
input            [3:0] cfg_pix_op_sel_i;          // Pixel operation to be performed during the copy
108
input    [`LPIX_MSB:0] cfg_rec_width_i;           // Rectangle width configuration
109
input    [`LPIX_MSB:0] cfg_rec_height_i;          // Rectangle height configuration
110
input    [`APIX_MSB:0] cfg_src_px_addr_i;         // Source pixel address configuration
111
input                  cfg_src_cl_swp_i;          // Source Column/Line-Swap configuration
112
input                  cfg_src_x_swp_i;           // Source X-Swap configuration
113
input                  cfg_src_y_swp_i;           // Source Y-Swap configuration
114
input           [15:0] cfg_transparent_color_i;   // Transparent color (for rectangle transparent copy operation)
115
 
116
input    [`LPIX_MSB:0] display_width_i;           // Display width
117
 
118
input            [2:0] gfx_mode_i;                // Video mode (1xx:16bpp / 011:8bpp / 010:4bpp / 001:2bpp / 000:1bpp)
119
 
120
input                  gpu_enable_i;              // GPU enable
121
 
122
input                  exec_fill_i;               // Rectangle fill on going
123
input                  exec_copy_i;               // Rectangle copy on going
124
input                  exec_copy_trans_i;         // Rectangle transparent copy on going
125
input                  trig_exec_i;               // Trigger rectangle execution
126
 
127
input           [15:0] vid_ram_dout_i;            // Video-RAM data input
128
input                  vid_ram_dout_rdy_nxt_i;    // Video-RAM data output ready during next cycle
129
 
130
 
131
//=============================================================================
132
// 1)  WIRE, REGISTERS AND PARAMETER DECLARATION
133
//=============================================================================
134
 
135
// Video modes decoding
136
wire       gfx_mode_1_bpp    =  (gfx_mode_i == 3'b000);
137
wire       gfx_mode_2_bpp    =  (gfx_mode_i == 3'b001);
138
wire       gfx_mode_4_bpp    =  (gfx_mode_i == 3'b010);
139
wire       gfx_mode_8_bpp    =  (gfx_mode_i == 3'b011);
140
wire       gfx_mode_16_bpp   = ~(gfx_mode_8_bpp | gfx_mode_4_bpp | gfx_mode_2_bpp | gfx_mode_1_bpp);
141
 
142
 
143
// Pixel operation decoding
144
wire       pix_op_00         =  (cfg_pix_op_sel_i == 4'b0000);  // S
145
wire       pix_op_01         =  (cfg_pix_op_sel_i == 4'b0001);  // not S
146
wire       pix_op_02         =  (cfg_pix_op_sel_i == 4'b0010);  // not D
147
 
148
wire       pix_op_03         =  (cfg_pix_op_sel_i == 4'b0011);  // S and D
149
wire       pix_op_04         =  (cfg_pix_op_sel_i == 4'b0100);  // S or  D
150
wire       pix_op_05         =  (cfg_pix_op_sel_i == 4'b0101);  // S xor D
151
 
152
wire       pix_op_06         =  (cfg_pix_op_sel_i == 4'b0110);  // not (S and D)
153
wire       pix_op_07         =  (cfg_pix_op_sel_i == 4'b0111);  // not (S or  D)
154
wire       pix_op_08         =  (cfg_pix_op_sel_i == 4'b1000);  // not (S xor D)
155
 
156
wire       pix_op_09         =  (cfg_pix_op_sel_i == 4'b1001);  // (not S) and      D
157
wire       pix_op_10         =  (cfg_pix_op_sel_i == 4'b1010);  //      S  and (not D)
158
wire       pix_op_11         =  (cfg_pix_op_sel_i == 4'b1011);  // (not S) or       D
159
wire       pix_op_12         =  (cfg_pix_op_sel_i == 4'b1100);  //      S  or  (not D)
160
 
161
wire       pix_op_13         =  (cfg_pix_op_sel_i == 4'b1101);  // Fill 0            if S not transparent
162
wire       pix_op_14         =  (cfg_pix_op_sel_i == 4'b1110);  // Fill 1            if S not transparent
163
wire       pix_op_15         =  (cfg_pix_op_sel_i == 4'b1111);  // Fill 'fill_color' if S not transparent
164
 
165
wire       dma_done;
166
wire       pixel_is_transparent;
167
 
168
// 16 bits one-hot decoder
169
function [15:0] one_hot16;
170
   input  [3:0] binary;
171
   begin
172
      one_hot16         = 16'h0000;
173
      one_hot16[binary] =  1'b1;
174
   end
175
endfunction
176
 
177
 
178
//=============================================================================
179
// 2)  DMA STATE MACHINE
180
//=============================================================================
181
 
182
// State definition
183
parameter  IDLE           = 3'h0;
184
parameter  INIT           = 3'h1;
185
parameter  SKIP           = 3'h2;
186
parameter  SRC_READ       = 3'h3;
187
parameter  DST_READ       = 3'h4;
188
parameter  DST_WRITE      = 3'h5;
189
 
190
// State machine
191
reg  [2:0] dma_state;
192
reg  [2:0] dma_state_nxt;
193
 
194
// State arcs
195
wire       needs_src_read    = (exec_copy_i & ~pix_op_02) | exec_copy_trans_i;
196
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);
197
wire       needs_dst_write   = (exec_fill_i | exec_copy_trans_i | exec_copy_i) &  ~pixel_is_transparent;
198
 
199
wire       data_ready_nxt    =   (dma_state==SRC_READ) |
200
                               (((dma_state==DST_READ) |
201
                                 (dma_state==DST_WRITE)) & ~pixel_is_transparent) ? vid_ram_dout_rdy_nxt_i : 1'b1;
202
 
203
// State transition
204
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)
205
  case (dma_state)
206
    IDLE           : dma_state_nxt = ~trig_exec_i       ?  IDLE      :  INIT      ;
207
 
208
    INIT           : dma_state_nxt =  needs_src_read    ?  SRC_READ  :
209
                                      needs_dst_read    ?  DST_READ  :
210
                                      needs_dst_write   ?  DST_WRITE :  SKIP      ;
211
 
212
    SKIP           : dma_state_nxt =  dma_done          ?  IDLE      :  SKIP      ;
213
 
214
    SRC_READ       : dma_state_nxt = ~data_ready_nxt    ?  SRC_READ  :
215
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;
216
 
217
    DST_READ       : dma_state_nxt = ~data_ready_nxt    ?  DST_READ  :
218
                                      needs_dst_write   ?  DST_WRITE :
219
                                      dma_done          ?  IDLE      :  SRC_READ  ;
220
 
221
    DST_WRITE      : dma_state_nxt = ~data_ready_nxt    ?  DST_WRITE :
222
                                      dma_done          ?  IDLE      :
223
                                      needs_src_read    ?  SRC_READ  :
224
                                      needs_dst_read    ?  DST_READ  :  DST_WRITE ;
225
  // pragma coverage off
226
    default        : dma_state_nxt =  IDLE;
227
  // pragma coverage on
228
  endcase
229
 
230
// State machine
231
always @(posedge mclk or posedge puc_rst)
232
  if (puc_rst)            dma_state <= IDLE;
233
  else if (~gpu_enable_i) dma_state <= IDLE;
234
  else                    dma_state <= dma_state_nxt;
235
 
236
 
237
// Utility signals
238
wire   dma_init        = (dma_state==INIT);
239
wire   dma_pixel_done  = (dma_state==SKIP) | ((dma_state==DST_READ)  & pixel_is_transparent) |
240
                                             ((dma_state==DST_WRITE) & data_ready_nxt      ) ;
241
assign gpu_exec_done_o = (dma_state==IDLE) & ~trig_exec_i;
242 6 olivier.gi
assign gpu_dma_busy_o  = (dma_state!=IDLE);
243 3 olivier.gi
 
244
 
245
//=============================================================================
246
// 3)  COUNT TRANSFERS
247
//=============================================================================
248
reg [`LPIX_MSB:0] height_cnt;
249
wire              height_cnt_done;
250
reg [`LPIX_MSB:0] width_cnt;
251
wire              width_cnt_done;
252
 
253
// Height Counter
254
wire              height_cnt_init = dma_init;
255
wire              height_cnt_dec  = dma_pixel_done & width_cnt_done & ~height_cnt_done;
256
 
257
always @(posedge mclk or posedge puc_rst)
258
  if (puc_rst)              height_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
259
  else if (height_cnt_init) height_cnt <= cfg_rec_height_i;
260
  else if (height_cnt_dec)  height_cnt <= height_cnt-{{`LPIX_MSB{1'h0}},1'b1};
261
 
262
assign                      height_cnt_done = (height_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});
263
 
264
// Width Counter
265
wire              width_cnt_init = dma_init | height_cnt_dec;
266
wire              width_cnt_dec  = dma_pixel_done & ~width_cnt_done;
267
 
268
always @(posedge mclk or posedge puc_rst)
269
  if (puc_rst)              width_cnt <= {{`LPIX_MSB{1'h0}},1'b1};
270
  else if (width_cnt_init)  width_cnt <= cfg_rec_width_i;
271
  else if (width_cnt_dec)   width_cnt <= width_cnt-{{`LPIX_MSB{1'h0}},1'b1};
272
 
273
assign            width_cnt_done = (width_cnt=={{`LPIX_MSB{1'h0}}, 1'b1});
274
 
275
// DMA Transfer is done when both counters are done
276
assign            dma_done       = height_cnt_done & width_cnt_done;
277
 
278
 
279
//=============================================================================
280
// 4)  SOURCE ADDRESS GENERATION
281
//=============================================================================
282
 
283
reg  [`APIX_MSB:0] vram_src_addr;
284
wire [`APIX_MSB:0] vram_src_addr_calc;
285
 
286
wire               vram_src_addr_inc  = dma_pixel_done & needs_src_read;
287
wire [`APIX_MSB:0] vram_src_addr_nxt  = trig_exec_i ? cfg_src_px_addr_i : vram_src_addr_calc;
288
 
289
always @ (posedge mclk or posedge puc_rst)
290
  if (puc_rst)                              vram_src_addr <=  {`APIX_MSB+1{1'b0}};
291
  else if (trig_exec_i | vram_src_addr_inc) vram_src_addr <=  vram_src_addr_nxt;
292
 
293
 
294
// Compute the next address
295
ogfx_gpu_dma_addr ogfx_gpu_dma_src_addr_inst (
296
 
297
// OUTPUTs
298
    .vid_ram_addr_nxt_o      ( vram_src_addr_calc      ),   // Next Video-RAM address
299
 
300
// INPUTs
301
    .mclk                    ( mclk                    ),   // Main system clock
302
    .puc_rst                 ( puc_rst                 ),   // Main system reset
303
    .display_width_i         ( display_width_i         ),   // Display width
304
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),   // Graphic mode  1 bpp resolution
305
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),   // Graphic mode  2 bpp resolution
306
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),   // Graphic mode  4 bpp resolution
307
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),   // Graphic mode  8 bpp resolution
308
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),   // Graphic mode 16 bpp resolution
309
    .vid_ram_addr_i          ( vram_src_addr           ),   // Video-RAM address
310
    .vid_ram_addr_init_i     ( dma_init                ),   // Video-RAM address initialization
311
    .vid_ram_addr_step_i     ( vram_src_addr_inc       ),   // Video-RAM address step
312
    .vid_ram_width_i         ( cfg_rec_width_i         ),   // Video-RAM width
313
    .vid_ram_win_x_swap_i    ( cfg_src_x_swp_i         ),   // Video-RAM X-Swap configuration
314
    .vid_ram_win_y_swap_i    ( cfg_src_y_swp_i         ),   // Video-RAM Y-Swap configuration
315
    .vid_ram_win_cl_swap_i   ( cfg_src_cl_swp_i        )    // Video-RAM CL-Swap configuration
316
);
317
 
318
//=============================================================================
319
// 5)  SOURCE DATA MASK
320
//=============================================================================
321
 
322
reg  [15:0] vram_src_mask;
323
wire [15:0] vram_src_mask_shift    = one_hot16(vram_src_addr_nxt[3:0]);
324
wire [15:0] vram_src_mask_vram_nxt = ({16{gfx_mode_1_bpp }} &     vram_src_mask_shift       ) |
325
                                     ({16{gfx_mode_2_bpp }} & {{2{vram_src_mask_shift[14]}},
326
                                                               {2{vram_src_mask_shift[12]}},
327
                                                               {2{vram_src_mask_shift[10]}},
328
                                                               {2{vram_src_mask_shift[8] }},
329
                                                               {2{vram_src_mask_shift[6] }},
330
                                                               {2{vram_src_mask_shift[4] }},
331
                                                               {2{vram_src_mask_shift[2] }},
332
                                                               {2{vram_src_mask_shift[0] }}}) |
333
                                     ({16{gfx_mode_4_bpp }} & {{4{vram_src_mask_shift[12]}},
334
                                                               {4{vram_src_mask_shift[8] }},
335
                                                               {4{vram_src_mask_shift[4] }},
336
                                                               {4{vram_src_mask_shift[0] }}}) |
337
                                     ({16{gfx_mode_8_bpp }} & {{8{vram_src_mask_shift[8] }},
338
                                                               {8{vram_src_mask_shift[0] }}}) |
339
                                     ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;
340
 
341
wire [15:0] vram_src_mask_fill_nxt = ({16{gfx_mode_1_bpp }} &  16'h0001) |
342
                                     ({16{gfx_mode_2_bpp }} &  16'h0003) |
343
                                     ({16{gfx_mode_4_bpp }} &  16'h000f) |
344
                                     ({16{gfx_mode_8_bpp }} &  16'h00ff) |
345
                                     ({16{gfx_mode_16_bpp}} &  16'hffff) ;
346
 
347
wire [15:0] vram_src_mask_nxt      = exec_fill_i ? vram_src_mask_fill_nxt :
348
                                                   vram_src_mask_vram_nxt ;
349
 
350
always @ (posedge mclk or posedge puc_rst)
351
  if (puc_rst)                               vram_src_mask <=  16'h0000;
352
  else if (trig_exec_i | vram_src_addr_inc)  vram_src_mask <=  vram_src_mask_nxt;
353
 
354
 
355
//=============================================================================
356
// 6)  DESTINATION ADDRESS GENERATION
357
//=============================================================================
358
 
359
reg  [`APIX_MSB:0] vram_dst_addr;
360
wire [`APIX_MSB:0] vram_dst_addr_calc;
361
 
362
wire               vram_dst_addr_inc  = dma_pixel_done;
363
wire [`APIX_MSB:0] vram_dst_addr_nxt  = trig_exec_i ? cfg_dst_px_addr_i : vram_dst_addr_calc;
364
 
365
always @ (posedge mclk or posedge puc_rst)
366
  if (puc_rst)                              vram_dst_addr <=  {`APIX_MSB+1{1'b0}};
367
  else if (trig_exec_i | vram_dst_addr_inc) vram_dst_addr <=  vram_dst_addr_nxt;
368
 
369
 
370
// Compute the next address
371
ogfx_gpu_dma_addr ogfx_gpu_dma_dst_addr_inst (
372
 
373
// OUTPUTs
374
    .vid_ram_addr_nxt_o      ( vram_dst_addr_calc      ),   // Next Video-RAM address
375
 
376
// INPUTs
377
    .mclk                    ( mclk                    ),   // Main system clock
378
    .puc_rst                 ( puc_rst                 ),   // Main system reset
379
    .display_width_i         ( display_width_i         ),   // Display width
380
    .gfx_mode_1_bpp_i        ( gfx_mode_1_bpp          ),   // Graphic mode  1 bpp resolution
381
    .gfx_mode_2_bpp_i        ( gfx_mode_2_bpp          ),   // Graphic mode  2 bpp resolution
382
    .gfx_mode_4_bpp_i        ( gfx_mode_4_bpp          ),   // Graphic mode  4 bpp resolution
383
    .gfx_mode_8_bpp_i        ( gfx_mode_8_bpp          ),   // Graphic mode  8 bpp resolution
384
    .gfx_mode_16_bpp_i       ( gfx_mode_16_bpp         ),   // Graphic mode 16 bpp resolution
385
    .vid_ram_addr_i          ( vram_dst_addr           ),   // Video-RAM address
386
    .vid_ram_addr_init_i     ( dma_init                ),   // Video-RAM address initialization
387
    .vid_ram_addr_step_i     ( vram_dst_addr_inc       ),   // Video-RAM address step
388
    .vid_ram_width_i         ( cfg_rec_width_i         ),   // Video-RAM width
389
    .vid_ram_win_x_swap_i    ( cfg_dst_x_swp_i         ),   // Video-RAM X-Swap configuration
390
    .vid_ram_win_y_swap_i    ( cfg_dst_y_swp_i         ),   // Video-RAM Y-Swap configuration
391
    .vid_ram_win_cl_swap_i   ( cfg_dst_cl_swp_i        )    // Video-RAM CL-Swap configuration
392
);
393
 
394
//=============================================================================
395
// 7)  DESTINATION DATA MASK
396
//=============================================================================
397
 
398
reg  [15:0] vram_dst_mask;
399
wire [15:0] vram_dst_mask_shift = one_hot16(vram_dst_addr_nxt[3:0]);
400
wire [15:0] vram_dst_mask_nxt   = ({16{gfx_mode_1_bpp }} &     vram_dst_mask_shift       ) |
401
                                  ({16{gfx_mode_2_bpp }} & {{2{vram_dst_mask_shift[14]}},
402
                                                            {2{vram_dst_mask_shift[12]}},
403
                                                            {2{vram_dst_mask_shift[10]}},
404
                                                            {2{vram_dst_mask_shift[8] }},
405
                                                            {2{vram_dst_mask_shift[6] }},
406
                                                            {2{vram_dst_mask_shift[4] }},
407
                                                            {2{vram_dst_mask_shift[2] }},
408
                                                            {2{vram_dst_mask_shift[0] }}}) |
409
                                  ({16{gfx_mode_4_bpp }} & {{4{vram_dst_mask_shift[12]}},
410
                                                            {4{vram_dst_mask_shift[8] }},
411
                                                            {4{vram_dst_mask_shift[4] }},
412
                                                            {4{vram_dst_mask_shift[0] }}}) |
413
                                  ({16{gfx_mode_8_bpp }} & {{8{vram_dst_mask_shift[8] }},
414
                                                            {8{vram_dst_mask_shift[0] }}}) |
415
                                  ({16{gfx_mode_16_bpp}} & {16{1'b1}}                    ) ;
416
 
417
always @ (posedge mclk or posedge puc_rst)
418
  if (puc_rst)                               vram_dst_mask <=  16'h0000;
419
  else if (trig_exec_i | vram_dst_addr_inc)  vram_dst_mask <=  vram_dst_mask_nxt;
420
 
421
 
422
//=============================================================================
423
// 8)  VIDEO-MEMORY INTERFACE
424
//=============================================================================
425
 
426
//--------------------------
427
// Source data
428
//--------------------------
429
 
430
// Align source data to destination for lower resolution
431
wire [15:0] src_data_mask        = ((exec_fill_i ? cfg_fill_color_i : vid_ram_dout_i) & vram_src_mask);
432
wire        src_data_mask_1_bpp  =  (|src_data_mask);
433
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]}),
434
                                    (|{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]})};
435
wire  [3:0] src_data_mask_4_bpp  = {(|{src_data_mask[15], src_data_mask[11], src_data_mask[7] , src_data_mask[3]}),
436
                                    (|{src_data_mask[14], src_data_mask[10], src_data_mask[6] , src_data_mask[2]}),
437
                                    (|{src_data_mask[13], src_data_mask[9] , src_data_mask[5] , src_data_mask[1]}),
438
                                    (|{src_data_mask[12], src_data_mask[8] , src_data_mask[4] , src_data_mask[0]})};
439
wire  [7:0] src_data_mask_8_bpp  = {(|{src_data_mask[15], src_data_mask[7]}),
440
                                    (|{src_data_mask[14], src_data_mask[6]}),
441
                                    (|{src_data_mask[13], src_data_mask[5]}),
442
                                    (|{src_data_mask[12], src_data_mask[4]}),
443
                                    (|{src_data_mask[11], src_data_mask[3]}),
444
                                    (|{src_data_mask[10], src_data_mask[2]}),
445
                                    (|{src_data_mask[9] , src_data_mask[1]}),
446
                                    (|{src_data_mask[8] , src_data_mask[0]})};
447
wire [15:0] src_data_mask_16_bpp =     src_data_mask;
448
 
449
wire [15:0] src_data_align       =  ({16{gfx_mode_1_bpp }} & {16{src_data_mask_1_bpp}}) |
450
                                    ({16{gfx_mode_2_bpp }} &  {8{src_data_mask_2_bpp}}) |
451
                                    ({16{gfx_mode_4_bpp }} &  {4{src_data_mask_4_bpp}}) |
452
                                    ({16{gfx_mode_8_bpp }} &  {2{src_data_mask_8_bpp}}) |
453
                                    ({16{gfx_mode_16_bpp}} &     src_data_mask_16_bpp ) ;
454
 
455
// Detect read accesses
456
reg         src_data_ready;
457
wire        src_data_ready_nxt = ((dma_state==SRC_READ) & data_ready_nxt) | (exec_fill_i & dma_init);
458
always @ (posedge mclk or posedge puc_rst)
459
  if (puc_rst) src_data_ready <=  1'b0;
460
  else         src_data_ready <=  src_data_ready_nxt;
461
 
462
// Read data buffer
463
reg  [15:0] src_data_buf;
464
always @ (posedge mclk or posedge puc_rst)
465
  if (puc_rst)              src_data_buf <=  16'h0000;
466
  else if (src_data_ready)  src_data_buf <=  src_data_align;
467
 
468
// Source data
469
wire [15:0] src_data =  src_data_ready ? src_data_align : src_data_buf;
470
 
471
//--------------------------
472
// Destination data
473
//--------------------------
474
 
475
// Detect read access
476
reg         dst_data_ready;
477
wire        dst_data_ready_nxt = ((dma_state==DST_READ) & data_ready_nxt);
478
always @ (posedge mclk or posedge puc_rst)
479
  if (puc_rst) dst_data_ready <=  1'b0;
480
  else         dst_data_ready <=  dst_data_ready_nxt;
481
 
482
// Read data buffer
483
reg  [15:0] dst_data_buf;
484
always @ (posedge mclk or posedge puc_rst)
485
  if (puc_rst)              dst_data_buf <=  16'h0000;
486
  else if (dst_data_ready)  dst_data_buf <=  vid_ram_dout_i;
487
 
488
// Source data
489
wire [15:0] dst_data =  dst_data_ready ? vid_ram_dout_i : dst_data_buf;
490
 
491
//--------------------------
492
// Detect transparency
493
//--------------------------
494
wire [15:0] transparent_color_align  = ({16{gfx_mode_1_bpp }} & {16{cfg_transparent_color_i[0]  }}) |
495
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_transparent_color_i[1:0]}}) |
496
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_transparent_color_i[3:0]}}) |
497
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_transparent_color_i[7:0]}}) |
498
                                       ({16{gfx_mode_16_bpp}} &     cfg_transparent_color_i       ) ;
499
 
500
wire        pixel_is_transparent_nxt = ((exec_copy_trans_i & src_data_ready                                      ) |
501
                                        (exec_copy_i       & src_data_ready & (pix_op_13 | pix_op_14 | pix_op_15)) |
502
                                        (exec_fill_i       &                  (pix_op_13 | pix_op_14 | pix_op_15)) ) & (src_data_align==transparent_color_align);
503
reg         pixel_is_transparent_reg;
504
always @ (posedge mclk or posedge puc_rst)
505
  if (puc_rst)                                 pixel_is_transparent_reg <=  1'b0;
506
  else if (dma_pixel_done | (dma_state==IDLE)) pixel_is_transparent_reg <=  1'b0;
507
  else if (pixel_is_transparent_nxt)           pixel_is_transparent_reg <=  1'b1;
508
 
509
assign      pixel_is_transparent     = (pixel_is_transparent_nxt | pixel_is_transparent_reg);
510
 
511
//--------------------------
512
// Pixel operation
513
//--------------------------
514
wire [15:0] fill_color_align         = ({16{gfx_mode_1_bpp }} & {16{cfg_fill_color_i[0]  }}) |
515
                                       ({16{gfx_mode_2_bpp }} &  {8{cfg_fill_color_i[1:0]}}) |
516
                                       ({16{gfx_mode_4_bpp }} &  {4{cfg_fill_color_i[3:0]}}) |
517
                                       ({16{gfx_mode_8_bpp }} &  {2{cfg_fill_color_i[7:0]}}) |
518
                                       ({16{gfx_mode_16_bpp}} &     cfg_fill_color_i       ) ;
519
 
520
wire [15:0] pixel_data               = ({16{pix_op_00}} &  ( src_data             )) |  // S
521
                                       ({16{pix_op_01}} &  (~src_data             )) |  // not S
522
                                       ({16{pix_op_02}} &  (             ~dst_data)) |  // not D
523
 
524
                                       ({16{pix_op_03}} &  ( src_data  &  dst_data)) |  // S and D
525
                                       ({16{pix_op_04}} &  ( src_data  |  dst_data)) |  // S or  D
526
                                       ({16{pix_op_05}} &  ( src_data  ^  dst_data)) |  // S xor D
527
 
528
                                       ({16{pix_op_06}} & ~( src_data  &  dst_data)) |  // not (S and D)
529
                                       ({16{pix_op_07}} & ~( src_data  |  dst_data)) |  // not (S or  D)
530
                                       ({16{pix_op_08}} & ~( src_data  ^  dst_data)) |  // not (S xor D)
531
 
532
                                       ({16{pix_op_09}} &  (~src_data  &  dst_data)) |  // (not S) and      D
533
                                       ({16{pix_op_10}} &  ( src_data  & ~dst_data)) |  //      S  and (not D)
534
                                       ({16{pix_op_11}} &  (~src_data  |  dst_data)) |  // (not S) or       D
535
                                       ({16{pix_op_12}} &  ( src_data  | ~dst_data)) |  //      S  or  (not D)
536
 
537
                                       ({16{pix_op_13}} &  ( 16'h0000             )) |  // Fill 0 if S not transparent
538
                                       ({16{pix_op_14}} &  ( 16'hffff             )) |  // Fill 1 if S not transparent
539
                                       ({16{pix_op_15}} &  ( fill_color_align     )) ;  // Fill 'fill_color' if S not transparent
540
 
541
 
542
 
543
// RAM interface
544
assign      vid_ram_din_o  =  (pixel_data & vram_dst_mask) | (dst_data & ~vram_dst_mask);
545
 
546
assign      vid_ram_addr_o =  (dma_state==SRC_READ) ? vram_src_addr[`APIX_MSB:4] :
547
                                                      vram_dst_addr[`APIX_MSB:4] ;
548
 
549
assign      vid_ram_wen_o  = ~( (dma_state==DST_WRITE) & ~pixel_is_transparent) ;
550
 
551
assign      vid_ram_cen_o  = ~( (dma_state==SRC_READ)                           |
552
                               ((dma_state==DST_READ)  & ~pixel_is_transparent) |
553
                               ((dma_state==DST_WRITE) & ~pixel_is_transparent));
554
 
555
 
556
endmodule // ogfx_gpu_dma
557
 
558
`ifdef OGFX_NO_INCLUDE
559
`else
560
`include "openGFX430_undefines.v"
561
`endif

powered by: WebSVN 2.1.0

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