summaryrefslogtreecommitdiffstats
path: root/fpga/hp_lcd_driver/common.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/hp_lcd_driver/common.vhdl')
-rw-r--r--fpga/hp_lcd_driver/common.vhdl381
1 files changed, 381 insertions, 0 deletions
diff --git a/fpga/hp_lcd_driver/common.vhdl b/fpga/hp_lcd_driver/common.vhdl
new file mode 100644
index 0000000..7275184
--- /dev/null
+++ b/fpga/hp_lcd_driver/common.vhdl
@@ -0,0 +1,381 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+use work.all;
+
+-- on the cyclone iv
+-- i_clk/4 = 19.676158
+-- the scope's pixel clock is 19.66080
+-- (p-0.25)*19.66080 = p * 19.676158
+--p=1/[4*(1-(19.676158/19.66080))]=320.04
+
+
+entity common is
+ generic (input_video_width : natural := 2;
+ video_width : natural := 2;
+ addr_width : natural := 18;
+ phase_slip : natural := 320;
+ i_clk_multiple : natural := 4;
+ use_pclk : natural := 0;
+ target : string := "artix7");
+ port (clk_50m : in std_logic;
+ sys_rst_n : in std_logic;
+ video : in std_logic_vector(input_video_width -1 downto 0);
+ hsync_in : in std_logic;
+ vsync_in : in std_logic;
+ pclk_in : in std_logic;
+ r_out : out std_logic;
+ b_out : out std_logic;
+ g_out : out std_logic;
+ hsync_out : out std_logic;
+ vsync_out : out std_logic;
+ hdmi_c_p : out std_logic;
+ hdmi_c_n : out std_logic;
+ hdmi_r_p : out std_logic;
+ hdmi_r_n : out std_logic;
+ hdmi_g_p : out std_logic;
+ hdmi_g_n : out std_logic;
+ hdmi_b_p : out std_logic;
+ hdmi_b_n : out std_logic;
+ hdmi_vcc : out std_logic;
+ i_clk_out : out std_logic;
+ led : out std_logic;
+ video_out_data : out std_logic_vector(video_width-1 downto 0);
+ video_out_valid : out std_logic;
+ video_out_clk : out std_logic;
+ video_out_index : out std_logic
+ );
+
+end common;
+
+architecture Behavioral of common is
+
+ signal video_lut : std_logic_vector (video_width-1 downto 0);
+ signal wr_addr : std_logic_vector(addr_width-1 downto 0);
+ signal wr_data : std_logic_vector(video_width-1 downto 0);
+ signal wr_data_b : std_logic_vector(video_width-1 downto 0);
+ signal wr_en : std_logic;
+
+ signal rd_addr : std_logic_vector(addr_width-1 downto 0);
+ signal rd_data : std_logic_vector(video_width-1 downto 0);
+
+ signal r : std_logic_vector(7 downto 0);
+ signal g : std_logic_vector(7 downto 0);
+ signal b : std_logic_vector(7 downto 0);
+
+
+ signal clk_locked : std_logic;
+
+ signal i_clk : std_logic;
+
+ signal o_clk : std_logic;
+ signal o_clk_x2 : std_logic;
+ signal o_clk_phy : std_logic;
+ signal sys_rst : std_logic;
+
+ signal pa : natural;
+ signal epk : std_logic;
+ signal ic : natural;
+
+
+ signal h : natural;
+ signal v : natural;
+
+
+ signal c : natural;
+ signal t : std_logic;
+
+ signal wr_index : std_logic;
+
+begin
+
+
+-- clocking:
+-- i_clk is 4*(nominal) 20MHz to give us 4 choices of sampling position
+-- o_clk is the output pixel clock
+-- o_clk_x2 is used by the spartan serdes
+-- o_clk_phy is used the the hdmi phy (cylone4 it's o_clk x5, spartan 6 it's o_clk x 10)
+
+ clkgen : entity work.clkgen
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk_in => clk_50m,
+ i_clk => i_clk,
+ o_clk => o_clk,
+ o_clk_x2 => o_clk_x2,
+ o_clk_phy => o_clk_phy,
+ locked => clk_locked
+ );
+
+
+ video_lut <= "1111" when video(0) = '1' else
+ "1011" when video(1) = '1' else
+ "1100" when video(2) = '1' else
+ "1010" when video(3) = '1' else
+ "0011" when video(4) = '1' else
+ "1110" when video(5) = '1' else
+ "1001" when video(6) = '1' else
+ "1101" when video(7) = '1' else
+ "0000";
+
+ hdmi_vcc <= '1';
+
+
+ process (i_clk, sys_rst_n)
+ begin
+ if sys_rst_n = '0' then
+ ic <= 0;
+ pa <= phase_slip;
+ epk <= '0';
+ elsif rising_edge(i_clk) then
+
+ if ic = 0 then
+ epk <= '1';
+ if pa = 0 then
+ pa <= phase_slip;
+ ic <= i_clk_multiple;
+ else
+ ic <= i_clk_multiple-1;
+ pa <= pa -1;
+ end if;
+ else
+ if epk = '1' then
+ epk <= '0';
+ end if;
+ ic <= ic-1;
+ end if;
+ end if;
+ end process;
+
+
+ i_clk_out <= epk;
+
+
+ input0 : entity work.input_stage
+ generic map(
+ video_width => video_width,
+ addr_width => addr_width,
+ clk_multiple => i_clk_multiple,
+-- HP54502A
+-- phase => 1,
+-- h_front_porch => 200,
+-- h_active => 592,
+-- v_front_porch => 1,
+-- v_active => 384,
+-- frame_start => 383,
+-- h_stride => 384,
+-- v_stride => 262143,
+-- HP54522A
+ phase => 1,
+ h_front_porch => 190,
+ h_active => 640,
+ v_front_porch => 22,
+ v_active => 384,
+ frame_start => 383,
+ h_stride => 384,
+ v_stride => 524287,
+ phase_slip => phase_slip,
+ use_pclk => use_pclk
+ )
+ port map (
+ sys_rst_n => sys_rst_n,
+ clk => i_clk,
+ video_in => video_lut,
+ pclk_in => pclk_in,
+ hsync_in => not hsync_in,
+ vsync_in => not vsync_in,
+
+ video_out => wr_data,
+ addr_out => wr_addr,
+ wren_out => wr_en,
+ index_out => wr_index
+ );
+
+ video_out_data <= wr_data;
+ video_out_valid <= wr_en;
+ video_out_index <= wr_index;
+ video_out_clk <= i_clk;
+
+
+
+--
+-- process (i_clk) begin
+-- if sys_rst_n='0' then
+-- h<=0;
+-- v<=0;
+-- wr_addr <=(others =>'0');
+-- elsif rising_edge(i_clk) then
+-- if h /= 383 then
+-- h<=h+1;
+-- wr_addr <= std_logic_vector(unsigned(wr_addr)+1);
+-- else
+-- h<=0;
+-- if v /= 591 then
+-- v<=v+1;
+-- wr_addr <= std_logic_vector(unsigned(wr_addr)+1);
+-- else
+-- v<=0;
+-- wr_addr <=(others =>'0');
+-- end if;
+-- end if;
+-- end if;
+-- end process;
+--
+-- wr_en <= '1';
+--
+-- wr_data <="01" when (h=0) or (h=383) or (v=0) or (v=591)
+-- else "00";
+--
+
+ vram0 : entity work.vram
+ generic map (
+ video_width => video_width,
+ addr_width => addr_width
+ )
+ port map (
+ wr_clk => i_clk,
+ wr_en => wr_en,
+ wr_addr => wr_addr,
+ wr_data => wr_data,
+ rd_clk => o_clk,
+ rd_addr => rd_addr,
+ rd_data => rd_data
+ );
+
+
+
+-- r<=x"00";
+-- b<=x"00";
+
+
+
+
+ r <= x"ff" when rd_data(0) = '1' else
+ x"00";
+
+-- r<=x"ff" when rd_data(0)='1' and rd_data(3)='1' else
+-- x"80" when rd_data(0)='1' else
+-- x"00";
+
+ g <= x"ff" when rd_data(1) = '1' and rd_data(3) = '1' else
+ x"80" when rd_data(1) = '1' else
+ x"00";
+ b <= x"ff" when rd_data(2) = '1' and rd_data(3) = '1' else
+ x"80" when rd_data(2) = '1' else
+ x"00";
+
+
+
+--"ff" when rd_data(1) = '1' else
+-- x"80" when rd_data(0) = '1' else
+-- ix"00";
+
+
+
+
+ output0 : entity work.output_stage
+
+-- didn't work for me from this thing, only from mac, works at 60Hz xrandr --newmode "$M" 18.24 384 400 440 600 592 593 596 613 -HSync +Vsync
+-- Modeline "384x592_80.00" 25.40 384 408 448 512 592 593 596 620 -HSync +Vsync
+
+ generic map (
+ target => target,
+ addr_width => addr_width,
+-- h_active => 384,
+-- h_sync_start => 400,
+-- h_sync_end => 440,
+-- h_total => 640,
+-- v_active => 592,
+-- v_sync_start => 593,
+-- v_sync_end => 596,
+-- v_total => 613,
+-- h_stride => 1,
+-- v_stride => 384
+
+-- HP54502A
+-- h_active => 384,
+-- h_sync_start => 400,
+-- h_sync_end => 440,
+-- h_total => 660,
+-- v_active => 592,
+-- v_sync_start => 593,
+-- v_sync_end => 596,
+-- v_total => 613,
+-- h_stride => 1,
+-- v_stride => 384
+
+-- HP54522A
+ h_active => 384,
+ h_sync_start => 400,
+ h_sync_end => 456,
+ h_total => 660,
+-- h_active => 417,
+-- h_sync_start => 440,
+-- h_sync_end => 480,
+-- h_total => 660,
+ v_active => 640,
+ v_sync_start => 641,
+ v_sync_end => 644,
+ v_total => 650,
+ h_stride => 1,
+ v_stride => 384
+
+-- h_active => 640,
+-- h_sync_start=>656,
+-- h_sync_end =>752,
+-- h_total=>800,
+--
+-- v_active =>480,
+-- v_sync_start=>490,
+-- v_sync_end=>492,
+-- v_total=>525,
+-- h_stride=>1,
+-- v_stride=>384
+
+ )
+
+ port map(
+ clk_locked => clk_locked,
+ clk => o_clk,
+ clk_x2 => o_clk_x2,
+ clk_phy => o_clk_phy,
+ sys_rst_n => sys_rst_n,
+ vsync_in => not vsync_in,
+ r_in => r,
+ g_in => g,
+ b_in => b,
+ addr_out => rd_addr,
+ r_out => r_out,
+ g_out => g_out,
+ b_out => b_out,
+ hsync_out => hsync_out,
+ vsync_out => vsync_out,
+ hdmi_c_p => hdmi_c_p,
+ hdmi_c_n => hdmi_c_n,
+ hdmi_r_p => hdmi_r_p,
+ hdmi_r_n => hdmi_r_n,
+ hdmi_g_p => hdmi_g_p,
+ hdmi_g_n => hdmi_g_n,
+ hdmi_b_p => hdmi_b_p,
+ hdmi_b_n => hdmi_b_n
+ );
+
+ process (clk_50m, c)
+ begin
+ if rising_edge(clk_50m) then
+
+ if c < 19999999 then
+ c <= c+1;
+ else
+ c <= 0;
+ t <= not t;
+ end if;
+ end if;
+ end process;
+
+
+ led <= t;
+
+
+end Behavioral;
+