summaryrefslogtreecommitdiffstats
path: root/fpga/hp_lcd_driver/input_formatter.vhdl
blob: f8b27c2c7b5ce7690aa65a1ff19edbb2d9b74567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;



entity input_formatter is
    generic (
        addr_width    : natural := 17;
        clk_multiple  : natural := 4;
        phase         : natural := 2;
        h_front_porch : natural := 208;
        h_active      : natural := 592;
        v_front_porch : natural := 2;
        v_active      : natural := 384;
        frame_start   : natural := 0;
        h_stride      : natural := 384;
        v_stride      : natural := 1;
        phase_slip    : natural := 320;
        use_pclk      : natural := 0
        );
    port
        (
            sys_rst_n : in  std_logic;
            clk       : in  std_logic;
            hsync     : in  std_logic;
            vsync     : in  std_logic;
            pclk      : in  std_logic;
            addr_out  : out std_logic_vector(addr_width-1 downto 0);
            wren_out  : out std_logic;
            h_grid    : out std_logic;
            v_grid    : out std_logic
            );

end input_formatter;


architecture beh of input_formatter is

    signal row_addr : std_logic_vector(addr_width-1 downto 0);
    signal addr     : std_logic_vector(addr_width-1 downto 0);
    signal wren     : std_logic;

    signal pclk_ne : std_logic;
    signal pclk_pe : std_logic;

    signal hsync_ne : std_logic;
    signal hsync_pe : std_logic;

    signal v_fp_counter     : natural;
    signal v_active_counter : natural;
    signal h_fp_counter     : natural;
    signal h_active_counter : natural;

    signal h_div       : natural;
    signal phase_accum : natural;


begin


    hsync_ed : entity work.edge_det
        port map(
            clk => clk,
            sig => hsync,
            e   => open,
            ne  => hsync_ne,
            pe  => hsync_pe);


    pclk_ed : entity work.edge_det
        port map(
            clk => clk,
            sig => pclk,
            ne  => pclk_ne,
            pe  => pclk_pe);




    addr_out <= addr;


    process (sys_rst_n, clk, hsync_pe, vsync)
    begin
        if sys_rst_n = '0' then
            row_addr         <= (others => '0');
            addr             <= (others => '0');
            h_div            <= 0;
            h_active_counter <= 0;
            h_fp_counter     <= 0;
            v_active_counter <= 0;
            v_fp_counter     <= 0;
            phase_accum      <= phase_slip;
        elsif rising_edge(clk) then
            if hsync_pe = '1' then
                --if v_active_counter = 0 and v_fp_counter=0 then
                if vsync = '1' then
                    row_addr         <= std_logic_vector(to_unsigned(frame_start, addr_width));
                    v_fp_counter     <= v_front_porch;
                    v_active_counter <= v_active;
                elsif v_fp_counter /= 0 then
                    v_fp_counter <= v_fp_counter -1;
                elsif v_active_counter /= 0 then
                    v_active_counter <= v_active_counter -1;

                    h_fp_counter     <= h_front_porch * clk_multiple + phase;
                    h_active_counter <= h_active;
                    phase_accum      <= phase_slip;
                    h_div            <= 0;

                    addr     <= row_addr;
                    row_addr <= std_logic_vector(unsigned(row_addr)+v_stride);
                end if;
            elsif h_fp_counter /= 0 then
                h_fp_counter <= h_fp_counter -1;
            elsif h_active_counter /= 0 then

                if use_pclk = 0 then
                    if h_div = 0 then
                        wren <= '1';
                        if phase_accum = 0 then
                            phase_accum <= phase_slip;
                            h_div       <= clk_multiple;
                        else
                            phase_accum <= phase_accum-1;
                            h_div       <= clk_multiple-1;
                        end if;
                    else
                        h_div <= h_div -1;
                        wren  <= '0';
                    end if;
                else
		    wren <= pclk_ne;
                end if;

                if wren = '1' then
                    h_active_counter <= h_active_counter -1;
                    addr             <= std_logic_vector(unsigned(addr)+h_stride);
                end if;
            end if;
        end if;
    end process;

    addr_out <= addr;
    wren_out <= wren;


    h_grid <= '1' when ((h_active_counter mod 16) = (h_active mod 16)) or (h_Active_counter = 1)
--    h_grid <= '1' when (h_active_counter=h_active) or (h_active_counter=h_active-2)
else '0';

    v_grid <= '1' when ((v_active_counter mod 16) = (v_active mod 16)) or (v_active_counter = 1)
              else '0';


end beh;