diff options
author | James McKenzie <root@ka-ata-killa.panaceas.james.local> | 2025-09-04 21:46:39 +0100 |
---|---|---|
committer | James McKenzie <root@ka-ata-killa.panaceas.james.local> | 2025-09-04 21:46:39 +0100 |
commit | ab5b79919a39262a30c6a130629a44d071300e40 (patch) | |
tree | c292f40ef31426db5819b333f4ca004609b0dd1a /fpga/hp_lcd_driver/common.vhdl | |
parent | a129c9146977227840cbb46e6d748ac885e41088 (diff) | |
download | hp_instrument_lcds-ab5b79919a39262a30c6a130629a44d071300e40.tar.gz hp_instrument_lcds-ab5b79919a39262a30c6a130629a44d071300e40.tar.bz2 hp_instrument_lcds-ab5b79919a39262a30c6a130629a44d071300e40.zip |
add common module
Diffstat (limited to 'fpga/hp_lcd_driver/common.vhdl')
-rw-r--r-- | fpga/hp_lcd_driver/common.vhdl | 379 |
1 files changed, 379 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..f796421 --- /dev/null +++ b/fpga/hp_lcd_driver/common.vhdl @@ -0,0 +1,379 @@ +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(wideo_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; + +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; + |