From 1f66814a3b25e032dc7c59bedf905191f544c56a Mon Sep 17 00:00:00 2001 From: Henning Heggen Date: Tue, 22 Sep 2015 15:39:17 +0200 Subject: [PATCH] hheggen: Added SFP_DDM module (SFP Rx power readback) to peripheral hub design. Compile script compile.pl modified (added include statements for CTS and HUB) -> new config_compile.pl necessary (see config_compile_gsi.pl). --- base/code/SFP_DDM.vhd | 527 -------------------------- base/code/SFP_DDM_periph_hub_v1.0.vhd | 445 ++++++++++++++++++++++ hub/compile.pl | 1 + hub/config_compile.pl | 1 + hub/config_compile_gsi.pl | 20 + hub/trb3_periph_hub.prj | 6 +- hub/trb3_periph_hub.vhd | 89 +++-- scripts/compile.pl | 24 +- 8 files changed, 551 insertions(+), 562 deletions(-) delete mode 100644 base/code/SFP_DDM.vhd create mode 100644 base/code/SFP_DDM_periph_hub_v1.0.vhd create mode 120000 hub/compile.pl create mode 120000 hub/config_compile.pl create mode 100644 hub/config_compile_gsi.pl diff --git a/base/code/SFP_DDM.vhd b/base/code/SFP_DDM.vhd deleted file mode 100644 index f19d0f8..0000000 --- a/base/code/SFP_DDM.vhd +++ /dev/null @@ -1,527 +0,0 @@ ----------------------------------------------------------------------------------- --- Company: GSI, Darmstadt (CSEE) --- Engineer: Henning Heggen --- --- Create Date: 09:50:07 11/27/2014 --- Design Name: --- Module Name: SFP_DDM - Behavioral --- Project Name: --- Target Devices: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ----------------------------------------------------------------------------------- -library IEEE; -use IEEE.STD_LOGIC_1164.all; -use IEEE.STD_LOGIC_ARITH.all; -use IEEE.STD_LOGIC_UNSIGNED.all; - - -entity SFP_DDM is - port( - CLK100 : in std_logic; - SLOW_CTRL_IN : in std_logic_vector(31 downto 0); - DATA_OUT : out std_logic_vector(3*32-1 downto 0); - SCL_EXT : out std_logic_vector(8 downto 1); - SDA_EXT : inout std_logic_vector(8 downto 1) - ); -end SFP_DDM; - -architecture Behavioral of SFP_DDM is - - signal SDA_IN : std_logic; - signal SDA : std_logic; - signal SCL : std_logic; - signal resetI2C : std_logic; - - type state_type is (reset, start, s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, - s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, stop0, stop1, stop2); - signal state : state_type; - signal bitcount : integer range 0 to 7; - constant slaveAddr_W : std_logic_vector(7 downto 0) := "10100010"; --slaveAddr & '0'; - constant slaveAddr_R : std_logic_vector(7 downto 0) := "10100011"; --slaveAddr & '1'; - signal byteAddr : std_logic_vector(7 downto 0); - signal dataRcvd : std_logic_vector(15 downto 0); - signal latch_data : std_logic := '0'; - - -- Clock division for I2C state machine - signal div512 : std_logic_vector(8 downto 0) := "000000000"; - signal CLK_I2C : std_logic; - - -- Signals for control state machine - signal counter : integer range 0 to 127 := 0; - signal SEL : integer range 0 to 1535 := 0; - signal run : std_logic; - signal running : std_logic := '0'; - signal selSFPs : std_logic_vector(8 downto 1); - ----------------------------------------------------------------------------------- -begin ---- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- ----------------------------------------------------------------------------------- - - -- Global signal assignments - run <= not SLOW_CTRL_IN(0); - selSFPs(8 downto 1) <= not SLOW_CTRL_IN(11 downto 4); - DATA_OUT(95 downto 64) <= x"00000000"; - - -- Address of diagnostic byte to read - -- Bytes 96/97: Temperature MSB/LSB - -- Bytes 98/99: Vcc MSB/LSB - -- Bytes 100/101: Tx bias current - -- Bytes 102/103: Transceiver Tx power MSB/LSB - -- Bytes 104/105: Transceiver Rx power MSB/LSB - byteAddr <= CONV_STD_LOGIC_VECTOR(104, 8); - - ------------------------------------------------------------------------------ - -- Clock for I2C state machine - -- FSM states toggle SCL => 2 FSM cycles = 1 SCL cycle (transfer of 1 bit) - -- => FSM must run at twice the SCL frequency - -- I2C standard: SCL = 100kHz => CLK_I2C needs to run at 200kHz - ------------------------------------------------------------------------------ - I2C_Clock : process (CLK100) - begin - if RISING_EDGE(CLK100) then - div512 <= div512 + 1; - if (div512(8) = '0') then - CLK_I2C <= '0'; - else - CLK_I2C <= '1'; - end if; - end if; - end process; - - ------------------------------------------------------------------------------ - -- Slow control - ------------------------------------------------------------------------------ - Control_FSM : process(CLK_I2C) - begin - if RISING_EDGE(CLK_I2C) then - if (run = '1' and running = '0') then - counter <= 1; - SEL <= 1; - running <= '1'; - resetI2C <= '0'; - elsif (running = '1' and SEL /= 0) then - resetI2C <= '0'; - counter <= counter + 1; -- Overflow every 128 cycles of CLK_I2C - if (counter = 0) then - SEL <= SEL + 1; - end if; - if (counter = 2) then - case SEL is - - when 1 => - if (selSFPs(1) = '1') then - resetI2C <= '1'; - end if; - - when 2 => - if (selSFPs(2) = '1') then - resetI2C <= '1'; - end if; - - when 3 => - if (selSFPs(3) = '1') then - resetI2C <= '1'; - end if; - - when 4 => - if (selSFPs(4) = '1') then - resetI2C <= '1'; - end if; - - when 5 => - if (selSFPs(5) = '1') then - resetI2C <= '1'; - end if; - - when 6 => - if (selSFPs(6) = '1') then - resetI2C <= '1'; - end if; - - when 7 => - if (selSFPs(7) = '1') then - resetI2C <= '1'; - end if; - - when 8 => - if (selSFPs(8) = '1') then - resetI2C <= '1'; - end if; - - when 1535 => - SEL <= 0; - running <= '0'; - - when others => - - end case; - end if; - end if; - end if; - end process; - - -- I2C state machine output multiplexer (selects between SFP modules) - process(CLK100, SEL) - begin - if RISING_EDGE(CLK100) then - if (running = '0' and run = '0') then - DATA_OUT(63 downto 0) <= x"FEFEFEFEFEFEFEFE"; - else - case SEL is - when 1 => - if (selSFPs(1) = '1') then - SDA_EXT(1) <= SDA; - SCL_EXT(1) <= SCL; - SDA_IN <= SDA_EXT(1); - if (latch_data = '1') then - DATA_OUT(7 downto 0) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(7 downto 0) <= x"FE"; - end if; - - when 2 => - if (selSFPs(2) = '1') then - SDA_EXT(2) <= SDA; - SCL_EXT(2) <= SCL; - SDA_IN <= SDA_EXT(2); - if (latch_data = '1') then - DATA_OUT(15 downto 8) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(15 downto 8) <= x"FE"; - end if; - - when 3 => - if (selSFPs(3) = '1') then - SDA_EXT(3) <= SDA; - SCL_EXT(3) <= SCL; - SDA_IN <= SDA_EXT(3); - if (latch_data = '1') then - DATA_OUT(23 downto 16) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(23 downto 16) <= x"FE"; - end if; - - when 4 => - if (selSFPs(4) = '1') then - SDA_EXT(4) <= SDA; - SCL_EXT(4) <= SCL; - SDA_IN <= SDA_EXT(4); - if (latch_data = '1') then - DATA_OUT(31 downto 24) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(31 downto 24) <= x"FE"; - end if; - - when 5 => - if (selSFPs(5) = '1') then - SDA_EXT(5) <= SDA; - SCL_EXT(5) <= SCL; - SDA_IN <= SDA_EXT(5); - if (latch_data = '1') then - DATA_OUT(39 downto 32) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(39 downto 32) <= x"FE"; - end if; - - when 6 => - if (selSFPs(6) = '1') then - SDA_EXT(6) <= SDA; - SCL_EXT(6) <= SCL; - SDA_IN <= SDA_EXT(6); - if (latch_data = '1') then - DATA_OUT(47 downto 40) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(47 downto 40) <= x"FE"; - end if; - - when 7 => - if (selSFPs(7) = '1') then - SDA_EXT(7) <= SDA; - SCL_EXT(7) <= SCL; - SDA_IN <= SDA_EXT(7); - if (latch_data = '1') then - DATA_OUT(55 downto 48) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(55 downto 48) <= x"FE"; - end if; - - when 8 => - if (selSFPs(8) = '1') then - SDA_EXT(8) <= SDA; - SCL_EXT(8) <= SCL; - SDA_IN <= SDA_EXT(8); - if (latch_data = '1') then - DATA_OUT(63 downto 56) <= dataRcvd(11 downto 4); - end if; - else - DATA_OUT(63 downto 56) <= x"FE"; - end if; - - when others => - SCL_EXT <= (others => 'Z'); - SDA_EXT <= (others => 'Z'); - end case; - end if; - end if; - end process; - - ------------------------------------------------------------------------------ - -- I2C state machine - ------------------------------------------------------------------------------ - I2C_FSM : process (CLK_I2C, resetI2C) - begin - if RISING_EDGE(CLK_I2C) then - if (resetI2C = '1') then -- Reset - state <= reset; - else - case state is - ------------------------------------------------------------------ - -- Start signal - ------------------------------------------------------------------ - when reset => -- Idle - SCL <= 'Z'; - SDA <= 'Z'; - dataRcvd <= x"0FE0"; - latch_data <= '0'; - state <= start; - - when start => -- Start - SCL <= 'Z'; - SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> start - bitcount <= 7; -- Initializing bit counter - state <= s00; - - ------------------------------------------------------------------ - -- Send 7-bit slave address plus write bit, MSB first - ------------------------------------------------------------------ - when s00 => - SCL <= '0'; - SDA <= slaveAddr_W(bitcount); - state <= s01; - - when s01 => - SCL <= 'Z'; - if (bitcount - 1) >= 0 then - bitcount <= bitcount - 1; - state <= s00; -- Continue transfer - else - bitcount <= 7; - state <= s02; -- Check for acknowledgement - end if; - - -- Get acknowledgement from slave and continue - when s02 => - SCL <= '0'; - SDA <= 'Z'; - state <= s03; - - when s03 => - SCL <= 'Z'; - if SDA_IN = '0' then - state <= s04; -- Acknowledge received => go on - else - state <= stop1; -- No acknowledge => abort - end if; - - ------------------------------------------------------------------ - -- Send 8-bit address of diagnostic byte, MSB first - ------------------------------------------------------------------ - when s04 => - SCL <= '0'; - SDA <= byteAddr(bitcount); - state <= s05; - - when s05 => - SCL <= 'Z'; - if (bitcount - 1) >= 0 then - bitcount <= bitcount - 1; - state <= s04; -- continue transfer - else - bitcount <= 7; - state <= s06; -- check for acknowledgement - end if; - - -- Get acknowledgement from slave and continue - when s06 => - SCL <= '0'; - SDA <= 'Z'; - state <= s07; - - when s07 => - SCL <= 'Z'; - if SDA_IN = '0' then - state <= s08; -- Acknowledge received => go on - else - state <= stop1; -- No acknowledge => abort - end if; - - ------------------------------------------------------------------ - -- Send repeated start signal - ------------------------------------------------------------------ - when s08 => - SCL <= '0'; - SDA <= 'Z'; - if SDA_IN = '0' then -- SDA should still be 0 here from acknowledgement - state <= s09; - else - state <= stop1; -- No acknowledge => abort - end if; - - when s09 => - SCL <= 'Z'; - SDA <= 'Z'; - state <= s10; - - when s10 => -- Start - SCL <= 'Z'; - SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> Start - state <= s11; - - ------------------------------------------------------------------ - -- Send 7-bit slave address plus read bit, MSB first - ------------------------------------------------------------------ - when s11 => - SCL <= '0'; - SDA <= slaveAddr_R(bitcount); - state <= s12; - - when s12 => - SCL <= 'Z'; - if (bitcount - 1) >= 0 then - bitcount <= bitcount - 1; - state <= s11; -- continue transfer - else - bitcount <= 7; - state <= s13; -- check for acknowledgement - end if; - - -- Get acknowledgement from slave and continue - when s13 => - SCL <= '0'; - SDA <= 'Z'; - state <= s14; - - when s14 => - SCL <= 'Z'; - if SDA_IN = '0' then - state <= s15; -- Acknowledge received => go on - else - state <= stop1; -- No acknowledge => abort - end if; - - ------------------------------------------------------------------ - -- Read 1st byte (MSB) from slave (MSB first) - ------------------------------------------------------------------ - when s15 => - SCL <= '0'; - SDA <= 'Z'; - state <= s16; - - when s16 => - SCL <= 'Z'; - dataRcvd(8 + bitcount) <= SDA_IN; -- Read byte from bus MSB first - if (bitcount - 1) >= 0 then - bitcount <= bitcount - 1; - state <= s15; - else - bitcount <= 7; - state <= s17; - end if; - - -- Send acknowledge signal - when s17 => - SCL <= '0'; - SDA <= '0'; -- Send acknowledge signal (0) - state <= s18; - - when s18 => - SCL <= 'Z'; -- Clocking out acknowledge signal - state <= s19; - - ------------------------------------------------------------------ - -- Read 2nd byte (LSB) from slave (MSB first) - ------------------------------------------------------------------ - when s19 => - SCL <= '0'; - SDA <= 'Z'; - state <= s20; - - when s20 => - SCL <= 'Z'; - dataRcvd(bitcount) <= SDA_IN; -- Read byte from bus MSB first - if (bitcount - 1) >= 0 then - bitcount <= bitcount - 1; - state <= s19; - else - bitcount <= 7; - state <= s21; - end if; - - -- Send not acknowledge signal - when s21 => - SCL <= '0'; - SDA <= 'Z'; -- Send not acknowledge signal (1) - state <= s22; - - when s22 => - SCL <= 'Z'; -- Clocking out not acknowledge signal - state <= stop0; - - - ------------------------------------------------------------------ - -- STOP transfer and handle received data - ------------------------------------------------------------------ - when stop0 => - SCL <= '0'; - SDA <= '0'; -- SDA goes to 0 to prepare for 0 to 1 transition - state <= stop1; - - when stop1 => - SCL <= 'Z'; - SDA <= '0'; - latch_data <= '1'; - state <= stop2; - - when stop2 => - SCL <= 'Z'; - SDA <= 'Z'; -- SDA changes from 0 to 1 while SCL is 1 -> Stop - latch_data <= '0'; - state <= stop2; -- FSM idle until next reset - - ------------------------------------------------------------------ - -- Error (only usefull if status checked externally) - ------------------------------------------------------------------ - -- Gets here only if Ack is error - --WHEN x"EE" => - -- SCL <= '1'; - -- SDA <= '1'; - -- state <= x"EE"; - - -- Catch invalid states - when others => - SCL <= 'Z'; - SDA <= 'Z'; - end case; - end if; - end if; - end process; - - ----------------------------------------------------------------------------------------------- -end Behavioral; --- END --- END --- END --- END --- END --- END --- END --- END --- END --- ----------------------------------------------------------------------------------------------- diff --git a/base/code/SFP_DDM_periph_hub_v1.0.vhd b/base/code/SFP_DDM_periph_hub_v1.0.vhd new file mode 100644 index 0000000..77cf1d6 --- /dev/null +++ b/base/code/SFP_DDM_periph_hub_v1.0.vhd @@ -0,0 +1,445 @@ +---------------------------------------------------------------------------------- +-- Company: GSI, Darmstadt (RBEE) +-- Engineer: Henning Heggen +-- +-- Create Date: 2015/08/11 +-- Design Name: +-- Module Name: SFP_DDM_periph_hub - Behavioral +-- Project Name: +-- Target Devices: TRB3 peripheral FPGA with HUB Addon +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use IEEE.MATH_REAL.all; + +library work; +use work.trb_net_std.all; + + +entity SFP_DDM_periph_hub is + port( + CLK100 : in std_logic; + TRB_RESET : in std_logic; + + BUSDDM_RX : in CTRLBUS_RX; + BUSDDM_TX : out CTRLBUS_TX; + + SCL_EXT : out std_logic_vector(6 downto 1); + SDA_EXT : inout std_logic_vector(6 downto 1) + ); +end SFP_DDM_periph_hub; + +architecture Behavioral of SFP_DDM_periph_hub is + + -- Control and data register + signal CTRL_DATA_REG : std_logic_vector(2*32-1 downto 0) := x"FBFBFBFBFBFBFFFF"; + + -- I2C state machine signals + signal SCL : std_logic; + signal SDA : std_logic; + signal SDA_IN : std_logic; + signal resetI2C : std_logic; + type state_type is (reset, start, s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, + s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, stop0, stop1, stop2, Err); + signal state : state_type; + signal bitcount : integer range 0 to 7; + constant slaveAddr_W : std_logic_vector(7 downto 0) := "10100010"; --slaveAddr & '0'; + constant slaveAddr_R : std_logic_vector(7 downto 0) := "10100011"; --slaveAddr & '1'; + signal byteAddr : std_logic_vector(7 downto 0) := x"68"; -- Address of first diagnostic byte to read (2 bytes read) + -- Bytes 96/97: Temperature MSB/LSB + -- Bytes 98/99: Vcc MSB/LSB + -- Bytes 100/101: Tx bias current + -- Bytes 102/103: Transceiver Tx power MSB/LSB + -- Bytes 104/105: Transceiver Rx power MSB/LSB + signal dataRcvd : std_logic_vector(15 downto 0); + + -- I2C output signals + signal SCL_OUT : std_logic_vector(6 downto 1); + signal SDA_OUT : std_logic_vector(6 downto 1); + + -- Clock division for I2C state machine + signal div512 : unsigned(8 downto 0) := (others => '0'); + signal CLK_I2C : std_logic; + + -- Signals for control state machine / multiplexing + signal SEL : integer range 1 to 6 := 1; + signal enable : std_logic_vector(6 downto 1); + signal timer : integer range 0 to 32767 := 0; + +------------------------------------------------------------------------------- +begin ---- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN - +------------------------------------------------------------------------------- + + -- Output MUX + with SEL select SCL_OUT <= + (1 => SCL, others => '1') when 1, + (2 => SCL, others => '1') when 2, + (3 => SCL, others => '1') when 3, + (4 => SCL, others => '1') when 4, + (5 => SCL, others => '1') when 5, + (6 => SCL, others => '1') when 6, + (others => '1') when others; + + with SEL select SDA_OUT <= + (1 => SDA, others => '1') when 1, + (2 => SDA, others => '1') when 2, + (3 => SDA, others => '1') when 3, + (4 => SDA, others => '1') when 4, + (5 => SDA, others => '1') when 5, + (6 => SDA, others => '1') when 6, + (others => '1') when others; + + -- Input MUX + with SEL select SDA_IN <= + SDA_EXT(1) when 1, + SDA_EXT(2) when 2, + SDA_EXT(3) when 3, + SDA_EXT(4) when 4, + SDA_EXT(5) when 5, + SDA_EXT(6) when 6, + '1' when others; + + -- Tri-state IO-buffers + SCL_EXT(1) <= '0' when SCL_OUT(1) = '0' else 'Z'; + SCL_EXT(2) <= '0' when SCL_OUT(2) = '0' else 'Z'; + SCL_EXT(3) <= '0' when SCL_OUT(3) = '0' else 'Z'; + SCL_EXT(4) <= '0' when SCL_OUT(4) = '0' else 'Z'; + SCL_EXT(5) <= '0' when SCL_OUT(5) = '0' else 'Z'; + SCL_EXT(6) <= '0' when SCL_OUT(6) = '0' else 'Z'; + + SDA_EXT(1) <= '0' when SDA_OUT(1) = '0' else 'Z'; + SDA_EXT(2) <= '0' when SDA_OUT(2) = '0' else 'Z'; + SDA_EXT(3) <= '0' when SDA_OUT(3) = '0' else 'Z'; + SDA_EXT(4) <= '0' when SDA_OUT(4) = '0' else 'Z'; + SDA_EXT(5) <= '0' when SDA_OUT(5) = '0' else 'Z'; + SDA_EXT(6) <= '0' when SDA_OUT(6) = '0' else 'Z'; + + -- Enable signals (slow control) + enable(6 downto 1) <= CTRL_DATA_REG(5 downto 0); + + ----------------------------------------------------------------------------- + -- SFP DDM CTRL_DATA_REG Bus Handler + ----------------------------------------------------------------------------- + PROC_CTRL_DATA_REG : process + variable pos : integer; + begin + wait until rising_edge(CLK100); + if (TRB_RESET = '1') then + CTRL_DATA_REG(15 downto 0) <= x"FFFF"; -- On reset, enable all channels + end if; + pos := to_integer(unsigned(busddm_rx.addr))*32; + busddm_tx.data <= CTRL_DATA_REG(pos+31 downto pos); + busddm_tx.ack <= busddm_rx.read; + if busddm_rx.write = '1' and to_integer(unsigned(busddm_rx.addr)) = 0 then + CTRL_DATA_REG(15 downto 0) <= busddm_rx.data(15 downto 0); + end if; + end process; + + ------------------------------------------------------------------------------ + -- Clock for I2C state machine (200kHz for 100kHz bit rate (SCL)) + ------------------------------------------------------------------------------ + I2C_Clock : process (CLK100) + begin + if RISING_EDGE(CLK100) then + div512 <= to_unsigned((to_integer(div512) + 1), 9); + CLK_I2C <= div512(8); + end if; + end process; + + ------------------------------------------------------------------------------ + -- Timer (Periodically toggles selected CH and resets I2C statemachine) + ------------------------------------------------------------------------------ + Timer_Proc : process(CLK_I2C) + begin + if RISING_EDGE(CLK_I2C) then + + timer <= timer + 1; + + if (timer = 0) then + if (SEL < 6) then + SEL <= SEL + 1; + else + SEL <= 1; + end if; + resetI2C <= '1'; + else + resetI2C <= '0'; + end if; + + end if; + end process; + + ------------------------------------------------------------------------------ + -- I2C state machine + ------------------------------------------------------------------------------ + I2C_FSM : process (CLK_I2C, resetI2C, SEL) + begin + if RISING_EDGE(CLK_I2C) then + if (resetI2C = '1') then -- Periodic reset + state <= reset; + else + case state is + ------------------------------------------------------------------ + -- Start signal + ------------------------------------------------------------------ + when reset => -- Idle + SCL <= '1'; + SDA <= '1'; + if (enable(SEL)) = '1' then -- If selected CH enabled -> Start + dataRcvd <= x"0FC0"; + state <= start; + else + dataRcvd <= x"0FD0"; -- If not -> mark as disabled + state <= stop1; + end if; + + when start => -- Start + SCL <= '1'; + SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> start + bitcount <= 7; -- Initializing bit counter + state <= s00; + + ------------------------------------------------------------------ + -- Send 7-bit slave address plus write bit, MSB first + ------------------------------------------------------------------ + when s00 => + SCL <= '0'; + SDA <= slaveAddr_W(bitcount); + state <= s01; + + when s01 => + SCL <= '1'; + if (bitcount - 1) >= 0 then + bitcount <= bitcount - 1; + state <= s00; -- Continue transfer + else + bitcount <= 7; + state <= s02; -- Check for acknowledgement + end if; + + -- Get acknowledgement from slave and continue + when s02 => + SCL <= '0'; + SDA <= '1'; + state <= s03; + + when s03 => + SCL <= '1'; + if SDA_IN = '0' then + state <= s04; -- Acknowledge received => go on + else + state <= Err; -- No acknowledge => abort + end if; + + ------------------------------------------------------------------ + -- Send 8-bit address of diagnostic byte, MSB first + ------------------------------------------------------------------ + when s04 => + SCL <= '0'; + SDA <= byteAddr(bitcount); + state <= s05; + + when s05 => + SCL <= '1'; + if (bitcount - 1) >= 0 then + bitcount <= bitcount - 1; + state <= s04; -- continue transfer + else + bitcount <= 7; + state <= s06; -- check for acknowledgement + end if; + + -- Get acknowledgement from slave and continue + when s06 => + SCL <= '0'; + SDA <= '1'; + state <= s07; + + when s07 => + SCL <= '1'; + if SDA_IN = '0' then + state <= s08; -- Acknowledge received => go on + else + state <= Err; -- No acknowledge => abort + end if; + + ------------------------------------------------------------------ + -- Send repeated start signal + ------------------------------------------------------------------ + when s08 => + SCL <= '0'; + SDA <= '1'; + if SDA_IN = '0' then -- SDA should still be 0 here from acknowledgement + state <= s09; + else + state <= Err; -- No acknowledge => abort + end if; + + when s09 => + SCL <= '1'; + SDA <= '1'; + state <= s10; + + when s10 => -- Start + SCL <= '1'; + SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> Start + state <= s11; + + ------------------------------------------------------------------ + -- Send 7-bit slave address plus read bit, MSB first + ------------------------------------------------------------------ + when s11 => + SCL <= '0'; + SDA <= slaveAddr_R(bitcount); + state <= s12; + + when s12 => + SCL <= '1'; + if (bitcount - 1) >= 0 then + bitcount <= bitcount - 1; + state <= s11; -- continue transfer + else + bitcount <= 7; + state <= s13; -- check for acknowledgement + end if; + + -- Get acknowledgement from slave and continue + when s13 => + SCL <= '0'; + SDA <= '1'; + state <= s14; + + when s14 => + SCL <= '1'; + if SDA_IN = '0' then + state <= s15; -- Acknowledge received => go on + else + state <= Err; -- No acknowledge => abort + end if; + + ------------------------------------------------------------------ + -- Read 1st byte (MSB) from slave (MSB first) + ------------------------------------------------------------------ + when s15 => + SCL <= '0'; + SDA <= '1'; + state <= s16; + + when s16 => + SCL <= '1'; + dataRcvd(8 + bitcount) <= SDA_IN; -- Read byte from bus MSB first + if (bitcount - 1) >= 0 then + bitcount <= bitcount - 1; + state <= s15; + else + bitcount <= 7; + state <= s17; + end if; + + -- Send acknowledge signal + when s17 => + SCL <= '0'; + SDA <= '0'; -- Send acknowledge signal (0) + state <= s18; + + when s18 => + SCL <= '1'; -- Clocking out acknowledge signal + state <= s19; + + ------------------------------------------------------------------ + -- Read 2nd byte (LSB) from slave (MSB first) + ------------------------------------------------------------------ + when s19 => + SCL <= '0'; + SDA <= '1'; + state <= s20; + + when s20 => + SCL <= '1'; + dataRcvd(bitcount) <= SDA_IN; -- Read byte from bus MSB first + if (bitcount - 1) >= 0 then + bitcount <= bitcount - 1; + state <= s19; + else + bitcount <= 7; + state <= s21; + end if; + + -- Send not acknowledge signal + when s21 => + SCL <= '0'; + SDA <= '1'; -- Send not acknowledge signal (1) + state <= s22; + + when s22 => + SCL <= '1'; -- Clocking out not acknowledge signal + state <= stop0; + + + ------------------------------------------------------------------ + -- STOP transfer and handle received data + ------------------------------------------------------------------ + when stop0 => + SCL <= '0'; + SDA <= '0'; -- SDA goes to 0 to prepare for 0 to 1 transition + state <= stop1; + + when stop1 => + SCL <= '1'; + SDA <= '0'; + if (SEL = 1) then + CTRL_DATA_REG(16+1*8-1 downto 16+(1-1)*8) <= dataRcvd(11 downto 4); + elsif (SEL = 2) then + CTRL_DATA_REG(16+2*8-1 downto 16+(2-1)*8) <= dataRcvd(11 downto 4); + elsif (SEL = 3) then + CTRL_DATA_REG(16+3*8-1 downto 16+(3-1)*8) <= dataRcvd(11 downto 4); + elsif (SEL = 4) then + CTRL_DATA_REG(16+4*8-1 downto 16+(4-1)*8) <= dataRcvd(11 downto 4); + elsif (SEL = 5) then + CTRL_DATA_REG(16+5*8-1 downto 16+(5-1)*8) <= dataRcvd(11 downto 4); + elsif (SEL = 6) then + CTRL_DATA_REG(16+6*8-1 downto 16+(6-1)*8) <= dataRcvd(11 downto 4); + else + CTRL_DATA_REG <= CTRL_DATA_REG; + end if; + state <= stop2; + + when stop2 => + SCL <= '1'; + SDA <= '1'; -- SDA changes from 0 to 1 while SCL is 1 -> Stop + state <= stop2; -- FSM idle until next reset + + ------------------------------------------------------------------ + -- Error + ------------------------------------------------------------------ + -- Gets here only if Ack is error + when Err => + SCL <= '0'; + SDA <= '0'; + dataRcvd <= x"0FE0"; + state <= stop1; + + -- Catch invalid states + when others => + SCL <= '1'; + SDA <= '1'; + state <= Err; + end case; + end if; + end if; + end process; + + +---------------------------------------------------------------------------------------------- +end Behavioral; --- END --- END --- END --- END --- END --- END --- END --- END --- END --- +---------------------------------------------------------------------------------------------- diff --git a/hub/compile.pl b/hub/compile.pl new file mode 120000 index 0000000..4456748 --- /dev/null +++ b/hub/compile.pl @@ -0,0 +1 @@ +../scripts/compile.pl \ No newline at end of file diff --git a/hub/config_compile.pl b/hub/config_compile.pl new file mode 120000 index 0000000..67b86a0 --- /dev/null +++ b/hub/config_compile.pl @@ -0,0 +1 @@ +config_compile_gsi.pl \ No newline at end of file diff --git a/hub/config_compile_gsi.pl b/hub/config_compile_gsi.pl new file mode 100644 index 0000000..d56ff3c --- /dev/null +++ b/hub/config_compile_gsi.pl @@ -0,0 +1,20 @@ +TOPNAME => "trb3_periph_hub", +lm_license_file_for_synplify => "27000\@lxcad01.gsi.de", +lm_license_file_for_par => "1702\@hadeb05.gsi.de", +lattice_path => '/opt/lattice/diamond/3.5_x64/', +synplify_path => '/opt/synplicity/J-2014.09-SP2', +#synplify_command => "/opt/lattice/diamond/3.4_x64/bin/lin64/synpwrap -fg -options", +synplify_command => "/opt/synplicity/J-2014.09-SP2/bin/synplify_premier_dp", + +#Include only necessary lpf files +include_TDC => 0, +include_GBE => 0, +include_CTS => 0, +include_HUB => 1, # for the hub design on periph fpga +central_FPGA => 0, + +#Report settings +firefox_open => 1, +twr_number_of_errors => 20, + + diff --git a/hub/trb3_periph_hub.prj b/hub/trb3_periph_hub.prj index 08ee24b..f9762eb 100644 --- a/hub/trb3_periph_hub.prj +++ b/hub/trb3_periph_hub.prj @@ -101,8 +101,10 @@ add_file -vhdl -lib work "../../trbnet/special/spi_master.vhd" add_file -vhdl -lib work "../../trbnet/special/spi_slim.vhd" add_file -vhdl -lib work "../../trbnet/special/spi_databus_memory.vhd" add_file -vhdl -lib work "../../trbnet/special/fpga_reboot.vhd" -add_file -vhdl -lib work "../../trbnet/sfp_interface.vhd" -add_file -vhdl -lib work "../../trbnet/special/sfp_i2c_readout.vhd" + +#add_file -vhdl -lib work "../../trbnet/sfp_interface.vhd" +#add_file -vhdl -lib work "../../trbnet/special/sfp_i2c_readout.vhd" +add_file -vhdl -lib work "../base/code/SFP_DDM_periph_hub_v1.0.vhd" add_file -vhdl -lib work "../../trbnet/lattice/ecp3/spi_dpram_32_to_8.vhd" add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp2m_fifo.vhd" diff --git a/hub/trb3_periph_hub.vhd b/hub/trb3_periph_hub.vhd index fc67a5a..a7a8e0b 100644 --- a/hub/trb3_periph_hub.vhd +++ b/hub/trb3_periph_hub.vhd @@ -224,6 +224,9 @@ architecture trb3_periph_hub_arch of trb3_periph_hub is --FPGA Test signal time_counter : unsigned(31 downto 0); + -- SFP DDM + signal busddm_rx : CTRLBUS_RX; + signal busddm_tx : CTRLBUS_TX; begin --------------------------------------------------------------------------- @@ -525,27 +528,41 @@ THE_MEDIA_DOWNLINK : trb_net16_med_ecp3_sfp_4 ); - -THE_SFP_i2C : sfp_i2c_readout - generic map( - SFP_NUMBER => 6 - ) - port map( - CLOCK => clk_100_i, - RESET => reset_i, +------------------------------------------------------------------------------- +-- SFP I2C Digital Diagnostic Monitoring (DDM) Entity +------------------------------------------------------------------------------- +-- Generate_SFP_DDM : if INCLUDE_SFP_DDM = c_YES generate + THE_SFP_DDM : entity work.SFP_DDM_periph_hub + port map ( + CLK100 => clk_100_i, + TRB_RESET => reset_i, + BUSDDM_RX => busddm_rx, + BUSDDM_TX => busddm_tx, + SCL_EXT => SFP_MOD1, + SDA_EXT => SFP_MOD2 + ); +--end generate Generate_Sfp_DDM; + +--THE_SFP_i2C : sfp_i2c_readout +-- generic map( +-- SFP_NUMBER => 6 +-- ) +-- port map( +-- CLOCK => clk_100_i, +-- RESET => reset_i, - BUS_DATA_IN => i2c_data_in, - BUS_DATA_OUT => i2c_data_out, - BUS_ADDR_IN => i2c_addr, - BUS_WRITE_IN => i2c_write, - BUS_READ_IN => i2c_read, - BUS_ACK_OUT => i2c_ack, - BUS_NACK_OUT => i2c_nack, +-- BUS_DATA_IN => i2c_data_in, +-- BUS_DATA_OUT => i2c_data_out, +-- BUS_ADDR_IN => i2c_addr, +-- BUS_WRITE_IN => i2c_write, +-- BUS_READ_IN => i2c_read, +-- BUS_ACK_OUT => i2c_ack, +-- BUS_NACK_OUT => i2c_nack, - SDA => SFP_MOD2, --- SDA_IN => buf_SFP_MOD2_IN, - SCL => SFP_MOD1 - ); +-- SDA => SFP_MOD2, +---- SDA_IN => buf_SFP_MOD2_IN, +-- SCL => SFP_MOD1 +-- ); --------------------------------------------------------------------------- -- Hub @@ -628,7 +645,7 @@ THE_HUB : trb_net16_hub_base generic map( PORT_NUMBER => 6, PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"b000", 3 => x"b200", 4 => x"d600", 5 => x"d500", others => x"0000"), - PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 9, 3 => 9, 4 => 8, 5 => 4, others => 0) + PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 9, 3 => 9, 4 => 1, 5 => 4, others => 0) ) port map( CLK => clk_100_i, @@ -695,18 +712,30 @@ THE_HUB : trb_net16_hub_base BUS_WRITE_ACK_IN(3) => sci2_ack, BUS_NO_MORE_DATA_IN(3) => '0', BUS_UNKNOWN_ADDR_IN(3) => '0', - --I2C for SFP - BUS_READ_ENABLE_OUT(4) => i2c_read, - BUS_WRITE_ENABLE_OUT(4) => i2c_write, - BUS_DATA_OUT(4*32+31 downto 4*32) => i2c_data_in, - BUS_ADDR_OUT(4*16+7 downto 4*16) => i2c_addr, - BUS_ADDR_OUT(4*16+15 downto 4*16+9) => open, + --SFP DDM + BUS_READ_ENABLE_OUT(4) => busddm_rx.read, + BUS_WRITE_ENABLE_OUT(4) => busddm_rx.write, + BUS_DATA_OUT(4*32+15 downto 4*32) => busddm_rx.data(15 downto 0), + BUS_ADDR_OUT(4*16+1 downto 4*16) => busddm_rx.addr(1 downto 0), + BUS_ADDR_OUT(4*16+15 downto 4*16+2) => open, BUS_TIMEOUT_OUT(4) => open, - BUS_DATA_IN(4*32+31 downto 4*32) => i2c_data_out, - BUS_DATAREADY_IN(4) => i2c_ack, - BUS_WRITE_ACK_IN(4) => i2c_ack, + BUS_DATA_IN(4*32+31 downto 4*32) => busddm_tx.data, + BUS_DATAREADY_IN(4) => busddm_tx.ack, + BUS_WRITE_ACK_IN(4) => busddm_rx.write, BUS_NO_MORE_DATA_IN(4) => '0', - BUS_UNKNOWN_ADDR_IN(4) => i2c_nack, + BUS_UNKNOWN_ADDR_IN(4) => '0', + --I2C for SFP + --BUS_READ_ENABLE_OUT(4) => i2c_read, + --BUS_WRITE_ENABLE_OUT(4) => i2c_write, + --BUS_DATA_OUT(4*32+31 downto 4*32) => i2c_data_in, + --BUS_ADDR_OUT(4*16+7 downto 4*16) => i2c_addr, + --BUS_ADDR_OUT(4*16+15 downto 4*16+9) => open, + --BUS_TIMEOUT_OUT(4) => open, + --BUS_DATA_IN(4*32+31 downto 4*32) => i2c_data_out, + --BUS_DATAREADY_IN(4) => i2c_ack, + --BUS_WRITE_ACK_IN(4) => i2c_ack, + --BUS_NO_MORE_DATA_IN(4) => '0', + --BUS_UNKNOWN_ADDR_IN(4) => i2c_nack, --SEU Detection BUS_READ_ENABLE_OUT(5) => bussed_rx.read, BUS_WRITE_ENABLE_OUT(5) => bussed_rx.write, diff --git a/scripts/compile.pl b/scripts/compile.pl index f0b5452..13555d8 100755 --- a/scripts/compile.pl +++ b/scripts/compile.pl @@ -21,6 +21,9 @@ my $lattice_bin_path = "$lattice_path/bin/lin64"; # note the lin/lin my $include_TDC = $config{include_TDC} || 0; my $include_GBE = $config{include_GBE} || 0; +my $include_CTS = $config{include_CTS} || 0; +my $include_HUB = $config{include_HUB} || 0; +my $central_FPGA = $config{central_FPGA} || 0; my $twr_number_of_errors = $config{twr_number_of_errors} || 10; @@ -98,8 +101,11 @@ $ENV{'LM_LICENSE_FILE'}=$lm_license_file_for_synplify; my $FAMILYNAME="LatticeECP3"; my $DEVICENAME="LFE3-150EA"; -my $PACKAGE="FPBGA672"; my $SPEEDGRADE="8"; +my $PACKAGE="FPBGA672"; +if ($central_FPGA) { +$PACKAGE="FPBGA1156"; +} my $WORKDIR = "workdir"; unless(-d $WORKDIR) { @@ -112,7 +118,7 @@ system("ln -sfT $lattice_path $WORKDIR/lattice-diamond"); print GREEN, "Generating constraints file...\n\n", RESET; system("cp ../base/$TOPNAME.lpf $WORKDIR/$TOPNAME.lpf"); -if($include_TDC) { +if($include_TDC && $include_CTS==0) { system("cat tdc_release/trbnet_constraints.lpf >> $WORKDIR/$TOPNAME.lpf"); system("cat tdc_release/tdc_constraints_64.lpf >> $WORKDIR/$TOPNAME.lpf"); system("cat tdc_release/unimportant_lines_constraints.lpf >> $WORKDIR/$TOPNAME.lpf"); @@ -120,6 +126,18 @@ if($include_TDC) { } if($include_GBE) { +} +if($include_HUB) { + system("cat trb3_periph_hub_constraints.lpf >> $WORKDIR/$TOPNAME.lpf"); +} + +if($include_CTS) { +my $CbmNetPath = "../../cbmnet"; +my $config_vhd = 'config_mainz_a2.vhd'; +system("ln -f -s $config_vhd config.vhd") unless (-e "config.vhd"); +system("./compile_constraints.pl"); +system("cp ../base/mulipar_nodelist_example.txt workdir/nodelist.txt") unless (-e "workdir/nodelist.txt"); +symlink($CbmNetPath, '../cbmnet/cbmnet') unless (-e '../cbmnet/cbmnet'); } if($include_TDC) { @@ -253,7 +271,7 @@ if($par==1 || $all==1){ system("rm $TOPNAME.ncd"); if ($isMultiPar) { - $c=qq|LC_ALL=en_US.UTF-8; par -m ../nodes_lxhadeb07.txt -n $nrNodes -w -i 15 -l 5 -y -s 8 -t 33 -c 1 -e 2 -exp parCDP=1:parCDR=1:parPlcInLimit=0:parPlcInNeighborSize=1:parPathBased=ON:parHold=1:parHoldLimit=10000:paruseNBR=1 $tpmap.ncd $TOPNAME.dir $TOPNAME.prf;|; + $c=qq|LC_ALL=en_US.UTF-8; par -m nodelist.txt -n $nrNodes -w -i 15 -l 5 -y -s 8 -t 1 -c 1 -e 2 -exp parCDP=1:parCDR=1:parPlcInLimit=0:parPlcInNeighborSize=1:parPathBased=ON:parHold=1:parHoldLimit=10000:paruseNBR=1 $tpmap.ncd $TOPNAME.dir $TOPNAME.prf;|; execute($c); # find and copy the .ncd file which has met the timing constraints -- 2.43.0