OpenCores
URL https://opencores.org/ocsvn/395_vgs/395_vgs/trunk

Subversion Repositories 395_vgs

[/] [395_vgs/] [trunk/] [hdl/] [blitter.vhd] - Blame information for rev 26

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 zuofu
--ECE395 GPU:
2
--Blitter Subunit
3
--=====================================================
4
--Designed by:
5
--Zuofu Cheng
6
--James Cavanaugh
7
--Eric Sands
8
--
9
--of the University of Illinois at Urbana Champaign
10
--under the direction of Dr. Lippold Haken
11
--====================================================
12
--
13
--Heavily based off of HDL examples provided by XESS Corporation
14
--www.xess.com
15
--
16
--Based in part on Doug Hodson's work which in turn
17
--was based off of the XSOC from Gray Research LLC.
18
--                                                                              
19
--
20
--release under the GNU General Public License
21
--and kindly hosted by www.opencores.org
22
 
23
library IEEE, UNISIM;
24
use IEEE.std_logic_1164.all;
25
use IEEE.numeric_std.all;
26
use UNISIM.VComponents.all;
27
use WORK.common.all;
28
use WORK.xsasdram.all;
29
use WORK.sdram.all;
30
use WORK.vga_pckg.all;
31
use WORK.fifo_cc_pckg.all;
32
use IEEE.STD_LOGIC_ARITH.ALL;
33
use IEEE.STD_LOGIC_UNSIGNED.ALL;
34
 
35
 
36
package Blitter_pckg is
37
        component Blitter
38
                generic(
39
            FREQ                :     natural := 50_000;  -- operating frequency in KHz
40
            PIPE_EN                     :     boolean := true;  -- enable pipelined operations
41
       DATA_WIDTH          :     natural := 16;  -- host & SDRAM data width
42
            ADDR_WIDTH          :     natural := 23  -- host-side address width
43
          );
44
          port(
45
     clk                   : in  std_logic;  -- master clock
46
     rst                                           : in  std_logic;  -- reset for this entity
47
     rd                    : out std_logic;  -- initiate read operation
48
     wr                    : out std_logic;  -- initiate write operation
49
     opBegun               : in std_logic;   -- read/write/self-refresh op begun (clocked)
50
     earlyopBegun                               : in std_logic;
51
          done                  : in std_logic;   -- read or write operation is done
52
          rddone                                           : in std_logic;   -- read operation is done
53
          rdPending                                : in std_logic;   -- read operation is not done
54
     Addr                  : out  std_logic_vector(ADDR_WIDTH-1 downto 0);  -- address to SDRAM
55
     DIn                   : out  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to dualport to SDRAM
56
     DOut                  : in std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from dualport to SDRAM
57
 
58
          blit_begin                  : in std_logic;
59
          source_address                   : in std_logic_vector(ADDR_WIDTH-1 downto 0);
60
          source_lines                          : in std_logic_vector(15 downto 0);
61
 
62
          target_address                   : in std_logic_vector(ADDR_WIDTH-1 downto 0);
63
          line_size                                     : in std_logic_vector(11 downto 0);
64
          alphaOp                                       : in std_logic;  -- if true then current operation is a blend alphaOp
65
          front_buffer                          : in std_logic;  -- if false, then we are writing to back buffer
66
          blit_done                                     : out std_logic --line has been completely copied
67
          );
68
        end component Blitter;
69
end package Blitter_pckg;
70
 
71
library IEEE, UNISIM;
72
use IEEE.std_logic_1164.all;
73
use IEEE.numeric_std.all;
74
use UNISIM.VComponents.all;
75
use WORK.common.all;
76
use WORK.xsasdram.all;
77
use WORK.sdram.all;
78
use WORK.vga_pckg.all;
79
use WORK.fifo_cc_pckg.all;
80
use IEEE.STD_LOGIC_ARITH.ALL;
81
use IEEE.STD_LOGIC_UNSIGNED.ALL;
82
 
83
---- Uncomment the following library declaration if instantiating
84
---- any Xilinx primitives in this code.
85
--library UNISIM;
86
--use UNISIM.VComponents.all;
87
 
