wave: add square waveform generator
This commit is contained in:
parent
c6eaf0e9e6
commit
50dedf1dd8
@ -1,12 +1,12 @@
|
|||||||
all: sim
|
all: sim
|
||||||
sim: test.ghw
|
sim: pdmout_test.ghw square_test.ghw
|
||||||
|
|
||||||
sim_sources = pdmout_test.vhdl
|
sim_sources = pdmout_test.vhdl square_test.vhdl
|
||||||
sources = pdmout.vhdl
|
sources = pdmout.vhdl square.vhdl
|
||||||
|
|
||||||
|
|
||||||
test.ghw: work-obj93.cf
|
%.ghw: work-obj93.cf
|
||||||
ghdl -r pdmout_test --wave=$@
|
ghdl -r $* --wave=$@
|
||||||
|
|
||||||
|
|
||||||
work-obj93.cf: $(sim_sources) $(sources)
|
work-obj93.cf: $(sim_sources) $(sources)
|
||||||
|
130
wave/square.vhdl
Normal file
130
wave/square.vhdl
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
-- some kind of square wave generator, writing 16-bit samples
|
||||||
|
-- to a memory address using DMA periodically
|
||||||
|
entity square is
|
||||||
|
port
|
||||||
|
(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
|
||||||
|
-- bus slave interface
|
||||||
|
s_we : in std_logic;
|
||||||
|
s_addr : in std_logic_vector(15 downto 0);
|
||||||
|
s_din : in std_logic_vector(15 downto 0);
|
||||||
|
|
||||||
|
-- bus master interface (DMA!!)
|
||||||
|
m_busy : in std_logic;
|
||||||
|
m_we : out std_logic;
|
||||||
|
m_addr : out std_logic_vector(15 downto 0);
|
||||||
|
m_dout : out std_logic_vector(15 downto 0)
|
||||||
|
);
|
||||||
|
end square;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Mem layout:
|
||||||
|
-- 0x00: 16-bit unsigned period (units of 256 clock cycles)
|
||||||
|
-- 0x02: 16-bit unsigned high value
|
||||||
|
-- 0x04: 16-bit unsigned low value
|
||||||
|
-- 0x06: 16-bit output address
|
||||||
|
-- 0x08: flags: [enabled]
|
||||||
|
|
||||||
|
architecture Behavioral of square is
|
||||||
|
|
||||||
|
-- all registers
|
||||||
|
signal period, hi_val, lo_val, out_addr: std_logic_vector(15 downto 0);
|
||||||
|
signal enabled: std_logic;
|
||||||
|
|
||||||
|
signal counter: unsigned(23 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- counter process
|
||||||
|
-- drives counter
|
||||||
|
process(clk, rst)
|
||||||
|
begin
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
counter <= to_unsigned(0, 24);
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if enabled = '0' or counter(22 downto 7) = unsigned(period) then
|
||||||
|
counter <= to_unsigned(0, 24);
|
||||||
|
else
|
||||||
|
counter <= counter + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- signal generation
|
||||||
|
-- drives m_we, m_addr, m_dout
|
||||||
|
process(clk, rst)
|
||||||
|
variable high: std_logic;
|
||||||
|
variable deferred: std_logic;
|
||||||
|
begin
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
m_we <= '0';
|
||||||
|
m_addr <= x"0000";
|
||||||
|
m_dout <= x"0000";
|
||||||
|
high := '0';
|
||||||
|
deferred := '0';
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
m_we <= '0';
|
||||||
|
|
||||||
|
if enabled = '1' then
|
||||||
|
if counter = 0 and m_busy = '1' then
|
||||||
|
deferred := '1';
|
||||||
|
elsif deferred = '1' or (counter = 0 and m_busy = '0') then
|
||||||
|
m_we <= '1';
|
||||||
|
m_addr <= out_addr;
|
||||||
|
if high = '1' then
|
||||||
|
m_dout <= hi_val;
|
||||||
|
else
|
||||||
|
m_dout <= lo_val;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
high := not high;
|
||||||
|
deferred := '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- Bus slave process
|
||||||
|
-- drives period, value, out_addr, enabled
|
||||||
|
process(clk, rst)
|
||||||
|
begin
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
period <= x"0000";
|
||||||
|
hi_val <= x"0000";
|
||||||
|
lo_val <= x"0000";
|
||||||
|
out_addr <= x"0000";
|
||||||
|
enabled <= '0';
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if s_we = '1' then
|
||||||
|
case s_addr(3 downto 0) is
|
||||||
|
when x"0" =>
|
||||||
|
period <= s_din;
|
||||||
|
when x"2" =>
|
||||||
|
hi_val <= s_din;
|
||||||
|
when x"4" =>
|
||||||
|
lo_val <= s_din;
|
||||||
|
when x"6" =>
|
||||||
|
out_addr <= s_din;
|
||||||
|
when x"8" =>
|
||||||
|
enabled <= s_din(0);
|
||||||
|
when others =>
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
112
wave/square_test.vhdl
Normal file
112
wave/square_test.vhdl
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use std.textio.all;
|
||||||
|
|
||||||
|
entity square_test is
|
||||||
|
end square_test;
|
||||||
|
|
||||||
|
architecture rtl of square_test is
|
||||||
|
|
||||||
|
component square is
|
||||||
|
port
|
||||||
|
(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
|
||||||
|
-- bus slave interface
|
||||||
|
s_we : in std_logic;
|
||||||
|
s_addr : in std_logic_vector(15 downto 0);
|
||||||
|
s_din : in std_logic_vector(15 downto 0);
|
||||||
|
|
||||||
|
-- bus master interface (DMA!!)
|
||||||
|
m_busy : in std_logic;
|
||||||
|
m_we : out std_logic;
|
||||||
|
m_addr : out std_logic_vector(15 downto 0);
|
||||||
|
m_dout : out std_logic_vector(15 downto 0)
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
signal finished, clk, rst: std_logic := '0';
|
||||||
|
|
||||||
|
signal s_we, m_busy, m_we: std_logic;
|
||||||
|
signal s_addr, s_din, m_addr, m_dout: std_logic_vector(15 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
dut: square port map(clk => clk, rst => rst,
|
||||||
|
s_we => s_we, s_addr => s_addr, s_din => s_din,
|
||||||
|
m_busy => m_busy, m_we => m_we, m_addr => m_addr, m_dout => m_dout);
|
||||||
|
|
||||||
|
-- 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';
|
||||||
|
|
||||||
|
wait for 1 ns;
|
||||||
|
assert(m_we='0') report "Fail rst" severity error;
|
||||||
|
|
||||||
|
rst <= '0';
|
||||||
|
m_busy <= '0';
|
||||||
|
|
||||||
|
wait for 10 ns;
|
||||||
|
|
||||||
|
s_we <= '1';
|
||||||
|
s_addr <= x"0000"; -- period
|
||||||
|
s_din <= x"0001"; -- 256 cycles (2560 ns)
|
||||||
|
|
||||||
|
wait for 10 ns;
|
||||||
|
|
||||||
|
s_we <= '1';
|
||||||
|
s_addr <= x"0002"; -- high
|
||||||
|
s_din <= x"0042";
|
||||||
|
|
||||||
|
wait for 10 ns;
|
||||||
|
|
||||||
|
s_we <= '1';
|
||||||
|
s_addr <= x"0004"; -- low
|
||||||
|
s_din <= x"0037";
|
||||||
|
|
||||||
|
wait for 10 ns;
|
||||||
|
|
||||||
|
s_we <= '1';
|
||||||
|
s_addr <= x"0006"; -- DNA address
|
||||||
|
s_din <= x"babe";
|
||||||
|
|
||||||
|
wait for 10 ns;
|
||||||
|
|
||||||
|
s_we <= '1';
|
||||||
|
s_addr <= x"0008"; -- enable
|
||||||
|
s_din <= x"0001";
|
||||||
|
|
||||||
|
wait for 20 ns;
|
||||||
|
|
||||||
|
assert(m_addr = x"babe") report "Fail to write to mem addr" severity error;
|
||||||
|
assert(m_we = '1') report "Fail to write to mem we" severity error;
|
||||||
|
assert(m_dout = x"0037") report "Fail to write to mem dout" severity error;
|
||||||
|
|
||||||
|
wait for 20 ns;
|
||||||
|
|
||||||
|
assert(m_we = '0') report "Fail to stop m_we" severity error;
|
||||||
|
|
||||||
|
wait for 1300 ns;
|
||||||
|
|
||||||
|
assert(m_dout = x"0042") report "Fail to write to mem dout" severity error;
|
||||||
|
|
||||||
|
assert false report "Test done." severity note;
|
||||||
|
|
||||||
|
finished <= '1';
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end rtl;
|
Loading…
Reference in New Issue
Block a user