diff options
Diffstat (limited to 'mixed_hdl')
-rw-r--r-- | mixed_hdl/Makefile | 44 | ||||
-rw-r--r-- | mixed_hdl/averaging_filter.vhd | 55 | ||||
-rw-r--r-- | mixed_hdl/averaging_filter_cfg.vhd | 48 | ||||
-rw-r--r-- | mixed_hdl/counter.v | 23 | ||||
-rw-r--r-- | mixed_hdl/simulation.v | 41 | ||||
-rw-r--r-- | mixed_hdl/top.v | 26 |
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 |