library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.numeric_std.ALL; --use work.ipbus.all; package ngFEC_pack is constant txpolarity :std_logic_vector(47 downto 0):= x"000000000000"; constant rxpolarity :std_logic_vector(47 downto 0):= x"000000000000"; constant ttc_rxpolarity :std_logic := '0'; constant ttc_txpolarity :std_logic := '0'; type ipb_wbus is record ipb_addr: std_logic_vector(31 downto 0); ipb_wdata: std_logic_vector(31 downto 0); ipb_strobe: std_logic; ipb_write: std_logic; end record; type ipb_wbus_array is array(natural range <>) of ipb_wbus; -- The signals going from slaves to master - parallel bus type ipb_rbus is record ipb_rdata: std_logic_vector(31 downto 0); ipb_ack: std_logic; ipb_err: std_logic; end record; type ipb_rbus_array is array(natural range <>) of ipb_rbus; constant IPB_RBUS_NULL: ipb_rbus := ((others => '0'), '0', '0'); constant IPB_WBUS_NULL: ipb_wbus := ((others => '0'), (others => '0'), '0', '0'); constant IPBDC_SEL_WIDTH: integer := 5; type ipbdc_bus is record phase: std_logic_vector(1 downto 0); ad: std_logic_vector(31 downto 0); flag: std_logic; end record; type ipbdc_bus_array is array(natural range <>) of ipbdc_bus; constant IPBDC_BUS_NULL: ipbdc_bus := ("00", (others => '0'), '0'); -- For top-level generics type ipb_mac_cfg is (EXTERNAL, INTERNAL); type ipb_ip_cfg is (EXTERNAL, INTERNAL); -- sfp constants CONSTANT kNUM_SFPS : INTEGER := 48; CONSTANT first_sfp : INTEGER := 1; CONSTANT last_sfp : INTEGER := first_sfp + kNUM_SFPS - 1; --------------------------------------- -- partition ids constant no_partition : integer := 14; constant kNUM_I2C_ngCCM : integer := 12; constant JTAG_PARTITION : integer := no_partition-2; constant BKP_PARTITION : integer := no_partition-1; constant kNUM_I2C_BUSSES : integer := kNUM_I2C_ngCCM; --------------------------------------- constant cr_tail : STD_LOGIC_VECTOR(15 downto 0) := x"1195"; -- control register tail constant is_tail : STD_LOGIC_VECTOR(15 downto 0) := x"1196"; -- input size register tail constant os_tail : STD_LOGIC_VECTOR(15 downto 0) := x"1197"; -- input size register tail constant word0 : STD_LOGIC_VECTOR(31 downto 0) := x"00000000"; constant word1 : STD_LOGIC_VECTOR(31 downto 0) := x"00000001"; constant word2 : STD_LOGIC_VECTOR(31 downto 0) := x"00000002"; constant bram_word_size : integer := 11; type array6X12 is array(0 to 5) of std_logic_vector(11 downto 0); type array6X32 is array(0 to 5) of std_logic_vector(31 downto 0); type array8X32 is array(0 to 7) of std_logic_vector(31 downto 0); type array_32x5bit is array (31 downto 0) of std_logic_vector(4 downto 0); constant part : array_32x5bit := ( 0 => "0"&x"0", 1 => "0"&x"1", 2 => "0"&x"2", 3 => "0"&x"3", 4 => "0"&x"4", 5 => "0"&x"5", 6 => "0"&x"6", 7 => "0"&x"7", 8 => "0"&x"8", 9 => "0"&x"9", 10 => "0"&x"a", 11 => "0"&x"b", JTAG_PARTITION => "0"&x"f", BKP_PARTITION => "1"&x"f", OTHERS => "1"&x"5"); type ttc_counter_regs is array (0 to 8) of std_logic_vector(31 downto 0); type state is (process_s, wait_s, refresh_s); type protocol is (CCMlike, QIE10like, GBTXlike, idle); type block_state is array (no_partition-1 downto 0) of state; type ram_register is array (no_partition-1 downto 0) of std_logic_vector(31 downto 0);--# of partitions type ngccm_register is array (no_partition-1 downto 0) of std_logic_vector(31 downto 0);--partitions type ipb_in is array (no_partition-1 downto 0) of ipb_wbus; --partitions type ipb_sfp_in is array (kNUM_SFPS-1 downto 0) of ipb_in; type ipb_out is array (no_partition-1 downto 0) of ipb_rbus; --partitions type ipb_sfp_out is array (kNUM_SFPS-1 downto 0) of ipb_out; type I2C_sfp_ack is array (kNUM_SFPS-1 downto 0) of std_logic_vector(13 downto 0); type ram_container is record ram_addr : STD_LOGIC_VECTOR (bram_word_size downto 0); ram_datain : STD_LOGIC_VECTOR (31 downto 0); ram_wr : STD_LOGIC_VECTOR (0 downto 0); ram_dataout : STD_LOGIC_VECTOR (31 downto 0); ram_addrout : STD_LOGIC_VECTOR (bram_word_size downto 0); end record; constant init_block_ram : ram_container := (ram_addr =>(others => '0'), ram_datain =>(others => '0'), ram_wr =>(others => '0'), ram_dataout =>(others => '0'), ram_addrout =>(others => '0')); type block_ram is array (no_partition-1 downto 0) of ram_container; type ram_wbus is record wr : std_logic; addr : std_logic_vector(11 downto 0); wdata : std_logic_vector(31 downto 0); end record; type ram_rbus is record rdata : std_logic_vector(31 downto 0); end record; type ram_rbus_A is array (natural range <>) of ram_rbus; type ram_wbus_A is array (natural range <>) of ram_wbus; constant init_ipb_rbus : ipb_rbus := (ipb_rdata => (others=> '0'), ipb_ack => '0', ipb_err => '0'); constant init_ipb_wbus : ipb_wbus := (ipb_addr => (others=>'0'), ipb_wdata => (others=>'0'), ipb_strobe => '0', ipb_write => '0'); TYPE sfp_en_arr IS ARRAY (0 TO 47) OF BOOLEAN; TYPE array_KNUM_SFPSx12 IS ARRAY (0 TO 47) OF STD_LOGIC_VECTOR(11 DOWNTO 0); TYPE array_128X32bit IS ARRAY (0 TO 127) OF STD_LOGIC_VECTOR(31 DOWNTO 0); TYPE array_512X32bit IS ARRAY (0 TO 511) OF STD_LOGIC_VECTOR(31 DOWNTO 0); TYPE array_1024X32bit IS ARRAY (0 TO 1023) OF STD_LOGIC_VECTOR(31 DOWNTO 0); CONSTANT SFP_ENABLE : sfp_en_arr := (others => true); --=== ipb slaves =============-- constant nbr_usr_slaves : positive := 3 + kNUM_SFPS; constant user_ipb_stat_regs : integer := kNUM_SFPS+1; constant user_ipb_ctrl_regs : integer := kNUM_SFPS+2; constant user_board_I2C : integer := 0; constant pipeline : boolean := true; type axi_wbus is record axi_awid : STD_LOGIC_VECTOR(5 DOWNTO 0); axi_awaddr : STD_LOGIC_VECTOR(31 DOWNTO 0); axi_awlen : STD_LOGIC_VECTOR(7 DOWNTO 0); axi_awsize : STD_LOGIC_VECTOR(2 DOWNTO 0); axi_awburst : STD_LOGIC_VECTOR(1 DOWNTO 0); axi_awvalid : STD_LOGIC; axi_wdata : STD_LOGIC_VECTOR(31 DOWNTO 0); axi_wstrb : STD_LOGIC_VECTOR(3 DOWNTO 0); axi_wlast : STD_LOGIC; axi_wvalid : STD_LOGIC; axi_bready : STD_LOGIC; axi_arid : STD_LOGIC_VECTOR(5 DOWNTO 0); axi_araddr : STD_LOGIC_VECTOR(31 DOWNTO 0); axi_arlen : STD_LOGIC_VECTOR(7 DOWNTO 0); axi_arsize : STD_LOGIC_VECTOR(2 DOWNTO 0); axi_arburst : STD_LOGIC_VECTOR(1 DOWNTO 0); axi_arvalid : STD_LOGIC; axi_rready : STD_LOGIC; end record; type axi_rbus is record axi_awready : STD_LOGIC; axi_wready : STD_LOGIC; axi_bid : STD_LOGIC_VECTOR(5 DOWNTO 0); axi_bresp : STD_LOGIC_VECTOR(1 DOWNTO 0); axi_bvalid : STD_LOGIC; axi_arready : STD_LOGIC; axi_rid : STD_LOGIC_VECTOR(5 DOWNTO 0); axi_rdata : STD_LOGIC_VECTOR(31 DOWNTO 0); axi_rresp : STD_LOGIC_VECTOR(1 DOWNTO 0); axi_rlast : STD_LOGIC; axi_rvalid : STD_LOGIC; c2c_link_up : STD_LOGIC; end record; CONSTANT kMSB_ngCCM : INTEGER := 11; -- For IPbus access (must match value in ADDR_MAP.v) CONSTANT kWAIT_ngCCM : INTEGER := 6; -- For IPbus access (must match value in ADDR_MAP.v) CONSTANT kWTICKS_ngCCM : INTEGER := 2; -- For IPbus access (must match value in ADDR_MAP.v) TYPE ngccm_pin_output_typ IS RECORD -- JTAG connection jtag_tdi : STD_LOGIC; jtag_tms : STD_LOGIC; jtag_tck : STD_LOGIC; jtag_trst : STD_LOGIC; sel_addr : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Redundant JTAG connection sec_jtag_tdi : STD_LOGIC; sec_jtag_tms : STD_LOGIC; sec_jtag_tck : STD_LOGIC; sec_jtag_trst : STD_LOGIC; sec_sel_addr : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Primary Fast Singnals peltier : STD_LOGIC_VECTOR(3 DOWNTO 0); bkp_reset : STD_LOGIC; bkp_reset_qie : STD_LOGIC; bkp_wte : STD_LOGIC; bkp_pwr_enable : STD_LOGIC; -- Redundant Fast Singnals sec_peltier : STD_LOGIC_VECTOR(3 DOWNTO 0); sec_reset : STD_LOGIC; sec_reset_qie : STD_LOGIC; sec_wte : STD_LOGIC; sec_pwr_enable : STD_LOGIC; -- Primary I2C connection -- There is only a single SCL for a grouping of I2C "busses" bkt_scl : STD_LOGIC_VECTOR(2 DOWNTO 0); bkt_sda : STD_LOGIC_VECTOR(kNUM_I2C_ngccm DOWNTO 1); -- Redundant I2C connection -- There is only a single SCL for a grouping of I2C "busses" sec_scl : STD_LOGIC; sec_sda : STD_LOGIC_VECTOR(kNUM_I2C_ngccm DOWNTO 1); -- Debug communication test_comm : STD_LOGIC; sec_test_comm : STD_LOGIC; prbs_rx : STD_LOGIC_VECTOR(19 downto 0); END RECORD ngccm_pin_output_typ; TYPE ngccm_pin_input_typ IS RECORD -- JTAG connection jtag_tdo : STD_LOGIC; jtag_tms : STD_LOGIC; jtag_tck : STD_LOGIC; jtag_trst : STD_LOGIC; geo_addr : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Redundant JTAG connection sec_jtag_tdo : STD_LOGIC; sec_jtag_tms : STD_LOGIC; sec_jtag_tck : STD_LOGIC; sec_jtag_trst : STD_LOGIC; sec_geo_addr : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Primary Fast Singnals ngccm_rev_id : STD_LOGIC_VECTOR(2 DOWNTO 0); bkp_pwr_good : STD_LOGIC; bkp_reset : STD_LOGIC; bkp_reset_qie : STD_LOGIC; bkp_wte : STD_LOGIC; bkp_pwr_enable : STD_LOGIC; -- Redundant Fast Singnals ngccm_neigh_rev_id : STD_LOGIC_VECTOR(2 DOWNTO 0); sec_pwr_good : STD_LOGIC; sec_reset : STD_LOGIC; sec_reset_qie : STD_LOGIC; sec_wte : STD_LOGIC; sec_pwr_enable : STD_LOGIC; -- Primary I2C connection -- There is only a single SCL for a grouping of I2C "busses" bkt_scl : STD_LOGIC_VECTOR(2 DOWNTO 0); bkt_sda : STD_LOGIC_VECTOR(kNUM_I2C_ngccm DOWNTO 1); -- Redundant I2C connection -- There is only a single SCL for a grouping of I2C "busses" sec_scl : STD_LOGIC; sec_sda : STD_LOGIC_VECTOR(kNUM_I2C_ngccm DOWNTO 1); -- Debug communication test_comm : STD_LOGIC; sec_test_comm : STD_LOGIC; prbs_tx : STD_LOGIC_VECTOR(19 downto 0); END RECORD ngccm_pin_input_typ; constant HF : boolean:=true; constant HBHE : boolean:=false; -- Declare functions function ipb_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer; function set_prbs_tabs(hbhehf_switch : boolean; seed_length: integer) return std_logic_vector; function inv_prbs_seed(hbhehf_switch : boolean; seed_length: integer) return boolean; function set_initialValue (hbhehf_switch : boolean; seed_length: integer;inverter:boolean)return std_logic_vector; function lsfr_HF (inverter : boolean;initial_value: std_logic_vector)return std_logic_vector; function lsfr_HBHE(initial_value : std_logic_vector)return std_logic_vector; function prbs_pattern_bitwise_err_cnt (PRBS_rx_pattern: std_logic_vector; PRBS_pattern_next:std_logic_vector;seed_length: integer;cnt_lenght: integer)return std_logic_vector; -- function ngFEC_partition_sel(signal addr : in std_logic_vector(31 downto 0)) return integer; FUNCTION ngCCM_Pins_to_GBT_Word (CONSTANT pinss : ngccm_pin_output_typ) RETURN STD_LOGIC_VECTOR; FUNCTION GBT_Word_to_ngCCM_Pins (CONSTANT GBT_Word : IN STD_LOGIC_VECTOR(83 DOWNTO 0)) RETURN ngccm_pin_input_typ; end ngFEC_pack; package body ngFEC_pack is function ipb_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer is variable sel : integer; begin -- addr, "00------------------------------" is reserved (system ipbus fabric) if std_match(addr, "011000000000000000000-----------") then sel := user_ipb_stat_regs; elsif std_match(addr, "011000000000000000001000--------") then sel := user_ipb_ctrl_regs; elsif std_match(addr, "011000000001--------------------") then sel := user_board_I2C; elsif SFP_ENABLE(0) and std_match(addr(31 DOWNTO 0), "01101-000000--------------------") THEN sel := 1; -- SFP port 1 elsif SFP_ENABLE(1) and std_match(addr(31 DOWNTO 0), "01101-000001--------------------") THEN sel := 2; -- SFP port 2 elsif SFP_ENABLE(2) and std_match(addr(31 DOWNTO 0), "01101-000010--------------------") THEN sel := 3; -- SFP port 3 elsif SFP_ENABLE(3) and std_match(addr(31 DOWNTO 0), "01101-000011--------------------") THEN sel := 4; -- SFP port 4 elsif SFP_ENABLE(4) and std_match(addr(31 DOWNTO 0), "01101-000100--------------------") THEN sel := 5; -- SFP port 5 elsif SFP_ENABLE(5) and std_match(addr(31 DOWNTO 0), "01101-000101--------------------") THEN sel := 6; -- SFP port 6 elsif SFP_ENABLE(6) and std_match(addr(31 DOWNTO 0), "01101-000110--------------------") THEN sel := 7; -- SFP port 7 elsif SFP_ENABLE(7) and std_match(addr(31 DOWNTO 0), "01101-000111--------------------") THEN sel := 8; -- SFP port 8 elsif SFP_ENABLE(8) and std_match(addr(31 DOWNTO 0), "01101-001000--------------------") THEN sel := 9; -- SFP port 9 elsif SFP_ENABLE(9) and std_match(addr(31 DOWNTO 0), "01101-001001--------------------") THEN sel := 10; -- SFP port 10 elsif SFP_ENABLE(10) and std_match(addr(31 DOWNTO 0), "01101-001010--------------------") THEN sel := 11; -- SFP port 11 elsif SFP_ENABLE(11) and std_match(addr(31 DOWNTO 0), "01101-001011--------------------") THEN sel := 12; -- SFP port 12 elsif SFP_ENABLE(12) and std_match(addr(31 DOWNTO 0), "01101-001100--------------------") THEN sel := 13; -- SFP port 13 elsif SFP_ENABLE(13) and std_match(addr(31 DOWNTO 0), "01101-001101--------------------") THEN sel := 14; -- SFP port 14 elsif SFP_ENABLE(14) and std_match(addr(31 DOWNTO 0), "01101-001110--------------------") THEN sel := 15; -- SFP port 15 elsif SFP_ENABLE(15) and std_match(addr(31 DOWNTO 0), "01101-001111--------------------") THEN sel := 16; -- SFP port 16 elsif SFP_ENABLE(16) and std_match(addr(31 DOWNTO 0), "01101-010000--------------------") THEN sel := 17; -- SFP port 17 elsif SFP_ENABLE(17) and std_match(addr(31 DOWNTO 0), "01101-010001--------------------") THEN sel := 18; -- SFP port 18 elsif SFP_ENABLE(18) and std_match(addr(31 DOWNTO 0), "01101-010010--------------------") THEN sel := 19; -- SFP port 19 elsif SFP_ENABLE(19) and std_match(addr(31 DOWNTO 0), "01101-010011--------------------") THEN sel := 20; -- SFP port 20 elsif SFP_ENABLE(20) and std_match(addr(31 DOWNTO 0), "01101-010100--------------------") THEN sel := 21; -- SFP port 21 elsif SFP_ENABLE(21) and std_match(addr(31 DOWNTO 0), "01101-010101--------------------") THEN sel := 22; -- SFP port 22 elsif SFP_ENABLE(22) and std_match(addr(31 DOWNTO 0), "01101-010110--------------------") THEN sel := 23; -- SFP port 23 elsif SFP_ENABLE(23) and std_match(addr(31 DOWNTO 0), "01101-010111--------------------") THEN sel := 24; -- SFP port 24 elsif SFP_ENABLE(24) and std_match(addr(31 DOWNTO 0), "01101-011000--------------------") THEN sel := 25; -- SFP port 25 elsif SFP_ENABLE(25) and std_match(addr(31 DOWNTO 0), "01101-011001--------------------") THEN sel := 26; -- SFP port 26 elsif SFP_ENABLE(26) and std_match(addr(31 DOWNTO 0), "01101-011010--------------------") THEN sel := 27; -- SFP port 27 elsif SFP_ENABLE(27) and std_match(addr(31 DOWNTO 0), "01101-011011--------------------") THEN sel := 28; -- SFP port 28 elsif SFP_ENABLE(28) and std_match(addr(31 DOWNTO 0), "01101-011100--------------------") THEN sel := 29; -- SFP port 29 elsif SFP_ENABLE(29) and std_match(addr(31 DOWNTO 0), "01101-011101--------------------") THEN sel := 30; -- SFP port 30 elsif SFP_ENABLE(30) and std_match(addr(31 DOWNTO 0), "01101-011110--------------------") THEN sel := 31; -- SFP port 31 elsif SFP_ENABLE(31) and std_match(addr(31 DOWNTO 0), "01101-011111--------------------") THEN sel := 32; -- SFP port 32 elsif SFP_ENABLE(32) and std_match(addr(31 DOWNTO 0), "01101-100000--------------------") THEN sel := 33; -- SFP port 33 elsif SFP_ENABLE(33) and std_match(addr(31 DOWNTO 0), "01101-100001--------------------") THEN sel := 34; -- SFP port 34 elsif SFP_ENABLE(34) and std_match(addr(31 DOWNTO 0), "01101-100010--------------------") THEN sel := 35; -- SFP port 35 elsif SFP_ENABLE(35) and std_match(addr(31 DOWNTO 0), "01101-100011--------------------") THEN sel := 36; -- SFP port 36 elsif SFP_ENABLE(36) and std_match(addr(31 DOWNTO 0), "01101-100100--------------------") THEN sel := 37; -- SFP port 37 elsif SFP_ENABLE(37) and std_match(addr(31 DOWNTO 0), "01101-100101--------------------") THEN sel := 38; -- SFP port 38 elsif SFP_ENABLE(38) and std_match(addr(31 DOWNTO 0), "01101-100110--------------------") THEN sel := 39; -- SFP port 39 elsif SFP_ENABLE(39) and std_match(addr(31 DOWNTO 0), "01101-100111--------------------") THEN sel := 40; -- SFP port 40 elsif SFP_ENABLE(40) and std_match(addr(31 DOWNTO 0), "01101-101000--------------------") THEN sel := 41; -- SFP port 41 elsif SFP_ENABLE(41) and std_match(addr(31 DOWNTO 0), "01101-101001--------------------") THEN sel := 42; -- SFP port 42 elsif SFP_ENABLE(42) and std_match(addr(31 DOWNTO 0), "01101-101010--------------------") THEN sel := 43; -- SFP port 43 elsif SFP_ENABLE(43) and std_match(addr(31 DOWNTO 0), "01101-101011--------------------") THEN sel := 44; -- SFP port 44 elsif SFP_ENABLE(44) and std_match(addr(31 DOWNTO 0), "01101-101100--------------------") THEN sel := 45; -- SFP port 45 elsif SFP_ENABLE(45) and std_match(addr(31 DOWNTO 0), "01101-101101--------------------") THEN sel := 46; -- SFP port 46 elsif SFP_ENABLE(46) and std_match(addr(31 DOWNTO 0), "01101-101110--------------------") THEN sel := 47; -- SFP port 47 elsif SFP_ENABLE(47) and std_match(addr(31 DOWNTO 0), "01101-101111--------------------") THEN sel := 48; -- SFP port 48 else sel := user_ipb_stat_regs; end if; return sel; end ipb_addr_sel; -- function ngFEC_partition_sel(signal addr : in std_logic_vector(31 downto 0)) return integer is -- variable part : integer; -- begin -- IF std_match(addr(26), '0') then -- IF std_match(addr(19 DOWNTO 16), x"0") THEN part := 0; -- ELSIF std_match(addr(19 DOWNTO 16), x"1") THEN part := 1; -- ELSIF std_match(addr(19 DOWNTO 16), x"2") THEN part := 2; -- ELSIF std_match(addr(19 DOWNTO 16), x"3") THEN part := 3; -- ELSIF std_match(addr(19 DOWNTO 16), x"4") THEN part := 4; -- ELSIF std_match(addr(19 DOWNTO 16), x"5") THEN part := 5; -- ELSIF std_match(addr(19 DOWNTO 16), x"6") THEN part := 6; -- ELSIF std_match(addr(19 DOWNTO 16), x"7") THEN part := 7; -- ELSIF std_match(addr(19 DOWNTO 16), x"8") THEN part := 8; -- ELSIF std_match(addr(19 DOWNTO 16), x"9") THEN part := 9; -- ELSIF std_match(addr(19 DOWNTO 16), x"a") THEN part := 10; -- ELSIF std_match(addr(19 DOWNTO 16), x"b") THEN part := 11; -- ELSIF std_match(addr(19 DOWNTO 16), x"c") THEN part := 12; -- ELSIF std_match(addr(19 DOWNTO 16), x"d") THEN part := 13; -- ELSIF std_match(addr(19 DOWNTO 16), x"f") THEN part := JTAG_PARTITION; -- reserved for JTAG -- ELSE part := 21; -- END IF; -- ELSIF std_match(addr(26), '1') then --redundant channels -- IF std_match(addr(19 DOWNTO 16), x"f") THEN part := BKP_PARTITION; -- reserved for BKP commands -- ELSE part := 21; -- END IF; -- ELSE part := 21; -- END IF; -- return part; --end ngFEC_partition_sel; FUNCTION GBT_Word_to_ngCCM_Pins ( CONSTANT GBT_Word : IN STD_LOGIC_VECTOR(83 DOWNTO 0)) RETURN ngccm_pin_input_typ IS VARIABLE pinss : ngccm_pin_input_typ; BEGIN -- FUNCTION GBT_Word_to_Pins pinss.jtag_tck := GBT_Word(0); pinss.jtag_tdo := GBT_Word(2); pinss.jtag_tms := GBT_Word(4); pinss.jtag_trst := GBT_Word(6); pinss.geo_addr(0) := GBT_Word(8); pinss.geo_addr(1) := GBT_Word(10); pinss.geo_addr(2) := GBT_Word(12); pinss.geo_addr(3) := GBT_Word(14); pinss.ngccm_rev_id(0) := GBT_Word(32); pinss.ngccm_rev_id(1) := GBT_Word(34); pinss.ngccm_rev_id(2) := GBT_Word(36); pinss.bkp_pwr_good := GBT_Word(38); pinss.bkp_reset := GBT_Word(40); pinss.bkp_reset_qie := GBT_Word(42); pinss.bkp_wte := GBT_Word(44); pinss.bkp_pwr_enable := GBT_Word(46); -- There is only a single SCL for a grouping of I2C "busses" pinss.bkt_scl(0) := GBT_Word(72); pinss.bkt_sda(1) := GBT_Word(48); pinss.bkt_sda(2) := GBT_Word(50); pinss.bkt_sda(3) := GBT_Word(52); pinss.bkt_sda(4) := GBT_Word(54); pinss.bkt_sda(5) := GBT_Word(56); pinss.bkt_scl(1) := GBT_Word(74); pinss.bkt_sda(6) := GBT_Word(58); pinss.bkt_sda(7) := GBT_Word(60); pinss.bkt_sda(8) := GBT_Word(62); pinss.bkt_sda(9) := GBT_Word(64); pinss.bkt_sda(10) := GBT_Word(66); pinss.bkt_scl(2) := GBT_Word(76); pinss.bkt_sda(11) := GBT_Word(68); pinss.bkt_sda(12) := GBT_Word(70); pinss.test_comm := GBT_Word(78); pinss.prbs_tx := GBT_Word(83 downto 80) & GBT_Word(31 downto 16); RETURN pinss; END FUNCTION GBT_Word_to_ngCCM_Pins; FUNCTION ngCCM_Pins_to_GBT_Word ( CONSTANT pinss : ngccm_pin_output_typ) RETURN STD_LOGIC_VECTOR IS VARIABLE GBT_Word : STD_LOGIC_VECTOR(83 DOWNTO 0); BEGIN -- FUNCTION ngCCM_Pins_to_GBT_Word -- Primary JTAG connection GBT_Word(0) := pinss.jtag_tck; GBT_Word(2) := pinss.jtag_tdi; GBT_Word(4) := pinss.jtag_tms; GBT_Word(6) := pinss.jtag_trst; GBT_Word(8) := pinss.sel_addr(0); GBT_Word(10) := pinss.sel_addr(1); GBT_Word(12) := pinss.sel_addr(2); GBT_Word(14) := pinss.sel_addr(3); -- Redundant JTAG connection GBT_Word(1) := pinss.jtag_tck; GBT_Word(3) := pinss.jtag_tdi; GBT_Word(5) := pinss.jtag_tms; GBT_Word(7) := pinss.jtag_trst; GBT_Word(9) := pinss.sel_addr(0); GBT_Word(11) := pinss.sel_addr(1); GBT_Word(13) := pinss.sel_addr(2); GBT_Word(15) := pinss.sel_addr(3); -- Primary Fast Singnals GBT_Word(32) := pinss.peltier(0); GBT_Word(34) := pinss.peltier(1); GBT_Word(36) := pinss.peltier(2); GBT_Word(38) := pinss.peltier(3); GBT_Word(40) := pinss.bkp_reset; GBT_Word(42) := pinss.bkp_reset_qie; GBT_Word(44) := pinss.bkp_wte; GBT_Word(46) := pinss.bkp_pwr_enable; -- Redundant Fast Singnals GBT_Word(33) := pinss.peltier(0); GBT_Word(35) := pinss.peltier(1); GBT_Word(37) := pinss.peltier(2); GBT_Word(39) := pinss.peltier(3); GBT_Word(41) := pinss.bkp_reset; GBT_Word(43) := pinss.sec_reset_qie; GBT_Word(45) := pinss.sec_wte; GBT_Word(47) := pinss.bkp_pwr_enable; -- Primary I2C connection GBT_Word(48) := pinss.bkt_sda(1); GBT_Word(50) := pinss.bkt_sda(2); GBT_Word(52) := pinss.bkt_sda(3); GBT_Word(54) := pinss.bkt_sda(4); GBT_Word(56) := pinss.bkt_sda(5); GBT_Word(58) := pinss.bkt_sda(6); GBT_Word(60) := pinss.bkt_sda(7); GBT_Word(62) := pinss.bkt_sda(8); GBT_Word(64) := pinss.bkt_sda(9); GBT_Word(66) := pinss.bkt_sda(10); GBT_Word(68) := pinss.bkt_sda(11); -- internal ngCCM I2C slave GBT_Word(70) := pinss.bkt_sda(12); GBT_Word(72) := pinss.bkt_scl(0); GBT_Word(74) := pinss.bkt_scl(1); GBT_Word(76) := pinss.bkt_scl(2); -- Redundant I2C connection GBT_Word(49) := pinss.bkt_sda(1); GBT_Word(51) := pinss.bkt_sda(2); GBT_Word(53) := pinss.bkt_sda(3); GBT_Word(55) := pinss.bkt_sda(4); GBT_Word(57) := pinss.bkt_sda(5); GBT_Word(59) := pinss.bkt_sda(6); GBT_Word(61) := pinss.bkt_sda(7); GBT_Word(63) := pinss.bkt_sda(8); GBT_Word(65) := pinss.bkt_sda(9); GBT_Word(67) := pinss.bkt_sda(10); GBT_Word(69) := pinss.bkt_sda(11); -- internal ngCCM I2C slave GBT_Word(71) := pinss.bkt_sda(12); GBT_Word(73) := pinss.bkt_scl(0); GBT_Word(75) := pinss.bkt_scl(1); GBT_Word(77) := pinss.bkt_scl(2); -- Debug connection GBT_Word(31 downto 16) := pinss.prbs_rx(15 downto 0); GBT_Word(78) := pinss.test_comm; GBT_Word(79) := pinss.test_comm; GBT_Word(83 downto 80) := pinss.prbs_rx(19 downto 16); RETURN GBT_Word; END FUNCTION ngCCM_Pins_to_GBT_Word; function set_prbs_tabs(hbhehf_switch : boolean; seed_length: integer) return std_logic_vector is variable tabs : std_logic_vector(seed_length-1 downto 0); begin if hbhehf_switch = HF then case seed_length is when 3 => tabs := "110"; -- for debug of this code when 4 => tabs := "1100"; -- not standard comm. code but from Wikipedia as a possibility when 7 => tabs := "1100000"; -- not standard but similar to 8b/10b encoded patterns when 9 => tabs := "100010000"; -- ITU-T O.150 when 11 => tabs := "10100000000"; -- ITU-T O.150 when 15 => tabs := "110000000000000"; -- ITU-T O.150 when 17 => tabs := "10010000000000000"; -- OIF-CEI-P-02.0 when 20 => tabs := "10000000000000000100"; -- ITU-T O.150 when 23 => tabs := "10000100000000000000000"; -- ITU-T O.150 when 29 => tabs := "10100000000000000000000000000"; -- ITU-T O.150 when 31 => tabs := "1001000000000000000000000000000"; -- ITU-T O.150 / OIF-CEI-02.0 when others => tabs :=(others=>'0'); -- use all 0's to indicate unknown taps end case; -- Taps for lfsrHBHE().These are based on the Table 1: Primitive binary polynomials from -- URL: http://poincare.matf.bg.ac.rs/~ezivkovm/publications/primpol1.pdf elsif hbhehf_switch = HBHE then case seed_length is when 3 => tabs := "001"; when 4 => tabs := "0001"; when 7 => tabs := "0011111"; when 9 => tabs := "011100110"; when 11 => tabs := "00101010011"; when 15 => tabs := "001000011110000"; when 17 => tabs := "00001000010110010"; when 20 => tabs := "00101010001000000001"; when 23 => tabs := "00000010001110000010000"; when 29 => tabs := "00000001000001100010000000100"; when 31 => tabs := "0000000000000001010001010000001"; when others => tabs :=(others=>'1'); -- use all 1's to indicate unknown taps end case; end if; return tabs; end function; function inv_prbs_seed (hbhehf_switch : boolean; seed_length: integer) return boolean is variable inverter : boolean; begin if hbhehf_switch = HF then case seed_length is when 3 => inverter := true; when 4 => inverter := false; when 7 => inverter := true; when 9 => inverter := false; when 11 => inverter := false; when 15 => inverter := true; when 17 => inverter := false; when 20 => inverter := false; when 23 => inverter := true; when 29 => inverter := true; when 31 => inverter := true; when others => inverter :=(false); end case; -- elsif hbhehf_switch = HBHE then -- case seed_length is -- when others => inverter := false; -- end case; end if; return inverter; end function; function set_initialValue (hbhehf_switch : boolean; seed_length: integer;inverter:boolean) return std_logic_vector is variable initial_value : std_logic_vector(seed_length-1 downto 0); begin if hbhehf_switch = HF then if inverter then initial_value:=(others=>'0'); else initial_value:=(others=>'1'); end if; elsif hbhehf_switch = HBHE then initial_value := set_prbs_tabs(HBHE,seed_length); --seed; end if; return initial_value; end function; -- the lsfr_HF() function was loosely based on a synthesizable module -- found in the book HDL Chip Design by Douglas J. Smith -- in Chapter 7, pg 185. -- -- Pass in the current value of the lfsr counter and the output is the next -- value. If initializing the counter, pass in all '0's. This is an invalid -- value for lfsr counters since it prevents the counter from advancing -- (output is all '0's). However, use of all '0's indicates that the reset -- value is wanted. If inv is false, the reset pattern is all '1's. If inv -- is true, the reset pattern is all '0's since the input is inverted first, -- creating all '1's. function lsfr_HF (inverter : boolean;initial_value: std_logic_vector) return std_logic_vector is variable feedback : std_logic_vector(initial_value'high downto 0); variable taps : std_logic_vector(initial_value'high downto 0); variable fb : std_logic:='0'; variable fbinv : std_logic:='1'; begin taps := set_prbs_tabs(HF,initial_value'length); feedback := initial_value; for i in initial_value'high downto 0 loop if taps(i) = '1' then if inverter then fbinv := fbinv xnor feedback(i+initial_value'low); fb := fbinv; else fb := fb xor feedback(i+initial_value'low); end if; end if; end loop; feedback:= feedback(initial_value'high-1 downto initial_value'low)&fb; return feedback; end function; -- the lsfr_HBHE() function is based on a Galois or one-to-many Implemenation. --URL: http://www.markharvey.info/fpga/lfsr/lfsr.html -- The most-significant bit is feedback directly into the least significant bit, and is also individually XORed with the chosen taps. -- If initializing the counter, pass the seed which is also same as the taps. function lsfr_HBHE (initial_value: std_logic_vector) return std_logic_vector is variable feedback : std_logic_vector(initial_value'high downto 0); variable taps : std_logic_vector(initial_value'high downto 0); begin taps := set_prbs_tabs(HBHE,initial_value'length); feedback := initial_value; for i in initial_value'high-1 downto 0 loop if taps(i) = '1' then feedback(i) := feedback(i) xor feedback(initial_value'high); else feedback(i) := feedback(i); end if; end loop; feedback:= feedback(initial_value'high-1 downto initial_value'low) & feedback(initial_value'high); return feedback; end function; ------------------------------------------------------------------------------------------------------------------- function prbs_pattern_bitwise_err_cnt (PRBS_rx_pattern: std_logic_vector; PRBS_pattern_next:std_logic_vector;seed_length: integer;cnt_lenght: integer) return std_logic_vector is variable prbs_error_detection : std_logic_vector(seed_length-1 downto 0):= (others=>'0'); variable prbs_bitwise_error_detection_cnt : unsigned(cnt_lenght-1 downto 0):=(others=>'0'); begin prbs_error_detection := PRBS_rx_pattern xor PRBS_pattern_next; for i in prbs_error_detection'high downto prbs_error_detection'low loop if prbs_error_detection(i) = '1' then prbs_bitwise_error_detection_cnt := prbs_bitwise_error_detection_cnt + 1; else prbs_bitwise_error_detection_cnt := prbs_bitwise_error_detection_cnt; end if; end loop; return std_logic_vector(prbs_bitwise_error_detection_cnt); end function; end package body;