-------------------------------------------- -- Company: Liverpool University -- Engineer: Ilya Tsurin -- -- Create Date: 21:41:25 11/19/2009 -- Design Name: Master Card for the Telescope -- Module Name: Tboard - Behavioral -- Project Name: -- Target Devices: XC3S500E-4FG320 -- Tool versions: ISE 11.3 WebPack -- Description: -- -- Dependencies: Top Module -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- FE MAC address convention: -- S2:AF:XX:XX:XX:XX (hex) -- S = SSSS (bin) - MC selection switch -- 2 = MXLU (bin) - IEEE convention: locally (L=1) -- administered unicast (U=0) -- -- M = 1 - master card read and write operations -- (section A could be used for addressing -- different registers, currently A=XXXX -- is used, where X = 'don't care') -- PMT1 counter (bytes 0..3, read only) -- PMT2 counter (bytes 4..7 read only) -- Coincidence counter (bytes 8..11, read only) -- not implemented yet: -- -------------------- -- DUT_1 temperature (bytes 12..13, read only) -- ... -- DUT_15 temperature (bytes 40..41, read only) -- M = 0 - font-end read and write operations: -- A = 0000..1111 (bin) - Front-end address -- F = RW00 (bin) - reset front-end -- RW01 (bin) - write front-end -- RW10 (bin) - read front-end -- RW11 (bin) - void function -- -- R=1 (read only) - timeout on reading the front-end -- W=1 (read only) - timeout on writing into front-end -- -- 8X = 0000..1111 (bin) - Packet ID: to distinguish ehternet -- packets in the network card buffer -- memory -------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; --use IEEE.NUMERIC_STD.ALL; --library XilinxCoreLib; --use XilinxCoreLib.all; library UNISIM; use UNISIM.VComponents.all; entity tboard is Port ( Clock : in std_logic; OSC_40 : in std_logic; ETH_CRS : in std_logic; ETH_COL : in std_logic; ETH_RX_DV : in std_logic; ETH_RX_CLK : in std_logic; ETH_RX_ERR : in std_logic; ETH_RXD : in std_logic_vector (3 downto 0); ETH_TX_EN : out std_logic; ETH_TX_CLK : in std_logic; ETH_TX_ERR : out std_logic; ETH_TXD : out std_logic_vector (3 downto 0); ETH_MDC : out std_logic; ETH_MDIO : inout std_logic; USB_nTXE : out std_logic; USB_nRXF : out std_logic; USB_nRD : in std_logic; USB_WR : in std_logic; USB_DAT : inout std_logic_vector (7 downto 0); PMT : in std_logic_vector (1 downto 0); SIT : in std_logic_vector (3 downto 0); SITR : in std_logic; SYS_ADR : out std_logic_vector (3 downto 0); -- SYS_ADR(3) = LED(4) -- SYS_ADR(2) = LED(5) -- SYS_ADR(1) = LED(6) -- SYS_ADR(0) = LED(7) SYS_CLK : out std_logic_vector (3 downto 0); -- SYS_CLK(1) = LED(0) -- SYS_CLK(0) = LED(3) SYS_TRG : out std_logic_vector (3 downto 0); -- SYS_TRG(0) = LED(2) SYS_RES : out std_logic_vector (3 downto 0); -- SYS_RES(0) = LED(1) TST_SYN : out std_logic; TST_TRG : out std_logic; TST_DV0 : in std_logic; TST_PUL : out std_logic; TST_RES : out std_logic; TST_SCL : out std_logic; TST_SDA : inout std_logic; SW : in std_logic_vector(3 downto 0); BTN : in std_logic; BTS : in std_logic; BTW : in std_logic; BTE : in std_logic; BTC : in std_logic; ROTA : in std_logic; ROTB : in std_logic; CLK_50MHZ: in std_logic; CLK_AUX: in std_logic; CLK_SMA: in std_logic; AD_CONV: out std_logic; AMP_CS: out std_logic; AMP_DOUT: in std_logic; AMP_SHDN: out std_logic; DAC_CLR: out std_logic; DAC_CS: out std_logic; DS_WIRE: inout std_logic; FPGA_M0: inout std_logic; FPGA_M1: inout std_logic; FPGA_M2: in std_logic; FPGA_INIT_B: out std_logic; -- ghost signals -- FPGA_RDWR_B: out std_logic; -- FPGA_HSWAP: in std_logic; LCD_E: out std_logic; LCD_RS: out std_logic; LCD_RW: out std_logic; PS2_CLK: out std_logic; PS2_DATA: out std_logic; RS232_DCE_RXD: in std_logic; -- PIC18F4550 RS232_DCE_TXD: out std_logic; RS232_DTE_RXD: in std_logic; RS232_DTE_TXD: out std_logic; -- PL155-P SD_A: out std_logic_vector(12 downto 0); SD_BA: out std_logic_vector(1 downto 0); SD_CAS: out std_logic; SD_CK_N: out std_logic; SD_CK_P: out std_logic; SD_CKE: out std_logic; SD_CS: out std_logic; SD_DQ: inout std_logic_vector(15 downto 0); SD_LDM: out std_logic; SD_LDQS: inout std_logic; SD_RAS: out std_logic; SD_UDM: out std_logic; SD_UDQS: inout std_logic; SD_WE: out std_logic; SD_CK_FB: in std_logic; -- SF_A(24) is shared with TST_RES SF_A1: inout std_logic_vector(23 downto 20); SF_A0: out std_logic_vector(19 downto 0); SF_BYTE: out std_logic; SF_CE0: out std_logic; SF_D: inout std_logic_vector(15 downto 1); SF_OE: out std_logic; SF_STS: in std_logic; SF_WE: out std_logic; SPI_MISO: in std_logic; SPI_MOSI: out std_logic; SPI_SCK: inout std_logic; SPI_SS_B: out std_logic; SPI_ALT_CS_JP11: out std_logic; VGA_BLUE: out std_logic; VGA_GREEN: out std_logic; VGA_HSYNC: out std_logic; VGA_RED: out std_logic; VGA_VSYNC: out std_logic -- ghost signals -- XC_CMD: out std_logic_vector(1 downto 0); -- XC_CPLD_EN: in std_logic; -- XC_D: inout std_logic_vector(2 downto 0); -- XC_TRIG: in std_logic; -- XC_GCK0: out std_logic; -- GCLK10: out std_logic ); attribute pinnum: string; attribute pinnum of Clock: signal is "C9"; attribute pinnum of OSC_40: signal is "E10"; attribute pinnum of ETH_CRS: signal is "U13"; attribute pinnum of ETH_COL: signal is "U6"; attribute pinnum of ETH_RX_DV: signal is "V2"; attribute pinnum of ETH_RX_CLK: signal is "V3"; attribute pinnum of ETH_RX_ERR: signal is "U14"; attribute pinnum of ETH_RXD: signal is "V14,U11,V8,U14"; attribute pinnum of ETH_TX_EN: signal is "P15"; attribute pinnum of ETH_TX_CLK: signal is "T7"; attribute pinnum of ETH_TX_ERR: signal is "R6"; attribute pinnum of ETH_TXD: signal is "T5,R5,T15,R11"; attribute pinnum of ETH_MDC: signal is "P9"; attribute pinnum of ETH_MDIO: signal is "U5"; attribute pinnum of USB_nTXE: signal is "E8"; attribute pinnum of USB_nRXF: signal is "B4"; attribute pinnum of USB_nRD: signal is "C7"; attribute pinnum of USB_WR: signal is "F8"; attribute pinnum of USB_DAT: signal is "B6,F7,E7,D5,D7,C5,A6,A4"; attribute pinnum of PMT: signal is "C12,D12"; attribute pinnum of SIT: signal is "A15,B15,C3,C15"; attribute pinnum of SITR: signal is "D9"; attribute pinnum of SYS_ADR: signal is "C11,D11,E9,F9"; attribute pinnum of SYS_CLK: signal is "B16,C14,B13,E12"; attribute pinnum of SYS_TRG: signal is "A16,B14,A13,E11"; attribute pinnum of SYS_RES: signal is "D14,A14,F12,F11"; attribute pinnum of TST_SYN: signal is "D10"; attribute pinnum of TST_TRG: signal is "G9"; attribute pinnum of TST_DV0: signal is "B11"; attribute pinnum of TST_PUL: signal is "A8"; attribute pinnum of TST_RES: signal is "A11"; attribute pinnum of TST_SCL: signal is "E13"; attribute pinnum of TST_SDA: signal is "C4"; attribute pinnum of SW: signal is "N17,H18,L14,L13"; attribute pinnum of BTN: signal is "V4"; attribute pinnum of BTS: signal is "K17"; attribute pinnum of BTW: signal is "D18"; attribute pinnum of BTE: signal is "H13"; attribute pinnum of BTC: signal is "V16"; attribute pinnum of ROTA: signal is "K18"; attribute pinnum of ROTB: signal is "G18"; end tboard; architecture Behavioral of tboard is -- System wake up -------------------------------------------- signal PLL_REG: std_logic_vector(3 downto 0); signal PLL_DEL: std_logic_vector(3 downto 0); signal RX_SOF : std_logic; -- RX (receive) frame signal DV_DEL : std_logic; -------------------------------------------- -- Ethernet input package -------------------------------------------- signal RXB_CLK: std_logic; signal RXB_CNT: natural range 0 to 2047; signal MAC_CHK: std_logic_vector(7 downto 0); signal MC_FLAG: std_logic; signal UNICAST: std_logic; -- MAC match, chip select signal COM_RES: std_logic; -- Common reset before loop signal FE_ADR: std_logic_vector(47 downto 0); -- FE_ADR(47 downto 44) switch -- FE_ADR(43 downto 40) unicast -- FE_ADR(39 downto 36) FE address -- FE_ADR(35 downto 32) command -- FE_ADR(31 downto 0) packet ID signal HOST_ADR: std_logic_vector(47 downto 0); signal DAT_LEN: std_logic_vector(10 downto 0); signal LIM_DAT: natural range 0 to 2047; -------------------------------------------- -- Command flags for a single-loop processor -------------------------------------------- signal WR_ENA: std_logic; signal RD_ENA: std_logic; signal CL_ENA: std_logic; -------------------------------------------- -- input RAM -------------------------------------------- signal iRAM_WR: std_logic; -- input RAM write enable signal WR_CYCLE: std_logic; -- input RAM read enable signal FSENT_CNT: natural range 0 to 2047; -- counter of FE bytes signal WTO_CNT: natural range 0 to 1048575; -- FE timeout counter signal iRAM_WA: std_logic_vector(10 downto 0); signal iRAM_RA: std_logic_vector(10 downto 0); signal iRAM_LIM: std_logic; -- reset on overflow signal iRAM_TOT: std_logic; -- reset on timeout -------------------------------------------- -- Output RAM -------------------------------------------- signal RD_CYCLE: std_logic; -- output RAM write enable signal FREC_CNT: natural range 0 to 2047; -- counter of FE bytes signal FREC_DEL: natural range 0 to 2047; -- delayed counter signal RTO_CNT: natural range 0 to 65535; -- FE timeout counter signal oRAM_WA: std_logic_vector(10 downto 0); signal oRAM_RA: std_logic_vector(10 downto 0); signal oRAM_TOT: std_logic; signal oRAM_L1: std_logic; signal oRAM_L2: std_logic; signal oRAM_LIM: std_logic; -------------------------------------------- -- Timeout flags for read and write operation -------------------------------------------- signal FEW_TOT: std_logic; signal FER_TOT: std_logic; -------------------------------------------- -- Ethernet output package -------------------------------------------- signal TX_SOF: std_logic; -- TX (transmit) frame signal TXB_CNT: natural range 0 to 2047; signal TXF_RES: std_logic; signal TX_CYCLE: std_logic; -- Output data valid -------------------------------------------- -- Checksum variables -------------------------------------------- signal CRC_CLK: std_logic; signal CRC_INI: std_logic; signal CRC_DAT: std_logic_vector(7 downto 0); signal CRC_CRC: std_logic_vector(31 downto 0); signal CRC_RES: std_logic_vector(31 downto 0); -------------------------------------------- -- Data buffers -------------------------------------------- signal LIM_NUM: natural range 0 to 2047; signal RXF_LIM: std_logic; signal TXE_LIM: std_logic; signal TXE_L1: std_logic; signal TXE_L2: std_logic; signal RXB_DAT: std_logic_vector(7 downto 0); -- merging input nibbles signal INF_DAT: std_logic_vector(7 downto 0); -- latched for the iRAM signal OUT_DAT: std_logic_vector(7 downto 0); -- oRAM to the Ethernet signal USB_INP: std_logic_vector(7 downto 0); -- USB bi-dir buffer signal USB_OUT: std_logic_vector(7 downto 0); -- USB bi-dir buffer -- Clock inverters -------------------------------------------- signal U2R_CLK: std_logic; signal U3W_CLK: std_logic; signal U2_WEA: std_logic_vector(0 downto 0); signal U3_WEA: std_logic_vector(0 downto 0); -------------------------------------------- -- Track trigger -------------------------------------------- signal TRG_AND: std_logic; signal TRG_FAN: std_logic; signal TRG_RES: std_logic; signal TRG_CNT: natural range 0 to 512; -------------------------------------------- -- Event counters, pariod 1M samples -- Rate 1 kHz -> 20 min data taking -- Rage 100 kHz -> 10 sec data taking -------------------------------------------- signal PM1_CNT: natural range 0 to 1048575; signal PM2_CNT: natural range 0 to 1048575; signal COI_CNT: natural range 0 to 1048575; signal PM1_OVF: std_logic; signal PM2_OVF: std_logic; signal COI_OVF: std_logic; -------------------------------------------- -- MC data registers -------------------------------------------- signal PM1_REG: std_logic_vector(31 downto 0); signal PM2_REG: std_logic_vector(31 downto 0); signal COI_REG: std_logic_vector(31 downto 0); -------------------------------------------- -- MC data gateway -------------------------------------------- signal MC_DATA: std_logic_vector(7 downto 0); signal MC_CLK: std_logic; signal MC_WR: std_logic; -------------------------------------------- -- FE reset -------------------------------------------- signal RES_CNT: natural range 0 to 7; signal FE_RES: std_logic; -------------------------------------------- -- Temperature registers -------------------------------------------- signal Temp00: std_logic_vector(7 downto 0); signal Temp01: std_logic_vector(7 downto 0); signal Temp10: std_logic_vector(7 downto 0); signal Temp11: std_logic_vector(7 downto 0); signal Temp20: std_logic_vector(7 downto 0); signal Temp21: std_logic_vector(7 downto 0); signal Temp30: std_logic_vector(7 downto 0); signal Temp31: std_logic_vector(7 downto 0); signal Temp40: std_logic_vector(7 downto 0); signal Temp41: std_logic_vector(7 downto 0); signal Temp50: std_logic_vector(7 downto 0); signal Temp51: std_logic_vector(7 downto 0); signal Temp60: std_logic_vector(7 downto 0); signal Temp61: std_logic_vector(7 downto 0); signal Temp70: std_logic_vector(7 downto 0); signal Temp71: std_logic_vector(7 downto 0); signal Temp80: std_logic_vector(7 downto 0); signal Temp81: std_logic_vector(7 downto 0); signal Temp90: std_logic_vector(7 downto 0); signal Temp91: std_logic_vector(7 downto 0); signal TempA0: std_logic_vector(7 downto 0); signal TempA1: std_logic_vector(7 downto 0); signal TempB0: std_logic_vector(7 downto 0); signal TempB1: std_logic_vector(7 downto 0); signal TempC0: std_logic_vector(7 downto 0); signal TempC1: std_logic_vector(7 downto 0); signal DCE_STB: std_logic; signal TempXX: std_logic_vector(7 downto 0); -------------------------------------------- -- Emulate RS232 port (9600 baud) -------------------------------------------- signal FE_CLK: std_logic; signal RS_CLK: std_logic; signal RS_CNT: natural range 0 to 4095; signal RS_EOF: std_logic; signal RS_GTE: std_logic; -------------------------------------------- -- declaring Tlog component -------------------------------------------- component TLOG is port ( CLK: in std_logic; RXD: in std_logic; T0: out std_logic_vector(7 downto 0); T1: out std_logic_vector(7 downto 0); T2: out std_logic_vector(7 downto 0); T3: out std_logic_vector(7 downto 0); T4: out std_logic_vector(7 downto 0); T5: out std_logic_vector(7 downto 0); T6: out std_logic_vector(7 downto 0); T7: out std_logic_vector(7 downto 0); T8: out std_logic_vector(7 downto 0); T9: out std_logic_vector(7 downto 0); T10: out std_logic_vector(7 downto 0); T11: out std_logic_vector(7 downto 0); T12: out std_logic_vector(7 downto 0); T13: out std_logic_vector(7 downto 0); T14: out std_logic_vector(7 downto 0); T15: out std_logic_vector(7 downto 0); T16: out std_logic_vector(7 downto 0); T17: out std_logic_vector(7 downto 0); T18: out std_logic_vector(7 downto 0); T19: out std_logic_vector(7 downto 0); T20: out std_logic_vector(7 downto 0); T21: out std_logic_vector(7 downto 0); T22: out std_logic_vector(7 downto 0); T23: out std_logic_vector(7 downto 0); T24: out std_logic_vector(7 downto 0); T25: out std_logic_vector(7 downto 0) ); end component; -------------------------------------------- -- declaring CRC component -------------------------------------------- component CRC port ( Clock: in std_logic; Init : in std_logic; Data : in std_logic_vector(7 downto 0); CRC : out std_logic_vector(31 downto 0) ); end component; -------------------------------------------- -- declaring RAM component -------------------------------------------- component RAM port ( clka: in std_logic; wea: in std_logic_vector(0 downto 0); addra: in std_logic_vector(10 downto 0); dina: in std_logic_vector(7 downto 0); clkb: in std_logic; addrb: in std_logic_vector(10 downto 0); doutb: out std_logic_vector(7 downto 0) ); end component; -------------------------------------------- -- Data type conversion: -- binary#10 -> natural -------------------------------------------- function BIT11_to_NUM(BIT_ARR: std_logic_vector(10 downto 0)) return natural is variable TEMP: natural range 0 to 2047; begin TEMP:=0; for I in BIT_ARR'range loop TEMP:= TEMP * 2; if (BIT_ARR(I) = '1') then TEMP:= TEMP + 1; else null; end if; end loop; return TEMP; end BIT11_to_NUM; -------------------------------------------- -- OK, here the entity starts begin -- Permanent assignments -------------------------------------------- -- Resolve pin conflicts -------------------------------------------- AD_CONV <= '0'; AMP_CS <= '1'; AMP_SHDN <= '1'; DAC_CLR <= '0'; DAC_CS <= '1'; DS_WIRE <= 'Z'; -- M2..M0 are selected by jumpers FPGA_M0 <= 'Z'; FPGA_M1 <= 'Z'; -- FPGA_M2 <= 'Z'; FPGA_INIT_B <= '1'; LCD_E <= '0'; LCD_RS <= '0'; LCD_RW <= '0'; PS2_CLK <= '0'; PS2_DATA <= '0'; RS232_DCE_TXD <= '0'; SD_A <= (others => '0'); SD_BA <= "00"; SD_CAS <= '1'; -- NOP SD_CK_N <= '1'; SD_CK_P <= '0'; SD_CKE <= '0'; -- disable clock SD_CS <= '1'; -- disable command decoder SD_DQ <= (others => 'Z'); SD_LDM <= '0'; SD_LDQS <= 'Z'; SD_RAS <= '1'; -- NOP SD_UDM <= '0'; SD_UDQS <= 'Z'; SD_WE <= '1'; -- NOP SF_A1 <= (others => 'Z'); SF_A0 <= (others => '0'); SF_BYTE <= '0'; SF_CE0 <= '1'; SF_D <= (others => 'Z'); SF_OE <= '1'; SF_WE <= '1'; SPI_MOSI <= '0'; SPI_SCK <= '0'; SPI_SS_B <= '1'; SPI_ALT_CS_JP11 <= 'Z'; VGA_BLUE <='0'; VGA_GREEN <='0'; VGA_HSYNC <='0'; VGA_RED <='0'; VGA_VSYNC <='0'; -------------------------------------------- -- FE clock fanout -------------------------------------------- SYS_CLK <= (others => OSC_40); -------------------------------------------- -- Test block is not yet used -------------------------------------------- TST_TRG <= '0'; TST_SYN <= '0'; TST_RES <= '0'; TST_PUL <= '0'; -------------------------------------------- -- Test block is not yet used -------------------------------------------- ETH_TX_ERR <= '0'; ETH_MDIO <= 'Z'; ETH_MDC <= '0'; ETH_TX_EN <= TX_CYCLE; -------------------------------------------- -- Counter limits -------------------------------------------- LIM_NUM <= BIT11_to_NUM(DAT_LEN); -------------- process(LIM_NUM) begin if (LIM_NUM >= 46) then LIM_DAT <= LIM_NUM; else LIM_DAT <= 46; end if; end process; -------------------------------------------- -- !!! Wake up !!! -- Capture the frame delimiter (Result CLK <-) -------------------------------------------- process(ETH_RX_CLK, ETH_RXD) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then PLL_DEL <= ETH_RXD; end if; end process; -------------- process(ETH_RX_CLK, PLL_DEL) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then PLL_REG <= PLL_DEL; end if; end process; -------------------------------------------- -- Start of the RX frame (CLK ->) -------------------------------------------- process(ETH_RX_CLK, ETH_RX_DV, ETH_RXD, PLL_REG) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (ETH_RX_DV = '1') then if (ETH_RXD = x"D" and PLL_REG = x"5") then RX_SOF <= '1'; else null; end if; else RX_SOF <= '0'; end if; end if; end process; -------------------------------------------- -- Signal for the clock synchronisation (CLK ->) -------------------------------------------- process(ETH_RX_CLK, ETH_RX_DV) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then DV_DEL <= ETH_RX_DV; end if; end process; -------------------------------------------- -- RX nibble swapper and data clock (CLK <-) -- (synchronize phase with RX_SOF signal) -------------------------------------------- process(ETH_RX_CLK, DV_DEL, RX_SOF) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then if (DV_DEL = '1' and RX_SOF = '0') then RXB_CLK <= '0'; else RXB_CLK <= not RXB_CLK; end if; end if; end process; -------------------------------------------- -- RX byte counter (CLK ->) -------------------------------------------- process(RXB_CLK, RX_SOF) begin if (RXB_CLK'event and RXB_CLK = '1') then if (RX_SOF = '1') then RXB_CNT <= RXB_CNT + 1; else RXB_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Compile bytes from nibbles. Data are -- ready for latching by (CLK ->) under -- NIR_SWP = '0' condition -------------------------------------------- process(ETH_RX_CLK, RXB_CLK, ETH_RXD) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (RXB_CLK = '1') then RXB_DAT(3 downto 0) <= ETH_RXD; else null; end if; end if; end process; -------------- RXB_DAT(7 downto 4) <= ETH_RXD; -------------------------------------------- -- Validate FE addressing (unicast) -------------------------------------------- process(ETH_RX_CLK, RXB_CNT, RXB_CLK, RXB_DAT, SW) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (RXB_CNT = 1 and RXB_CLK = '0') then MAC_CHK <= RXB_DAT; else null; end if; end if; end process; -------------------------------------------- -- Locally administered unicast -------------------------------------------- process(MAC_CHK) begin if ((MAC_CHK(7 downto 4) = SW) and (MAC_CHK(1 downto 0) = "10")) then UNICAST <= '1'; else UNICAST <= '0'; end if; end process; -------------------------------------------- -- Issue reset pulse -------------------------------------------- process(ETH_RX_CLK, UNICAST, RXB_CLK, RXB_CNT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (UNICAST = '1' and RXB_CLK = '0') then case RXB_CNT is when 2 => COM_RES <= '1'; when 3 => COM_RES <= '0'; when others => null; end case; else null; end if; end if; end process; -------------------------------------------- -- Capture the RX data -------------------------------------------- process(ETH_RX_CLK, UNICAST, RXB_CLK, RXB_CNT, MAC_CHK, RXB_DAT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (UNICAST = '1' and RXB_CLK = '0') then case RXB_CNT is when 2 => FE_ADR(47 downto 40) <= MAC_CHK; FE_ADR(39 downto 32) <= RXB_DAT; when 3 => FE_ADR(31 downto 24) <= RXB_DAT; when 4 => FE_ADR(23 downto 16) <= RXB_DAT; when 5 => FE_ADR(15 downto 8) <= RXB_DAT; when 6 => FE_ADR(7 downto 0) <= RXB_DAT; when 7 => HOST_ADR(47 downto 40) <= RXB_DAT; when 8 => HOST_ADR(39 downto 32) <= RXB_DAT; when 9 => HOST_ADR(31 downto 24) <= RXB_DAT; when 10 => HOST_ADR(23 downto 16) <= RXB_DAT; when 11 => HOST_ADR(15 downto 8) <= RXB_DAT; when 12 => HOST_ADR(7 downto 0) <= RXB_DAT; when 13 => DAT_LEN(10 downto 8) <= RXB_DAT(2 downto 0); when 14 => DAT_LEN(7 downto 0) <= RXB_DAT; when others => INF_DAT <= RXB_DAT; end case; else null; end if; end if; end process; -------------------------------------------- -- Master card addressing -------------------------------------------- MC_FLAG <= FE_ADR(43); -- OR MAC_CHK(3) -------------------------------------------- -- Command decoding (NIR_CNT = 2) -------------------------------------------- process(FE_ADR) begin case FE_ADR(33 downto 32) is when "00" => WR_ENA <= '0'; RD_ENA <= '0'; CL_ENA <= '1'; when "01" => WR_ENA <= '1'; RD_ENA <= '0'; CL_ENA <= '0'; when "10" => WR_ENA <= '0'; RD_ENA <= '1'; CL_ENA <= '0'; when others => WR_ENA <= '0'; RD_ENA <= '0'; CL_ENA <= '0'; end case; end process; -------------------------------------------- -- control RX (input) RAM write enable -- (receive data from PC via ethernet) -------------------------------------------- process(ETH_RX_CLK, UNICAST, RXB_CLK, WR_ENA, RXB_CNT, LIM_NUM) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (UNICAST = '1' and RXB_CLK = '0' and WR_ENA = '1') then if (RXB_CNT = 0) then -- clear beyond RF_SOF iRAM_WR <= '0'; elsif (RXB_CNT = 15) then iRAM_WR <= '1'; elsif (RXB_CNT = (LIM_NUM + 15)) then iRAM_WR <= '0'; elsif (RXB_CNT = 1515) then iRAM_WR <= '0'; else null; end if; else null; end if; end if; end process; -------------------------------------------- -- iRAM write address -------------------------------------------- process(RXB_CLK, RXB_CNT) begin if (RXB_CLK'event and RXB_CLK = '0') then iRAM_WA <= conv_std_logic_vector(RXB_CNT, 11); end if; end process; -------------------------------------------- -------------------------------------------- -- control RX (input) RAM read enable -- (send data to the front-end) -------------------------------------------- process(iRAM_LIM, iRAM_TOT, iRAM_WR) begin if (iRAM_LIM = '1' or iRAM_TOT = '1') then WR_CYCLE <= '0'; elsif (iRAM_WR'event and iRAM_WR = '0') then WR_CYCLE <= '1'; end if; end process; -------------------------------------------- -- counter for bytes sent to FE (USB_nRD <-) -------------------------------------------- process(COM_RES, FE_CLK, WR_CYCLE) begin if (COM_RES = '1') then FSENT_CNT <= 0; elsif (FE_CLK'event and FE_CLK = '0') then if (WR_CYCLE = '1') then FSENT_CNT <= FSENT_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- iRAM read address (offset to jump over) -------------------------------------------- iRAM_RA <= conv_std_logic_vector((FSENT_CNT + 15), 11); -------------------------------------------- -- FE write timeout counter -------------------------------------------- process(ETH_RX_CLK, WR_CYCLE) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then if (WR_CYCLE = '1') then WTO_CNT <= WTO_CNT + 1; else WTO_CNT <= 0; end if; end if; end process; -------------------------------------------- -- end of data packet sent to FE -------------------------------------------- process(COM_RES, FE_CLK, FSENT_CNT, LIM_NUM) begin if (COM_RES = '1') then iRAM_LIM <= '0'; elsif (FE_CLK'event and FE_CLK = '1') then if (FSENT_CNT = LIM_NUM) then iRAM_LIM <= '1'; else null; end if; end if; end process; -------------------------------------------- -- FE write timeout -------------------------------------------- process(ETH_RX_CLK, WTO_CNT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (WTO_CNT = 1048575) then iRAM_TOT <= '1'; elsif (WTO_CNT = 0) then iRAM_TOT <= '0'; else null; end if; end if; end process; -------------------------------------------- -- FE write timeout flag -------------------------------------------- process(iRAM_TOT, COM_RES, WR_ENA) begin if (iRAM_TOT = '1') then FEW_TOT <= '1'; elsif (COM_RES'event and COM_RES = '0') then if (WR_ENA = '1') then FEW_TOT <= '0'; else null; end if; end if; end process; -------------------------------------------- -------------------------------------------- -------------------------------------------- -- Start FE reading -------------------------------------------- process(oRAM_LIM, oRAM_TOT, ETH_RX_CLK, UNICAST, RD_ENA, RXB_CNT, RXB_CLK) begin if (oRAM_LIM = '1' or oRAM_TOT = '1') then RD_CYCLE <= '0'; elsif (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (UNICAST = '1' and RD_ENA = '1' and RXB_CNT = 3 and RXB_CLK = '0') then RD_CYCLE <= '1'; else null; end if; end if; end process; -------------------------------------------- -- counter for bytes received from FE -------------------------------------------- process(COM_RES, MC_CLK, RD_CYCLE) begin if (COM_RES = '1') then FREC_CNT <= 0; elsif (MC_CLK'event and MC_CLK = '0') then if (RD_CYCLE = '1') then FREC_CNT <= FREC_CNT + 1; else null; end if; end if; end process; -------------- process(COM_RES, MC_CLK, FREC_CNT) begin if (COM_RES = '1') then FREC_DEL <= 0; elsif (MC_CLK'event and MC_CLK = '1') then FREC_DEL <= FREC_CNT; end if; end process; -------------------------------------------- -- oRAM write address -------------------------------------------- oRAM_WA <= conv_std_logic_vector((FREC_DEL + 22), 11); -------------------------------------------- -- FE read timeout counter -------------------------------------------- process(ETH_RX_CLK, RD_CYCLE) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then if (RD_CYCLE = '1') then RTO_CNT <= RTO_CNT + 1; else RTO_CNT <= 0; end if; end if; end process; -------------------------------------------- -- end of data packet received from FE -------------------------------------------- process(COM_RES, MC_CLK, FREC_DEL, LIM_NUM) begin if (COM_RES = '1') then oRAM_L1 <= '0'; elsif (MC_CLK'event and MC_CLK = '0') then if (FREC_DEL >= (LIM_NUM - 1)) then oRAM_L1 <= '1'; end if; end if; end process; -------------- process(ETH_RX_CLK, oRAM_L1) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then oRAM_L2 <= oRAM_L1; end if; end process; -------------- process(ETH_RX_CLK, oRAM_L2) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then oRAM_LIM <= oRAM_L2; end if; end process; -------------------------------------------- -- FE read timeout -------------------------------------------- process(ETH_RX_CLK, RTO_CNT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (RTO_CNT = 65535) then oRAM_TOT <= '1'; elsif (RTO_CNT = 0) then oRAM_TOT <= '0'; else null; end if; end if; end process; -------------------------------------------- -- FE read timeout flag -------------------------------------------- process(oRAM_TOT, COM_RES, RD_ENA) begin if (oRAM_TOT = '1') then FER_TOT <= '1'; elsif (COM_RES'event and COM_RES = '0') then if (RD_ENA = '1') then FER_TOT <= '0'; else null; end if; end if; end process; -------------------------------------------- -------------------------------------------- -- Transmission frame -------------------------------------------- process(TXF_RES, RD_CYCLE) begin if (TXF_RES = '1') then TX_SOF <= '0'; elsif (RD_CYCLE'event and RD_CYCLE = '0') then TX_SOF <= '1'; end if; end process; -------------------------------------------- -- TX nibble swapper = CRC32 clock (CLK ->) -------------------------------------------- process(ETH_TX_CLK, RD_CYCLE) begin if (ETH_TX_CLK'event and ETH_TX_CLK = '1') then if (RD_CYCLE = '1') then CRC_CLK <= '0'; else CRC_CLK <= not CRC_CLK; end if; end if; end process; -------------------------------------------- -- TX byte counter (CLK ->) -------------------------------------------- process(CRC_CLK, TX_SOF) begin if (CRC_CLK'event and CRC_CLK = '1') then if (TX_SOF = '1') then TXB_CNT <= TXB_CNT + 1; else TXB_CNT <= 0; end if; end if; end process; -------------------------------------------- -- oRAM read address -------------------------------------------- process(CRC_CLK, TXB_CNT) begin if (CRC_CLK'event and CRC_CLK = '0') then oRAM_RA <= conv_std_logic_vector(TXB_CNT, 11); end if; end process; -------------------------------------------- -- End of transmission frame (CLK ->) -------------------------------------------- process(CRC_CLK, TXB_CNT, LIM_DAT) begin if (CRC_CLK'event and CRC_CLK = '0') then if (TXB_CNT = 0) then TXF_RES <= '0'; elsif (TXB_CNT = (22 + LIM_DAT + 4 + 1)) then TXF_RES <= '1'; elsif (TXB_CNT = 1527) then TXF_RES <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Drive ETH_TX_EN signal -------------------------------------------- process(ETH_TX_CLK, CRC_CLK, TXB_CNT, LIM_DAT) begin if (ETH_TX_CLK'event and ETH_TX_CLK = '0') then if (CRC_CLK = '1') then -- Causes J/K/ = x55 for the receiver on the other end if (TXB_CNT = 1) then TX_CYCLE <= '1'; elsif (TXB_CNT = (22 + LIM_DAT + 4 + 1)) then TX_CYCLE <= '0'; elsif (TXB_CNT = 1527) then TX_CYCLE <= '0'; else null; end if; else null; end if; end if; end process; -------------------------------------------- -- Initialize CRC variables (CLK <-) -------------------------------------------- process(ETH_TX_CLK, TXB_CNT, CRC_CLK) begin if (ETH_TX_CLK'event and ETH_TX_CLK = '0') then if (TXB_CNT = 9) then if (CRC_CLK = '1') then CRC_INI <= '1'; else CRC_INI <= '0'; end if; else null; end if; end if; end process; -------------------------------------------- -- compile the Ethernet output packet -------------------------------------------- process(ETH_TX_CLK, TXB_CNT, CRC_CLK, HOST_ADR, FE_ADR, FER_TOT, FEW_TOT, LIM_DAT, OUT_DAT, CRC_CRC, CRC_RES) begin if (ETH_TX_CLK'event and ETH_TX_CLK = '0') then -- 6 times preamble 0x55 -------------------------------------------- if ((TXB_CNT >= 1) and (7 >= TXB_CNT)) then ETH_TXD <= x"5"; -- Delimiter 0xD5 -------------------------------------------- elsif (TXB_CNT = 8) then if (CRC_CLK = '1') then ETH_TXD <= x"5"; else ETH_TXD <= x"D"; end if; -- Destination (Host) MAC address -------------------------------------------- elsif (TXB_CNT = 9) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(43 downto 40); else ETH_TXD <= HOST_ADR(47 downto 44); end if; elsif (TXB_CNT = 10) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(35 downto 32); else ETH_TXD <= HOST_ADR(39 downto 36); end if; elsif (TXB_CNT = 11) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(27 downto 24); else ETH_TXD <= HOST_ADR(31 downto 28); end if; elsif (TXB_CNT = 12) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(19 downto 16); else ETH_TXD <= HOST_ADR(23 downto 20); end if; elsif (TXB_CNT = 13) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(11 downto 8); else ETH_TXD <= HOST_ADR(15 downto 12); end if; elsif (TXB_CNT = 14) then if (CRC_CLK = '1') then ETH_TXD <= HOST_ADR(3 downto 0); else ETH_TXD <= HOST_ADR(7 downto 4); end if; -- Source (Front-end) address -------------------------------------------- elsif (TXB_CNT = 15) then if (CRC_CLK = '1') then ETH_TXD <= FE_ADR(43 downto 40); else ETH_TXD <= FE_ADR(47 downto 44); end if; elsif (TXB_CNT = 16) then if (CRC_CLK = '1') then ETH_TXD(3) <= FER_TOT; ETH_TXD(2) <= FEW_TOT; ETH_TXD(1 downto 0) <= FE_ADR(33 downto 32); else ETH_TXD <= FE_ADR(39 downto 36); end if; elsif (TXB_CNT = 17) then if (CRC_CLK = '1') then ETH_TXD <= FE_ADR(27 downto 24); else ETH_TXD <= FE_ADR(31 downto 28); end if; elsif (TXB_CNT = 18) then if (CRC_CLK = '1') then ETH_TXD <= FE_ADR(19 downto 16); else ETH_TXD <= FE_ADR(23 downto 20); end if; elsif (TXB_CNT = 19) then if (CRC_CLK = '1') then ETH_TXD <= FE_ADR(11 downto 8); else ETH_TXD <= FE_ADR(15 downto 12); end if; elsif (TXB_CNT = 20) then if (CRC_CLK = '1') then ETH_TXD <= FE_ADR(3 downto 0); else ETH_TXD <= FE_ADR(7 downto 4); end if; -- Packet length -------------------------------------------- elsif (TXB_CNT = 21) then if (CRC_CLK = '1') then ETH_TXD(2 downto 0) <= DAT_LEN(10 downto 8); ETH_TXD(3) <= '0'; else ETH_TXD <= (others => '0'); end if; elsif (TXB_CNT = 22) then if (CRC_CLK = '1') then ETH_TXD <= DAT_LEN(3 downto 0); else ETH_TXD <= DAT_LEN(7 downto 4); end if; -- Data block -------------------------------------------- -- elsif ((TXB_CNT >= 23) and ((22 + LIM_DAT) >= TXB_CNT)) then -------------------------------------------- -- CRC32 -------------------------------------------- elsif (TXB_CNT = (22 + LIM_DAT + 1)) then -- *** Important *** Use CRC_CRC Nibble here if (CRC_CLK = '1') then ETH_TXD <= CRC_CRC(3 downto 0); else ETH_TXD <= CRC_CRC(7 downto 4); end if; elsif (TXB_CNT = (22 + LIM_DAT + 2)) then if (CRC_CLK = '1') then ETH_TXD <= CRC_RES(11 downto 8); else ETH_TXD <= CRC_RES(15 downto 12); end if; elsif (TXB_CNT = (22 + LIM_DAT + 3)) then if (CRC_CLK = '1') then ETH_TXD <= CRC_RES(19 downto 16); else ETH_TXD <= CRC_RES(23 downto 20); end if; elsif (TXB_CNT = (22 + LIM_DAT + 4)) then if (CRC_CLK = '1') then ETH_TXD <= CRC_RES(27 downto 24); else ETH_TXD <= CRC_RES(31 downto 28); end if; -- Data block -------------------------------------------- else if (CRC_CLK = '1') then ETH_TXD <= OUT_DAT(3 downto 0); else ETH_TXD <= OUT_DAT(7 downto 4); end if; end if; end if; end process; -------------------------------------------- -- CRC data -------------------------------------------- process(TXB_CNT, HOST_ADR, FE_ADR, FER_TOT, FEW_TOT, LIM_DAT, OUT_DAT) begin -- Destination (Host) MAC address -------------------------------------------- if (TXB_CNT = 9) then CRC_DAT <= HOST_ADR(47 downto 40); elsif (TXB_CNT = 10) then CRC_DAT <= HOST_ADR(39 downto 32); elsif (TXB_CNT = 11) then CRC_DAT <= HOST_ADR(31 downto 24); elsif (TXB_CNT = 12) then CRC_DAT <= HOST_ADR(23 downto 16); elsif (TXB_CNT = 13) then CRC_DAT <= HOST_ADR(15 downto 8); elsif (TXB_CNT = 14) then CRC_DAT <= HOST_ADR(7 downto 0); -- Source (Front-end) address -------------------------------------------- elsif (TXB_CNT = 15) then CRC_DAT <= FE_ADR(47 downto 40); elsif (TXB_CNT = 16) then CRC_DAT(7 downto 4) <= FE_ADR(39 downto 36); CRC_DAT(3) <= FER_TOT; CRC_DAT(2) <= FEW_TOT; CRC_DAT(1 downto 0) <= FE_ADR(33 downto 32); elsif (TXB_CNT = 17) then CRC_DAT <= FE_ADR(31 downto 24); elsif (TXB_CNT = 18) then CRC_DAT <= FE_ADR(23 downto 16); elsif (TXB_CNT = 19) then CRC_DAT <= FE_ADR(15 downto 8); elsif (TXB_CNT = 20) then CRC_DAT <= FE_ADR(7 downto 0); -- Packet length -------------------------------------------- elsif (TXB_CNT = 21) then CRC_DAT(7 downto 3) <= "00000"; CRC_DAT(2 downto 0) <= DAT_LEN(10 downto 8); elsif (TXB_CNT = 22) then CRC_DAT <= DAT_LEN(7 downto 0); -- Data block -------------------------------------------- -- elsif ((TXB_CNT >= 23) and ((22 + LIM_DAT) >= TXB_CNT)) then else CRC_DAT <= OUT_DAT; end if; end process; -------------------------------------------- -------------------------------------------- -- Calculate CRC32 for transmitted data ------------------------------------------- U1:CRC port map ( Clock => CRC_CLK, Init => CRC_INI, Data => CRC_DAT, CRC => CRC_CRC); -------------------------------------------- -- Keep the CRC result (the last data byte) -------------------------------------------- process(CRC_CLK, TXB_CNT, LIM_DAT, CRC_CRC) begin if (CRC_CLK'event and CRC_CLK = '0') then if (TXB_CNT = (22 + LIM_DAT + 1)) then CRC_RES <= CRC_CRC; else null; end if; end if; end process; -------------------------------------------- -------------------------------------------- -- Condition RAM clocks and write enable -------------------------------------------- U2R_CLK <= not FE_CLK; U3W_CLK <= not MC_CLK; -------------- process(iRAM_WR) begin if (iRAM_WR = '1') then U2_WEA <= "1"; else U2_WEA <= "0"; end if; end process; -------------- process(RD_CYCLE) begin if (RD_CYCLE = '1') then U3_WEA <= "1"; else U3_WEA <= "0"; end if; end process; -------------------------------------------- -- RAM for the FE control data -------------------------------------------- U2:RAM port map( clka => RXB_CLK, wea => U2_WEA, addra => iRAM_WA, dina => INF_DAT, clkb => U2R_CLK, addrb => iRAM_RA, doutb => USB_OUT); -------------------------------------------- -- RAM for the event data -------------------------------------------- U3:RAM port map( clka => U3W_CLK, wea => U3_WEA, addra => oRAM_WA, dina => USB_INP, clkb => CRC_CLK, addrb => oRAM_RA, doutb => OUT_DAT); -------------------------------------------- -- Select one Alibava board -------------------------------------------- SYS_ADR <= FE_ADR(39 downto 36); -------------------------------------------- -- Bi-directional IO for the USB-like port -------------------------------------------- process(WR_CYCLE, USB_OUT) begin if (WR_CYCLE = '1') then USB_DAT <= USB_OUT; else USB_DAT <= (others => 'Z'); end if; end process; -------------------------- -- USB_INP <= USB_DAT; -------------------------------------------- -- The oRAM is filled with the MC data if -- the card address is 0xF, or the FE data -- otherwise -------------------------------------------- process(MC_FLAG, MC_DATA, USB_DAT) begin if (MC_FLAG = '1') then USB_INP <= MC_DATA; else USB_INP <= USB_DAT; end if; end process; -------------------------------------------- -- The MC data clock selection for FE read -------------------------------------------- process(ETH_RX_CLK, RXB_CLK) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then MC_WR <= not RXB_CLK; end if; end process; -------------- process(MC_FLAG, MC_WR, USB_WR) begin if (MC_FLAG = '1') then MC_CLK <= MC_WR; else MC_CLK <= USB_WR; end if; end process; -------------------------------------------- -- The MC data clock selection for FE write -------------------------------------------- process(MC_FLAG, USB_nRD, RS_CLK) begin if (MC_FLAG = '1') then FE_CLK <= RS_CLK; else FE_CLK <= USB_nRD; end if; end process; -------------------------------------------- -- FE write enable (Should be OK now) -------------------------------------------- process(COM_RES, FE_CLK, FSENT_CNT, LIM_NUM) begin if (COM_RES = '1') then RXF_LIM <= '0'; elsif (FE_CLK'event and FE_CLK = '1') then if (FSENT_CNT = LIM_NUM) then RXF_LIM <= '1'; else null; end if; end if; end process; -------------- process(RXF_LIM, iRAM_TOT, iRAM_WR, MC_FLAG) begin if (RXF_LIM = '1' or iRAM_TOT = '1') then USB_nRXF <= '1'; elsif (iRAM_WR'event and iRAM_WR = '0') then if (MC_FLAG = '0') then USB_nRXF <= '0'; else null; end if; end if; end process; -- USB_nRXF <= not WR_CYCLE; -- write FE (RD_CYCLE) -------------------------------------------- -- FE read enable -------------------------------------------- process(COM_RES, MC_CLK, FREC_DEL, LIM_NUM) begin if (COM_RES = '1') then TXE_L1 <= '0'; elsif (MC_CLK'event and MC_CLK = '0') then if (FREC_DEL >= (LIM_NUM - 1)) then TXE_L1 <= '1'; end if; end if; end process; -------------- process(ETH_RX_CLK, TXE_L1) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then TXE_L2 <= TXE_L1; end if; end process; -------------- process(ETH_RX_CLK, TXE_L2) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then TXE_LIM <= TXE_L2; end if; end process; -------------- -------------- process(TXE_LIM, oRAM_TOT, ETH_RX_CLK, UNICAST, -- process(oRAM_LIM, oRAM_TOT, ETH_RX_CLK, UNICAST, RD_ENA, RXB_CNT, MC_FLAG, RXB_CLK) begin if (TXE_LIM = '1' or oRAM_TOT = '1') then -- if (oRAM_LIM = '1' or oRAM_TOT = '1') then USB_nTXE <= '1'; elsif (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (UNICAST = '1' and RD_ENA = '1' and RXB_CNT = 3 and MC_FLAG = '0' and RXB_CLK = '0') then USB_nTXE <= '0'; else null; end if; end if; end process; -- USB_nTXE <= not RD_CYCLE; -- read FE (WR_CYCLE) -------------------------------------------- -- FE reset signal -------------------------------------------- -- process(ETH_RX_CLK, UNICAST, CL_ENA, RXB_CNT, RXB_CLK) -- begin -- if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then -- if (UNICAST = '1' and CL_ENA = '1' and RXB_CNT = 3) then -- if (RXB_CLK = '1') then -- FE_RES <= '1'; -- else -- FE_RES <= '0'; -- end if; -- else -- null; -- end if; -- end if; -- end process; process(OSC_40, UNICAST, CL_ENA, COM_RES) begin if (OSC_40'event and OSC_40 = '0') then if (UNICAST = '1' and CL_ENA = '1' and COM_RES = '1') then RES_CNT <= RES_CNT + 1; else RES_CNT <= 0; end if; end if; end process; -------------- process(OSC_40, RES_CNT) begin if (OSC_40'event and OSC_40 = '1') then case RES_CNT is when 1 => FE_RES <= '1'; when 3 => FE_RES <= '0'; when others => null; end case; end if; end process; -------------------------------------------- -------------------------------------------- -- Delay PMT(0) by ~10ns using RC circuit -- between free pins SCL (out) and SDA (inp) -------------------------------------------- TST_SCL <= PMT(0); TST_SDA <= 'Z'; -------------------------------------------- -- Coincidence of PMT(1) and delayed PMT(0) -------------------------------------------- process(TRG_RES, PMT, TST_SDA) begin if (TRG_RES = '1') then TRG_AND <= '0'; elsif (TST_SDA'event and TST_SDA = '0') then if (PMT(1) = '0') then TRG_AND <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Keep trigger signal for 512 clock -- periods (40 MHz) for readout latency -------------------------------------------- process(OSC_40, TRG_AND) begin if (OSC_40'event and OSC_40 = '1') then if (TRG_AND = '1') then TRG_CNT <= TRG_CNT + 1; else TRG_CNT <= 0; end if; end if; end process; -------------- process(OSC_40, TRG_CNT) begin if (OSC_40'event and OSC_40 = '0') then if (TRG_CNT = 3) then --511 TRG_RES <= '1'; else TRG_RES <= '0'; end if; end if; end process; -------------------------------------------- process(FE_RES, TRG_AND) begin if (FE_RES = '1') then TRG_FAN <= '0'; elsif (TRG_AND'event and TRG_AND = '1') then TRG_FAN <= '1'; end if; end process; -- Trigger fanout -------------------------------------------- SYS_TRG <= (others => TRG_FAN); -------------------------------------------- -- Scalers -------------------------------------------- process(FE_RES, PMT, PM1_OVF) begin if (FE_RES = '1') then PM1_CNT <= 0; elsif (PMT(0)'event and PMT(0) = '0') then if (PM1_OVF = '0') then PM1_CNT <= PM1_CNT + 1; else null; end if; end if; end process; -------------- process(FE_RES, PMT, PM2_OVF) begin if (FE_RES = '1') then PM2_CNT <= 0; elsif (PMT(1)'event and PMT(1) = '0') then if (PM2_OVF = '0') then PM2_CNT <= PM2_CNT + 1; else null; end if; end if; end process; -------------- process(FE_RES, TRG_AND, COI_OVF) begin if (FE_RES = '1') then COI_CNT <= 0; elsif (TRG_AND'event and TRG_AND = '1') then if (COI_OVF = '0') then COI_CNT <= COI_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- Overflow flags -------------------------------------------- process(FE_RES, PMT, PM1_CNT) begin if (FE_RES = '1') then PM1_OVF <= '0'; elsif (PMT(0)'event and PMT(0) = '1') then if (PM1_CNT = 1048575) then PM1_OVF <= '1'; else null; end if; end if; end process; -------------- process(FE_RES, PMT, PM2_CNT) begin if (FE_RES = '1') then PM2_OVF <= '0'; elsif (PMT(1)'event and PMT(1) = '1') then if (PM2_CNT = 1048575) then PM2_OVF <= '1'; else null; end if; end if; end process; -------------- process(FE_RES, TRG_AND, COI_CNT) begin if (FE_RES = '1') then COI_OVF <= '0'; elsif (TRG_AND'event and TRG_AND = '0') then if (COI_CNT = 1048575) then COI_OVF <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Store scalers data -------------------------------------------- process(RD_CYCLE, MC_FLAG, PM1_OVF, PM1_CNT, PM2_OVF, PM2_CNT, COI_OVF, COI_CNT) begin if (RD_CYCLE'event and RD_CYCLE = '1') then if (MC_FLAG = '1') then PM1_REG(31 downto 21) <= "00000000000"; PM1_REG(20) <= PM1_OVF; PM1_REG(19 downto 0) <= conv_std_logic_vector(PM1_CNT, 20); PM2_REG(31 downto 21) <= "00000000000"; PM2_REG(20) <= PM2_OVF; PM2_REG(19 downto 0) <= conv_std_logic_vector(PM2_CNT, 20); COI_REG(31 downto 21) <= "00000000000"; COI_REG(20) <= COI_OVF; COI_REG(19 downto 0) <= conv_std_logic_vector(COI_CNT, 20); else null; end if; end if; end process; -------------------------------------------- -- Temperature logger -------------------------------------------- U4:TLOG port map( CLK => OSC_40, RXD => RS232_DCE_RXD, T0 => Temp00, T1 => Temp01, T2 => Temp10, T3 => Temp11, T4 => Temp20, T5 => Temp21, T6 => Temp30, T7 => Temp31, T8 => Temp40, T9 => Temp41, T10 => Temp50, T11 => Temp51, T12 => Temp60, T13 => Temp61, T14 => Temp70, T15 => Temp71, T16 => Temp80, T17 => Temp81, T18 => Temp90, T19 => Temp91, T20 => TempA0, T21 => TempA1, T22 => TempB0, T23 => TempB1, T24 => TempC0, T25 => TempC1 ); -------------------------------------------- -- Output scalers data -------------------------------------------- process(FREC_DEL, PM1_REG, PM2_REG, COI_REG, Temp00, Temp01, Temp10, Temp11, Temp20, Temp21, Temp30, Temp31, Temp40, Temp41, Temp50, Temp51, Temp60, Temp61, Temp70, Temp71, Temp80, Temp81, Temp90, Temp91, TempA0, TempA1, TempB0, TempB1, TempC0, TempC1) begin case FREC_DEL is when 0 => MC_DATA <= PM1_REG(31 downto 24); when 1 => MC_DATA <= PM1_REG(23 downto 16); when 2 => MC_DATA <= PM1_REG(15 downto 8); when 3 => MC_DATA <= PM1_REG( 7 downto 0); when 4 => MC_DATA <= PM2_REG(31 downto 24); when 5 => MC_DATA <= PM2_REG(23 downto 16); when 6 => MC_DATA <= PM2_REG(15 downto 8); when 7 => MC_DATA <= PM2_REG( 7 downto 0); when 8 => MC_DATA <= COI_REG(31 downto 24); when 9 => MC_DATA <= COI_REG(23 downto 16); when 10 => MC_DATA <= COI_REG(15 downto 8); when 11 => MC_DATA <= COI_REG( 7 downto 0); when 12 => MC_DATA <= Temp00; when 13 => MC_DATA <= Temp01; when 14 => MC_DATA <= Temp10; when 15 => MC_DATA <= Temp11; when 16 => MC_DATA <= Temp20; when 17 => MC_DATA <= Temp21; when 18 => MC_DATA <= Temp30; when 19 => MC_DATA <= Temp31; when 20 => MC_DATA <= Temp40; when 21 => MC_DATA <= Temp41; when 22 => MC_DATA <= Temp50; when 23 => MC_DATA <= Temp51; when 24 => MC_DATA <= Temp60; when 25 => MC_DATA <= Temp61; when 26 => MC_DATA <= Temp70; when 27 => MC_DATA <= Temp71; when 28 => MC_DATA <= Temp80; when 29 => MC_DATA <= Temp81; when 30 => MC_DATA <= Temp90; when 31 => MC_DATA <= Temp91; when 32 => MC_DATA <= TempA0; when 33 => MC_DATA <= TempA1; when 34 => MC_DATA <= TempB0; when 35 => MC_DATA <= TempB1; when 36 => MC_DATA <= TempC0; when 37 => MC_DATA <= TempC1; when others => MC_DATA <= (others => '0'); end case; end process; -------------------------------------------- -- Reset fanout -------------------------------------------- SYS_RES <= (others => FE_RES); -------------------------------------------- -------------------------------------------- -- 9600 baud clock -------------------------------------------- process(ETH_RX_CLK, WR_CYCLE, RS_EOF) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '0') then if (WR_CYCLE = '1' and RS_EOF = '0') then RS_CNT <= RS_CNT + 1; else RS_CNT <= 0; end if; end if; end process; -------------- process(ETH_RX_CLK, RS_CNT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (RS_CNT = 2604) then RS_EOF <= '1'; else RS_EOF <= '0'; end if; end if; end process; -------------- process(ETH_RX_CLK, RS_CNT) begin if (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (RS_CNT = 1302) then RS_CLK <= '0'; elsif (RS_CNT = 2604) then RS_CLK <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Gate out RS232 data before they are ready -------------------------------------------- process(WR_CYCLE, ETH_RX_CLK, MC_FLAG, RS_CNT) begin if (WR_CYCLE = '0') then RS_GTE <= '0'; elsif (ETH_RX_CLK'event and ETH_RX_CLK = '1') then if (MC_FLAG = '1' and RS_CNT = 1303) then RS_GTE <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Output RS232 data -------------------------------------------- process(RS_GTE, USB_OUT) begin if (RS_GTE = '1') then RS232_DTE_TXD <= USB_OUT(0); else RS232_DTE_TXD <= '1'; end if; end process; -------------------------------------------- end Behavioral;