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

Subversion Repositories 395_vgs

[/] [395_vgs/] [trunk/] [hdl/] [vga.vhd] - Blame information for rev 20

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

Line No. Rev Author Line
1 9 zuofu
library IEEE, unisim;
2
use IEEE.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
use unisim.vcomponents.all;
5
use work.common.all;
6
 
7
package vga_pckg is
8
  component vga
9
    generic (
10
      FREQ            :     natural := 50_000;  -- master clock frequency (in KHz)
11
      CLK_DIV         :     natural := 1;  -- FREQ / CLK_DIV = pixel clock
12
      PIXEL_WIDTH     :     natural := 8;  -- pixel width: 1, 2, 4, 8, or 16 bits
13
      PIXELS_PER_LINE :     natural := 800;  -- pixels per video scan line
14
      LINES_PER_FRAME :     natural := 600;  -- scan lines per video frame
15
      NUM_RGB_BITS    :     natural := 2;  -- width of R, G and B color output buses (2 or 3 are only valid values)
16
      FIT_TO_SCREEN   :     boolean := true  -- fit width x length to monitor screen
17
      );
18
    port (
19
      rst             : in  std_logic;  -- reset
20
      clk             : in  std_logic;  -- master clock
21
      wr              : in  std_logic;  -- write-enable for pixel buffer
22
      pixel_data_in   : in  std_logic_vector(15 downto 0);  -- input databus to pixel buffer
23
      full            : out std_logic;  -- pixel buffer full
24
      eof             : out std_logic;  -- end of vga frame
25
      r, g, b         : out std_logic_vector(NUM_RGB_BITS-1 downto 0);  -- R,G,B color output buses
26
      hsync_n         : out std_logic;  -- horizontal sync pulse
27
      vsync_n         : out std_logic;  -- vertical sync pulse
28
      blank           : out std_logic   -- blanking signal
29
      );
30
  end component vga;
31
end package vga_pckg;
32
 
33
 
34 20 esands
library ieee, unisim;
35
use ieee.std_logic_1164.all;
36
use ieee.std_logic_unsigned.all;
37
use unisim.vcomponents.all;
38 9 zuofu
 
39 20 esands
 
40
package fifo_cc_pckg is
41
        component fifo_cc is
42
        port (
43
          clk      : in  std_logic;
44
          rst      : in  std_logic;
45
          rd       : in  std_logic;
46
          wr       : in  std_logic;
47
          data_in  : in  std_logic_vector(15 downto 0);
48
          data_out : out std_logic_vector(15 downto 0);
49
          full     : out std_logic;
50
          empty    : out std_logic;
51
          level    : out std_logic_vector(7 downto 0)
52
          );
53
        end component fifo_cc;
54
end package fifo_cc_pckg;
55
 
56
 
57 9 zuofu
library IEEE, unisim;
58
use IEEE.std_logic_1164.all;
59
use IEEE.numeric_std.all;
60
use unisim.vcomponents.all;
61
use work.common.all;
62
 
63
entity vga is
64
  generic (
65
    FREQ            :     natural := 50_000;  -- master clock frequency (in KHz)
66
    CLK_DIV         :     natural := 1;  -- FREQ / CLK_DIV = pixel clock
67 20 esands
    PIXEL_WIDTH     :     natural := 8;  -- pixel width: 1, 2, 4, 8, or 16 bits
68
    PIXELS_PER_LINE :     natural := 320;  -- pixels per video scan line
69
    LINES_PER_FRAME :     natural := 200;  -- scan lines per video frame
70 9 zuofu
    NUM_RGB_BITS    :     natural := 2;  -- width of R, G and B color output buses
71
    FIT_TO_SCREEN   :     boolean := true  -- fit width x length to monitor screen
72
    );
73
  port (
74
    rst             : in  std_logic;    -- reset
75
    clk             : in  std_logic;    -- master clock
76
    wr              : in  std_logic;    -- write-enable for pixel buffer
77
    pixel_data_in   : in  std_logic_vector(15 downto 0);  -- input databus to pixel buffer
78
    full            : out std_logic;    -- pixel buffer full
79
    eof             : out std_logic;    -- end of vga frame
80
    r, g, b         : out std_logic_vector(NUM_RGB_BITS-1 downto 0);  -- R,G,B color output buses
81
    hsync_n         : out std_logic;    -- horizontal sync pulse
82
    vsync_n         : out std_logic;    -- vertical sync pulse
83
    blank           : out std_logic     -- blanking signal
84
    );