88
entity Blitter is
89
          generic(
90
            FREQ                :     natural := 50_000;  -- operating frequency in KHz
91
            PIPE_EN                     :     boolean := true;  -- enable pipelined operations
92
       DATA_WIDTH          :     natural := 16;  -- host & SDRAM data width
93
            ADDR_WIDTH          :     natural := 23  -- host-side address width
94
          );
95
          port(
96
     clk                   : in  std_logic;  -- master clock
97
     rst                                           : in  std_logic;  -- reset for this entity
98
     rd                    : out  std_logic;  -- initiate read operation
99
     wr                    : out  std_logic;  -- initiate write operation
100
     opBegun               : in std_logic;  -- read/write/self-refresh op begun (clocked)
101
     earlyopBegun                               : in std_logic;
102
          done                  : in std_logic;  -- read or write operation is done
103
          rddone                                           : in std_logic;  -- read operation is done
104
          rdPending                                : in std_logic;      -- read operation is not done
105
     Addr                  : out  std_logic_vector(ADDR_WIDTH-1 downto 0);  -- address to SDRAM
106
     DIn                   : out  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to dualport to SDRAM
107
     DOut                  : in std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from dualport to SDRAM
108
 
109
          blit_begin                  : in std_logic;
110
          source_address                   : in std_logic_vector(ADDR_WIDTH-1 downto 0);
111
          source_lines                          : in std_logic_vector(15 downto 0);
112
 
113
          target_address                   : in std_logic_vector(ADDR_WIDTH-1 downto 0);
114
          line_size                                     : in std_logic_vector(11 downto 0);
115
          alphaOp                                       : in std_logic;  -- if true then current operation is a blend alphaOp
116
          front_buffer                          : in std_logic;  -- if false, then we are writing to back buffer
117
          blit_done                                     : out std_logic --line has been completely copied
118
          );
119
end Blitter;
120
 
121
architecture Behavioral of Blitter is
122
 
123
  -- states of the memory tester state machine
124
  type blitState is (
125
    STANDBY,
126
         INIT1,                              -- init
127
    INIT2,
128
         READ,                               -- load queue with line
129
    EMPTY_PIPE,                         -- empty read pipeline
130
         READ_B,                                                                                 -- read contents of VRAM for blend
131
         EMPTY_PIPE_B,                                                           -- empty read pipeline again
132
         WRITE1,                             -- compare memory contents with pseudo-random data
133
    WRITE2,
134
         STOP                                -- stop and indicate memory status
135
    );
136
  signal state_r, state_x : blitState;  -- state register and next state
137
 
138
  -- registers
