wave: axi4-compliant wave
This commit is contained in:
46
wave/pdm.vhdl
Normal file
46
wave/pdm.vhdl
Normal file
@@ -0,0 +1,46 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity pdm is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
-- hardware
|
||||
out_pin : out std_logic;
|
||||
|
||||
-- input interface
|
||||
enabled : in std_logic;
|
||||
sample : in std_logic_vector(15 downto 0)
|
||||
);
|
||||
end pdm;
|
||||
|
||||
architecture Behavioral of pdm is
|
||||
|
||||
signal feedback: signed(16 downto 0);
|
||||
|
||||
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) and enabled = '1' 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;
|
||||
|
||||
end Behavioral;
|
||||
175
wave/wave.vhdl
Normal file
175
wave/wave.vhdl
Normal file
@@ -0,0 +1,175 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
-- some kind of square wave generator, with PDM output
|
||||
entity wave is
|
||||
port
|
||||
(
|
||||
-- AXI4 slave interface
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
|
||||
-- read addr
|
||||
araddr : in std_logic_vector(31 downto 0);
|
||||
arvalid : in std_logic;
|
||||
arready : out std_logic;
|
||||
|
||||
-- read data
|
||||
rdata : out std_logic_vector(31 downto 0);
|
||||
rresp : out std_logic;
|
||||
rvalid : out std_logic;
|
||||
rready : in std_logic;
|
||||
|
||||
-- write addr
|
||||
awaddr : in std_logic_vector(31 downto 0);
|
||||
awvalid : in std_logic;
|
||||
awready : out std_logic;
|
||||
|
||||
-- write data
|
||||
wdata : in std_logic_vector(31 downto 0);
|
||||
wstrb : in std_logic_vector(3 downto 0);
|
||||
|
||||
-- write resp
|
||||
bresp : out std_logic;
|
||||
bvalid : out std_logic;
|
||||
bready : in std_logic;
|
||||
|
||||
|
||||
-- PDM output!
|
||||
pdmout : out std_logic
|
||||
);
|
||||
end wave;
|
||||
|
||||
--
|
||||
-- Mem layout:
|
||||
-- 0x00: control: [bit0: enabled]
|
||||
-- 0x04: 32-bit unsigned period (in clock cycles)
|
||||
-- 0x08: 16-bit unsigned high value (high 16 bits ignored)
|
||||
-- 0x0c: 16-bit unsigned low value (high 16 bits ignored)
|
||||
|
||||
architecture Behavioral of wave is
|
||||
|
||||
component pdm is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
-- hardware
|
||||
out_pin : out std_logic;
|
||||
|
||||
-- input interface
|
||||
enabled : in std_logic;
|
||||
sample : in std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
-- all registers
|
||||
signal period, hi_val, lo_val, sample: std_logic_vector(15 downto 0);
|
||||
signal enabled, rst, onwrite: std_logic;
|
||||
signal counter: unsigned(23 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
arready <= '1';
|
||||
awready <= '1';
|
||||
rst <= not aresetn;
|
||||
|
||||
pdm0: pdm port map(clk => aclk, rst => rst, out_pin => pdmout,
|
||||
sample => sample, enabled => enabled);
|
||||
|
||||
-- main process
|
||||
-- drives counter, sample
|
||||
process(aclk, aresetn)
|
||||
variable high: std_logic;
|
||||
begin
|
||||
|
||||
if aresetn = '0' then
|
||||
counter <= to_unsigned(0, 24);
|
||||
sample <= x"0000";
|
||||
high := '0';
|
||||
elsif rising_edge(aclk) then
|
||||
counter <= to_unsigned(0, 24);
|
||||
if high = '1' then
|
||||
sample <= hi_val;
|
||||
else
|
||||
sample <= lo_val;
|
||||
end if;
|
||||
|
||||
if enabled = '1' and unsigned(period) /= 0 and onwrite = '0' then
|
||||
if counter(22 downto 7) = unsigned(period) - 1
|
||||
and counter(6 downto 0) = x"7f" then
|
||||
high := not high;
|
||||
else
|
||||
counter <= counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-- Bus slave process
|
||||
-- drives period, value, out_addr, enabled, onwrite
|
||||
process(aclk, aresetn)
|
||||
-- 00: control, 01: period, 02: high, 03: low
|
||||
variable waddr: std_logic_vector(2 downto 0);
|
||||
variable raddr: std_logic_vector(2 downto 0);
|
||||
begin
|
||||
|
||||
if aresetn = '0' then
|
||||
period <= x"0000";
|
||||
hi_val <= x"0000";
|
||||
lo_val <= x"0000";
|
||||
enabled <= '0';
|
||||
waddr := "000";
|
||||
|
||||
elsif rising_edge(aclk) then
|
||||
|
||||
rvalid <= '0';
|
||||
rdata <= x"00000000";
|
||||
rresp <= '0';
|
||||
bvalid <= '0';
|
||||
bresp <= '0';
|
||||
onwrite <= '0';
|
||||
|
||||
if arvalid = '1' then
|
||||
raddr := araddr(4 downto 2);
|
||||
end if;
|
||||
if awvalid = '1' then
|
||||
waddr := awaddr(4 downto 2);
|
||||
end if;
|
||||
if arvalid = '1' then
|
||||
case waddr(1 downto 0) is
|
||||
when "00" =>
|
||||
rdata(0) <= enabled;
|
||||
when "01" =>
|
||||
rdata(23 downto 8) <= period;
|
||||
when "10" =>
|
||||
rdata(15 downto 0) <= hi_val;
|
||||
when "11" =>
|
||||
rdata(15 downto 0) <= lo_val;
|
||||
when others =>
|
||||
end case;
|
||||
rvalid <= '1';
|
||||
end if;
|
||||
if unsigned(wstrb) > 0 then
|
||||
case waddr(1 downto 0) is
|
||||
when "00" =>
|
||||
enabled <= wdata(0);
|
||||
when "01" =>
|
||||
period <= wdata(23 downto 8);
|
||||
when "10" =>
|
||||
hi_val <= wdata(15 downto 0);
|
||||
when "11" =>
|
||||
lo_val <= wdata(15 downto 0);
|
||||
when others =>
|
||||
end case;
|
||||
bvalid <= '1';
|
||||
onwrite <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
165
wave/wave_test.vhdl
Normal file
165
wave/wave_test.vhdl
Normal file
@@ -0,0 +1,165 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity wave_test is
|
||||
end wave_test;
|
||||
|
||||
architecture rtl of wave_test is
|
||||
|
||||
component wave is
|
||||
port
|
||||
(
|
||||
-- AXI4 slave interface
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
|
||||
-- read addr
|
||||
araddr : in std_logic_vector(31 downto 0);
|
||||
arvalid : in std_logic;
|
||||
arready : out std_logic;
|
||||
|
||||
-- read data
|
||||
rdata : out std_logic_vector(31 downto 0);
|
||||
rresp : out std_logic;
|
||||
rvalid : out std_logic;
|
||||
rready : in std_logic;
|
||||
|
||||
-- write addr
|
||||
awaddr : in std_logic_vector(31 downto 0);
|
||||
awvalid : in std_logic;
|
||||
awready : out std_logic;
|
||||
|
||||
-- write data
|
||||
wdata : in std_logic_vector(31 downto 0);
|
||||
wstrb : in std_logic_vector(3 downto 0);
|
||||
|
||||
-- write resp
|
||||
bresp : out std_logic;
|
||||
bvalid : out std_logic;
|
||||
bready : in std_logic;
|
||||
|
||||
|
||||
-- PDM output!
|
||||
pdmout : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal finished, clk, rst, rstn: std_logic := '0';
|
||||
|
||||
signal arvalid, arready, awvalid, awready: std_logic;
|
||||
signal rresp, rvalid, rready, bresp, bvalid, bready: std_logic;
|
||||
signal wstrb: std_logic_vector(3 downto 0);
|
||||
signal araddr, rdata, awaddr, wdata: std_logic_vector(31 downto 0);
|
||||
|
||||
signal pdmout: std_logic;
|
||||
|
||||
constant period: integer := 7 * 256;
|
||||
constant half_time: time := 1280 ns * period;
|
||||
|
||||
begin
|
||||
rstn <= not rst;
|
||||
dut: wave port map(aclk => clk, aresetn => rstn,
|
||||
arvalid => arvalid, arready => arready, awvalid => awvalid, awready => awready,
|
||||
rresp => rresp, rvalid => rvalid, rready => rready, bresp => bresp, bvalid => bvalid, bready => bready,
|
||||
wstrb => wstrb, araddr => araddr, rdata => rdata, awaddr => awaddr, wdata => wdata,
|
||||
pdmout => pdmout
|
||||
);
|
||||
|
||||
-- tick tock
|
||||
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';
|
||||
|
||||
arvalid <= '0';
|
||||
awvalid <= '0';
|
||||
wstrb <= "0000";
|
||||
|
||||
wait for 1 ns;
|
||||
-- assert(='0') report "Fail rst" severity error;
|
||||
|
||||
rst <= '0';
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
awvalid <= '1';
|
||||
awaddr <= x"00000000"; -- enable
|
||||
wstrb <= "1111";
|
||||
wdata <= x"00000001";
|
||||
bready <= '1';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(bvalid = '1') report "Write error" severity error;
|
||||
assert(bresp = '0') report "Write fail" severity error;
|
||||
assert(awready = '1') report "Write error" severity error;
|
||||
|
||||
awaddr <= x"00000004"; -- period
|
||||
wdata <= std_logic_vector(to_unsigned(period, 32));
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
-- read back
|
||||
wstrb <= "0000";
|
||||
awvalid <= '0';
|
||||
arvalid <= '1';
|
||||
araddr <= x"00000004";
|
||||
rready <= '1';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(unsigned(rdata) = period) report "Period readback failed" severity error;
|
||||
|
||||
arvalid <= '0';
|
||||
awvalid <= '1';
|
||||
wstrb <= "1111";
|
||||
|
||||
awaddr <= x"00000008"; -- high
|
||||
wdata <= x"00008000";
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
awaddr <= x"0000000c"; -- low
|
||||
wdata <= x"00004000";
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
wstrb <= "0000";
|
||||
awvalid <= '0';
|
||||
|
||||
wait for 30 ns;
|
||||
assert(pdmout = '1') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '0') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '0') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '1') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '0') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '0') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '0') report "wrong pdmout" severity error;
|
||||
wait for 10 ns;
|
||||
assert(pdmout = '1') report "wrong pdmout" severity error;
|
||||
|
||||
wait for 100 us;
|
||||
|
||||
assert false report "Test done." severity note;
|
||||
|
||||
finished <= '1';
|
||||
wait;
|
||||
|
||||
end process;
|
||||
end rtl;
|
||||
Reference in New Issue
Block a user