85
end entity vga;
86
 
87
 
88
architecture vga_arch of vga is
89
  constant NORM : natural := 1000;      -- normalization factor for us * KHz
90
 
91
  -- video timing parameters for FIT_TO_SCREEN mode
92
  constant HSYNC_START_F  : natural := (NORM * PIXELS_PER_LINE * CLK_DIV)/FREQ + 1;  -- start of horiz. sync pulse with a scanline (us)
93
  constant HSYNC_PERIOD_F : natural := HSYNC_START_F + 6;  -- horizontal scanline period (us)
94
  constant HSYNC_WIDTH_F  : natural := 4;  -- width of horiz. sync pulse (us)
95
  constant HSYNC_FREQ_F   : natural := NORM / HSYNC_PERIOD_F;  -- scanline frequency (KHz) 
96
  constant VSYNC_START_F  : natural := HSYNC_PERIOD_F * LINES_PER_FRAME + 340;  -- start of vert. sync pulse within a frame (us)
97
  constant VSYNC_PERIOD_F : natural := VSYNC_START_F + 1084;  -- video frame period (us)
98
  constant VSYNC_WIDTH_F  : natural := 64;  -- width of vert. sync pulse (us)
99
 
100
  -- video timing for 31 KHz horizontal, 60 Hz vertical screen refresh
101
  constant HSYNC_START  : natural := 26;  -- start of horiz. sync pulse with a scanline (us)
102
  constant HSYNC_PERIOD : natural := 32;  -- horizontal scanline period (us)
103
  constant HSYNC_WIDTH  : natural := 4;  -- width of horiz. sync pulse (us)
104
  constant HSYNC_FREQ   : natural := NORM / HSYNC_PERIOD;  -- scanline frequency (KHz) 
105
  constant VSYNC_START  : natural := 15_700;  -- start of vert. sync pulse within a frame (us)
106
  constant VSYNC_PERIOD : natural := 16_784;  -- video frame period (us)
107
  constant VSYNC_WIDTH  : natural := 64;  -- width of vert. sync pulse (us)
108
 
109
  signal   clk_div_cnt                :     unsigned(7 downto 0);
110
  signal   cke                        :     std_logic;
111
  signal   line_cnt, pixel_cnt        :     unsigned(15 downto 0);  -- current video line and pixel within line
112
  signal   fifo_rst                   :     std_logic;
113
  signal   fifo_level                 :     std_logic_vector(7 downto 0);
114
  signal   eof_i, eof_x, eof_r        :     std_logic;
115
  signal   v_gate, cke_v_gate         :     std_logic;
116
  signal   h_blank, v_blank, visible  :     std_logic;
117
  constant PIX_PROC_DELAY             :     natural := 3;  -- time delay to read a pixel from the FIFO and colormap it
118
  signal   hsync_x, hsync_r           :     std_logic_vector(PIX_PROC_DELAY downto 1);
119
  signal   blank_x, blank_r           :     std_logic_vector(PIX_PROC_DELAY downto 1);
120
  signal   cke_rd, rd_x, rd_r         :     std_logic;
121
  signal   pixel                      :     std_logic_vector(PIXEL_WIDTH-1 downto 0);
122
  signal   pixel_data_x, pixel_data_r :     std_logic_vector(15 downto 0);
123
  signal   pixel_data_out             :     std_logic_vector(15 downto 0);
124
  signal   rgb_x, rgb_r               :     std_logic_vector(3*NUM_RGB_BITS-1 downto 0);
125
  component fifo_cc
126
    port (
127
      clk                             : in  std_logic;
128
      rst                             : in  std_logic;
129
      rd                              : in  std_logic;
130
      wr                              : in  std_logic;
131
      data_in                         : in  std_logic_vector(15 downto 0);
132
      data_out                        : out std_logic_vector(15 downto 0);
133
      full                            : out std_logic;
134
      empty                           : out std_logic;
135
      level                           : out std_logic_vector(7 downto 0)
136
      );
