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;