aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mixed_hdl/Makefile44
-rw-r--r--mixed_hdl/averaging_filter.vhd55
-rw-r--r--mixed_hdl/averaging_filter_cfg.vhd48
-rw-r--r--mixed_hdl/counter.v23
-rw-r--r--mixed_hdl/simulation.v41
-rw-r--r--mixed_hdl/top.v26
6 files changed, 237 insertions, 0 deletions
diff --git a/mixed_hdl/Makefile b/mixed_hdl/Makefile
new file mode 100644
index 0000000..a1dcd37
--- /dev/null
+++ b/mixed_hdl/Makefile
@@ -0,0 +1,44 @@
+# SPDX-FileCopyrightText: 2023 Brian Woods
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# this is for ghdl-gcc or ghdl-llvm but it will not work with ghdl-mcode
+
+VERI_SRC=simulation.v top.v counter.v averaging_filter_cfg.v
+VHDL_SRC=averaging_filter.vhd averaging_filter_cfg.vhd
+# These are the top level of modules to import to verilog
+VHDL_MTOP=averaging_filter_cfg
+
+# top module, we also use this for the object name
+TOP=simulation
+# this needs to match what's in top sim file
+WAVE_DUMP=simulation.vcd
+
+VHDL_OBJ=$(VHDL_SRC:.vhd=.o)
+VHDL_MTOP_VERI=$(addsuffix .v, $(VHDL_MTOP))
+SRC=$(VERI_SRC) $(VHDL_MTOP_VERI)
+WAVE_CONF=$(TOP).gtkw
+VERI_FLAGS=
+VHDL_WORKLIB=work
+VHDL_FLAGS=--std=08 --work=$(VHDL_WORKLIB)
+
+.PHONY: all clean sim
+
+all: $(TOP)
+
+$(VHDL_MTOP_VERI): %.v: $(VHDL_OBJ)
+ ghdl synth $(VHDL_FLAGS) --out=verilog $($@:.v=) > $@
+
+$(VHDL_OBJ): %.o: %.vhd
+ ghdl analyze $(VHDL_FLAGS) $<
+
+$(TOP): $(SRC)
+ iverilog -o $@ $(FLAGS) -s $@ $^
+
+$(WAVE_DUMP): $(TOP)
+ vvp $<
+
+sim: $(WAVE_DUMP)
+ gtkwave --save $(WAVE_CONF) --saveonexit $<
+
+clean:
+ rm -f $(TOP) $(VHDL_OBJ) $(VHDL_MTOP_VERI) $(VHDL_WORKLIB)-obj08.cf $(WAVE_DUMP) $(WAVE_CONF)
diff --git a/mixed_hdl/averaging_filter.vhd b/mixed_hdl/averaging_filter.vhd
new file mode 100644
index 0000000..5e45aa9
--- /dev/null
+++ b/mixed_hdl/averaging_filter.vhd
@@ -0,0 +1,55 @@
+-- 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(
+ data_in: in signed(data_width-1 downto 0);
+ data_out: out signed(data_width-1 downto 0);
+ en: in std_logic;
+ dr: out std_logic;
+ clr: in std_logic;
+ clk: in std_logic
+ );
+end entity;
+
+architecture func of averaging_filter is
+ 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');
+ dr <= '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(data_in, running_sum'length);
+ data_array(1 to averaging_amount-1) <=
+ data_array(0 to averaging_amount-2);
+ data_array(0) <= data_in;
+ end if;
+ dr <= en;
+ end if;
+ end process;
+ data_out <= running_sum(data_width + overflow_buffer - 1
+ downto overflow_buffer);
+end func;
diff --git a/mixed_hdl/averaging_filter_cfg.vhd b/mixed_hdl/averaging_filter_cfg.vhd
new file mode 100644
index 0000000..9772041
--- /dev/null
+++ b/mixed_hdl/averaging_filter_cfg.vhd
@@ -0,0 +1,48 @@
+-- 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 averaging_filter_cfg is
+ port(
+ data_in: in signed(7 downto 0);
+ data_out: out signed(7 downto 0);
+ en: in std_logic;
+ dr: out std_logic;
+ clr: in std_logic;
+ clk: in std_logic
+ );
+end entity;
+
+architecture func of averaging_filter_cfg is
+ component averaging_filter is
+ generic (
+ data_width: integer;
+ averaging_amount: integer
+ );
+ port(
+ data_in: in signed(data_width-1 downto 0);
+ data_out: out signed(data_width-1 downto 0);
+ en: in std_logic;
+ dr: out std_logic;
+ clr: in std_logic;
+ clk: in std_logic
+ );
+ end component;
+begin
+ filter_cfg: averaging_filter
+ generic map(
+ data_width => 8,
+ averaging_amount => 4
+ )
+ port map(
+ data_in => data_in,
+ data_out => data_out,
+ en => en,
+ dr => dr,
+ clr => clr,
+ clk => clk
+ );
+end func;
diff --git a/mixed_hdl/counter.v b/mixed_hdl/counter.v
new file mode 100644
index 0000000..23ab9f2
--- /dev/null
+++ b/mixed_hdl/counter.v
@@ -0,0 +1,23 @@
+module counter(count, dr, en, rst, clk);
+
+ parameter WIDTH = 8;
+
+ output [WIDTH-1: 0] count;
+ output dr;
+ input en, rst, clk;
+
+ reg [WIDTH-1: 0] count;
+ wire en, rst, clk;
+ reg dr;
+
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst)
+ count <= 0;
+ else
+ dr <= en;
+ if (en)
+ count <= count + 1;
+ end
+
+endmodule // counter
diff --git a/mixed_hdl/simulation.v b/mixed_hdl/simulation.v
new file mode 100644
index 0000000..6b6e298
--- /dev/null
+++ b/mixed_hdl/simulation.v
@@ -0,0 +1,41 @@
+module simulation;
+
+ reg rst = 0;
+ reg clk = 0;
+ reg en = 0;
+ wire [7:0] count;
+ wire [7:0] out_data;
+ wire dr;
+
+ /* Make a reset that pulses once. */
+ initial begin
+ $dumpfile("simulation.vcd");
+ $dumpvars(0, simulation);
+
+ # 17 rst = 1;
+ # 11 rst = 0;
+ # 29 rst = 1;
+ # 11 rst = 0;
+ //# 100 $stop;
+ # 1000 $finish;
+ end
+
+ /* Make a regular pulsing clock. */
+ always #5 clk = !clk;
+
+ initial begin
+ #60
+ forever #10 en = !en;
+ end
+
+ top top_logic (count,
+ out_data,
+ dr,
+ en,
+ rst,
+ clk);
+
+ initial
+ $monitor("At time %t, value = %h (%0d)",
+ $time, out_data, out_data);
+endmodule // simulation
diff --git a/mixed_hdl/top.v b/mixed_hdl/top.v
new file mode 100644
index 0000000..ce9083b
--- /dev/null
+++ b/mixed_hdl/top.v
@@ -0,0 +1,26 @@
+module top(count, out_data, dr, en, rst, clk);
+
+ parameter WIDTH = 8;
+
+ output [WIDTH-1: 0] count;
+ output [WIDTH-1: 0] out_data;
+ output dr;
+ input en, clk, rst;
+
+ wire [WIDTH-1: 0] counter;
+ wire counter_to_filter;
+
+ assign count = counter;
+ counter #(WIDTH) counter_1 (counter,
+ counter_to_filter,
+ en,
+ rst,
+ clk);
+ averaging_filter_cfg filter_1(counter,
+ counter_to_filter,
+ rst,
+ clk,
+ out_data,
+ dr);
+
+endmodule // top