vhdl-sincos-gen/synth/digilent_atlys/top_test_sincos.vhdl

172 lines
4.8 KiB
VHDL

--
-- Test sine / cosine function core on Digilent Atlys board.
--
--
-- Serial port protocol (via USB):
--
-- * Baud rate 115200
--
-- * Send 6 bytes
-- { 0x41 0x42 phase(7:0) phase(15:8) phase(23:16) phase(31:24) }
-- to calculate sine and cosine of phase on the 18-bit / 20-bit core.
-- Board answers with 8 bytes
-- { sin(7:0) sin(15:8) sin(23:16) sin(31:24)
-- cos(7:0) cos(15:8) cos(23:16) cos(31:24 }
--
-- * Send 6 bytes
-- { 0x41 0x43 phase(7:0) phase(15:8) phase(23:16) phase(31:24) }
-- to calculate sine and cosine of phase on the 24-bit / 26-bit core.
-- Board answers with 8 bytes
-- { sin(7:0) sin(15:8) sin(23:16) sin(31:24)
-- cos(7:0) cos(15:8) cos(23:16) cos(31:24 }
--
-- * Send 2 bytes { 0x41 0x44 } to start clock-enable modulation.
--
-- * Send 3 bytes { 0x41 0x45 } to stop clock-enable modulation.
--
-- Status LEDs:
-- LED 0 = Ready (waiting for command)
-- LED 1 = Calculating
-- LED 2 = Clock-enable modulation active
-- LED 3 = Transmitting
--
-- AC97 audio:
-- 999.985 Hz sine wave on output
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top_test_sincos is
port (
-- 100 MHz system clock
clk: in std_logic;
-- Reset button
resetn: in std_logic;
-- Status LEDs
led: out std_logic_vector(7 downto 0);
-- Uart
uartrx: in std_logic;
uarttx: out std_logic;
-- AC97 audio
ac97_bitclk: in std_logic;
ac97_sdi: in std_logic;
ac97_sdo: out std_logic;
ac97_sync: out std_logic;
ac97_rst: out std_logic );
end entity;
architecture rtl of top_test_sincos is
-- Frequency is 21845 / 2**20 * 48000 Hz = 999.985 Hz
constant tone_freq: integer := 21845;
signal r_rstgen: std_logic_vector(7 downto 0) := "00000000";
signal r_reset: std_logic;
signal r_ac97_rstcnt: unsigned(7 downto 0);
signal r_ac97_rst: std_logic;
signal r_ac97_phase: unsigned(19 downto 0);
signal s_ac97_sine: signed(17 downto 0);
signal s_ac97_dataleft: signed(19 downto 0);
signal s_ac97_dataright: signed(19 downto 0);
signal s_ac97_ready: std_logic;
begin
-- Instantiate test design with serial interface.
u0: entity work.test_sincos_serial
generic map (
serial_bitrate_divider => 868 )
port map (
clk => clk,
rst => r_reset,
ser_rx => uartrx,
ser_tx => uarttx,
stat_ready => led(0),
stat_calc => led(1),
stat_clkmod => led(2),
stat_txser => led(3) );
-- Instantiate sine generator for AC97 output.
u1: entity work.sincos_gen_d18_p20
port map (
clk => ac97_bitclk,
clk_en => '1',
in_phase => r_ac97_phase,
out_sin => s_ac97_sine,
out_cos => open );
-- Instantiate AC97 output
u2: entity work.ac97out
port map (
bitclk => ac97_bitclk,
resetn => r_ac97_rst,
data_left => s_ac97_dataleft,
data_right => s_ac97_dataright,
data_valid => '1',
data_ready => s_ac97_ready,
ac97_sdi => ac97_sdi,
ac97_sdo => ac97_sdo,
ac97_sync => ac97_sync );
-- Pad 18-bit signed samples to 20-bit.
s_ac97_dataleft <= s_ac97_sine & "00";
s_ac97_dataright <= s_ac97_sine & "00";
-- Drive unused LEDs.
led(7 downto 4) <= "0000";
-- Drive AC97 reset pin.
ac97_rst <= r_ac97_rst;
-- Reset synchronizer.
process (clk) is
begin
if rising_edge(clk) then
if resetn = '0' then
r_rstgen <= (others => '0');
r_reset <= '1';
else
r_rstgen <= "1" & r_rstgen(7 downto 1);
r_reset <= not r_rstgen(0);
end if;
end if;
end process;
-- Reset generator for AC97 codec.
process (clk) is
begin
if rising_edge(clk) then
if r_reset = '1' then
r_ac97_rstcnt <= (others => '1');
r_ac97_rst <= '0';
else
r_ac97_rstcnt <= r_ac97_rstcnt - 1;
if r_ac97_rstcnt = 0 then
r_ac97_rst <= '1';
end if;
end if;
end if;
end process;
-- Synchronous process in AC97 bitclock domain.
process (ac97_bitclk) is
begin
if rising_edge(ac97_bitclk) then
if s_ac97_ready = '1' then
r_ac97_phase <= r_ac97_phase + tone_freq;
end if;
end if;
end process;
end architecture;