137
  end component fifo_cc;
138
  component sync
139
    generic (
140
      FREQ                            :     natural := 50_000;  -- master clock frequency (in KHz)
141
      PERIOD                          :     natural := 32;  -- period of sync pulse (in us)
142
      START                           :     natural := 26;  -- time sync pulse starts within the period (in us)
143
      WIDTH                           :     natural := 4;  -- width of sync pulse (in us)
144
      VISIBLE                         :     natural := 1024  -- number of visible pixels/line or lines/frame
145
      );
146
    port (
147
      rst                             : in  std_logic;  -- reset
148
      clk                             : in  std_logic;  -- master clock
149
      cke                             : in  std_logic;  -- clock-enable
150
      sync_n                          : out std_logic;  -- sync pulse
151
      gate                            : out std_logic;  -- single-clock pulse at start of sync pulse
152
      blank                           : out std_logic;  -- blanking signal
153
      cnt                             : out unsigned(15 downto 0)  -- output the timing counter value
154
      );
155
  end component sync;
156
 
157
begin
158
 
159
  -- clock divider for reducing the pixel clock rate
160
  process(clk, rst)
161
  begin
162
    if rst = YES then
163
      clk_div_cnt   <= (others => '0');
164
      cke           <= YES;
165
    elsif rising_edge(clk) then
166
      if clk_div_cnt = CLK_DIV-1 then
167
        clk_div_cnt <= (others => '0');
168
        cke         <= YES;
169
      else
170
        clk_div_cnt <= clk_div_cnt + 1;
171
        cke         <= NO;
172
      end if;
173
    end if;
174
  end process;
175
 
176
  -- pixel data buffer
177
  cke_rd <= rd_x and cke;
178
  fifo : fifo_cc
179
    port map (
180
      clk      => clk,
181
      rd       => cke_rd,
182
      wr       => wr,
183
      data_in  => pixel_data_in,
184
      rst      => fifo_rst,
185
      data_out => pixel_data_out,
186
      full     => open,
187
      empty    => open,
188
      level    => fifo_level
189
      );
190
  full   <= YES when fifo_level(7 downto 3) = "11111" else NO;
191
 
192
  -- the clock enable for the vertical sync module is also combined with a gate signal
193
  -- that is generated at the end of every scanline by the horizontal sync module
194
  cke_v_gate <= cke and v_gate;
195
 
196
  -- generate the horizontal and vertical sync pulses for FIT_TO_SCREEN mode
197
  gen_syncs_fit : if FIT_TO_SCREEN = true generate
198
    hsync       : sync
199
      generic map (
200
        FREQ    => FREQ / CLK_DIV,      -- master pixel-clock frequency
201
        PERIOD  => HSYNC_PERIOD_F,      -- scanline period (32 us)
202
        START   => HSYNC_START_F,       -- start of horizontal sync pulse in scan line
203
        WIDTH   => HSYNC_WIDTH_F,       -- width of horizontal sync pulse
204
        VISIBLE => PIXELS_PER_LINE
205
        )
206
      port map (
207
        rst     => rst,
208
        clk     => clk,                 -- master clock
209
        cke     => cke,                 -- a new pixel is output whenever the clock is enabled
210
        sync_n  => hsync_x(1),          -- send pulse through delay line
211
        gate    => v_gate,              -- send gate signal to increment vertical sync pulse generator once per scan line
212
        blank   => h_blank,             -- blanking signal within a scan line
213
        cnt     => pixel_cnt            -- current pixel within the scan line
214
        );
215
 
216
    vsync : sync
217
      generic map (
218
        FREQ    => HSYNC_FREQ_F,        -- scanline frequency
219
        PERIOD  => VSYNC_PERIOD_F,      -- image frame period
220
        START   => VSYNC_START_F,       -- start of vertical sync pulse in frame
221
        WIDTH   => VSYNC_WIDTH_F,       -- width of vertical sync pulse
222
        VISIBLE => LINES_PER_FRAME
223
        )
