--============================================================================== -- CERN (BE-CO-HT) -- Top-level design for CONV-TTL-RS485 --============================================================================== -- -- author: Theodor Stana (t.stana@cern.ch) -- -- date of creation: 2014-07-24 -- -- version: 1.0 -- -- description: -- -- dependencies: -- general-cores repository [1] -- -- references: -- [1] Platform-independent core collection webpage on OHWR, -- http://www.ohwr.org/projects/general-cores/repository -- [2] ELMA, Access to board data using SNMP and I2C -- http://www.ohwr.org/documents/227 -- --============================================================================== -- GNU LESSER GENERAL PUBLIC LICENSE --============================================================================== -- This source file is free software; you can redistribute it and/or modify it -- under the terms of the GNU Lesser General Public License as published by the -- Free Software Foundation; either version 2.1 of the License, or (at your -- option) any later version. This source is distributed in the hope that it -- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- See the GNU Lesser General Public License for more details. You should have -- received a copy of the GNU Lesser General Public License along with this -- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html --============================================================================== -- last changes: -- 2014-07-24 Theodor Stana File created --============================================================================== -- TODO: - --============================================================================== library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gencores_pkg.all; use work.wishbone_pkg.all; use work.conv_common_gw_pkg.all; entity conv_ttl_rs485 is port ( -- Clocks clk_20_i : in std_logic; clk_125_p_i : in std_logic; clk_125_n_i : in std_logic; -- I2C interface scl_i : in std_logic; scl_o : out std_logic; scl_en_o : out std_logic; sda_i : in std_logic; sda_o : out std_logic; sda_en_o : out std_logic; -- VME interface vme_sysreset_n_i : in std_logic; vme_ga_i : in std_logic_vector(4 downto 0); vme_gap_i : in std_logic; -- PCB version recognition pcbrev_i : in std_logic_vector(5 downto 0); -- Channel enable global_oen_o : out std_logic; ttl_oen_o : out std_logic; inv_oen_o : out std_logic; rs485_oen_o : out std_logic; -- Front panel channels ttl_n_i : in std_logic_vector(5 downto 0); ttl_o : out std_logic_vector(5 downto 0); inv_n_i : in std_logic_vector(3 downto 0); inv_o : out std_logic_vector(3 downto 0); -- Rear panel channels rs485_n_i : in std_logic_vector(5 downto 0); rs485_fs_n_i : in std_logic_vector(5 downto 0); rs485_o : out std_logic_vector(5 downto 0); -- Rear input and output termination lines iterm_en_o : out std_logic_vector(5 downto 0); oterm_en_o : out std_logic_vector(5 downto 0); -- Channel leds led_front_n_o : out std_logic_vector(5 downto 0); led_front_inv_n_o : out std_logic_vector(3 downto 0); led_rear_n_o : out std_logic_vector(5 downto 0); -- SPI interface to on-board flash chip flash_cs_n_o : out std_logic; flash_sclk_o : out std_logic; flash_mosi_o : out std_logic; flash_miso_i : in std_logic; -- PLL DACs -- 20 MHz VCXO control dac20_din_o : out std_logic; dac20_sclk_o : out std_logic; dac20_sync_n_o : out std_logic; -- 125 MHz clock generator control dac125_din_o : out std_logic; dac125_sclk_o : out std_logic; dac125_sync_n_o : out std_logic; -- SFP lines sfp_los_i : in std_logic; sfp_present_i : in std_logic; sfp_rate_select_o : out std_logic; sfp_scl_b : inout std_logic; sfp_sda_b : inout std_logic; sfp_tx_disable_o : out std_logic; sfp_tx_fault_i : in std_logic; -- Thermometer data port thermometer_b : inout std_logic; -- Switches sw_gp_n_i : in std_logic_vector(7 downto 0); sw_multicast_n_i : in std_logic_vector(3 downto 0); -- RTM lines rtmm_i : in std_logic_vector(2 downto 0); rtmp_i : in std_logic_vector(2 downto 0); -- Front panel bicolor LEDs led_ctrl0_o : out std_logic; led_ctrl0_oen_o : out std_logic; led_ctrl1_o : out std_logic; led_ctrl1_oen_o : out std_logic; led_gp_2_4_o : out std_logic; led_gp_1_3_o : out std_logic; led_oterm_wr_o : out std_logic; led_iterm_syserror_o : out std_logic; led_gf_syspw_o : out std_logic; led_ttl_i2c_o : out std_logic ); end entity conv_ttl_rs485; architecture arch of conv_ttl_rs485 is --============================================================================ -- Constant declarations --============================================================================ -- Number of repetition channels constant c_nr_chans : integer := 6; constant c_nr_inv_chans : integer := 4; -- Number of bicolor LED lines & columns constant c_bicolor_led_lines : integer := 2; constant c_bicolor_led_cols : integer := 6; -- Board ID - ASCII string "T485" constant c_board_id : std_logic_vector(31 downto 0) := x"54343835"; -- Gateware version constant c_gwvers : std_logic_vector(7 downto 0) := x"20"; --============================================================================ -- Type declarations --============================================================================ type t_ttlbar_nosig_cnt is array (c_nr_chans-1 downto 0) of unsigned(10 downto 0); type t_led_inv_cnt is array(c_nr_chans-1 downto 0) of unsigned(18 downto 0); --============================================================================ -- Signal declarations --============================================================================ -- Reset signal signal rst_20_n : std_logic; -- TTL & RS485 signals signal rs485_fs : std_logic_vector(c_nr_chans-1 downto 0); signal pulse_in : std_logic_vector(c_nr_chans-1 downto 0); signal pulse_out : std_logic_vector(c_nr_chans-1 downto 0); signal inv_pulse_in_n : std_logic_vector(c_nr_inv_chans-1 downto 0); signal inv_pulse_out : std_logic_vector(c_nr_inv_chans-1 downto 0); signal pulse_ttl : std_logic_vector(c_nr_chans-1 downto 0); signal pulse_rs485 : std_logic_vector(c_nr_chans-1 downto 0); signal pulse_rs485_mapped : std_logic_vector(c_nr_chans-1 downto 0); signal inhibit_first_pulse : std_logic; signal inhibit_first_pulse_d0 : std_logic; signal inhibit_cnt : unsigned(10 downto 0); -- Line signals -- for reflection in line status register of conv_common_gw signal line_ttl : std_logic_vector(c_nr_chans-1 downto 0); signal line_invttl : std_logic_vector(3 downto 0); signal line_rs485 : std_logic_vector(c_nr_chans-1 downto 0); -- Switch signals (for inverting switch inputs to the common g/w) signal sw_ttl : std_logic; signal sw_iterm_en : std_logic; signal sw_oterm_en : std_logic; signal sw_gp : std_logic_vector(7 downto 0); signal sw_other : std_logic_vector(31 downto 0); -- No signal on TTL-BAR signal ttlbar_nosig_cnt : t_ttlbar_nosig_cnt; signal ttlbar_nosig : std_logic_vector(c_nr_chans-1 downto 0); -- INV-TTL internal signals signal inv_n : std_logic_vector(3 downto 0); signal inv_n_d0 : std_logic_vector(3 downto 0); signal inv_n_fedge_p : std_logic_vector(3 downto 0); -- Channel LED signals signal led_pulse : std_logic_vector(c_nr_chans-1 downto 0); signal led_inv_pulse : std_logic_vector(c_nr_inv_chans-1 downto 0); -- I2C LEDs signal led_i2c : std_logic; signal led_i2c_err : std_logic; signal led_inv : std_logic_vector(3 downto 0); signal led_inv_cnt : t_led_inv_cnt; -- System error (ERR) LED control signal led_syserr : std_logic; -- Bicolor LED signals signal bicolor_led_state : std_logic_vector(2*c_bicolor_led_cols*c_bicolor_led_lines-1 downto 0); signal bicolor_led_col : std_logic_vector(c_bicolor_led_cols-1 downto 0); signal bicolor_led_line : std_logic_vector(c_bicolor_led_lines-1 downto 0); signal bicolor_led_line_oen : std_logic_vector(c_bicolor_led_lines-1 downto 0); --============================================================================== -- architecture begin --============================================================================== begin --============================================================================ -- Channel input logic --============================================================================ -- TTL switch sw_ttl <= not sw_gp_n_i(7); -- The "no signal detect" block -- -- If the signal line is high for 100 us, the ttlbar_nosig lines disable -- the input to the TTL side MUX and the OR gate. -- -- The counter is disabled if the switch is set for TTL signals, to avoid -- unnecessary power consumption by the counter. p_ttlbar_nosig : process(clk_20_i) begin if rising_edge(clk_20_i) then for i in 0 to c_nr_chans-1 loop if (rst_20_n = '0') or (ttl_n_i(i) = '0') then ttlbar_nosig(i) <= '0'; ttlbar_nosig_cnt(i) <= (others => '0'); elsif (sw_ttl = '0') then ttlbar_nosig_cnt(i) <= ttlbar_nosig_cnt(i) + 1; if (ttlbar_nosig_cnt(i) = 1999) then ttlbar_nosig(i) <= '1'; ttlbar_nosig_cnt(i) <= (others => '0'); end if; end if; end loop; end if; end process p_ttlbar_nosig; -- TTL and blocking inputs pulse_ttl <= not ttl_n_i when sw_ttl = '1' else ttl_n_i and (not ttlbar_nosig); -- Pulse input on RS-485 side valid only when failsafe not high -- see Texas slyt257 for implementation details gen_rs485_input : for i in 0 to c_nr_chans-1 generate rs485_fs(i) <= rs485_n_i(i) nor rs485_fs_n_i(i); pulse_rs485_mapped(i) <= (not rs485_n_i(i)) when rs485_fs(i) = '0' else '0'; pulse_rs485(0) <= pulse_rs485_mapped(0); pulse_rs485(1) <= pulse_rs485_mapped(4) when rtmp_i = "101" else pulse_rs485_mapped(1); pulse_rs485(2) <= pulse_rs485_mapped(2) when rtmp_i = "101" else pulse_rs485_mapped(2); pulse_rs485(3) <= pulse_rs485_mapped(3) when rtmp_i = "101" else pulse_rs485_mapped(3); pulse_rs485(4) <= pulse_rs485_mapped(1) when rtmp_i = "101" else pulse_rs485_mapped(4); pulse_rs485(5) <= pulse_rs485_mapped(5) when rtmp_i = "101" else pulse_rs485_mapped(5); end generate gen_rs485_input; -- This process has the effect of extending the reset an extra 100 us, to avoid -- a pulse being generated or erroneously counted during the period of no signal -- detect p_inhibit_first_pulse : process (clk_20_i) begin if rising_edge(clk_20_i) then if (rst_20_n = '0') then inhibit_cnt <= (others => '0'); inhibit_first_pulse <= '1'; elsif (inhibit_first_pulse = '1') then inhibit_cnt <= inhibit_cnt + 1; if (inhibit_cnt = 1999) then inhibit_first_pulse <= '0'; end if; end if; end if; end process p_inhibit_first_pulse; -- Delay inhibit first pulse signal, use this to enable input, thus avoiding -- internal reset states of conv_common_gw p_inhibit_first_pulse_d0 : process (clk_20_i) begin if rising_edge(clk_20_i) then if (rst_20_n = '0') then inhibit_first_pulse_d0 <= '1'; else inhibit_first_pulse_d0 <= inhibit_first_pulse; end if; end if; end process; -- Pulse input valid only after inhibit period is over pulse_in <= (pulse_ttl or pulse_rs485) when (inhibit_first_pulse_d0 = '0') else (others => '0'); -- Line inputs for reflection in status register line_ttl <= not ttl_n_i; line_invttl <= not inv_n_i; line_rs485 <= not rs485_n_i; -- Switch inputs for reflection in status register sw_gp <= not sw_gp_n_i; sw_other( 3 downto 0) <= not sw_multicast_n_i; sw_other(31 downto 4) <= (others => '0'); --============================================================================ -- Instantiate common generic gateware for converter boards --============================================================================ cmp_conv_common : conv_common_gw generic map ( g_nr_chans => c_nr_chans, g_board_id => c_board_id, g_gwvers => c_gwvers, g_pgen_fixed_width => false, g_pgen_gf_len => 1, g_with_pulse_cnt => true, g_with_pulse_timetag => true, g_with_man_trig => true, g_man_trig_pwidth => 24, g_with_thermometer => true, g_bicolor_led_columns => c_bicolor_led_cols, g_bicolor_led_lines => c_bicolor_led_lines ) port map ( -- Clocks clk_20_i => clk_20_i, clk_125_p_i => clk_125_p_i, clk_125_n_i => clk_125_n_i, -- Reset output signal, synchronous to 20 MHz clock rst_n_o => rst_20_n, -- Glitch filter active-low enable signal gf_en_n_i => sw_gp_n_i(0), -- Burst mode enable signal. Disabled in conv-ttl-rs485 burst_en_n_i => '1', -- Pulse width selection, port low means 250ns, high means 1.2us. -- Switch to determine short or long pulse mode. -- ON switch means SHORT 250ns pulse repetition with max frequency 2MHz -- OFF switch means LONG 1.2us pulse repetition with max freq ~104kHz -- In conv-ttl-rs485 this switch is not meaningful pulse_width_sel_n_i => '0', -- Channel enable global_ch_oen_o => global_oen_o, pulse_front_oen_o => ttl_oen_o, pulse_rear_oen_o => rs485_oen_o, inv_oen_o => inv_oen_o, -- Front panel channels pulse_i => pulse_in, pulse_front_i => pulse_ttl, pulse_rear_i => pulse_rs485, pulse_o => pulse_out, -- Inverted pulse I/O inv_pulse_i_n => inv_pulse_in_n, inv_pulse_o => inv_pulse_out, -- Channel leds led_pulse_o => led_pulse, -- inverted channel leds led_inv_pulse_o => led_inv_pulse, -- I2C interface scl_i => scl_i, scl_o => scl_o, scl_en_o => scl_en_o, sda_i => sda_i, sda_o => sda_o, sda_en_o => sda_en_o, -- VME interface vme_sysreset_n_i => vme_sysreset_n_i, vme_ga_i => vme_ga_i, vme_gap_i => vme_gap_i, -- SPI interface to on-board flash chip flash_cs_n_o => flash_cs_n_o, flash_sclk_o => flash_sclk_o, flash_mosi_o => flash_mosi_o, flash_miso_i => flash_miso_i, -- PLL DACs -- 20 MHz VCXO control dac20_din_o => dac20_din_o, dac20_sclk_o => dac20_sclk_o, dac20_sync_n_o => dac20_sync_n_o, -- 125 MHz clock generator control dac125_din_o => dac125_din_o, dac125_sclk_o => dac125_sclk_o, dac125_sync_n_o => dac125_sync_n_o, -- SFP lines sfp_los_i => sfp_los_i, sfp_present_i => sfp_present_i, sfp_rate_select_o => sfp_rate_select_o, sfp_sda_b => sfp_scl_b, sfp_scl_b => sfp_sda_b, sfp_tx_disable_o => sfp_tx_disable_o, sfp_tx_fault_i => sfp_tx_fault_i, -- I2C LED signals -- conect to a bicolor LED of choice -- led_i2c_o pulses four times on I2C transfer led_i2c_o => led_i2c, -- Switch inputs (for readout from converter status register) sw_gp_i => sw_gp, sw_other_i => sw_other, -- PCB Version information hwvers_i => pcbrev_i, -- RTM lines rtmm_i => rtmm_i, rtmp_i => rtmp_i, -- TTL, INV-TTL and rear-panel channel inputs, for reflection in line status register line_front_i => line_ttl, line_inv_i => line_invttl, line_rear_i => line_rs485, line_front_fs_i => ttlbar_nosig, line_inv_fs_i => (others => '0'), line_rear_fs_i => rs485_fs, -- Thermometer line thermometer_b => thermometer_b, -- System error LED, active-high on system error -- ERR bicolor LED should light red when led_syserr_o = '1' led_syserr_o => led_syserr, -- Bicolor LED signals bicolor_led_state_i => bicolor_led_state, bicolor_led_col_o => bicolor_led_col, bicolor_led_line_o => bicolor_led_line, bicolor_led_line_oen_o => bicolor_led_line_oen ); ttl_o <= pulse_out when sw_ttl = '1' else not pulse_out; -- rs485_o (1 downto 0) <= pulse_out (1 downto 0); -- Channels 3 and 4 output copies of chans 1 and 2 respectively -- depending on RTMP Id of RTM connected. -- *RTM with DB9 connectors has only 2 o/p channels in rs485 RTMP = Gnd Open Gnd -- *Optical RTM only 2 o/p channels in optical RTMP= Open Open Gnd -- in these cases channel 3 copies channel 1 -- channel 4 copies channel 2 -- rs485_o (3 downto 2) <= pulse_out (1 downto 0) when rtmp_i = "101" or rtmp_i = "100" -- else pulse_out (3 downto 2); -- rs485_o (5 downto 4) <= pulse_out (5 downto 4); --============================================================================ -- Channel output logic --============================================================================ -- Front and rear panel outputs rs485_o(0) <= pulse_out(0); rs485_o(1) <= pulse_out(0) when rtmp_i = "101" else pulse_out(1); rs485_o(2) <= pulse_out(2); rs485_o(3) <= pulse_out(3); rs485_o(4) <= pulse_out(1) when rtmp_i = "101" else pulse_out(4); rs485_o(5) <= pulse_out(1) when rtmp_i = "101" else pulse_out(5); -- LED outputs -- Boards earlier than v4 do not use -ve logic for LEDs. -- For these LED pulse signals are still in +ve logic. led_front_n_o <= led_pulse when pcbrev_i (5 downto 0) = "000000" else not led_pulse; led_front_inv_n_o <= led_inv_pulse when pcbrev_i (5 downto 0) = "000000" else not led_inv_pulse; led_rear_n_o <= led_pulse when pcbrev_i (5 downto 0) = "000000" else not led_pulse; -- INV-TTL outputs inv_pulse_in_n <= inv_n_i; inv_o <= inv_pulse_out; -- Channel terminations sw_iterm_en <= sw_gp(1); sw_oterm_en <= sw_gp(2); iterm_en_o <= (others => sw_iterm_en); oterm_en_o <= (others => sw_oterm_en); --============================================================================ -- External logic for bicolor LED control --============================================================================ -- Assign bicolor LED lines & columns to outputs led_ttl_i2c_o <= bicolor_led_col(0); led_oterm_wr_o <= bicolor_led_col(1); led_iterm_syserror_o <= bicolor_led_col(2); led_gf_syspw_o <= bicolor_led_col(3); led_gp_2_4_o <= bicolor_led_col(4); led_gp_1_3_o <= bicolor_led_col(5); led_ctrl0_o <= bicolor_led_line(0); led_ctrl1_o <= bicolor_led_line(1); led_ctrl0_oen_o <= bicolor_led_line_oen(0); led_ctrl1_oen_o <= bicolor_led_line_oen(1); -- TTL mode (state of TTL switch) bicolor_led_state( 1 downto 0) <= c_LED_GREEN when (sw_ttl = '1') else c_LED_OFF; -- Output termination enabled bicolor_led_state( 3 downto 2) <= c_LED_GREEN when (sw_oterm_en = '1') else c_LED_OFF; -- Input termination enabled bicolor_led_state( 5 downto 4) <= c_LED_GREEN when (sw_iterm_en = '1') else c_LED_OFF; -- Glitch filter enabled bicolor_led_state( 7 downto 6) <= c_LED_GREEN when (sw_gp(0) = '1') else c_LED_OFF; -- General-purpose 4 bicolor_led_state( 9 downto 8) <= c_LED_OFF; -- General-purpose 3 bicolor_led_state(11 downto 10) <= c_LED_OFF; -- I2C bicolor_led_state(13 downto 12) <= c_LED_GREEN when (led_i2c = '1') else c_LED_OFF; -- White Rabbit LED bicolor_led_state(15 downto 14) <= c_LED_OFF; -- System error bicolor_led_state(17 downto 16) <= c_LED_RED when (led_syserr = '1') or (c_gwvers(7 downto 4) = "0000" ) else c_LED_OFF; -- System power bicolor_led_state(19 downto 18) <= c_LED_GREEN; -- General-purpose 2 bicolor_led_state(21 downto 20) <= c_LED_OFF; -- General-purpose 1 bicolor_led_state(23 downto 22) <= c_LED_OFF; end architecture arch; --============================================================================== -- architecture end --==============================================================================