diff --git a/libraries/base/diag/hdllib.cfg b/libraries/base/diag/hdllib.cfg index 665e7c025c9d45d5b32789017688bc9fdc4c4671..7153230c231b88424110673de3ec95beceedebef 100644 --- a/libraries/base/diag/hdllib.cfg +++ b/libraries/base/diag/hdllib.cfg @@ -13,8 +13,8 @@ synth_files = $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_rx_seq.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_frm_generator.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_frm_monitor.vhd - $UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_tx_seq.vhd - $UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_rx_seq.vhd + src/vhdl/mms_diag_tx_seq.vhd + src/vhdl/mms_diag_rx_seq.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/avs_diag_tx_seq.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/avs_diag_rx_seq.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/avs_diag_tx_seq_12.vhd @@ -38,7 +38,7 @@ test_bench_files = $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_tx_frm.vhd $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_frm_generator.vhd $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_frm_monitor.vhd - $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_mms_diag_seq.vhd + tb/vhdl/tb_mms_diag_seq.vhd tb/vhdl/tb_diag_block_gen.vhd tb/vhdl/tb_mms_diag_block_gen.vhd tb/vhdl/tb_diag_regression.vhd diff --git a/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b7a4d348a96b67a2c5edb97f15717d3196cf00d0 --- /dev/null +++ b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd @@ -0,0 +1,137 @@ + ------------------------------------------------------------------------------- +-- +-- 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, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +ENTITY mms_diag_rx_seq IS + GENERIC ( + g_nof_diag_inst : NATURAL := 1; + g_dat_w : NATURAL := c_word_w; -- >= 1, test data width + g_sim : BOOLEAN := FALSE + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + st_clk : IN STD_LOGIC; + + -- Memory Mapped Slave + mm_sla_in : IN t_mem_mosi; -- master out slave in + mm_sla_out : OUT t_mem_miso; -- master in slave out + + -- Streaming interface + rx_snk_in : IN t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0) -- source out sink in + ); +END mms_diag_rx_seq; + + +ARCHITECTURE str OF mms_diag_rx_seq IS + + CONSTANT c_latency : NATURAL := 1; -- read latency + CONSTANT c_init_sl : STD_LOGIC := '0'; -- optional, init all dat words to std_logic '0', '1' or 'X' + CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0'); + CONSTANT c_nof_mm_regs : NATURAL := 4+g_nof_diag_inst; + CONSTANT c_mm_addr_w : NATURAL := ceil_log2(c_nof_mm_regs); + + CONSTANT c_mem_rec : t_c_mem := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl); + + SIGNAL out_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0); + SIGNAL in_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0); + +BEGIN + + gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE + u_diag_rx_seq: ENTITY WORK.diag_rx_seq + GENERIC MAP ( + g_dat_w => g_dat_w, + g_diag_res_w => c_word_w+1 + ) + PORT MAP ( + rst => mm_rst, + clk => st_clk, + + -- Write and read back registers: + diag_en => out_reg( i), -- 0 to 31 (for 12 instances: 11 downto 0 used) + diag_sel => out_reg( c_word_w+i), -- 32 to 63 (for 12 instances: 43 downto 32 used) + + -- Read only registers: + orv(diag_res) => in_reg(2*c_word_w+i), -- 64 to 95 (for 12 instances: 75 downto 64 used) + diag_res_val => in_reg(3*c_word_w+i), -- 96 to 127 (for 12 instances: 107 downto 96 used) + + -- Streaming + in_dat => rx_snk_in(i).data(c_word_w-1 DOWNTO 0), + in_val => rx_snk_in(i).valid + ); + + -- Read-only registers for received data, starting from offset 4: + in_reg ( (4+i)*c_word_w+c_word_w-1 DOWNTO (4+i)*c_word_w) <= rx_snk_in(i).data(c_word_w-1 DOWNTO 0); + + END GENERATE; + + u_common_reg_r_w : ENTITY common_lib.common_reg_r_w + GENERIC MAP( + g_reg => c_mem_rec, + g_init_reg => c_init_reg + ) + PORT MAP( + rst => mm_rst, + clk => mm_clk, + clken => '1', + -- control side + wr_en => mm_sla_in.wr, + wr_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0), + wr_dat => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0), + rd_en => mm_sla_in.rd, + rd_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0), + rd_dat => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0), + rd_val => OPEN, + -- data side + out_reg => out_reg, + in_reg => in_reg + ); + + --Connect out_reg to in_reg for write and readback register: + in_reg(63 downto 0) <= out_reg(63 downto 0); + + --Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt + in_reg(3*c_word_w-1 DOWNTO 2*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res + in_reg(4*c_word_w-1 DOWNTO 3*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res_val + + +END str; + + + + + + + + + + + + + diff --git a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd new file mode 100644 index 0000000000000000000000000000000000000000..766955d7d15c60f37a2b026de4fa3c0aff785091 --- /dev/null +++ b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd @@ -0,0 +1,130 @@ + ------------------------------------------------------------------------------- +-- +-- 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, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +ENTITY mms_diag_tx_seq IS + GENERIC ( + g_nof_diag_inst : NATURAL := 1; + g_dat_w : NATURAL := c_word_w; -- >= 1, test data width + g_sim : BOOLEAN := FALSE + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + st_clk : IN STD_LOGIC; + + -- Memory Mapped Slave + mm_sla_in : IN t_mem_mosi; -- master out slave in + mm_sla_out : OUT t_mem_miso; -- master in slave out + + -- Streaming interface + tx_src_out : OUT t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0); -- source out sink in + tx_src_in : IN t_dp_siso_arr(g_nof_diag_inst-1 DOWNTO 0) -- source in sink out + ); +END mms_diag_tx_seq; + + +ARCHITECTURE str OF mms_diag_tx_seq IS + + CONSTANT c_latency : NATURAL := 1; -- read latency + CONSTANT c_init_sl : STD_LOGIC := '0'; -- optional, init all dat words to std_logic '0', '1' or 'X' + CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0'); + CONSTANT c_nof_mm_regs : NATURAL := 2+g_nof_diag_inst; + CONSTANT c_mm_addr_w : NATURAL := ceil_log2(c_nof_mm_regs); + + CONSTANT c_mem_rec : t_c_mem := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl); + + SIGNAL out_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0); + SIGNAL in_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0); + +BEGIN + + gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE + u_diag_tx_seq: ENTITY WORK.diag_tx_seq + GENERIC MAP ( + g_dat_w => g_dat_w + ) + PORT MAP ( + rst => mm_rst, + clk => st_clk, + + -- Write and read back registers: + diag_en => out_reg( i), -- 0 to 31 + diag_sel => out_reg( c_word_w+i), -- 32 to 63 + diag_dat => out_reg(3*c_word_w+i*c_word_w-1 DOWNTO 2*c_word_w+i*c_word_w), -- downto 64 + + -- Streaming + diag_req => tx_src_in(i).ready, + out_dat => tx_src_out(i).data(c_word_w-1 DOWNTO 0), + out_val => tx_src_out(i).valid + ); + END GENERATE; + + u_common_reg_r_w : ENTITY common_lib.common_reg_r_w + GENERIC MAP( + g_reg => c_mem_rec, + g_init_reg => c_init_reg + ) + PORT MAP( + rst => mm_rst, + clk => mm_clk, + clken => '1', + -- control side + wr_en => mm_sla_in.wr, + wr_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0), + wr_dat => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0), + rd_en => mm_sla_in.rd, + rd_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0), + rd_dat => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0), + rd_val => OPEN, + -- data side + out_reg => out_reg, + in_reg => in_reg + ); + + --Connect out_reg to in_reg for write and readback register: + in_reg(63 downto 0) <= out_reg(63 downto 0); + + --Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt + in_reg((2+g_nof_diag_inst)*c_word_w-1 DOWNTO 2*c_word_w) <= (OTHERS => '0'); --diag_dat + + +END str; + + + + + + + + + + + + + diff --git a/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd b/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1b53ce598c9bc18b7585a15bef80670c1b95e86f --- /dev/null +++ b/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd @@ -0,0 +1,166 @@ +-------------------------------------------------------------------------------- +-- +-- 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, dp_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.tb_common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +ENTITY tb_mms_diag_seq IS +END ENTITY tb_mms_diag_seq; + +ARCHITECTURE str of tb_mms_diag_seq IS + + CONSTANT c_nof_diag_inst : NATURAL := 1; -- Enter number of diag instances here. Max = 32. + CONSTANT c_sim : BOOLEAN := TRUE; + + CONSTANT mm_clk_period : TIME := 8 ns; -- 125 MHz + CONSTANT st_clk_period : TIME := 5 ns; -- 200 MHz + + CONSTANT c_all_bits_high : INTEGER := -1; + CONSTANT c_all_bits_low : INTEGER := 0; + + CONSTANT c_offset_rx_en : NATURAL := 0; --offsets relative to MM base address + CONSTANT c_offset_rx_mode : NATURAL := 1; + CONSTANT c_offset_diag_res : NATURAL := 2; + CONSTANT c_offset_diag_res_val : NATURAL := 3; + + CONSTANT c_offset_tx_en : NATURAL := 0; + CONSTANT c_offset_tx_mode : NATURAL := 1; + CONSTANT c_offset_tx_dat : NATURAL := 2; + + SIGNAL st_clk : STD_LOGIC := '0'; + SIGNAL mm_clk : STD_LOGIC := '0'; + SIGNAL sys_rst : STD_LOGIC := '1'; + + SIGNAL tx_mm_mosi : t_mem_mosi; + SIGNAL tx_mm_miso : t_mem_miso; + + SIGNAL rx_mm_mosi : t_mem_mosi; + SIGNAL rx_mm_miso : t_mem_miso; + + SIGNAL tx_src_out : t_dp_sosi_arr(c_nof_diag_inst-1 DOWNTO 0); -- source out sink in + SIGNAL tx_src_in : t_dp_siso_arr(c_nof_diag_inst-1 DOWNTO 0); -- source in sink out + +BEGIN + + sys_rst <= '0' AFTER 100 ns; + + st_clk <= NOT mm_clk AFTER mm_clk_period/2; -- Would be generated by SOPC if there was one. + mm_clk <= NOT mm_clk AFTER mm_clk_period/2; + p_mm_wr : PROCESS + BEGIN + + tx_mm_miso <= c_mem_miso_rst; + tx_mm_mosi <= c_mem_mosi_rst; + rx_mm_miso <= c_mem_miso_rst; + rx_mm_mosi <= c_mem_mosi_rst; + + WHILE sys_rst='1' LOOP + WAIT UNTIL rising_edge(mm_clk); + END LOOP; + + FOR I IN 0 TO 9 LOOP + WAIT UNTIL rising_edge(mm_clk); + END LOOP; + + -- Enable DIAG TX sequencer, set modes of RX and TX to PRNG + proc_mem_mm_bus_wr(c_offset_tx_mode, c_all_bits_high, mm_clk, tx_mm_mosi); + proc_mem_mm_bus_wr(c_offset_tx_en, c_all_bits_high, mm_clk, tx_mm_mosi); + proc_mem_mm_bus_wr(c_offset_rx_mode, c_all_bits_high, mm_clk, rx_mm_mosi); + + WAIT FOR 100 ns; + + -- Receivers should have aligned to the data now. Enable the DIAG RX monitor. + proc_mem_mm_bus_wr(c_offset_rx_en, c_all_bits_high, mm_clk, rx_mm_mosi); + + WAIT FOR 200 ns; + + -- Now read the diagnostics result: first put the request on the bus. + proc_mem_mm_bus_rd(c_offset_diag_res, mm_clk, rx_mm_mosi); + + -- Wait because of read latency + proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk); + + -- Read data is now available in tx_mm_miso.rddata + FOR i in 0 to c_nof_diag_inst-1 LOOP -- All unconnected diag_res signals will of course be 'X' - only read the first c_nof_diag_inst bits. + ASSERT rx_mm_miso.rddata(i) = '0' + REPORT " Uniboard: ************************ MM READ DIAG RESULT NOT ZERO! ************************" SEVERITY FAILURE; + END LOOP; + + ASSERT FALSE + REPORT "Uniboard: MM read DIAG result OK." SEVERITY NOTE; + + WAIT; + + END PROCESS; + + u_mms_diag_tx_seq: ENTITY WORK.mms_diag_tx_seq + GENERIC MAP( + g_nof_diag_inst => c_nof_diag_inst, + g_dat_w => c_word_w, + g_sim => c_sim + ) + PORT MAP( + -- Clocks and reset + mm_rst => sys_rst, + mm_clk => mm_clk, + st_clk => st_clk, + + -- Memory Mapped Slave + mm_sla_in => tx_mm_mosi, -- master out slave in + mm_sla_out => tx_mm_miso, -- master in slave out + + -- Streaming interface + tx_src_out => tx_src_out, + tx_src_in => tx_src_in + ); + + gen_ready_signals : FOR i IN 0 TO c_nof_diag_inst-1 GENERATE -- Ready signals for all instantiated diag rx modules + tx_src_in(i).ready <= '1'; + END GENERATE; + + u_mms_diag_rx_seq: ENTITY WORK.mms_diag_rx_seq + GENERIC MAP( + g_nof_diag_inst => c_nof_diag_inst, + g_dat_w => c_word_w, + g_sim => c_sim + ) + PORT MAP( + -- Clocks and reset + mm_rst => sys_rst, + mm_clk => mm_clk, + st_clk => st_clk, + + -- Memory Mapped Slave + mm_sla_in => rx_mm_mosi, -- master out slave in + mm_sla_out => rx_mm_miso, -- master in slave out + + -- Streaming interface + rx_snk_in => tx_src_out + ); + +END ARCHITECTURE str;