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 26

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 26 zuofu
      PIXELS_PER_LINE :     natural := 320;  -- pixels per video scan line
14
      LINES_PER_FRAME :     natural := 200;  -- scan lines per video frame
15 9 zuofu
      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 26 zuofu
  signal   fifo_rst, fifo_empty       :     std_logic;
113 9 zuofu
  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 26 zuofu
      empty    => fifo_empty,
188 9 zuofu
      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 26 zuofu
  get_pixel : process(visible, pixel_data_out, pixel_data_r, rd_r, pixel_cnt, fifo_empty)
290 9 zuofu
  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 26 zuofu
                if fifo_empty = '1' then                                --ERIC
326
                        pixel_data_x <= x"0000";                        --ERIC
327
                else                                                                                    --ERIC
328
                pixel_data_x <= pixel_data_out;
329
           end if;                                                                              --ERIC
330 9 zuofu
    end if;
331
 
332
    -- the current pixel is in the lower bits of the pixel data shift register
333 26 zuofu
        pixel <= pixel_data_r(pixel'range);
334 9 zuofu
  end process get_pixel;
335
 
336
  -- map the current pixel to RGB values
337
  map_pixel : process(pixel, rgb_r, blank_r)
338
  begin
339
    if NUM_RGB_BITS=2 then
340
    case PIXEL_WIDTH is
341
      when 1          =>                -- 1-bit pixels map to black or white
342
                          rgb_x <= (others => pixel(0));
343
      when 2          =>                -- 2-bit pixels map to black, 2/3 gray, 1/3 gray, and white
344
                          rgb_x <= pixel(1 downto 0) & pixel(1 downto 0) & pixel(1 downto 0);
345
      when 4          =>                -- 4-bit pixels map to 8 colors (ignore MSB)
346
                          rgb_x <= pixel(2) & pixel(2) & pixel(1) & pixel(1) & pixel(0) & pixel(0);
347
      when 8          =>                -- 8-bit pixels map directly to RGB values
348
        rgb_x <= pixel(7 downto 6) & pixel(4 downto 1);
349
      when others     =>                -- 16-bit pixels maps directly to RGB values
350
        rgb_x <= pixel(8) & pixel(7) & pixel(5) & pixel(4) & pixel(2) & pixel(1);
351
    end case;
352
    else -- NUM_RGB_BITS=3
353
    case PIXEL_WIDTH is
354
      when 1          =>                -- 1-bit pixels map to black or white
355
                          rgb_x <= (others => pixel(0));
356
      when 2          =>                -- 2-bit pixels map to black, 5/7 gray, 3/7 gray, and  1/7 gray
357
                          rgb_x <= pixel(1 downto 0) & '0' & pixel(1 downto 0) & '0' & pixel(1 downto 0) & '0';
358
      when 4          =>                -- 4-bit pixels map to 8 colors (ignore MSB)
359
                          rgb_x <= pixel(2) & pixel(2) & pixel(2) & pixel(1) & pixel(1) & pixel(1) & pixel(0) & pixel(0) & pixel(0);
360
      when 8          =>                -- 8-bit pixels map to RGB with reduced resolution in green component
361
        rgb_x <= pixel(7 downto 5) & pixel(4 downto 3) & '0' & pixel(2 downto 0);
362
      when others     =>                -- 16-bit pixels map directly to RGB values
363
        rgb_x <= pixel(8 downto 0);
364
    end case;
365
    end if;
366
 
367
    -- just blank the pixel if not in the visible region of the screen
368
    if blank_r(blank_r'high-1) = YES then
369
      rgb_x <= (others => '0');
370
    end if;
371
 
372
    -- break the pixel into its red, green and blue components
373
    r <= rgb_r(3*NUM_RGB_BITS-1 downto 2*NUM_RGB_BITS);
374
    g <= rgb_r(2*NUM_RGB_BITS-1 downto NUM_RGB_BITS);
375
    b <= rgb_r(NUM_RGB_BITS-1 downto 0);
376
  end process map_pixel;
377
 
378
-- update registers
379
  update : process(rst, clk)
380
  begin
381
    if rst = YES then
382
      eof_r          <= '0';
383
      rd_r           <= NO;
384
      hsync_r        <= (others => '1');
385
      blank_r        <= (others => '0');
386
      pixel_data_r   <= (others => '0');
387
      rgb_r          <= (others => '0');
388
    elsif rising_edge(clk) then
389
      eof_r          <= eof_x;          -- end-of-frame signal goes at full clock rate to external system
390
      if cke = YES then
391
        rd_r         <= rd_x;
392
        hsync_r      <= hsync_x;
393
        blank_r      <= blank_x;
394
        pixel_data_r <= pixel_data_x;
395
        rgb_r        <= rgb_x;
396
      end if;
397
    end if;
398
  end process update;
399
 
400
end architecture vga_arch;
401
 
402
 
403
 
404
library IEEE, unisim;
405
use IEEE.std_logic_1164.all;
406
use IEEE.numeric_std.all;
407
use unisim.vcomponents.all;
408
use work.common.all;
409
 
410
-- Generate a sync pulse within a waveform PERIOD.
411
-- Also output the value of the counter used for timing so that
412
-- it can be used in generating an address for a video RAM.
413
 
414
entity sync is
415
  generic (
416
    FREQ    :     natural := 50_000;    -- master clock frequency (in KHz)
417
    PERIOD  :     natural := 32;        -- period of sync pulse (in us)
418
    START   :     natural := 26;        -- time sync pulse starts within the period (in us)
419
    WIDTH   :     natural := 4;         -- width of sync pulse (in us)
420
    VISIBLE :     natural := 1024       -- number of visible pixels/line or lines/frame
421
    );
422
  port (
423
    rst     : in  std_logic;            -- reset
424
    clk     : in  std_logic;            -- master clock
425
    cke     : in  std_logic;            -- clock-enable
426
    sync_n  : out std_logic;            -- sync pulse
427
    gate    : out std_logic;            -- single-clock pulse at start of sync pulse
428
    blank   : out std_logic;            -- blanking signal
429
    cnt     : out unsigned(15 downto 0)  -- output the timing counter value
430
    );
431
end entity sync;
432
 
433
 
434
architecture sync_arch of sync is
435
  constant NORM             : natural := 1000;  -- normalization factor for us * KHz
436
  constant CYC_PERIOD       : natural := (PERIOD * FREQ)/NORM;  -- sync wave PERIOD in clock cycles
437
  constant CYC_START        : natural := (START * FREQ)/NORM;  -- sync pulse START in cycles
438
  constant CYC_WIDTH        : natural := (WIDTH * FREQ)/NORM;  -- sync pulse WIDTH in cycles
439
  constant CYC_END          : natural := CYC_START + CYC_WIDTH;  -- sync pulse end in cycles
440
  signal   cnt_r, cnt_x     : unsigned(cnt'range);  -- counter for timing sync pulse waveform
441
  signal   sync_r, sync_x   : std_logic;  -- sync register
442
  signal   gate_r, gate_x   : std_logic;  -- gate register
443
  signal   blank_r, blank_x : std_logic;  -- blank register
444
begin
445
 
446
-- increment counter and wrap around to zero at end of period
447
  cnt_x <= (others => '0') when cnt_r = CYC_PERIOD-1 else cnt_r+1;
448
 
449
-- generate sync pulse within waveform period
450
  sync_x <= LO when cnt_r = CYC_START-1 else
451
            HI when cnt_r = CYC_END-1   else
452
            sync_r;
453
  sync_n <= sync_r;
454
 
455
-- generate gate signal at start of sync pulse
456
  gate_x <= YES when cnt_r = CYC_START-1 else NO;
457
  gate   <= gate_r;
458
 
459
-- generate blank signal after initial visible period
460
  blank_x <= YES when cnt_r = VISIBLE-1    else
461
             NO  when cnt_r = CYC_PERIOD-1 else
462
             blank_r;
463
  blank   <= blank_r;
464
 
465
-- output counter value
466
  cnt <= cnt_r;
467
 
468
-- update counter and registers
469
  update : process(rst, clk)
470
  begin
471
    if rst = YES then
472
      cnt_r     <= (others => '0');
473
      sync_r    <= HI;
474
      gate_r    <= NO;
475
      blank_r   <= YES;
476
    elsif rising_edge(clk) then
477
      if cke = YES then
478
        cnt_r   <= cnt_x;
479
        sync_r  <= sync_x;
480
        gate_r  <= gate_x;
481
        blank_r <= blank_x;
482
      end if;
483
    end if;
484
  end process update;
485
 
486
end architecture sync_arch;
487
 
488
 
489
 
490
library ieee, unisim;
491
use ieee.std_logic_1164.all;
492
use ieee.std_logic_unsigned.all;
493
use unisim.vcomponents.all;
494
 
495
entity fifo_cc is
496
  port (
497
    clk      : in  std_logic;
498
    rst      : in  std_logic;
499
    rd       : in  std_logic;
500
    wr       : in  std_logic;
501
    data_in  : in  std_logic_vector(15 downto 0);
502
    data_out : out std_logic_vector(15 downto 0);
503
    full     : out std_logic;
504
    empty    : out std_logic;
505
    level    : out std_logic_vector(7 downto 0)
506
    );
507
end entity fifo_cc;
508
 
509
architecture arch of fifo_cc is
510
  signal full_i   : std_logic;
511
  signal empty_i  : std_logic;
512
  signal rd_addr  : std_logic_vector(7 downto 0) := "00000000";
513
  signal wr_addr  : std_logic_vector(7 downto 0) := "00000000";
514
  signal level_i  : std_logic_vector(7 downto 0) := "00000000";
515
  signal rd_allow : std_logic;
516
  signal wr_allow : std_logic;
517
begin
518
 
519
  bram1 : RAMB4_S16_S16 port map (addra => rd_addr, addrb => wr_addr,
520
                                 dia    => (others => '0'), dib => data_in, wea => '0', web => '1',
521
                                 clka   => clk, clkb => clk, rsta => '0', rstb => '0',
522
                                 ena    => rd_allow, enb => wr_allow, doa => data_out );
523
 
524
  rd_allow <= rd and not empty_i;
525
  wr_allow <= wr and not full_i;
526
 
527
  process (clk, rst)
528
  begin
529
    if rst = '1' then
530
      rd_addr   <= (others => '0');
531
      wr_addr   <= (others => '0');
532
      level_i   <= (others => '0');
533
    elsif rising_edge(clk) then
534
      if rd_allow = '1' then
535
        rd_addr <= rd_addr + '1';
536
      end if;
537
      if wr_allow = '1' then
538
        wr_addr <= wr_addr + '1';
539
      end if;
540
      if (wr_allow and not rd_allow and not full_i) = '1' then
541
        level_i <= level_i + '1';
542
      elsif (rd_allow and not wr_allow and not empty_i) = '1' then
543
        level_i <= level_i - '1';
544
      end if;
545
    end if;
546
  end process;
547
 
548
  full_i  <= '1' when level_i = "11111111" else '0';
549
  full    <= full_i;
550
  empty_i <= '1' when level_i = "00000000" else '0';
551
  empty   <= empty_i;
552
  level   <= level_i;
553
 
554
end architecture arch;

powered by: WebSVN 2.1.0

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