diff --git a/boards/uniboard2/libraries/unb2_board/hdllib.cfg b/boards/uniboard2/libraries/unb2_board/hdllib.cfg index 4a749f839d577404a3d04df185762b6d57f6e368..b8206d185fcf50f7cf21ae47e31e076e841bc726 100644 --- a/boards/uniboard2/libraries/unb2_board/hdllib.cfg +++ b/boards/uniboard2/libraries/unb2_board/hdllib.cfg @@ -8,25 +8,25 @@ build_dir_synth = $HDL_BUILD_DIR synth_files = src/vhdl/unb2_board_pkg.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_system_info.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_system_info_reg.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/mms_unb1_board_system_info.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_clk_rst.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_clk200_pll.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_pulser.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_wdi_extend.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_node_ctrl.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_sens_ctrl.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_sens.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_sens_reg.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/mms_unb1_board_sens.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb1_board_wdi_reg.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/src/vhdl/unb2_board_peripherals_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_clk_rst.vhd + src/vhdl/unb2_board_clk200_pll.vhd + src/vhdl/unb2_board_pulser.vhd + src/vhdl/unb2_board_wdi_extend.vhd + src/vhdl/unb2_board_node_ctrl.vhd + src/vhdl/unb2_board_sens_ctrl.vhd + src/vhdl/unb2_board_sens.vhd + src/vhdl/unb2_board_sens_reg.vhd + src/vhdl/mms_unb2_board_sens.vhd + src/vhdl/unb2_board_wdi_reg.vhd src/vhdl/ctrl_unb2_board.vhd + src/vhdl/unb2_board_peripherals_pkg.vhd test_bench_files = - $RADIOHDL/boards/uniboard1/libraries/unb1_board/tb/vhdl/tb_mms_unb1_board_sens.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/tb/vhdl/tb_unb1_board_clk200_pll.vhd - $RADIOHDL/boards/uniboard1/libraries/unb1_board/tb/vhdl/tb_unb1_board_node_ctrl.vhd + tb/vhdl/tb_mms_unb2_board_sens.vhd + tb/vhdl/tb_unb2_board_clk200_pll.vhd + tb/vhdl/tb_unb2_board_node_ctrl.vhd diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_sens.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..260f43faffca16ffa2c2158b6176dc52ce229abe --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_sens.vhd @@ -0,0 +1,118 @@ +------------------------------------------------------------------------------- +-- +-- 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 : MMS for unb1_board_sens +-- Description: See unb1_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_unb1_board_sens IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_clk_freq : NATURAL := 100*10**6; -- clk frequency in Hz + 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_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 := '0'; + sda : INOUT STD_LOGIC := '0'; + + -- Temperature alarm output + temp_alarm : OUT STD_LOGIC + ); +END mms_unb1_board_sens; + + +ARCHITECTURE str OF mms_unb1_board_sens IS + + CONSTANT c_sens_nof_result : NATURAL := 4; -- Should match nof read bytes via I2C in the unb1_board_sens_ctrl SEQUENCE list + 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_unb1_board_sens_reg : ENTITY work.unb1_board_sens_reg + GENERIC MAP ( + 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, + + -- 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 BN3 and all nodes implies that sens_err is only valid for BN3. + sens_data => sens_data, + + -- Max temp threshold + temp_high => temp_high + ); + + u_unb1_board_sens : ENTITY work.unb1_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 <= '1' WHEN (SIGNED(sens_data(0)) > SIGNED('0' & temp_high)) ELSE '0'; + +END str; + diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_system_info.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_system_info.vhd new file mode 100644 index 0000000000000000000000000000000000000000..aa1b4d69c46d3a907720ce67f8af8485c4f686cd --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/mms_unb2_board_system_info.vhd @@ -0,0 +1,137 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.unb1_board_pkg.ALL; + +ENTITY mms_unb1_board_system_info IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_design_name : STRING; + g_use_phy : t_c_unb1_board_use_phy; + g_fw_version : t_unb1_board_fw_version := c_unb1_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_aux : t_c_unb1_board_aux := c_unb1_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_unb1_board_nof_chip_w-1 DOWNTO 0); + bck_id : OUT STD_LOGIC_VECTOR(c_unb1_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_unb1_board_system_info; + + +ARCHITECTURE str OF mms_unb1_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_unb1_board_system_info: ENTITY work.unb1_board_system_info + GENERIC MAP ( + g_sim => g_sim, + g_fw_version => g_fw_version + ) + PORT MAP ( + clk => mm_clk, + hw_version => hw_version, + id => id, + info => i_info, + chip_id => chip_id, + bck_id => bck_id + ); + + u_unb1_board_system_info_reg: ENTITY work.unb1_board_system_info_reg + GENERIC MAP ( + g_design_name => g_design_name, + g_use_phy => g_use_phy, + 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_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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk200_pll.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk200_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..7db080bc1c26015a6012bdc935d3b7306ef2b0ac --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk200_pll.vhd @@ -0,0 +1,263 @@ +------------------------------------------------------------------------------- +-- +-- 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, 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 @ 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_unb1_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 unb1_board_clk200_pll IS + GENERIC ( + g_technology : NATURAL := c_tech_stratixiv; + g_sel : NATURAL := 0; + g_operation_mode : STRING := "NORMAL"; -- "NORMAL", "NO_COMPENSATION", or "SOURCE_SYNCHRONOUS" --> requires PLL_COMPENSATE assignment to an input pin to compensate for (stratixiv) + + -- g_sel=0 for clk200_pll.vhd + 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 + + -- g_sel=1 for clk200_pll_p6.vhd + g_clk0_phase_shift : STRING := "0"; -- = 000 = st_clk_vec[0] = st_clk200 + g_clk_vec_w : NATURAL := 6; -- clk200_pll_p6.vhd and supports up to 6 extra output clocks, e.g. with phase 0 to 90 in steps of 11.25 degrees, and with same or lower frequency + g_clk1_phase_shift : STRING := "0"; -- = 000 = st_clk_vec[1] = st_clk200p + g_clk2_phase_shift : STRING := "156"; -- = 011.25 = st_clk_vec[2] + g_clk3_phase_shift : STRING := "313"; -- = 022.5 = st_clk_vec[3] + g_clk4_phase_shift : STRING := "469"; -- = 033.75 = st_clk_vec[4] + g_clk5_phase_shift : STRING := "625"; -- = 045 = st_clk_vec[5] + -- "781"; -- = 056.25 + g_clk6_phase_shift : STRING := "938"; -- = 067.5 = st_clk_vec[6] + -- "1094"; -- = 078.75 + g_clk1_divide_by : NATURAL := 32; -- = clk 200/32 MHz + g_clk2_divide_by : NATURAL := 32; -- = clk 200/32 MHz + g_clk3_divide_by : NATURAL := 32; -- = clk 200/32 MHz + g_clk4_divide_by : NATURAL := 32; -- = clk 200/32 MHz + g_clk5_divide_by : NATURAL := 32; -- = clk 200/32 MHz + g_clk6_divide_by : NATURAL := 32 -- = clk 200/32 MHz + ); + 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; + -- . g_sel=0 + 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; + -- . g_sel=1 + st_clk_vec : OUT STD_LOGIC_VECTOR(g_clk_vec_w-1 DOWNTO 0) -- PLL c6-c1 + ); +END unb1_board_clk200_pll; + + +ARCHITECTURE stratix4 OF unb1_board_clk200_pll IS + + CONSTANT c_reset_len : NATURAL := c_meta_delay_len; + + CONSTANT c_clk1_used : STRING := sel_a_b(g_clk_vec_w>0, "PORT_USED", "PORT_UNUSED"); + CONSTANT c_clk2_used : STRING := sel_a_b(g_clk_vec_w>1, "PORT_USED", "PORT_UNUSED"); + CONSTANT c_clk3_used : STRING := sel_a_b(g_clk_vec_w>2, "PORT_USED", "PORT_UNUSED"); + CONSTANT c_clk4_used : STRING := sel_a_b(g_clk_vec_w>3, "PORT_USED", "PORT_UNUSED"); + CONSTANT c_clk5_used : STRING := sel_a_b(g_clk_vec_w>4, "PORT_USED", "PORT_UNUSED"); + CONSTANT c_clk6_used : STRING := sel_a_b(g_clk_vec_w>5, "PORT_USED", "PORT_UNUSED"); + + 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 i_st_clk_vec : STD_LOGIC_VECTOR(5 DOWNTO 0) := (OTHERS=>'0'); + + 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; + st_clk_vec <= i_st_clk_vec(g_clk_vec_w-1 DOWNTO 0); + + gen_0 : IF g_sel=0 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 => clk200, + c0 => i_st_clk200, + c1 => i_st_clk200p, + c2 => i_st_clk400, + locked => st_locked + ); + END GENERATE; + + gen_1 : IF g_sel=1 GENERATE + i_st_clk200p <= i_st_clk_vec(0); + + u_st_pll_p6 : ENTITY tech_pll_lib.tech_pll_clk200_p6 + GENERIC MAP ( + g_technology => g_technology, + g_operation_mode => g_operation_mode, + g_clk0_phase_shift => g_clk0_phase_shift, + g_clk1_used => c_clk1_used, + g_clk2_used => c_clk2_used, + g_clk3_used => c_clk3_used, + g_clk4_used => c_clk4_used, + g_clk5_used => c_clk5_used, + g_clk6_used => c_clk6_used, + g_clk1_divide_by => g_clk1_divide_by, + g_clk2_divide_by => g_clk2_divide_by, + g_clk3_divide_by => g_clk3_divide_by, + g_clk4_divide_by => g_clk4_divide_by, + g_clk5_divide_by => g_clk5_divide_by, + g_clk6_divide_by => g_clk6_divide_by, + g_clk1_phase_shift => g_clk1_phase_shift, + g_clk2_phase_shift => g_clk2_phase_shift, + g_clk3_phase_shift => g_clk3_phase_shift, + g_clk4_phase_shift => g_clk4_phase_shift, + g_clk5_phase_shift => g_clk5_phase_shift, + g_clk6_phase_shift => g_clk6_phase_shift + ) + PORT MAP ( + areset => arst, + inclk0 => clk200, + c0 => i_st_clk200, + c1 => i_st_clk_vec(0), + c2 => i_st_clk_vec(1), + c3 => i_st_clk_vec(2), + c4 => i_st_clk_vec(3), + c5 => i_st_clk_vec(4), + c6 => i_st_clk_vec(5), + 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 stratix4; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk_rst.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk_rst.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2d7247adce1f3d25a407e8e972ece51304dbd32c --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_clk_rst.vhd @@ -0,0 +1,86 @@ +------------------------------------------------------------------------------- +-- +-- 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; + +-- 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 unb1_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 unb1_board_clk_rst; + + +ARCHITECTURE str OF unb1_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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_node_ctrl.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_node_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5974d6f3e6fedb1fe0a7424d6dc1185a87a7f115 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_node_ctrl.vhd @@ -0,0 +1,129 @@ +------------------------------------------------------------------------------- +-- +-- 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; + +-- Purpose: +-- Provide the basic node control along with an SOPC Builder system: +-- . sys_rst for sys_clk +-- . pulse every 1 us, 1 ms and 1 s +-- . extend WDI to avoid watchdog reset during SW reload + +ENTITY unb1_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 wdi by about 2**(14-1)= 8 s + ); + PORT ( + xo_clk : IN STD_LOGIC; -- from pin, also used as reference for the PLL in the SOPC design + xo_rst_n : OUT STD_LOGIC; -- to SOPC design + sys_clk : IN STD_LOGIC; -- system clock from PLL in SOPC design (= mm_clk) + sys_locked : IN STD_LOGIC; -- system clock PLL locked from SOPC design + sys_rst : OUT STD_LOGIC; -- system reset released after system clock PLL has locked (= mm_rst) + cal_clk : IN STD_LOGIC := '0'; -- calibration or configuration interface clock + cal_rst : OUT STD_LOGIC; -- calibration or configuration interface reset, released after sys_rst is released + st_clk : IN STD_LOGIC := '0'; -- streaming interface clock + st_rst : OUT STD_LOGIC; -- streaming interface reset, released after sys_rst is released + wdi_in : IN STD_LOGIC; -- from SW running on the NIOS2 in the SOPC design + wdi_out : OUT STD_LOGIC; -- to FPGA pin + pulse_us : OUT STD_LOGIC; -- pulses every us + pulse_ms : OUT STD_LOGIC; -- pulses every ms + pulse_s : OUT STD_LOGIC -- pulses every s + ); +END unb1_board_node_ctrl; + + +ARCHITECTURE str OF unb1_board_node_ctrl IS + + CONSTANT c_reset_len : NATURAL := 4; -- >= c_meta_delay_len from common_pkg + + SIGNAL i_sys_rst : STD_LOGIC; + SIGNAL i_pulse_ms : STD_LOGIC; + +BEGIN + + sys_rst <= i_sys_rst; + + pulse_ms <= i_pulse_ms; + + u_unb1_board_clk_rst : ENTITY work.unb1_board_clk_rst + PORT MAP ( + xo_clk => xo_clk, + xo_rst_n => xo_rst_n, + sys_clk => sys_clk, + sys_locked => sys_locked, + sys_rst => i_sys_rst -- release reset some clock cycles after sys_locked went high + ); + + u_common_areset_cal : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => i_sys_rst, -- release reset some clock cycles after i_sys_rst went low + clk => cal_clk, + out_rst => cal_rst + ); + + u_common_areset_st : ENTITY common_lib.common_areset + GENERIC MAP ( + g_rst_level => '1', + g_delay_len => c_reset_len + ) + PORT MAP ( + in_rst => i_sys_rst, -- release reset some clock cycles after i_sys_rst went low + clk => st_clk, + out_rst => st_rst + ); + + u_unb1_board_pulser : ENTITY work.unb1_board_pulser + GENERIC MAP ( + g_pulse_us => g_pulse_us, + g_pulse_ms => g_pulse_ms, + g_pulse_s => g_pulse_s + ) + PORT MAP ( + rst => i_sys_rst, + clk => sys_clk, + pulse_us => pulse_us, + pulse_ms => i_pulse_ms, + pulse_s => pulse_s + ); + + u_unb1_board_wdi_extend : ENTITY work.unb1_board_wdi_extend + GENERIC MAP ( + g_extend_w => g_wdi_extend_w + ) + PORT MAP ( + rst => i_sys_rst, + clk => sys_clk, + pulse_ms => i_pulse_ms, + wdi_in => wdi_in, + wdi_out => wdi_out + ); + +END str; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_peripherals_pkg.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_peripherals_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8482d9cb56ae25049e4bdddd95e6273f1ed3523a --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_peripherals_pkg.vhd @@ -0,0 +1,154 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- 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; -- = 3 -- 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_ddr3 + -- pi_ddr_capture (uses DP-MM read FIFO for data access) + reg_ddr3_adr_w : NATURAL; -- = 3 -- fixed, from c_mm_reg in ddr3_reg + + -- 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 (defaults for unb1_board_terminals_mesh used in fn_terminal_bf) + 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_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 + 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, 3, 1, 1, 1, 1, 1, 3, 3, 3, 4, 6, 2, 2, 1, 4, 3, 6, 13, 12, 2, 32, 8, 2, 8, 10, 16, 1024, 14, 5, 3, 11, 5, 16, 11, 3); + +END unb2_board_peripherals_pkg; + +PACKAGE BODY unb2_board_peripherals_pkg IS +END unb2_board_peripherals_pkg; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pkg.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pkg.vhd index 677bb2aaa05b493c8f3e2c146da54fc36ba12760..e3994ca5a738959c9829d23a61de92c7776878b7 100644 --- a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pkg.vhd +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pkg.vhd @@ -95,7 +95,8 @@ PACKAGE unb2_board_pkg IS aux : t_c_unb2_board_aux; END RECORD; - CONSTANT c_unb2_board_ci : t_c_unb2_board_ci := (c_unb2_board_aux); + -- FIXME: this does not compile in modelsim: (pls compare with unb1_board_pkg.vhd) + --CONSTANT c_unb2_board_ci : t_c_unb2_board_ci := (c_unb2_board_aux); TYPE t_unb2_board_fw_version IS RECORD @@ -130,9 +131,6 @@ PACKAGE 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; - FUNCTION func_unb2_board_chip_id(chip_id : IN STD_LOGIC_VECTOR(c_unb2_board_aux.chip_id_w-1 DOWNTO 0); - node_type : IN t_e_unb2_board_node) RETURN STD_LOGIC_VECTOR; - END unb2_board_pkg; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pulser.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pulser.vhd new file mode 100644 index 0000000000000000000000000000000000000000..41b6c0d21facdabeeccc560dc3772ef6c26f204d --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_pulser.vhd @@ -0,0 +1,117 @@ +------------------------------------------------------------------------------- +-- +-- 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; + +-- Purpose: Provide timing pulses for interval 1 us, 1 ms and 1 s + +ENTITY unb1_board_pulser IS + GENERIC ( + g_pulse_us : NATURAL := 125/(10**6); -- nof clk cycles to get us period + g_pulse_ms : NATURAL := 1000; -- nof pulse_us pulses to get ms period + g_pulse_s : NATURAL := 1000 -- nof pulse_ms pulses to get s period + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + sync : IN STD_LOGIC := '0'; + pulse_us : OUT STD_LOGIC; -- pulses after every g_pulse_us clock cycles + pulse_ms : OUT STD_LOGIC; -- pulses after every g_pulse_us*g_pulse_ms clock cycles + pulse_s : OUT STD_LOGIC -- pulses after every g_pulse_us*g_pulse_ms*g_pulse_s clock cycles + ); +END unb1_board_pulser; + + +ARCHITECTURE str OF unb1_board_pulser IS + + SIGNAL pulse_us_pp : STD_LOGIC; -- register to align with pulse_ms + SIGNAL pulse_us_p : STD_LOGIC; -- register to align with pulse_s + SIGNAL pulse_us_reg : STD_LOGIC; -- output register + SIGNAL i_pulse_us : STD_LOGIC; + + SIGNAL pulse_ms_p : STD_LOGIC; -- register to align with pulse_s + SIGNAL pulse_ms_reg : STD_LOGIC; -- output register + SIGNAL i_pulse_ms : STD_LOGIC; + + SIGNAL pulse_s_reg : STD_LOGIC; -- output register + SIGNAL i_pulse_s : STD_LOGIC; + +BEGIN + + pulse_us <= i_pulse_us; + pulse_ms <= i_pulse_ms; + pulse_s <= i_pulse_s; + + p_clk : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + pulse_us_p <= pulse_us_pp; + pulse_us_reg <= pulse_us_p; + pulse_ms_reg <= pulse_ms_p; + i_pulse_us <= pulse_us_reg; + i_pulse_ms <= pulse_ms_reg; + i_pulse_s <= pulse_s_reg; + END IF; + END PROCESS; + + u_common_pulser_us : ENTITY common_lib.common_pulser + GENERIC MAP ( + g_pulse_period => g_pulse_us + ) + PORT MAP ( + rst => rst, + clk => clk, + clken => '1', + pulse_en => '1', + pulse_clr => sync, + pulse_out => pulse_us_pp + ); + + u_common_pulser_ms : ENTITY common_lib.common_pulser + GENERIC MAP ( + g_pulse_period => g_pulse_ms + ) + PORT MAP ( + rst => rst, + clk => clk, + clken => '1', + pulse_en => pulse_us_pp, + pulse_clr => sync, + pulse_out => pulse_ms_p + ); + + u_common_pulser_s : ENTITY common_lib.common_pulser + GENERIC MAP ( + g_pulse_period => g_pulse_s + ) + PORT MAP ( + rst => rst, + clk => clk, + clken => '1', + pulse_en => pulse_ms_p, + pulse_clr => sync, + pulse_out => pulse_s_reg + ); + +END str; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..69da14c09114c2af39c456b3ff3bc82df7bd381c --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens.vhd @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE i2c_lib.i2c_pkg.ALL; + + +ENTITY unb1_board_sens is + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_clk_freq : NATURAL := 100*10**6; -- clk frequency in Hz + g_temp_high : NATURAL := 85; + g_sens_nof_result : NATURAL := 4 -- Should match nof read bytes via I2C in the unb1_board_sens_ctrl SEQUENCE list + ); + 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 unb1_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 := 0; -- 2**c_i2c_comma_w * system clock period comma time after I2C start and after each octet + -- 0 = no comma time + + CONSTANT c_sens_phy : t_c_i2c_phy := (c_sens_clk_cnt, c_sens_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 + + u_unb1_board_sens_ctrl : ENTITY work.unb1_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 + ); + + u_i2c_smbus : ENTITY i2c_lib.i2c_smbus + GENERIC MAP ( + g_i2c_phy => c_sens_phy + ) + 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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_ctrl.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..9d134435d00e60a36d5ead0828fe47425c0d3e1e --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_ctrl.vhd @@ -0,0 +1,175 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +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 common_lib.common_pkg.ALL; + + +ENTITY unb1_board_sens_ctrl IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_nof_result : NATURAL := 4; + 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 unb1_board_sens_ctrl IS + + -- I2C slave addresses of the devices on the I2C bus on UniBoard + CONSTANT FPGA_MAX1617_ADR : NATURAL := MAX1617_ADR_LOW_LOW; -- FPGA temperature sensor, slave address is "0011000" + CONSTANT ETH_MAX1617_ADR : NATURAL := MAX1617_ADR_MID_LOW; -- ETH temperature sensor, slave address is "0101001" + CONSTANT HOTSWAP_LTC4260_ADR : NATURAL := LTC4260_ADR_LOW_LOW_LOW; -- Hot swap controller, slave address is "1000100"; + + 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 , FPGA_MAX1617_ADR, MAX1617_CMD_READ_REMOTE_TEMP, + SMBUS_READ_BYTE , ETH_MAX1617_ADR, MAX1617_CMD_READ_REMOTE_TEMP, + SMBUS_READ_BYTE , HOTSWAP_LTC4260_ADR, LTC4260_CMD_SENSE, + SMBUS_READ_BYTE , HOTSWAP_LTC4260_ADR, LTC4260_CMD_SOURCE, + SMBUS_C_SAMPLE_SDA, 0, c_timeout_sda, 0, 0, + SMBUS_C_END, + SMBUS_C_NOP + ); -- = (7 24 1) (7 77 1) (7 68 4) (7 68 5) (20, timeout[0:3]) (19) + + CONSTANT c_seq_len : NATURAL := c_SEQ'LENGTH-1; -- upto SMBUS_C_END, the SMBUS_C_NOP is dummy to allow sufficient seq_cnt range + + -- The protocol list c_SEQ yields a list of g_nof_result=14 result bytes: + -- . expected SMBUS_READ_BYTE -> rdbyte, ok=0 + -- . expected SMBUS_WRITE_BYTE -> ok=0 + -- . expected SMBUS_C_END -> ok=0 + -- ==> so expected result_dat[0:4] = [rdbyte, rdbyte, rdbyte, rdbyte, rdbyte] + + 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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_reg.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f1c6bf75ad7b7edfe405d44a58ee80c5d03e05b2 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_sens_reg.vhd @@ -0,0 +1,162 @@ +------------------------------------------------------------------------------- +-- +-- 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: Provide MM slave register for unb1_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 FN and BN: +-- 0 = FPGA temperature = TInt8(fpga_temp) +-- Only via BN3: +-- 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 BN3 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 unb1_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 unb1_board_sens_reg; + + +ARCHITECTURE rtl OF unb1_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 BN3 + 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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info.vhd new file mode 100644 index 0000000000000000000000000000000000000000..aa946c8accb9ac9a5d1ceb297186c5f57de7f95c --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info.vhd @@ -0,0 +1,102 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- 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; +USE work.unb1_board_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 unb1_board_system_info IS + GENERIC ( + g_sim : BOOLEAN := FALSE; + g_fw_version : t_unb1_board_fw_version := c_unb1_board_fw_version; -- firmware version x.y (4b.4b) + g_aux : t_c_unb1_board_aux := c_unb1_board_aux -- aux contains the hardware version + ); + 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_unb1_board_nof_uniboard_w-1 DOWNTO 0); -- ID[7:3] + chip_id : OUT STD_LOGIC_VECTOR(c_unb1_board_nof_chip_w-1 DOWNTO 0); -- ID[2:0] + node_id : OUT STD_LOGIC_VECTOR(c_unb1_board_nof_node_w-1 DOWNTO 0); -- ID[1:0] + is_bn : OUT STD_LOGIC; -- '1' for Back Node, else '0' for Front Node + is_bn3 : OUT STD_LOGIC -- '1' for Back Node 3, else '0'. + ); +END unb1_board_system_info; + + +ARCHITECTURE str OF unb1_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_bn : STD_LOGIC; + SIGNAL nxt_is_bn3 : 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_bn <= nxt_is_bn; + is_bn3 <= nxt_is_bn3; + END IF; + END PROCESS; + + cs_sim <= is_true(g_sim); + + p_info : PROCESS(cs_sim, hw_version_reg, id_reg) + BEGIN + nxt_info <= (OTHERS=>'0'); + 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 3); + nxt_chip_id <= id_reg(2 DOWNTO 0); + nxt_node_id <= id_reg(1 DOWNTO 0); + nxt_is_bn <= id_reg(2); + nxt_is_bn3 <= '1' WHEN TO_UINT(id_reg(2 DOWNTO 0)) = 7 ELSE '0'; + +END str; diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info_reg.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..407bbda4cc931a4d5170ce482d7cf6820a3bcdb4 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_system_info_reg.vhd @@ -0,0 +1,152 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- 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_UNB1_BOARD_SYSTEM_INFO| +-- ============================================================================= +-- 0 [23..0] RO info +-- 1 [7..0] RO use_phy +-- 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.unb1_board_pkg.ALL; + +ENTITY unb1_board_system_info_reg IS + GENERIC ( + g_design_name : STRING; + g_use_phy : t_c_unb1_board_use_phy; + 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 unb1_board_system_info_reg; + + +ARCHITECTURE rtl OF unb1_board_system_info_reg IS + + CONSTANT c_nof_fixed_regs : NATURAL := 2; -- info, use_phy + CONSTANT c_nof_design_name_regs : NATURAL := 8; -- design_name + CONSTANT c_nof_stamp_regs : NATURAL := 3; -- date, time, svn rev + CONSTANT c_nof_design_note_regs : NATURAL := 8; -- 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) := TO_UVEC(g_use_phy.eth1g, 1) & + TO_UVEC(g_use_phy.tr_front,1) & + TO_UVEC(g_use_phy.tr_mesh, 1) & + TO_UVEC(g_use_phy.tr_back, 1) & + TO_UVEC(g_use_phy.ddr3_I, 1) & + TO_UVEC(g_use_phy.ddr3_II, 1) & + TO_UVEC(g_use_phy.adc, 1) & + TO_UVEC(g_use_phy.wdi, 1); + + 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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_extend.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_extend.vhd new file mode 100644 index 0000000000000000000000000000000000000000..75e14ae5a35474004c6492f3d13eb357a1b924c9 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_extend.vhd @@ -0,0 +1,98 @@ +------------------------------------------------------------------------------- +-- +-- 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; + +-- 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 unb1_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 unb1_board_wdi_extend; + + +ARCHITECTURE str OF unb1_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/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_reg.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..80578aa8d577629d0b0cc3358ba9e0bb8fd40d57 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/unb2_board_wdi_reg.vhd @@ -0,0 +1,90 @@ +------------------------------------------------------------------------------- +-- +-- 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: +-- 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 unb1_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 unb1_board_wdi_reg; + + +ARCHITECTURE rtl OF unb1_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/uniboard2/libraries/unb2_board/tb/vhdl/tb_mms_unb2_board_sens.vhd b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_mms_unb2_board_sens.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d3515ad40ebce96a3b69ca7b1bba94405de5b572 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_mms_unb2_board_sens.vhd @@ -0,0 +1,212 @@ +------------------------------------------------------------------------------- +-- +-- 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_unb1_board_sens +-- +-- Features: +-- . Verify that the UniBoard sensors are read. +-- +-- Usage: +-- . > as 10 +-- . > run -all + +ENTITY tb_mms_unb1_board_sens IS +END tb_mms_unb1_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; + + +ARCHITECTURE tb OF tb_mms_unb1_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 unb1_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_unb1_board_sens : ENTITY work.mms_unb1_board_sens + GENERIC MAP ( + g_sim => c_sim, + g_clk_freq => c_clk_freq, + g_temp_high => c_temp_high + ) + 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 back 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/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd new file mode 100644 index 0000000000000000000000000000000000000000..703de911b4666612274a5476616664234e9e604c --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_clk200_pll.vhd @@ -0,0 +1,142 @@ +------------------------------------------------------------------------------- +-- +-- 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_unb1_board_clk200_pll IS +END tb_unb1_board_clk200_pll; + + +ARCHITECTURE tb OF tb_unb1_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; + + SIGNAL st_clk_vec : STD_LOGIC_VECTOR(c_clk_vec_w-1 DOWNTO 0); -- PLL c6-c1 + +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.unb1_board_clk200_pll + GENERIC MAP ( + g_sel => 0, -- g_sel=0 for clk200_pll.vhd + -- g_sel=0 for clk200_pll.vhd + g_clk200_phase_shift => "0", + g_clk200p_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.unb1_board_clk200_pll + GENERIC MAP ( + g_sel => 0, -- g_sel=0 for clk200_pll.vhd + -- g_sel=0 for clk200_pll.vhd + 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.unb1_board_clk200_pll + GENERIC MAP ( + g_sel => 1, -- g_sel=0 for clk200_pll.vhd + -- g_sel=1 for clk200_pll_p6.vhd + g_clk200_phase_shift => "0", + -- g_sel=1 for clk200_pll_p6.vhd + g_clk0_phase_shift => "0", + g_clk_vec_w => c_clk_vec_w, + g_clk1_phase_shift => "0", + g_clk2_phase_shift => "156", + g_clk3_phase_shift => "313", + g_clk4_phase_shift => "469", + g_clk5_phase_shift => "625", + g_clk6_phase_shift => "938", + g_clk1_divide_by => c_clk_div, + g_clk2_divide_by => c_clk_div, + g_clk3_divide_by => c_clk_div, + g_clk4_divide_by => c_clk_div, + g_clk5_divide_by => c_clk_div, + g_clk6_divide_by => c_clk_div + ) + PORT MAP ( + arst => ext_rst, + clk200 => ext_clk, + st_clk200 => dp_clk200, + st_rst200 => dp_rst200, + -- . g_sel=1 + st_clk_vec => st_clk_vec + ); + +END tb; diff --git a/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..642d51b167d4368d0d5317d0cf9781d3628b2f18 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/tb/vhdl/tb_unb2_board_node_ctrl.vhd @@ -0,0 +1,103 @@ +------------------------------------------------------------------------------- +-- +-- 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_unb1_board_node_ctrl IS +END tb_unb1_board_node_ctrl; + + +ARCHITECTURE tb OF tb_unb1_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_sys_clk_period : TIME := c_xo_clk_period/5; -- 5 MHz PLL output from XO reference + CONSTANT c_sys_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 xo_clk : STD_LOGIC := '0'; + SIGNAL xo_rst_n : STD_LOGIC; + + SIGNAL sys_clk : STD_LOGIC := '0'; + SIGNAL sys_locked : STD_LOGIC := '0'; + SIGNAL sys_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 + + xo_clk <= NOT xo_clk AFTER c_xo_clk_period/2; + + sys_clk <= NOT sys_clk AFTER c_sys_clk_period/2; + sys_locked <= '0', '1' AFTER c_sys_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.unb1_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 ( + xo_clk => xo_clk, + xo_rst_n => xo_rst_n, + sys_clk => sys_clk, + sys_locked => sys_locked, + sys_rst => sys_rst, + wdi_in => wdi_in, + wdi_out => wdi_out, + pulse_us => pulse_us, + pulse_ms => pulse_ms, + pulse_s => pulse_s + ); + +END tb;