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 3

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

powered by: WebSVN 2.1.0

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