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

Subversion Repositories wb_vga

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

powered by: WebSVN 2.1.0

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