From f3268337719d8d94b1ea791f1b00425daf8db1f7 Mon Sep 17 00:00:00 2001 From: Brian Woods Date: Fri, 24 Feb 2023 17:20:09 -0500 Subject: averaging_filter: add base files Need to do more testing, possibly some Octave input and output. --- averaging_filter/Makefile | 34 +++++++++++++++ averaging_filter/averaging_filter.vhd | 54 ++++++++++++++++++++++++ averaging_filter/simulation.vhd | 79 +++++++++++++++++++++++++++++++++++ averaging_filter/top.vhd | 46 ++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 averaging_filter/Makefile create mode 100644 averaging_filter/averaging_filter.vhd create mode 100644 averaging_filter/simulation.vhd create mode 100644 averaging_filter/top.vhd diff --git a/averaging_filter/Makefile b/averaging_filter/Makefile new file mode 100644 index 0000000..69a09ca --- /dev/null +++ b/averaging_filter/Makefile @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2023 Brian Woods +# SPDX-License-Identifier: GPL-2.0-or-later + +# this is for ghdl-gcc, I've not tested it on ghdl-llvm but it will not +# work with ghdl-mcode + +SRC=simulation.vhd top.vhd averaging_filter.vhd +OBJ=$(SRC:.vhd=.o) +TOP=simulation +TOP_OBJ=e~$(TOP).o +WAVE_DUMP=$(TOP).ghw +WAVE_CONF=$(TOP).gtkw +WORKLIB=work +FLAGS=--std=08 --work=$(WORKLIB) +TIME=1us + +.PHONY: all clean sim + +all: $(TOP) + +%.o: %.vhd + ghdl -a $(FLAGS) $< + +$(TOP): $(OBJ) + ghdl -e $(FLAGS) $@ + +$(WAVE_DUMP): $(TOP) + ghdl -r $(FLAGS) $< --wave=$@ --stop-time=$(TIME) + +sim: $(WAVE_DUMP) + gtkwave --save $(WAVE_CONF) --saveonexit $< + +clean: + rm -f $(OBJ) $(TOP_OBJ) $(TOP) $(WAVE_DUMP) $(WAVE_CONF) $(WORKLIB)-obj*.cf diff --git a/averaging_filter/averaging_filter.vhd b/averaging_filter/averaging_filter.vhd new file mode 100644 index 0000000..3792d96 --- /dev/null +++ b/averaging_filter/averaging_filter.vhd @@ -0,0 +1,54 @@ +-- SPDX-FileCopyrightText: 2023 Brian Woods +-- SPDX-License-Identifier: GPL-2.0-or-later + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use IEEE.math_real.ceil; +use IEEE.math_real.log2; + +entity averaging_filter is + generic ( + data_width: integer := 16; + averaging_amount: integer := 32; + overflow_buffer: integer := + integer(ceil(log2(real(averaging_amount)))) + ); + port( + input: in signed(data_width-1 downto 0); + output: out signed(data_width-1 downto 0); + en: in std_logic; + clr: in std_logic; + clk: in std_logic + ); +end entity; + +architecture func of averaging_filter is + --constant overflow_buffer: integer := + -- integer(ceil(log2(averaging_amount))); + type data_array_type is + array (0 to averaging_amount-1) of + signed(data_width-1 downto 0); + signal data_array: data_array_type; + signal running_sum: signed (data_width + overflow_buffer - 1 downto 0); +begin + process (clk, clr) + begin + if (clr='1') then + data_array <= (others => (others => '0')); + running_sum <= (others => '0'); + elsif (clk='1' and clk'event) then + if (en='1') then + running_sum <= running_sum - + resize(data_array(averaging_amount-1), + running_sum'length) + + resize(input, running_sum'length); + data_array(1 to averaging_amount-1) <= + data_array(0 to averaging_amount-2); + data_array(0) <= input; + end if; + end if; + end process; + output <= running_sum(data_width + overflow_buffer - 1 + downto overflow_buffer); +end func; diff --git a/averaging_filter/simulation.vhd b/averaging_filter/simulation.vhd new file mode 100644 index 0000000..a341f48 --- /dev/null +++ b/averaging_filter/simulation.vhd @@ -0,0 +1,79 @@ +-- SPDX-FileCopyrightText: 2023 Brian Woods +-- SPDX-License-Identifier: GPL-2.0-or-later + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity simulation is +end; + +architecture sim of simulation is + component top is + port( + input: in signed(17 downto 0); + output: out signed(17 downto 0); + en: in std_logic; + clr: in std_logic; + clk: in std_logic + ); + end component; + + signal input: signed(17 downto 0) := (others => '0'); + signal output: signed(17 downto 0); + signal en: std_logic := '0'; + signal clr: std_logic := '0'; + signal clk: std_logic := '0'; + signal int_input: integer := 0; + signal int_output: integer; +begin + dut: top port map( + input => input, + output => output, + en => en, + clr => clr, + clk => clk + ); + + clk <= not clk after 5 ns; + + int_output <= to_integer(output); + --int_output <= 42; + input <= to_signed(int_input, input'length); + + process begin + -- at 0 ns + int_input <= 100000; + en <= '0'; + clr <= '1'; + wait for 10 ns; + + -- at 10 ns + int_input <= 100000; + en <= '1'; + clr <= '1'; + wait for 10 ns; + + -- at 20 ns + int_input <= 100000; + en <= '1'; + clr <= '0'; + wait for 80 ns; + + -- at 100 ns + int_input <= 100000; + en <= '1'; + clr <= '0'; + wait for 300 ns; + + -- at 400 ns + int_input <= 100000; + en <= '0'; + clr <= '0'; + wait for 10 ns; + + -- end sim + wait; + end process; + +end sim; diff --git a/averaging_filter/top.vhd b/averaging_filter/top.vhd new file mode 100644 index 0000000..8241877 --- /dev/null +++ b/averaging_filter/top.vhd @@ -0,0 +1,46 @@ +-- SPDX-FileCopyrightText: 2023 Brian Woods +-- SPDX-License-Identifier: GPL-2.0-or-later + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity top is + port( + input: in signed(17 downto 0); + output: out signed(17 downto 0); + en: in std_logic; + clr: in std_logic; + clk: in std_logic + ); +end entity; + +architecture func of top is + component averaging_filter is + generic ( + data_width: integer; + averaging_amount: integer + ); + port( + input: in signed(data_width-1 downto 0); + output: out signed(data_width-1 downto 0); + en: in std_logic; + clr: in std_logic; + clk: in std_logic + ); + end component; +begin + -- controlled by the top signals + filter01: averaging_filter + generic map( + data_width => 18, + averaging_amount => 16 + ) + port map( + input => input, + output => output, + en => en, + clr => clr, + clk => clk + ); +end func; -- cgit v1.2.3