224
      port map (
225
        rst     => rst,
226
        clk     => clk,                 -- master clock
227
        cke     => cke_v_gate,          -- enable clock once per horizontal scan line
228
        sync_n  => vsync_n,             -- send pulse through delay line
229
        gate    => eof_x,               -- indicate the end of a complete frame
230
        blank   => v_blank,             -- blanking signal within a frame
231
        cnt     => line_cnt             -- current scan line within a frame
232
        );
233
  end generate;
234
 
235
  -- generate the horizontal and vertical sync pulses for 31 KHz horizontal, 60 Hz vertical screen refresh
236
  gen_syncs_nofit : if FIT_TO_SCREEN = false generate
237
    hsync         : sync
238
      generic map (
239
        FREQ    => FREQ / CLK_DIV,      -- master pixel-clock frequency
240
        PERIOD  => HSYNC_PERIOD,        -- scanline period (32 us)
241
        START   => HSYNC_START,         -- start of horizontal sync pulse in scan line
242
        WIDTH   => HSYNC_WIDTH,         -- width of horizontal sync pulse
243
        VISIBLE => PIXELS_PER_LINE
244
        )
245
      port map (
246
        rst     => rst,
247
        clk     => clk,                 -- master clock
248
        cke     => cke,                 -- clock always enabled so there is a new pixel output on every clock pulse
249
        sync_n  => hsync_x(1),          -- send pulse through delay line
250
        gate    => v_gate,              -- send gate signal to increment vertical sync pulse generator once per scan line
251
        blank   => h_blank,             -- blanking signal within a scan line
252
        cnt     => pixel_cnt            -- current pixel within the scan line
253
        );
254
 
255
    vsync : sync
256
      generic map (
257
        FREQ    => HSYNC_FREQ,          -- scanline frequency (KHz)
258
        PERIOD  => VSYNC_PERIOD,        -- image frame period
259
        START   => VSYNC_START,         -- start of vertical sync pulse in frame
260
        WIDTH   => VSYNC_WIDTH,         -- width of vertical sync pulse
261
        VISIBLE => LINES_PER_FRAME
262
        )
263
      port map (
264
        rst     => rst,
265
        clk     => clk,                 -- master clock
266
        cke     => cke_v_gate,          -- enable clock once per horizontal scan line
267
        sync_n  => vsync_n,             -- send pulse through delay line
268
        gate    => eof_x,               -- indicate the end of a complete frame
269
        blank   => v_blank,             -- blanking signal within a frame
270
        cnt     => line_cnt             -- current scan line within a frame
271
        );
272
  end generate;
273
 
274
  eof_i    <= eof_x and not eof_r;      -- shorten end-of-frame signal to a single clock cycle
275
  eof      <= eof_i;
276
  fifo_rst <= eof_i or rst;             -- clear the contents of the pixel buffer at the end of every frame
277
 
278
  visible    <= h_blank nor v_blank;    -- pixels are visible when horiz. & vertical blank are inactive 
279
  blank_x(1) <= not visible;            -- send blanking signal through delay line
280
 
281
  -- pass the horiz. and vert. syncs and blanking signal through delay lines to compensate for the
282
  -- processing delays incurred by the pixel data
283
  hsync_x(hsync_x'high downto 2) <= hsync_r(hsync_r'high-1 downto 1);
