1 ------------------------------------------------------------------------------
2 -- Copyright (C) 2011, Kenichi Kurimoto
4 -- This program is free software; you can redistribute it and/or modify
5 -- it under the terms of the GNU General Public License as published by
6 -- the Free Software Foundation; either version 2 of the License, or
7 -- (at your option) any later version.
9 -- This program is distributed in the hope that it will be useful,
10 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- GNU General Public License for more details.
14 -- You should have received a copy of the GNU General Public License
15 -- along with this program; if not, write to the Free Software
16 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -----------------------------------------------------------------------------
19 -- File: yccmemcont.vhd
20 -- Author: Kenichi Kurimoto
21 -- Description: YCbCr memory + controller
22 ------------------------------------------------------------------------------
25 use ieee.std_logic_1164.all;
26 use ieee.numeric_std.all;
31 use grlib.devices.all;
34 use techmap.gencomp.all;
38 memtech : integer := DEFMEMTECH);
42 kready1 : out std_logic;
43 kstrobe1 : in std_logic;
44 kdata1 : in std_logic_vector(7 downto 0);
45 kready2 : in std_logic;
46 kstrobe2 : out std_logic;
47 kdata2 : out std_logic_vector(23 downto 0);
48 samp_fact : in std_logic;
49 error : out std_logic;
50 startgen : in std_logic
53 -- samp_fact = 0 -> 4:1:1
54 -- samp_fact = 1 -> 4:2:2
56 architecture rtl of yccmemcont is
58 type sstate_type is (mem0, mem1);
59 type mstate_type is (empty, writing, full, reading, standby);
61 type control_reg is record
64 mem0state : mstate_type;
65 mem1state : mstate_type;
66 countf : std_logic_vector(8 downto 0);
67 -- selectf : std_logic_vector(1 downto 0);
68 countb : std_logic_vector(7 downto 0);
72 signal r, rin : control_reg;
73 signal y0address, y1address : std_logic_vector(7 downto 0);
74 signal cb0address, cb1address, cr0address, cr1address : std_logic_vector(6 downto 0);
75 signal y0datain, y1datain, cb0datain, cb1datain, cr0datain, cr1datain : std_logic_vector(7 downto 0);
76 signal y0dataout, y1dataout, cb0dataout, cb1dataout, cr0dataout, cr1dataout : std_logic_vector(7 downto 0);
77 signal y0enable, y1enable, cb0enable, cb1enable, cr0enable, cr1enable : std_logic;
78 signal y0write, y1write, cb0write, cb1write, cr0write, cr1write : std_logic;
81 yram0 : syncram generic map(tech => memtech, abits => 8, dbits => 8)
82 port map( clk, y0address, y0datain, y0dataout, y0enable, y0write);
83 yram1 : syncram generic map(tech => memtech, abits => 8, dbits => 8)
84 port map( clk, y1address, y1datain, y1dataout, y1enable, y1write);
85 cbram0 : syncram generic map(tech => memtech, abits => 7, dbits => 8)
86 port map( clk, cb0address, cb0datain, cb0dataout, cb0enable, cb0write);
87 cbram1 : syncram generic map(tech => memtech, abits => 7, dbits => 8)
88 port map( clk, cb1address, cb1datain, cb1dataout, cb1enable, cb1write);
89 crram0 : syncram generic map(tech => memtech, abits => 7, dbits => 8)
90 port map( clk, cr0address, cr0datain, cr0dataout, cr0enable, cr0write);
91 crram1 : syncram generic map(tech => memtech, abits => 7, dbits => 8)
92 port map( clk, cr1address, cr1datain, cr1dataout, cr1enable, cr1write);
95 comb : process (r, rst, kstrobe1, kdata1, kready2, samp_fact, y0dataout, y1dataout,
96 cb0dataout, cb1dataout, cr0dataout, cr1dataout, startgen)
97 variable v : control_reg;
98 variable vkready1 : std_logic;
99 variable verror : std_logic;
100 variable vy0address, vy1address : std_logic_vector(7 downto 0);
101 variable vcb0address, vcb1address, vcr0address, vcr1address : std_logic_vector(6 downto 0);
102 variable vy0enable, vy1enable, vcb0enable, vcb1enable, vcr0enable, vcr1enable : std_logic;
103 variable vy0write, vy1write, vcb0write, vcb1write, vcr0write, vcr1write : std_logic;
104 variable fcountup, bcountup : std_logic;
105 variable fcntint : integer;
106 variable vstrobe : std_logic;
107 variable outdata : std_logic_vector(23 downto 0);
112 vy0enable := '0'; vy1enable := '0'; vcb0enable := '0'; vcb1enable := '0'; vcr0enable := '0'; vcr1enable := '0';
113 vy0write := '0'; vy1write := '0'; vcb0write := '0'; vcb1write := '0'; vcr0write := '0'; vcr1write := '0';
114 fcountup := '0'; bcountup := '0';
115 vy0address := (others => '0'); vy1address := (others => '0');
116 vcb0address := (others => '0'); vcb1address := (others => '0');
117 vcr0address := (others => '0'); vcr1address := (others => '0');
120 fcntint := to_integer(unsigned(r.countf));
121 if (kstrobe1 = '1') then
122 if ((r.swf = mem0 and (r.mem0state = full or r.mem0state = reading))or
123 (r.swf = mem1 and (r.mem1state = full or r.mem1state = reading)))then
127 if(r.swf = mem0) then
128 if(samp_fact = '0') then
129 if(fcntint < 256) then
132 vy0address := r.countf(7 downto 0);
133 elsif(fcntint < 320) then
136 vcb0address := r.countf(6 downto 0);
137 elsif(fcntint < 384) then
140 vcr0address := '0' & r.countf(5 downto 0);
145 if(fcntint < 256) then
148 vy0address := r.countf(7 downto 0);
149 elsif(fcntint < 384) then
152 vcb0address := r.countf(6 downto 0);
153 elsif(fcntint < 512) then
156 vcr0address := r.countf(6 downto 0);
162 if(samp_fact = '0') then
163 if(fcntint < 256) then
166 vy1address := r.countf(7 downto 0);
167 elsif(fcntint < 320) then
170 vcb1address := r.countf(6 downto 0);
171 elsif(fcntint < 384) then
174 vcr1address := '0' & r.countf(5 downto 0);
179 if(fcntint < 256) then
182 vy1address := r.countf(7 downto 0);
183 elsif(fcntint < 384) then
186 vcb1address := r.countf(6 downto 0);
187 elsif(fcntint < 512) then
190 vcr1address := r.countf(6 downto 0);
199 if (r.swf = mem0 and (r.mem0state = empty or r.mem0state = writing)) or (r.swf = mem1 and (r.mem1state = empty or r.mem1state = writing)) then
205 if (kready2 = '1') then
206 if(r.swb = mem0 and (r.mem0state = full or r.mem0state = reading)) then
212 vy0address := r.countb(7) & r.countb(3) & r.countb(6 downto 4) & r.countb(2 downto 0);
213 if(samp_fact = '0') then
214 vcb0address := '0' & r.countb(7 downto 5) & r.countb(3 downto 1);
215 vcr0address := '0' & r.countb(7 downto 5) & r.countb(3 downto 1);
217 vcb0address := r.countb(7 downto 1);
218 vcr0address := r.countb(7 downto 1);
220 elsif(r.swb = mem1 and (r.mem1state = full or r.mem1state = reading))then
226 vy1address := r.countb(7) & r.countb(3) & r.countb(6 downto 4) & r.countb(2 downto 0);
227 if(samp_fact = '0') then
228 vcb1address := '0' & r.countb(7 downto 5) & r.countb(3 downto 1);
229 vcr1address := '0' & r.countb(7 downto 5) & r.countb(3 downto 1);
231 vcb1address := r.countb(7 downto 1);
232 vcr1address := r.countb(7 downto 1);
238 outdata := y0dataout & cb0dataout & cr0dataout;
240 outdata := y1dataout & cb1dataout & cr1dataout;
245 --check empty case batting memory read write access
250 if (r.swf = mem0 and fcountup = '1') then
251 v.mem0state := writing;
254 if ((samp_fact = '0' and fcntint = 383 and fcountup = '1')or(samp_fact = '1' and fcntint = 511 and fcountup = '1')) then
259 if (r.swb = mem0 and kready2 = '1') then
260 v.mem0state := reading;
263 if (r.countb = "11111111") then
264 v.mem0state := standby;
268 v.mem0state := empty;
274 if (r.swf = mem1 and fcountup = '1') then
275 v.mem1state := writing;
278 if ((samp_fact = '0' and fcntint = 383 and fcountup = '1')or(samp_fact = '1' and fcntint = 511 and fcountup = '1')) then
283 if (r.swb = mem1 and kready2 = '1') then
284 v.mem1state := reading;
287 if (r.countb = "11111111") then
288 v.mem1state := standby;
292 v.mem1state := empty;
297 if(fcountup = '1') then
298 v.countf := r.countf + '1';
299 if (samp_fact = '0') and (fcntint = 383) then
300 v.countf := "000000000";
301 elsif (samp_fact = '1') and (fcntint = 511) then
302 v.countf := "000000000";
305 if (bcountup = '1') then
306 v.countb := r.countb + '1';
310 if rst = '0' or startgen = '1' then
313 v.mem0state := empty;
314 v.mem1state := empty;
315 v.countf := (others => '0');
316 v.countb := (others => '0');
324 kstrobe2 <= r.stb2keep;
327 y0address <= vy0address;
328 y1address <= vy1address;
329 cb0address <= vcb0address;
330 cb1address <= vcb1address;
331 cr0address <= vcr0address;
332 cr1address <= vcr1address;
333 y0enable <= vy0enable;
334 y1enable <= vy1enable;
335 cb0enable <= vcb0enable;
336 cb1enable <= vcb1enable;
337 cr0enable <= vcr0enable;
338 cr1enable <= vcr1enable;
341 cb0write <= vcb0write;
342 cb1write <= vcb1write;
343 cr0write <= vcr0write;
344 cr1write <= vcr1write;
358 if rising_edge(clk) then