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

Subversion Repositories wb_vga

[/] [wb_vga/] [tags/] [a01/] [mem_reader.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tantos
--
2
--  File: mem_reader.vhd
3
--
4
--  (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
5
--  This code is distributed under the terms and conditions of the GNU General Public Lince.
6
--
7
 
8
library IEEE;
9
use IEEE.std_logic_1164.all;
10
 
11
library work;
12
use work.technology.all;
13
 
14
entity mem_reader is
15
        generic (
16
                v_mem_width: positive := 16;
17
                v_addr_width: positive:= 20;
18
                fifo_size: positive := 256;
19
                dual_scan_fifo_size: positive := 256
20
        );
21
        port (
22
                clk: in std_logic;
23
                clk_en: in std_logic;
24
                pix_clk_en: in std_logic;
25
                reset: in std_logic := '0';
26
 
27
                total: in std_logic_vector(v_addr_width-1 downto 0);   -- total video memory size in bytes 7..0
28
                fifo_treshold: in std_logic_vector(7 downto 0);        -- priority change threshold
29
                bpp: in std_logic_vector(1 downto 0);                  -- number of bits makes up a pixel valid values: 1,2,4,8
30
                multi_scan: in std_logic_vector(1 downto 0);           -- number of repeated scans
31
 
32
                -- Can be githces on it!!! Don't clock by it!!!
33
                high_prior: out std_logic;                      -- signals to the memory arbitrer to give high 
34
                                                                -- priority to the video engine
35
                v_mem_rd: out std_logic;                        -- video memory read request
36
                v_mem_rdy: in std_logic;                        -- video memory data ready
37
                v_mem_addr: out std_logic_vector (v_addr_width-1 downto 0); -- video memory address
38
                v_mem_data: in std_logic_vector (v_mem_width-1 downto 0);   -- video memory data
39
 
40
                blank: in std_logic;                            -- video sync generator blank output
41
                h_tc: in std_logic;                                                     -- horizontal sync pulse. Must be 1 clock wide!
42
                video_out: out std_logic_vector (7 downto 0)    -- video output binary signal (unused bits are forced to 0)
43
        );
44
end mem_reader;
45
 
46
architecture mem_reader of mem_reader is
47
        component fifo
48
                generic (fifo_width : positive;
49
                                 used_width : positive;
50
                                 fifo_depth : positive
51
                );
52
                port (d_in : in std_logic_vector(fifo_width-1 downto 0);
53
                          clk : in std_logic;
54
                          wr : in std_logic;
55
                          rd : in std_logic;
56
                          a_clr : in std_logic := '0';
57
                          s_clr : in std_logic := '0';
58
                          d_out : out std_logic_vector(fifo_width-1 downto 0);
59
                          used : out std_logic_vector(used_width-1 downto 0);
60
                          full : out std_logic;
61
                          empty : out std_logic
62
                );
63
        end component;
64
 
65
        signal fifo_rd: std_logic;
66
        signal fifo_out: std_logic_vector(v_mem_width-1 downto 0);
67
 
68
        signal video_fifo_out: std_logic_vector(v_mem_width-1 downto 0);
69
        signal video_fifo_usedw: std_logic_vector(7 downto 0);
70
        signal video_fifo_rd: std_logic;
71
        signal video_fifo_full: std_logic;
72
        signal video_fifo_empty: std_logic;
73
 
74
        signal ds_fifo_out: std_logic_vector(v_mem_width-1 downto 0);
75
--      signal ds_fifo_usedw: std_logic_vector(7 downto 0);
76
        signal ds_fifo_rd: std_logic;
77
        signal ds_fifo_clr: std_logic;
78
--      signal ds_fifo_full: std_logic;
79
--      signal ds_fifo_empty: std_logic;
80
 
81
        signal i_video_out: std_logic_vector(7 downto 0);
82
        signal ds_mode: std_logic;
83
 
84
        subtype pixel_cntr_var is integer range 0 to 7;
85
 
86
--      signal i_v_mem_rd: std_logic := '0';
87
 
88
begin
89
        -- memory decoupler FIFO
90
        pixel_fifo: fifo
91
                generic map (
92
                        fifo_width => v_mem_width,
93
                        used_width => 8,
94
                        fifo_depth => fifo_size
95
                )
96
                port map (
97
                        d_in => v_mem_data,
98
                        clk => clk,
99
                        wr => v_mem_rdy,
100
                        rd => video_fifo_rd,
101
--                      a_clr => '0',
102
                        a_clr => reset,
103
                        s_clr => reset,
104
                        full => video_fifo_full,
105
                        d_out => video_fifo_out,
106
                        used => video_fifo_usedw,
107
                  empty => video_fifo_empty
108
                );
109
 
110
        -- dual-scan FIFO
111
        ds_pixel_fifo: fifo
112
                generic map (
113
                        fifo_width => v_mem_width,
114
                        used_width => 8,
115
                        fifo_depth => dual_scan_fifo_size
116
                )
117
                port map (
118
                        d_in => fifo_out,
119
                        clk => clk,
120
                        wr => fifo_rd,
121
                        rd => ds_fifo_rd,
122
--                      a_clr => '0',
123
                        a_clr => reset,
124
                        s_clr =>  ds_fifo_clr,
125
                        d_out => ds_fifo_out
126
                );
127
 
128
        -- Multiplexer for DS data handling
129
        fifo_mux: for i in v_mem_width-1 downto 0 generate
130
        begin
131
                fifo_out(i) <= (video_fifo_out(i) and not ds_mode) or (ds_fifo_out(i) and ds_mode);
132
--              fifo_out(i) <= (video_fifo_out(i) and not ds_mode);
133
        end generate;
134
        --fifo_out <= (video_fifo_out and not ds_mode);
135
        ds_fifo_rd    <= ('0'     and not ds_mode) or (fifo_rd and ds_mode);
136
        video_fifo_rd <= (fifo_rd and not ds_mode) or ('0'     and ds_mode);
137
 
138
        -- Counter handles DS
139
        ds_counter : process is
140
                variable cnt: std_logic_vector(1 downto 0);
141
        begin
142
                wait until clk'EVENT and clk = '1';
143
                if (reset = '1') then
144
                        cnt := (others => '0');
145
                        ds_fifo_clr <= '1';
146
                        ds_mode <= '0';
147
                else
148
                        if (clk_en = '1') then
149
                                if (h_tc = '1') then
150
                                        if (is_zero(cnt)) then
151
                                                ds_mode <= '0';
152
                                                ds_fifo_clr <= '1';
153
                                        else
154
                                                ds_mode <= '1';
155
                                                ds_fifo_clr <= '0';
156
                                        end if;
157
                                        if (cnt = multi_scan) then
158
                                                cnt := (others => '0');
159
                                        else
160
                                                cnt := add_one(cnt);
161
                                        end if;
162
                                else
163
                                        ds_fifo_clr <= '0';
164
                                end if;
165
                        else
166
                                ds_fifo_clr <= '1';
167
                                ds_mode <= '0';
168
                        end if;
169
                end if;
170
        end process;
171
 
172
        -- Pixel data reader state machine
173
        pixel_cntr : process is
174
                variable pixel_cnt: std_logic_vector(v_addr_width-1 downto 0);
175
        begin
176
                wait until clk'EVENT and clk='1';
177
                if (reset = '1') then
178
                        pixel_cnt := (others => '0');
179
                else
180
                        -- A little cheet. It won't work with constant v_mem_rdy.
181
                        if (v_mem_rdy = '1') then
182
                                -- data is already written to the FIFO, all we need to do is to update the counter,
183
                                -- and remove the request
184
                                if (pixel_cnt = total) then
185
                                        pixel_cnt := (others => '0');
186
                                else
187
                                        pixel_cnt := add_one(pixel_cnt);
188
                                end if;
189
                        end if;
190
                end if;
191
                v_mem_addr <= pixel_cnt;
192
        end process;
193
        v_mem_rd <= not video_fifo_full;
194
 
195
        -- Pixel data output state machine.
196
        pixel_output: process is
197
                subtype pixel_cntr_var is integer range 0 to v_mem_width-1;
198
 
199
                variable pixel_cntr : pixel_cntr_var;
200
                variable shift_reg : std_logic_vector (v_mem_width-1 downto 0);
201
        type rst_states is (in_reset,read,normal);
202
                variable rst_state : rst_states := in_reset;
203
        begin
204
                wait until clk'EVENT and clk='1';
205
                if (reset = '1') then
206
                        fifo_rd <= '0';
207
                        i_video_out <= (others => '0');
208
                        shift_reg := (others => '0');
209
                        pixel_cntr := 0;
210
                        rst_state := in_reset;
211
                else
212
                  if (not (rst_state = normal)) then
213
                    -- perform one read after reset otherwise the picture will be shifted rigth one pixel
214
                    case (rst_state) is
215
                      when in_reset =>
216
                    if (video_fifo_empty = '0') then
217
                          fifo_rd <= '1';
218
                          rst_state := read;
219
                        else
220
                          fifo_rd <= '0';
221
                        end if;
222
                      when read =>
223
                                                pixel_cntr := 0;
224
                                                shift_reg := fifo_out;
225
                        fifo_rd <= '0';
226
                        rst_state := normal;
227
                      when others =>
228
                    end case;
229
                  else
230
                        if (pix_clk_en = '0') then
231
                                fifo_rd <= '0'; -- clear any pending read requests
232
                        else
233
                                if (blank = '1') then
234
                                        fifo_rd <= '0'; -- clear any pending read requests
235
                                        i_video_out <= (others => '0'); -- disable output
236
--                                      i_video_out <= (others => 'U'); -- disable output
237
                                else
238
                                        case (bpp) is
239
                                                when "00" =>
240
                                                        -- shift next data to the output and optionally read the next data from the fifo
241
                                                        i_video_out(0) <= shift_reg(v_mem_width-1);
242
                                                        i_video_out(7 downto 1) <= (others => '0');
243
                                                        if (pixel_cntr = v_mem_width-1) then
244
                                                                -- Read next data
245
                                                                pixel_cntr := 0;
246
                                                                shift_reg := fifo_out;
247
                                                                fifo_rd <= '0';
248
                                                        elsif (pixel_cntr = v_mem_width-2) then
249
                                                                -- Request next data from FIFO
250
                                                                pixel_cntr := pixel_cntr + 1;
251
                                                                fifo_rd <= '1';
252
                                                                shift_reg := sl(shift_reg,1);
253
                                                        else
254
                                                                -- Simple increment
255
                                                                pixel_cntr := pixel_cntr + 1;
256
                                                                fifo_rd <= '0';
257
                                                                shift_reg := sl(shift_reg,1);
258
                                                        end if;
259
                                                when "01" =>
260
                                                        -- shift next data to the output and optionally read the next data from the fifo
261
                                                        i_video_out(1 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-2);
262
                                                        i_video_out(7 downto 2) <= (others => '0');
263
                                                        if (pixel_cntr = v_mem_width/2-1) then
264
                                                                -- Read next data
265
                                                                pixel_cntr := 0;
266
                                                                shift_reg := fifo_out;
267
                                                                fifo_rd <= '0';
268
                                                        elsif (pixel_cntr = v_mem_width/2-2) then
269
                                                                -- Request next data from FIFO
270
                                                                pixel_cntr := pixel_cntr + 1;
271
                                                                fifo_rd <= '1';
272
                                                                shift_reg := sl(shift_reg,2);
273
                                                        else
274
                                                                -- Simple increment
275
                                                                pixel_cntr := pixel_cntr + 1;
276
                                                                fifo_rd <= '0';
277
                                                                shift_reg := sl(shift_reg,2);
278
                                                        end if;
279
                                                when "10" =>
280
                                                        -- shift next data to the output and optionally read the next data from the fifo
281
                                                        i_video_out(3 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-4);
282
                                                        i_video_out(7 downto 4) <= (others => '0');
283
                                                        if (pixel_cntr = v_mem_width/4-1) then
284
                                                                -- Read next data
285
                                                                pixel_cntr := 0;
286
                                                                shift_reg := fifo_out;
287
                                                                fifo_rd <= '0';
288
                                                        elsif (pixel_cntr = v_mem_width/4-2) then
289
                                                                -- Request next data from FIFO
290
                                                                pixel_cntr := pixel_cntr + 1;
291
                                                                fifo_rd <= '1';
292
                                                                shift_reg := sl(shift_reg,4);
293
                                                        else
294
                                                                -- Simple increment
295
                                                                pixel_cntr := pixel_cntr + 1;
296
                                                                fifo_rd <= '0';
297
                                                                shift_reg := sl(shift_reg,4);
298
                                                        end if;
299
                                                when "11" =>
300
                                                        if (v_mem_width = 8) then
301
                                                                -- 8 bit memory with 8 bit output: every clock reads a byte from the fifo.
302
                                                                fifo_rd <= '1';
303
                                                                i_video_out(7 downto 0) <= fifo_out;
304
                                                        else
305
                                                                -- shift next data to the output and optionally read the next data from the fifo
306
                                                                i_video_out(7 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-8);
307
                                                                if (pixel_cntr = v_mem_width/8-1) then
308
                                                                        -- Read next data
309
                                                                        pixel_cntr := 0;
310
                                                                        shift_reg := fifo_out;
311
                                                                        fifo_rd <= '0';
312
                                                                elsif (pixel_cntr = v_mem_width/8-2) then
313
                                                                        -- Request next data from FIFO
314
                                                                        pixel_cntr := pixel_cntr + 1;
315
                                                                        fifo_rd <= '1';
316
                                                                        shift_reg := sl(shift_reg,8);
317
                                                                else
318
                                                                        -- Simple increment
319
                                                                        pixel_cntr := pixel_cntr + 1;
320
                                                                        fifo_rd <= '0';
321
                                                                        shift_reg := sl(shift_reg,8);
322
                                                                end if;
323
                                                        end if;
324
                                                when others => -- Unsupported setting. Do nothing
325
                                                        i_video_out(7 downto 0) <= (others => '0');
326
                                                        fifo_rd <= '0';
327
                                                        pixel_cntr := 0;
328
                                        end case;
329
                                end if;
330
                        end if;
331
                end if;
332
        end if;
333
        end process;
334
 
335
        video_out <= i_video_out;
336
 
337
        -- Simple logic generates the high_prior output
338
        priority: process is
339
        begin
340
                wait on video_fifo_usedw,fifo_treshold,video_fifo_full;
341
                if (video_fifo_usedw < fifo_treshold and video_fifo_full = '0') then
342
                        high_prior <= '1';
343
                else
344
                        high_prior <= '0';
345
                end if;
346
        end process;
347
end mem_reader;

powered by: WebSVN 2.1.0

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