------------------------------------------------------- -- Design Name : mDAB_2_ctrl_top -- File Name : mDAB_2_ctrl3_top.vhd -- Device : CPLD, XC2C128-7VQG100I -- Function : mDAB, camera, flasher and ilumination control -- -- Coder : K.-H. Sulanke, DESY, 2021-10-14 ------------------------------------------------------- -- Rev. 1 to be used for the mDAB_2 board -- Rev. 3 including rev. readout, fw-rev.=bit_11..0, board-rev.=bit_15..12 library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_bit.all; use ieee.std_logic_arith.all; library unisim ; use unisim.vcomponents.all ; entity mDAB_2_ctrl_top is port( -- bank1, VCCIO = 1.8V CAL_CLK : in std_logic; -- -- CAL_SYNC : in std_logic; -- MCU_CAL_MISO : out std_logic; -- MCU_CAL_MOSI : in std_logic; -- MCU_CAL_SS : in std_logic; -- low active MCU signal MCU_AFE_SEL : in std_logic; -- -- MCU_CAL_RST : in std_logic; -- MCU_CAL_SCLK : in std_logic; -- MCU_CAL_A : in std_logic_vector(3 downto 0); -- MCU_CAL_A4 not used ADC_CSn : out std_logic; -- -- ADC_EOCn : in std_logic; -- ADC_CONVSTnR : out std_logic; -- ADC_SDIR : out std_logic; -- ADC_SCLKR : out std_logic; -- ADC_SDO : in std_logic; -- --bank2, VCCIO = 3.3V INTLK_2 : in std_logic; -- DAC_SCLK : out std_logic; -- Flasher Bias voltage control DAC_SYNCn : out std_logic; -- DAC_DIN : out std_logic; -- -- DAC_VREF : in std_logic; -- FLASH1_POW_EN : out std_logic; -- FLASH1_SELECT_CLR : out std_logic; -- low active FLASH1_SELECT_DIN : out std_logic; -- FLASH1_SELECT_CLK : out std_logic; FLASH2_POW_EN : out std_logic; -- FLASH2_SELECT_CLK : out std_logic; -- FLASH2_SELECT_DIN : out std_logic; -- FLASH2_SELECT_CLR : out std_logic; -- low active ILUM_POW_EN : out std_logic; -- CAM1_POW_EN : out std_logic; -- CAM1_ENA : out std_logic; -- high active, = camera_1 power enable CAM1_SS : out std_logic; -- low active CAM1_MISO : in std_logic; -- CAM1_MOSI : out std_logic; -- CAM1_SCLK : out std_logic; -- LUM1_ENA : out std_logic; -- CAM2_POW_EN : out std_logic; -- CAM2_ENA : out std_logic; -- CAM2_SS : out std_logic; -- low active CAM2_MISO : in std_logic; -- CAM2_MOSI : out std_logic; -- CAM2_SCLK : out std_logic; -- LUM2_ENA : out std_logic; -- CAM3_POW_EN : out std_logic; -- CAM3_ENA : out std_logic; -- CAM3_SS : out std_logic; -- low active CAM3_MISO : in std_logic; -- CAM3_MOSI : out std_logic; -- CAM3_SCLK : out std_logic; -- LUM3_ENA : out std_logic ); end mDAB_2_ctrl_top ; architecture arch_mDAB_2_ctrl_top of mDAB_2_ctrl_top is constant FW_REV : std_logic_vector(15 downto 0) := X"2003"; signal pow_en_shrg : std_logic_vector(2 downto 0); signal pow_en_shrg_lat : std_logic_vector(2 downto 0); signal cam_shrg : std_logic_vector(5 downto 0); signal cam_shrg_lat : std_logic_vector(5 downto 0); signal cam1_ss_nd : std_logic; signal cam2_ss_nd : std_logic; signal cam3_ss_nd : std_logic; signal cam_ena_ss_nd : std_logic; signal flash1_ena_ss : std_logic; signal flash2_ena_ss : std_logic; signal flash_brt_ss : std_logic; -- flasher DAC signal adc_cs_nd : std_logic; -- flasher bias voltage read back ADC signal adc_convst_nd : std_logic; signal fwrd_ss_nd : std_logic; -- firmware read select signal fwrd_cyc : std_logic; -- signal power_ena_ss : std_logic; signal latch_ena_nd : std_logic; signal clear_ss_nd : std_logic; -- global clear signal signal dec_out : std_logic_vector(12 downto 0); -- high active signals signal fw_shrg : std_logic_vector(15 downto 0); -- firmware shift register -- added for synchronization signal afe_sel : std_logic; signal intlk2 : std_logic; signal cal_mosi : std_logic; signal cal_ss : std_logic; signal cal_a : std_logic_vector(3 downto 0); signal cal_sclk_shrg : std_logic_vector(2 downto 0); signal cal_sclk_lh : std_logic; --signal cal_sclk_hl : std_logic; signal lat_ena_shrg : std_logic_vector(2 downto 0); signal lat_ena_lh : std_logic; begin SYNC_ALL: process(CAL_CLK) begin if rising_edge(CAL_CLK) then afe_sel <= MCU_AFE_SEL; intlk2 <= INTLK_2; cal_mosi <= MCU_CAL_MOSI; cal_ss <= MCU_CAL_SS; cal_a <= MCU_CAL_A; cal_sclk_shrg(0) <= MCU_CAL_SCLK; cal_sclk_shrg(1) <= cal_sclk_shrg(0); cal_sclk_shrg(2) <= cal_sclk_shrg(1); if cal_sclk_shrg = B"011" then cal_sclk_lh <= '1'; else cal_sclk_lh <= '0'; end if; -- if cal_sclk_shrg = B"110" then -- cal_sclk_hl <= '1'; -- else -- cal_sclk_hl <= '0'; -- end if; end if; end process SYNC_ALL; --cal_ss <= MCU_CAL_SS; DECODE: process(CAL_CLK) begin if rising_edge(CAL_CLK) then if (afe_sel='0') and (intlk2='1') and (cal_ss='0') then case (cal_a) is when "0000" => dec_out <= ( 0 => '1', others => '0'); when "0001" => dec_out <= ( 1 => '1', others => '0'); when "0010" => dec_out <= ( 2 => '1', others => '0'); when "0011" => dec_out <= ( 3 => '1', others => '0'); when "0100" => dec_out <= ( 4 => '1', others => '0'); when "0101" => dec_out <= ( 5 => '1', others => '0'); when "0110" => dec_out <= ( 6 => '1', others => '0'); when "0111" => dec_out <= ( 7 => '1', others => '0'); when "1000" => dec_out <= ( 8 => '1', others => '0'); when "1101" => dec_out <= ( 9 => '1', others => '0'); when "1110" => dec_out <= (10 => '1', others => '0'); when "1111" => dec_out <= (11 => '1', others => '0'); when "1010" => dec_out <= (12 => '1', others => '0'); -- rev. readout added when others => dec_out <= (others => '0'); end case; else dec_out <= (others => '0'); end if; end if; -- rising_edge(CAL_CLK) end process DECODE; flash_brt_ss <= dec_out(0); flash1_ena_ss <= dec_out(1); cam1_ss_nd <= dec_out(2); cam2_ss_nd <= dec_out(3); cam3_ss_nd <= dec_out(4); cam_ena_ss_nd <= dec_out(5); flash2_ena_ss <= dec_out(6); -- new adc_convst_nd <= dec_out(7); -- new adc_cs_nd <= dec_out(8); -- new power_ena_ss <= dec_out(9); -- global enable for the power-enable shift register latch_ena_nd <= dec_out(10); clear_ss_nd <= dec_out(11); fwrd_ss_nd <= dec_out(12); FWREV_RD: process(CAL_CLK) begin if rising_edge (CAL_CLK) then if fwrd_ss_nd = '0' then fw_shrg <= FW_REV; fwrd_cyc <= '0'; elsif cal_sclk_lh='1' then fwrd_cyc <= '1'; -- delay the change of bits by one clock if fwrd_cyc = '1' then fw_shrg(15 downto 1) <= fw_shrg(14 downto 0); end if; end if; -- fwrd_ss_nd = '0' end if; -- rising_edge (CAL_CLK) end process FWREV_RD; LATCH_ENA_STB: process(CAL_CLK) -- 20Mhz system clock used for deglitching here begin if rising_edge (CAL_CLK) then lat_ena_shrg(0) <= latch_ena_nd; lat_ena_shrg(1) <= lat_ena_shrg(0); lat_ena_shrg(2) <= lat_ena_shrg(1); if lat_ena_shrg(2 downto 1) = B"01" then -- to deal with short pulses lat_ena_lh <= '1'; else lat_ena_lh <= '0'; end if; end if; --rising_edge (CAL_CLK) end process LATCH_ENA_STB; POWER_ENA: process(CAL_CLK) begin if rising_edge (CAL_CLK) then if clear_ss_nd = '1' then pow_en_shrg <= (others => '0'); elsif power_ena_ss = '1' then if cal_sclk_lh = '1' then pow_en_shrg(0) <= cal_mosi; pow_en_shrg(2 downto 1) <= pow_en_shrg(1 downto 0); end if; --rising_edge (MCU_CAL_SCLK) end if; -- clear_ss_nd = '0' end if; -- rising_edge (CAL_CLK) end process POWER_ENA; POWER_ENA_LAT: process(CAL_CLK) begin if rising_edge (CAL_CLK) then if clear_ss_nd = '1' then pow_en_shrg_lat <= (others => '0'); elsif lat_ena_lh = '1' then pow_en_shrg_lat <= pow_en_shrg; end if; -- clear_ss_nd = '1' end if; --rising_edge (CAL_CLK) end process POWER_ENA_LAT; CAM1_POW_EN <= pow_en_shrg_lat(0); -- CAM2_POW_EN <= pow_en_shrg_lat(0); -- CAM3_POW_EN <= pow_en_shrg_lat(0); -- ILUM_POW_EN <= pow_en_shrg_lat(0) and INTLK_2; -- FLASH1_POW_EN <= pow_en_shrg_lat(1) and INTLK_2; -- FLASH2_POW_EN <= pow_en_shrg_lat(2) and INTLK_2; -- CAMERA_SEL: process(CAL_CLK) begin if rising_edge (CAL_CLK) then if clear_ss_nd = '1' then cam_shrg <= (others => '0'); elsif cam_ena_ss_nd = '1' then if cal_sclk_lh='1' then cam_shrg(0) <= cal_mosi; cam_shrg(5 downto 1) <= cam_shrg(4 downto 0); end if; --cal_sclk_lh='1' end if; -- clear_ss_nd = '0' end if; --rising_edge (CAL_CLK) end process CAMERA_SEL; CAMERA_LAT: process(CAL_CLK) begin if rising_edge (CAL_CLK) then if clear_ss_nd = '1' then cam_shrg_lat <= (others => '0'); elsif lat_ena_lh='1' then cam_shrg_lat <= cam_shrg; end if; end if; --rising_edge (CAL_CLK) end process CAMERA_LAT; CAM1_ENA <= cam_shrg_lat(0); CAM2_ENA <= cam_shrg_lat(2); CAM3_ENA <= cam_shrg_lat(4); CAM1_SS <= not (cam1_ss_nd and cam_shrg_lat(0)); CAM2_SS <= not (cam2_ss_nd and cam_shrg_lat(2)); CAM3_SS <= not (cam3_ss_nd and cam_shrg_lat(4)); LUM1_ENA <= cam_shrg_lat(1) and INTLK_2; LUM2_ENA <= cam_shrg_lat(3) and INTLK_2; LUM3_ENA <= cam_shrg_lat(5) and INTLK_2; -- CAM_SCLK <= MCU_CAL_SCLK and -- ((cam1_ss_nd and cam_shrg_lat(0)) or -- (cam2_ss_nd and cam_shrg_lat(2)) or -- (cam3_ss_nd and cam_shrg_lat(4))) ; CAM1_SCLK <= MCU_CAL_SCLK and cam1_ss_nd and cam_shrg_lat(0); CAM1_MOSI <= MCU_CAL_MOSI and cam1_ss_nd and cam_shrg_lat(0); CAM2_SCLK <= MCU_CAL_SCLK and cam2_ss_nd and cam_shrg_lat(2); CAM2_MOSI <= MCU_CAL_MOSI and cam2_ss_nd and cam_shrg_lat(2); CAM3_SCLK <= MCU_CAL_SCLK and cam3_ss_nd and cam_shrg_lat(4); CAM3_MOSI <= MCU_CAL_MOSI and cam3_ss_nd and cam_shrg_lat(4); DAC_SCLK <= MCU_CAL_SCLK and flash_brt_ss; -- assuming MCU_CAL_SCLK is '0' in quiet state DAC_SYNCn <= not flash_brt_ss; DAC_DIN <= MCU_CAL_MOSI; FLASH1_SELECT_CLK <= MCU_CAL_SCLK and flash1_ena_ss; FLASH1_SELECT_CLR <= not clear_ss_nd; FLASH1_SELECT_DIN <= MCU_CAL_MOSI and flash1_ena_ss; FLASH2_SELECT_CLK <= MCU_CAL_SCLK and flash2_ena_ss; FLASH2_SELECT_CLR <= not clear_ss_nd; FLASH2_SELECT_DIN <= MCU_CAL_MOSI and flash2_ena_ss; ADC_CSn <= not adc_cs_nd; -- ADC_CONVSTnR <= not adc_convst_nd; -- pulse to start conversion ADC_SDIR <= MCU_CAL_MOSI and adc_cs_nd; -- ADC_SCLKR <= MCU_CAL_SCLK and adc_cs_nd; -- -- MCU_CAL_MISO <= (CAM_MISO and (cam1_ss_nd or cam2_ss_nd or cam3_ss_nd)) or -- (ADC_SDO and adc_cs_nd); MCU_CAL_MISO <= (CAM1_MISO and cam1_ss_nd) or (CAM2_MISO and cam2_ss_nd) or (CAM3_MISO and cam3_ss_nd) or (ADC_SDO and adc_cs_nd) or (fw_shrg(15) and fwrd_ss_nd); end arch_mDAB_2_ctrl_top ;