Skip to content
Snippets Groups Projects
Commit 51fa9af8 authored by Daniel van der Schuur's avatar Daniel van der Schuur
Browse files

-Added beamformer module and ARTS TAB wrapper around it.

parent 0074f040
No related branches found
No related tags found
No related merge requests found
hdl_lib_name = arts_tab_beamformer
hdl_library_clause_name = arts_tab_beamformer_lib
hdl_lib_uses_synth = dp beamformer
hdl_lib_uses_sim = diag
hdl_lib_technology =
synth_files =
src/vhdl/arts_tab_beamformer.vhd
test_bench_files =
tb/vhdl/tb_arts_tab_beamformer.vhd
regression_test_vhdl =
# no self checking tb available yet
[modelsim_project_file]
modelsim_copy_files =
src/hex hex
[quartus_project_file]
###############################################################################
#
# Copyright (C) 2013
# 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/>.
#
###############################################################################
from common import *
from mem_init_file import list_to_hex
# Purpose:
# . Generate HEX files with weights for the X and Y pol
# Description:
# . Converts list of 176 words to HEX file
# . 176 words = 2 (X,Y pols) interleaved streams of 88 complex numbers
PATH = "../hex"
FILENAME = "beamformer_weights"
NOF_WEIGHTS_RAMS = 12
COMPLEX_WIDTH = 16
NOF_WORDS_PER_POL = 88
MEM_WIDTH =32
MEM_DEPTH = 176
###############################################################################
# Create the data list
# . 176 words = 2 (X,Y pols) interleaved streams of 88 complex numbers
# . X-pol = complex( 1, 1)
# . Y-pol = complex(-1,-1)
###############################################################################
complex_x = [complex(i, 0) for i in range(NOF_WORDS_PER_POL)]
complex_y = [complex(i, 0) for i in range(NOF_WORDS_PER_POL)]
concat_int_x = concat_complex(complex_x, COMPLEX_WIDTH)
concat_int_y = concat_complex(complex_y, COMPLEX_WIDTH)
data = interleave([concat_int_x,concat_int_y])
print data
###############################################################################
# Write the HEX file
###############################################################################
for i in range(NOF_WEIGHTS_RAMS):
list_to_hex(data, PATH+"/"+FILENAME+"_"+str(i)+".mif", MEM_WIDTH, MEM_DEPTH)
###############################################################################
#
# Copyright (C) 2013
# 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/>.
#
###############################################################################
from common import *
from mem_init_file import list_to_hex
# Purpose:
# . Generate HEX files with simple complex numbers to tag the X and Y pol
# Description:
# . Converts list of 176 words to HEX file
# . 176 words = 2 (X,Y pols) interleaved streams of 88 complex numbers
# . X-pol = complex( 1, 1)
# . Y-pol = complex(-1,-1)
PATH = "../hex"
FILENAME = "mms_diag_block_gen_0"
COMPLEX_WIDTH = 8
NOF_WORDS_PER_POL = 88
MEM_WIDTH = 16
MEM_DEPTH = 176
###############################################################################
# Create the data list
# . 176 words = 2 (X,Y pols) interleaved streams of 88 complex numbers
# . X-pol = complex( 1, 1)
# . Y-pol = complex(-1,-1)
###############################################################################
complex_x = NOF_WORDS_PER_POL * [complex( 1, 1)]
complex_y = NOF_WORDS_PER_POL * [complex(-1,-1)]
concat_int_x = concat_complex(complex_x, COMPLEX_WIDTH)
concat_int_y = concat_complex(complex_y, COMPLEX_WIDTH)
data = interleave([concat_int_x,concat_int_y])
print data
###############################################################################
# Write the HEX file
###############################################################################
list_to_hex(data, PATH+"/"+FILENAME+".hex", MEM_WIDTH, MEM_DEPTH)
-------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
-------------------------------------------------------------------------------
-- Author:
-- . Daniel van der Schuur
-- Purpose:
-- . Beamformer instance with ARTS specific weight addressing
-- Description:
-- . All comments apply to the default generic parameter values
-- . With 176 32b (16b complex) weights per stream, we'll use
-- 5632kb per stream = 1 M9K RAM per stream, or 12 M9Ks in total.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
LIBRARY common_lib, common_mult_lib, technology_lib, dp_lib, beamformer_lib;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY arts_tab_beamformer IS
GENERIC (
g_technology : NATURAL := c_tech_select_default;
g_nof_inputs : NATURAL := 12; --12 dishes, X,Y pols interleaved
g_nof_tabs : NATURAL := 12; --12 Tied Array Beams
g_nof_beamlets : NATURAL := 88; --88 beamlets per FPGA (704 per UniBoard) in 8b mode
g_data_w : NATURAL := 8 --8b complex input data
);
PORT (
dp_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
ram_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- MM interface to upload weights to RAM
ram_miso : OUT t_mem_miso;
snk_in_arr : IN t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); -- All streams must be synchronous
src_out_arr : OUT t_dp_sosi_arr(g_nof_tabs-1 DOWNTO 0)
);
END arts_tab_beamformer;
ARCHITECTURE str OF arts_tab_beamformer IS
-----------------------------------------------------------------------------
-- dp_counter
-----------------------------------------------------------------------------
CONSTANT c_nof_counts : NATURAL := 3;
CONSTANT c_nof_samples_per_beamlet : NATURAL := 100; --800000
CONSTANT c_nof_pols : NATURAL := 2;
SIGNAL dp_counter_count_src_out_arr : t_dp_sosi_arr(c_nof_counts-1 DOWNTO 0);
SIGNAL dp_counter_src_out : t_dp_sosi;
-----------------------------------------------------------------------------
-- beamformer
-----------------------------------------------------------------------------
CONSTANT c_nof_weights : NATURAL := 2*g_nof_beamlets; --176 (2 (XY interleaved) * 88 beamlets)
SIGNAL weight_addr : STD_LOGIC_VECTOR(ceil_log2(c_nof_weights)-1 DOWNTO 0);
BEGIN
-----------------------------------------------------------------------------
-- dp_counter to tag input samples with useful indices
-- . c0 = range(0,1,1) c_nof_pols, X,Y
-- . c1 = range(0,800000,1) c_nof_samples_per_beamlet
-- . c2 = range(0,88,1) c_nof_beamlets
-----------------------------------------------------------------------------
u_dp_counter : ENTITY dp_lib.dp_counter
GENERIC MAP (
g_nof_counters => c_nof_counts,-- c2, c1, c0
g_range_start => (0,0,0,0,0,0,0, 0, 0, 0),
g_range_stop => (0,0,0,0,0,0,0,g_nof_beamlets, c_nof_samples_per_beamlet, c_nof_pols),
g_range_step => (0,0,0,0,0,0,0, 1, 1, 1)
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in => snk_in_arr(0),
src_out => dp_counter_src_out,
count_src_out_arr => dp_counter_count_src_out_arr
);
------------------------------------------------------------------------------
-- Convert (dp_counter) counts to weight address
-- . For each stream, the weights sit in RAM as follows:
-- . All X pol weights @ even offsets: 0,2,4,..,174
-- . All Y pol weights @ odd offsets: 1,3,5,..,175
-- . X pol Beamlet 0 @ address 0
-- . Y pol Beamlet 0 @ address 1
-- . X pol Beamlet 1 @ address 2
-- . Y pol Beamlet 1 @ address 3
-- . .
-- . .
-- . X pol Beamlet 87 @ address 174
-- . Y pol Beamlet 87 @ address 175
------------------------------------------------------------------------------
weight_addr(0) <= dp_counter_count_src_out_arr(0).data(0); -- X pol = even adress, Y pol = odd address
weight_addr(7 DOWNTO 1) <= dp_counter_count_src_out_arr(2).data(6 DOWNTO 0); -- 88 beamets @ adresses 0,2,..174.
-----------------------------------------------------------------------------
-- beamformer for each TAB
-----------------------------------------------------------------------------
gen_beamformer : FOR i IN 0 TO g_nof_tabs-1 GENERATE
u_beamformer : ENTITY beamformer_lib.beamformer
GENERIC MAP (
g_technology => g_technology,
g_nof_inputs => g_nof_inputs,
g_nof_weights => c_nof_weights,
g_data_w => g_data_w
)
PORT MAP (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
weight_addr => weight_addr,
snk_in_arr => snk_in_arr,
src_out => src_out_arr(i)
);
END GENERATE;
END str;
--------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
--------------------------------------------------------------------------------
-- Author:
-- . Daniel van der Schuur
-- Purpose:
-- . Feed ARTS input data to arts_tab_beamformer, verify output rate
-- Description:
-- . All comments apply to the default generic parameter values
LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
ENTITY tb_arts_tab_beamformer IS
GENERIC (
g_technology : NATURAL := c_tech_select_default;
g_nof_inputs : NATURAL := 12; --12 dishes, X,Y pols interleaved
g_nof_tabs : NATURAL := 12; --12 Tied Array Beams
g_nof_beamlets : NATURAL := 88; --88 beamlets per FPGA (704 per UniBoard) in 8b mode
g_data_w : NATURAL := 8 --8b complex input data
);
END tb_arts_tab_beamformer;
ARCHITECTURE tb OF tb_arts_tab_beamformer IS
-----------------------------------------------------------------------------
-- General
-----------------------------------------------------------------------------
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_mm_clk_period : TIME := 25 ns;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC;
-----------------------------------------------------------------------------
-- Block generator
-- . 2 pols * 88 beamlets * 2*8b @ 781250 Hz = 2.2Gbps per stream
-- . Max data rate of 16b stream = 3.2Gbps
-- . 2.2Gbps = 3.2Gbps /256 * 176
-- . Blocksize = 2 pols * 88 beamlets = 176
-- . Gapsize = 256-176
-----------------------------------------------------------------------------
CONSTANT c_bg_block_size : NATURAL := 2*g_nof_beamlets;
CONSTANT c_bg_gapsize : NATURAL := 256-c_bg_block_size;
CONSTANT c_bg_blocks_per_sync : NATURAL := 10; --not used
CONSTANT c_bg_ctrl : t_diag_block_gen := ('1', -- enable
'0', -- enable_sync
TO_UVEC( c_bg_block_size, c_diag_bg_samples_per_packet_w),
TO_UVEC(c_bg_blocks_per_sync, c_diag_bg_blocks_per_sync_w),
TO_UVEC( c_bg_gapsize, c_diag_bg_gapsize_w),
TO_UVEC( 0, c_diag_bg_mem_low_adrs_w),
TO_UVEC( c_bg_block_size-1, c_diag_bg_mem_high_adrs_w),
TO_UVEC( 0, c_diag_bg_bsn_init_w));
SIGNAL block_gen_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0);
-----------------------------------------------------------------------------
-- ARTS TAB beamformer
-----------------------------------------------------------------------------
SIGNAL arts_tab_beamformer_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL arts_tab_beamformer_src_out_arr : t_dp_sosi_arr(g_nof_tabs-1 DOWNTO 0);
BEGIN
-----------------------------------------------------------------------------
-- Clocks and reset
-----------------------------------------------------------------------------
dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
-----------------------------------------------------------------------------
-- Block generator:
-- . X pol = complex( 1, 1)
-- . Y pol = complex(-1,-1)
-----------------------------------------------------------------------------
u_mms_diag_block_gen : ENTITY diag_lib.mms_diag_block_gen
GENERIC MAP (
g_nof_streams => 1,
g_buf_dat_w => 2*g_data_w,
g_buf_addr_w => ceil_log2(TO_UINT(c_bg_ctrl.samples_per_packet)),
g_file_name_prefix => "hex/mms_diag_block_gen",
g_diag_block_gen_rst => c_bg_ctrl
)
PORT MAP (
mm_clk => mm_clk,
mm_rst => mm_rst,
dp_clk => dp_clk,
dp_rst => dp_rst,
out_sosi_arr => block_gen_src_out_arr
);
-----------------------------------------------------------------------------
-- Device under test: ARTS TAB beamformer
-- . All outputs = 1+1j, -1-1j, 2+2j, -2-2j, .. 175+175j, -175-175j times g_nof_inputs.
-----------------------------------------------------------------------------
gen_arts_tab_beamformer_snk_in_arr : FOR i IN 0 TO g_nof_inputs-1 GENERATE
arts_tab_beamformer_snk_in_arr(i) <= block_gen_src_out_arr(0); -- Copy the block gen stream 12 times
END GENERATE;
u_arts_tab_beamformer : ENTITY work.arts_tab_beamformer
GENERIC MAP (
g_technology => g_nof_beamlets,
g_nof_inputs => g_nof_inputs,
g_nof_tabs => g_nof_tabs,
g_nof_beamlets => g_nof_beamlets,
g_data_w => g_data_w
)
PORT MAP (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr => arts_tab_beamformer_snk_in_arr,
src_out_arr => arts_tab_beamformer_src_out_arr
);
END tb;
hdl_lib_name = beamformer
hdl_library_clause_name = beamformer_lib
hdl_lib_uses_synth = common common_mult technology mm dp
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
src/vhdl/beamformer.vhd
test_bench_files =
tb/vhdl/tb_beamformer.vhd
regression_test_vhdl =
# no self checking tb available yet
[modelsim_project_file]
[quartus_project_file]
-------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
-------------------------------------------------------------------------------
-- Author:
-- . Daniel van der Schuur
-- Purpose:
-- . Structural beamformer using weights RAM, multiplier and adder stage
-- Description:
-- . This beamformer multiplies each valid input sample of snk_in_arr by
-- weights read from RAM, and adds the resulting products of all streams
-- together into a single output stream.
-- . The weight is taken from the RAM that corresponds to the snk_in stream
-- index.
-- . To keep this beamformer generic and easily reusable the user can wrap
-- this beamformer with simple application specific logic to control
-- weight_addr.
-- . Input/output reordering and quantization are also application
-- specific and should be done in the wrapper.
-- . The input array snk_in_arr must be synchronous.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
LIBRARY common_lib, common_mult_lib, technology_lib, dp_lib;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY beamformer IS
GENERIC (
g_technology : NATURAL := c_tech_select_default;
g_nof_inputs : NATURAL;
g_data_w : NATURAL;
g_nof_weights : NATURAL;
g_weights_w : NATURAL := 16;
g_weights_file : STRING := "hex/beamformer_weights";
g_weights_write_only : BOOLEAN := FALSE
);
PORT (
dp_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
ram_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- MM interface to upload weights to RAM
ram_miso : OUT t_mem_miso;
weight_addr : IN STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0); -- Weight RAM address
snk_in_arr : IN t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); -- All streams must be synchronous
src_out : OUT t_dp_sosi
);
END beamformer;
ARCHITECTURE str OF beamformer IS
------------------------------------------------------------------------------
-- Weights RAM
------------------------------------------------------------------------------
CONSTANT c_common_ram_crw_crw_ram : t_c_mem := (latency => 1,
adr_w => ceil_log2(g_nof_weights),
dat_w => c_nof_complex*g_weights_w,
nof_dat => g_nof_weights,
init_sl => '0');
TYPE t_common_ram_crw_crw_adr_b_arr IS ARRAY(g_nof_inputs-1 DOWNTO 0) OF STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0);
TYPE t_common_ram_crw_crw_rd_dat_b_arr IS ARRAY(g_nof_inputs-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_nof_complex*g_weights_w-1 DOWNTO 0);
SIGNAL ram_mosi_arr : t_mem_mosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL ram_miso_arr : t_mem_miso_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL common_ram_crw_crw_adr_b_arr : t_common_ram_crw_crw_adr_b_arr;
SIGNAL common_ram_crw_crw_rd_en_b_arr : STD_LOGIC_VECTOR(g_nof_inputs-1 DOWNTO 0);
SIGNAL common_ram_crw_crw_rd_dat_b_arr : t_common_ram_crw_crw_rd_dat_b_arr;
SIGNAL common_ram_crw_crw_rd_val_b_arr : STD_LOGIC_VECTOR(g_nof_inputs-1 DOWNTO 0);
SIGNAL common_ram_crw_crw_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
------------------------------------------------------------------------------
-- Pipeline
------------------------------------------------------------------------------
SIGNAL dp_pipeline_arr_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
------------------------------------------------------------------------------
-- Multiplier stage
------------------------------------------------------------------------------
SIGNAL dp_complex_mult_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0);
SIGNAL dp_complex_mult_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
BEGIN
------------------------------------------------------------------------------
-- Weights RAM
------------------------------------------------------------------------------
gen_common_ram_crw_crw : FOR i IN 0 TO g_nof_inputs-1 GENERATE
-- Read request on every incoming valid cycle
common_ram_crw_crw_rd_en_b_arr(i) <= snk_in_arr(i).valid;
-- Use entity input for read address
common_ram_crw_crw_adr_b_arr(i) <= weight_addr;
-- Dual clock RAM
u_common_ram_crw_crw : ENTITY common_lib.common_ram_crw_crw
GENERIC MAP (
g_technology => g_technology,
g_ram => c_common_ram_crw_crw_ram,
-- g_init_file => g_weights_file & "_" & NATURAL'IMAGE(i) & ".hex",
g_true_dual_port => FALSE --NOT(g_weights_write_only)
)
PORT MAP (
rst_a => mm_rst,
clk_a => mm_clk,
wr_en_a => ram_mosi_arr(i).wr,
wr_dat_a => ram_mosi_arr(i).wrdata(c_common_ram_crw_crw_ram.dat_w -1 DOWNTO 0),
adr_a => ram_mosi_arr(i).address(c_common_ram_crw_crw_ram.adr_w-1 DOWNTO 0),
rd_en_a => ram_mosi_arr(i).rd,
rd_dat_a => ram_miso_arr(i).rddata(c_common_ram_crw_crw_ram.dat_w -1 DOWNTO 0),
rd_val_a => ram_miso_arr(i).rdval,
rst_b => dp_rst,
clk_b => dp_clk,
wr_en_b => '0',
wr_dat_b => (OTHERS =>'0'),
adr_b => common_ram_crw_crw_adr_b_arr(i),
rd_en_b => common_ram_crw_crw_rd_en_b_arr(i),
rd_dat_b => common_ram_crw_crw_rd_dat_b_arr(i),
rd_val_b => common_ram_crw_crw_rd_val_b_arr(i)
);
-- RAM output rewired to SOSI array
common_ram_crw_crw_src_out_arr(i).re(g_weights_w-1 DOWNTO 0) <= common_ram_crw_crw_rd_dat_b_arr(i)( g_weights_w-1 DOWNTO 0);
common_ram_crw_crw_src_out_arr(i).im(g_weights_w-1 DOWNTO 0) <= common_ram_crw_crw_rd_dat_b_arr(i)(2*g_weights_w-1 DOWNTO g_weights_w);
common_ram_crw_crw_src_out_arr(i).valid <= common_ram_crw_crw_rd_val_b_arr(i);
END GENERATE;
-- Combine the individual RAM MM buses into one
u_common_mem_mux : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_inputs,
g_mult_addr_w => ceil_log2(g_nof_weights)
)
PORT MAP (
mosi => ram_mosi,
miso => ram_miso,
mosi_arr => ram_mosi_arr,
miso_arr => ram_miso_arr
);
------------------------------------------------------------------------------
-- Pipeline to align snk_in_arr with dp_ram_src_out_arr
------------------------------------------------------------------------------
u_dp_pipeline_arr : ENTITY dp_lib.dp_pipeline_arr
GENERIC MAP(
g_nof_streams => g_nof_inputs,
g_pipeline => 1
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in_arr => common_ram_crw_crw_src_out_arr,
src_out_arr => dp_pipeline_arr_src_out_arr
);
------------------------------------------------------------------------------
-- Multiplier stage
------------------------------------------------------------------------------
gen_mult_inputs: FOR i IN 0 TO g_nof_inputs-1 GENERATE
dp_complex_mult_snk_in_2arr_2(i)(0) <= dp_pipeline_arr_src_out_arr(i); -- Streaming data
dp_complex_mult_snk_in_2arr_2(i)(1) <= common_ram_crw_crw_src_out_arr(i); -- Weights RAM
END GENERATE;
u_dp_complex_mult : ENTITY dp_lib.dp_complex_mult
GENERIC MAP (
g_nof_multipliers => g_nof_inputs,
g_data_w => g_data_w
)
PORT MAP (
clk => dp_clk,
rst => dp_rst,
snk_in_2arr_2 => dp_complex_mult_snk_in_2arr_2,
src_out_arr => dp_complex_mult_src_out_arr
);
------------------------------------------------------------------------------
-- Adder stage
------------------------------------------------------------------------------
u_dp_complex_add : ENTITY dp_lib.dp_complex_add
GENERIC MAP (
g_nof_inputs => g_nof_inputs,
g_data_w => 2*g_data_w
)
PORT MAP (
clk => dp_clk,
rst => dp_rst,
snk_in_arr => dp_complex_mult_src_out_arr,
src_out => src_out
);
END str;
--------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
--------------------------------------------------------------------------------
-- Author:
-- . Daniel van der Schuur
-- Purpose:
-- .
-- Description:
-- .
LIBRARY IEEE, common_lib, dp_lib, technology_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
ENTITY tb_beamformer IS
GENERIC (
g_technology : NATURAL := c_tech_select_default;
g_nof_inputs : NATURAL := 4;
g_nof_weights : NATURAL := 32;
g_data_w : NATURAL := 8 --8b complex input data
);
END tb_beamformer;
ARCHITECTURE tb OF tb_beamformer IS
-----------------------------------------------------------------------------
-- General
-----------------------------------------------------------------------------
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_mm_clk_period : TIME := 25 ns;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC;
-----------------------------------------------------------------------------
-- beamformer
-----------------------------------------------------------------------------
SIGNAL beamformer_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL beamformer_src_out : t_dp_sosi;
SIGNAL beamformer_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0);
BEGIN
-----------------------------------------------------------------------------
-- Clocks and reset
-----------------------------------------------------------------------------
dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
-----------------------------------------------------------------------------
-- beamformer for each TAB
-----------------------------------------------------------------------------
u_beamformer : ENTITY work.beamformer
GENERIC MAP (
g_technology => g_technology,
g_nof_inputs => g_nof_inputs,
g_nof_weights => g_nof_weights,
g_data_w => g_data_w
)
PORT MAP (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
weight_addr => beamformer_weight_addr,
snk_in_arr => beamformer_snk_in_arr,
src_out => beamformer_src_out
);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment