OSDN Git Service

works
[fpga-leon-mjpeg/leon-mjpeg.git] / grlib-gpl-1.0.22-b4095 / lib / kuri / mjpeg / yccrgb.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library grlib;
6 use grlib.amba.all;
7 use grlib.stdlib.all;
8 use grlib.devices.all;
9
10 library techmap;
11 use techmap.gencomp.all;
12
13 entity yccrgb is
14    generic (
15       memtech : integer := DEFMEMTECH;
16       hirq   : integer := 0;       
17       mhindex : integer := 0;
18       chprot : integer := 3);
19    port (
20       rst   : in std_ulogic;
21       clk   : in std_ulogic;
22       ahbmi : in ahb_mst_in_type;
23       ahbmo : out ahb_mst_out_type;
24       kready  : out std_logic;
25       kstrobe : in std_logic;
26       kdata   : in std_logic_vector(23 downto 0);
27       xmcumax : in std_logic_vector(5 downto 0);
28       ymcumax : in std_logic_vector(4 downto 0);
29       incaddy  : in std_logic_vector(15 downto 0);
30       incaddmcux : in std_logic_vector(15 downto 0);
31       incaddmcuy : in std_logic_vector(10 downto 0);
32       fbstartadd : in std_logic_vector(31 downto 0);
33       startgen   : in std_logic
34    );
35 end;
36
37 architecture rtl of yccrgb is
38
39
40 constant mhconfig : ahb_config_type := (
41  0 => ahb_device_reg( VENDOR_CONTRIB, CONTRIB_CORE1, 0, 0, 0),
42  others => zero32);
43  
44 constant fdepth : integer :=256;
45           
46 function mysigned_mul(a,b : std_logic_vector) return std_logic_vector is
47 variable z : std_logic_vector(a'length + b'length -1 downto 0);
48 begin
49     z := std_logic_vector(signed(a) * signed(b));
50     return(z);
51 end;
52
53 function mysigned_mul2(b,a : std_logic_vector) return std_logic_vector is
54 variable sum : std_logic_vector(15 downto 0);
55 variable p0 : std_logic_vector(15 downto 0);
56 variable p1 : std_logic_vector(15 downto 0);
57 variable p2 : std_logic_vector(15 downto 0);
58 variable p3 : std_logic_vector(15 downto 0);
59 variable p4 : std_logic_vector(15 downto 0);
60 variable p5 : std_logic_vector(15 downto 0);
61 variable p6 : std_logic_vector(15 downto 0);
62 variable p7 : std_logic_vector(15 downto 0);
63 variable p_plus : std_logic_vector(15 downto 0);
64 begin
65     p0 := "00000001" & not(a(7) and b(0)) & (a(6) and b(0))& (a(5) and b(0)) & (a(4) and b(0))
66            & (a(3) and b(0)) & (a(2) and b(0))& (a(1) and b(0)) & (a(0) and b(0));
67     p1 := "0000000" & not(a(7) and b(1)) & (a(6) and b(1))& (a(5) and b(1)) & (a(4) and b(1))
68           & (a(3) and b(1)) & (a(2) and b(1))& (a(1) and b(1)) & (a(0) and b(1)) & '0';           
69     p2 := "000000" & not(a(7) and b(2)) & (a(6) and b(2))& (a(5) and b(2)) & (a(4) and b(2))
70           & (a(3) and b(2)) & (a(2) and b(2))& (a(1) and b(2)) & (a(0) and b(2)) & "00";
71     p3 := "00000" & not(a(7) and b(3)) & (a(6) and b(3))& (a(5) and b(3)) & (a(4) and b(3))
72           & (a(3) and b(3)) & (a(2) and b(3))& (a(1) and b(3)) & (a(0) and b(3)) & "000";
73     p4 := "0000" & not(a(7) and b(4)) & (a(6) and b(4))& (a(5) and b(4)) & (a(4) and b(4))
74           & (a(3) and b(4)) & (a(2) and b(4))& (a(1) and b(4)) & (a(0) and b(4)) & "0000";    
75     p5 := "000" & not(a(7) and b(5)) & (a(6) and b(5))& (a(5) and b(5)) & (a(4) and b(5))
76           & (a(3) and b(5)) & (a(2) and b(5))& (a(1) and b(5)) & (a(0) and b(5)) & "00000";    
77     p6 := "00" & not(a(7) and b(6)) & (a(6) and b(6))& (a(5) and b(6)) & (a(4) and b(6))
78           & (a(3) and b(6)) & (a(2) and b(6))& (a(1) and b(6)) & (a(0) and b(6)) & "000000";          
79     p7 := '1' & (a(7) and b(7)) & not(a(6) and b(7))& not(a(5) and b(7)) & not(a(4) and b(7))
80           & not(a(3) and b(7)) & not(a(2) and b(7))& not(a(1) and b(7)) & not(a(0) and b(7)) 
81           & "0000000";
82     sum := std_logic_vector((unsigned(p0) + unsigned(p1)) + (unsigned(p2) + unsigned(p3)) + (unsigned(p4) 
83           + unsigned(p5)) + (unsigned(p6) + unsigned(p7)));
84     return(sum);
85 end;  
86
87 function mysigned_add(a,b : std_logic_vector) return std_logic_vector is
88 variable ex_a : std_logic_vector(a'length downto 0);
89 variable ex_b : std_logic_vector(b'length downto 0);
90 variable z1 : std_logic_vector(a'length downto 0);
91 variable z2 : std_logic_vector(b'length downto 0);
92 begin
93     ex_a := a(a'left) & a;
94     ex_b := b(b'left) & b;
95     if( a'length > b'length)then
96        z1 := std_logic_vector(signed(ex_a) + signed(ex_b));
97        return(z1);
98     else
99        z2 := std_logic_vector(signed(ex_a) + signed(ex_b));
100        return(z2);
101     end if;
102 end;
103
104 type fstate_type is (ready, stuck);
105 type mstate_type is (idle, busreq, grant, nonseq, seq);
106
107 type control_reg is record
108    ycc    : std_logic_vector(23 downto 0);
109    written : std_ulogic;
110    fifo_state : fstate_type;
111    fifo_rp : std_logic_vector(7 downto 0);
112    fifo_wp : std_logic_vector(7 downto 0);
113    gen_add : std_logic_vector(31 downto 0);
114    temp_data : std_logic_vector(15 downto 0);
115    mstate : mstate_type;
116    yxpoint : std_logic_vector( 6 downto 0);
117    xmcu : std_logic_vector(5 downto 0);
118    ymcu : std_logic_vector(4 downto 0);
119    keep_data : std_logic_vector(31 downto 0);
120    dhready : std_logic;
121 end record;
122
123 signal r, rin : control_reg;
124 signal read_en_fifo, write_en_fifo : std_logic;
125 signal read_pointer_fifo : std_logic_vector(7 downto 0);
126 signal write_pointer_fifo : std_logic_vector(7 downto 0);
127 signal data_out_fifo : std_logic_vector(31 downto 0);
128 signal data_in_fifo : std_logic_vector(31 downto 0);
129
130 begin
131 ram0 : syncram_2p generic map(tech => memtech, abits => 8, dbits => 32, sepclk => 0)
132             port map( clk, read_en_fifo, read_pointer_fifo, data_out_fifo,
133                 clk, write_en_fifo, write_pointer_fifo, data_in_fifo);
134
135 comb : process (r, rst, ahbmi, kstrobe, kdata, xmcumax, ymcumax, incaddmcuy, fbstartadd, startgen, data_out_fifo)
136       variable v : control_reg;
137       variable virq : std_logic_vector(NAHBIRQ-1 downto 0);
138       variable vsready : std_logic;
139       variable fifo_write : std_logic;
140       variable fifo_read :std_logic;
141       variable write_point : integer;
142       variable read_point : integer;
143       variable num_ele : integer;
144       variable mhtrans : std_logic_vector(1 downto 0);
145       variable mhbusreq : std_ulogic;
146       variable mhprot : std_logic_vector(3 downto 0);
147       variable add_inc : std_logic;
148       variable vmhwdata : std_logic_vector(31 downto 0);
149       variable incval : std_logic_vector(15 downto 0);
150       variable refresh : std_logic;
151       variable rout : std_logic_vector(4 downto 0);
152       variable gout : std_logic_vector(5 downto 0);
153       variable bout : std_logic_vector(4 downto 0);     
154       variable node1 : std_logic_vector(9 downto 0);
155       variable node2 : std_logic_vector(9 downto 0);
156       variable node3 : std_logic_vector(15 downto 0);
157       variable node4 : std_logic_vector(15 downto 0);
158       variable node5 : std_logic_vector(15 downto 0);
159       variable node6 : std_logic_vector(15 downto 0);
160       variable node7 : std_logic_vector(9 downto 0);
161       variable node8 : std_logic_vector(8 downto 0);
162       variable node9 : std_logic_vector(9 downto 0);
163       variable node10 : std_logic_vector(9 downto 0);     
164       constant c_01011010 : std_logic_vector(7 downto 0) := "01011010";
165       constant c_11101010 : std_logic_vector(7 downto 0) := "11101010";
166       constant c_11010010 : std_logic_vector(7 downto 0) := "11010010";
167       constant c_01110001 : std_logic_vector(7 downto 0) := "01110001";      
168     begin
169
170    v := r;
171    virq := (others => '0');
172    mhprot := conv_std_logic_vector(chprot,4);
173    v.written := '0';
174    fifo_write := '0';
175    vsready := '1';
176    mhbusreq := '0';
177    mhtrans := HTRANS_IDLE;
178       
179    if kstrobe = '1' then
180         v.ycc(23 downto 0) := kdata;
181         v.written := '1';            
182    end if;
183
184 -- register write   
185       node1 := mysigned_add(('0' & r.ycc(15 downto 8)), "110000000");
186       node2 := mysigned_add(('0' & r.ycc(7 downto 0)), "110000000");
187       node3 := mysigned_mul2(c_01011010, node2(7 downto 0));
188       node4 := mysigned_mul2(c_11101010, node1(7 downto 0));
189       node5 := mysigned_mul2(c_11010010, node2(7 downto 0));
190       node6 := mysigned_mul2(c_01110001, node1(7 downto 0));
191       node7 := mysigned_add(('0' & r.ycc(23 downto 16)), (node3(14 downto 7) & '0'));
192       node8 := mysigned_add((node4(13 downto 7) & '0'), (node5(13 downto 7) & '0'));
193       node9 := mysigned_add(('0' & r.ycc(23 downto 16)), ( node6(14 downto 7) & '0'));
194       node10 := mysigned_add(('0' & r.ycc(23 downto 16)), node8);
195       if(node7(9) = '1') then
196          rout := "00000";
197       elsif(node7(8) = '1') then
198          rout := "11111";
199       else
200          rout := node7(7 downto 3);
201       end if;
202      
203       if(node10(9) = '1') then
204          gout := "000000";
205       elsif(node10(8) = '1') then
206          gout := "111111";
207       else
208          gout := node10(7 downto 2);
209       end if;
210       
211       if(node9(9) = '1') then
212          bout := "00000";
213       elsif(node9(8) = '1') then
214          bout := "11111";
215       else
216          bout := node9(7 downto 3);
217       end if;
218
219 -- Fifo part
220    write_point := to_integer(unsigned(r.fifo_wp));
221    read_point := to_integer(unsigned(r.fifo_rp));
222    if write_point >= read_point then
223        num_ele := write_point - read_point;
224    else
225        num_ele := fdepth - read_point + write_point;
226    end if;
227    if num_ele > fdepth/2 then
228        vsready := '0';
229    end if;
230    if (num_ele = fdepth/2) and ( r.written = '1' or r.fifo_state = stuck) then
231        vsready := '0';
232    end if;
233    
234    case r.fifo_state is
235    when ready =>
236       if r.written = '1' then
237          v.temp_data := rout & gout & bout;
238          v.fifo_state := stuck;
239       end if;
240    when stuck =>
241       if r.written = '1' then
242          fifo_write := '1';
243          write_point := write_point + 1;
244          if write_point = fdepth then
245             write_point := 0;
246          end if;
247          v.fifo_state := ready;
248       end if;
249    end case; 
250       
251    data_in_fifo <= r.temp_data & rout & gout & bout; 
252    write_en_fifo <= fifo_write;
253    v.fifo_wp := std_logic_vector(to_unsigned(write_point,8));
254
255 -- AHB master part
256    fifo_read := '0';
257    add_inc := '0';
258
259    case r.mstate is
260    when idle =>
261        mhbusreq := '0';
262        mhtrans := HTRANS_IDLE;
263        if (num_ele >= 8) then
264            v.mstate := busreq;
265        end if;
266    when busreq =>
267        mhbusreq := '1';
268        mhtrans := HTRANS_NONSEQ;
269        if  (ahbmi.hready = '1') and (ahbmi.hgrant(mhindex) = '1') then
270            v.mstate := nonseq;
271        end if;
272    when nonseq =>
273        mhbusreq := '1';
274        mhtrans := HTRANS_NONSEQ;
275        if ahbmi.hready = '1' then
276            fifo_read := '1';
277            add_inc := '1';
278            v.mstate := seq;
279        end if;
280    when seq =>
281        mhbusreq := '1';
282        mhtrans := HTRANS_SEQ;
283        if ahbmi.hready = '1' then
284            fifo_read := '1';
285            add_inc := '1';
286            if (r.yxpoint(2 downto 0) = "111") then
287                v.mstate := idle;
288            end if;
289        end if;
290    when others =>
291    end case;
292    
293    
294    refresh := '0';
295    incval := (others => '0');
296    if add_inc = '1' then
297    v.yxpoint := r.yxpoint + '1';
298        if r.yxpoint(2 downto 0) /= "111" then
299           incval := "0000000000000100";
300        else 
301           if r.yxpoint(6 downto 3) /= "1111" then
302              incval := incaddy;
303           else 
304              v.xmcu := r.xmcu + '1';
305              if r.xmcu /= xmcumax then
306                 incval := incaddmcux;
307              else   
308                 v.xmcu := "000000";
309                 v.ymcu := r.ymcu + '1';
310                 if r.ymcu /= ymcumax then
311                    incval := "00000" & incaddmcuy;
312                 else
313                    v.ymcu := "00000";
314                    refresh := '1';
315                 end if;
316              end if;
317           end if;
318        end if;
319    end if;
320   
321    if refresh = '1' then
322        v.gen_add := fbstartadd;
323    else
324        v.gen_add := std_logic_vector(signed(r.gen_add) + signed(incval));
325    end if;
326
327    if fifo_read = '1' then
328       read_point := read_point + 1;
329       if read_point = fdepth then
330           read_point := 0;
331       end if;
332    end if;
333    v.fifo_rp :=  std_logic_vector(to_unsigned(read_point,8));
334    
335 -- for the hready assert
336    v.dhready := ahbmi.hready;
337    if  (ahbmi.hready = '1') or (ahbmi.hgrant(mhindex) = '0') then
338       v.keep_data := data_out_fifo;
339    end if;
340    if (r.dhready = '0') and (ahbmi.hgrant(mhindex) = '1') then
341       vmhwdata := r.keep_data;
342    else
343       vmhwdata := data_out_fifo;
344    end if; 
345
346 -- soft reset
347    if startgen = '1' then
348          v.gen_add := fbstartadd;
349          v.written := '0';
350          v.fifo_state := ready;
351          v.fifo_rp := (others => '0');
352          v.fifo_wp := (others => '0');
353          v.mstate := idle;
354          v.yxpoint := (others => '0');
355          v.xmcu := (others => '0');
356          v.ymcu := (others => '0');
357    end if;      
358 -- reset part
359    if rst = '0' then
360          v.ycc := (others => '0');
361          v.written := '0';
362          v.fifo_state := ready;
363          v.fifo_rp := (others => '0');
364          v.fifo_wp := (others => '0');
365          v.mstate := idle;
366          v.yxpoint := (others => '0');
367          v.xmcu := (others => '0');
368          v.ymcu := (others => '0');  
369          v.temp_data := (others => '0');
370          v.gen_add := (others => '0'); 
371    end if;
372    
373 -- signal
374    rin <= v;   
375    kready <= vsready;
376    read_en_fifo <= '1';
377    write_pointer_fifo <= r.fifo_wp(7 downto 0);
378    read_pointer_fifo <= r.fifo_rp(7 downto 0);
379    ahbmo.haddr <= r.gen_add;
380    ahbmo.htrans <= mhtrans;
381    ahbmo.hbusreq <= mhbusreq;
382    ahbmo.hprot <= mhprot;
383    ahbmo.hwdata <= vmhwdata; 
384    
385
386 end process;
387
388    ahbmo.hconfig <= mhconfig;
389    ahbmo.hlock <= '0';
390    ahbmo.hwrite <= '1';
391    ahbmo.hsize <= "010";
392    ahbmo.hburst <= HBURST_INCR;   
393    ahbmo.hirq <= (others => '0');
394    ahbmo.hindex <= mhindex;
395
396    
397 -- registers 
398 reg : process(clk)
399 begin
400    if rising_edge(clk) then
401         r <= rin;
402    end if;
403 end process;
404
405
406 end;
407