wave: axi4-compliant wave
This commit is contained in:
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;
|
||||
Reference in New Issue
Block a user