aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Woods2023-04-12 12:55:22 -0400
committerBrian Woods2023-04-12 12:55:22 -0400
commit68083e9e02744022631d5b77e119f8d0fcb306b8 (patch)
tree2269ea10e709218a12b2854af8dcacb6e72a0696
parent2e5b437fc94aa989ca81aa820739178281d218d8 (diff)
mixed_hdl: add init filesHEADmaster
This isn't fully mixed but rather it supports VHDL modiles in a verilog simulation. You can't have verilog undernearth the VHDL either. It uses the ghdl (v3 or higher) synth option to synth the VHDL top modules to verilog and then it uses those with Icarus.
-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