284
  hsync_n                        <= hsync_r(hsync_r'high);
285
  blank_x(blank_x'high downto 2) <= blank_r(blank_r'high-1 downto 1);
286
  blank                          <= blank_r(blank_r'high);
287
 
288
  -- get the current pixel from the word of pixel data or read more pixel data from the buffer
289
  get_pixel : process(visible, pixel_data_out, pixel_data_r, rd_r, pixel_cnt)
290
  begin
291
    rd_x <= NO;                         -- by default, don't read next word of pixel data from the buffer
292
 
293
    -- shift pixel data depending on its width so the next pixel is in the LSBs of the pixel data shift register
294
    case PIXEL_WIDTH is
295
      when 1      =>                    -- 1-bit pixels, 16 per pixel data word
296
        if (visible = YES) and (pixel_cnt(3 downto 0) = 0) then
297
          rd_x       <= YES;            -- read new pixel data from buffer every 16 clocks during visible portion of scan line
298
        end if;
299
        pixel_data_x <= "0" & pixel_data_r(15 downto 1);  -- left-shift pixel data to move next pixel to LSB
300
      when 2      =>                    -- 2-bit pixels, 8 per pixel data word
301
        if (visible = YES) and (pixel_cnt(2 downto 0) = 0) then
302
          rd_x       <= YES;            -- read new pixel data from buffer every 8 clocks during visible portion of scan line
303
        end if;
304
        pixel_data_x <= "00" & pixel_data_r(15 downto 2);  -- left-shift pixel data to move next pixel to LSB 
305
      when 4      =>                    -- 4-bit pixels, 4 per pixel data word
306
        if (visible = YES) and (pixel_cnt(1 downto 0) = 0) then
307
          rd_x       <= YES;            -- read new pixel data from buffer every 4 clocks during visible portion of scan line
308
        end if;
309
        pixel_data_x <= "0000" & pixel_data_r(15 downto 4);  -- left-shift pixel data to move next pixel to LSB 
310
      when 8      =>                    -- 8-bit pixels, 2 per pixel data word
311
        if (visible = YES) and (pixel_cnt(0 downto 0) = 0) then
312
          rd_x       <= YES;            -- read new pixel data from buffer every 2 clocks during visible portion of scan line
313
        end if;
314
        pixel_data_x <= "00000000" & pixel_data_r(15 downto 8);  -- left-shift pixel data to move next pixel to LSB 
315
      when others =>                    -- any other width, then 1 per pixel data word
316
        if (visible = YES) then
317
          rd_x       <= YES;            -- read new pixel data from buffer every clock during visible portion of scan line
318
        end if;
319
        pixel_data_x <= pixel_data_r;
320
    end case;
321
 
322
    -- store the pixel data from the buffer instead of shifting the pixel data
323
    -- if a read operation was initiated in the previous cycle.
324
    if rd_r = YES then
325
      pixel_data_x <= pixel_data_out;
326
    end if;
327
 
328
    -- the current pixel is in the lower bits of the pixel data shift register
329
    pixel <= pixel_data_r(pixel'range);
330
  end process get_pixel;
331
 
332
  -- map the current pixel to RGB values
333
  map_pixel : process(pixel, rgb_r, blank_r)
334
  begin
335
    if NUM_RGB_BITS=2 then
336
    case PIXEL_WIDTH is
337
      when 1          =>                -- 1-bit pixels map to black or white
338
                          rgb_x <= (others => pixel(0));
339
      when 2          =>                -- 2-bit pixels map to black, 2/3 gray, 1/3 gray, and white
340
                          rgb_x <= pixel(1 downto 0) & pixel(1 downto 0) & pixel(1 downto 0);
341
      when 4          =>                -- 4-bit pixels map to 8 colors (ignore MSB)
342
                          rgb_x <= pixel(2) & pixel(2) & pixel(1) & pixel(1) & pixel(0) & pixel(0);
343
      when 8          =>                -- 8-bit pixels map directly to RGB values
344
        rgb_x <= pixel(7 downto 6) & pixel(4 downto 1);
345
      when others     =>                -- 16-bit pixels maps directly to RGB values
346
        rgb_x <= pixel(8) & pixel(7) & pixel(5) & pixel(4) & pixel(2) & pixel(1);
347
    end case;
348
    else -- NUM_RGB_BITS=3
349
    case PIXEL_WIDTH is
350
      when 1          =>                -- 1-bit pixels map to black or white
351
                          rgb_x <= (others => pixel(0));
352
      when 2          =>                -- 2-bit pixels map to black, 5/7 gray, 3/7 gray, and  1/7 gray
353
                          rgb_x <= pixel(1 downto 0) & '0' & pixel(1 downto 0) & '0' & pixel(1 downto 0) & '0';
354
      when 4          =>                -- 4-bit pixels map to 8 colors (ignore MSB)
355
                          rgb_x <= pixel(2) & pixel(2) & pixel(2) & pixel(1) & pixel(1) & pixel(1) & pixel(0) & pixel(0) & pixel(0);
356
      when 8          =>                -- 8-bit pixels map to RGB with reduced resolution in green component
357
        rgb_x <= pixel(7 downto 5) & pixel(4 downto 3) & '0' & pixel(2 downto 0);
358
      when others     =>                -- 16-bit pixels map directly to RGB values
359
        rgb_x <= pixel(8 downto 0);
360
    end case;
361
    end if;
362
 
363
    -- just blank the pixel if not in the visible region of the screen
364
    if blank_r(blank_r'high-1) = YES then
365
      rgb_x <= (others => '0');
366
    end if;
367
 
368
    -- break the pixel into its red, green and blue components
369
    r <= rgb_r(3*NUM_RGB_BITS-1 downto 2*NUM_RGB_BITS);
370
    g <= rgb_r(2*NUM_RGB_BITS-1 downto NUM_RGB_BITS);
371
    b <= rgb_r(NUM_RGB_BITS-1 downto 0);
372
  end process map_pixel;
373
 
374
-- update registers
375
  update : process(rst, clk)
376
  begin
377
    if rst = YES then
378
      eof_r          <= '0';
379
      rd_r           <= NO;
380
      hsync_r        <= (others => '1');
381
      blank_r        <= (others => '0');
382
      pixel_data_r   <= (others => '0');
383
      rgb_r          <= (others => '0');
384
    elsif rising_edge(clk) then
385
      eof_r          <= eof_x;          -- end-of-frame signal goes at full clock rate to external system
386
      if cke = YES then
387
        rd_r         <= rd_x;
388
        hsync_r      <= hsync_x;
389
        blank_r      <= blank_x;
390
        pixel_data_r <= pixel_data_x;
391
        rgb_r        <= rgb_x;
392
      end if;
393
    end if;
394
  end process update;
395
 
396
end architecture vga_arch;
397
 
398
 
399
 
400
library IEEE, unisim;
401
use IEEE.std_logic_1164.all;
402
use IEEE.numeric_std.all;
403
use unisim.vcomponents.all;
404
use work.common.all;
405
 
406
-- Generate a sync pulse within a waveform PERIOD.
407
-- Also output the value of the counter used for timing so that
408
-- it can be used in generating an address for a video RAM.
409
 
410
entity sync is
411
  generic (
412
    FREQ    :     natural := 50_000;    -- master clock frequency (in KHz)
413
    PERIOD  :     natural := 32;        -- period of sync pulse (in us)
414
    START   :     natural := 26;        -- time sync pulse starts within the period (in us)
415
    WIDTH   :     natural := 4;         -- width of sync pulse (in us)
416
    VISIBLE :     natural := 1024       -- number of visible pixels/line or lines/frame
417
    );
418
  port (
419
    rst     : in  std_logic;            -- reset
420
    clk     : in  std_logic;            -- master clock
421
    cke     : in  std_logic;            -- clock-enable
422
    sync_n  : out std_logic;            -- sync pulse
423
    gate    : out std_logic;            -- single-clock pulse at start of sync pulse
424
    blank   : out std_logic;            -- blanking signal
425
    cnt     : out unsigned(15 downto 0)  -- output the timing counter value
426
    );
427
end entity sync;
428
 
429
 
430
architecture sync_arch of sync is
431
  constant NORM             : natural := 1000;  -- normalization factor for us * KHz
432
  constant CYC_PERIOD       : natural := (PERIOD * FREQ)/NORM;  -- sync wave PERIOD in clock cycles
433
  constant CYC_START        : natural := (START * FREQ)/NORM;  -- sync pulse START in cycles
434
  constant CYC_WIDTH        : natural := (WIDTH * FREQ)/NORM;  -- sync pulse WIDTH in cycles
435
  constant CYC_END          : natural := CYC_START + CYC_WIDTH;  -- sync pulse end in cycles
436
  signal   cnt_r, cnt_x     : unsigned(cnt'range);  -- counter for timing sync pulse waveform
437
  signal   sync_r, sync_x   : std_logic;  -- sync register
438
  signal   gate_r, gate_x   : std_logic;  -- gate register
439
  signal   blank_r, blank_x : std_logic;  -- blank register
440
begin
441
 
442
-- increment counter and wrap around to zero at end of period
443
  cnt_x <= (others => '0') when cnt_r = CYC_PERIOD-1 else cnt_r+1;
444
 
445
-- generate sync pulse within waveform period
446
  sync_x <= LO when cnt_r = CYC_START-1 else
447
            HI when cnt_r = CYC_END-1   else
448
            sync_r;
449
  sync_n <= sync_r;
450
 
451
-- generate gate signal at start of sync pulse
452
  gate_x <= YES when cnt_r = CYC_START-1 else NO;
453
  gate   <= gate_r;
454
 
455
-- generate blank signal after initial visible period
456
  blank_x <= YES when cnt_r = VISIBLE-1    else
457
             NO  when cnt_r = CYC_PERIOD-1 else
458
             blank_r;
459
  blank   <= blank_r;
460
 
461
-- output counter value
462
  cnt <= cnt_r;
463
 
464
-- update counter and registers
465
  update : process(rst, clk)
466
  begin
467
    if rst = YES then
468
      cnt_r     <= (others => '0');
469
      sync_r    <= HI;
470
      gate_r    <= NO;
471
      blank_r   <= YES;
472
    elsif rising_edge(clk) then
473
      if cke = YES then
474
        cnt_r   <= cnt_x;
475
        sync_r  <= sync_x;
476
        gate_r  <= gate_x;
477
        blank_r <= blank_x;
478
      end if;
479
    end if;
480
  end process update;
481
 
482
end architecture sync_arch;
483
 
484
 
485
 
486
library ieee, unisim;
487
use ieee.std_logic_1164.all;
488
use ieee.std_logic_unsigned.all;
489
use unisim.vcomponents.all;
490
 
491
entity fifo_cc is
492
  port (
493
    clk      : in  std_logic;
494
    rst      : in  std_logic;
495
    rd       : in  std_logic;
496
    wr       : in  std_logic;
497
    data_in  : in  std_logic_vector(15 downto 0);
498
    data_out : out std_logic_vector(15 downto 0);
499
    full     : out std_logic;
500
    empty    : out std_logic;
501
    level    : out std_logic_vector(7 downto 0)
502
    );
503
end entity fifo_cc;
504
 
505
architecture arch of fifo_cc is
506
  signal full_i   : std_logic;
507
  signal empty_i  : std_logic;
508
  signal rd_addr  : std_logic_vector(7 downto 0) := "00000000";
509
  signal wr_addr  : std_logic_vector(7 downto 0) := "00000000";
510
  signal level_i  : std_logic_vector(7 downto 0) := "00000000";
511
  signal rd_allow : std_logic;
512
  signal wr_allow : std_logic;
513
begin
514
 
515
  bram1 : RAMB4_S16_S16 port map (addra => rd_addr, addrb => wr_addr,
516
                                 dia    => (others => '0'), dib => data_in, wea => '0', web => '1',
517
                                 clka   => clk, clkb => clk, rsta => '0', rstb => '0',
518
                                 ena    => rd_allow, enb => wr_allow, doa => data_out );
519
 
520
  rd_allow <= rd and not empty_i;
521
  wr_allow <= wr and not full_i;
522
 
523
  process (clk, rst)
524
  begin
525
    if rst = '1' then
526
      rd_addr   <= (others => '0');
527
      wr_addr   <= (others => '0');
528
      level_i   <= (others => '0');
529
    elsif rising_edge(clk) then
530
      if rd_allow = '1' then
531
        rd_addr <= rd_addr + '1';
532
      end if;
533
      if wr_allow = '1' then
534
        wr_addr <= wr_addr + '1';
535
      end if;
536
      if (wr_allow and not rd_allow and not full_i) = '1' then
537
        level_i <= level_i + '1';
538
      elsif (rd_allow and not wr_allow and not empty_i) = '1' then
539
        level_i <= level_i - '1';
540
      end if;
541
    end if;
542
  end process;
543
 
544
  full_i  <= '1' when level_i = "11111111" else '0';
545
  full    <= full_i;
546
  empty_i <= '1' when level_i = "00000000" else '0';
547
  empty   <= empty_i;
548
  level   <= level_i;
549
 
550
end architecture arch;

powered by: WebSVN 2.1.0

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