From ea52764fc476246629120a869ddbe15422a6f7e9 Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Sun, 28 Feb 2021 22:11:17 -0800 Subject: [PATCH] Add pdmout module --- wave/makefile | 17 ++++++ wave/pdmout.vhdl | 78 +++++++++++++++++++++++++ wave/pdmout_test.vhdl | 128 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 wave/makefile create mode 100644 wave/pdmout.vhdl create mode 100644 wave/pdmout_test.vhdl diff --git a/wave/makefile b/wave/makefile new file mode 100644 index 0000000..b0dc89b --- /dev/null +++ b/wave/makefile @@ -0,0 +1,17 @@ +all: sim +sim: test.ghw + +sim_sources = pdmout_test.vhdl +sources = pdmout.vhdl + + +test.ghw: work-obj93.cf + ghdl -r pdmout_test --wave=$@ + + +work-obj93.cf: $(sim_sources) $(sources) + ghdl -a $^ + +PHONY: sim + +.PRECIOUS: test.ghw diff --git a/wave/pdmout.vhdl b/wave/pdmout.vhdl new file mode 100644 index 0000000..85ff681 --- /dev/null +++ b/wave/pdmout.vhdl @@ -0,0 +1,78 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity pdmout is + port + ( + clk : in std_logic; + rst : in std_logic; + + -- hardware + out_pin : out std_logic; + + -- bus interface + we : in std_logic; + addr : in std_logic_vector(15 downto 0); + din : in std_logic_vector(15 downto 0) + ); +end pdmout; + +-- +-- Mem layout: +-- 0x00: 16-bit unsigned amplitude +-- 0x02: flags: [enabled] + +architecture Behavioral of pdmout is + + signal sample: std_logic_vector(15 downto 0); + signal feedback: signed(16 downto 0); + signal enabled: std_logic; + +begin + + -- PDM process + -- drives pin_out, feedback + process(clk, rst) + begin + + if rst = '1' then + feedback <= to_signed(0, 17); + out_pin <= '0'; + elsif rising_edge(clk) then + if feedback > 0 then + out_pin <= '1'; + feedback <= feedback + signed("0" & sample) - ("0" & x"ffff"); + else + out_pin <= '0'; + feedback <= feedback + signed("0" & sample); + end if; + end if; + + end process; + + -- Bus process + -- drives sample, enabled + process(clk, rst) + begin + + if rst = '1' then + sample <= x"0000"; + enabled <= '0'; + elsif rising_edge(clk) then + case addr(3 downto 0) is + when x"0" => + if we = '1' then + sample <= din; + end if; + when x"2" => + if we = '1' then + enabled <= din(0); + end if; + when others => + end case; + end if; + + end process; + +end Behavioral; diff --git a/wave/pdmout_test.vhdl b/wave/pdmout_test.vhdl new file mode 100644 index 0000000..eecc0f9 --- /dev/null +++ b/wave/pdmout_test.vhdl @@ -0,0 +1,128 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use std.textio.all; + +entity pdmout_test is +end pdmout_test; + +architecture rtl of pdmout_test is + + component pdmout is + port + ( + clk : in std_logic; + rst : in std_logic; + + -- hardware + out_pin : out std_logic; + + -- bus interface + we : in std_logic; + addr : in std_logic_vector(15 downto 0); + din : in std_logic_vector(15 downto 0) + ); + end component; + + signal finished: std_logic := '0'; + signal clk: std_logic := '0'; + signal rst, bus_we, pdm_out: std_logic; + signal bus_miso, bus_mosi, bus_addr: std_logic_vector(15 downto 0); + +begin + dut: pdmout port map(clk => clk, rst => rst, out_pin => pdm_out, + we => bus_we, addr => bus_addr, + din => bus_mosi); + + process + begin + if finished = '0' then + clk <= not clk; + wait for 5 ns; + else + clk <= '0'; + wait; + end if; + end process; + + process + begin + rst <= '1'; + + wait for 1 ns; + assert(pdm_out='0') report "Fail rst" severity error; + + rst <= '0'; + + wait for 10 ns; + + bus_addr <= x"0000"; + bus_mosi <= x"8000"; + bus_we <= '1'; + + wait for 10 ns; + assert(pdm_out='0') report "enabled didn't work?" severity error; + + bus_addr <= x"0002"; + bus_mosi <= x"0001"; + bus_we <= '1'; + + wait for 10 ns; + + bus_addr <= x"0000"; + bus_we <= '0'; + + wait for 20 ns; + assert(pdm_out='1') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='1') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='1') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + + bus_addr <= x"0000"; + bus_mosi <= x"0000"; + bus_we <= '1'; + + wait for 10 ns; + + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + + bus_addr <= x"0000"; + bus_mosi <= x"4000"; + bus_we <= '1'; + wait for 10 ns; + + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='1') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='1') report "output is wrong" severity error; + wait for 10 ns; + assert(pdm_out='0') report "output is wrong" severity error; + + + assert false report "Test done." severity note; + + finished <= '1'; + wait; + + end process; +end rtl;