aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Woods2023-02-24 17:20:09 -0500
committerBrian Woods2023-02-27 12:47:00 -0500
commitf3268337719d8d94b1ea791f1b00425daf8db1f7 (patch)
treecb8f7acddb449cc6fa93d612582349df7c8fab07
parentfb64bf7d3c180973a279916825d69674a4fd4ba5 (diff)
averaging_filter: add base files
Need to do more testing, possibly some Octave input and output.
-rw-r--r--averaging_filter/Makefile34
-rw-r--r--averaging_filter/averaging_filter.vhd54
-rw-r--r--averaging_filter/simulation.vhd79
-rw-r--r--averaging_filter/top.vhd46
4 files changed, 213 insertions, 0 deletions
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;