Commit e0c10e48 authored by Dejan Priversek's avatar Dejan Priversek
Browse files

Implemented moving average filter on ADC samples

parent 467a3ffa
......@@ -468,7 +468,7 @@ begin
frd_data_cnt <= frd_data_cnt + 1;
end if;
-- enable read out of samples from RAM
-- enable reading samples from RAM
-- assert data valid according to the fisrt sample location within RAM address
if frd_DataOutValid = '1' then
if PreTrigSavingCntMod_d = 0 then
......
......@@ -361,18 +361,34 @@ architecture rtl of fpga is
pll_locked : out STD_LOGIC);
end component;
component clk_wiz_0
port
(-- Clock in ports
-- Clock out ports
clk_out1 : out std_logic;
clk_out2 : out std_logic;
-- Status and control signals
reset : in std_logic;
locked : out std_logic;
clk_in1 : in std_logic
);
end component;
component clk_wiz_0
port
(-- Clock in ports
-- Clock out ports
clk_out1 : out std_logic;
clk_out2 : out std_logic;
-- Status and control signals
reset : in std_logic;
locked : out std_logic;
clk_in1 : in std_logic
);
end component;
component mavg is
generic (
MAX_MAVG_LEN_LOG : integer := 2
);
port (
i_clk : in std_logic;
i_rst : in std_logic;
-- input
mavg_len_log : in integer range 0 to MAX_MAVG_LEN_LOG;
i_data_en : in std_logic;
i_data : in std_logic_vector(9 downto 0);
-- output
o_data_valid : out std_logic;
o_data : out std_logic_vector(9 downto 0));
end component;
signal clk_adc_dclk : std_logic;
signal clk_adc_p_delayed : std_logic;
......@@ -817,7 +833,7 @@ signal DebugMState : integer range 0 to 7;
signal DebugADCState : integer range 0 to 7;
signal DebugADCState_d : integer range 0 to 7;
signal PreTrigSaving : std_logic := '0';
signal DataIn : std_logic_vector(31 downto 0);
signal DDR3DataIn : std_logic_vector(31 downto 0);
signal DataInTest : unsigned (31 downto 0);
signal DataWriteEn : std_logic;
signal DataWriteEn_d : std_logic;
......@@ -838,6 +854,16 @@ signal device_temp_d : std_logic_vector(11 downto 0);
signal device_temp_dd : std_logic_vector(11 downto 0);
signal ram_rdy : std_logic;
--adc post-processing
signal mavg_enA: std_logic;
signal mavg_enA_d: std_logic;
signal mavg_datavalidA : std_logic;
signal mavg_dataA : std_logic_vector(9 downto 0);
signal mavg_enB: std_logic;
signal mavg_enB_d: std_logic;
signal mavg_datavalidB : std_logic;
signal mavg_dataB : std_logic_vector(9 downto 0);
-- attribute strings
attribute KEEP: boolean;
attribute ASYNC_REG: boolean;
......@@ -1012,7 +1038,7 @@ port map (
ui_clk => ifclk,
rst => clearflags,
FrameSize => framesize_dd,
DataIn => std_logic_vector(dataAd) & std_logic_vector(dataBd) & dataDd(11 downto 0),
DataIn => DDR3DataIn,
--DataIn => std_logic_vector(to_unsigned(saved_sample_cnt_d,32)), --* debug!
-- DataIn => std_logic_vector(DataInTest (9 downto 0))
-- & std_logic_vector(DataInTest (9 downto 0))
......@@ -1277,6 +1303,30 @@ clk_wiz_0_pll : clk_wiz_0
clk_in1 => clk_adc_dclk
);
mavg_ch1: mavg
generic map (MAX_MAVG_LEN_LOG => 2)
PORT MAP (
i_clk => clk_adc_dclk,
i_rst => clearflags_d,
mavg_len_log => 2,
i_data_en => mavg_enA,
i_data => dataA,
o_data_valid => mavg_datavalidA,
o_data => mavg_dataA
);
mavg_ch2: mavg
generic map (MAX_MAVG_LEN_LOG => 2)
PORT MAP (
i_clk => clk_adc_dclk,
i_rst => clearflags_d,
mavg_len_log => 2,
i_data_en => mavg_enB,
i_data => dataB,
o_data_valid => mavg_datavalidB,
o_data => mavg_dataB
);
clk_fx3 <= not(ifclk);
slcs <= '0';
......@@ -1310,6 +1360,8 @@ pktend <= '1'; -- TODO:
--LED_i(1) <= NOT(init_calib_complete_d); -- debug led
--LED_i(1) <= not(dac_pll_locked); -- debug led
DDR3DataIn <= std_logic_vector(dataAd) & std_logic_vector(dataBd) & dataDd(11 downto 0);
ADC_interface_rising: process(clk_adc_dclk)
begin
......@@ -1330,9 +1382,17 @@ begin
-- read digital channels
dataDd <= dataD;
--dataDd <= "00" & std_logic_vector(unsigned(genSignal_1_dd)); --test (debug)!
-- read ADC data
dataAd <= signed(dataA);
dataBd <= signed(dataB);
-- read ADC data and enable averaging
if mavg_enA_d = '1' then
dataAd <= signed(mavg_dataA);
else
dataAd <= signed(dataA);
end if;
if mavg_enB_d = '1' then
dataBd <= signed(mavg_dataB);
else
dataBd <= signed(dataB);
end if;
genSignal_1_d <= genSignal_1(11 downto 2);
genSignal_1_dd <= genSignal_1_d;
......@@ -1472,6 +1532,8 @@ begin
when 27 =>
digitalClkDivide_L <= cfg_do_B(31 downto 16);
digitalClkDivide_tmp <= digitalClkDivide_H & digitalClkDivide_L;
mavg_enA <= cfg_do_B(9);
mavg_enB <= cfg_do_B(8);
when 28 =>
digitalClkDivide <= unsigned(digitalClkDivide_tmp);
when others => null;
......@@ -1515,6 +1577,7 @@ begin
PreTrigWriteEn <= '0';
else
-- select signal for trigger source
trig_signal_d <= trig_signal; -- monitor current and next value for trigger
......@@ -1608,6 +1671,9 @@ begin
digital_OutputWordMask_d <= digital_OutputWordMask;
digital_direction_d <= digital_Direction;
ets_on_d <= ets_on;
mavg_enA_d <= mavg_enA;
mavg_enB_d <= mavg_enB;
saved_sample_cnt <= 0;
saved_sample_cnt_d <= 0;
......
......@@ -155,7 +155,7 @@ BEGIN
DataIn <= X"000000DD000000010000000200000003";
end if;
if writing_frame = '1' then
if wr_skip_cnt = 21 then
if wr_skip_cnt = 23 then
WriteEn <= '1';
wr_skip_cnt <= 0;
else
......@@ -187,7 +187,7 @@ BEGIN
for i in 0 to 150 loop
wait until rising_edge(clk);
flagd <= '0';
for i in 0 to 80 loop
for i in 0 to 56 loop
wait until rising_edge(clk);
end loop;
flagd <= '1';
......@@ -195,7 +195,7 @@ BEGIN
wait until rising_edge(clk);
end loop;
flagd <= '0';
for i in 0 to 128 loop
for i in 0 to 82 loop
wait until rising_edge(clk);
end loop;
flagd <= '1';
......
----------------------------------------------------------------------------------
-- Copyright (C) 2019 Dejan Priversek
--
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mavg is
generic (
MAX_MAVG_LEN_LOG : integer := 2
);
port (
i_clk : in std_logic;
i_rst : in std_logic;
-- input
mavg_len_log : in integer range 0 to MAX_MAVG_LEN_LOG;
i_data_en : in std_logic;
i_data : in std_logic_vector(9 downto 0);
-- output
o_data_valid : out std_logic;
o_data : out std_logic_vector(9 downto 0));
end mavg;
architecture Behavioral of mavg is
type t_mavg is array (0 to 2**MAX_MAVG_LEN_LOG-1) of signed(9 downto 0);
signal p_mavg : t_mavg;
signal r_acc : signed(10+MAX_MAVG_LEN_LOG-1 downto 0); -- average accumulator
signal cnt_invalid : unsigned(MAX_MAVG_LEN_LOG-1 downto 0):= to_unsigned(0,MAX_MAVG_LEN_LOG);
signal cnt_valid : unsigned(MAX_MAVG_LEN_LOG-1 downto 0):= to_unsigned(0,MAX_MAVG_LEN_LOG);
signal i_data_valid : std_logic;
begin
mavg: process(i_clk)
begin
if(rising_edge(i_clk)) then
o_data_valid <= i_data_valid;
-- if (i_rst='1') then
-- i_data_valid <= '0';
-- r_acc <= (others=>'0');
-- p_mavg <= (others=>(others=>'0'));
if (i_data_en='1') then
-- Moving average is enabled
-- count when dataout will be valid
if i_data_valid = '0' then
if cnt_invalid = to_unsigned(2**mavg_len_log-1,cnt_invalid'LENGTH) then
i_data_valid <= '1';
cnt_invalid <= to_unsigned(0,cnt_invalid'LENGTH);
else
i_data_valid <= '0';
cnt_invalid <= cnt_invalid + 1;
end if;
end if;
p_mavg <= signed(i_data)&p_mavg(0 to p_mavg'length-2);
r_acc <= r_acc + signed(i_data) - p_mavg(p_mavg'length-1);
else
-- Moving average is DISABLED
i_data_valid <= '0';
r_acc <= (others=>'0');
p_mavg <= (others=>(others=>'0'));
end if;
o_data <= std_logic_vector(r_acc(10+mavg_len_log-1 downto mavg_len_log)); -- divide by 2^mavg_len
end if;
end process mavg;
end Behavioral;
\ No newline at end of file
----------------------------------------------------------------------------------
-- Copyright (C) 2019 Dejan Priversek
--
-- 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;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY mavg_tb IS
END mavg_tb;
ARCHITECTURE behavior OF mavg_tb IS
-- Component Declaration for the Unit Under Test (UUT)
component mavg is
generic (
MAX_MAVG_LEN_LOG : integer := 3
);
port (
i_clk : in std_logic;
i_rst : in std_logic;
-- input
mavg_len_log : in integer range 0 to MAX_MAVG_LEN_LOG;
i_data_en : in std_logic;
i_data : in std_logic_vector(9 downto 0);
-- output
o_data_valid : out std_logic;
o_data : out std_logic_vector(9 downto 0));
end component;
--constants
CONSTANT MAX_MAVG_LEN_LOG : integer := 3;
--Inputs
signal i_clk : std_logic := '0';
signal i_rst : std_logic := '0';
signal i_data_en : std_logic := '0';
signal mavg_len_log : integer range 0 to MAX_MAVG_LEN_LOG :=MAX_MAVG_LEN_LOG;
signal i_data : std_logic_vector(9 downto 0) := (others => '0');
--Outputs
signal o_data_valid : std_logic;
signal o_data : std_logic_vector(9 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
constant clk_divide_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: mavg
generic map (MAX_MAVG_LEN_LOG => MAX_MAVG_LEN_LOG)
PORT MAP (
i_clk => i_clk,
i_rst => i_rst,
mavg_len_log => mavg_len_log,
i_data_en => i_data_en,
i_data => i_data,
o_data_valid => o_data_valid,
o_data => o_data
);
-- Clock process definitions
clk_process :process
begin
i_clk <= '0';
wait for clk_period/2;
i_clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
variable counter1 : signed (9 downto 0) := to_signed(-12,i_data'length);
variable counter2 : signed (9 downto 0) := to_signed(-12,i_data'length);
begin
i_rst <= '0';
wait until rising_edge(i_clk);
mavg_len_log <= MAX_MAVG_LEN_LOG;
i_rst <= '1';
wait until rising_edge(i_clk);
i_rst <= '0';
--generate input data
while counter1 < to_signed(63,counter1'LENGTH) loop
wait until rising_edge(i_clk);
counter1 := counter1 + 2;
i_data_en <= '1';
i_data <= std_logic_vector(counter1);
end loop;
wait until rising_edge(i_clk);
i_rst <= '0';
i_data_en <= '0';
end process;
END;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment