summaryrefslogtreecommitdiffstats
path: root/fpga/hp_lcd_driver/output_formatter.vhdl
blob: 1f9e89f7ba4be3fe9da63c0f6e2eeaaf79d426c0 (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
library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;



entity output_formatter is
    generic (addr_width    : natural := 17;
             h_front_porch : natural := 208;
             h_active      : natural := 384;
             h_sync_start  : natural := 400;
             h_sync_end    : natural := 440;
             h_total       : natural := 600;
             v_active      : natural := 592;
             v_sync_start  : natural := 593;
             v_sync_end    : natural := 596;
             v_total       : natural := 614;
             h_stride      : natural := 1;
             v_stride      : natural := 384
             );
    port (
        sys_rst_n : in  std_logic;
        clk       : in  std_logic;
        vsync_in  : in  std_logic;
        addr_out  : out std_logic_vector(addr_width -1 downto 0);
        blank_out : out std_logic;
        vsync_out : out std_logic;
        hsync_out : out std_logic;
        grid_out  : out std_logic
        );
end output_formatter;


architecture beh of output_formatter is

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

    signal vsync_in_ne : std_logic;

    signal h : natural;
    signal v : natural;

    signal blank  : std_logic;
    signal vblank : std_logic;
    signal vsync  : std_logic;
    signal hsync  : std_logic;
    signal grid  : std_logic;


begin

    vsync_ed : entity work.edge_det
        port map(
            clk => clk,
            sig => vsync_in,
            e   => open,
            pe  => open,
            ne  => vsync_in_ne);

    process (clk, vsync_in_ne, sys_rst_n)
    begin
        if sys_rst_n = '0' then
            h <= 0;
            v <= 0;
        elsif rising_edge(clk) then
            if h /= (h_total-1) then
                h <= h+1;
            else
                if v /= (v_total-1) then
                    v <= v+1;
                    h <= 0;
                else  --if vsync_in_ne = '1' then -- JMM if we synchronise the vsyncs then the display goes to sleep
                    h <= 0;
                    v <= 0;
                end if;
            end if;
        end if;
    end process;


    process (clk, h, h, sys_rst_n)
    begin
        if sys_rst_n = '0' then
            row_addr <= (others => '0');
            addr     <= (others => '0');
            blank    <= '1';
            vblank   <= '1';
            vsync    <= '0';
            hsync    <= '0';
	    grid <='0';
        elsif rising_edge(clk) then
            if h = 0 then
                if v = 0 then
                    row_addr <= std_logic_vector(to_unsigned(v_stride, row_addr'length));
                    addr     <= (others => '0');
                    --addr     <= std_logic_vector(to_unsigned(h_stride, addr'length));
                    blank    <= '0';
                    vblank   <= '0';
                elsif v = v_active  then
                    vblank <= '1';
                elsif v = v_sync_start then
                    vsync <= '1';
                elsif v = v_sync_end then
                    vsync <= '0';
                else
                    blank    <= vblank;
                    row_addr <= std_logic_vector(unsigned(row_addr)+v_stride);
		    addr <= row_addr;
                    --addr     <= std_logic_vector(unsigned(row_addr)+h_stride);
                end if;
            elsif h = h_active then
                blank <= '1';
            elsif h = h_sync_start then
                hsync <= '1';
            elsif h = h_sync_end then
                hsync <= '0';
            else
                addr <= std_logic_vector(unsigned(addr)+h_stride);
            end if;

    grid <= '1' when h  = 0 else
	'1' when h=10 else
	'1' when h=h_active-11 else
	'1' when h=h_active-1 else
        '1' when v=0 else
	'1' when v=10 else
	'1' when v=v_active-11 else
	'1' when v=v_active-1 else
	'0';

        end if;
    end process;



    addr_out  <= addr;
    blank_out <= blank;
    hsync_out <= hsync;
    vsync_out <= vsync;
    grid_out <= grid;

end beh;