139
  signal addr_r, addr_x : unsigned(addr'range);  -- address register
140
 
141
  signal s_addr_r, s_addr_x : std_logic_vector(ADDR_WIDTH - 1 downto 0); --per line start address
142
  signal t_addr_r, t_addr_x : std_logic_vector(ADDR_WIDTH - 1 downto 0); --per line target address
143
 
144
  signal current_line_r, current_line_x : std_logic_vector(15 downto 0);
145
  signal count_r, count_x       : std_logic_vector(11 downto 0);
146
  signal tot_pix_r, tot_pix_x : std_logic_vector(11 downto 0);
147
  signal blend_data_r, blend_data_x : std_logic_vector(15 downto 0);
148
 
149
  -- internal signals
150
  signal rd_q : std_logic;
151
  signal wr_q : std_logic;
152
  signal empty_q : std_logic;
153
  signal reset_q : std_logic;
154
  signal out_q : std_logic_vector(15 downto 0);
155
  signal level_q: std_logic_vector(7 downto 0);
156
 
157
  signal rd_b : std_logic;
158
  signal wr_b : std_logic;
159
  signal empty_b : std_logic;
160
  signal reset_b : std_logic;
161
  signal out_b : std_logic_vector(15 downto 0);
162
  signal level_b: std_logic_vector(7 downto 0);
163
 
164
  signal q_write : std_logic;
165
  signal b_write : std_logic;
166
 
167
begin
168
 
169
        -- fifo buffer
170
        u1 : fifo_cc
171
        port map(
172
                clk=>clk,
173
                rst=>reset_q,
174
                rd=>rd_q,
175
                wr=>wr_q,
176
                data_in=>dOut,
177
                data_out=>out_q,
178
                full=>open,
179
                empty=>empty_q,
180
                level=>level_q
181
        );
182
 
183
        u2 : fifo_cc
184
        port map(
185
                clk=>clk,
186
                rst=>reset_q, --hack
187
                rd=>rd_b,
188
                wr=>wr_b,
189
                data_in=>dOut,
190
                data_out=>out_b,
191
                full=>open,
192
                empty=>empty_b,
193
                level=>level_b
194
        );
195
 
196
  -- connect internal registers to external busses 
197
 
198
  -- memory address bus driven by memory address register     
199
  addr <= std_logic_vector(addr_r);   -- linear memory addressing
200
  wr_q <= rdDone and q_write;  -- whenever something is causing rdDone to go high, we need to queue it
201
  wr_b <= rdDone and b_write;
202
 
203
  --if not doing an AlphaOp, we can directly copy pixel, wire vram input to blend result register
204
  dIn <=  blend_data_r when alphaOp = YES else out_q;
205
 
206
   -- memory test controller state machine operations
207
  combinatorial : process(state_r, addr_r, current_line_r,
208
                                                                  s_addr_r, t_addr_r,
209
                                                                  earlyOpbegun, rdPending,
210
                                                                  source_address, target_address,
211
                                                                  empty_q, source_lines, line_size, count_r,
212
                                                                  alphaOp, level_q, level_b, tot_pix_r, blit_begin, front_buffer)         -- *********** added by Eric
213
  begin
214
 
215
    -- default operations (do nothing unless explicitly stated in the following case statement)
216
    rd      <= NO;                      -- no memory write
217
    wr      <= NO;                      -- no memory read
218
    rd_q        <= NO;
219
         rd_b           <= NO;
220
         reset_q <= NO;
221
    blit_done <= NO;
222
         q_write <= NO;
223
         b_write <= NO;
224
 
225
         current_line_x <= current_line_r;
226
         s_addr_x <= s_addr_r;
227
         t_addr_x <= t_addr_r;
228
         count_x <= count_r;
229
         tot_pix_x <= tot_pix_r;
230
         addr_x  <= addr_r;                  -- next address is the same as current address
231
    state_x <= state_r;
232
         blend_data_x <= blend_data_r;
233
 
234
    -- **** compute the next state and operations ****
235
    case state_r is
236
 
237
      ------------------------------------------------------
238
      -- initialize blitter
239
      ------------------------------------------------------
240
      when STANDBY =>                                                                    -- goto this state at beginning of operation
241
                        if (blit_begin = YES) then
242
                                state_x <= INIT1;
243
                        end if;
244
 
245
                when INIT1 =>                                         -- latch in blit parameters
246
                  if (front_buffer = YES) then
247
                                t_addr_x <= target_address;
248
                  else
249
                                t_addr_x <= target_address + x"009600";
250
                  end if;
251
 
252
                  s_addr_x <= source_address;
253
                  tot_pix_x <= line_size;
254
                  current_line_x <= x"0000";
255
                  count_x <= x"000";
256
                  reset_q  <= YES;
257
                  blit_done <= NO;
258
                  state_x <= INIT2;
259
 
260
                when INIT2 =>                                                                             -- this state happens for every line
261
                  addr_x   <= unsigned(s_addr_r);
262
                  count_x <= x"000";
263
                  q_write <= YES;
264
                  state_x <= READ;
265
 
266
                when READ =>                                -- Read data in from the source address into the FIFO
267
        q_write <= YES;
268
                  rd <= YES;                                                                              -- actual write to FIFO is straight through assignment
269
                  if (earlyOpBegun = YES) then                            -- which is somewhere above
270
                                addr_x <= addr_r + 1;                 -- increment address read next memory location
271
                                count_x <= count_r + 1;
272
        end if;
273
                  if count_r = tot_pix_r then
274
            state_x <= EMPTY_PIPE;
275
        end if;
276
 
277
      when EMPTY_PIPE =>
278
                 q_write <= YES;
279
                 if (rdPending = NO) then
280
                          count_x <= x"000";
281
                  addr_x <= unsigned(t_addr_r);         -- set address to target        
282
                          if (alphaOp = NO) then                                         -- if not doing alpha operation then we can write the pixels
283
                                        state_x <= WRITE1;
284
                          else
285
                                        state_x <= READ_B;                                       -- otherwise we need to read the current contents of the VRAM
286
                          end if;
287
                  end if;
288
 
289
                when READ_B =>
290
                  b_write <= YES;
291
                  rd <= YES;                                                                              -- read from VRAM into buffer FIFO_B
292
                  if (earlyOpBegun = YES) then
293
                                addr_x <= addr_r + 1;
294
                                count_x <= count_r + 1;
295
        end if;
296
                  if (count_r = tot_pix_r) then
297
                           state_x <= EMPTY_PIPE_B;
298
                  end if;
299
 
300
      when EMPTY_PIPE_B =>
301
                 b_write <= YES;
302
                 if (rdPending = NO) then
303
                          count_x <= x"000";
304
                  addr_x <= unsigned(t_addr_r);         -- set address to target        
305
                          rd_q <= YES;
306
                     rd_b <= YES;
307
                          state_x <= WRITE1;
308
 
309
                  end if;
310
 
311
                when WRITE1 =>
312
                  count_x <= x"000";
313
                  rd_q <= YES;
314
                  rd_b <= YES;
315
                  --perform blending here (synchronous)
316
                  if (out_q(15 downto 8) = x"E7") then
317
                          blend_data_x(15 downto 8) <= out_b(15 downto 8);
318
                  else
319
                          blend_data_x(15 downto 8 )<= out_q(15 downto 8);
320
                  end if;
321
 
322
                  if (out_q(7 downto 0) = x"E7") then
323
                          blend_data_x(7 downto 0) <= out_b(7 downto 0);
324
                  else
325
                          blend_data_x(7 downto 0)<= out_q(7 downto 0);
326
                  end if;
327
 
328
                  state_x <= WRITE2;
329
 
330
      when WRITE2 =>                                -- write to memory
331
        wr <= YES;                                                                   -- with data from FIFO
332
 
333
                  if (earlyOpBegun = YES) then
334
                     rd_q <= YES;
335
                          rd_b <= YES;
336
 
337
                          --perform blending here (synchronous)
338
                          if (out_q(15 downto 8) = x"E7") then
339
                                  blend_data_x(15 downto 8) <= out_b(15 downto 8);
340
                          else
341
                                  blend_data_x(15 downto 8 )<= out_q(15 downto 8);
342
                          end if;
343
 
344
                          if (out_q(7 downto 0) = x"E7") then
345
                                  blend_data_x(7 downto 0) <= out_b(7 downto 0);
346
                          else
347
                                  blend_data_x(7 downto 0)<= out_q(7 downto 0);
348
                          end if;
349
 
350
                          if empty_q /= YES then                                            -- if we still have more data to write to VRAM
351
                 addr_x  <= addr_r + 1;                 -- increment address
352
                                 count_x <= count_r + 1;
353
                          else
354
                        current_line_x <= current_line_r + 1;    -- we're done with a whole line
355
                           state_x <= STOP;
356
                          end if;
357
        end if;
358
 
359
                when others =>                                                                   -- stop and unreachable states                    
360
                if (current_line_r = source_lines) then
361
                                blit_done <= YES;                                                -- Operation is complete, so we just sit here
362
                        else                                                                                                     -- all per line stuff neeeds to be reset here
363
                                count_x <= x"000";
364
                                s_addr_x <= s_addr_r + x"0000A0";
365
                                t_addr_x <= t_addr_r + x"0000A0";
366
                                reset_q <= YES;
367
                                state_x <= INIT2;
368
                        end if;
369
                end case;
370
 
371
  end process;
372
 
373
 
374
  -- update the registers of the memory tester controller       
375
  update : process(clk)
376
  begin
377
    if (clk'event and clk = '1') then
378
      if rst = YES then
379
        state_r <= STANDBY;
380
      else
381
        addr_r  <= addr_x;
382
        state_r <= state_x;
383
                  current_line_r <= current_line_x;
384
                  s_addr_r <= s_addr_x;
385
                  t_addr_r <= t_addr_x;
386
                  count_r <= count_x;
387
                  tot_pix_r <= tot_pix_x;
388
                  blend_data_r <= blend_data_x;
389
                end if;
390
    end if;
391
  end process;
392
 
393
end Behavioral;

powered by: WebSVN 2.1.0

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