+++ /dev/null
-----------------------------------------------------------------------------------\r
--- Company: GSI, Darmstadt (CSEE)\r
--- Engineer: Henning Heggen\r
--- \r
--- Create Date: 09:50:07 11/27/2014 \r
--- Design Name: \r
--- Module Name: SFP_DDM - Behavioral \r
--- Project Name: \r
--- Target Devices: \r
--- Tool versions: \r
--- Description: \r
---\r
--- Dependencies: \r
---\r
--- Revision: \r
--- Revision 0.01 - File Created\r
--- Additional Comments: \r
---\r
-----------------------------------------------------------------------------------\r
-library IEEE;\r
-use IEEE.STD_LOGIC_1164.all;\r
-use IEEE.STD_LOGIC_ARITH.all;\r
-use IEEE.STD_LOGIC_UNSIGNED.all;\r
-\r
-\r
-entity SFP_DDM is\r
- port(\r
- CLK100 : in std_logic;\r
- SLOW_CTRL_IN : in std_logic_vector(31 downto 0);\r
- DATA_OUT : out std_logic_vector(3*32-1 downto 0);\r
- SCL_EXT : out std_logic_vector(8 downto 1);\r
- SDA_EXT : inout std_logic_vector(8 downto 1)\r
- );\r
-end SFP_DDM;\r
-\r
-architecture Behavioral of SFP_DDM is\r
-\r
- signal SDA_IN : std_logic;\r
- signal SDA : std_logic;\r
- signal SCL : std_logic;\r
- signal resetI2C : std_logic;\r
- \r
- type state_type is (reset, start, s00, s01, s02, s03, s04, s05, s06, s07, s08, s09,\r
- s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, stop0, stop1, stop2);\r
- signal state : state_type;\r
- signal bitcount : integer range 0 to 7;\r
- constant slaveAddr_W : std_logic_vector(7 downto 0) := "10100010"; --slaveAddr & '0';\r
- constant slaveAddr_R : std_logic_vector(7 downto 0) := "10100011"; --slaveAddr & '1';\r
- signal byteAddr : std_logic_vector(7 downto 0);\r
- signal dataRcvd : std_logic_vector(15 downto 0);\r
- signal latch_data : std_logic := '0';\r
-\r
- -- Clock division for I2C state machine\r
- signal div512 : std_logic_vector(8 downto 0) := "000000000";\r
- signal CLK_I2C : std_logic;\r
-\r
- -- Signals for control state machine\r
- signal counter : integer range 0 to 127 := 0;\r
- signal SEL : integer range 0 to 1535 := 0;\r
- signal run : std_logic;\r
- signal running : std_logic := '0';\r
- signal selSFPs : std_logic_vector(8 downto 1);\r
-\r
-----------------------------------------------------------------------------------\r
-begin ---- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- \r
-----------------------------------------------------------------------------------\r
-\r
- -- Global signal assignments\r
- run <= not SLOW_CTRL_IN(0);\r
- selSFPs(8 downto 1) <= not SLOW_CTRL_IN(11 downto 4);\r
- DATA_OUT(95 downto 64) <= x"00000000";\r
-\r
- -- Address of diagnostic byte to read\r
- -- Bytes 96/97: Temperature MSB/LSB\r
- -- Bytes 98/99: Vcc MSB/LSB\r
- -- Bytes 100/101: Tx bias current\r
- -- Bytes 102/103: Transceiver Tx power MSB/LSB\r
- -- Bytes 104/105: Transceiver Rx power MSB/LSB\r
- byteAddr <= CONV_STD_LOGIC_VECTOR(104, 8);\r
-\r
- ------------------------------------------------------------------------------\r
- -- Clock for I2C state machine\r
- -- FSM states toggle SCL => 2 FSM cycles = 1 SCL cycle (transfer of 1 bit)\r
- -- => FSM must run at twice the SCL frequency\r
- -- I2C standard: SCL = 100kHz => CLK_I2C needs to run at 200kHz\r
- ------------------------------------------------------------------------------\r
- I2C_Clock : process (CLK100)\r
- begin\r
- if RISING_EDGE(CLK100) then\r
- div512 <= div512 + 1;\r
- if (div512(8) = '0') then\r
- CLK_I2C <= '0';\r
- else\r
- CLK_I2C <= '1';\r
- end if;\r
- end if;\r
- end process;\r
-\r
- ------------------------------------------------------------------------------\r
- -- Slow control\r
- ------------------------------------------------------------------------------\r
- Control_FSM : process(CLK_I2C)\r
- begin\r
- if RISING_EDGE(CLK_I2C) then\r
- if (run = '1' and running = '0') then\r
- counter <= 1;\r
- SEL <= 1;\r
- running <= '1';\r
- resetI2C <= '0';\r
- elsif (running = '1' and SEL /= 0) then\r
- resetI2C <= '0';\r
- counter <= counter + 1; -- Overflow every 128 cycles of CLK_I2C\r
- if (counter = 0) then\r
- SEL <= SEL + 1;\r
- end if;\r
- if (counter = 2) then\r
- case SEL is\r
-\r
- when 1 =>\r
- if (selSFPs(1) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 2 =>\r
- if (selSFPs(2) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 3 =>\r
- if (selSFPs(3) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 4 =>\r
- if (selSFPs(4) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 5 =>\r
- if (selSFPs(5) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 6 =>\r
- if (selSFPs(6) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 7 =>\r
- if (selSFPs(7) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 8 =>\r
- if (selSFPs(8) = '1') then\r
- resetI2C <= '1';\r
- end if;\r
-\r
- when 1535 =>\r
- SEL <= 0;\r
- running <= '0';\r
- \r
- when others =>\r
- \r
- end case;\r
- end if;\r
- end if;\r
- end if;\r
- end process;\r
-\r
- -- I2C state machine output multiplexer (selects between SFP modules)\r
- process(CLK100, SEL)\r
- begin\r
- if RISING_EDGE(CLK100) then\r
- if (running = '0' and run = '0') then\r
- DATA_OUT(63 downto 0) <= x"FEFEFEFEFEFEFEFE";\r
- else\r
- case SEL is\r
- when 1 =>\r
- if (selSFPs(1) = '1') then\r
- SDA_EXT(1) <= SDA;\r
- SCL_EXT(1) <= SCL;\r
- SDA_IN <= SDA_EXT(1);\r
- if (latch_data = '1') then\r
- DATA_OUT(7 downto 0) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(7 downto 0) <= x"FE";\r
- end if;\r
- \r
- when 2 =>\r
- if (selSFPs(2) = '1') then\r
- SDA_EXT(2) <= SDA;\r
- SCL_EXT(2) <= SCL;\r
- SDA_IN <= SDA_EXT(2);\r
- if (latch_data = '1') then\r
- DATA_OUT(15 downto 8) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(15 downto 8) <= x"FE";\r
- end if;\r
- \r
- when 3 =>\r
- if (selSFPs(3) = '1') then\r
- SDA_EXT(3) <= SDA;\r
- SCL_EXT(3) <= SCL;\r
- SDA_IN <= SDA_EXT(3);\r
- if (latch_data = '1') then\r
- DATA_OUT(23 downto 16) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(23 downto 16) <= x"FE";\r
- end if;\r
-\r
- when 4 =>\r
- if (selSFPs(4) = '1') then\r
- SDA_EXT(4) <= SDA;\r
- SCL_EXT(4) <= SCL;\r
- SDA_IN <= SDA_EXT(4);\r
- if (latch_data = '1') then\r
- DATA_OUT(31 downto 24) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(31 downto 24) <= x"FE";\r
- end if;\r
- \r
- when 5 =>\r
- if (selSFPs(5) = '1') then\r
- SDA_EXT(5) <= SDA;\r
- SCL_EXT(5) <= SCL;\r
- SDA_IN <= SDA_EXT(5);\r
- if (latch_data = '1') then\r
- DATA_OUT(39 downto 32) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(39 downto 32) <= x"FE";\r
- end if;\r
-\r
- when 6 =>\r
- if (selSFPs(6) = '1') then\r
- SDA_EXT(6) <= SDA;\r
- SCL_EXT(6) <= SCL;\r
- SDA_IN <= SDA_EXT(6);\r
- if (latch_data = '1') then\r
- DATA_OUT(47 downto 40) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(47 downto 40) <= x"FE";\r
- end if;\r
-\r
- when 7 =>\r
- if (selSFPs(7) = '1') then\r
- SDA_EXT(7) <= SDA;\r
- SCL_EXT(7) <= SCL;\r
- SDA_IN <= SDA_EXT(7);\r
- if (latch_data = '1') then\r
- DATA_OUT(55 downto 48) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(55 downto 48) <= x"FE";\r
- end if;\r
-\r
- when 8 =>\r
- if (selSFPs(8) = '1') then\r
- SDA_EXT(8) <= SDA;\r
- SCL_EXT(8) <= SCL;\r
- SDA_IN <= SDA_EXT(8);\r
- if (latch_data = '1') then\r
- DATA_OUT(63 downto 56) <= dataRcvd(11 downto 4);\r
- end if;\r
- else\r
- DATA_OUT(63 downto 56) <= x"FE";\r
- end if;\r
-\r
- when others =>\r
- SCL_EXT <= (others => 'Z');\r
- SDA_EXT <= (others => 'Z');\r
- end case;\r
- end if;\r
- end if;\r
- end process;\r
-\r
- ------------------------------------------------------------------------------\r
- -- I2C state machine\r
- ------------------------------------------------------------------------------\r
- I2C_FSM : process (CLK_I2C, resetI2C)\r
- begin\r
- if RISING_EDGE(CLK_I2C) then\r
- if (resetI2C = '1') then -- Reset\r
- state <= reset;\r
- else\r
- case state is\r
- ------------------------------------------------------------------\r
- -- Start signal\r
- ------------------------------------------------------------------\r
- when reset => -- Idle\r
- SCL <= 'Z';\r
- SDA <= 'Z';\r
- dataRcvd <= x"0FE0";\r
- latch_data <= '0';\r
- state <= start;\r
- \r
- when start => -- Start\r
- SCL <= 'Z';\r
- SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> start\r
- bitcount <= 7; -- Initializing bit counter\r
- state <= s00;\r
-\r
- ------------------------------------------------------------------\r
- -- Send 7-bit slave address plus write bit, MSB first\r
- ------------------------------------------------------------------\r
- when s00 =>\r
- SCL <= '0';\r
- SDA <= slaveAddr_W(bitcount);\r
- state <= s01;\r
- \r
- when s01 =>\r
- SCL <= 'Z';\r
- if (bitcount - 1) >= 0 then\r
- bitcount <= bitcount - 1;\r
- state <= s00; -- Continue transfer\r
- else\r
- bitcount <= 7;\r
- state <= s02; -- Check for acknowledgement\r
- end if;\r
-\r
- -- Get acknowledgement from slave and continue\r
- when s02 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- state <= s03;\r
- \r
- when s03 =>\r
- SCL <= 'Z';\r
- if SDA_IN = '0' then\r
- state <= s04; -- Acknowledge received => go on\r
- else\r
- state <= stop1; -- No acknowledge => abort\r
- end if;\r
-\r
- ------------------------------------------------------------------\r
- -- Send 8-bit address of diagnostic byte, MSB first\r
- ------------------------------------------------------------------\r
- when s04 =>\r
- SCL <= '0';\r
- SDA <= byteAddr(bitcount);\r
- state <= s05;\r
- \r
- when s05 =>\r
- SCL <= 'Z';\r
- if (bitcount - 1) >= 0 then\r
- bitcount <= bitcount - 1;\r
- state <= s04; -- continue transfer\r
- else\r
- bitcount <= 7;\r
- state <= s06; -- check for acknowledgement\r
- end if;\r
-\r
- -- Get acknowledgement from slave and continue\r
- when s06 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- state <= s07;\r
- \r
- when s07 =>\r
- SCL <= 'Z';\r
- if SDA_IN = '0' then\r
- state <= s08; -- Acknowledge received => go on\r
- else\r
- state <= stop1; -- No acknowledge => abort\r
- end if;\r
-\r
- ------------------------------------------------------------------\r
- -- Send repeated start signal\r
- ------------------------------------------------------------------\r
- when s08 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- if SDA_IN = '0' then -- SDA should still be 0 here from acknowledgement\r
- state <= s09;\r
- else\r
- state <= stop1; -- No acknowledge => abort\r
- end if;\r
- \r
- when s09 =>\r
- SCL <= 'Z';\r
- SDA <= 'Z';\r
- state <= s10;\r
- \r
- when s10 => -- Start\r
- SCL <= 'Z';\r
- SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> Start\r
- state <= s11;\r
-\r
- ------------------------------------------------------------------ \r
- -- Send 7-bit slave address plus read bit, MSB first\r
- ------------------------------------------------------------------\r
- when s11 =>\r
- SCL <= '0';\r
- SDA <= slaveAddr_R(bitcount);\r
- state <= s12;\r
- \r
- when s12 =>\r
- SCL <= 'Z';\r
- if (bitcount - 1) >= 0 then\r
- bitcount <= bitcount - 1;\r
- state <= s11; -- continue transfer\r
- else\r
- bitcount <= 7;\r
- state <= s13; -- check for acknowledgement\r
- end if;\r
-\r
- -- Get acknowledgement from slave and continue\r
- when s13 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- state <= s14;\r
- \r
- when s14 =>\r
- SCL <= 'Z';\r
- if SDA_IN = '0' then\r
- state <= s15; -- Acknowledge received => go on\r
- else\r
- state <= stop1; -- No acknowledge => abort\r
- end if;\r
-\r
- ------------------------------------------------------------------ \r
- -- Read 1st byte (MSB) from slave (MSB first)\r
- ------------------------------------------------------------------\r
- when s15 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- state <= s16;\r
- \r
- when s16 =>\r
- SCL <= 'Z';\r
- dataRcvd(8 + bitcount) <= SDA_IN; -- Read byte from bus MSB first\r
- if (bitcount - 1) >= 0 then\r
- bitcount <= bitcount - 1;\r
- state <= s15;\r
- else\r
- bitcount <= 7;\r
- state <= s17;\r
- end if;\r
-\r
- -- Send acknowledge signal\r
- when s17 =>\r
- SCL <= '0';\r
- SDA <= '0'; -- Send acknowledge signal (0)\r
- state <= s18;\r
- \r
- when s18 =>\r
- SCL <= 'Z'; -- Clocking out acknowledge signal\r
- state <= s19;\r
-\r
- ------------------------------------------------------------------\r
- -- Read 2nd byte (LSB) from slave (MSB first)\r
- ------------------------------------------------------------------\r
- when s19 =>\r
- SCL <= '0';\r
- SDA <= 'Z';\r
- state <= s20;\r
- \r
- when s20 =>\r
- SCL <= 'Z';\r
- dataRcvd(bitcount) <= SDA_IN; -- Read byte from bus MSB first\r
- if (bitcount - 1) >= 0 then\r
- bitcount <= bitcount - 1;\r
- state <= s19;\r
- else\r
- bitcount <= 7;\r
- state <= s21;\r
- end if;\r
-\r
- -- Send not acknowledge signal\r
- when s21 =>\r
- SCL <= '0';\r
- SDA <= 'Z'; -- Send not acknowledge signal (1)\r
- state <= s22;\r
- \r
- when s22 =>\r
- SCL <= 'Z'; -- Clocking out not acknowledge signal\r
- state <= stop0;\r
-\r
-\r
- ------------------------------------------------------------------\r
- -- STOP transfer and handle received data\r
- ------------------------------------------------------------------\r
- when stop0 =>\r
- SCL <= '0';\r
- SDA <= '0'; -- SDA goes to 0 to prepare for 0 to 1 transition\r
- state <= stop1;\r
- \r
- when stop1 =>\r
- SCL <= 'Z';\r
- SDA <= '0';\r
- latch_data <= '1';\r
- state <= stop2;\r
- \r
- when stop2 =>\r
- SCL <= 'Z';\r
- SDA <= 'Z'; -- SDA changes from 0 to 1 while SCL is 1 -> Stop\r
- latch_data <= '0';\r
- state <= stop2; -- FSM idle until next reset\r
-\r
- ------------------------------------------------------------------\r
- -- Error (only usefull if status checked externally)\r
- ------------------------------------------------------------------\r
- -- Gets here only if Ack is error\r
- --WHEN x"EE" =>\r
- -- SCL <= '1';\r
- -- SDA <= '1';\r
- -- state <= x"EE";\r
-\r
- -- Catch invalid states\r
- when others =>\r
- SCL <= 'Z';\r
- SDA <= 'Z';\r
- end case;\r
- end if;\r
- end if;\r
- end process;\r
-\r
-\r
-----------------------------------------------------------------------------------------------\r
-end Behavioral; --- END --- END --- END --- END --- END --- END --- END --- END --- END ---\r
-----------------------------------------------------------------------------------------------\r
--- /dev/null
+----------------------------------------------------------------------------------\r
+-- Company: GSI, Darmstadt (RBEE)\r
+-- Engineer: Henning Heggen\r
+-- \r
+-- Create Date: 2015/08/11\r
+-- Design Name: \r
+-- Module Name: SFP_DDM_periph_hub - Behavioral \r
+-- Project Name: \r
+-- Target Devices: TRB3 peripheral FPGA with HUB Addon\r
+-- Tool versions: \r
+-- Description: \r
+--\r
+-- Dependencies: \r
+--\r
+-- Revision: \r
+-- Revision 0.01 - File Created\r
+-- Additional Comments: \r
+----------------------------------------------------------------------------------\r
+\r
+library IEEE;\r
+use IEEE.STD_LOGIC_1164.all;\r
+use IEEE.NUMERIC_STD.all;\r
+use IEEE.MATH_REAL.all;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+\r
+\r
+entity SFP_DDM_periph_hub is\r
+ port(\r
+ CLK100 : in std_logic;\r
+ TRB_RESET : in std_logic;\r
+\r
+ BUSDDM_RX : in CTRLBUS_RX;\r
+ BUSDDM_TX : out CTRLBUS_TX;\r
+\r
+ SCL_EXT : out std_logic_vector(6 downto 1);\r
+ SDA_EXT : inout std_logic_vector(6 downto 1)\r
+ );\r
+end SFP_DDM_periph_hub;\r
+\r
+architecture Behavioral of SFP_DDM_periph_hub is\r
+\r
+ -- Control and data register\r
+ signal CTRL_DATA_REG : std_logic_vector(2*32-1 downto 0) := x"FBFBFBFBFBFBFFFF";\r
+\r
+ -- I2C state machine signals\r
+ signal SCL : std_logic;\r
+ signal SDA : std_logic;\r
+ signal SDA_IN : std_logic;\r
+ signal resetI2C : std_logic;\r
+ type state_type is (reset, start, s00, s01, s02, s03, s04, s05, s06, s07, s08, s09,\r
+ s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, stop0, stop1, stop2, Err);\r
+ signal state : state_type;\r
+ signal bitcount : integer range 0 to 7;\r
+ constant slaveAddr_W : std_logic_vector(7 downto 0) := "10100010"; --slaveAddr & '0';\r
+ constant slaveAddr_R : std_logic_vector(7 downto 0) := "10100011"; --slaveAddr & '1';\r
+ signal byteAddr : std_logic_vector(7 downto 0) := x"68"; -- Address of first diagnostic byte to read (2 bytes read)\r
+ -- Bytes 96/97: Temperature MSB/LSB\r
+ -- Bytes 98/99: Vcc MSB/LSB\r
+ -- Bytes 100/101: Tx bias current\r
+ -- Bytes 102/103: Transceiver Tx power MSB/LSB\r
+ -- Bytes 104/105: Transceiver Rx power MSB/LSB\r
+ signal dataRcvd : std_logic_vector(15 downto 0);\r
+\r
+ -- I2C output signals\r
+ signal SCL_OUT : std_logic_vector(6 downto 1);\r
+ signal SDA_OUT : std_logic_vector(6 downto 1);\r
+\r
+ -- Clock division for I2C state machine\r
+ signal div512 : unsigned(8 downto 0) := (others => '0');\r
+ signal CLK_I2C : std_logic;\r
+\r
+ -- Signals for control state machine / multiplexing\r
+ signal SEL : integer range 1 to 6 := 1;\r
+ signal enable : std_logic_vector(6 downto 1);\r
+ signal timer : integer range 0 to 32767 := 0;\r
+\r
+-------------------------------------------------------------------------------\r
+begin ---- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN ----- BEGIN - \r
+-------------------------------------------------------------------------------\r
+\r
+ -- Output MUX\r
+ with SEL select SCL_OUT <=\r
+ (1 => SCL, others => '1') when 1,\r
+ (2 => SCL, others => '1') when 2,\r
+ (3 => SCL, others => '1') when 3,\r
+ (4 => SCL, others => '1') when 4,\r
+ (5 => SCL, others => '1') when 5,\r
+ (6 => SCL, others => '1') when 6,\r
+ (others => '1') when others;\r
+\r
+ with SEL select SDA_OUT <=\r
+ (1 => SDA, others => '1') when 1,\r
+ (2 => SDA, others => '1') when 2,\r
+ (3 => SDA, others => '1') when 3,\r
+ (4 => SDA, others => '1') when 4,\r
+ (5 => SDA, others => '1') when 5,\r
+ (6 => SDA, others => '1') when 6,\r
+ (others => '1') when others;\r
+\r
+ -- Input MUX\r
+ with SEL select SDA_IN <=\r
+ SDA_EXT(1) when 1,\r
+ SDA_EXT(2) when 2,\r
+ SDA_EXT(3) when 3,\r
+ SDA_EXT(4) when 4,\r
+ SDA_EXT(5) when 5,\r
+ SDA_EXT(6) when 6,\r
+ '1' when others;\r
+\r
+ -- Tri-state IO-buffers\r
+ SCL_EXT(1) <= '0' when SCL_OUT(1) = '0' else 'Z';\r
+ SCL_EXT(2) <= '0' when SCL_OUT(2) = '0' else 'Z';\r
+ SCL_EXT(3) <= '0' when SCL_OUT(3) = '0' else 'Z';\r
+ SCL_EXT(4) <= '0' when SCL_OUT(4) = '0' else 'Z';\r
+ SCL_EXT(5) <= '0' when SCL_OUT(5) = '0' else 'Z';\r
+ SCL_EXT(6) <= '0' when SCL_OUT(6) = '0' else 'Z';\r
+\r
+ SDA_EXT(1) <= '0' when SDA_OUT(1) = '0' else 'Z';\r
+ SDA_EXT(2) <= '0' when SDA_OUT(2) = '0' else 'Z';\r
+ SDA_EXT(3) <= '0' when SDA_OUT(3) = '0' else 'Z';\r
+ SDA_EXT(4) <= '0' when SDA_OUT(4) = '0' else 'Z';\r
+ SDA_EXT(5) <= '0' when SDA_OUT(5) = '0' else 'Z';\r
+ SDA_EXT(6) <= '0' when SDA_OUT(6) = '0' else 'Z';\r
+\r
+ -- Enable signals (slow control)\r
+ enable(6 downto 1) <= CTRL_DATA_REG(5 downto 0);\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- SFP DDM CTRL_DATA_REG Bus Handler \r
+ -----------------------------------------------------------------------------\r
+ PROC_CTRL_DATA_REG : process\r
+ variable pos : integer;\r
+ begin\r
+ wait until rising_edge(CLK100);\r
+ if (TRB_RESET = '1') then\r
+ CTRL_DATA_REG(15 downto 0) <= x"FFFF"; -- On reset, enable all channels\r
+ end if;\r
+ pos := to_integer(unsigned(busddm_rx.addr))*32;\r
+ busddm_tx.data <= CTRL_DATA_REG(pos+31 downto pos);\r
+ busddm_tx.ack <= busddm_rx.read;\r
+ if busddm_rx.write = '1' and to_integer(unsigned(busddm_rx.addr)) = 0 then\r
+ CTRL_DATA_REG(15 downto 0) <= busddm_rx.data(15 downto 0);\r
+ end if;\r
+ end process;\r
+\r
+ ------------------------------------------------------------------------------\r
+ -- Clock for I2C state machine (200kHz for 100kHz bit rate (SCL))\r
+ ------------------------------------------------------------------------------\r
+ I2C_Clock : process (CLK100)\r
+ begin\r
+ if RISING_EDGE(CLK100) then\r
+ div512 <= to_unsigned((to_integer(div512) + 1), 9);\r
+ CLK_I2C <= div512(8);\r
+ end if;\r
+ end process;\r
+\r
+ ------------------------------------------------------------------------------\r
+ -- Timer (Periodically toggles selected CH and resets I2C statemachine)\r
+ ------------------------------------------------------------------------------\r
+ Timer_Proc : process(CLK_I2C)\r
+ begin\r
+ if RISING_EDGE(CLK_I2C) then\r
+\r
+ timer <= timer + 1;\r
+\r
+ if (timer = 0) then\r
+ if (SEL < 6) then\r
+ SEL <= SEL + 1;\r
+ else\r
+ SEL <= 1;\r
+ end if;\r
+ resetI2C <= '1';\r
+ else\r
+ resetI2C <= '0';\r
+ end if;\r
+ \r
+ end if;\r
+ end process;\r
+\r
+ ------------------------------------------------------------------------------\r
+ -- I2C state machine\r
+ ------------------------------------------------------------------------------\r
+ I2C_FSM : process (CLK_I2C, resetI2C, SEL)\r
+ begin\r
+ if RISING_EDGE(CLK_I2C) then\r
+ if (resetI2C = '1') then -- Periodic reset\r
+ state <= reset;\r
+ else\r
+ case state is\r
+ ------------------------------------------------------------------\r
+ -- Start signal\r
+ ------------------------------------------------------------------\r
+ when reset => -- Idle\r
+ SCL <= '1';\r
+ SDA <= '1';\r
+ if (enable(SEL)) = '1' then -- If selected CH enabled -> Start\r
+ dataRcvd <= x"0FC0";\r
+ state <= start;\r
+ else\r
+ dataRcvd <= x"0FD0"; -- If not -> mark as disabled\r
+ state <= stop1;\r
+ end if;\r
+ \r
+ when start => -- Start\r
+ SCL <= '1';\r
+ SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> start\r
+ bitcount <= 7; -- Initializing bit counter\r
+ state <= s00;\r
+\r
+ ------------------------------------------------------------------\r
+ -- Send 7-bit slave address plus write bit, MSB first\r
+ ------------------------------------------------------------------\r
+ when s00 =>\r
+ SCL <= '0';\r
+ SDA <= slaveAddr_W(bitcount);\r
+ state <= s01;\r
+\r
+ when s01 =>\r
+ SCL <= '1';\r
+ if (bitcount - 1) >= 0 then\r
+ bitcount <= bitcount - 1;\r
+ state <= s00; -- Continue transfer\r
+ else\r
+ bitcount <= 7;\r
+ state <= s02; -- Check for acknowledgement\r
+ end if;\r
+\r
+ -- Get acknowledgement from slave and continue\r
+ when s02 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ state <= s03;\r
+\r
+ when s03 =>\r
+ SCL <= '1';\r
+ if SDA_IN = '0' then\r
+ state <= s04; -- Acknowledge received => go on\r
+ else\r
+ state <= Err; -- No acknowledge => abort\r
+ end if;\r
+\r
+ ------------------------------------------------------------------\r
+ -- Send 8-bit address of diagnostic byte, MSB first\r
+ ------------------------------------------------------------------\r
+ when s04 =>\r
+ SCL <= '0';\r
+ SDA <= byteAddr(bitcount);\r
+ state <= s05;\r
+\r
+ when s05 =>\r
+ SCL <= '1';\r
+ if (bitcount - 1) >= 0 then\r
+ bitcount <= bitcount - 1;\r
+ state <= s04; -- continue transfer\r
+ else\r
+ bitcount <= 7;\r
+ state <= s06; -- check for acknowledgement\r
+ end if;\r
+\r
+ -- Get acknowledgement from slave and continue\r
+ when s06 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ state <= s07;\r
+\r
+ when s07 =>\r
+ SCL <= '1';\r
+ if SDA_IN = '0' then\r
+ state <= s08; -- Acknowledge received => go on\r
+ else\r
+ state <= Err; -- No acknowledge => abort\r
+ end if;\r
+\r
+ ------------------------------------------------------------------\r
+ -- Send repeated start signal\r
+ ------------------------------------------------------------------\r
+ when s08 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ if SDA_IN = '0' then -- SDA should still be 0 here from acknowledgement\r
+ state <= s09;\r
+ else\r
+ state <= Err; -- No acknowledge => abort\r
+ end if;\r
+\r
+ when s09 =>\r
+ SCL <= '1';\r
+ SDA <= '1';\r
+ state <= s10;\r
+\r
+ when s10 => -- Start\r
+ SCL <= '1';\r
+ SDA <= '0'; -- SDA changes from 1 to 0 while SCL is 1 -> Start\r
+ state <= s11;\r
+\r
+ ------------------------------------------------------------------ \r
+ -- Send 7-bit slave address plus read bit, MSB first\r
+ ------------------------------------------------------------------\r
+ when s11 =>\r
+ SCL <= '0';\r
+ SDA <= slaveAddr_R(bitcount);\r
+ state <= s12;\r
+\r
+ when s12 =>\r
+ SCL <= '1';\r
+ if (bitcount - 1) >= 0 then\r
+ bitcount <= bitcount - 1;\r
+ state <= s11; -- continue transfer\r
+ else\r
+ bitcount <= 7;\r
+ state <= s13; -- check for acknowledgement\r
+ end if;\r
+\r
+ -- Get acknowledgement from slave and continue\r
+ when s13 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ state <= s14;\r
+\r
+ when s14 =>\r
+ SCL <= '1';\r
+ if SDA_IN = '0' then\r
+ state <= s15; -- Acknowledge received => go on\r
+ else\r
+ state <= Err; -- No acknowledge => abort\r
+ end if;\r
+\r
+ ------------------------------------------------------------------ \r
+ -- Read 1st byte (MSB) from slave (MSB first)\r
+ ------------------------------------------------------------------\r
+ when s15 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ state <= s16;\r
+\r
+ when s16 =>\r
+ SCL <= '1';\r
+ dataRcvd(8 + bitcount) <= SDA_IN; -- Read byte from bus MSB first\r
+ if (bitcount - 1) >= 0 then\r
+ bitcount <= bitcount - 1;\r
+ state <= s15;\r
+ else\r
+ bitcount <= 7;\r
+ state <= s17;\r
+ end if;\r
+\r
+ -- Send acknowledge signal\r
+ when s17 =>\r
+ SCL <= '0';\r
+ SDA <= '0'; -- Send acknowledge signal (0)\r
+ state <= s18;\r
+\r
+ when s18 =>\r
+ SCL <= '1'; -- Clocking out acknowledge signal\r
+ state <= s19;\r
+\r
+ ------------------------------------------------------------------\r
+ -- Read 2nd byte (LSB) from slave (MSB first)\r
+ ------------------------------------------------------------------\r
+ when s19 =>\r
+ SCL <= '0';\r
+ SDA <= '1';\r
+ state <= s20;\r
+\r
+ when s20 =>\r
+ SCL <= '1';\r
+ dataRcvd(bitcount) <= SDA_IN; -- Read byte from bus MSB first\r
+ if (bitcount - 1) >= 0 then\r
+ bitcount <= bitcount - 1;\r
+ state <= s19;\r
+ else\r
+ bitcount <= 7;\r
+ state <= s21;\r
+ end if;\r
+\r
+ -- Send not acknowledge signal\r
+ when s21 =>\r
+ SCL <= '0';\r
+ SDA <= '1'; -- Send not acknowledge signal (1)\r
+ state <= s22;\r
+\r
+ when s22 =>\r
+ SCL <= '1'; -- Clocking out not acknowledge signal\r
+ state <= stop0;\r
+\r
+\r
+ ------------------------------------------------------------------\r
+ -- STOP transfer and handle received data\r
+ ------------------------------------------------------------------\r
+ when stop0 =>\r
+ SCL <= '0';\r
+ SDA <= '0'; -- SDA goes to 0 to prepare for 0 to 1 transition\r
+ state <= stop1;\r
+\r
+ when stop1 =>\r
+ SCL <= '1';\r
+ SDA <= '0';\r
+ if (SEL = 1) then\r
+ CTRL_DATA_REG(16+1*8-1 downto 16+(1-1)*8) <= dataRcvd(11 downto 4);\r
+ elsif (SEL = 2) then\r
+ CTRL_DATA_REG(16+2*8-1 downto 16+(2-1)*8) <= dataRcvd(11 downto 4);\r
+ elsif (SEL = 3) then\r
+ CTRL_DATA_REG(16+3*8-1 downto 16+(3-1)*8) <= dataRcvd(11 downto 4);\r
+ elsif (SEL = 4) then\r
+ CTRL_DATA_REG(16+4*8-1 downto 16+(4-1)*8) <= dataRcvd(11 downto 4);\r
+ elsif (SEL = 5) then\r
+ CTRL_DATA_REG(16+5*8-1 downto 16+(5-1)*8) <= dataRcvd(11 downto 4);\r
+ elsif (SEL = 6) then\r
+ CTRL_DATA_REG(16+6*8-1 downto 16+(6-1)*8) <= dataRcvd(11 downto 4);\r
+ else\r
+ CTRL_DATA_REG <= CTRL_DATA_REG;\r
+ end if;\r
+ state <= stop2;\r
+\r
+ when stop2 =>\r
+ SCL <= '1';\r
+ SDA <= '1'; -- SDA changes from 0 to 1 while SCL is 1 -> Stop\r
+ state <= stop2; -- FSM idle until next reset\r
+\r
+ ------------------------------------------------------------------\r
+ -- Error\r
+ ------------------------------------------------------------------\r
+ -- Gets here only if Ack is error\r
+ when Err =>\r
+ SCL <= '0';\r
+ SDA <= '0';\r
+ dataRcvd <= x"0FE0";\r
+ state <= stop1;\r
+\r
+ -- Catch invalid states\r
+ when others =>\r
+ SCL <= '1';\r
+ SDA <= '1';\r
+ state <= Err;\r
+ end case;\r
+ end if;\r
+ end if;\r
+ end process;\r
+\r
+\r
+----------------------------------------------------------------------------------------------\r
+end Behavioral; --- END --- END --- END --- END --- END --- END --- END --- END --- END ---\r
+----------------------------------------------------------------------------------------------\r
--- /dev/null
+../scripts/compile.pl
\ No newline at end of file
--- /dev/null
+config_compile_gsi.pl
\ No newline at end of file
--- /dev/null
+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,
+
+
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"
--FPGA Test
signal time_counter : unsigned(31 downto 0);
+ -- SFP DDM
+ signal busddm_rx : CTRLBUS_RX;
+ signal busddm_tx : CTRLBUS_TX;
begin
---------------------------------------------------------------------------
);
-
-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
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,
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,
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;
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) {
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");
}
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) {
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