diff --git a/boards/uniboard2b/libraries/unb2b_board/hdllib.cfg b/boards/uniboard2b/libraries/unb2b_board/hdllib.cfg index 9e2592071927a866e7dd3e4d2a7c0d5b50410399..eeaa49ec3fb83c933044102a5f2bdec5a8746057 100644 --- a/boards/uniboard2b/libraries/unb2b_board/hdllib.cfg +++ b/boards/uniboard2b/libraries/unb2b_board/hdllib.cfg @@ -12,38 +12,38 @@ hdl_lib_include_ip = ip_arria10_e1sg_tse_sgmii_lvds #ip_arria10_e1sg_pll_clk125 synth_files = - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_pkg.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_system_info.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_system_info_reg.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/mms_unb2_board_system_info.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_clk200_pll.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_clk25_pll.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_clk125_pll.vhd -# ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_clk200mm_pll.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_wdi_extend.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_node_ctrl.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_pmbus_ctrl.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_sens_ctrl.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_hmc_ctrl.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_sens.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_sens_reg.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_fpga_sens_reg.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/mms_unb2_board_sens.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/mms_unb2_fpga_sens.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_wdi_reg.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_qsfp_leds.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/ctrl_unb2_board.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_front_io.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_back_io.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_ring_io.vhd - ../../../uniboard2a/libraries/unb2a_board/src/vhdl/unb2_board_peripherals_pkg.vhd + src/vhdl/unb2_board_pkg.vhd + src/vhdl/unb2_board_system_info.vhd + src/vhdl/unb2_board_system_info_reg.vhd + src/vhdl/mms_unb2_board_system_info.vhd + src/vhdl/unb2_board_clk200_pll.vhd + src/vhdl/unb2_board_clk25_pll.vhd + src/vhdl/unb2_board_clk125_pll.vhd +# src/vhdl/unb2_board_clk200mm_pll.vhd + src/vhdl/unb2_board_wdi_extend.vhd + src/vhdl/unb2_board_node_ctrl.vhd + src/vhdl/unb2_board_pmbus_ctrl.vhd + src/vhdl/unb2_board_sens_ctrl.vhd + src/vhdl/unb2_board_hmc_ctrl.vhd + src/vhdl/unb2_board_sens.vhd + src/vhdl/unb2_board_sens_reg.vhd + src/vhdl/unb2_fpga_sens_reg.vhd + src/vhdl/mms_unb2_board_sens.vhd + src/vhdl/mms_unb2_fpga_sens.vhd + src/vhdl/unb2_board_wdi_reg.vhd + src/vhdl/unb2_board_qsfp_leds.vhd + src/vhdl/ctrl_unb2_board.vhd + src/vhdl/unb2_board_front_io.vhd + src/vhdl/unb2_board_back_io.vhd + src/vhdl/unb2_board_ring_io.vhd + src/vhdl/unb2_board_peripherals_pkg.vhd test_bench_files = - ../../../uniboard2a/libraries/unb2a_board/tb/vhdl/tb_mms_unb2_board_sens.vhd - ../../../uniboard2a/libraries/unb2a_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd - ../../../uniboard2a/libraries/unb2a_board/tb/vhdl/tb_unb2_board_clk25_pll.vhd - ../../../uniboard2a/libraries/unb2a_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd - ../../../uniboard2a/libraries/unb2a_board/tb/vhdl/tb_unb2_board_qsfp_leds.vhd + tb/vhdl/tb_mms_unb2_board_sens.vhd + tb/vhdl/tb_unb2_board_clk200_pll.vhd + tb/vhdl/tb_unb2_board_clk25_pll.vhd + tb/vhdl/tb_unb2_board_node_ctrl.vhd + tb/vhdl/tb_unb2_board_qsfp_leds.vhd [modelsim_project_file] diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/ctrl_unb2_board.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/ctrl_unb2_board.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4e76c651b8c47229d1b54c9e9320893d9d23b592 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/ctrl_unb2_board.vhd @@ -0,0 +1,819 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide general control infrastructure +-- Usage: In a design <design_name>.vhd that consists of: +-- . mmm_<design_name>.vhd with a Nios2 and the MM bus and the peripherals +-- . ctrl_unb2_board.vhd with e.g. 1GbE, PPS, I2C, Remu, EPCS + +LIBRARY IEEE, common_lib, dp_lib, ppsh_lib, i2c_lib, technology_lib, tech_tse_lib, eth_lib, remu_lib, epcs_lib, tech_pll_lib, tech_clkbuf_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE work.unb2_board_pkg.ALL; +USE i2c_lib.i2c_pkg.ALL; +USE technology_lib.technology_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE eth_lib.eth_pkg.ALL; + +ENTITY ctrl_unb2_board IS + GENERIC ( + ---------------------------------------------------------------------------- + -- General + ---------------------------------------------------------------------------- + g_technology : NATURAL := c_tech_arria10; + g_sim : BOOLEAN := FALSE; + g_design_name : STRING := "UNUSED"; + g_fw_version : t_unb2_board_fw_version := (0, 0); -- firmware version x.y + g_stamp_date : NATURAL := 0; + g_stamp_time : NATURAL := 0; + g_stamp_svn : NATURAL := 0; + g_design_note : STRING := "UNUSED"; + g_base_ip : STD_LOGIC_VECTOR(16-1 DOWNTO 0) := X"0A63"; -- Base IP address used by unb_osy: 10.99.xx.yy + g_mm_clk_freq : NATURAL := c_unb2_board_mm_clk_freq_125M; + g_eth_clk_freq : NATURAL := c_unb2_board_eth_clk_freq_125M; + g_tse_clk_buf : BOOLEAN := FALSE; + + ---------------------------------------------------------------------------- + -- External CLK + ---------------------------------------------------------------------------- + g_dp_clk_freq : NATURAL := c_unb2_board_ext_clk_freq_200M; + g_dp_clk_use_pll : BOOLEAN := TRUE; + -- PLL phase clk shift with respect to CLK + -- STRING := "0" = 0 + -- STRING := "156" = 011.25 + -- STRING := "313" = 022.5 + -- STRING := "469" = 033.75 + -- STRING := "625" = 045 + -- STRING := "781" = 056.25 + -- STRING := "938" = 067.5 + -- STRING := "1094" = 078.75 + -- STRING := "1250" = 090 + -- STRING := "1406" = 1250+ 156 = 101.25 + -- STRING := "1563" = 1250+ 313 = 112.5 + -- STRING := "1719" = 1250+ 469 = 123.75 + -- STRING := "1875" = 1250+ 625 = 135 + -- STRING := "2031" = 1250+ 781 = 146.25 + -- STRING := "2188" = 1250+ 938 = 157.5 + -- STRING := "2344" = 1250+1094 = 168.75 + -- STRING := "2500" = 1250+1250 = 180 + -- STRING := "2656" = 2500+ 156 = 191.25 + -- STRING := "2813" = 2500+ 313 = 202.5 + -- STRING := "2969" = 2500+ 469 = 213.75 + -- STRING := "3125" = 2500+ 625 = 225 + -- STRING := "3281" = 2500+ 781 = 236.25 + -- STRING := "3438" = 2500+ 938 = 247.5 + -- STRING := "3594" = 2500+1094 = 258.75 + -- STRING := "3750" = 2500+1250 = 270 + -- STRING := "3906" = 3750+ 156 = 281.25 + -- STRING := "4063" = 3750+ 313 = 292.5 + -- STRING := "4219" = 3750+ 469 = 303.75 + -- STRING := "4375" = 3750+ 625 = 315 + -- STRING := "4531" = 3750+ 781 = 326.25 + -- STRING := "4688" = 3750+ 938 = 337.5 + -- STRING := "4844" = 3750+1094 = 348.75 + -- STRING := "5000" = 3750+1250 = 360 + g_dp_clk_phase : STRING := "0"; -- phase offset for PLL c0, typically any phase is fine, do not use 225 +-30 degrees because there the PPS edge occurs + + ---------------------------------------------------------------------------- + -- 1GbE UDP offload + ---------------------------------------------------------------------------- + g_udp_offload : BOOLEAN := FALSE; + g_udp_offload_nof_streams : NATURAL := c_eth_nof_udp_ports; + + ---------------------------------------------------------------------------- + -- Auxiliary Interface + ---------------------------------------------------------------------------- + g_fpga_temp_high : NATURAL := 85; + g_app_led_red : BOOLEAN := FALSE; -- when TRUE use external LED control via app_led_red + g_app_led_green : BOOLEAN := FALSE; -- when TRUE use external LED control via app_led_green + + g_aux : t_c_unb2_board_aux := c_unb2_board_aux; + g_factory_image : BOOLEAN := FALSE; + g_protect_addr_range: BOOLEAN := FALSE; + g_protected_addr_lo : NATURAL := 0; -- Byte address + g_protected_addr_hi : NATURAL := 41943039 -- Byte address, for UniBoard1 this is 640 sectors*256 pages*256 bytes -1 = 41943039 + ); + PORT ( + -- + -- >>> SOPC system with conduit peripheral MM bus + -- + -- System + cs_sim : OUT STD_LOGIC; + + xo_ethclk : OUT STD_LOGIC; -- 125 MHz ETH_CLK + xo_rst : OUT STD_LOGIC; -- reset in ETH_CLK domain released after few cycles + xo_rst_n : OUT STD_LOGIC; + + ext_clk200 : OUT STD_LOGIC; -- 200 MHz CLK + ext_rst200 : OUT STD_LOGIC; -- reset in CLK clock domain released after mm_rst + + mm_clk : OUT STD_LOGIC; -- MM clock from xo_ethclk PLL + mm_rst : OUT STD_LOGIC; -- reset in MM clock domain released after xo_ethclk PLL locked + + dp_rst : OUT STD_LOGIC; -- reset in DP clock domain released after mm_rst and after CLK PLL locked in case g_dp_clk_use_pll=TRUE + dp_clk : OUT STD_LOGIC; -- 200 MHz DP clock from CLK system clock direct or via CLK PLL dependent on g_dp_clk_use_pll + dp_pps : OUT STD_LOGIC; -- PPS in dp_clk domain + dp_rst_in : IN STD_LOGIC; -- externally wire OUT dp_rst to dp_rst_in to avoid delta cycle difference on dp_clk + dp_clk_in : IN STD_LOGIC; -- externally wire OUT dp_clk to dp_clk_in to avoid delta cycle difference on dp_clk + + mb_I_ref_rst : OUT STD_LOGIC; -- reset in MB_I_REF_CLK domain released after mm_rst + mb_II_ref_rst : OUT STD_LOGIC; -- reset in MB_II_REF_CLK domain released after mm_rst + + this_chip_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_chip_w-1 DOWNTO 0); -- [1:0], so range 0-3 for PN + this_bck_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_uniboard_w-1 DOWNTO 0); -- [1:0] used out of ID[7:2] to index boards 3..0 in subrack + + app_led_red : IN STD_LOGIC := '0'; + app_led_green : IN STD_LOGIC := '1'; + + -- PIOs + pout_wdi : IN STD_LOGIC; -- Toggled by unb_osy; can be overriden by reg_wdi. + + -- Manual WDI override + reg_wdi_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_wdi_miso : OUT t_mem_miso; + + -- REMU + reg_remu_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_remu_miso : OUT t_mem_miso; + + -- EPCS read + reg_dpmm_data_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_dpmm_data_miso : OUT t_mem_miso; + reg_dpmm_ctrl_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_dpmm_ctrl_miso : OUT t_mem_miso; + + -- EPCS write + reg_mmdp_data_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_mmdp_data_miso : OUT t_mem_miso; + reg_mmdp_ctrl_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_mmdp_ctrl_miso : OUT t_mem_miso; + + -- EPCS status/control + reg_epcs_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_epcs_miso : OUT t_mem_miso; + + -- MM buses to/from mms_unb2_board_system_info + reg_unb_system_info_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_unb_system_info_miso : OUT t_mem_miso; + + rom_unb_system_info_mosi : IN t_mem_mosi := c_mem_mosi_rst; + rom_unb_system_info_miso : OUT t_mem_miso; + + -- UniBoard I2C sensors + reg_unb_sens_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_unb_sens_miso : OUT t_mem_miso; + + reg_unb_pmbus_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_unb_pmbus_miso : OUT t_mem_miso; + + -- FPGA sensors + reg_fpga_temp_sens_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_fpga_temp_sens_miso : OUT t_mem_miso; + reg_fpga_voltage_sens_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_fpga_voltage_sens_miso : OUT t_mem_miso; + + -- PPSH + reg_ppsh_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_ppsh_miso : OUT t_mem_miso; + + -- eth1g control&monitoring + eth1g_mm_rst : IN STD_LOGIC; + eth1g_tse_mosi : IN t_mem_mosi; -- ETH TSE MAC registers + eth1g_tse_miso : OUT t_mem_miso; + eth1g_reg_mosi : IN t_mem_mosi; -- ETH control and status registers + eth1g_reg_miso : OUT t_mem_miso; + eth1g_reg_interrupt : OUT STD_LOGIC; -- Interrupt + eth1g_ram_mosi : IN t_mem_mosi; -- ETH rx frame and tx frame memory + eth1g_ram_miso : OUT t_mem_miso; + + -- eth1g UDP streaming ports + udp_tx_sosi_arr : IN t_dp_sosi_arr(g_udp_offload_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + udp_tx_siso_arr : OUT t_dp_siso_arr(g_udp_offload_nof_streams-1 DOWNTO 0); + udp_rx_sosi_arr : OUT t_dp_sosi_arr(g_udp_offload_nof_streams-1 DOWNTO 0); + udp_rx_siso_arr : IN t_dp_siso_arr(g_udp_offload_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + + -- + -- >>> Ctrl FPGA pins + -- + -- GENERAL + CLK : IN STD_LOGIC; -- System Clock + PPS : IN STD_LOGIC; -- System Sync + WDI : OUT STD_LOGIC; -- Watchdog Clear + INTA : INOUT STD_LOGIC; -- FPGA interconnect line + INTB : INOUT STD_LOGIC; -- FPGA interconnect line + + -- Others + VERSION : IN STD_LOGIC_VECTOR(g_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(g_aux.id_w-1 DOWNTO 0); + TESTIO : INOUT STD_LOGIC_VECTOR(g_aux.testio_w-1 DOWNTO 0); + + -- I2C Interface to Sensors + SENS_SC : INOUT STD_LOGIC := 'Z'; + SENS_SD : INOUT STD_LOGIC := 'Z'; + + -- pmbus + PMBUS_SC : INOUT STD_LOGIC := 'Z'; + PMBUS_SD : INOUT STD_LOGIC := 'Z'; + PMBUS_ALERT : IN STD_LOGIC := '0'; + + -- DDR reference clock domains reset creation + MB_I_REF_CLK : IN STD_LOGIC := '0'; -- 25 MHz + MB_II_REF_CLK : IN STD_LOGIC := '0'; -- 25 MHz + + -- 1GbE Control Interface + ETH_CLK : IN STD_LOGIC; -- 125 MHz + ETH_SGIN : IN STD_LOGIC_VECTOR(c_unb2_board_nof_eth-1 DOWNTO 0) := (OTHERS=>'0'); + ETH_SGOUT : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_eth-1 DOWNTO 0) + ); +END ctrl_unb2_board; + + +ARCHITECTURE str OF ctrl_unb2_board IS + + CONSTANT c_rom_version : NATURAL := 1; -- Only increment when something changes to the register map of rom_system_info. + + CONSTANT c_reset_len : NATURAL := 4; -- >= c_meta_delay_len from common_pkg + CONSTANT c_mm_clk_freq : NATURAL := sel_a_b(g_sim=FALSE,g_mm_clk_freq,c_unb2_board_mm_clk_freq_10M); + + + -- Clock and reset + SIGNAL i_ext_clk200 : STD_LOGIC; + SIGNAL ext_pps : STD_LOGIC; + + SIGNAL common_areset_in_rst : STD_LOGIC; + + SIGNAL i_xo_ethclk : STD_LOGIC; + SIGNAL i_xo_rst : STD_LOGIC; + SIGNAL i_mm_rst : STD_LOGIC; + SIGNAL i_mm_clk : STD_LOGIC; + SIGNAL mm_locked : STD_LOGIC; + SIGNAL mm_sim_clk : STD_LOGIC := '1'; + SIGNAL epcs_clk : STD_LOGIC := '1'; + SIGNAL clk125 : STD_LOGIC := '1'; + SIGNAL clk100 : STD_LOGIC := '1'; + SIGNAL clk50 : STD_LOGIC := '1'; + + SIGNAL mm_wdi : STD_LOGIC; + SIGNAL eth1g_st_clk : STD_LOGIC; + SIGNAL eth1g_st_rst : STD_LOGIC; + + SIGNAL mm_pulse_ms : STD_LOGIC; + SIGNAL mm_pulse_s : STD_LOGIC; + SIGNAL mm_board_sens_start : STD_LOGIC; + + SIGNAL led_toggle : STD_LOGIC; + SIGNAL led_toggle_red : STD_LOGIC; + SIGNAL led_toggle_green : STD_LOGIC; + + -- eth1g + SIGNAL i_tse_clk : STD_LOGIC; + SIGNAL eth1g_led : t_tech_tse_led; + + -- Manual WDI override + SIGNAL wdi_override : STD_LOGIC; + + -- Temperature alarm (temp > g_fpga_temp_high) + SIGNAL temp_alarm : STD_LOGIC; + + -- UDP offload I/O + SIGNAL eth1g_udp_tx_sosi_arr : t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + SIGNAL eth1g_udp_tx_siso_arr : t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0); + SIGNAL eth1g_udp_rx_sosi_arr : t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0); + SIGNAL eth1g_udp_rx_siso_arr : t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + + attribute keep: boolean; + attribute keep of led_toggle_red: signal is true; + attribute keep of led_toggle_green: signal is true; + + attribute maxfan : integer; + attribute maxfan of dp_rst : signal is 1024; + +BEGIN + + ext_clk200 <= i_ext_clk200; + xo_ethclk <= i_xo_ethclk; + xo_rst <= i_xo_rst; + xo_rst_n <= NOT i_xo_rst; + mm_clk <= i_mm_clk; + mm_rst <= i_mm_rst; + + -- Default leave unused INOUT tri-state + INTA <= 'Z'; + INTB <= 'Z'; + + TESTIO <= (OTHERS=>'Z'); -- Leave unused INOUT tri-state + + ext_pps <= PPS; -- use more special name for PPS pin signal to ease searching for it in editor + + ----------------------------------------------------------------------------- + -- ext_clk200 = CLK + ----------------------------------------------------------------------------- + i_ext_clk200 <= CLK; -- use more special name for CLK pin signal to ease searching for it in editor, the external 200 MHz CLK as ext_clk200 + + u_common_areset_ext : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => '0', -- release reset after some clock cycles + clk => i_ext_clk200, + out_rst => ext_rst200 + ); + + ----------------------------------------------------------------------------- + -- xo_ethclk = ETH_CLK + ----------------------------------------------------------------------------- + + i_xo_ethclk <= ETH_CLK; -- use the ETH_CLK pin as xo_clk + + u_common_areset_xo : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => '0', -- release reset after some clock cycles + clk => i_xo_ethclk, + out_rst => i_xo_rst + ); + + + ----------------------------------------------------------------------------- + -- MB_I_REF_CLK --> mb_I_ref_rst + -- MB_II_REF_CLK --> mb_II_ref_rst + ----------------------------------------------------------------------------- + + u_common_areset_mb_I : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => i_mm_rst, -- release reset some clock cycles after i_mm_rst went low + clk => MB_I_REF_CLK, + out_rst => mb_I_ref_rst + ); + + u_common_areset_mb_II : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => i_mm_rst, -- release reset some clock cycles after i_mm_rst went low + clk => MB_II_REF_CLK, + out_rst => mb_II_ref_rst + ); + + ----------------------------------------------------------------------------- + -- dp_clk + dp_rst generation + -- . dp_clk = i_ext_clk200 in sim or on HW when PLL is not desired + -- . dp_rst always comes from common_areset + ----------------------------------------------------------------------------- + no_pll: IF g_sim=TRUE OR (g_sim=FALSE AND g_dp_clk_use_pll=FALSE) GENERATE + dp_clk <= i_ext_clk200; + common_areset_in_rst <= i_mm_rst; + END GENERATE; + + gen_pll: IF g_sim=FALSE AND g_dp_clk_use_pll=TRUE GENERATE + u_unb2_board_clk200_pll : ENTITY work.unb2_board_clk200_pll + GENERIC MAP ( + g_technology => g_technology, + g_use_fpll => TRUE, + g_clk200_phase_shift => g_dp_clk_phase + ) + PORT MAP ( + arst => i_mm_rst, + clk200 => i_ext_clk200, + st_clk200 => dp_clk, -- = c0 + st_rst200 => common_areset_in_rst + ); + END GENERATE; + + u_common_areset_dp_rst : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => common_areset_in_rst, -- release reset some clock cycles after i_mm_rst went low + clk => dp_clk_in, + out_rst => dp_rst + ); + + ----------------------------------------------------------------------------- + -- mm_clk + -- . use mm_sim_clk in sim + -- . derived from ETH_CLK via PLL on hardware + ----------------------------------------------------------------------------- + + i_mm_clk <= mm_sim_clk WHEN g_sim = TRUE ELSE + clk125 WHEN g_mm_clk_freq = c_unb2_board_mm_clk_freq_125M ELSE + clk100 WHEN g_mm_clk_freq = c_unb2_board_mm_clk_freq_100M ELSE + clk50 WHEN g_mm_clk_freq = c_unb2_board_mm_clk_freq_50M ELSE + clk50; -- default + + gen_mm_clk_sim: IF g_sim = TRUE GENERATE + epcs_clk <= NOT epcs_clk AFTER 25 ns; -- 20 MHz, 50ns/2 + clk50 <= NOT clk50 AFTER 10 ns; -- 50 MHz, 20ns/2 + clk100 <= NOT clk100 AFTER 5 ns; -- 100 MHz, 10ns/2 + clk125 <= NOT clk125 AFTER 4 ns; -- 125 MHz, 8ns/2 + mm_sim_clk <= NOT mm_sim_clk AFTER 50 ns; -- 10 MHz, 100ns/2 --> FIXME: this mm_sim_clk should come from the MMM so that its speed can be adapted + mm_locked <= '0', '1' AFTER 70 ns; + END GENERATE; + + gen_mm_clk_hardware: IF g_sim = FALSE GENERATE + u_unb2_board_clk125_pll : ENTITY work.unb2_board_clk125_pll + GENERIC MAP ( + g_use_fpll => TRUE, + g_technology => g_technology + ) + PORT MAP ( + arst => i_xo_rst, + clk125 => i_xo_ethclk, + c0_clk20 => epcs_clk, + c1_clk50 => clk50, + c2_clk100 => clk100, + c3_clk125 => clk125, + pll_locked => mm_locked + ); + END GENERATE; + + u_unb2_board_node_ctrl : ENTITY work.unb2_board_node_ctrl + GENERIC MAP ( + g_pulse_us => c_mm_clk_freq / (10**6) -- nof system clock cycles to get us period, equal to system clock frequency / 10**6 + ) + PORT MAP ( + -- MM clock domain reset + mm_clk => i_mm_clk, + mm_locked => mm_locked, + mm_rst => i_mm_rst, + -- WDI extend + mm_wdi_in => pout_wdi, + mm_wdi_out => mm_wdi, -- actively toggle the WDI via pout_wdi from software with toggle extend to allow software reload + -- Pulses + mm_pulse_us => OPEN, + mm_pulse_ms => mm_pulse_ms, + mm_pulse_s => mm_pulse_s -- could be used to toggle a LED + ); + + ----------------------------------------------------------------------------- + -- System info + ----------------------------------------------------------------------------- + cs_sim <= is_true(g_sim); + + u_mms_unb2_board_system_info : ENTITY work.mms_unb2_board_system_info + GENERIC MAP ( + g_sim => g_sim, + g_technology => g_technology, + g_design_name => g_design_name, + g_fw_version => g_fw_version, + g_stamp_date => g_stamp_date, + g_stamp_time => g_stamp_time, + g_stamp_svn => g_stamp_svn, + g_design_note => g_design_note, + g_rom_version => c_rom_version + ) + PORT MAP ( + mm_clk => i_mm_clk, + mm_rst => i_mm_rst, + + hw_version => VERSION, + id => ID, + + reg_mosi => reg_unb_system_info_mosi, + reg_miso => reg_unb_system_info_miso, + + rom_mosi => rom_unb_system_info_mosi, + rom_miso => rom_unb_system_info_miso, + + chip_id => this_chip_id, + bck_id => this_bck_id + ); + + + ----------------------------------------------------------------------------- + -- Red LED control + ----------------------------------------------------------------------------- + + gen_app_led_red: IF g_app_led_red = TRUE GENERATE + -- Let external app control the LED via the app_led_red input + TESTIO(c_unb2_board_testio_led_red) <= app_led_red; + END GENERATE; + + no_app_led_red: IF g_app_led_red = FALSE GENERATE + TESTIO(c_unb2_board_testio_led_red) <= led_toggle_red; + END GENERATE; + + + ----------------------------------------------------------------------------- + -- Green LED control + ----------------------------------------------------------------------------- + + gen_app_led_green: IF g_app_led_green = TRUE GENERATE + -- Let external app control the LED via the app_led_green input + TESTIO(c_unb2_board_testio_led_green) <= app_led_green; + END GENERATE; + + no_app_led_green: IF g_app_led_green = FALSE GENERATE + TESTIO(c_unb2_board_testio_led_green) <= led_toggle_green; + END GENERATE; + + + ------------------------------------------------------------------------------ + -- Toggle red LED when unb2_minimal is running, green LED for other designs. + ------------------------------------------------------------------------------ + led_toggle_red <= sel_a_b(g_factory_image=TRUE, led_toggle, '0'); + led_toggle_green <= sel_a_b(g_factory_image=FALSE, led_toggle, '0'); + + u_toggle : ENTITY common_lib.common_toggle + PORT MAP ( + rst => i_mm_rst, + clk => i_mm_clk, + in_dat => mm_pulse_s, + out_dat => led_toggle + ); + + + ------------------------------------------------------------------------------ + -- WDI override + ------------------------------------------------------------------------------ + -- Actively reset watchdog from software when used, else disable watchdog by leaving the WDI at tri-state level. + -- A high temp_alarm will keep WDI asserted, causing the watch dog to reset the FPGA. + -- A third option is to override the WDI manually using the output of a dedicated reg_wdi. + WDI <= mm_wdi OR temp_alarm OR wdi_override; + + u_unb2_board_wdi_reg : ENTITY work.unb2_board_wdi_reg + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + + sla_in => reg_wdi_mosi, + sla_out => reg_wdi_miso, + + wdi_override => wdi_override + ); + + + ------------------------------------------------------------------------------ + -- Remote upgrade + ------------------------------------------------------------------------------ + -- Every design instantiates an mms_remu instance + MM status & control ports. + -- So there is full control over the memory mapped registers to set start address of the flash + -- and reconfigure from that address. + u_mms_remu: ENTITY remu_lib.mms_remu + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + + epcs_clk => epcs_clk, + + remu_mosi => reg_remu_mosi, + remu_miso => reg_remu_miso + ); + + ------------------------------------------------------------------------------- + ---- EPCS + ------------------------------------------------------------------------------- + u_mms_epcs: ENTITY epcs_lib.mms_epcs + GENERIC MAP ( + g_technology => g_technology, + g_protect_addr_range => g_protect_addr_range, + g_protected_addr_lo => g_protected_addr_lo, + g_protected_addr_hi => g_protected_addr_hi + ) + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + + epcs_clk => epcs_clk, + + epcs_mosi => reg_epcs_mosi, + epcs_miso => reg_epcs_miso, + + dpmm_ctrl_mosi => reg_dpmm_ctrl_mosi, + dpmm_ctrl_miso => reg_dpmm_ctrl_miso, + + dpmm_data_mosi => reg_dpmm_data_mosi, + dpmm_data_miso => reg_dpmm_data_miso, + + mmdp_ctrl_mosi => reg_mmdp_ctrl_mosi, + mmdp_ctrl_miso => reg_mmdp_ctrl_miso, + + mmdp_data_mosi => reg_mmdp_data_mosi, + mmdp_data_miso => reg_mmdp_data_miso + ); + + ------------------------------------------------------------------------------ + -- PPS input + ------------------------------------------------------------------------------ + + u_mms_ppsh : ENTITY ppsh_lib.mms_ppsh + GENERIC MAP ( + g_technology => g_technology, + g_st_clk_freq => g_dp_clk_freq + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + st_rst => dp_rst_in, + st_clk => dp_clk_in, + pps_ext => ext_pps, -- with unknown but constant phase to st_clk + + -- Memory-mapped clock domain + reg_mosi => reg_ppsh_mosi, + reg_miso => reg_ppsh_miso, + + -- Streaming clock domain + pps_sys => dp_pps + ); + + + ------------------------------------------------------------------------------ + -- I2C control for UniBoard sensors + ------------------------------------------------------------------------------ + + mm_board_sens_start <= mm_pulse_s WHEN g_sim=FALSE ELSE mm_pulse_s; --mm_pulse_ms; ms pulse comes before the end of the I2C frame, this results in an overflow in simulation -- speed up in simulation + + u_mms_unb2_board_sens : ENTITY work.mms_unb2_board_sens + GENERIC MAP ( + g_sim => g_sim, + g_i2c_peripheral => c_i2c_peripheral_sens, + g_sens_nof_result => 40, + g_clk_freq => g_mm_clk_freq, + g_comma_w => 13 + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + mm_start => mm_board_sens_start, + + -- Memory-mapped clock domain + reg_mosi => reg_unb_sens_mosi, + reg_miso => reg_unb_sens_miso, + + -- i2c bus + scl => SENS_SC, + sda => SENS_SD + ); + + u_mms_unb2_board_pmbus : ENTITY work.mms_unb2_board_sens + GENERIC MAP ( + g_sim => g_sim, + g_i2c_peripheral => c_i2c_peripheral_pmbus, + g_sens_nof_result => 42, + g_clk_freq => g_mm_clk_freq, + g_comma_w => 13 + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + mm_start => mm_board_sens_start, + + -- Memory-mapped clock domain + reg_mosi => reg_unb_pmbus_mosi, + reg_miso => reg_unb_pmbus_miso, + + -- i2c bus + scl => PMBUS_SC, + sda => PMBUS_SD + ); + + u_mms_unb2_fpga_sens : ENTITY work.mms_unb2_fpga_sens + GENERIC MAP ( + g_sim => g_sim, + g_technology => g_technology, + g_temp_high => g_fpga_temp_high + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => i_mm_clk, + + --mm_start => mm_board_sens_start, -- this does not work, perhaps pulsewidth is too small + mm_start => '1', -- this works + + -- Memory-mapped clock domain + reg_temp_mosi => reg_fpga_temp_sens_mosi, + reg_temp_miso => reg_fpga_temp_sens_miso, + reg_voltage_mosi => reg_fpga_voltage_sens_mosi, + reg_voltage_miso => reg_fpga_voltage_sens_miso, + + -- Temperature alarm + temp_alarm => temp_alarm + ); + + + ------------------------------------------------------------------------------ + -- Ethernet 1GbE + ------------------------------------------------------------------------------ + + gen_tse_clk_buf: IF g_tse_clk_buf=TRUE GENERATE + -- Separate clkbuf for the 1GbE tse_clk: + u_tse_clk_buf : ENTITY tech_clkbuf_lib.tech_clkbuf + GENERIC MAP ( + g_technology => g_technology, + g_clock_net => "GLOBAL" + ) + PORT MAP ( + inclk => i_xo_ethclk, + outclk => i_tse_clk + ); + END GENERATE; + + gen_tse_no_clk_buf: IF g_tse_clk_buf=FALSE GENERATE + i_tse_clk <= i_xo_ethclk; + END GENERATE; + + + wire_udp_offload: FOR i IN 0 TO g_udp_offload_nof_streams-1 GENERATE + eth1g_udp_tx_sosi_arr(i) <= udp_tx_sosi_arr(i); + udp_tx_siso_arr(i) <= eth1g_udp_tx_siso_arr(i); + + udp_rx_sosi_arr(i) <= eth1g_udp_rx_sosi_arr(i); + eth1g_udp_rx_siso_arr(i) <= udp_rx_siso_arr(i); + END GENERATE; + + -- In simulation use file IO for MM control. In simulation only use 1GbE for streaming DP data offload (or on load) via 1GbE. + no_eth1g : IF g_sim=TRUE AND g_udp_offload=FALSE GENERATE + eth1g_reg_interrupt <= '0'; + eth1g_tse_miso <= c_mem_miso_rst; + eth1g_reg_miso <= c_mem_miso_rst; + eth1g_ram_miso <= c_mem_miso_rst; + END GENERATE; + + --On hardware always generate 1GbE for MM control. In simulation only use 1GbE for streaming DP data offload (or on load) via 1GbE. + gen_eth: IF g_sim=FALSE OR g_udp_offload=TRUE GENERATE + + eth1g_st_clk <= dp_clk_in WHEN g_udp_offload=TRUE ELSE i_mm_clk; + eth1g_st_rst <= dp_rst_in WHEN g_udp_offload=TRUE ELSE eth1g_mm_rst; + + u_eth : ENTITY eth_lib.eth + GENERIC MAP ( + g_technology => g_technology, + g_init_ip_address => g_base_ip & X"0000", -- Last two bytes set by board/FPGA ID. + g_cross_clock_domain => g_udp_offload, + g_frm_discard_en => TRUE + ) + PORT MAP ( + -- Clocks and reset + mm_rst => eth1g_mm_rst, -- use reset from QSYS + mm_clk => i_mm_clk, -- use mm_clk direct + eth_clk => i_tse_clk, -- 125 MHz clock + st_rst => eth1g_st_rst, + st_clk => eth1g_st_clk, + + -- UDP transmit interface + udp_tx_snk_in_arr => eth1g_udp_tx_sosi_arr, + udp_tx_snk_out_arr => eth1g_udp_tx_siso_arr, + -- UDP receive interface + udp_rx_src_in_arr => eth1g_udp_rx_siso_arr, + udp_rx_src_out_arr => eth1g_udp_rx_sosi_arr, + + -- Memory Mapped Slaves + tse_sla_in => eth1g_tse_mosi, + tse_sla_out => eth1g_tse_miso, + reg_sla_in => eth1g_reg_mosi, + reg_sla_out => eth1g_reg_miso, + reg_sla_interrupt => eth1g_reg_interrupt, + ram_sla_in => eth1g_ram_mosi, + ram_sla_out => eth1g_ram_miso, + + -- PHY interface + eth_txp => ETH_SGOUT(0), + eth_rxp => ETH_SGIN(0), + + -- LED interface + tse_led => eth1g_led + ); + END GENERATE; + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_sens.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..99c8a77fc9f765c6aa1fe3c80cf8b2c7951337a6 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_sens.vhd @@ -0,0 +1,122 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose : MMS for unb2_board_sens +-- Description: See unb2_board_sens.vhd + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + + +ENTITY mms_unb2_board_sens IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_i2c_peripheral : NATURAL; + g_sens_nof_result : NATURAL; -- Should match nof read bytes via I2C in the unb2_board_sens_ctrl SEQUENCE list + g_clk_freq : NATURAL := 100*10**6; -- clk frequency in Hz + g_temp_high : NATURAL := 85; + g_comma_w : NATURAL := 0 + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + mm_start : IN STD_LOGIC; + + -- Memory-mapped clock domain + reg_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- actual ranges defined by c_mm_reg + reg_miso : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- i2c bus + scl : INOUT STD_LOGIC := 'Z'; + sda : INOUT STD_LOGIC := 'Z'; + + -- Temperature alarm output + temp_alarm : OUT STD_LOGIC + ); +END mms_unb2_board_sens; + + +ARCHITECTURE str OF mms_unb2_board_sens IS + + CONSTANT c_temp_high_w : NATURAL := 7; -- Allow user to use only 7 (no sign, only positive) of 8 bits to set set max temp + + SIGNAL sens_err : STD_LOGIC; + SIGNAL sens_data : t_slv_8_arr(0 TO g_sens_nof_result-1); + + SIGNAL temp_high : STD_LOGIC_VECTOR(c_temp_high_w-1 DOWNTO 0); + +BEGIN + + u_unb2_board_sens_reg : ENTITY work.unb2_board_sens_reg + GENERIC MAP ( + g_sens_nof_result => g_sens_nof_result, + g_temp_high => g_temp_high + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + + -- Memory Mapped Slave in mm_clk domain + sla_in => reg_mosi, + sla_out => reg_miso, + + -- MM registers + sens_err => sens_err, -- using same protocol list for both node2 and all nodes implies that sens_err is only valid for node2. + sens_data => sens_data, + + -- Max temp threshold + temp_high => temp_high + ); + + u_unb2_board_sens : ENTITY work.unb2_board_sens + GENERIC MAP ( + g_sim => g_sim, + g_i2c_peripheral => g_i2c_peripheral, + g_clk_freq => g_clk_freq, + g_temp_high => g_temp_high, + g_sens_nof_result => g_sens_nof_result, + g_comma_w => g_comma_w + ) + PORT MAP ( + clk => mm_clk, + rst => mm_rst, + start => mm_start, + -- i2c bus + scl => scl, + sda => sda, + -- read results + sens_evt => OPEN, + sens_err => sens_err, + sens_data => sens_data + ); + + -- Temperature: 7 bits (1 bit per degree) plus sign. A faulty readout (never pulled down = all ones) + -- would produce -1 degrees so does not trigger a temperature alarm. + -- temp_high is 7 bits, preceded by a '0' to allow only positive temps to be set. + temp_alarm <= '1' WHEN (SIGNED(sens_data(0)) > SIGNED('0' & temp_high)) ELSE '0'; + +END str; + diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_system_info.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_system_info.vhd new file mode 100644 index 0000000000000000000000000000000000000000..69c9f0c602854dfa773e96fc6f03a3e1b83d7a2f --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_board_system_info.vhd @@ -0,0 +1,141 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, technology_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.unb2_board_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + +ENTITY mms_unb2_board_system_info IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_technology : NATURAL := c_tech_arria10; + g_design_name : STRING; + g_fw_version : t_unb2_board_fw_version := c_unb2_board_fw_version; -- firmware version x.y + g_stamp_date : NATURAL := 0; + g_stamp_time : NATURAL := 0; + g_stamp_svn : NATURAL := 0; + g_design_note : STRING := ""; + g_rom_version : NATURAL := 1; + g_aux : t_c_unb2_board_aux := c_unb2_board_aux -- aux contains the hardware version + ); + PORT ( + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + + -- MM registers + reg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_miso : OUT t_mem_miso; + + rom_mosi : IN t_mem_mosi := c_mem_mosi_rst; + rom_miso : OUT t_mem_miso; + + hw_version : IN STD_LOGIC_VECTOR(g_aux.version_w-1 DOWNTO 0); + id : IN STD_LOGIC_VECTOR(g_aux.id_w-1 DOWNTO 0); + + chip_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_chip_w-1 DOWNTO 0); + bck_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_uniboard_w-1 DOWNTO 0); + + -- Info output still supported for older designs + info : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) + ); +END mms_unb2_board_system_info; + + +ARCHITECTURE str OF mms_unb2_board_system_info IS + + -- Provide different prefixes (absolute and relative) for the same path. ModelSim understands $UNB, Quartus does not. + -- Required because the work paths of ModelSim and Quartus are different. + CONSTANT c_quartus_path_prefix : STRING := ""; + CONSTANT c_modelsim_path_prefix : STRING := "$UNB/Firmware/designs/" & g_design_name & "/build/synth/quartus/"; + CONSTANT c_path_prefix : STRING := sel_a_b(g_sim, c_modelsim_path_prefix, c_quartus_path_prefix); + +-- No longer supporting MIF files in sim as non-$UNB (e.g. $AARTFAAC) designs will cause path error. +-- CONSTANT c_mif_name : STRING := sel_a_b((g_design_name="UNUSED"), g_design_name, c_path_prefix & g_design_name & ".mif"); + CONSTANT c_mif_name : STRING := sel_a_b(g_sim, "UNUSED", sel_a_b((g_design_name="UNUSED"), g_design_name, c_path_prefix & g_design_name & ".mif")); + + CONSTANT c_rom_addr_w : NATURAL := 10; -- 2^10 = 1024 addresses * 32 bits = 4 kiB + + CONSTANT c_mm_rom : t_c_mem := (latency => 1, + adr_w => c_rom_addr_w, + dat_w => c_word_w, + nof_dat => 2**c_rom_addr_w, -- = 2**adr_w + init_sl => '0'); + + SIGNAL i_info : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + +BEGIN + + info <= i_info; + + u_unb2_board_system_info: ENTITY work.unb2_board_system_info + GENERIC MAP ( + g_sim => g_sim, + g_fw_version => g_fw_version, + g_rom_version => g_rom_version, + g_technology => g_technology + ) + PORT MAP ( + clk => mm_clk, + hw_version => hw_version, + id => id, + info => i_info, + chip_id => chip_id, + bck_id => bck_id + ); + + u_unb2_board_system_info_reg: ENTITY work.unb2_board_system_info_reg + GENERIC MAP ( + g_design_name => g_design_name, + g_stamp_date => g_stamp_date, + g_stamp_time => g_stamp_time, + g_stamp_svn => g_stamp_svn, + g_design_note => g_design_note + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + + sla_in => reg_mosi, + sla_out => reg_miso, + + info => i_info + ); + + u_common_rom : ENTITY common_lib.common_rom + GENERIC MAP ( + g_technology => g_technology, + g_ram => c_mm_rom, + g_init_file => c_mif_name + ) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + rd_en => rom_mosi.rd, + rd_adr => rom_mosi.address(c_mm_rom.adr_w-1 DOWNTO 0), + rd_dat => rom_miso.rddata(c_mm_rom.dat_w-1 DOWNTO 0), + rd_val => rom_miso.rdval + ); + +END str; + diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_fpga_sens.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_fpga_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..96ae8dc74dd007749a9ceafa6f9b081e45e2085e --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/mms_unb2_fpga_sens.vhd @@ -0,0 +1,122 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose : MMS for unb2_fpga_sens +-- Description: See unb2_fpga_sens.vhd + +LIBRARY IEEE, technology_lib, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + + +ENTITY mms_unb2_fpga_sens IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_technology : NATURAL := c_tech_arria10; + g_temp_high : NATURAL := 85 + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + mm_start : IN STD_LOGIC; + + -- Memory-mapped clock domain + reg_temp_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- actual ranges defined by c_mm_reg + reg_temp_miso : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + reg_voltage_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- actual ranges defined by c_mm_reg + reg_voltage_miso : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- Temperature alarm output + temp_alarm : OUT STD_LOGIC + ); +END mms_unb2_fpga_sens; + + +ARCHITECTURE str OF mms_unb2_fpga_sens IS + + CONSTANT c_sens_nof_result : NATURAL := 1; -- + CONSTANT c_temp_high_w : NATURAL := 7; -- Allow user to use only 7 (no sign, only positive) of 8 bits to set set max temp + + SIGNAL sens_err : STD_LOGIC; + SIGNAL sens_data : t_slv_8_arr(0 TO c_sens_nof_result-1); + + SIGNAL temp_high : STD_LOGIC_VECTOR(c_temp_high_w-1 DOWNTO 0); + +BEGIN + + u_unb2_fpga_sens_reg : ENTITY work.unb2_fpga_sens_reg + GENERIC MAP ( + g_sim => g_sim, + g_technology => g_technology, + g_sens_nof_result => c_sens_nof_result, + g_temp_high => g_temp_high + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + start => mm_start, + + -- Memory Mapped Slave in mm_clk domain + sla_temp_in => reg_temp_mosi, + sla_temp_out => reg_temp_miso, + sla_voltage_in => reg_voltage_mosi, + sla_voltage_out => reg_voltage_miso, + + -- MM registers + --sens_err => sens_err, -- using same protocol list for both node2 and all nodes implies that sens_err is only valid for node2. + --sens_data => sens_data, + + -- Max temp threshold + temp_high => temp_high + ); + +-- u_unb2_board_sens : ENTITY work.unb2_board_sens +-- GENERIC MAP ( +-- g_sim => g_sim, +-- g_clk_freq => g_clk_freq, +-- g_temp_high => g_temp_high, +-- g_sens_nof_result => c_sens_nof_result +-- ) +-- PORT MAP ( +-- clk => mm_clk, +-- rst => mm_rst, +-- start => mm_start, +-- -- i2c bus +-- scl => scl, +-- sda => sda, +-- -- read results +-- sens_evt => OPEN, +-- sens_err => sens_err, +-- sens_data => sens_data +-- ); + + -- Temperature: 7 bits (1 bit per degree) plus sign. A faulty readout (never pulled down = all ones) + -- would produce -1 degrees so does not trigger a temperature alarm. + -- temp_high is 7 bits, preceded by a '0' to allow only positive temps to be set. + temp_alarm <= '0';--<= '1' WHEN (SIGNED(sens_data(0)) > SIGNED('0' & temp_high)) ELSE '0'; + +END str; + diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_back_io.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_back_io.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8142ed4527a9840b4b19c806788f9fb1da0b1737 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_back_io.vhd @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------ +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE work.unb2_board_pkg.ALL; + + +ENTITY unb2_board_back_io IS + GENERIC ( + g_nof_back_bus : NATURAL := c_unb2_board_tr_back.nof_bus + ); + PORT ( + serial_tx_arr : IN STD_LOGIC_VECTOR(g_nof_back_bus * c_unb2_board_tr_back.bus_w-1 DOWNTO 0) := (OTHERS=>'0'); + serial_rx_arr : OUT STD_LOGIC_VECTOR(g_nof_back_bus * c_unb2_board_tr_back.bus_w-1 DOWNTO 0); + + -- back transceivers + BCK_RX : IN t_unb2_board_back_bus_2arr(g_nof_back_bus-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + BCK_TX : OUT t_unb2_board_back_bus_2arr(g_nof_back_bus-1 DOWNTO 0); + + BCK_SDA : INOUT STD_LOGIC_VECTOR(c_unb2_board_tr_back.i2c_w-1 DOWNTO 0); + BCK_SCL : INOUT STD_LOGIC_VECTOR(c_unb2_board_tr_back.i2c_w-1 DOWNTO 0); + BCK_ERR : INOUT STD_LOGIC_VECTOR(c_unb2_board_tr_back.i2c_w-1 DOWNTO 0) + ); +END unb2_board_back_io; + +ARCHITECTURE str OF unb2_board_back_io IS + + -- help signals so we can iterate through buses + SIGNAL si_tx_2arr : t_unb2_board_back_bus_2arr(g_nof_back_bus-1 DOWNTO 0); + SIGNAL si_rx_2arr : t_unb2_board_back_bus_2arr(g_nof_back_bus-1 DOWNTO 0); + +BEGIN + + gen_buses : FOR i IN 0 TO g_nof_back_bus-1 GENERATE + BCK_TX(i) <= si_tx_2arr(i); + si_rx_2arr(i) <= BCK_RX(i); + END GENERATE; + + + gen_wire_bus : FOR i IN 0 TO g_nof_back_bus-1 GENERATE + gen_wire_signals : FOR j IN 0 TO c_unb2_board_tr_back.bus_w-1 GENERATE + + si_tx_2arr(i)(j) <= serial_tx_arr(i*c_unb2_board_tr_back.bus_w + j); + serial_rx_arr(i*c_unb2_board_tr_back.bus_w + j) <= si_rx_2arr(i)(j); + + END GENERATE; + END GENERATE; + +END; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk125_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk125_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..858cc68b92013637641691b30cdb7eb3bf206202 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk125_pll.vhd @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, technology_lib, tech_clkbuf_lib, tech_pll_lib, tech_fractional_pll_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + +-- Purpose: PLL for UniBoard node CLK input @ 125 MHz +-- Description: +-- c0 = 20 MHz +-- c1 = 50 MHz +-- c2 = 100 MHz +-- c3 = 125 MHz +-- + +ENTITY unb2_board_clk125_pll IS + GENERIC ( + g_technology : NATURAL := c_tech_arria10; + g_use_clkbuf : BOOLEAN := TRUE; + g_use_fpll : BOOLEAN := FALSE + ); + PORT ( + arst : IN STD_LOGIC := '0'; + clk125 : IN STD_LOGIC := '0'; -- connect to UniBoard ETH_clk pin (125 MHz) + + c0_clk20 : OUT STD_LOGIC; -- PLL c0 + c1_clk50 : OUT STD_LOGIC; -- PLL c1 + c2_clk100 : OUT STD_LOGIC; -- PLL c2 + c3_clk125 : OUT STD_LOGIC; -- PLL c3 + pll_locked : OUT STD_LOGIC + ); +END unb2_board_clk125_pll; + + +ARCHITECTURE arria10 OF unb2_board_clk125_pll IS + + SIGNAL clk125buf : STD_LOGIC; + +BEGIN + + no_clkbuf : IF g_use_clkbuf=FALSE GENERATE + clk125buf <= clk125; + END GENERATE; + + gen_clkbuf : IF g_use_clkbuf=TRUE GENERATE + u_clkbuf : ENTITY tech_clkbuf_lib.tech_clkbuf + GENERIC MAP ( + g_technology => g_technology, + g_clock_net => "GLOBAL" + ) + PORT MAP ( + inclk => clk125, + outclk => clk125buf + ); + END GENERATE; + + + gen_pll : IF g_use_fpll=FALSE GENERATE + u_pll : ENTITY tech_pll_lib.tech_pll_clk125 + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + areset => arst, + inclk0 => clk125buf, + c0 => c0_clk20, + c1 => c1_clk50, + c2 => c2_clk100, + c3 => c3_clk125, + locked => pll_locked + ); + END GENERATE; + + gen_fractional_pll : IF g_use_fpll=TRUE GENERATE + u_pll : ENTITY tech_fractional_pll_lib.tech_fractional_pll_clk125 + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + areset => arst, + inclk0 => clk125buf, + c0 => c0_clk20, + c1 => c1_clk50, + c2 => c2_clk100, + c3 => c3_clk125, + locked => pll_locked + ); + END GENERATE; + +END arria10; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk200_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk200_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..63e575d26d41b00f75fa42ee937f963b5cf02aac --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk200_pll.vhd @@ -0,0 +1,222 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, technology_lib, tech_clkbuf_lib, tech_pll_lib, tech_fractional_pll_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + +-- Purpose: PLL for UniBoard node CLK input @ 200 MHz +-- Description: +-- . The PLL runs in normal mode using c0 to compensate for the internal clock +-- network delay, so that c0 = st_clk200 is aligned to the input clk200. +-- . The assumption is that default the streaming DSP will run on the 200 MHz +-- clock from the CLK input via c1 = st_clk200p. +-- . The PLL normal mode operation compensates for internal clock network +-- delays of c0. This compensations aligns c0 to inclk0. With +-- tb_unb2_board_clk200_pll.vhd it appears that the phase setting for c0 does +-- not influence the compensation. Therefore it is llso possible to use +-- g_clk200_phase_shift /= 0 and touse c0 as processing clock instead of c1. +-- . The phase offset of c0 and c1 in the clk200_pll MegaWizard component +-- can be set in steps of 11.25 degrees (and even finer): +-- g_clk200_phase_shift (for c0) +-- phase [degrees] g_clk200p_phase_shift (for c1) +-- 0 "0" +-- 11.25 "156" +-- 22.5 "313" +-- 33.75 "469" +-- 45 "625" +-- 56.25 "781" +-- 67.5 "938" +-- 78.75 "1094" +-- 90 "1250" +-- 101.25 "1406" = 1250+ 156 +-- 112.5 "1563" = 1250+ 313 +-- 123.75 "1719" = 1250+ 469 +-- 135 "1875" = 1250+ 625 +-- 146.25 "2031" = 1250+ 781 +-- 157.5 "2188" = 1250+ 938 +-- 168.75 "2344" = 1250+1094 +-- 180 "2500" = 1250+1250 +-- 191.25 "2656" = 2500+ 156 +-- 202.5 "2813" = 2500+ 313 +-- 213.75 "2969" = 2500+ 469 +-- 225 "3125" = 2500+ 625 +-- 236.25 "3281" = 2500+ 781 +-- 247.5 "3438" = 2500+ 938 +-- 258.75 "3594" = 2500+1094 +-- 270 "3750" = 2500+1250 +-- 281.25 "3906" = 3750+ 156 +-- 292.5 "4063" = 3750+ 313 +-- 303.75 "4219" = 3750+ 469 +-- 315 "4375" = 3750+ 625 +-- 326.25 "4531" = 3750+ 781 +-- 337.5 "4688" = 3750+ 938 +-- 348.75 "4844" = 3750+1094 +-- 360 "5000" = 3750+1250 +-- . With a phase offset of 22.5 degrees the c1 = clk200p is offset by a 1/16 +-- period of 200 MHz, so 1/8 period of the 400 MHz DCLK from ADU and 1/4 +-- period of the 800 MHz sample SCLK of ADU. This phase offset can be used +-- to achieve stable timing between the DCLK and the clk200p domain. +-- . Some DSP may also be possible at 400 MHz via st_clk400. Note that this +-- 400 MHz can also be used at places where only a little more than 200 MHz +-- would be needed, e.g. to create packets at full data rate. +-- Therefore it is not necessary to create yet another st clock frequency. +-- This to also avoid the EMI or RFI that a non integer factor of 200 MHz +-- like e.g. 250 MHz would cause. +-- . At 400 MHz ADC samples can be clocked in at 800 MSps using DDIO. At 800 +-- MSps the sample period is 1250 ns. Input timing can be tuned via fixed +-- pad input delays and/or by using another phase of the PLL output clock. +-- Remarks: +-- . If necessary more 400 M clock phase could be made available, via g_sel. +-- + +ENTITY unb2_board_clk200_pll IS + GENERIC ( + g_technology : NATURAL := c_tech_arria10; + g_use_clkbuf : BOOLEAN := TRUE; + g_use_fpll : BOOLEAN := FALSE; + g_operation_mode : STRING := "NORMAL"; -- "NORMAL", "NO_COMPENSATION", or "SOURCE_SYNCHRONOUS" --> requires PLL_COMPENSATE assignment to an input pin to compensate for (stratixiv) + g_clk200_phase_shift : STRING := "0"; -- default use 0 degrees, see clk200_pll.vhd for other phase values + g_clk200p_phase_shift : STRING := "0" -- default use 0 degrees, see clk200_pll.vhd for other phase values + ); + PORT ( + -- It depends on g_sel which outputs are actually available + -- . common + arst : IN STD_LOGIC := '0'; + clk200 : IN STD_LOGIC := '0'; -- connect to UniBoard CLK pin + st_clk200 : OUT STD_LOGIC; -- PLL c0 = g_clk200_phase_shift degrees phase offset to input clk200 + st_rst200 : OUT STD_LOGIC; + st_clk200p : OUT STD_LOGIC; -- PLL c1 = g_clk200p_phase_shift degrees phase offset to input clk200 (see clk200_pll.vhd from MegaWizard) + st_rst200p : OUT STD_LOGIC; + st_clk400 : OUT STD_LOGIC; -- PLL c2 = 0 degrees phase offset to input clk200 + st_rst400 : OUT STD_LOGIC + ); +END unb2_board_clk200_pll; + + +ARCHITECTURE arria10 OF unb2_board_clk200_pll IS + + CONSTANT c_reset_len : NATURAL := c_meta_delay_len; + + SIGNAL clk200buf : STD_LOGIC; + SIGNAL i_st_rst200 : STD_LOGIC; + SIGNAL i_st_clk200 : STD_LOGIC; + SIGNAL i_st_clk200p : STD_LOGIC; + SIGNAL i_st_clk400 : STD_LOGIC; + + SIGNAL st_locked : STD_LOGIC; + SIGNAL st_locked_n : STD_LOGIC; + +BEGIN + + st_rst200 <= i_st_rst200; + st_clk200 <= i_st_clk200; + st_clk200p <= i_st_clk200p; + st_clk400 <= i_st_clk400; + + no_clkbuf : IF g_use_clkbuf=FALSE GENERATE + clk200buf <= clk200; + END GENERATE; + + gen_clkbuf : IF g_use_clkbuf=TRUE GENERATE + u_clkbuf : ENTITY tech_clkbuf_lib.tech_clkbuf + GENERIC MAP ( + g_technology => g_technology, + g_clock_net => "GLOBAL" + ) + PORT MAP ( + inclk => clk200, + outclk => clk200buf + ); + END GENERATE; + + gen_st_pll : IF g_use_fpll=FALSE GENERATE + u_st_pll : ENTITY tech_pll_lib.tech_pll_clk200 + GENERIC MAP ( + g_technology => g_technology, + g_operation_mode => g_operation_mode, + g_clk0_phase_shift => g_clk200_phase_shift, + g_clk1_phase_shift => g_clk200p_phase_shift + ) + PORT MAP ( + areset => arst, + inclk0 => clk200buf, + c0 => i_st_clk200, + c1 => i_st_clk200p, + c2 => i_st_clk400, + locked => st_locked + ); + END GENERATE; + + gen_st_fractional_pll : IF g_use_fpll=TRUE GENERATE + u_st_fractional_pll : ENTITY tech_fractional_pll_lib.tech_fractional_pll_clk200 + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + areset => arst, + inclk0 => clk200buf, -- 200 MHz + c0 => i_st_clk200, -- 200 MHz + c1 => i_st_clk200p, -- 200 MHz shifted 90 degrees + c2 => i_st_clk400, -- 400 MHz + locked => st_locked + ); + END GENERATE; + + -- Release clock domain resets after some clock cycles when the PLL has locked + st_locked_n <= NOT st_locked; + + u_rst200 : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => st_locked_n, + clk => i_st_clk200, + out_rst => i_st_rst200 + ); + + u_rst200p : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => st_locked_n, + clk => i_st_clk200p, + out_rst => st_rst200p + ); + + u_rst400 : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => st_locked_n, + clk => i_st_clk400, + out_rst => st_rst400 + ); + +END arria10; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk25_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk25_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a4f7612305993083e11746a92216ab1586e1126c --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk25_pll.vhd @@ -0,0 +1,69 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, technology_lib, tech_pll_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + +-- Purpose: PLL for UniBoard node CLK input @ 25 MHz +-- Description: +-- c0 = 20 MHz +-- c1 = 50 MHz +-- c2 = 100 MHz +-- c3 = 125 MHz +-- + +ENTITY unb2_board_clk25_pll IS + GENERIC ( + g_technology : NATURAL := c_tech_arria10 + ); + PORT ( + arst : IN STD_LOGIC := '0'; + clk25 : IN STD_LOGIC := '0'; -- connect to UniBoard ETH_clk pin (25 MHz) + + c0_clk20 : OUT STD_LOGIC; -- PLL c0 + c1_clk50 : OUT STD_LOGIC; -- PLL c1 + c2_clk100 : OUT STD_LOGIC; -- PLL c2 + c3_clk125 : OUT STD_LOGIC; -- PLL c3 + pll_locked : OUT STD_LOGIC + ); +END unb2_board_clk25_pll; + + +ARCHITECTURE arria10 OF unb2_board_clk25_pll IS +BEGIN + + u_pll : ENTITY tech_pll_lib.tech_pll_clk25 + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + areset => arst, + inclk0 => clk25, + c0 => c0_clk20, + c1 => c1_clk50, + c2 => c2_clk100, + c3 => c3_clk125, + locked => pll_locked + ); +END arria10; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk_rst.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk_rst.vhd new file mode 100644 index 0000000000000000000000000000000000000000..561075cf83b12b408cda4871c1272434f693beeb --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_clk_rst.vhd @@ -0,0 +1,86 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +-- Purpose: +-- 1) initial power up xo_rst_n that can be used to reset a SOPC system (via +-- reset_n). +-- 2) sys_rst released when the sys_clk PLL from the SOPC system has locked, +-- can be used as a system reset for the sys_clk domain. + +ENTITY unb2_board_clk_rst IS + PORT ( + -- Reference clock and reset to SOPC system PLL + xo_clk : IN STD_LOGIC; -- reference XO clock (e.g. 25 MHz also use by PLL in SOPC) + xo_rst_n : OUT STD_LOGIC; -- NOT xo_rst (e.g. to reset the SOPC with NIOS2 uP) + -- System clock and locked from SOPC system PLL + sys_clk : IN STD_LOGIC; -- system clock derived from the reference XO clock (e.g. 125 MHz by a PLL from SOPC with NIOS2 uP) + sys_locked : IN STD_LOGIC; -- system clock PLL locked + sys_rst : OUT STD_LOGIC -- system reset released some cycles after the system clock PLL has in locked + ); +END unb2_board_clk_rst; + + +ARCHITECTURE str OF unb2_board_clk_rst IS + + CONSTANT c_reset_len : NATURAL := 4; -- >= c_meta_delay_len from common_pkg + + -- XO clock domain + SIGNAL xo_rst : STD_LOGIC; -- initial reset released after some XO clock cycles + + -- SYS clock domain + SIGNAL sys_locked_n : STD_LOGIC; + +BEGIN + + -- Reference clock and reset to SOPC system PLL + xo_rst_n <= NOT xo_rst; + + u_common_areset_xo : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => '0', -- release reset after some clock cycles + clk => xo_clk, + out_rst => xo_rst + ); + + -- System clock from SOPC system PLL and system reset + sys_locked_n <= NOT sys_locked; + + u_common_areset_sys : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => sys_locked_n, -- release reset after some clock cycles when the PLL has locked + clk => sys_clk, + out_rst => sys_rst + ); + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_front_io.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_front_io.vhd new file mode 100644 index 0000000000000000000000000000000000000000..73927379317d0a4639fbd006f8af9da384338e59 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_front_io.vhd @@ -0,0 +1,78 @@ +------------------------------------------------------------------------------ +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE work.unb2_board_pkg.ALL; + + +ENTITY unb2_board_front_io IS + GENERIC ( + g_nof_qsfp_bus : NATURAL := c_unb2_board_tr_qsfp.nof_bus + ); + PORT ( + serial_tx_arr : IN STD_LOGIC_VECTOR(g_nof_qsfp_bus * c_unb2_board_tr_qsfp.bus_w-1 DOWNTO 0) := (OTHERS=>'0'); + serial_rx_arr : OUT STD_LOGIC_VECTOR(g_nof_qsfp_bus * c_unb2_board_tr_qsfp.bus_w-1 DOWNTO 0); + + green_led_arr : IN STD_LOGIC_VECTOR(g_nof_qsfp_bus-1 DOWNTO 0) := (OTHERS=>'0'); + red_led_arr : IN STD_LOGIC_VECTOR(g_nof_qsfp_bus-1 DOWNTO 0) := (OTHERS=>'0'); + + QSFP_RX : IN t_unb2_board_qsfp_bus_2arr(g_nof_qsfp_bus-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + QSFP_TX : OUT t_unb2_board_qsfp_bus_2arr(g_nof_qsfp_bus-1 DOWNTO 0); + + --QSFP_SDA : INOUT STD_LOGIC_VECTOR(c_unb2_board_tr_qsfp.i2c_w-1 downto 0); + --QSFP_SCL : INOUT STD_LOGIC_VECTOR(c_unb2_board_tr_qsfp.i2c_w-1 downto 0); + --QSFP_RST : INOUT STD_LOGIC; + + QSFP_LED : OUT STD_LOGIC_VECTOR(c_unb2_board_tr_qsfp_nof_leds-1 DOWNTO 0) + ); +END unb2_board_front_io; + +ARCHITECTURE str OF unb2_board_front_io IS + + -- help signals so we can iterate through buses + SIGNAL si_tx_2arr : t_unb2_board_qsfp_bus_2arr(g_nof_qsfp_bus-1 DOWNTO 0); + SIGNAL si_rx_2arr : t_unb2_board_qsfp_bus_2arr(g_nof_qsfp_bus-1 DOWNTO 0); + +BEGIN + + gen_leds : FOR i IN 0 TO g_nof_qsfp_bus-1 GENERATE + QSFP_LED(i*2) <= green_led_arr(i); + QSFP_LED(i*2+1) <= red_led_arr(i); + END GENERATE; + + + gen_buses : FOR i IN 0 TO g_nof_qsfp_bus-1 GENERATE + QSFP_TX(i) <= si_tx_2arr(i); + si_rx_2arr(i) <= QSFP_RX(i); + END GENERATE; + + + gen_wire_bus : FOR i IN 0 TO g_nof_qsfp_bus-1 GENERATE + gen_wire_signals : FOR j IN 0 TO c_unb2_board_tr_qsfp.bus_w-1 GENERATE + + si_tx_2arr(i)(j) <= serial_tx_arr(i*c_unb2_board_tr_qsfp.bus_w + j); + serial_rx_arr(i*c_unb2_board_tr_qsfp.bus_w + j) <= si_rx_2arr(i)(j); + + END GENERATE; + END GENERATE; + +END; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_hmc_ctrl.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_hmc_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..12b817b2abf10ac61c4c575bd3e8bf7301bc8c59 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_hmc_ctrl.vhd @@ -0,0 +1,192 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE i2c_lib.i2c_smbus_pkg.ALL; +USE i2c_lib.i2c_dev_unb2_pkg.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY unb2_board_hmc_ctrl IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_nof_result : NATURAL := 42; + g_temp_high : NATURAL := 85 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + start : IN STD_LOGIC; -- pulse to start the I2C sequence to read out the sensors + out_dat : OUT STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + out_val : OUT STD_LOGIC; + in_dat : IN STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + in_val : IN STD_LOGIC; + in_err : IN STD_LOGIC; + in_ack : IN STD_LOGIC; + in_end : IN STD_LOGIC; + result_val : OUT STD_LOGIC; + result_err : OUT STD_LOGIC; + result_dat : OUT t_slv_8_arr(0 TO g_nof_result-1) + ); +END ENTITY; + + +ARCHITECTURE rtl OF unb2_board_hmc_ctrl IS + + TYPE t_SEQUENCE IS ARRAY (NATURAL RANGE <>) OF NATURAL; + + -- The I2C bit rate is c_i2c_bit_rate = 50 [kbps], so 20 us period. Hence 20 us wait time for SDA is enough + -- Assume clk <= 200 MHz, so 5 ns period. Hence timeout of 4000 is enough. + CONSTANT c_timeout_sda : NATURAL := sel_a_b(g_sim, 0, 16); -- wait 16 * 256 = 4096 clk periods + + CONSTANT c_SEQ : t_SEQUENCE := ( + SMBUS_READ_BYTE , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, -- RX supply + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, -- TX supply + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_C_SAMPLE_SDA, 0, c_timeout_sda, 0, 0, + SMBUS_C_END, + SMBUS_C_NOP + ); + + CONSTANT c_seq_len : NATURAL := c_SEQ'LENGTH-1; + + -- The protocol list c_SEQ yields a list of result bytes (result_dat) + -- make sure that g_nof_result matches the number of result bytes + + SIGNAL start_reg : STD_LOGIC; + + SIGNAL seq_cnt : NATURAL RANGE 0 TO c_seq_len := c_seq_len; + SIGNAL nxt_seq_cnt : NATURAL; + + SIGNAL rx_cnt : NATURAL RANGE 0 TO g_nof_result; + SIGNAL nxt_rx_cnt : NATURAL; + + SIGNAL rx_val : STD_LOGIC; + SIGNAL nxt_rx_val : STD_LOGIC; + SIGNAL rx_err : STD_LOGIC; + SIGNAL nxt_rx_err : STD_LOGIC; + SIGNAL rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_val : STD_LOGIC; + SIGNAL nxt_result_err : STD_LOGIC; + SIGNAL i_result_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_dat : t_slv_8_arr(result_dat'RANGE); + +BEGIN + + result_dat <= i_result_dat; + + regs: PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + start_reg <= '0'; + seq_cnt <= c_seq_len; + rx_cnt <= 0; + rx_val <= '0'; + rx_err <= '0'; + rx_dat <= (OTHERS=>(OTHERS=>'0')); + result_val <= '0'; + result_err <= '0'; + i_result_dat <= (OTHERS=>(OTHERS=>'0')); + ELSIF rising_edge(clk) THEN + start_reg <= start; + seq_cnt <= nxt_seq_cnt; + rx_cnt <= nxt_rx_cnt; + rx_val <= nxt_rx_val; + rx_err <= nxt_rx_err; + rx_dat <= nxt_rx_dat; + result_val <= nxt_result_val; + result_err <= nxt_result_err; + i_result_dat <= nxt_result_dat; + END IF; + END PROCESS; + + -- Issue the protocol list + p_seq_cnt : PROCESS(seq_cnt, start_reg, in_ack) + BEGIN + nxt_seq_cnt <= seq_cnt; + IF start_reg = '1' THEN + nxt_seq_cnt <= 0; + ELSIF seq_cnt<c_seq_len AND in_ack='1' THEN + nxt_seq_cnt <= seq_cnt + 1; + END IF; + END PROCESS; + + out_dat <= STD_LOGIC_VECTOR(TO_UVEC(c_SEQ(seq_cnt), c_byte_w)); + out_val <= '1' WHEN seq_cnt<c_seq_len ELSE '0'; + + -- Fill the rx_dat byte array + p_rx_dat : PROCESS(start_reg, rx_err, in_err, rx_dat, rx_cnt, in_dat, in_val) + BEGIN + nxt_rx_err <= rx_err; + IF start_reg = '1' THEN + nxt_rx_err <= '0'; + ELSIF in_err='1' THEN + nxt_rx_err <= '1'; + END IF; + + nxt_rx_dat <= rx_dat; + nxt_rx_cnt <= rx_cnt; + IF start_reg = '1' THEN + nxt_rx_dat <= (OTHERS=>(OTHERS=>'0')); + nxt_rx_cnt <= 0; + ELSIF in_val='1' THEN + nxt_rx_dat(rx_cnt) <= in_dat; + nxt_rx_cnt <= rx_cnt + 1; + END IF; + END PROCESS; + + nxt_rx_val <= in_end; + + -- Capture the complete rx_dat byte array + nxt_result_val <= rx_val; + nxt_result_err <= rx_err; + nxt_result_dat <= rx_dat WHEN rx_val='1' ELSE i_result_dat; + +END rtl; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_node_ctrl.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_node_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..afe1feab4e4d7fc402bc8adc4a0519c823ab754c --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_node_ctrl.vhd @@ -0,0 +1,114 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +-- Purpose: Provide the basic node clock control (resets, pulses, WDI) +-- Description: +-- . Create mm_rst for mm_clk: +-- . Extend WDI to avoid watchdog reset during software reload +-- . Pulse every 1 us, 1 ms and 1 s + +ENTITY unb2_board_node_ctrl IS + GENERIC ( + g_pulse_us : NATURAL := 125; -- nof system clock cycles to get us period, equal to system clock frequency / 10**6 + g_pulse_ms : NATURAL := 1000; -- nof pulse_us pulses to get ms period (fixed, use less to speed up simulation) + g_pulse_s : NATURAL := 1000; -- nof pulse_ms pulses to get s period (fixed, use less to speed up simulation) + g_wdi_extend_w : NATURAL := 14 -- extend the mm_wdi_in by toggling the mm_wdi_out for about 2**(14-1)= 8 s more + ); + PORT ( + -- MM clock domain reset + mm_clk : IN STD_LOGIC; -- MM clock + mm_locked : IN STD_LOGIC := '1'; -- MM clock PLL locked (or use default '1') + mm_rst : OUT STD_LOGIC; -- MM reset released after MM clock PLL has locked + + -- WDI extend + mm_wdi_in : IN STD_LOGIC; -- from software running on the NIOS2 in the SOPC design + mm_wdi_out : OUT STD_LOGIC; -- to FPGA pin + + -- Pulses + mm_pulse_us : OUT STD_LOGIC; -- pulses every us + mm_pulse_ms : OUT STD_LOGIC; -- pulses every ms + mm_pulse_s : OUT STD_LOGIC -- pulses every s + ); +END unb2_board_node_ctrl; + + +ARCHITECTURE str OF unb2_board_node_ctrl IS + + CONSTANT c_reset_len : NATURAL := 4; -- >= c_meta_delay_len from common_pkg + + SIGNAL mm_locked_n : STD_LOGIC; + SIGNAL i_mm_rst : STD_LOGIC; + SIGNAL i_mm_pulse_ms : STD_LOGIC; + +BEGIN + + -- Create mm_rst reset in mm_clk domain based on mm_locked + mm_rst <= i_mm_rst; + + mm_locked_n <= NOT mm_locked; + + u_common_areset_mm : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', -- power up default will be inferred in FPGA + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => mm_locked_n, -- release reset after some clock cycles when the PLL has locked + clk => mm_clk, + out_rst => i_mm_rst + ); + + -- Create 1 pulse per us, per ms and per s + mm_pulse_ms <= i_mm_pulse_ms; + + u_common_pulser_us_ms_s : ENTITY common_lib.common_pulser_us_ms_s + GENERIC MAP ( + g_pulse_us => g_pulse_us, + g_pulse_ms => g_pulse_ms, + g_pulse_s => g_pulse_s + ) + PORT MAP ( + rst => i_mm_rst, + clk => mm_clk, + pulse_us => mm_pulse_us, + pulse_ms => i_mm_pulse_ms, + pulse_s => mm_pulse_s + ); + + -- Toggle the WDI every 1 ms + u_unb2_board_wdi_extend : ENTITY work.unb2_board_wdi_extend + GENERIC MAP ( + g_extend_w => g_wdi_extend_w + ) + PORT MAP ( + rst => i_mm_rst, + clk => mm_clk, + pulse_ms => i_mm_pulse_ms, + wdi_in => mm_wdi_in, + wdi_out => mm_wdi_out + ); + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_peripherals_pkg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_peripherals_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..18e45198042d4743f27025fb08a8b775157d74f0 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_peripherals_pkg.vhd @@ -0,0 +1,173 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Central location for collecting the peripheral MM register widths +-- Description: +-- The MM register width can be fixed or application dependent. When the MM +-- register width is fixed it can be defined as a local constant in the +-- module *_reg.vhd file or it may be defined in a module package. +-- When modules are used in a design the MM register widths are needed to +-- connect the 'node' part of the design to the 'sopc' part. Most designs do +-- use the same widths also for the variable width MM registers. Therefore +-- rather then obtaining the variable MM register widths from local design +-- constants and the fixed widths from module packages, it seems easier to +-- collect them here in t_c_unb2_board_peripherals_mm_reg. +-- Remarks: +-- . The c_unb2_board_peripherals_mm_reg_default suits most designs, if +-- necessary design specific t_c_unb2_board_peripherals_mm_reg constants +-- can be defined here as well. +-- . If some design would need different widths for multiple instances, then +-- these widths need to be defined locally in that design. + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; + +PACKAGE unb2_board_peripherals_pkg IS + + + -- *_adr_w : Actual MM address widths + -- *_dat_w : The default MM data width is c_word_w=32, otherwise it is specified in the record + TYPE t_c_unb2_board_peripherals_mm_reg IS RECORD + cross_clock_domain : BOOLEAN; -- = TRUE -- use FALSE when mm_clk and dp_clk are the same, else use TRUE to cross the clock domain + + -- 1GbE + reg_tse_adr_w : NATURAL; -- = 10 -- = c_tse_byte_addr_w from tse_pkg.vhd + reg_eth_adr_w : NATURAL; -- = 4 -- = c_eth_reg_addr_w from eth_pkg.vhd + ram_eth_adr_w : NATURAL; -- = 10 -- = c_eth_ram_addr_w from eth_pkg.vhd + + -- pi_system_info (first word of reg_unb_system_info_adr_w is backwards compatible with the original single word PIO system info) + reg_unb_system_info_adr_w : NATURAL; -- = 5 -- fixed, from c_mm_reg in unb_system_info_reg + rom_unb_system_info_adr_w : NATURAL; -- = 10 -- fixed, from c_mm_rom in mms_unb_system_info + -- pi_reg_common + reg_common_adr_w : NATURAL; -- = 1 -- fixed, from c_mem_reg in mms_common_reg + + -- pi_ppsh + reg_ppsh_adr_w : NATURAL; -- = 1 -- fixed, from c_mm_reg in ppsh_reg + + -- pi_unb_sens + reg_unb_sens_adr_w : NATURAL; -- = 6 -- fixed, from c_mm_reg in unb_sens_reg + + -- pi_dpmm + reg_dpmm_data_adr_w : NATURAL; -- = 1 -- fixed, see dp_fifo_to_mm.vhd + reg_dpmm_ctrl_adr_w : NATURAL; -- = 1 -- fixed, from c_mm_reg in dp_fifo_to_mm_reg.vhd + + -- pi_mmdp + reg_mmdp_data_adr_w : NATURAL; -- = 1 -- fixed, see dp_fifo_from_mm.vhd + reg_mmdp_ctrl_adr_w : NATURAL; -- = 1 -- fixed, from c_mm_reg in dp_fifo_from_mm_reg.vhd + + -- pi_dp_ram_from_mm + reg_dp_ram_from_mm_adr_w : NATURAL; -- = 1 -- fixed, see dp_ram_from_mm.vhd + -- ram_dp_ram_from_mm_adr_w : NATURAL; -- = VAR -- Variable, from c_mm_reg in dp_ram_from_mm_reg.vhd + + -- pi_dp_ram_to_mm +-- ram_dp_ram_to_mm_adr_w : NATURAL; -- = VAR -- Variable, from c_mm_reg in dp_ram_to_mm_reg.vhd + + -- pi_epcs (uses DP-MM read and write FIFOs for data access) + reg_epcs_adr_w : NATURAL; -- = 3 -- fixed, from c_mm_reg in epcs_reg + + -- pi_remu + reg_remu_adr_w : NATURAL; -- = 3 -- fixed, from c_mm_reg in remu_reg + + -- pi_ddr + -- pi_ddr_capture (uses DP-MM read FIFO for data access) + reg_ddr_adr_w : NATURAL; -- = 3 -- fixed, from c_mm_reg in ddr_reg + + -- pi_io_ddr + reg_io_ddr_adr_w : NATURAL; -- = 16 -- fixed, from c_mm_reg in io_ddr (3) and in io_ddr_reg (8) that get multiplexed in on addresses 0..2, 8..15 + + -- pi_tr_nonbonded + reg_tr_nonbonded_adr_w : NATURAL; -- = 4 -- fixed, from c_mm_reg in tr_nonbonded_reg + + -- pi_diagnostics + reg_diagnostics_adr_w : NATURAL; -- = 6 -- fixed, from c_mm_reg in diagnostics_reg + + -- pi_dp_throttle + reg_dp_throttle_adr_w : NATURAL; -- = 2 -- fixed, from c_mm_reg in dp_throttle_reg + + -- pi_bsn_source + reg_bsn_source_adr_w : NATURAL; -- = 2 -- fixed, from c_mm_reg in dp_bsn_source_reg.vhd + + -- pi_bsn_schedurer + reg_bsn_scheduler_adr_w : NATURAL; -- = 1 -- fixed, from c_mm_reg in dp_bsn_scheduler_reg.vhd + + -- pi_bsn_monitor + reg_bsn_monitor_adr_w : NATURAL; -- = 4 -- fixed, from c_mm_reg in dp_bsn_monitor_reg.vhd + + -- pi_aduh_quad (defaults for ADU) + reg_adc_quad_adr_w : NATURAL; -- = 3 -- fixed, from c_mm_reg in aduh_quad_reg.vhd + + -- pi_aduh_i2c_commander (defaults for ADU) + reg_i2c_commander_adr_w : NATURAL; -- = 6 -- = c_i2c_cmdr_aduh_i2c_mm.control_adr_w, from i2c_commander_aduh_pkg, used to pass on commander_adr_w + ram_i2c_protocol_adr_w : NATURAL; -- = 13 -- = c_i2c_cmdr_aduh_i2c_mm.protocol_adr_w, from i2c_commander_aduh_pkg + ram_i2c_result_adr_w : NATURAL; -- = 12 -- = c_i2c_cmdr_aduh_i2c_mm.result_adr_w, from i2c_commander_aduh_pkg + + -- pi_aduh_monitor (defaults for ADU or WG used in bn_capture) + reg_aduh_mon_adr_w : NATURAL; -- = 2 -- fixed, from c_mm_reg in aduh_monitor_reg.vhd + ram_aduh_mon_dat_w : NATURAL; -- = 32 -- = c_sp_data_w, see node_bn_capture.vhd + ram_aduh_mon_adr_w : NATURAL; -- = 8 -- = ceil_log2(c_bn_capture.sp.monitor_buffer_nof_samples/c_wideband_factor), see node_bn_capture.vhd + + -- pi_diag_wg_wideband.py (defaults for WG used in bn_capture) + reg_diag_wg_adr_w : NATURAL; -- = 2 -- fixed, from c_mm_reg in diag_wg_wideband_reg + ram_diag_wg_dat_w : NATURAL; -- = 8 -- defined here, see bn_capture_input.vhd + ram_diag_wg_adr_w : NATURAL; -- = 10 -- defined here, see bn_capture_input.vhd + + -- pi_diag_data_buffer.py + ram_diag_db_nof_buf : NATURAL; -- = 16 + ram_diag_db_buf_size : NATURAL; -- = 1024 + ram_diag_db_adr_w : NATURAL; -- = 14 -- = ram_diag_db_nof_buf*ceil_log2(ram_diag_db_buf_size) + reg_diag_db_adr_w : NATURAL; -- = 5 -- 32 words for 16 streams max + + -- pi_diag_block_gen (defaults when used with the BF for Apertif) + reg_diag_bg_adr_w : NATURAL; -- = 3 + ram_diag_bg_adr_w : NATURAL; -- = 11 -- = ceil_log2(c_bf.nof_subbands*c_bf.nof_signal_paths/c_bf.nof_input_streams = 24*64/16 = 96) + ceil_log2(c_bf.nof_input_streams = 16) + + -- pi_diag_tx_seq.py + reg_diag_tx_seq_w : NATURAL; -- = 2 + + -- pi_diag_tx_seq.py + reg_diag_rx_seq_w : NATURAL; -- = 3 + + -- pi_bf_bf (defaults for the BF for Apertif) + reg_bf_offsets_adr_w : NATURAL; -- = 5 -- = ceil_log2(c_bf.nof_offsets = 6) + ceil_log2(c_bf.nof_bf_units = 4) + ram_bf_weights_adr_w : NATURAL; -- = 16 -- = ceil_log2(c_bf.nof_bf_units*c_bf.nof_signal_paths*c_bf.nof_weights = 4 * 64 * 256 = 65536) + ram_st_sst_bf_adr_w : NATURAL; -- = 11 -- = ceil_log2(c_bf.nof_bf_units*c_bf.stat_data_sz*c_bf.nof_weights = 4 * 2 * 256 = 2048) + + -- pi_mdio + reg_mdio_adr_w : NATURAL; -- = 3 + + -- dp_offload + reg_dp_offload_tx_adr_w : NATURAL; -- = 1 + + -- pi_unb_fpga_sensors + reg_fpga_temp_sens_adr_w : NATURAL; -- = 3 + reg_fpga_voltage_sens_adr_w : NATURAL; -- = 4 + + -- pi_unb_pmbus + reg_unb_pmbus_adr_w : NATURAL; -- = 6 + END RECORD; + + CONSTANT c_unb2_board_peripherals_mm_reg_default : t_c_unb2_board_peripherals_mm_reg := (TRUE, 10, 4, 10, 5, 10, 1, 1, 6, 1, 1, 1, 1, 1, 3, 3, 3, 16, 4, 6, 2, 2, 1, 4, 3, 6, 13, 12, 2, 32, 8, 2, 8, 10, 16, 1024, 14, 5, 3, 11, 2, 3, 5, 16, 11, 3, 1, 3, 4, 6); + +END unb2_board_peripherals_pkg; + +PACKAGE BODY unb2_board_peripherals_pkg IS +END unb2_board_peripherals_pkg; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pkg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a811f49c45e417bdd3488a25b295196c7aeddf1f --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pkg.vhd @@ -0,0 +1,175 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009-2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +PACKAGE unb2_board_pkg IS + + -- UniBoard + CONSTANT c_unb2_board_nof_node : NATURAL := 4; -- number of nodes on UniBoard + CONSTANT c_unb2_board_nof_node_w : NATURAL := 2; -- = ceil_log2(c_unb2_board_nof_node) + CONSTANT c_unb2_board_nof_chip : NATURAL := c_unb2_board_nof_node; -- = 4 + CONSTANT c_unb2_board_nof_chip_w : NATURAL := 2; -- = ceil_log2(c_unb2_board_nof_chip) + CONSTANT c_unb2_board_nof_ddr : NATURAL := 2; -- each node has 2 DDR modules + + -- Subrack + CONSTANT c_unb2_board_nof_uniboard : NATURAL := 4; -- nof UniBoard in a subrack + CONSTANT c_unb2_board_nof_uniboard_w : NATURAL := 6; -- Only 2 required for 4 boards; full width is 6. + + -- Clock frequencies + CONSTANT c_unb2_board_ext_clk_freq_200M : NATURAL := 200 * 10**6; -- external clock, SMA clock + CONSTANT c_unb2_board_eth_clk_freq_25M : NATURAL := 25 * 10**6; -- fixed 25 MHz ETH XO clock used as reference clock for the PLL + CONSTANT c_unb2_board_eth_clk_freq_125M : NATURAL := 125 * 10**6; -- fixed 125 MHz ETH XO clock used as direct clock for TSE + CONSTANT c_unb2_board_tse_clk_freq : NATURAL := 125 * 10**6; -- fixed 125 MHz TSE reference clock derived from ETH_clk by PLL + CONSTANT c_unb2_board_cal_clk_freq : NATURAL := 40 * 10**6; -- fixed 40 MHz IO calibration clock derived from ETH_clk by PLL + CONSTANT c_unb2_board_mm_clk_freq_10M : NATURAL := 10 * 10**6; -- clock when g_sim=TRUE + CONSTANT c_unb2_board_mm_clk_freq_25M : NATURAL := 25 * 10**6; -- clock derived from ETH_clk by PLL + CONSTANT c_unb2_board_mm_clk_freq_50M : NATURAL := 50 * 10**6; -- clock derived from ETH_clk by PLL + CONSTANT c_unb2_board_mm_clk_freq_100M : NATURAL := 100 * 10**6; -- clock derived from ETH_clk by PLL + CONSTANT c_unb2_board_mm_clk_freq_125M : NATURAL := 125 * 10**6; -- clock derived from ETH_clk by PLL + + -- I2C + CONSTANT c_unb2_board_reg_sens_adr_w : NATURAL := 3; -- must match ceil_log2(c_mm_nof_dat) in unb2_board_sens_reg.vhd + + CONSTANT c_i2c_peripheral_sens : NATURAL := 0; + CONSTANT c_i2c_peripheral_pmbus : NATURAL := 1; + CONSTANT c_i2c_peripheral_hmc : NATURAL := 2; + + -- ETH + CONSTANT c_unb2_board_nof_eth : NATURAL := 2; -- number of ETH channels per node + + -- CONSTANT RECORD DECLARATIONS --------------------------------------------- + + -- c_unb2_board_signature_* : random signature words used for unused status bits to ensure that the software reads the correct interface address + CONSTANT c_unb2_board_signature_eth1g_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := X"46e46cbc"; + CONSTANT c_unb2_board_signature_eth10g_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := X"2bd2e40a"; + + CONSTANT c_unb2_board_signature_eth1g : INTEGER := TO_SINT(c_unb2_board_signature_eth1g_slv ); + CONSTANT c_unb2_board_signature_eth10g : INTEGER := TO_SINT(c_unb2_board_signature_eth10g_slv ); + + -- Transceivers + TYPE t_c_unb2_board_tr IS RECORD + nof_bus : NATURAL; + bus_w : NATURAL; + i2c_w : NATURAL; + END RECORD; + + --CONSTANT c_unb2_board_tr_back : t_c_unb2_board_tr := (2, 24, 3); -- per node: 2 buses with 24 channels + CONSTANT c_unb2_board_tr_back : t_c_unb2_board_tr := (1, 24, 3); -- per node: 1 buses with 24 channels (testing) + --CONSTANT c_unb2_board_tr_back : t_c_unb2_board_tr := (2, 12, 3); -- per node: 2 buses with 24 channels (testing) + --CONSTANT c_unb2_board_tr_back : t_c_unb2_board_tr := (2, 4, 3); -- per node: 2 buses with 24 channels (testing) + + CONSTANT c_unb2_board_tr_ring : t_c_unb2_board_tr := (2, 12, 0); -- per node: 2 buses with 12 channels + --CONSTANT c_unb2_board_tr_ring : t_c_unb2_board_tr := (2, 4, 0); -- per node: 2 buses with 12 channels (testing) + + CONSTANT c_unb2_board_tr_qsfp : t_c_unb2_board_tr := (6, 4, 6); -- per node: 6 buses with 4 channels + CONSTANT c_unb2_board_tr_qsfp_nof_leds : NATURAL := c_unb2_board_tr_qsfp.nof_bus * 2; -- 2 leds per qsfp + + + TYPE t_unb2_board_qsfp_bus_2arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_unb2_board_tr_qsfp.bus_w-1 DOWNTO 0); + TYPE t_unb2_board_ring_bus_2arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_unb2_board_tr_ring.bus_w-1 DOWNTO 0); + TYPE t_unb2_board_back_bus_2arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_unb2_board_tr_back.bus_w-1 DOWNTO 0); + + + -- Auxiliary + + -- Test IO Interface + TYPE t_c_unb2_board_testio IS RECORD + tst_w : NATURAL; -- = nof tst = 2; [tst_w-1 +tst_lo : tst_lo] = [5:4], + led_w : NATURAL; -- = nof led = 2; [led_w-1 +led_lo : led_lo] = [3:2], + jmp_w : NATURAL; -- = nof jmp = 2; [jmp_w-1 +jmp_lo : jmp_lo] = [1:0], + tst_lo : NATURAL; -- = 2; + led_lo : NATURAL; -- = 2; + jmp_lo : NATURAL; -- = 0; + END RECORD; + + CONSTANT c_unb2_board_testio : t_c_unb2_board_testio := (2, 2, 2, 2, 2, 0); + CONSTANT c_unb2_board_testio_led_green : NATURAL := c_unb2_board_testio.led_lo; + CONSTANT c_unb2_board_testio_led_red : NATURAL := c_unb2_board_testio.led_lo+1; + + TYPE t_c_unb2_board_aux IS RECORD + version_w : NATURAL; -- = 2; + id_w : NATURAL; -- = 8; -- 6+2 bits wide = total node ID for up to 64 UniBoards in a system and 4 nodes per board + chip_id_w : NATURAL; -- = 2; -- board node ID for the 4 FPGA nodes on a UniBoard + testio_w : NATURAL; -- = 6; + testio : t_c_unb2_board_testio; + END RECORD; + + CONSTANT c_unb2_board_aux : t_c_unb2_board_aux := (2, 8, c_unb2_board_nof_chip_w, 6, c_unb2_board_testio); + + TYPE t_e_unb2_board_node IS (e_any); + + TYPE t_unb2_board_fw_version IS RECORD + hi : NATURAL; -- = 0..15 + lo : NATURAL; -- = 0..15, firmware version is: hi.lo + END RECORD; + + CONSTANT c_unb2_board_fw_version : t_unb2_board_fw_version := (0, 0); + + -- SIGNAL RECORD DECLARATIONS ----------------------------------------------- + + + -- I2C, MDIO + -- . If no I2C bus arbitration or clock stretching is needed then the SCL only needs to be output. + -- . Can also be used for a PHY Management Data IO interface with serial clock MDC and serial data MDIO + TYPE t_unb2_board_i2c_inout IS RECORD + scl : STD_LOGIC; -- serial clock + sda : STD_LOGIC; -- serial data + END RECORD; + + -- System info + TYPE t_c_unb2_board_system_info IS RECORD + version : NATURAL; -- UniBoard board HW version (2 bit value) + id : NATURAL; -- UniBoard FPGA node id (8 bit value) + -- Derived ID info: + bck_id : NATURAL; -- = id[7:2], ID part from back plane + chip_id : NATURAL; -- = id[1:0], ID part from UniBoard + node_id : NATURAL; -- = id[1:0], node ID: 0, 1, 2 or 3 + is_node2 : NATURAL; -- 1 for Node 2, else 0. + END RECORD; + + FUNCTION func_unb2_board_system_info(VERSION : IN STD_LOGIC_VECTOR(c_unb2_board_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(c_unb2_board_aux.id_w-1 DOWNTO 0)) RETURN t_c_unb2_board_system_info; + +END unb2_board_pkg; + + +PACKAGE BODY unb2_board_pkg IS + + FUNCTION func_unb2_board_system_info(VERSION : IN STD_LOGIC_VECTOR(c_unb2_board_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(c_unb2_board_aux.id_w-1 DOWNTO 0)) RETURN t_c_unb2_board_system_info IS + VARIABLE v_system_info : t_c_unb2_board_system_info; + BEGIN + v_system_info.version := TO_INTEGER(UNSIGNED(VERSION)); + v_system_info.id := TO_INTEGER(UNSIGNED(ID)); + v_system_info.bck_id := TO_INTEGER(UNSIGNED(ID(7 DOWNTO 2))); + v_system_info.chip_id := TO_INTEGER(UNSIGNED(ID(1 DOWNTO 0))); + v_system_info.node_id := TO_INTEGER(UNSIGNED(ID(1 DOWNTO 0))); + IF UNSIGNED(ID(1 DOWNTO 0))=2 THEN v_system_info.is_node2 := 1; ELSE v_system_info.is_node2 := 0; END IF; + RETURN v_system_info; + END; + +END unb2_board_pkg; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pmbus_ctrl.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pmbus_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..934ac9f4beb8ca5a97cf3803134d19477c0a57fa --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_pmbus_ctrl.vhd @@ -0,0 +1,192 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE i2c_lib.i2c_smbus_pkg.ALL; +USE i2c_lib.i2c_dev_unb2_pkg.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY unb2_board_pmbus_ctrl IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_nof_result : NATURAL := 42; + g_temp_high : NATURAL := 85 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + start : IN STD_LOGIC; -- pulse to start the I2C sequence to read out the sensors + out_dat : OUT STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + out_val : OUT STD_LOGIC; + in_dat : IN STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + in_val : IN STD_LOGIC; + in_err : IN STD_LOGIC; + in_ack : IN STD_LOGIC; + in_end : IN STD_LOGIC; + result_val : OUT STD_LOGIC; + result_err : OUT STD_LOGIC; + result_dat : OUT t_slv_8_arr(0 TO g_nof_result-1) + ); +END ENTITY; + + +ARCHITECTURE rtl OF unb2_board_pmbus_ctrl IS + + TYPE t_SEQUENCE IS ARRAY (NATURAL RANGE <>) OF NATURAL; + + -- The I2C bit rate is c_i2c_bit_rate = 50 [kbps], so 20 us period. Hence 20 us wait time for SDA is enough + -- Assume clk <= 200 MHz, so 5 ns period. Hence timeout of 4000 is enough. + CONSTANT c_timeout_sda : NATURAL := sel_a_b(g_sim, 0, 16); -- wait 16 * 256 = 4096 clk periods + + CONSTANT c_SEQ : t_SEQUENCE := ( + SMBUS_READ_BYTE , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, -- RX supply + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR0_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, -- TX supply + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_TCVR1_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CORE_BMR464_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_CTRL_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_FPGAIO_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_PMB_VCCRAM_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_C_SAMPLE_SDA, 0, c_timeout_sda, 0, 0, + SMBUS_C_END, + SMBUS_C_NOP + ); + + CONSTANT c_seq_len : NATURAL := c_SEQ'LENGTH-1; + + -- The protocol list c_SEQ yields a list of result bytes (result_dat) + -- make sure that g_nof_result matches the number of result bytes + + SIGNAL start_reg : STD_LOGIC; + + SIGNAL seq_cnt : NATURAL RANGE 0 TO c_seq_len := c_seq_len; + SIGNAL nxt_seq_cnt : NATURAL; + + SIGNAL rx_cnt : NATURAL RANGE 0 TO g_nof_result; + SIGNAL nxt_rx_cnt : NATURAL; + + SIGNAL rx_val : STD_LOGIC; + SIGNAL nxt_rx_val : STD_LOGIC; + SIGNAL rx_err : STD_LOGIC; + SIGNAL nxt_rx_err : STD_LOGIC; + SIGNAL rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_val : STD_LOGIC; + SIGNAL nxt_result_err : STD_LOGIC; + SIGNAL i_result_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_dat : t_slv_8_arr(result_dat'RANGE); + +BEGIN + + result_dat <= i_result_dat; + + regs: PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + start_reg <= '0'; + seq_cnt <= c_seq_len; + rx_cnt <= 0; + rx_val <= '0'; + rx_err <= '0'; + rx_dat <= (OTHERS=>(OTHERS=>'0')); + result_val <= '0'; + result_err <= '0'; + i_result_dat <= (OTHERS=>(OTHERS=>'0')); + ELSIF rising_edge(clk) THEN + start_reg <= start; + seq_cnt <= nxt_seq_cnt; + rx_cnt <= nxt_rx_cnt; + rx_val <= nxt_rx_val; + rx_err <= nxt_rx_err; + rx_dat <= nxt_rx_dat; + result_val <= nxt_result_val; + result_err <= nxt_result_err; + i_result_dat <= nxt_result_dat; + END IF; + END PROCESS; + + -- Issue the protocol list + p_seq_cnt : PROCESS(seq_cnt, start_reg, in_ack) + BEGIN + nxt_seq_cnt <= seq_cnt; + IF start_reg = '1' THEN + nxt_seq_cnt <= 0; + ELSIF seq_cnt<c_seq_len AND in_ack='1' THEN + nxt_seq_cnt <= seq_cnt + 1; + END IF; + END PROCESS; + + out_dat <= STD_LOGIC_VECTOR(TO_UVEC(c_SEQ(seq_cnt), c_byte_w)); + out_val <= '1' WHEN seq_cnt<c_seq_len ELSE '0'; + + -- Fill the rx_dat byte array + p_rx_dat : PROCESS(start_reg, rx_err, in_err, rx_dat, rx_cnt, in_dat, in_val) + BEGIN + nxt_rx_err <= rx_err; + IF start_reg = '1' THEN + nxt_rx_err <= '0'; + ELSIF in_err='1' THEN + nxt_rx_err <= '1'; + END IF; + + nxt_rx_dat <= rx_dat; + nxt_rx_cnt <= rx_cnt; + IF start_reg = '1' THEN + nxt_rx_dat <= (OTHERS=>(OTHERS=>'0')); + nxt_rx_cnt <= 0; + ELSIF in_val='1' THEN + nxt_rx_dat(rx_cnt) <= in_dat; + nxt_rx_cnt <= rx_cnt + 1; + END IF; + END PROCESS; + + nxt_rx_val <= in_end; + + -- Capture the complete rx_dat byte array + nxt_result_val <= rx_val; + nxt_result_err <= rx_err; + nxt_result_dat <= rx_dat WHEN rx_val='1' ELSE i_result_dat; + +END rtl; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_qsfp_leds.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_qsfp_leds.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f90d2dc68961b44125a049a8e170d394778f678e --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_qsfp_leds.vhd @@ -0,0 +1,186 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +-- Purpose: Provide visual activity information via the UniBoard2 front panel QSFP LEDs. +-- Description: +-- The testio LED on UniBoard2 is not visible via the front panel. The +-- front panel does have a dual colour LED for each QSFP lane. Therefore +-- these QSFP LEDs are used to signal some application information and lane +-- status/activity information. +-- +-- LED lights: +-- +-- 1) Default behaviour for all QSFP leds: +-- . off = no FPGA image is running +-- +-- 2) For factory image: +-- . green off +-- . red toggling every 1 s = factory image is running (g_factory_image=TRUE) +-- +-- 3) For a user image without Gbps lane functionality: +-- . red off +-- . green toggling every 1 s = user image is running (g_factory_image=FALSE and green_on_arr(I)='0' default) +-- +-- 4) For a user image with Gbps lane functionality: +-- . red off +-- . green toggling every 1 s when the lane status is not OK (green_on_arr(I)=xon='0') +-- . green on continously when the lane status is OK (green_on_arr(I)=xon='1') +-- . green led goes off briefly off when there is an Tx or Rx packet (green_evt_arr(I).sop='1') +-- +-- The combined colour amber (= red + green) is not used. The factory image +-- only uses the red led and the user image only uses the green led. +-- +-- Each QSFP carries c_quad = 4 lanes, therefore the green led LED can only +-- signal a combined status of the lanes. The combined status eg. be: +-- +-- 'and-status' = combined status is on when all lanes are on +-- 'or-status' = combined status is on when at least 1 lane is on +-- +-- Choose using 'or-status', because then the LED can give lane status +-- information when less than all 4 lane are connected. +-- + +ENTITY unb2_board_qsfp_leds IS + GENERIC ( + g_sim : BOOLEAN := FALSE; -- when true speed up led toggling in simulation + g_factory_image : BOOLEAN := FALSE; -- distinguish factory image and user images + g_nof_qsfp : NATURAL := 6; -- number of QSFP cages each with one dual led that can light red or green (or amber = red + green) + g_pulse_us : NATURAL := 200 -- nof clk cycles to get us period + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + -- internal pulser outputs + pulse_us : OUT STD_LOGIC; + pulse_ms : OUT STD_LOGIC; + pulse_s : OUT STD_LOGIC; + -- lane status + tx_siso_arr : IN t_dp_siso_arr(g_nof_qsfp*c_quad-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rst); + tx_sosi_arr : IN t_dp_sosi_arr(g_nof_qsfp*c_quad-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + rx_sosi_arr : IN t_dp_sosi_arr(g_nof_qsfp*c_quad-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + -- leds + green_led_arr : OUT STD_LOGIC_VECTOR(g_nof_qsfp-1 DOWNTO 0); + red_led_arr : OUT STD_LOGIC_VECTOR(g_nof_qsfp-1 DOWNTO 0) + ); +END unb2_board_qsfp_leds; + + +ARCHITECTURE str OF unb2_board_qsfp_leds IS + + CONSTANT c_nof_ms : NATURAL := sel_a_b(g_sim, 1, 100); -- force off for c_nof_ms and then on for at least c_nof_ms + CONSTANT c_nof_lanes : NATURAL := g_nof_qsfp*c_quad; -- number of transceiver lanes, fixed 4 per Quad-SFP cage + + SIGNAL i_pulse_ms : STD_LOGIC; + SIGNAL i_pulse_s : STD_LOGIC; + SIGNAL toggle_s : STD_LOGIC; + + SIGNAL green_on_arr : STD_LOGIC_VECTOR(g_nof_qsfp*c_quad-1 DOWNTO 0); + SIGNAL green_evt_arr : STD_LOGIC_VECTOR(g_nof_qsfp*c_quad-1 DOWNTO 0); + + SIGNAL qsfp_on_arr : STD_LOGIC_VECTOR(g_nof_qsfp-1 DOWNTO 0); + SIGNAL qsfp_evt_arr : STD_LOGIC_VECTOR(g_nof_qsfp-1 DOWNTO 0); + +BEGIN + + pulse_ms <= i_pulse_ms; + pulse_s <= i_pulse_s; + + -- Also output the pulses, because they could be useful for other purposes in the clk clock domain as well + u_common_pulser_us_ms_s : ENTITY common_lib.common_pulser_us_ms_s + GENERIC MAP ( + g_pulse_us => g_pulse_us, -- nof clk cycles to get us period + g_pulse_ms => sel_a_b(g_sim, 10, 1000), -- nof pulse_us pulses to get ms period + g_pulse_s => sel_a_b(g_sim, 10, 1000) -- nof pulse_ms pulses to get s period + ) + PORT MAP ( + rst => rst, + clk => clk, + pulse_us => pulse_us, + pulse_ms => i_pulse_ms, + pulse_s => i_pulse_s + ); + + u_common_toggle_s : ENTITY common_lib.common_toggle + PORT MAP ( + rst => rst, + clk => clk, + in_dat => i_pulse_s, + out_dat => toggle_s + ); + + gen_factory_image : IF g_factory_image=TRUE GENERATE + green_led_arr <= (OTHERS=>'0'); + + gen_red_led_arr : FOR I IN g_nof_qsfp-1 DOWNTO 0 GENERATE + u_red_led_controller : ENTITY common_lib.common_led_controller + GENERIC MAP ( + g_nof_ms => c_nof_ms + ) + PORT MAP ( + rst => rst, + clk => clk, + -- led control + ctrl_input => toggle_s, + -- led output + led => red_led_arr(I) + ); + END GENERATE; + END GENERATE; + + gen_user_image : IF g_factory_image=FALSE GENERATE + + red_led_arr <= (OTHERS=>'0'); + + gen_green_ctrl_arr : FOR I IN c_nof_lanes-1 DOWNTO 0 GENERATE + green_on_arr(I) <= tx_siso_arr(I).xon WHEN rising_edge(clk); + green_evt_arr(I) <= tx_sosi_arr(I).sop OR rx_sosi_arr(I).sop WHEN rising_edge(clk); + END GENERATE; + + gen_green_led_arr : FOR I IN g_nof_qsfp-1 DOWNTO 0 GENERATE + + qsfp_on_arr(I) <= orv(green_on_arr( (I+1)*c_quad-1 DOWNTO + I*c_quad)); + qsfp_evt_arr(I) <= orv(green_evt_arr((I+1)*c_quad-1 DOWNTO + I*c_quad)); + + u_green_led_controller : ENTITY common_lib.common_led_controller + GENERIC MAP ( + g_nof_ms => c_nof_ms + ) + PORT MAP ( + rst => rst, + clk => clk, + pulse_ms => i_pulse_ms, + -- led control + ctrl_on => qsfp_on_arr(I), + ctrl_evt => qsfp_evt_arr(I), + ctrl_input => toggle_s, + -- led output + led => green_led_arr(I) + ); + END GENERATE; + END GENERATE; + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_ring_io.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_ring_io.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2c924997a546d3de8092e6107b80f868482b3617 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_ring_io.vhd @@ -0,0 +1,63 @@ +------------------------------------------------------------------------------ +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE work.unb2_board_pkg.ALL; + + +ENTITY unb2_board_ring_io IS + GENERIC ( + g_nof_ring_bus : NATURAL := c_unb2_board_tr_ring.nof_bus + ); + PORT ( + serial_tx_arr : IN STD_LOGIC_VECTOR(g_nof_ring_bus * c_unb2_board_tr_ring.bus_w-1 DOWNTO 0) := (OTHERS=>'0'); + serial_rx_arr : OUT STD_LOGIC_VECTOR(g_nof_ring_bus * c_unb2_board_tr_ring.bus_w-1 DOWNTO 0); + + RING_RX : IN t_unb2_board_ring_bus_2arr(g_nof_ring_bus-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + RING_TX : OUT t_unb2_board_ring_bus_2arr(g_nof_ring_bus-1 DOWNTO 0) + ); +END unb2_board_ring_io; + +ARCHITECTURE str OF unb2_board_ring_io IS + + -- help signals so we can iterate through buses + SIGNAL si_tx_2arr : t_unb2_board_ring_bus_2arr(g_nof_ring_bus-1 DOWNTO 0); + SIGNAL si_rx_2arr : t_unb2_board_ring_bus_2arr(g_nof_ring_bus-1 DOWNTO 0); + +BEGIN + + gen_buses : FOR i IN 0 TO g_nof_ring_bus-1 GENERATE + RING_TX(i) <= si_tx_2arr(i); + si_rx_2arr(i) <= RING_RX(i); + END GENERATE; + + + gen_wire_bus : FOR i IN 0 TO g_nof_ring_bus-1 GENERATE + gen_wire_signals : FOR j IN 0 TO c_unb2_board_tr_ring.bus_w-1 GENERATE + + si_tx_2arr(i)(j) <= serial_tx_arr(i*c_unb2_board_tr_ring.bus_w + j); + serial_rx_arr(i*c_unb2_board_tr_ring.bus_w + j) <= si_rx_2arr(i)(j); + + END GENERATE; + END GENERATE; + +END; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6ef9b2c0ccd50fbd649779aa295f69409429b47c --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens.vhd @@ -0,0 +1,176 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE i2c_lib.i2c_pkg.ALL; +USE work.unb2_board_pkg.ALL; + +ENTITY unb2_board_sens is + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_i2c_peripheral : NATURAL; + g_clk_freq : NATURAL := 100*10**6; -- clk frequency in Hz + g_temp_high : NATURAL := 85; + g_sens_nof_result : NATURAL; -- Should match nof read bytes via I2C in the unb2_board_sens_ctrl SEQUENCE list + g_comma_w : NATURAL := 0 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + start : IN STD_LOGIC; + -- i2c bus + scl : INOUT STD_LOGIC; + sda : INOUT STD_LOGIC; + -- read results + sens_evt : OUT STD_LOGIC; + sens_err : OUT STD_LOGIC; + sens_data : OUT t_slv_8_arr(0 TO g_sens_nof_result-1) + ); +END ENTITY; + + +ARCHITECTURE str OF unb2_board_sens IS + + -- I2C clock rate settings + CONSTANT c_sens_clk_cnt : NATURAL := sel_a_b(g_sim, 1, func_i2c_calculate_clk_cnt(g_clk_freq/10**6)); -- define I2C clock rate + --CONSTANT c_sens_comma_w : NATURAL := 13; -- 2**c_i2c_comma_w * system clock period comma time after I2C start and after each octet + -- 0 = no comma time + +-- octave:4> t=1/50e6 +-- t = 2.0000e-08 +-- octave:5> delay=2^13 * t +-- delay = 1.6384e-04 +-- octave:6> delay/t +-- ans = 8192 +-- octave:7> log2(ans) +-- ans = 13 +-- octave:8> log2(delay/t) +-- ans = 13 + + + --CONSTANT c_sens_phy : t_c_i2c_phy := (c_sens_clk_cnt, c_sens_comma_w); + CONSTANT c_sens_phy : t_c_i2c_phy := (c_sens_clk_cnt, g_comma_w); + + SIGNAL smbus_in_dat : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + SIGNAL smbus_in_val : STD_LOGIC; + SIGNAL smbus_out_dat : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + SIGNAL smbus_out_val : STD_LOGIC; + SIGNAL smbus_out_err : STD_LOGIC; + SIGNAL smbus_out_ack : STD_LOGIC; + SIGNAL smbus_out_end : STD_LOGIC; + +BEGIN + + gen_unb2_board_sens_ctrl : IF g_i2c_peripheral=c_i2c_peripheral_sens GENERATE + u_unb2_board_sens_ctrl : ENTITY work.unb2_board_sens_ctrl + GENERIC MAP ( + g_sim => g_sim, + g_nof_result => g_sens_nof_result, + g_temp_high => g_temp_high + ) + PORT MAP ( + clk => clk, + rst => rst, + start => start, + in_dat => smbus_out_dat, + in_val => smbus_out_val, + in_err => smbus_out_err, + in_ack => smbus_out_ack, + in_end => smbus_out_end, + out_dat => smbus_in_dat, + out_val => smbus_in_val, + result_val => sens_evt, + result_err => sens_err, + result_dat => sens_data + ); + END GENERATE; + + gen_unb2_board_pmbus_ctrl : IF g_i2c_peripheral=c_i2c_peripheral_pmbus GENERATE + u_unb2_board_pmbus_ctrl : ENTITY work.unb2_board_pmbus_ctrl + GENERIC MAP ( + g_sim => g_sim, + g_nof_result => g_sens_nof_result, + g_temp_high => g_temp_high + ) + PORT MAP ( + clk => clk, + rst => rst, + start => start, + in_dat => smbus_out_dat, + in_val => smbus_out_val, + in_err => smbus_out_err, + in_ack => smbus_out_ack, + in_end => smbus_out_end, + out_dat => smbus_in_dat, + out_val => smbus_in_val, + result_val => sens_evt, + result_err => sens_err, + result_dat => sens_data + ); + END GENERATE; + + gen_unb2_board_hmc_ctrl : IF g_i2c_peripheral=c_i2c_peripheral_hmc GENERATE + u_unb2_board_hmc_ctrl : ENTITY work.unb2_board_hmc_ctrl + GENERIC MAP ( + g_sim => g_sim, + g_nof_result => g_sens_nof_result, + g_temp_high => g_temp_high + ) + PORT MAP ( + clk => clk, + rst => rst, + start => start, + in_dat => smbus_out_dat, + in_val => smbus_out_val, + in_err => smbus_out_err, + in_ack => smbus_out_ack, + in_end => smbus_out_end, + out_dat => smbus_in_dat, + out_val => smbus_in_val, + result_val => sens_evt, + result_err => sens_err, + result_dat => sens_data + ); + END GENERATE; + + u_i2c_smbus : ENTITY i2c_lib.i2c_smbus + GENERIC MAP ( + g_i2c_phy => c_sens_phy, + g_clock_stretch_sense_scl => TRUE + ) + PORT MAP ( + gs_sim => g_sim, + clk => clk, + rst => rst, + in_dat => smbus_in_dat, + in_req => smbus_in_val, + out_dat => smbus_out_dat, + out_val => smbus_out_val, + out_err => smbus_out_err, + out_ack => smbus_out_ack, + st_end => smbus_out_end, + scl => scl, + sda => sda + ); + +END ARCHITECTURE; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_ctrl.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fcaac6c2a37bc42a48a04406b3af61057853699b --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_ctrl.vhd @@ -0,0 +1,208 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE i2c_lib.i2c_smbus_pkg.ALL; +USE i2c_lib.i2c_dev_max1617_pkg.ALL; +USE i2c_lib.i2c_dev_ltc4260_pkg.ALL; +USE i2c_lib.i2c_dev_unb2_pkg.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY unb2_board_sens_ctrl IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_nof_result : NATURAL := 40; + g_temp_high : NATURAL := 85 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + start : IN STD_LOGIC; -- pulse to start the I2C sequence to read out the sensors + out_dat : OUT STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + out_val : OUT STD_LOGIC; + in_dat : IN STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + in_val : IN STD_LOGIC; + in_err : IN STD_LOGIC; + in_ack : IN STD_LOGIC; + in_end : IN STD_LOGIC; + result_val : OUT STD_LOGIC; + result_err : OUT STD_LOGIC; + result_dat : OUT t_slv_8_arr(0 TO g_nof_result-1) + ); +END ENTITY; + + +ARCHITECTURE rtl OF unb2_board_sens_ctrl IS + + -- I2C slave commands of the devices on the I2C bus on UniBoard + CONSTANT TMP451_LOC_HI : NATURAL := 16#00#; + CONSTANT TMP451_LOC_LO : NATURAL := 16#15#; + CONSTANT TMP451_REM_HI : NATURAL := 16#01#; + CONSTANT TMP451_REM_LO : NATURAL := 16#10#; + + CONSTANT CAT24C02_ADR_00 : NATURAL := 16#00#; -- should contain 'H' + CONSTANT CAT24C02_ADR_01 : NATURAL := 16#01#; -- should contain 'a' + CONSTANT CAT24C02_ADR_02 : NATURAL := 16#02#; -- should contain 'r' + CONSTANT CAT24C02_ADR_03 : NATURAL := 16#03#; -- should contain 'r' + CONSTANT CAT24C02_ADR_04 : NATURAL := 16#04#; -- should contain 'o' + + TYPE t_SEQUENCE IS ARRAY (NATURAL RANGE <>) OF NATURAL; + + -- The I2C bit rate is c_i2c_bit_rate = 50 [kbps], so 20 us period. Hence 20 us wait time for SDA is enough + -- Assume clk <= 200 MHz, so 5 ns period. Hence timeout of 4000 is enough. + CONSTANT c_timeout_sda : NATURAL := sel_a_b(g_sim, 0, 16); -- wait 16 * 256 = 4096 clk periods + + CONSTANT c_SEQ : t_SEQUENCE := ( + SMBUS_READ_BYTE , I2C_UNB2_SENS_EEPROM_CAT24C02_ADR, CAT24C02_ADR_00, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_TEMP_TMP451_ADR, TMP451_LOC_HI, + SMBUS_READ_BYTE , I2C_UNB2_SENS_TEMP_TMP451_ADR, TMP451_LOC_LO, + SMBUS_READ_BYTE , I2C_UNB2_SENS_TEMP_TMP451_ADR, TMP451_REM_HI, + SMBUS_READ_BYTE , I2C_UNB2_SENS_TEMP_TMP451_ADR, TMP451_REM_LO, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_QSFP0_BMR464_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP0_BMR464_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP0_BMR464_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP0_BMR464_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_QSFP1_BMR464_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP1_BMR464_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP1_BMR464_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_QSFP1_BMR464_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_CLK_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_SENS_CLK_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_CLK_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_CLK_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_3V3_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_SENS_3V3_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_3V3_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_3V3_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_READ_BYTE , I2C_UNB2_SENS_1V2_BMR461_ADR, PMBUS_REG_READ_VOUT_MODE, + SMBUS_READ_WORD , I2C_UNB2_SENS_1V2_BMR461_ADR, PMBUS_REG_READ_VOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_1V2_BMR461_ADR, PMBUS_REG_READ_IOUT, + SMBUS_READ_WORD , I2C_UNB2_SENS_1V2_BMR461_ADR, PMBUS_REG_READ_TEMP, + + SMBUS_C_SAMPLE_SDA, 0, c_timeout_sda, 0, 0, + SMBUS_C_END, + SMBUS_C_NOP + ); + + CONSTANT c_seq_len : NATURAL := c_SEQ'LENGTH-1; + + -- The protocol list c_SEQ yields a list of result bytes (result_dat) + -- make sure that g_nof_result matches the number of result bytes + + SIGNAL start_reg : STD_LOGIC; + + SIGNAL seq_cnt : NATURAL RANGE 0 TO c_seq_len := c_seq_len; + SIGNAL nxt_seq_cnt : NATURAL; + + SIGNAL rx_cnt : NATURAL RANGE 0 TO g_nof_result; + SIGNAL nxt_rx_cnt : NATURAL; + + SIGNAL rx_val : STD_LOGIC; + SIGNAL nxt_rx_val : STD_LOGIC; + SIGNAL rx_err : STD_LOGIC; + SIGNAL nxt_rx_err : STD_LOGIC; + SIGNAL rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_rx_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_val : STD_LOGIC; + SIGNAL nxt_result_err : STD_LOGIC; + SIGNAL i_result_dat : t_slv_8_arr(result_dat'RANGE); + SIGNAL nxt_result_dat : t_slv_8_arr(result_dat'RANGE); + +BEGIN + + result_dat <= i_result_dat; + + regs: PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + start_reg <= '0'; + seq_cnt <= c_seq_len; + rx_cnt <= 0; + rx_val <= '0'; + rx_err <= '0'; + rx_dat <= (OTHERS=>(OTHERS=>'0')); + result_val <= '0'; + result_err <= '0'; + i_result_dat <= (OTHERS=>(OTHERS=>'0')); + ELSIF rising_edge(clk) THEN + start_reg <= start; + seq_cnt <= nxt_seq_cnt; + rx_cnt <= nxt_rx_cnt; + rx_val <= nxt_rx_val; + rx_err <= nxt_rx_err; + rx_dat <= nxt_rx_dat; + result_val <= nxt_result_val; + result_err <= nxt_result_err; + i_result_dat <= nxt_result_dat; + END IF; + END PROCESS; + + -- Issue the protocol list + p_seq_cnt : PROCESS(seq_cnt, start_reg, in_ack) + BEGIN + nxt_seq_cnt <= seq_cnt; + IF start_reg = '1' THEN + nxt_seq_cnt <= 0; + ELSIF seq_cnt<c_seq_len AND in_ack='1' THEN + nxt_seq_cnt <= seq_cnt + 1; + END IF; + END PROCESS; + + out_dat <= STD_LOGIC_VECTOR(TO_UVEC(c_SEQ(seq_cnt), c_byte_w)); + out_val <= '1' WHEN seq_cnt<c_seq_len ELSE '0'; + + -- Fill the rx_dat byte array + p_rx_dat : PROCESS(start_reg, rx_err, in_err, rx_dat, rx_cnt, in_dat, in_val) + BEGIN + nxt_rx_err <= rx_err; + IF start_reg = '1' THEN + nxt_rx_err <= '0'; + ELSIF in_err='1' THEN + nxt_rx_err <= '1'; + END IF; + + nxt_rx_dat <= rx_dat; + nxt_rx_cnt <= rx_cnt; + IF start_reg = '1' THEN + nxt_rx_dat <= (OTHERS=>(OTHERS=>'0')); + nxt_rx_cnt <= 0; + ELSIF in_val='1' THEN + nxt_rx_dat(rx_cnt) <= in_dat; + nxt_rx_cnt <= rx_cnt + 1; + END IF; + END PROCESS; + + nxt_rx_val <= in_end; + + -- Capture the complete rx_dat byte array + nxt_result_val <= rx_val; + nxt_result_err <= rx_err; + nxt_result_dat <= rx_dat WHEN rx_val='1' ELSE i_result_dat; + +END rtl; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_reg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e38265c892ebbcc6bf09e1ba56aaa5eeef87cdb0 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_sens_reg.vhd @@ -0,0 +1,162 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide MM slave register for unb2_board_sens +-- Description: +-- +-- 31 24 23 16 15 8 7 0 wi +-- |-----------------|-----------------|-----------------|-----------------| +-- | xxx fpga_temp = sens_data[0][7:0]| 0 +-- |-----------------------------------------------------------------------| +-- | xxx eth_temp = sens_data[1][7:0]| 1 +-- |-----------------------------------------------------------------------| +-- | xxx hot_swap_v_sense = sens_data[2][7:0]| 2 +-- |-----------------------------------------------------------------------| +-- | xxx hot_swap_v_source = sens_data[3][7:0]| 3 +-- |-----------------------------------------------------------------------| +-- | xxx sens_err[0]| 4 +-- |-----------------------------------------------------------------------| +-- | xxx temp_high[6:0]| 5 +-- |-----------------------------------------------------------------------| +-- +-- * The fpga_temp and eth_temp are in degrees (two's complement) +-- * The hot swap voltages depend on: +-- . From i2c_dev_ltc4260_pkg: +-- LTC4260_V_UNIT_SENSE = 0.0003 -- 0.3 mV over Rs for current sense +-- LTC4260_V_UNIT_SOURCE = 0.4 -- 400 mV supply voltage (e.g +48 V) +-- LTC4260_V_UNIT_ADIN = 0.01 -- 10 mV ADC +-- +-- . From UniBoard unb_sensors.h: +-- SENS_HOT_SWAP_R_SENSE = 0.005 -- R sense on UniBoard is 5 mOhm (~= 10 mOhm // 10 mOhm) +-- SENS_HOT_SWAP_I_UNIT_SENSE = LTC4260_V_UNIT_SENSE / SENS_HOT_SWAP_R_SENSE +-- SENS_HOT_SWAP_V_UNIT_SOURCE = LTC4260_V_UNIT_SOURCE +-- +-- ==> +-- Via all nodes: +-- 0 = FPGA temperature = TInt8(fpga_temp) +-- Only via node2: +-- 1 = UniBoard ETH PHY temperature = TInt8(eth_temp) +-- 2 = UniBoard hot swap supply current = hot_swap_v_sense * SENS_HOT_SWAP_I_UNIT_SENSE +-- 3 = UniBoard hot swap supply voltage = hot_swap_v_source * SENS_HOT_SWAP_V_UNIT_SOURCE +-- 4 = I2C error status for node2 sensors access only, 0 = ok +-- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY unb2_board_sens_reg IS + GENERIC ( + g_sens_nof_result : NATURAL := 4; + g_temp_high : NATURAL := 85 + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + + -- Memory Mapped Slave in mm_clk domain + sla_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg + sla_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- MM registers + sens_err : IN STD_LOGIC := '0'; + sens_data : IN t_slv_8_arr(0 TO g_sens_nof_result-1); + + -- Max temp output + temp_high : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) + + ); +END unb2_board_sens_reg; + + +ARCHITECTURE rtl OF unb2_board_sens_reg IS + + -- Define the actual size of the MM slave register + CONSTANT c_mm_nof_dat : NATURAL := g_sens_nof_result+1+1; -- +1 to fit user set temp_high one additional address + -- +1 to fit sens_err in the last address + + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => ceil_log2(c_mm_nof_dat), + dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers + nof_dat => c_mm_nof_dat, + init_sl => '0'); + + SIGNAL i_temp_high : STD_LOGIC_VECTOR(6 DOWNTO 0); + +BEGIN + + temp_high <= i_temp_high; + + ------------------------------------------------------------------------------ + -- MM register access in the mm_clk domain + -- . Hardcode the shared MM slave register directly in RTL instead of using + -- the common_reg_r_w instance. Directly using RTL is easier when the large + -- MM register has multiple different fields and with different read and + -- write options per field in one MM register. + ------------------------------------------------------------------------------ + + p_mm_reg : PROCESS (mm_rst, mm_clk) + VARIABLE vA : NATURAL := 0; + BEGIN + IF mm_rst = '1' THEN + -- Read access + sla_out <= c_mem_miso_rst; + -- Write access, register values + i_temp_high <= TO_UVEC(g_temp_high, 7); + + ELSIF rising_edge(mm_clk) THEN + vA := TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)); + + -- Read access defaults + sla_out.rdval <= '0'; + + -- Write access: set register value + IF sla_in.wr = '1' THEN + IF vA = g_sens_nof_result+1 THEN + -- Only change temp_high if user writes a max. 7-bit value. This prevents accidentally + -- setting a negative temp as temp_high, e.g. 128 which becomes -128. + IF UNSIGNED(sla_in.wrdata(c_word_w-1 DOWNTO 7)) = 0 THEN + i_temp_high <= sla_in.wrdata(6 DOWNTO 0); + END IF; + END IF; + + -- Read access: get register value + ELSIF sla_in.rd = '1' THEN + sla_out <= c_mem_miso_rst; -- set unused rddata bits to '0' when read + sla_out.rdval <= '1'; -- c_mm_reg.latency = 1 + + -- no need to capture sens_data, it is not critical if the sens_data happens to be read just before and after an I2C access occurred + IF vA < g_sens_nof_result THEN + sla_out.rddata <= RESIZE_MEM_DATA(sens_data(vA)(c_byte_w-1 DOWNTO 0)); + ELSIF vA = g_sens_nof_result THEN + sla_out.rddata(0) <= sens_err; -- only valid for node2 + ELSE + sla_out.rddata(6 DOWNTO 0) <= i_temp_high; + END IF; + -- else unused addresses read zero + END IF; + END IF; + END PROCESS; + +END rtl; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a2be55ca47eb6b352b5cbee26ae7a584d3b23a6e --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info.vhd @@ -0,0 +1,102 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, technology_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE work.unb2_board_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + +-- Keep the UniBoard system info knowledge in this HDL entity and in the +-- corresponding software functions in unb_common.c,h. This avoids having to +-- define named constants for indexing the fields in the info word. + +ENTITY unb2_board_system_info IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_fw_version : t_unb2_board_fw_version := c_unb2_board_fw_version; -- firmware version x.y (4b.4b) + g_aux : t_c_unb2_board_aux := c_unb2_board_aux; -- aux contains the hardware version + g_rom_version: NATURAL := 1; + g_technology : NATURAL := c_tech_arria10 + ); + PORT ( + clk : IN STD_LOGIC; + hw_version : IN STD_LOGIC_VECTOR(g_aux.version_w-1 DOWNTO 0); + id : IN STD_LOGIC_VECTOR(g_aux.id_w-1 DOWNTO 0); + info : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + bck_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_uniboard_w-1 DOWNTO 0); -- ID[7:2] + chip_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_chip_w-1 DOWNTO 0); -- ID[1:0] + node_id : OUT STD_LOGIC_VECTOR(c_unb2_board_nof_node_w-1 DOWNTO 0); -- ID[1:0] + is_node2 : OUT STD_LOGIC -- '1' for Node 2, else '0'. + ); +END unb2_board_system_info; + + +ARCHITECTURE str OF unb2_board_system_info IS + + SIGNAL cs_sim : STD_LOGIC; + + SIGNAL hw_version_reg : STD_LOGIC_VECTOR(hw_version'RANGE); + SIGNAL id_reg : STD_LOGIC_VECTOR(id'RANGE); + SIGNAL nxt_info : STD_LOGIC_VECTOR(info'RANGE); + + SIGNAL nxt_bck_id : STD_LOGIC_VECTOR(bck_id'RANGE); + SIGNAL nxt_chip_id : STD_LOGIC_VECTOR(chip_id'RANGE); + SIGNAL nxt_node_id : STD_LOGIC_VECTOR(node_id'RANGE); + SIGNAL nxt_is_node2 : STD_LOGIC; + +BEGIN + + p_reg : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + -- inputs + hw_version_reg <= hw_version; + id_reg <= id; + -- output + info <= nxt_info; + bck_id <= nxt_bck_id; + chip_id <= nxt_chip_id; + node_id <= nxt_node_id; + is_node2 <= nxt_is_node2; + END IF; + END PROCESS; + + cs_sim <= is_true(g_sim); + + p_info : PROCESS(cs_sim, hw_version_reg, id_reg) + BEGIN + nxt_info(31 DOWNTO 27) <= TO_UVEC(g_technology, 5); + nxt_info(26 DOWNTO 24) <= TO_UVEC(g_rom_version, 3); + nxt_info(23 DOWNTO 20) <= TO_UVEC(g_fw_version.hi, 4); + nxt_info(19 DOWNTO 16) <= TO_UVEC(g_fw_version.lo, 4); + nxt_info(10) <= cs_sim; + nxt_info(9 DOWNTO 8) <= hw_version_reg; + nxt_info(7 DOWNTO 0) <= id_reg; + END PROCESS; + + nxt_bck_id <= id_reg(7 DOWNTO 2); + nxt_chip_id <= id_reg(1 DOWNTO 0); + nxt_node_id <= id_reg(1 DOWNTO 0); + nxt_is_node2 <= '1' WHEN TO_UINT(id_reg(1 DOWNTO 0)) = 2 ELSE '0'; + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info_reg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..08e9c515ba5ee06a3cbe13078105adcb0c14f806 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_system_info_reg.vhd @@ -0,0 +1,144 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- RO read only (no VHDL present to access HW in write mode) +-- WO write only (no VHDL present to access HW in read mode) +-- WE write event (=WO) +-- WR write control, read control +-- RW read status, write control +-- RC read, clear on read +-- FR FIFO read +-- FW FIFO write +-- +-- wi Bits R/W Name Default Description |REG_UNB2_BOARD_SYSTEM_INFO| +-- ============================================================================= +-- 0 [31..0] RO info +-- 1 [7..0] RO 0 +-- 2 [31..0] RO design_name +-- . .. . .. +-- 9 [31..0] RO design name +-- 10 [31..0] RO date stamp (YYYYMMDD) +-- 11 [31..0] RO time stamp (HHMMSS) +-- 12 [31..0] RO SVN stamp +-- 13 [31..0] RO note +-- . . . .. +-- 20 [31..0] RO note +-- ============================================================================= + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_str_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.unb2_board_pkg.ALL; + +ENTITY unb2_board_system_info_reg IS + GENERIC ( + g_design_name : STRING; + g_stamp_date : NATURAL := 0; + g_stamp_time : NATURAL := 0; + g_stamp_svn : NATURAL := 0; + g_design_note : STRING + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + + -- Memory Mapped Slave + sla_in : IN t_mem_mosi; + sla_out : OUT t_mem_miso; + + info : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) + ); +END unb2_board_system_info_reg; + + +ARCHITECTURE rtl OF unb2_board_system_info_reg IS + + CONSTANT c_nof_fixed_regs : NATURAL := 2; -- info, use_phy + CONSTANT c_nof_design_name_regs : NATURAL := 13; -- design_name + CONSTANT c_nof_stamp_regs : NATURAL := 3; -- date, time, svn rev + CONSTANT c_nof_design_note_regs : NATURAL := 13; -- note + + CONSTANT c_nof_regs : NATURAL := c_nof_fixed_regs + c_nof_design_name_regs + c_nof_stamp_regs + c_nof_design_note_regs; + + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => ceil_log2(c_nof_regs), + dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers + nof_dat => c_nof_regs, + init_sl => '0'); + + CONSTANT c_use_phy_w : NATURAL := 8; + CONSTANT c_use_phy : STD_LOGIC_VECTOR(c_use_phy_w-1 DOWNTO 0) := (OTHERS=> '0'); -- Unused but keep for compatibillity + + CONSTANT c_design_name : t_slv_32_arr(0 TO c_nof_design_name_regs-1) := str_to_ascii_slv_32_arr(g_design_name, c_nof_design_name_regs); + CONSTANT c_design_note : t_slv_32_arr(0 TO c_nof_design_note_regs-1) := str_to_ascii_slv_32_arr(g_design_note, c_nof_design_note_regs); + +BEGIN + + p_mm_reg : PROCESS (mm_rst, mm_clk) + VARIABLE vA : NATURAL := 0; + BEGIN + IF mm_rst = '1' THEN + -- Read access + sla_out <= c_mem_miso_rst; + ELSIF rising_edge(mm_clk) THEN + -- Read access defaults + sla_out.rdval <= '0'; + + -- Read access: get register value + IF sla_in.rd = '1' THEN + sla_out <= c_mem_miso_rst; -- set unused rddata bits to '0' when read + sla_out.rdval <= '1'; -- c_mm_reg.latency = 1 + + vA := TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)); + IF vA = 0 THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= info; + -- Use bit 11 to indicate that we're using the MM bus (not the info SLV). + -- Using the MM bus enables user to also read use_phy, design_name etc. + sla_out.rddata(11) <= '1'; + ELSIF vA = 1 THEN + sla_out.rddata(c_use_phy_w-1 DOWNTO 0) <= c_use_phy; + ELSIF vA < c_nof_fixed_regs + c_nof_design_name_regs THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= c_design_name(vA-c_nof_fixed_regs); + + ELSIF vA = c_nof_fixed_regs + c_nof_design_name_regs THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= TO_UVEC(g_stamp_date, c_word_w); + + ELSIF vA = c_nof_fixed_regs + c_nof_design_name_regs+1 THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= TO_UVEC(g_stamp_time, c_word_w); + + ELSIF vA = c_nof_fixed_regs + c_nof_design_name_regs+2 THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= TO_UVEC(g_stamp_svn, c_word_w); + + ELSIF vA < c_nof_fixed_regs + c_nof_design_name_regs+c_nof_stamp_regs+c_nof_design_note_regs THEN + sla_out.rddata(c_word_w-1 DOWNTO 0) <= c_design_note(vA-c_nof_fixed_regs-c_nof_design_name_regs-c_nof_stamp_regs); + + END IF; + + END IF; + END IF; + END PROCESS; + + +END rtl; + diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_extend.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_extend.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ffc5345b51204581561602c2e42a2cf28f7bece8 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_extend.vhd @@ -0,0 +1,98 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +-- Purpose: +-- Extend the input WDI that is controlled in SW (as it should be) to avoid +-- that the watchdog reset will occur when new SW is loaded, while keeping +-- the HDL image. This component extends the last input WDI by toggling the +-- output WDI for about 2**(g_extend_w-1) ms more. + +ENTITY unb2_board_wdi_extend IS + GENERIC ( + g_extend_w : NATURAL := 14 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + pulse_ms : IN STD_LOGIC; -- pulses every 1 ms + wdi_in : IN STD_LOGIC; + wdi_out : OUT STD_LOGIC + ); +END unb2_board_wdi_extend; + + +ARCHITECTURE str OF unb2_board_wdi_extend IS + + SIGNAL wdi_evt : STD_LOGIC; + + SIGNAL wdi_cnt : STD_LOGIC_VECTOR(g_extend_w-1 DOWNTO 0); + SIGNAL wdi_cnt_en : STD_LOGIC; + + SIGNAL i_wdi_out : STD_LOGIC; + SIGNAL nxt_wdi_out : STD_LOGIC; + +BEGIN + + wdi_out <= i_wdi_out; + + p_clk : PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + i_wdi_out <= '0'; + ELSIF rising_edge(clk) THEN + i_wdi_out <= nxt_wdi_out; + END IF; + END PROCESS; + + wdi_cnt_en <= '1' WHEN pulse_ms='1' AND wdi_cnt(wdi_cnt'HIGH)='0' ELSE '0'; + + nxt_wdi_out <= NOT i_wdi_out WHEN wdi_cnt_en='1' ELSE i_wdi_out; + + u_common_evt : ENTITY common_lib.common_evt + GENERIC MAP ( + g_evt_type => "BOTH", + g_out_reg => TRUE + ) + PORT MAP ( + rst => rst, + clk => clk, + in_sig => wdi_in, + out_evt => wdi_evt + ); + + u_common_counter : ENTITY common_lib.common_counter + GENERIC MAP ( + g_width => g_extend_w + ) + PORT MAP ( + rst => rst, + clk => clk, + cnt_clr => wdi_evt, + cnt_en => wdi_cnt_en, + count => wdi_cnt + ); + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_reg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..42a42742a54008100adefd7cc0b25a5df68ba5fa --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_board_wdi_reg.vhd @@ -0,0 +1,90 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: +-- Manually override WDI to initiate reconfiguratioon of the FPGA. +-- Write 0xB007FAC7 to address 0x0. + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY unb2_board_wdi_reg IS + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + + -- Memory Mapped Slave in mm_clk domain + sla_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg + sla_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- MM registers in st_clk domain + wdi_override : OUT STD_LOGIC + ); +END unb2_board_wdi_reg; + + +ARCHITECTURE rtl OF unb2_board_wdi_reg IS + + -- Define the actual size of the MM slave register + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => ceil_log2(1), + dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers + nof_dat => 1, + init_sl => '0'); + + -- For safety, WDI override requires the following word to be written: + CONSTANT c_cmd_reconfigure : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0 ) := x"B007FAC7"; -- "Boot factory" + +BEGIN + + p_mm_reg : PROCESS (mm_rst, mm_clk) + BEGIN + IF mm_rst = '1' THEN + -- Read access + sla_out <= c_mem_miso_rst; + -- Write access, register values + wdi_override <= '0'; + ELSIF rising_edge(mm_clk) THEN + -- Read access defaults: unused + sla_out <= c_mem_miso_rst; + + -- Write access: set register value + IF sla_in.wr = '1' THEN + CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + -- Write Block Sync + WHEN 0 => + IF sla_in.wrdata(c_word_w-1 DOWNTO 0) = c_cmd_reconfigure THEN + wdi_override <= '1'; + ELSE + wdi_override <= '0'; + END IF; + WHEN OTHERS => NULL; -- unused MM addresses + END CASE; + END IF; + + END IF; + END PROCESS; + +END rtl; + diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_fpga_sens_reg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_fpga_sens_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..eb233b1ac5546e80db457f343112f05d94548181 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2_fpga_sens_reg.vhd @@ -0,0 +1,89 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012-2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide MM slave register for unb2_fpga_sens +-- + +LIBRARY IEEE, common_lib, technology_lib, fpga_sense_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + + +ENTITY unb2_fpga_sens_reg IS + GENERIC ( + g_sim : BOOLEAN; + g_technology : NATURAL := c_tech_arria10; + g_sens_nof_result : NATURAL := 1; + g_temp_high : NATURAL := 85 + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + start : IN STD_LOGIC; + + -- Memory Mapped Slave in mm_clk domain + sla_temp_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg + sla_temp_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + sla_voltage_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg + sla_voltage_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- MM registers + --sens_err : IN STD_LOGIC := '0'; + --sens_data : IN t_slv_8_arr(0 TO g_sens_nof_result-1); -- FIXME should be OUT + + -- Max temp output + temp_high : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) + ); +END unb2_fpga_sens_reg; + + +ARCHITECTURE str OF unb2_fpga_sens_reg IS + + --SIGNAL i_temp_high : STD_LOGIC_VECTOR(6 DOWNTO 0); + +BEGIN + + temp_high <= (others => '0'); --i_temp_high; + + u_fpga_sense: ENTITY fpga_sense_lib.fpga_sense + GENERIC MAP ( + g_technology => g_technology, + g_sim => g_sim + ) + PORT MAP ( + mm_clk => mm_clk, + mm_rst => mm_rst, + + start_sense => start, + + reg_temp_mosi => sla_temp_in, + reg_temp_miso => sla_temp_out, + + reg_voltage_store_mosi => sla_voltage_in, + reg_voltage_store_miso => sla_voltage_out + ); + +END str; diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_mms_unb2_board_sens.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_mms_unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8d4444e6ec52404e78df2d8a4af7000658e82be4 --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_mms_unb2_board_sens.vhd @@ -0,0 +1,215 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Test bench for mms_unb2_board_sens +-- +-- Features: +-- . Verify that the UniBoard sensors are read. +-- +-- Usage: +-- . > as 10 +-- . > run -all + +ENTITY tb_mms_unb2_board_sens IS +END tb_mms_unb2_board_sens; + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE common_lib.tb_common_mem_pkg.ALL; +USE work.unb2_board_pkg.ALL; + +ARCHITECTURE tb OF tb_mms_unb2_board_sens IS + + CONSTANT c_sim : BOOLEAN := TRUE; --FALSE; + CONSTANT c_repeat : NATURAL := 2; + CONSTANT c_clk_freq : NATURAL := 100*10**6; + CONSTANT c_clk_period : TIME := (10**9/c_clk_freq) * 1 ns; + CONSTANT c_rst_period : TIME := 4 * c_clk_period; + + -- Model I2C sensor slaves as on the UniBoard + CONSTANT c_temp_high : NATURAL := 85; + CONSTANT c_fpga_temp_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "0011000"; -- MAX1618 address LOW LOW + CONSTANT c_fpga_temp : INTEGER := 60; + CONSTANT c_eth_temp_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "0101001"; -- MAX1618 address MID LOW + CONSTANT c_eth_temp : INTEGER := 40; + CONSTANT c_hot_swap_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "1000100"; -- LTC4260 address L L L + CONSTANT c_hot_swap_R_sense : REAL := 0.01; -- = 10 mOhm on UniBoard + + CONSTANT c_uniboard_current : REAL := 5.0; -- = assume 5.0 A on UniBoard --> hot swap = 5010 mAmpere (167) + CONSTANT c_uniboard_supply : REAL := 48.0; -- = assume 48.0 V on UniBoard --> hot swap = 48000 mVolt (120) + CONSTANT c_uniboard_adin : REAL := -1.0; -- = NC on UniBoard + + CONSTANT c_sens_nof_result : NATURAL := 4 + 1; + CONSTANT c_sens_expected : t_natural_arr(0 TO c_sens_nof_result-1) := (60, 40, 167, 120, 0); -- 4 bytes as read by c_SEQ in unb2_board_sens_ctrl + sens_err + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL clk : STD_LOGIC := '0'; + SIGNAL rst : STD_LOGIC := '1'; + SIGNAL start : STD_LOGIC; + + SIGNAL reg_mosi : t_mem_mosi := c_mem_mosi_rst; + SIGNAL reg_miso : t_mem_miso; + + SIGNAL sens_val : STD_LOGIC; + SIGNAL sens_dat : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + + SIGNAL scl_stretch : STD_LOGIC := 'Z'; + SIGNAL scl : STD_LOGIC; + SIGNAL sda : STD_LOGIC; + +BEGIN + + rst <= '0' AFTER 4*c_clk_period; + clk <= (NOT clk) OR tb_end AFTER c_clk_period/2; + + -- I2C bus + scl <= 'H'; -- model I2C pull up + sda <= 'H'; -- model I2C pull up, use '0' and '1' to verify sens_err + + scl <= scl_stretch; + + sens_clk_stretch : PROCESS (scl) + BEGIN + IF falling_edge(scl) THEN + scl_stretch <= '0', 'Z' AFTER 50 ns; -- < 10 ns to effectively disable stretching, >= 50 ns to enable it + END IF; + END PROCESS; + + p_mm_reg_stimuli : PROCESS + VARIABLE v_bsn : NATURAL; + VARIABLE vI : NATURAL; + VARIABLE vJ : NATURAL; + BEGIN + start <= '0'; + reg_mosi <= c_mem_mosi_rst; + + proc_common_wait_until_low(clk, rst); + proc_common_wait_some_cycles(clk, 10); + + FOR I IN 0 TO c_repeat-1 LOOP + -- start I2C access + start <= '1'; + proc_common_wait_some_cycles(clk, 1); + start <= '0'; + + -- wait for I2C access to have finished + proc_common_wait_some_cycles(clk, sel_a_b(c_sim, 5000, 500000)); + + -- read I2C result data + FOR I IN 0 TO c_sens_nof_result-1 LOOP + proc_mem_mm_bus_rd(I, clk, reg_miso, reg_mosi); -- read sens_data + END LOOP; + + proc_common_wait_some_cycles(clk, 1000); + END LOOP; + + proc_common_wait_some_cycles(clk, 100); + tb_end <= '1'; + WAIT; + END PROCESS; + + sens_val <= reg_miso.rdval; + sens_dat <= reg_miso.rddata(c_byte_w-1 DOWNTO 0); + + -- Verify sensor data + p_verify : PROCESS + BEGIN + WAIT UNTIL rising_edge(clk); -- Added this line to avoid warning: (vcom-1090) Possible infinite loop: Process contains no WAIT statement. + + proc_common_wait_until_high(clk, sens_val); + ASSERT TO_UINT(sens_dat)=c_sens_expected(0) REPORT "Wrong FPGA temperature value" SEVERITY ERROR; + proc_common_wait_some_cycles(clk, 1); + ASSERT TO_UINT(sens_dat)=c_sens_expected(1) REPORT "Wrong ETH temperature value" SEVERITY ERROR; + proc_common_wait_some_cycles(clk, 1); + ASSERT TO_UINT(sens_dat)=c_sens_expected(2) REPORT "Wrong hot swap V sense value" SEVERITY ERROR; + proc_common_wait_some_cycles(clk, 1); + ASSERT TO_UINT(sens_dat)=c_sens_expected(3) REPORT "Wrong hot swap V source value" SEVERITY ERROR; + proc_common_wait_some_cycles(clk, 1); + ASSERT TO_UINT(sens_dat)=c_sens_expected(4) REPORT "An I2C error occurred" SEVERITY ERROR; + + END PROCESS; + + + -- I2C sensors master + u_mms_unb2_board_sens : ENTITY work.mms_unb2_board_sens + GENERIC MAP ( + g_sim => c_sim, + g_i2c_peripheral => c_i2c_peripheral_sens, + g_sens_nof_result => 40, + g_clk_freq => c_clk_freq, + g_temp_high => c_temp_high, + g_comma_w => 13 + ) + PORT MAP ( + -- Clocks and reset + mm_rst => rst, + mm_clk => clk, + mm_start => start, + + -- Memory-mapped clock domain + reg_mosi => reg_mosi, + reg_miso => reg_miso, + + -- i2c bus + scl => scl, + sda => sda + ); + + -- I2C slaves that are available for each FPGA + u_fpga_temp : ENTITY i2c_lib.dev_max1618 + GENERIC MAP ( + g_address => c_fpga_temp_address + ) + PORT MAP ( + scl => scl, + sda => sda, + temp => c_fpga_temp + ); + + -- I2C slaves that are available only via FPGA node 3 + u_eth_temp : ENTITY i2c_lib.dev_max1618 + GENERIC MAP ( + g_address => c_eth_temp_address + ) + PORT MAP ( + scl => scl, + sda => sda, + temp => c_eth_temp + ); + + u_power : ENTITY i2c_lib.dev_ltc4260 + GENERIC MAP ( + g_address => c_hot_swap_address, + g_R_sense => c_hot_swap_R_sense + ) + PORT MAP ( + scl => scl, + sda => sda, + ana_current_sense => c_uniboard_current, + ana_volt_source => c_uniboard_supply, + ana_volt_adin => c_uniboard_adin + ); + +END tb; + diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk125_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk125_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..13f29d91913a0a613615e253ad05da073e3e694c --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk125_pll.vhd @@ -0,0 +1,71 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + + +-- Purpose: Simulate phase behaviour of PLL in normal mode +-- Description: +-- Usage: +-- > as 3 +-- > run -all + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY tb_unb2_board_clk125_pll IS +END tb_unb2_board_clk125_pll; + + +ARCHITECTURE tb OF tb_unb2_board_clk125_pll IS + + CONSTANT c_ext_clk_period : TIME := 8 ns; -- 125 MHz + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL ext_clk : STD_LOGIC := '0'; + SIGNAL ext_rst : STD_LOGIC; + SIGNAL c0_clk20 : STD_LOGIC; + SIGNAL c1_clk50 : STD_LOGIC; + SIGNAL c2_clk100 : STD_LOGIC; + SIGNAL c3_clk125 : STD_LOGIC; + SIGNAL pll_locked : STD_LOGIC; + +BEGIN + + tb_end <= '0', '1' AFTER c_ext_clk_period*5000; + + ext_clk <= NOT ext_clk OR tb_end AFTER c_ext_clk_period/2; + ext_rst <= '1', '0' AFTER c_ext_clk_period*7; + + dut_0 : ENTITY work.unb2_board_clk125_pll + PORT MAP ( + arst => ext_rst, + clk125 => ext_clk, + + c0_clk20 => c0_clk20, + c1_clk50 => c1_clk50, + c2_clk100 => c2_clk100, + c3_clk125 => c3_clk125, + + pll_locked => pll_locked + ); +END tb; diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a2e442c17a96dc1432cee7897a8e1f79917bea4d --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd @@ -0,0 +1,116 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + + +-- Purpose: Simulate phase behaviour of PLL in normal mode +-- Description: +-- Usage: +-- > as 3 +-- > run -all + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY tb_unb2_board_clk200_pll IS +END tb_unb2_board_clk200_pll; + + +ARCHITECTURE tb OF tb_unb2_board_clk200_pll IS + + CONSTANT c_ext_clk_period : TIME := 5 ns; -- 200 MHz + CONSTANT c_clk_vec_w : NATURAL := 6; + CONSTANT c_clk_div : NATURAL := 32; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL ext_clk : STD_LOGIC := '0'; + SIGNAL ext_rst : STD_LOGIC; + + SIGNAL st_clk200_0 : STD_LOGIC; + SIGNAL st_rst200_0 : STD_LOGIC; + + SIGNAL st_clk200p0 : STD_LOGIC; + SIGNAL st_rst200p0 : STD_LOGIC; + + SIGNAL st_clk200_45 : STD_LOGIC; + SIGNAL st_rst200_45 : STD_LOGIC; + + SIGNAL st_clk200p45 : STD_LOGIC; + SIGNAL st_rst200p45 : STD_LOGIC; + + SIGNAL st_clk400 : STD_LOGIC; + SIGNAL st_rst400 : STD_LOGIC; + + SIGNAL dp_clk200 : STD_LOGIC; + SIGNAL dp_rst200 : STD_LOGIC; + +BEGIN + + tb_end <= '0', '1' AFTER c_ext_clk_period*5000; + + ext_clk <= NOT ext_clk OR tb_end AFTER c_ext_clk_period/2; + ext_rst <= '1', '0' AFTER c_ext_clk_period*7; + + dut_0 : ENTITY work.unb2_board_clk200_pll + GENERIC MAP ( + g_clk200_phase_shift => "0" + ) + PORT MAP ( + arst => ext_rst, + clk200 => ext_clk, + st_clk200 => st_clk200_0, + st_rst200 => st_rst200_0, + st_clk200p => st_clk200p0, + st_rst200p => st_rst200p0, + st_clk400 => st_clk400, + st_rst400 => st_rst400 + ); + + dut_45 : ENTITY work.unb2_board_clk200_pll + GENERIC MAP ( + g_clk200_phase_shift => "625", + g_clk200p_phase_shift => "625" + ) + PORT MAP ( + arst => ext_rst, + clk200 => ext_clk, + st_clk200 => st_clk200_45, + st_rst200 => st_rst200_45, + st_clk200p => st_clk200p45, + st_rst200p => st_rst200p45, + st_clk400 => OPEN, + st_rst400 => OPEN + ); + + dut_p6 : ENTITY work.unb2_board_clk200_pll + GENERIC MAP ( + g_clk200_phase_shift => "0" + ) + PORT MAP ( + arst => ext_rst, + clk200 => ext_clk, + st_clk200 => dp_clk200, + st_rst200 => dp_rst200 + ); + +END tb; diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk25_pll.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk25_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..cbd3d0290147c376a450c5b718e38c57f8d652db --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_clk25_pll.vhd @@ -0,0 +1,71 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + + +-- Purpose: Simulate phase behaviour of PLL in normal mode +-- Description: +-- Usage: +-- > as 3 +-- > run -all + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY tb_unb2_board_clk25_pll IS +END tb_unb2_board_clk25_pll; + + +ARCHITECTURE tb OF tb_unb2_board_clk25_pll IS + + CONSTANT c_ext_clk_period : TIME := 40 ns; -- 25 MHz + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL ext_clk : STD_LOGIC := '0'; + SIGNAL ext_rst : STD_LOGIC; + SIGNAL c0_clk20 : STD_LOGIC; + SIGNAL c1_clk50 : STD_LOGIC; + SIGNAL c2_clk100 : STD_LOGIC; + SIGNAL c3_clk125 : STD_LOGIC; + SIGNAL pll_locked : STD_LOGIC; + +BEGIN + + tb_end <= '0', '1' AFTER c_ext_clk_period*5000; + + ext_clk <= NOT ext_clk OR tb_end AFTER c_ext_clk_period/2; + ext_rst <= '1', '0' AFTER c_ext_clk_period*7; + + dut_0 : ENTITY work.unb2_board_clk25_pll + PORT MAP ( + arst => ext_rst, + clk25 => ext_clk, + + c0_clk20 => c0_clk20, + c1_clk50 => c1_clk50, + c2_clk100 => c2_clk100, + c3_clk125 => c3_clk125, + + pll_locked => pll_locked + ); +END tb; diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a5dbd064dc9a2edc29f28336cfbba3bc4270b09c --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd @@ -0,0 +1,99 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + + +ENTITY tb_unb2_board_node_ctrl IS +END tb_unb2_board_node_ctrl; + + +ARCHITECTURE tb OF tb_unb2_board_node_ctrl IS + + CONSTANT c_scale : NATURAL := 100; -- scale to speed up simulation + + CONSTANT c_xo_clk_period : TIME := 1 us; -- 1 MHz XO, slow XO to speed up simulation + CONSTANT c_mm_clk_period : TIME := c_xo_clk_period/5; -- 5 MHz PLL output from XO reference + CONSTANT c_mm_locked_time : TIME := 10 us; + + CONSTANT c_pulse_us : NATURAL := 5; -- nof 5 MHz clk cycles to get us period + CONSTANT c_pulse_ms : NATURAL := 1000/c_scale; -- nof pulse_us pulses to get ms period + CONSTANT c_pulse_s : NATURAL := 1000; -- nof pulse_ms pulses to get s period + + CONSTANT c_wdi_extend_w : NATURAL := 14; -- extend wdi by about 2**(14-1)= 8 s (as defined by c_pulse_ms) + CONSTANT c_wdi_period : TIME := 1000 ms; -- wdi toggle after c_wdi_period + + -- Use c_sw_period=40000 ms to show that the c_wdi_extend_w=5 is not enough, the WD will kick in when the sw is off during reload + CONSTANT c_sw_period : TIME := 40000 ms; -- sw active for c_sw_period then inactive during reload for c_sw_period, etc. + -- Use c_sw_period=10000 ms to show that the c_wdi_extend_w=5 is enough, the WD will not kick in when the sw is off during reload + --CONSTANT c_sw_period : TIME := 6000 ms; -- sw active for c_sw_period then inactive during reload for c_sw_period, etc. + + SIGNAL mm_clk : STD_LOGIC := '0'; + SIGNAL mm_locked : STD_LOGIC := '0'; + SIGNAL mm_rst : STD_LOGIC; + + SIGNAL wdi : STD_LOGIC := '0'; + SIGNAL wdi_in : STD_LOGIC; + SIGNAL wdi_out : STD_LOGIC; + + SIGNAL sw : STD_LOGIC := '0'; + + SIGNAL pulse_us : STD_LOGIC; + SIGNAL pulse_ms : STD_LOGIC; + SIGNAL pulse_s : STD_LOGIC; + +BEGIN + + -- run 2000 ms + + mm_clk <= NOT mm_clk AFTER c_mm_clk_period/2; + mm_locked <= '0', '1' AFTER c_mm_locked_time; + + wdi <= NOT wdi AFTER c_wdi_period/c_scale; -- wd interrupt + sw <= NOT sw AFTER c_sw_period/c_scale; -- sw active / reload + + wdi_in <= wdi AND sw; -- sw wdi only when sw is active, during sw inactive the wdi_out will be extended + + dut : ENTITY work.unb2_board_node_ctrl + GENERIC MAP ( + g_pulse_us => c_pulse_us, + g_pulse_ms => c_pulse_ms, + g_pulse_s => c_pulse_s, + g_wdi_extend_w => c_wdi_extend_w + ) + PORT MAP ( + -- MM clock domain reset + mm_clk => mm_clk, + mm_locked => mm_locked, + mm_rst => mm_rst, + -- WDI extend + mm_wdi_in => wdi_in, + mm_wdi_out => wdi_out, + -- Pulses + mm_pulse_us => pulse_us, + mm_pulse_ms => pulse_ms, + mm_pulse_s => pulse_s + ); + +END tb; diff --git a/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_qsfp_leds.vhd b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_qsfp_leds.vhd new file mode 100644 index 0000000000000000000000000000000000000000..06f7e52d03b4c4be727e5f18049b20f9778e2ebd --- /dev/null +++ b/boards/uniboard2b/libraries/unb2b_board/tb/vhdl/tb_unb2_board_qsfp_leds.vhd @@ -0,0 +1,190 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Test bench for unb2_board_qsfp_leds +-- Description: +-- The test bench is self-stopping but not self-checking. Manually obeserve +-- in the wave window that: +-- 1) factory image: +-- - green led is off +-- - red led toggles +-- 2) user image +-- - red led is off +-- - green led toggles when any xon='0' +-- - green led is on continously when any xon='1' +-- - green led goes briefly off when any sop='1' +-- Usage: +-- > as 3 +-- > run -a + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +ENTITY tb_unb2_board_qsfp_leds IS +END tb_unb2_board_qsfp_leds; + +ARCHITECTURE tb OF tb_unb2_board_qsfp_leds IS + + CONSTANT c_clk_freq_hz : NATURAL := 200 * 10**6; + CONSTANT c_clk_period_ns : NATURAL := 10**9 / c_clk_freq_hz; + CONSTANT c_nof_clk_per_us : NATURAL := 1000 / c_clk_period_ns; + + CONSTANT clk_period : TIME := c_clk_period_ns * 1 ns; + + CONSTANT c_nof_qsfp : NATURAL := 2; + CONSTANT c_nof_lanes : NATURAL := c_nof_qsfp*c_quad; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL rst : STD_LOGIC; + SIGNAL clk : STD_LOGIC := '0'; + SIGNAL pulse_us : STD_LOGIC; + SIGNAL pulse_ms : STD_LOGIC; + SIGNAL pulse_s : STD_LOGIC; + + SIGNAL tx_siso_arr : t_dp_siso_arr(c_nof_lanes-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rst); + SIGNAL tx_sosi_arr : t_dp_sosi_arr(c_nof_lanes-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + SIGNAL rx_sosi_arr : t_dp_sosi_arr(c_nof_lanes-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + + SIGNAL dbg_xon_arr : STD_LOGIC_VECTOR(c_nof_lanes-1 DOWNTO 0); + SIGNAL dbg_tx_sop_arr : STD_LOGIC_VECTOR(c_nof_lanes-1 DOWNTO 0); + SIGNAL dbg_rx_sop_arr : STD_LOGIC_VECTOR(c_nof_lanes-1 DOWNTO 0); + + SIGNAL factory_green_led_arr : STD_LOGIC_VECTOR(c_nof_qsfp-1 DOWNTO 0); + SIGNAL factory_red_led_arr : STD_LOGIC_VECTOR(c_nof_qsfp-1 DOWNTO 0); + + SIGNAL user_green_led_arr : STD_LOGIC_VECTOR(c_nof_qsfp-1 DOWNTO 0); + SIGNAL user_red_led_arr : STD_LOGIC_VECTOR(c_nof_qsfp-1 DOWNTO 0); + + -- Cannot use proc_common_gen_pulse() to create sop in array. + -- proc_common_gen_pulse() works for dbg_sop, dbg_sosi.sop but not for dbg_sop_slv(I) or for tx_sosi_arr(I).sop. + -- The compiler then gives Error: "(vcom-1450) Actual (indexed name) for formal "pulse" is not a static signal name" + -- It does work if the array index is from a GENERATE statement, but it does not work when it is from a LOOP statement. + SIGNAL dbg_sop : STD_LOGIC; + SIGNAL dbg_sop_slv : STD_LOGIC_VECTOR(c_nof_lanes-1 DOWNTO 0); + SIGNAL dbg_sosi : t_dp_sosi; + +BEGIN + + clk <= NOT clk OR tb_end AFTER clk_period/2; + rst <= '1', '0' AFTER clk_period*7; + + -- Ease observation of record fields in Wave window, by mapping them to a SLV + dbg_xon_arr <= func_dp_stream_arr_get(tx_siso_arr, "XON"); + dbg_tx_sop_arr <= func_dp_stream_arr_get(tx_sosi_arr, "SOP"); + dbg_rx_sop_arr <= func_dp_stream_arr_get(rx_sosi_arr, "SOP"); + + p_stimuli : PROCESS + BEGIN + tx_siso_arr <= (OTHERS=>c_dp_siso_rst); + tx_sosi_arr <= (OTHERS=>c_dp_sosi_rst); + rx_sosi_arr <= (OTHERS=>c_dp_sosi_rst); + proc_common_wait_some_pulses(clk, pulse_ms, 50); + + -- Switch on each lane + FOR I IN 0 TO c_nof_lanes-1 LOOP + tx_siso_arr(I).xon <= '1'; + proc_common_wait_some_pulses(clk, pulse_ms, 10); + END LOOP; + proc_common_wait_some_pulses(clk, pulse_ms, 50); + + -- Issue the sop of a Tx packet on each lane + FOR I IN 0 TO c_nof_lanes-1 LOOP + -- Cannot use proc_common_gen_pulse(), because index I in a LOOP is not static + tx_sosi_arr(I).sop <= '1'; + WAIT UNTIL rising_edge(clk); + tx_sosi_arr(I).sop <= '0'; + proc_common_wait_some_pulses(clk, pulse_ms, 10); + END LOOP; + proc_common_wait_some_pulses(clk, pulse_ms, 50); + + -- Issue the sop of an Rx packet on each lane + FOR I IN 0 TO c_nof_lanes-1 LOOP + -- Cannot use proc_common_gen_pulse(), because index I in a LOOP is not static + rx_sosi_arr(I).sop <= '1'; + WAIT UNTIL rising_edge(clk); + rx_sosi_arr(I).sop <= '0'; + proc_common_wait_some_pulses(clk, pulse_ms, 10); + END LOOP; + proc_common_wait_some_pulses(clk, pulse_ms, 50); + + -- Switch off each lane + FOR I IN 0 TO c_nof_lanes-1 LOOP + tx_siso_arr(I).xon <= '0'; + proc_common_wait_some_pulses(clk, pulse_ms, 10); + END LOOP; + proc_common_wait_some_pulses(clk, pulse_ms, 50); + + tb_end <= '1'; + proc_common_wait_some_pulses(clk, pulse_ms, 10); + WAIT; + END PROCESS; + + u_unb2_factory_qsfp_leds : ENTITY work.unb2_board_qsfp_leds + GENERIC MAP ( + g_sim => TRUE, -- when true speed up led toggling in simulation + g_factory_image => TRUE, -- distinguish factory image and user images + g_nof_qsfp => c_nof_qsfp, -- number of QSFP cages each with one dual led that can light red or green (or amber = red + green) + g_pulse_us => c_nof_clk_per_us -- nof clk cycles to get us period + ) + PORT MAP ( + rst => rst, + clk => clk, + -- internal pulser outputs + pulse_us => pulse_us, + pulse_ms => pulse_ms, + pulse_s => pulse_s, + -- lane status + tx_siso_arr => tx_siso_arr, + tx_sosi_arr => tx_sosi_arr, + rx_sosi_arr => rx_sosi_arr, + -- leds + green_led_arr => factory_green_led_arr, + red_led_arr => factory_red_led_arr + ); + + u_unb2_user_qsfp_leds : ENTITY work.unb2_board_qsfp_leds + GENERIC MAP ( + g_sim => TRUE, -- when true speed up led toggling in simulation + g_factory_image => FALSE, -- distinguish factory image and user images + g_nof_qsfp => c_nof_qsfp, -- number of QSFP cages each with one dual led that can light red or green (or amber = red + green) + g_pulse_us => c_nof_clk_per_us -- nof clk cycles to get us period + ) + PORT MAP ( + rst => rst, + clk => clk, + -- internal pulser outputs + pulse_us => pulse_us, + pulse_ms => pulse_ms, + pulse_s => pulse_s, + -- lane status + tx_siso_arr => tx_siso_arr, + tx_sosi_arr => tx_sosi_arr, + rx_sosi_arr => rx_sosi_arr, + -- leds + green_led_arr => user_green_led_arr, + red_led_arr => user_red_led_arr + ); + +END tb;