OpenCores
URL https://opencores.org/ocsvn/spdif_interface/spdif_interface/trunk

Subversion Repositories spdif_interface

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 63 to Rev 64
    Reverse comparison

Rev 63 → Rev 64

/tags/spdif_rel_1/doc/src/spdif.doc Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/spdif_rel_1/doc/src/spdif.doc Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/spdif_rel_1/doc/spdif.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/spdif_rel_1/doc/spdif.pdf =================================================================== --- tags/spdif_rel_1/doc/spdif.pdf (nonexistent) +++ tags/spdif_rel_1/doc/spdif.pdf (revision 64)
tags/spdif_rel_1/doc/spdif.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/spdif_rel_1/rtl/vhdl/rx_phase_det.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_phase_det.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_phase_det.vhd (revision 64) @@ -0,0 +1,398 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Oversampling phase detector. Decodes bi-phase mark encoded ---- +---- signal. Clock must be at least 8 times higher than bit rate. ---- +---- The SPDIF bitrate must be minimum 100kHz. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.5 2004/07/19 16:58:37 gedra +-- Fixed bug. +-- +-- Revision 1.4 2004/07/12 17:06:41 gedra +-- Fixed bug with lock event generation. +-- +-- Revision 1.3 2004/07/11 16:19:50 gedra +-- Bug-fix. +-- +-- Revision 1.2 2004/06/13 18:08:50 gedra +-- Renamed generic and cleaned some lint's +-- +-- Revision 1.1 2004/06/06 15:43:02 gedra +-- Early version of the bi-phase mark decoder. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +entity rx_phase_det is + generic (WISHBONE_FREQ: natural := 33); -- WishBone frequency in MHz + port ( + wb_clk_i: in std_logic; -- wishbone clock + rxen: in std_logic; -- phase detector enable + spdif: in std_logic; -- SPDIF input signal + lock: out std_logic; -- true if locked to spdif input + lock_evt: out std_logic; -- lock status change event + rx_data: out std_logic; -- recevied data + rx_data_en: out std_logic; -- received data enable + rx_block_start: out std_logic; -- start-of-block pulse + rx_frame_start: out std_logic; -- start-of-frame pulse + rx_channel_a: out std_logic; -- 1 if channel A frame is recevied + rx_error: out std_logic; -- signal error was detected + ud_a_en: out std_logic; -- user data ch. A enable + ud_b_en: out std_logic; -- user data ch. B enable + cs_a_en: out std_logic; -- channel status ch. A enable + cs_b_en: out std_logic); -- channel status ch. B enable); +end rx_phase_det; + +architecture rtl of rx_phase_det is + + constant TRANSITIONS : integer := 70; + constant FRAMES_FOR_LOCK : integer := 3; + signal maxpulse, maxp, mp_cnt: integer range 0 to 16 * WISHBONE_FREQ; + signal last_cnt, max_thres : integer range 0 to 16 * WISHBONE_FREQ; + signal minpulse, minp, min_thres: integer range 0 to 8 * WISHBONE_FREQ; + signal zspdif, spdif_in, zspdif_in, trans, ztrans : std_logic; + signal trans_cnt : integer range 0 to TRANSITIONS; + signal valid, p_long, p_short: std_logic; + type pulse_type is (ZERO, SHORT, MED, LONG); + type pulse_array is array (0 to 3) of pulse_type; + signal preamble: pulse_array; + signal new_pulse, short_idx, ilock: std_logic; + type frame_state is (IDLE, HUNT, FRAMESTART, FRAME_RX); + signal framerx : frame_state; + signal frame_cnt : integer range 0 to FRAMES_FOR_LOCK; + signal bit_cnt : integer range 0 to 63; + signal pre_cnt : integer range 0 to 7; + type preamble_types is (NONE, PRE_X, PRE_Y, PRE_Z); + signal new_preamble, last_preamble : preamble_types; + signal irx_channel_a, zilock : std_logic; + +begin + + -- Pulse width analyzer + PHDET: process (wb_clk_i, rxen) + begin + if rxen = '0' then -- reset by configuration register bit + maxpulse <= 0; + maxp <= 0; + mp_cnt <= 0; + zspdif <= '0'; + zspdif_in <= '0'; + spdif_in <= '0'; + trans_cnt <= 0; + minpulse <= 0; + minp <= 8 * WISHBONE_FREQ; + last_cnt <= 0; + trans <= '0'; + valid <= '0'; + preamble <= (ZERO, ZERO, ZERO, ZERO); + max_thres <= 0; + min_thres <= 0; + new_preamble <= NONE; + ztrans <= '0'; + new_pulse <= '0'; + else + if rising_edge(wb_clk_i) then + -- sync spdif signal to wishbone clock + zspdif <= spdif; + spdif_in <= zspdif; + -- find the longest pulse, which is the bi-phase violation + -- also find the shortest pulse + zspdif_in <= spdif_in; + if zspdif_in /= spdif_in then -- input transition + mp_cnt <= 0; + trans <= '1'; + last_cnt <= mp_cnt; + if trans_cnt > 0 then + if mp_cnt > maxp then + maxp <= mp_cnt; + end if; + if mp_cnt < minp then + minp <= mp_cnt; + end if; + end if; + else + trans <= '0'; + if mp_cnt < 16 * WISHBONE_FREQ then + mp_cnt <= mp_cnt + 1; + end if; + end if; + -- transition counting + if trans = '1' then + if trans_cnt < TRANSITIONS then + trans_cnt <= trans_cnt + 1; + else + -- the max/min pulse length is updated after given # of transitions + trans_cnt <= 0; + maxpulse <= maxp; + maxp <= 0; + minpulse <= minp; + minp <= 8 * WISHBONE_FREQ; + min_thres <= maxp / 2; + if maxp < 11 then + max_thres <= maxp - 1; + else + max_thres <= maxp - 3; + end if; + end if; + end if; + -- detection of valid SPDIF signal + if maxpulse > 6 then + valid <= '1'; + else + valid <= '0'; + end if; + -- bit decoding + if trans = '1' then + if (last_cnt < min_thres) and (last_cnt > 0) then + p_short <= '1'; + preamble(0) <= SHORT; + else + p_short <= '0'; + end if; + if last_cnt >= max_thres then + p_long <= '1'; + preamble(0) <= LONG; + else + p_long <= '0'; + end if; + if last_cnt = 0 then + preamble(0) <= ZERO; + end if; + if (last_cnt < max_thres) and (last_cnt >= min_thres) then + preamble(0) <= MED; + end if; + preamble(3) <= preamble(2); + preamble(2) <= preamble(1); + preamble(1) <= preamble(0); + end if; + -- preamble detection + if preamble(3) = LONG and preamble(2) = LONG and preamble(1) = SHORT + and preamble(0) = SHORT then + new_preamble <= PRE_X; + elsif preamble(3) = LONG and preamble(2) = MED and preamble(1) = SHORT + and preamble(0) = MED then + new_preamble <= PRE_Y; + elsif preamble(3) = LONG and preamble(2) = SHORT and preamble(1) = SHORT + and preamble(0) = LONG then + new_preamble <= PRE_Z; + else + new_preamble <= NONE; + end if; + -- delayed transition pulse for the state machine + ztrans <= trans; + new_pulse <= ztrans; + end if; + end if; + end process; + + lock <= ilock; + rx_channel_a <= irx_channel_a; + + -- State machine that hunt for and lock onto sub-frames + FRX: process (wb_clk_i, rxen) + begin + if rxen = '0' then + framerx <= IDLE; + ilock <= '0'; + zilock <= '0'; + rx_data <= '0'; + rx_data_en <= '0'; + rx_block_start <= '0'; + rx_frame_start <= '0'; + irx_channel_a <= '0'; + ud_a_en <= '0'; + ud_b_en <= '0'; + cs_a_en <= '0'; + cs_b_en <= '0'; + rx_error <= '0'; + lock_evt <= '0'; + bit_cnt <= 0; + pre_cnt <= 0; + short_idx <= '0'; + frame_cnt <= 0; + last_preamble <= NONE; + elsif rising_edge(wb_clk_i) then + zilock <= ilock; + if zilock /= ilock then -- generate event for event reg. + lock_evt <= '1'; + else + lock_evt <= '0'; + end if; + case framerx is + when IDLE => -- wait for recevier to be enabled + if valid = '1' then + framerx <= HUNT; + end if; + when HUNT => -- wait for preamble detection + frame_cnt <= 0; + ilock <= '0'; + rx_error <= '0'; + if new_pulse = '1' then + if new_preamble /= NONE then + framerx <= FRAMESTART; + end if; + end if; + when FRAMESTART => -- reset sub-frame bit counter + bit_cnt <= 0; + pre_cnt <= 0; + if frame_cnt < FRAMES_FOR_LOCK then + frame_cnt <= frame_cnt + 1; + else + ilock <= '1'; + end if; + last_preamble <= new_preamble; + short_idx <= '0'; + rx_frame_start <= '1'; + rx_block_start <= '0'; + framerx <= FRAME_RX; + when FRAME_RX => -- receive complete sub-frame + if new_pulse = '1' then + if bit_cnt < 28 then + case preamble(0) is + when ZERO => + short_idx <= '0'; + when SHORT => + if short_idx = '0' then + short_idx <= '1'; + else + -- two short pulses is a logical '1' + bit_cnt <= bit_cnt + 1; + short_idx <= '0'; + rx_data <= '1'; + rx_data_en <= ilock; + -- user data enable for the capture register + if bit_cnt = 25 and ilock = '1' then + ud_a_en <= irx_channel_a; + ud_b_en <= not irx_channel_a; + end if; + -- channel status enable for the capture register + if bit_cnt = 26 and ilock = '1' then + cs_a_en <= irx_channel_a; + cs_b_en <= not irx_channel_a; + end if; + end if; + when MED => + -- medium pulse is logical '0' + bit_cnt <= bit_cnt + 1; + rx_data <= '0'; + rx_data_en <= ilock; + short_idx <= '0'; + -- user data enable for the capture register + if bit_cnt = 25 and ilock = '1' then + ud_a_en <= irx_channel_a; + ud_b_en <= not irx_channel_a; + end if; + -- channel status enable for the capture register + if bit_cnt = 26 and ilock = '1' then + cs_a_en <= irx_channel_a; + cs_b_en <= not irx_channel_a; + end if; + when LONG => + short_idx <= '0'; + when others => + framerx <= HUNT; + end case; + else + -- there should be 4 pulses in preamble + if pre_cnt < 7 then + pre_cnt <= pre_cnt + 1; + else + rx_error <= '1'; + framerx <= HUNT; + end if; + -- check for correct preamble here + if pre_cnt = 3 then + case last_preamble is + when PRE_X => + if new_preamble = PRE_Y then + framerx <= FRAMESTART; + irx_channel_a <= '0'; + else + rx_error <= '1'; + framerx <= HUNT; + end if; + when PRE_Y => + if new_preamble = PRE_X or new_preamble = PRE_Z then + irx_channel_a <= '1'; + -- start of new block? + if new_preamble = PRE_Z then + rx_block_start <= '1'; + end if; + framerx <= FRAMESTART; + else + rx_error <= '1'; + framerx <= HUNT; + end if; + when PRE_Z => + if new_preamble = PRE_Y then + irx_channel_a <= '0'; + framerx <= FRAMESTART; + else + rx_error <= '1'; + framerx <= HUNT; + end if; + when others => + rx_error <= '1'; + framerx <= HUNT; + end case; + end if; + end if; + else + rx_data_en <= '0'; + rx_block_start <= '0'; + rx_frame_start <= '0'; + ud_a_en <= '0'; + ud_b_en <= '0'; + cs_a_en <= '0'; + cs_b_en <= '0'; + end if; + when others => + framerx <= IDLE; + end case; + end if; + end process FRX; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_cap_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_cap_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_cap_reg.vhd (revision 64) @@ -0,0 +1,189 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver channel status capture module ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.4 2004/07/19 16:58:37 gedra +-- Fixed bug. +-- +-- Revision 1.3 2004/06/27 16:16:55 gedra +-- Signal renaming and bug fix. +-- +-- Revision 1.2 2004/06/26 14:14:47 gedra +-- Converted to numeric_std and fixed a few bugs. +-- +-- Revision 1.1 2004/06/05 17:16:46 gedra +-- Channel status/user data capture register +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.rx_package.all; + +entity rx_cap_reg is + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + cap_ctrl_wr: in std_logic; -- control register write + cap_ctrl_rd: in std_logic; -- control register read + cap_data_rd: in std_logic; -- data register read + cap_din: in std_logic_vector(31 downto 0); -- write data + rx_block_start: in std_logic; -- start of block signal + ch_data: in std_logic; -- channel status/user data + ud_a_en: in std_logic; -- user data ch. A enable + ud_b_en: in std_logic; -- user data ch. B enable + cs_a_en: in std_logic; -- channel status ch. A enable + cs_b_en: in std_logic; -- channel status ch. B enable + cap_dout: out std_logic_vector(31 downto 0); -- read data + cap_evt: out std_logic); -- capture event (interrupt) +end rx_cap_reg; + +architecture rtl of rx_cap_reg is + + signal cap_ctrl_bits, cap_ctrl_dout: std_logic_vector(31 downto 0); + signal cap_reg, cap_new : std_logic_vector(31 downto 0); + signal bitlen, cap_len : integer range 0 to 63; + signal bitpos, cur_pos : integer range 0 to 255; + signal chid, cdata, compared : std_logic; + signal d_enable : std_logic_vector(3 downto 0); + +begin + +-- Data bus or'ing + cap_dout <= cap_reg when cap_data_rd = '1' else cap_ctrl_dout; + +-- Capture control register + CREG: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "11111111111111110000000000000000") + port map ( + clk => clk, + rst => rst, + ctrl_wr => cap_ctrl_wr, + ctrl_rd => cap_ctrl_rd, + ctrl_din => cap_din, + ctrl_dout => cap_ctrl_dout, + ctrl_bits => cap_ctrl_bits); + + chid <= cap_ctrl_bits(6); + cdata <= cap_ctrl_bits(7); + +-- capture data register + CDAT: process (clk, rst) + begin + if rst = '1' then + cap_reg <= (others => '0'); + cap_new <= (others => '0'); + cur_pos <= 0; + cap_len <= 0; + cap_evt <= '0'; + compared <= '0'; + bitpos <= 0; + bitlen <= 0; + else + if rising_edge(clk) then + bitlen <= to_integer(unsigned(cap_ctrl_bits(5 downto 0))); + bitpos <= to_integer(unsigned(cap_ctrl_bits(15 downto 8))); + if bitlen > 0 then -- bitlen = 0 disables the capture function + -- bit counter, 0 to 191 + if rx_block_start = '1' then + cur_pos <= 0; + cap_len <= 0; + cap_new <= (others => '0'); + compared <= '0'; + elsif cs_b_en = '1' then -- ch. status #2 comes last, count then + cur_pos <= cur_pos + 1; + end if; + -- capture bits + if cur_pos >= bitpos and cap_len < bitlen then + case d_enable is + when "0001" => -- user data channel A + if cdata = '0' and chid = '0' then + cap_new(cap_len) <= ch_data; + cap_len <= cap_len + 1; + end if; + when "0010" => -- user data channel B + if cdata = '0' and chid = '1' then + cap_new(cap_len) <= ch_data; + cap_len <= cap_len + 1; + end if; + when "0100" => -- channel status ch. A + if cdata = '1' and chid = '0' then + cap_new(cap_len) <= ch_data; + cap_len <= cap_len + 1; + end if; + when "1000" => -- channel status ch. B + if cdata = '1' and chid = '1' then + cap_new(cap_len) <= ch_data; + cap_len <= cap_len + 1; + end if; + when others => null; + end case; + end if; + -- if all bits captured, check with previous data + if cap_len = bitlen and compared = '0' then + compared <= '1'; + -- event generated if captured bits differ + if cap_reg /= cap_new then + cap_evt <= '1'; + end if; + cap_reg <= cap_new; + else + cap_evt <= '0'; + end if; + end if; + end if; + end if; + end process CDAT; + + d_enable(0) <= ud_a_en; + d_enable(1) <= ud_b_en; + d_enable(2) <= cs_a_en; + d_enable(3) <= cs_b_en; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_spdif.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_spdif.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_spdif.vhd (revision 64) @@ -0,0 +1,389 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver. Top level entity for the receiver core. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.5 2004/07/19 16:58:37 gedra +-- Fixed bug. +-- +-- Revision 1.4 2004/07/12 17:06:41 gedra +-- Fixed bug with lock event generation. +-- +-- Revision 1.3 2004/07/11 16:19:50 gedra +-- Bug-fix. +-- +-- Revision 1.2 2004/06/27 16:16:55 gedra +-- Signal renaming and bug fix. +-- +-- Revision 1.1 2004/06/26 14:13:56 gedra +-- Top level entity for receiver. +-- +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use work.rx_package.all; + +entity rx_spdif is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64; + CH_ST_CAPTURE: integer range 0 to 8; + WISHBONE_FREQ: natural); + port ( + -- Wishbone interface + wb_clk_i: in std_logic; + wb_rst_i: in std_logic; + wb_sel_i: in std_logic; + wb_stb_i: in std_logic; + wb_we_i: in std_logic; + wb_cyc_i: in std_logic; + wb_bte_i: in std_logic_vector(1 downto 0); + wb_cti_i: in std_logic_vector(2 downto 0); + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); + wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0); + wb_ack_o: out std_logic; + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); + -- Interrupt line + rx_int_o: out std_logic; + -- SPDIF input signal + spdif_rx_i: in std_logic); +end rx_spdif; + +architecture rtl of rx_spdif is + + signal data_out, ver_dout : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal ver_rd : std_logic; + signal conf_rxen, conf_sample, evt_en, conf_chas, conf_valid : std_logic; + signal conf_blken, conf_valen, conf_useren, conf_staten : std_logic; + signal conf_paren, config_rd, config_wr : std_logic; + signal conf_mode : std_logic_vector(3 downto 0); + signal conf_bits, conf_dout : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal status_rd : std_logic; + signal stat_dout: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal imask_bits, imask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal imask_rd, imask_wr : std_logic; + signal istat_dout, istat_events: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal istat_rd, istat_wr, istat_lock : std_logic; + signal istat_lsbf, istat_hsbf, istat_paritya, istat_parityb: std_logic; + signal istat_cap : std_logic_vector(7 downto 0); + signal ch_st_cap_rd, ch_st_cap_wr, ch_st_data_rd: std_logic_vector(7 downto 0); + signal cap_dout : bus_array; + signal ch_data, ud_a_en, ud_b_en, cs_a_en, cs_b_en: std_logic; + signal mem_rd, sample_wr : std_logic; + signal sample_din, sample_dout : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal sbuf_wr_adr, sbuf_rd_adr : std_logic_vector(ADDR_WIDTH - 2 downto 0); + signal lock, rx_frame_start: std_logic; + signal rx_data, rx_data_en, rx_block_start: std_logic; + signal rx_channel_a, rx_error, lock_evt: std_logic; + +begin + +-- Data bus or'ing + DB16: if DATA_WIDTH = 16 generate + data_out <= ver_dout or conf_dout or stat_dout or imask_dout or istat_dout + when wb_adr_i(ADDR_WIDTH - 1) = '0' else sample_dout; + end generate DB16; + DB32: if DATA_WIDTH = 32 generate + data_out <= ver_dout or conf_dout or stat_dout or imask_dout or istat_dout or + cap_dout(1) or cap_dout(2) or cap_dout(3) or cap_dout(4) or + cap_dout(5) or cap_dout(6) or cap_dout(7) or cap_dout(0) when + wb_adr_i(ADDR_WIDTH - 1) = '0' else sample_dout; + end generate DB32; + +-- Wishbone bus cycle decoder + WB: rx_wb_decoder + generic map ( + DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH) + port map ( + wb_clk_i => wb_clk_i, + wb_rst_i => wb_rst_i, + wb_sel_i => wb_sel_i, + wb_stb_i => wb_stb_i, + wb_we_i => wb_we_i, + wb_cyc_i => wb_cyc_i, + wb_bte_i => wb_bte_i, + wb_cti_i => wb_cti_i, + wb_adr_i => wb_adr_i, + data_out => data_out, + wb_ack_o => wb_ack_o, + wb_dat_o => wb_dat_o, + version_rd => ver_rd, + config_rd => config_rd, + config_wr => config_wr, + status_rd => status_rd, + intmask_rd => imask_rd, + intmask_wr => imask_wr, + intstat_rd => istat_rd, + intstat_wr => istat_wr, + mem_rd => mem_rd, + mem_addr => sbuf_rd_adr, + ch_st_cap_rd => ch_st_cap_rd, + ch_st_cap_wr => ch_st_cap_wr, + ch_st_data_rd => ch_st_data_rd); + +-- Version register + VER : rx_ver_reg + generic map ( + DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH, + CH_ST_CAPTURE => CH_ST_CAPTURE) + port map ( + ver_rd => ver_rd, + ver_dout => ver_dout); + +-- Configuration register + CG32: if DATA_WIDTH = 32 generate + CONF: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "11111100000000001111111100000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => config_wr, + ctrl_rd => config_rd, + ctrl_din => wb_dat_i, + ctrl_dout => conf_dout, + ctrl_bits => conf_bits); + conf_mode(3 downto 0) <= conf_bits(23 downto 20); + conf_paren <= conf_bits(19); + conf_staten <= conf_bits(18); + conf_useren <= conf_bits(17); + conf_valen <= conf_bits(16); + end generate CG32; + CG16: if DATA_WIDTH = 16 generate + CONF: gen_control_reg + generic map ( + DATA_WIDTH => 16, + ACTIVE_BIT_MASK => "1111110000000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => config_wr, + ctrl_rd => config_rd, + ctrl_din => wb_dat_i, + ctrl_dout => conf_dout, + ctrl_bits => conf_bits); + conf_mode(3 downto 0) <= "0000"; + conf_paren <= '0'; + conf_staten <= '0'; + conf_useren <= '0'; + conf_valen <= '0'; + end generate CG16; + conf_blken <= conf_bits(5); + conf_valid <= conf_bits(4); + conf_chas <= conf_bits(3); + evt_en <= conf_bits(2); + conf_sample <= conf_bits(1); + conf_rxen <= conf_bits(0); + +-- status register + STAT : rx_status_reg + generic map ( + DATA_WIDTH => DATA_WIDTH) + port map ( + wb_clk_i => wb_clk_i, + status_rd => status_rd, + lock => lock, + chas => conf_chas, + rx_block_start => rx_block_start, + ch_data => rx_data, + cs_a_en => cs_a_en, + cs_b_en => cs_b_en, + status_dout => stat_dout); + +-- interrupt mask register + IM32: if DATA_WIDTH = 32 generate + IMASK: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "11111000000000001111111100000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => imask_wr, + ctrl_rd => imask_rd, + ctrl_din => wb_dat_i, + ctrl_dout => imask_dout, + ctrl_bits => imask_bits); + end generate IM32; + IM16: if DATA_WIDTH = 16 generate + IMASK: gen_control_reg + generic map ( + DATA_WIDTH => 16, + ACTIVE_BIT_MASK => "1111100000000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => imask_wr, + ctrl_rd => imask_rd, + ctrl_din => wb_dat_i, + ctrl_dout => imask_dout, + ctrl_bits => imask_bits); + end generate IM16; + +-- interrupt status register + ISTAT: gen_event_reg + generic map ( + DATA_WIDTH => DATA_WIDTH) + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + evt_wr => istat_wr, + evt_rd => istat_rd, + evt_din => wb_dat_i, + evt_dout => istat_dout, + event => istat_events, + evt_mask => imask_bits, + evt_en => evt_en, + evt_irq => rx_int_o); + istat_events(0) <= lock_evt; + istat_events(1) <= istat_lsbf; + istat_events(2) <= istat_hsbf; + istat_events(3) <= istat_paritya; + istat_events(4) <= istat_parityb; + istat_events(15 downto 5) <= (others => '0'); + IS32: if DATA_WIDTH = 32 generate + istat_events(23 downto 16) <= istat_cap(7 downto 0); + istat_events(31 downto 24) <= (others => '0'); + end generate IS32; + +-- capture registers + GCAP: if DATA_WIDTH = 32 and CH_ST_CAPTURE > 0 generate + CAPR: for k in 0 to CH_ST_CAPTURE - 1 generate + CHST: rx_cap_reg + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + cap_ctrl_wr => ch_st_cap_wr(k), + cap_ctrl_rd => ch_st_cap_rd(k), + cap_data_rd => ch_st_data_rd(k), + cap_din => wb_dat_i, + cap_dout => cap_dout(k), + cap_evt => istat_cap(k), + rx_block_start => rx_block_start, + ch_data => rx_data, + ud_a_en => ud_a_en, + ud_b_en => ud_b_en, + cs_a_en => cs_a_en, + cs_b_en => cs_b_en); + end generate CAPR; + -- unused capture registers set to zero + UCAPR: if CH_ST_CAPTURE < 8 generate + UC: for k in CH_ST_CAPTURE to 7 generate + cap_dout(k) <= (others => '0'); + end generate UC; + end generate UCAPR; + end generate GCAP; + +-- Sample buffer memory + MEM: dpram + generic map ( + DATA_WIDTH => DATA_WIDTH, + RAM_WIDTH => ADDR_WIDTH - 1) + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + din => sample_din, + wr_en => sample_wr, + rd_en => mem_rd, + wr_addr => sbuf_wr_adr, + rd_addr => sbuf_rd_adr, + dout => sample_dout); + +-- phase decoder + PDET: rx_phase_det + generic map ( + WISHBONE_FREQ => WISHBONE_FREQ) -- WishBone frequency in MHz + port map ( + wb_clk_i => wb_clk_i, + rxen => conf_rxen, + spdif => spdif_rx_i, + lock => lock, + lock_evt => lock_evt, + rx_data => rx_data, + rx_data_en => rx_data_en, + rx_block_start => rx_block_start, + rx_frame_start => rx_frame_start, + rx_channel_a => rx_channel_a, + rx_error => rx_error, + ud_a_en => ud_a_en, + ud_b_en => ud_b_en, + cs_a_en => cs_a_en, + cs_b_en => cs_b_en); + +-- frame decoder + FDEC: rx_decode + generic map ( + DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH) + port map ( + wb_clk_i => wb_clk_i, + conf_rxen => conf_rxen, + conf_sample => conf_sample, + conf_valid => conf_valid, + conf_mode => conf_mode, + conf_blken => conf_blken, + conf_valen => conf_valen, + conf_useren => conf_useren, + conf_staten => conf_staten, + conf_paren => conf_paren, + lock => lock, + rx_data => rx_data, + rx_data_en => rx_data_en, + rx_block_start => rx_block_start, + rx_frame_start => rx_frame_start, + rx_channel_a => rx_channel_a, + wr_en => sample_wr, + wr_addr => sbuf_wr_adr, + wr_data => sample_din, + stat_paritya => istat_paritya, + stat_parityb => istat_parityb, + stat_lsbf => istat_lsbf, + stat_hsbf => istat_hsbf); + +end rtl; + Index: tags/spdif_rel_1/rtl/vhdl/tx_spdif.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_spdif.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_spdif.vhd (revision 64) @@ -0,0 +1,363 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter. Top level entity for the transmitter ---- +---- core. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.1 2004/07/19 17:00:38 gedra +-- SPDIF transmitter top level. +-- +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use work.tx_package.all; + +entity tx_spdif is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64; + USER_DATA_BUF: integer range 0 to 1; + CH_STAT_BUF: integer range 0 to 1); + port ( + -- Wishbone interface + wb_clk_i: in std_logic; + wb_rst_i: in std_logic; + wb_sel_i: in std_logic; + wb_stb_i: in std_logic; + wb_we_i: in std_logic; + wb_cyc_i: in std_logic; + wb_bte_i: in std_logic_vector(1 downto 0); + wb_cti_i: in std_logic_vector(2 downto 0); + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); + wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0); + wb_ack_o: out std_logic; + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); + -- Interrupt line + tx_int_o: out std_logic; + -- SPDIF output signal + spdif_tx_o: out std_logic); +end tx_spdif; + +architecture rtl of tx_spdif is + + signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal version_rd : std_logic; + signal config_rd, config_wr, status_rd : std_logic; + signal config_dout, status_dout: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal intmask_bits, intmask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal intmask_rd, intmask_wr : std_logic; + signal intstat_dout, intstat_events: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal intstat_rd, intstat_wr : std_logic; + signal evt_hsbf, evt_lsbf : std_logic; + signal evt_hcsbf, evt_lcsbf : std_logic; + signal chstat_dout, chstat_bits: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal chstat_rd, chstat_wr : std_logic; + signal chstat_freq : std_logic_vector(1 downto 0); + signal chstat_gstat, chstat_preem, chstat_copy, chstat_audio : std_logic; + signal mem_wr, mem_rd, ch_status_wr, user_data_wr : std_logic; + signal sample_addr : std_logic_vector(ADDR_WIDTH - 2 downto 0); + signal sample_data: std_logic_vector(DATA_WIDTH - 1 downto 0); + signal conf_mode : std_logic_vector(3 downto 0); + signal conf_ratio : std_logic_vector(7 downto 0); + signal conf_udaten, conf_chsten : std_logic_vector(1 downto 0); + signal conf_tinten, conf_txdata, conf_txen : std_logic; + signal user_data_a, user_data_b : std_logic_vector(191 downto 0); + signal ch_stat_a, ch_stat_b : std_logic_vector(191 downto 0); + +begin + +-- Data bus or'ing + data_out <= version_dout or config_dout or intmask_dout or intstat_dout + when wb_adr_i(ADDR_WIDTH - 1) = '0' else (others => '0'); + +-- Wishbone bus cycle decoder + WB: tx_wb_decoder + generic map ( + DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH) + port map ( + wb_clk_i => wb_clk_i, + wb_rst_i => wb_rst_i, + wb_sel_i => wb_sel_i, + wb_stb_i => wb_stb_i, + wb_we_i => wb_we_i, + wb_cyc_i => wb_cyc_i, + wb_bte_i => wb_bte_i, + wb_cti_i => wb_cti_i, + wb_adr_i => wb_adr_i, + data_out => data_out, + wb_ack_o => wb_ack_o, + wb_dat_o => wb_dat_o, + version_rd => version_rd, + config_rd => config_rd, + config_wr => config_wr, + chstat_rd => chstat_rd, + chstat_wr => chstat_wr, + intmask_rd => intmask_rd, + intmask_wr => intmask_wr, + intstat_rd => intstat_rd, + intstat_wr => intstat_wr, + mem_wr => mem_wr, + user_data_wr => user_data_wr, + ch_status_wr => ch_status_wr); + +-- TxVersion - Version register + VER : tx_ver_reg + generic map ( + DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH, + USER_DATA_BUF => USER_DATA_BUF, + CH_STAT_BUF => CH_STAT_BUF) + port map ( + ver_rd => version_rd, + ver_dout => version_dout); + +-- TxConfig - Configuration register + CG32: if DATA_WIDTH = 32 generate + CONF: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "11101111111111110000111100000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => config_wr, + ctrl_rd => config_rd, + ctrl_din => wb_dat_i, + ctrl_dout => config_dout, + ctrl_bits => config_bits); + conf_mode(3 downto 0) <= config_bits(23 downto 20); + end generate CG32; + CG16: if DATA_WIDTH = 16 generate + CONF: gen_control_reg + generic map ( + DATA_WIDTH => 16, + ACTIVE_BIT_MASK => "1110111111111111") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => config_wr, + ctrl_rd => config_rd, + ctrl_din => wb_dat_i, + ctrl_dout => config_dout, + ctrl_bits => config_bits); + conf_mode(3 downto 0) <= "0000"; -- 16bit only + end generate CG16; + conf_ratio(7 downto 0) <= config_bits(15 downto 8); + UD: if USER_DATA_BUF = 1 generate + conf_udaten(1 downto 0) <= config_bits(7 downto 6); + end generate UD; + NUD: if USER_DATA_BUF = 0 generate + conf_udaten(1 downto 0) <= "00"; + end generate NUD; + CS: if CH_STAT_BUF = 1 generate + conf_chsten(1 downto 0) <= config_bits(5 downto 4); + end generate CS; + NCS: if CH_STAT_BUF = 0 generate + conf_chsten(1 downto 0) <= "00"; + end generate NCS; + conf_tinten <= config_bits(2); + conf_txdata <= config_bits(1); + conf_txen <= config_bits(0); + +-- TxChStat - channel status control register + CS32: if DATA_WIDTH = 32 generate + CHST: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "11111111000000000000000000000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => chstat_wr, + ctrl_rd => chstat_rd, + ctrl_din => wb_dat_i, + ctrl_dout => chstat_dout, + ctrl_bits => chstat_bits); + end generate CS32; + CS16: if DATA_WIDTH = 16 generate + CHST: gen_control_reg + generic map ( + DATA_WIDTH => 16, + ACTIVE_BIT_MASK => "1111111100000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => chstat_wr, + ctrl_rd => chstat_rd, + ctrl_din => wb_dat_i, + ctrl_dout => chstat_dout, + ctrl_bits => chstat_bits); + end generate CS16; + chstat_freq(1 downto 0) <= chstat_bits(7 downto 6); + chstat_gstat <= chstat_bits(3); + chstat_preem <= chstat_bits(2); + chstat_copy <= chstat_bits(1); + chstat_audio <= chstat_bits(0); + +-- TxIntMask - interrupt mask register + IM32: if DATA_WIDTH = 32 generate + IMASK: gen_control_reg + generic map ( + DATA_WIDTH => 32, + ACTIVE_BIT_MASK => "01111000000000000000000000000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => intmask_wr, + ctrl_rd => intmask_rd, + ctrl_din => wb_dat_i, + ctrl_dout => intmask_dout, + ctrl_bits => intmask_bits); + end generate IM32; + IM16: if DATA_WIDTH = 16 generate + IMASK: gen_control_reg + generic map ( + DATA_WIDTH => 16, + ACTIVE_BIT_MASK => "0111100000000000") + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + ctrl_wr => intmask_wr, + ctrl_rd => intmask_rd, + ctrl_din => wb_dat_i, + ctrl_dout => intmask_dout, + ctrl_bits => intmask_bits); + end generate IM16; + +-- TxIntStat - interrupt status register + ISTAT: gen_event_reg + generic map ( + DATA_WIDTH => DATA_WIDTH) + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + evt_wr => intstat_wr, + evt_rd => intstat_rd, + evt_din => wb_dat_i, + evt_dout => intstat_dout, + event => intstat_events, + evt_mask => intmask_bits, + evt_en => conf_tinten, + evt_irq => tx_int_o); + intstat_events(0) <= '0'; + intstat_events(1) <= evt_lsbf; -- lower sample buffer empty + intstat_events(2) <= evt_hsbf; -- higher sampel buffer empty + intstat_events(3) <= evt_lcsbf; -- lower ch.stat/user data buf empty + intstat_events(4) <= evt_hcsbf; -- higher ch.stat7user data buf empty + intstat_events(DATA_WIDTH - 1 downto 5) <= (others => '0'); + +-- Sample buffer memory + MEM: dpram + generic map ( + DATA_WIDTH => DATA_WIDTH, + RAM_WIDTH => ADDR_WIDTH - 1) + port map ( + clk => wb_clk_i, + rst => wb_rst_i, + din => wb_dat_i(DATA_WIDTH - 1 downto 0), + wr_en => mem_wr, + rd_en => mem_rd, + wr_addr => wb_adr_i(ADDR_WIDTH - 2 downto 0), + rd_addr => sample_addr, + dout => sample_data); + +-- UserData - byte buffer + UDB: tx_bitbuf + generic map (ENABLE_BUFFER => USER_DATA_BUF) + port map ( + wb_clk_i => wb_clk_i, + wb_rst_i => wb_rst_i, + buf_wr => user_data_wr, + wb_adr_i => wb_adr_i(4 downto 0), + wb_dat_i => wb_dat_i(15 downto 0), + buf_data_a => user_data_a, + buf_data_b => user_data_b); + +-- ChStat - byte buffer + CSB: tx_bitbuf + generic map (ENABLE_BUFFER => CH_STAT_BUF) + port map ( + wb_clk_i => wb_clk_i, + wb_rst_i => wb_rst_i, + buf_wr => ch_status_wr, + wb_adr_i => wb_adr_i(4 downto 0), + wb_dat_i => wb_dat_i(15 downto 0), + buf_data_a => ch_stat_a, + buf_data_b => ch_stat_b); + +-- Transmit encoder + TENC: tx_encoder + generic map (DATA_WIDTH => DATA_WIDTH, + ADDR_WIDTH => ADDR_WIDTH) + port map ( + wb_clk_i => wb_clk_i, + conf_mode => conf_mode, -- sample format + conf_ratio => conf_ratio, -- clock divider + conf_udaten => conf_udaten, -- user data control + conf_chsten => conf_chsten, -- ch. status control + conf_txdata => conf_txdata, -- sample data enable + conf_txen => conf_txen, -- spdif signal enable + user_data_a => user_data_a, -- ch. a user data + user_data_b => user_data_b, -- ch. b user data + ch_stat_a => ch_stat_a, -- ch. a status + ch_stat_b => ch_stat_b, -- ch. b status + chstat_freq => chstat_freq, -- sample freq. + chstat_gstat => chstat_gstat, -- generation status + chstat_preem => chstat_preem, -- preemphasis status + chstat_copy => chstat_copy, -- copyright bit + chstat_audio => chstat_audio, -- data format + sample_data => sample_data, -- audio data + mem_rd => mem_rd, -- sample buffer read + sample_addr => sample_addr, -- address + evt_lcsbf => evt_lcsbf, -- lower ch.st./user data buf empty + evt_hcsbf => evt_hcsbf, -- higher ch.st/user data buf empty + evt_hsbf => evt_hsbf, -- higher sample buf empty event + evt_lsbf => evt_lsbf, -- lower sample buf empty event + spdif_tx_o => spdif_tx_o); -- SPDIF output signal + +end rtl; + Index: tags/spdif_rel_1/rtl/vhdl/rx_decode.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_decode.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_decode.vhd (revision 64) @@ -0,0 +1,258 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Sample decoder. Extract sample words and write to sample ---- +---- buffer. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.4 2004/07/11 16:19:50 gedra +-- Bug-fix. +-- +-- Revision 1.3 2004/06/26 14:14:47 gedra +-- Converted to numeric_std and fixed a few bugs. +-- +-- Revision 1.2 2004/06/16 19:04:09 gedra +-- Fixed a few bugs. +-- +-- Revision 1.1 2004/06/13 18:07:47 gedra +-- Frame decoder and sample extractor +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity rx_decode is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64); + port ( + wb_clk_i: in std_logic; + conf_rxen: in std_logic; + conf_sample: in std_logic; + conf_valid: in std_logic; + conf_mode: in std_logic_vector(3 downto 0); + conf_blken: in std_logic; + conf_valen: in std_logic; + conf_useren: in std_logic; + conf_staten: in std_logic; + conf_paren: in std_logic; + lock: in std_logic; + rx_data: in std_logic; + rx_data_en: in std_logic; + rx_block_start: in std_logic; + rx_frame_start: in std_logic; + rx_channel_a: in std_logic; + wr_en: out std_logic; + wr_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); + wr_data: out std_logic_vector(DATA_WIDTH - 1 downto 0); + stat_paritya: out std_logic; + stat_parityb: out std_logic; + stat_lsbf: out std_logic; + stat_hsbf: out std_logic); +end rx_decode; + +architecture rtl of rx_decode is + + signal adr_cnt : integer range 0 to 2**(ADDR_WIDTH - 1) - 1; + type samp_states is (IDLE, CHA_SYNC, GET_SAMP, PAR_CHK); + signal sampst : samp_states; + signal bit_cnt, par_cnt : integer range 0 to 31; + signal samp_start : integer range 0 to 15; + signal tmp_data : std_logic_vector(26 downto 0); + signal tmp_stat : std_logic_vector(4 downto 0); + signal valid, next_is_a, blk_start : std_logic; + +begin + +-- output data + OD32: if DATA_WIDTH = 32 generate + wr_data(31 downto 27) <= tmp_stat; + wr_data(26 downto 0) <= tmp_data(26 downto 0); + end generate OD32; + OD16: if DATA_WIDTH = 16 generate + wr_data(15 downto 0) <= tmp_data(15 downto 0); + end generate OD16; + +-- State machine extracting audio samples + SAEX: process (wb_clk_i, conf_rxen) + begin -- process SAEX + if conf_rxen = '0' then + adr_cnt <= 0; + next_is_a <= '1'; + wr_en <= '0'; + wr_addr <= (others => '0'); + tmp_data <= (others => '0'); + par_cnt <= 0; + blk_start <= '0'; + stat_paritya <= '0'; + stat_parityb <= '0'; + stat_lsbf <= '0'; + stat_hsbf <= '0'; + valid <= '0'; + bit_cnt <= 0; + sampst <= IDLE; + tmp_stat <= (others => '0'); + elsif rising_edge(wb_clk_i) then + --extract and store samples + case sampst is + when IDLE => + next_is_a <= '1'; + if lock = '1' and conf_sample = '1' then + sampst <= CHA_SYNC; + end if; + when CHA_SYNC => + wr_addr <= std_logic_vector(to_unsigned(adr_cnt, ADDR_WIDTH - 1)); + wr_en <= '0'; + bit_cnt <= 0; + valid <= '0'; + par_cnt <= 0; + stat_paritya <= '0'; + stat_parityb <= '0'; + stat_lsbf <= '0'; + stat_hsbf <= '0'; + tmp_data(26 downto 0) <= (others => '0'); + if rx_block_start = '1' and conf_blken = '1' then + blk_start <= '1'; + end if; + if rx_frame_start = '1' and rx_channel_a = next_is_a then + next_is_a <= not next_is_a; + sampst <= GET_SAMP; + end if; + when GET_SAMP => + tmp_stat(0) <= blk_start; + if rx_data_en = '1' then + bit_cnt <= bit_cnt + 1; + -- audio part + if bit_cnt >= samp_start and bit_cnt <= 23 then + tmp_data(bit_cnt - samp_start) <= rx_data; + end if; + -- status bits + case bit_cnt is + when 24 => -- validity bit + valid <= rx_data; + if conf_valen = '1' then + tmp_stat(1) <= rx_data; + else + tmp_stat(1) <= '0'; + end if; + when 25 => -- user data + if conf_useren = '1' then + tmp_stat(2) <= rx_data; + else + tmp_stat(2) <= '0'; + end if; + when 26 => -- channel status + if conf_staten = '1' then + tmp_stat(3) <= rx_data; + else + tmp_stat(3) <= '0'; + end if; + when 27 => -- parity bit + if conf_paren = '1' then + tmp_stat(4) <= rx_data; + else + tmp_stat(4) <= '0'; + end if; + when others => + null; + end case; + -- parity: count number of 1's + if rx_data = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + if bit_cnt = 28 then + sampst <= PAR_CHK; + end if; + when PAR_CHK => + blk_start <= '0'; + if (valid = '0' and conf_valid = '1') or conf_valid = '0' then + wr_en <= '1'; + end if; + -- parity check + if par_cnt mod 2 /= 0 then + if rx_channel_a = '1' then + stat_paritya <= '1'; + else + stat_parityb <= '1'; + end if; + end if; + -- address counter + if adr_cnt < 2**(ADDR_WIDTH - 1) - 1 then + adr_cnt <= adr_cnt + 1; + else + adr_cnt <= 0; + stat_hsbf <= '1'; -- signal high buffer full + end if; + if adr_cnt = 2**(ADDR_WIDTH - 2) - 1 then + stat_lsbf <= '1'; -- signal low buffer full + end if; + sampst <= CHA_SYNC; + when others => + sampst <= IDLE; + end case; + end if; + end process SAEX; + +-- determine sample resolution from mode bits in 32bit mode + M32: if DATA_WIDTH = 32 generate + samp_start <= 8 when conf_mode = "0000" else + 7 when conf_mode = "0001" else + 6 when conf_mode = "0010" else + 5 when conf_mode = "0011" else + 4 when conf_mode = "0100" else + 3 when conf_mode = "0101" else + 2 when conf_mode = "0110" else + 1 when conf_mode = "0111" else + 0 when conf_mode = "1000" else + 8; + end generate M32; +-- in 16bit mode only 16bit of audio is supported + M16: if DATA_WIDTH = 16 generate + samp_start <= 8; + end generate M16; + + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/tx_bitbuf.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_bitbuf.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_bitbuf.vhd (revision 64) @@ -0,0 +1,108 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Bit buffer holding 2x192 bits of either channel status or ---- +---- user data for the transmitter. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/07/17 17:21:11 gedra +-- Fixed bug. +-- +-- Revision 1.1 2004/07/14 17:58:19 gedra +-- Transmitter channel status buffer. +-- +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tx_bitbuf is + generic (ENABLE_BUFFER: integer range 0 to 1); + port ( + wb_clk_i: in std_logic; -- clock + wb_rst_i: in std_logic; -- reset + buf_wr: in std_logic; -- buffer write strobe + wb_adr_i: in std_logic_vector(4 downto 0); -- address + wb_dat_i: in std_logic_vector(15 downto 0); -- data + buf_data_a: out std_logic_vector(191 downto 0); + buf_data_b: out std_logic_vector(191 downto 0)); +end tx_bitbuf; + +architecture rtl of tx_bitbuf is + + type buf_type is array (0 to 23) of std_logic_vector(7 downto 0); + signal buffer_a, buffer_b: buf_type; + +begin + + -- the byte buffer is 192 bits (24 bytes) for each channel + EB: if ENABLE_BUFFER = 1 generate + WBUF: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + for i in 0 to 23 loop + buffer_a(i) <= (others => '0'); + buffer_b(i) <= (others => '0'); + end loop; + elsif rising_edge(wb_clk_i) then + if buf_wr = '1' and to_integer(unsigned(wb_adr_i)) < 24 then + buffer_a(to_integer(unsigned(wb_adr_i))) <= wb_dat_i(7 downto 0); + buffer_b(to_integer(unsigned(wb_adr_i))) <= wb_dat_i(15 downto 8); + end if; + end if; + end process WBUF; + VGEN: for k in 0 to 23 generate + buf_data_a(8 * k + 7 downto 8 * k) <= buffer_a(k); + buf_data_b(8 * k + 7 downto 8 * k) <= buffer_b(k); + end generate VGEN; + end generate EB; + + -- if the byte buffer is not enabled, set all bits to zero + NEB: if ENABLE_BUFFER = 0 generate + buf_data_a(191 downto 0) <= (others => '0'); + buf_data_b(191 downto 0) <= (others => '0'); + end generate NEB; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/tx_package.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_package.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_package.vhd (revision 64) @@ -0,0 +1,189 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter component package. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/07/14 17:58:49 gedra +-- Added new components. +-- +-- Revision 1.1 2004/07/13 18:30:25 gedra +-- Transmitter component declarations. +-- +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +package tx_package is + +-- components used in the transmitter + + component gen_control_reg + generic (DATA_WIDTH: integer; + -- note that this vector is (0 to xx), reverse order + ACTIVE_BIT_MASK: std_logic_vector); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + ctrl_wr: in std_logic; -- control register write + ctrl_rd: in std_logic; -- control register read + ctrl_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + ctrl_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); + ctrl_bits: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component gen_event_reg + generic (DATA_WIDTH: integer); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + evt_wr: in std_logic; -- event register write + evt_rd: in std_logic; -- event register read + evt_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data + event: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector + evt_mask: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask + evt_en: in std_logic; -- irq enable + evt_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data + evt_irq: out std_logic); -- interrupt request + end component; + + component dpram + generic (DATA_WIDTH: positive; + RAM_WIDTH: positive); + port ( + clk: in std_logic; + rst: in std_logic; -- reset is optional, not used here + din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + wr_en: in std_logic; + rd_en: in std_logic; + wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component tx_wb_decoder + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- wishbone clock + wb_rst_i: in std_logic; -- reset signal + wb_sel_i: in std_logic; -- select input + wb_stb_i: in std_logic; -- strobe input + wb_we_i: in std_logic; -- write enable + wb_cyc_i: in std_logic; -- cycle input + wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension + wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address + data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus + wb_ack_o: out std_logic; -- acknowledge + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out + version_rd: out std_logic; -- Version register read + config_rd: out std_logic; -- Config register read + config_wr: out std_logic; -- Config register write + chstat_rd: out std_logic; -- Channel Status register read + chstat_wr: out std_logic; -- Channel Status register write + intmask_rd: out std_logic; -- Interrupt mask register read + intmask_wr: out std_logic; -- Interrupt mask register write + intstat_rd: out std_logic; -- Interrupt status register read + intstat_wr: out std_logic; -- Interrupt status register read + mem_wr: out std_logic; -- Sample memory write + user_data_wr: out std_logic; -- User data write + ch_status_wr: out std_logic); -- Ch. status write + end component; + + component tx_ver_reg + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer; + USER_DATA_BUF: integer; + CH_STAT_BUF: integer); + port ( + ver_rd: in std_logic; -- version register read + ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component tx_bitbuf + generic (ENABLE_BUFFER: integer range 0 to 1); + port ( + wb_clk_i: in std_logic; -- clock + wb_rst_i: in std_logic; -- reset + buf_wr: in std_logic; -- buffer write strobe + wb_adr_i: in std_logic_vector(4 downto 0); -- address + wb_dat_i: in std_logic_vector(15 downto 0); -- data + buf_data_a: out std_logic_vector(191 downto 0); + buf_data_b: out std_logic_vector(191 downto 0)); + end component; + + component tx_encoder + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64); + port ( + wb_clk_i: in std_logic; -- clock + conf_mode: in std_logic_vector(3 downto 0); -- sample format + conf_ratio: in std_logic_vector(7 downto 0); -- clock divider + conf_udaten: in std_logic_vector(1 downto 0); -- user data control + conf_chsten: in std_logic_vector(1 downto 0); -- ch. status control + conf_txdata: in std_logic; -- sample data enable + conf_txen: in std_logic; -- spdif signal enable + user_data_a: in std_logic_vector(191 downto 0); -- ch. a user data + user_data_b: in std_logic_vector(191 downto 0); -- ch. b user data + ch_stat_a: in std_logic_vector(191 downto 0); -- ch. a status + ch_stat_b: in std_logic_vector(191 downto 0); -- ch. b status + chstat_freq: in std_logic_vector(1 downto 0); -- sample freq. + chstat_gstat: in std_logic; -- generation status + chstat_preem: in std_logic; -- preemphasis status + chstat_copy: in std_logic; -- copyright bit + chstat_audio: in std_logic; -- data format + sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data + mem_rd: out std_logic; -- sample buffer read + sample_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); -- address + evt_lcsbf: out std_logic; -- lower ch.st./user data buf empty + evt_hcsbf: out std_logic; -- higher ch.st/user data buf empty + evt_hsbf: out std_logic; -- higher sample buf empty event + evt_lsbf: out std_logic; -- lower sample buf empty event + spdif_tx_o: out std_logic); + end component; + +end tx_package; Index: tags/spdif_rel_1/rtl/vhdl/tx_encoder.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_encoder.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_encoder.vhd (revision 64) @@ -0,0 +1,510 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter signal encoder. Reads out samples from the ---- +---- sample buffer, assembles frames and subframes and encodes ---- +---- serial data as bi-phase mark code. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tx_encoder is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64); + port ( + wb_clk_i: in std_logic; -- clock + conf_mode: in std_logic_vector(3 downto 0); -- sample format + conf_ratio: in std_logic_vector(7 downto 0); -- clock divider + conf_udaten: in std_logic_vector(1 downto 0); -- user data control + conf_chsten: in std_logic_vector(1 downto 0); -- ch. status control + conf_txdata: in std_logic; -- sample data enable + conf_txen: in std_logic; -- spdif signal enable + user_data_a: in std_logic_vector(191 downto 0); -- ch. a user data + user_data_b: in std_logic_vector(191 downto 0); -- ch. b user data + ch_stat_a: in std_logic_vector(191 downto 0); -- ch. a status + ch_stat_b: in std_logic_vector(191 downto 0); -- ch. b status + chstat_freq: in std_logic_vector(1 downto 0); -- sample freq. + chstat_gstat: in std_logic; -- generation status + chstat_preem: in std_logic; -- preemphasis status + chstat_copy: in std_logic; -- copyright bit + chstat_audio: in std_logic; -- data format + sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data + mem_rd: out std_logic; -- sample buffer read + sample_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); -- address + evt_lcsbf: out std_logic; -- lower ch.st./user data buf empty + evt_hcsbf: out std_logic; -- higher ch.st/user data buf empty + evt_hsbf: out std_logic; -- higher sample buf empty event + evt_lsbf: out std_logic; -- lower sample buf empty event + spdif_tx_o: out std_logic); +end tx_encoder; + +architecture rtl of tx_encoder is + + signal spdif_clk_en, spdif_out : std_logic; + signal clk_cnt : integer range 0 to 511; + type buf_states is (IDLE, READ_CHA, READ_CHB, CHA_RDY, CHB_RDY); + signal bufctrl : buf_states; + signal adr_cnt : integer range 0 to 2**(ADDR_WIDTH - 1) - 1; + signal cha_samp_ack, chb_samp_ack : std_logic; + type frame_states is (IDLE, BLOCK_START, CHANNEL_A, CHANNEL_B); + signal framest : frame_states; + signal frame_cnt : integer range 0 to 191; + signal bit_cnt, par_cnt : integer range 0 to 31; + signal inv_preamble, toggle, valid : std_logic; + signal def_user_data, def_ch_status : std_logic_vector(191 downto 0); + signal active_user_data, active_ch_status : std_logic_vector(191 downto 0); + signal audio : std_logic_vector(23 downto 0); + signal par_vector : std_logic_vector(26 downto 0); + signal send_audio, imem_rd : std_logic; + + constant X_PREAMBLE : std_logic_vector(0 to 7) := "11100010"; + constant Y_PREAMBLE : std_logic_vector(0 to 7) := "11100100"; + constant Z_PREAMBLE : std_logic_vector(0 to 7) := "11101000"; + + function encode_bit ( + signal bit_cnt : integer; -- sub-frame bit position + signal valid : std_logic; -- validity bit + signal frame_cnt : integer; -- frame counter + signal par_cnt : integer; -- parity counter + signal user_data : std_logic_vector(191 downto 0); + signal ch_status : std_logic_vector(191 downto 0); + signal audio : std_logic_vector(23 downto 0); + signal toggle : std_logic; + signal prev_spdif : std_logic) -- prev. value of spdif signal + return std_logic is + variable spdif, next_bit : std_logic; + begin + if bit_cnt > 3 and bit_cnt < 28 then -- audio part + next_bit := audio(bit_cnt - 4); + elsif bit_cnt = 28 then -- validity bit + next_bit := valid; + elsif bit_cnt = 29 then -- user data + next_bit := user_data(frame_cnt); + elsif bit_cnt = 30 then + next_bit := ch_status(frame_cnt); -- channel status + elsif bit_cnt = 31 then + if par_cnt mod 2 = 1 then + next_bit := '1'; + else + next_bit := '0'; + end if; + end if; + -- bi-phase mark encoding: + if next_bit = '0' then + if toggle = '0' then + spdif := not prev_spdif; + else + spdif := prev_spdif; + end if; + else + spdif := not prev_spdif; + end if; + return(spdif); + end encode_bit; + +begin + +-- SPDIF clock enable generation. The clock is a fraction of the Wishbone bus +-- clock, determined by the conf_ratio value. + CGEN: process (wb_clk_i) + begin + if rising_edge(wb_clk_i) then + if conf_txen = '0' then -- transmitter disabled + spdif_clk_en <= '0'; + clk_cnt <= 0; + else -- transmitter enabled + if clk_cnt < to_integer(unsigned(conf_ratio)) then -- <= ? + clk_cnt <= clk_cnt + 1; + spdif_clk_en <= '0'; + else + clk_cnt <= 0; + spdif_clk_en <= '1'; + end if; + end if; + end if; + end process CGEN; + +-- Sample memory read process. Enabled by the conf_txdata bit. +-- Buffer address is reset when disabled. Also generates events for +-- lower and upper buffer empty conditions + sample_addr <= std_logic_vector(to_unsigned(adr_cnt, ADDR_WIDTH - 1)); + mem_rd <= imem_rd; + + SRD: process (wb_clk_i) + begin + if rising_edge(wb_clk_i) then + if conf_txdata = '0' then + bufctrl <= IDLE; + imem_rd <= '0'; + adr_cnt <= 0; + evt_lsbf <= '0'; + evt_hsbf <= '0'; + else + case bufctrl is + when IDLE => + adr_cnt <= 0; + imem_rd <= '0'; + if conf_txdata = '1' then + bufctrl <= READ_CHA; + imem_rd <='1'; + end if; + when READ_CHA => + imem_rd <= '0'; + adr_cnt <= (adr_cnt + 1) mod 2**(ADDR_WIDTH - 1); + bufctrl <= CHA_RDY; + when CHA_RDY => + if cha_samp_ack = '1' then + imem_rd <= '1'; + bufctrl <= READ_CHB; + end if; + when READ_CHB => + imem_rd <= '0'; + adr_cnt <= (adr_cnt + 1) mod 2**(ADDR_WIDTH - 1); + bufctrl <= CHB_RDY; + when CHB_RDY => + if chb_samp_ack = '1' then + imem_rd <= '1'; + bufctrl <= READ_CHA; + end if; + when others => + bufctrl <= IDLE; + end case; + -- generate lower/upper buffer empty events + if imem_rd = '1' then + if adr_cnt = 2**(ADDR_WIDTH - 2) - 1 then + evt_lsbf <= '1'; + else + evt_lsbf <= '0'; + end if; + if adr_cnt = 2**(ADDR_WIDTH - 1) - 1 then + evt_hsbf <= '1'; + else + evt_hsbf <= '0'; + end if; + end if; + end if; + end if; + end process SRD; + +-- State machine that generates sub-frames and blocks + spdif_tx_o <= spdif_out; + + FRST: process (wb_clk_i) + begin + if rising_edge(wb_clk_i) then + if conf_txen = '0' then + framest <= IDLE; + frame_cnt <= 0; + bit_cnt <= 0; + spdif_out <= '0'; + inv_preamble <= '0'; + toggle <= '0'; + valid <= '1'; + send_audio <= '0'; + cha_samp_ack <= '0'; + chb_samp_ack <= '0'; + evt_lcsbf <= '0'; + evt_hcsbf <= '0'; + else + if spdif_clk_en = '1' then -- SPDIF clock is twice the bit rate + case framest is + when IDLE => + bit_cnt <= 0; + frame_cnt <= 0; + inv_preamble <= '0'; + toggle <= '0'; + framest <= BLOCK_START; + when BLOCK_START => -- Start of channels status block/Ch. A + evt_lcsbf <= '0'; + evt_hcsbf <= '0'; + chb_samp_ack <= '0'; + toggle <= not toggle; -- Each bit uses two clock enables, + if toggle = '1' then -- counted by the toggle bit. + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + if send_audio = '1' then + cha_samp_ack <= '1'; + end if; + framest <= CHANNEL_B; + end if; + end if; + -- Block start uses preamble Z. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= Z_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= Z_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when CHANNEL_A => -- Sub-frame: channel A. + evt_lcsbf <= '0'; + evt_hcsbf <= '0'; + chb_samp_ack <= '0'; + toggle <= not toggle; + if toggle = '1' then + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + if spdif_out = '1' then + inv_preamble <= '1'; + else + inv_preamble <= '0'; + end if; + if send_audio = '1' then + cha_samp_ack <= '1'; + end if; + framest <= CHANNEL_B; + end if; + end if; + -- Channel A uses preable X. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= X_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= X_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when CHANNEL_B => -- Sub-frame: channel B. + cha_samp_ack <= '0'; + toggle <= not toggle; + if toggle = '1' then + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + valid <= not conf_txdata; + if spdif_out = '1' then + inv_preamble <= '1'; + else + inv_preamble <= '0'; + end if; + send_audio <= conf_txdata; -- 1 if audio samples sohuld be sent + if send_audio = '1' then + chb_samp_ack <= '1'; + end if; + if frame_cnt < 191 then -- One block is 192 frames + frame_cnt <= frame_cnt + 1; + if frame_cnt = 96 then + evt_lcsbf <= '1'; + end if; + framest <= CHANNEL_A; + else + frame_cnt <= 0; + evt_hcsbf <= '1'; + framest <= BLOCK_START; + end if; + end if; + end if; + -- Channel B uses preable Y. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= Y_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= Y_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when others => + framest <= IDLE; + end case; + end if; + end if; + end if; + end process FRST; + +-- Audio data latching + DA32: if DATA_WIDTH = 32 generate + ALAT: process (wb_clk_i) + begin + if rising_edge(wb_clk_i) then + if send_audio = '0' then + audio(23 downto 0) <= (others => '0'); + else + case to_integer(unsigned(conf_mode)) is + when 0 => -- 16 bit audio + audio(23 downto 8) <= sample_data(15 downto 0); + audio(7 downto 0) <= (others => '0'); + when 1 => -- 17 bit audio + audio(23 downto 7) <= sample_data(16 downto 0); + audio(6 downto 0) <= (others => '0'); + when 2 => -- 18 bit audio + audio(23 downto 6) <= sample_data(17 downto 0); + audio(5 downto 0) <= (others => '0'); + when 3 => -- 19 bit audio + audio(23 downto 5) <= sample_data(18 downto 0); + audio(4 downto 0) <= (others => '0'); + when 4 => -- 20 bit audio + audio(23 downto 4) <= sample_data(19 downto 0); + audio(3 downto 0) <= (others => '0'); + when 5 => -- 21 bit audio + audio(23 downto 3) <= sample_data(20 downto 0); + audio(2 downto 0) <= (others => '0'); + when 6 => -- 22 bit audio + audio(23 downto 2) <= sample_data(21 downto 0); + audio(1 downto 0) <= (others => '0'); + when 7 => -- 23 bit audio + audio(23 downto 1) <= sample_data(22 downto 0); + audio(0) <= '0'; + when 8 => -- 24 bit audio + audio(23 downto 0) <= sample_data(23 downto 0); + when others => -- unsupported modes + audio(23 downto 0) <= (others => '0'); + end case; + end if; + end if; + end process ALAT; + end generate DA32; + + DA16: if DATA_WIDTH = 16 generate + ALAT: process (wb_clk_i) + begin + if rising_edge(wb_clk_i) then + if send_audio = '0' then + audio(23 downto 0) <= (others => '0'); + else + audio(23 downto 8) <= sample_data(15 downto 0); + audio(7 downto 0) <= (others => '0'); + end if; + end if; + end process ALAT; + end generate DA16; + +-- Parity vector. These bits are counted to generate even parity + par_vector(23 downto 0) <= audio(23 downto 0); + par_vector(24) <= valid; + par_vector(25) <= active_user_data(frame_cnt); + par_vector(26) <= active_ch_status(frame_cnt); + +-- Channel status and user datat to be used if buffers are disabled. +-- User data is then all zero, while channel status bits are taken from +-- register TxChStat. + def_user_data(191 downto 0) <= (others => '0'); + def_ch_status(0) <= '0'; -- consumer mode + def_ch_status(1) <= chstat_audio; -- audio bit + def_ch_status(2) <= chstat_copy; -- copy right + def_ch_status(5 downto 3) <= "000" when chstat_preem = '0' + else "001"; -- pre-emphasis + def_ch_status(7 downto 6) <= "00"; + def_ch_status(14 downto 8) <= (others => '0'); + def_ch_status(15) <= chstat_gstat; -- generation status + def_ch_status(23 downto 16) <= (others => '0'); + def_ch_status(27 downto 24) <= "0000" when chstat_freq = "00" else + "0010" when chstat_freq = "01" else + "0011" when chstat_freq = "10" else + "0001"; + def_ch_status(191 downto 28) <= (others => '0'); + +-- Generate channel status vector based on configuration register setting. + active_ch_status <= ch_stat_a when conf_chsten = "01" else + ch_stat_a when conf_chsten = "10" and framest = CHANNEL_A else + ch_stat_b when conf_chsten = "10" and framest = CHANNEL_B else + def_ch_status; + +-- Generate user data vector based on configuration register setting. + active_user_data <= user_data_a when conf_udaten = "01" else + user_data_a when conf_udaten = "10" and framest = CHANNEL_A else + user_data_b when conf_udaten = "10" and framest = CHANNEL_B else + def_user_data; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/tx_wb_decoder.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_wb_decoder.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_wb_decoder.vhd (revision 64) @@ -0,0 +1,204 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter: Wishbone bus cycle decoder. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/07/14 17:59:28 gedra +-- Changed write signal for status buffers. +-- +-- Revision 1.1 2004/07/13 18:29:50 gedra +-- Transmitter Wishbone bus cycle decoder. +-- +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tx_wb_decoder is + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- wishbone clock + wb_rst_i: in std_logic; -- reset signal + wb_sel_i: in std_logic; -- select input + wb_stb_i: in std_logic; -- strobe input + wb_we_i: in std_logic; -- write enable + wb_cyc_i: in std_logic; -- cycle input + wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension + wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address + data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus + wb_ack_o: out std_logic; -- acknowledge + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out + version_rd: out std_logic; -- Version register read + config_rd: out std_logic; -- Config register read + config_wr: out std_logic; -- Config register write + chstat_rd: out std_logic; -- Channel Status register read + chstat_wr: out std_logic; -- Channel Status register write + intmask_rd: out std_logic; -- Interrupt mask register read + intmask_wr: out std_logic; -- Interrupt mask register write + intstat_rd: out std_logic; -- Interrupt status register read + intstat_wr: out std_logic; -- Interrupt status register read + mem_wr: out std_logic; -- Sample memory write + user_data_wr: out std_logic; -- User data write + ch_status_wr: out std_logic); -- Ch. status write +end tx_wb_decoder; + +architecture rtl of tx_wb_decoder is + + constant REG_TXVERSION : std_logic_vector(6 downto 0) := "0000000"; + constant REG_TXCONFIG : std_logic_vector(6 downto 0) := "0000001"; + constant REG_TXCHSTAT : std_logic_vector(6 downto 0) := "0000010"; + constant REG_TXINTMASK : std_logic_vector(6 downto 0) := "0000011"; + constant REG_TXINTSTAT : std_logic_vector(6 downto 0) := "0000100"; + signal iack, iwr, ird : std_logic; + signal acnt: integer range 0 to 2**(ADDR_WIDTH - 1) - 1; + --signal all_ones : std_logic_vector(ADDR_WIDTH - 1 downto 0); + signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + + wb_ack_o <= iack; + +-- acknowledge generation + ACK: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + iack <= '0'; + elsif rising_edge(wb_clk_i) then + if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then + case wb_cti_i is + when "010" => -- incrementing burst + case wb_bte_i is -- burst extension + when "00" => -- linear burst + iack <= '1'; + when others => -- all other treated assert classic cycle + iack <= not iack; + end case; + when "111" => -- end of burst + iack <= not iack; + when others => -- all other treated assert classic cycle + iack <= not iack; + end case; + else + iack <= '0'; + end if; + end if; + end process ACK; + +-- write generation + WR: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + iwr <= '0'; + elsif rising_edge(wb_clk_i) then + if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and + wb_we_i = '1' then + case wb_cti_i is + when "010" => -- incrementing burst + case wb_bte_i is -- burst extension + when "00" => -- linear burst + iwr <= '1'; + when others => -- all other treated as classic cycle + iwr <= not iwr; + end case; + when "111" => -- end of burst + iwr <= not iwr; + when others => -- all other treated as classic cycle + iwr <= not iwr; + end case; + else + iwr <= '0'; + end if; + end if; + end process WR; + +-- read generation + ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and + wb_we_i = '0' else '0'; + + wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout; + + DREG: process (wb_clk_i) -- clock data from registers + begin + if rising_edge(wb_clk_i) then + rdout <= data_out; + end if; + end process DREG; + +-- read and write strobe generation + + version_rd <= '1' when wb_adr_i(6 downto 0) = REG_TXVERSION and ird = '1' + else '0'; + config_rd <= '1' when wb_adr_i(6 downto 0) = REG_TXCONFIG and ird = '1' + else '0'; + config_wr <= '1' when wb_adr_i(6 downto 0) = REG_TXCONFIG and iwr = '1' + else '0'; + chstat_rd <= '1' when wb_adr_i(6 downto 0) = REG_TXCHSTAT and ird = '1' + else '0'; + chstat_wr <= '1' when wb_adr_i(6 downto 0) = REG_TXCHSTAT and iwr = '1' + else '0'; + intmask_rd <= '1' when wb_adr_i(6 downto 0) = REG_TXINTMASK and ird = '1' + else '0'; + intmask_wr <= '1' when wb_adr_i(6 downto 0) = REG_TXINTMASK and iwr = '1' + else '0'; + intstat_rd <= '1' when wb_adr_i(6 downto 0) = REG_TXINTSTAT and ird = '1' + else '0'; + intstat_wr <= '1' when wb_adr_i(6 downto 0) = REG_TXINTSTAT and iwr = '1' + else '0'; + mem_wr <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and iwr = '1' else '0'; + +-- user data/ch. status register write strobes + user_data_wr <= '1' when iwr = '1' and + to_integer(unsigned(wb_adr_i)) > 31 and + to_integer(unsigned(wb_adr_i)) < 56 else '0'; + + ch_status_wr <= '1' when iwr = '1' and + to_integer(unsigned(wb_adr_i)) > 63 and + to_integer(unsigned(wb_adr_i)) < 88 else '0'; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/tx_ver_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/tx_ver_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/tx_ver_reg.vhd (revision 64) @@ -0,0 +1,86 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter TxVersion register. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tx_ver_reg is + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer; + USER_DATA_BUF: integer; + CH_STAT_BUF: integer); + port ( + ver_rd: in std_logic; -- version register read + ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); +end tx_ver_reg; + +architecture rtl of tx_ver_reg is + + signal version : std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + ver_dout <= version when ver_rd = '1' else (others => '0'); + + -- version vector generation + version(3 downto 0) <= "0001"; -- version 1 + G32: if DATA_WIDTH = 32 generate + version(4) <= '1'; + version(31 downto 16) <= (others => '0'); + end generate G32; + G16: if DATA_WIDTH = 16 generate + version(4) <= '0'; + end generate G16; + version(11 downto 5) <= std_logic_vector(to_unsigned(ADDR_WIDTH, 7)); + version(15 downto 14) <= (others => '0'); + version(12) <= '1' when USER_DATA_BUF = 1 else '0'; + version(13) <= '1' when CH_STAT_BUF = 1 else '0'; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_package.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_package.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_package.vhd (revision 64) @@ -0,0 +1,247 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver component package. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.8 2004/06/27 16:16:55 gedra +-- Signal renaming and bug fix. +-- +-- Revision 1.7 2004/06/26 14:14:47 gedra +-- Converted to numeric_std and fixed a few bugs. +-- +-- Revision 1.6 2004/06/23 18:10:17 gedra +-- Added Wishbone bus cycle decoder. +-- +-- Revision 1.5 2004/06/16 19:03:45 gedra +-- Changed status reg. declaration +-- +-- Revision 1.4 2004/06/13 18:08:09 gedra +-- Added frame decoder and sample extractor +-- +-- Revision 1.3 2004/06/10 18:57:36 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.2 2004/06/09 19:24:50 gedra +-- Added dual port ram. +-- +-- Revision 1.1 2004/06/07 18:06:00 gedra +-- Receiver component declarations. +-- +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package rx_package is + +-- type declarations + type bus_array is array (0 to 7) of std_logic_vector(31 downto 0); + +-- components + component rx_ver_reg + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer; + CH_ST_CAPTURE: integer); + port ( + ver_rd: in std_logic; -- version register read + ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); -- read data + end component; + + component gen_control_reg + generic (DATA_WIDTH: integer; + -- note that this vector is (0 to xx), reverse order + ACTIVE_BIT_MASK: std_logic_vector); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + ctrl_wr: in std_logic; -- control register write + ctrl_rd: in std_logic; -- control register read + ctrl_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + ctrl_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); + ctrl_bits: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component rx_status_reg + generic (DATA_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- clock + status_rd: in std_logic; -- status register read + lock: in std_logic; -- signal lock status + chas: in std_logic; -- channel A or B select + rx_block_start: in std_logic; -- start of block signal + ch_data: in std_logic; -- channel status/user data + cs_a_en: in std_logic; -- channel status ch. A enable + cs_b_en: in std_logic; -- channel status ch. B enable + status_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component gen_event_reg + generic (DATA_WIDTH: integer); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + evt_wr: in std_logic; -- event register write + evt_rd: in std_logic; -- event register read + evt_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data + event: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector + evt_mask: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask + evt_en: in std_logic; -- irq enable + evt_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data + evt_irq: out std_logic); -- interrupt request + end component; + + component rx_cap_reg + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + cap_ctrl_wr: in std_logic; -- control register write + cap_ctrl_rd: in std_logic; -- control register read + cap_data_rd: in std_logic; -- data register read + cap_din: in std_logic_vector(31 downto 0); -- write data + rx_block_start: in std_logic; -- start of block signal + ch_data: in std_logic; -- channel status/user data + ud_a_en: in std_logic; -- user data ch. A enable + ud_b_en: in std_logic; -- user data ch. B enable + cs_a_en: in std_logic; -- channel status ch. A enable + cs_b_en: in std_logic; -- channel status ch. B enable + cap_dout: out std_logic_vector(31 downto 0); -- read data + cap_evt: out std_logic); -- capture event (interrupt) + end component; + + component rx_phase_det + generic (WISHBONE_FREQ: natural := 33); -- WishBone frequency in MHz + port ( + wb_clk_i: in std_logic; + rxen: in std_logic; + spdif: in std_logic; + lock: out std_logic; + lock_evt: out std_logic; -- lock status change event + rx_data: out std_logic; + rx_data_en: out std_logic; + rx_block_start: out std_logic; + rx_frame_start: out std_logic; + rx_channel_a: out std_logic; + rx_error: out std_logic; + ud_a_en: out std_logic; -- user data ch. A enable + ud_b_en: out std_logic; -- user data ch. B enable + cs_a_en: out std_logic; -- channel status ch. A enable + cs_b_en: out std_logic); -- channel status ch. B enable); + end component; + + component dpram + generic (DATA_WIDTH: positive; + RAM_WIDTH: positive); + port ( + clk: in std_logic; + rst: in std_logic; -- reset is optional, not used here + din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + wr_en: in std_logic; + rd_en: in std_logic; + wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + component rx_decode + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64); + port ( + wb_clk_i: in std_logic; + conf_rxen: in std_logic; + conf_sample: in std_logic; + conf_valid: in std_logic; + conf_mode: in std_logic_vector(3 downto 0); + conf_blken: in std_logic; + conf_valen: in std_logic; + conf_useren: in std_logic; + conf_staten: in std_logic; + conf_paren: in std_logic; + lock: in std_logic; + rx_data: in std_logic; + rx_data_en: in std_logic; + rx_block_start: in std_logic; + rx_frame_start: in std_logic; + rx_channel_a: in std_logic; + wr_en: out std_logic; + wr_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); + wr_data: out std_logic_vector(DATA_WIDTH - 1 downto 0); + stat_paritya: out std_logic; + stat_parityb: out std_logic; + stat_lsbf: out std_logic; + stat_hsbf: out std_logic); + end component; + + component rx_wb_decoder + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- wishbone clock + wb_rst_i: in std_logic; -- reset signal + wb_sel_i: in std_logic; -- select input + wb_stb_i: in std_logic; -- strobe input + wb_we_i: in std_logic; -- write enable + wb_cyc_i: in std_logic; -- cycle input + wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address + wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier + data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus + wb_ack_o: out std_logic; -- acknowledge + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out + version_rd: out std_logic; -- Version register read + config_rd: out std_logic; -- Config register read + config_wr: out std_logic; -- Config register write + status_rd: out std_logic; -- Status register read + intmask_rd: out std_logic; -- Interrupt mask register read + intmask_wr: out std_logic; -- Interrupt mask register write + intstat_rd: out std_logic; -- Interrupt status register read + intstat_wr: out std_logic; -- Interrupt status register read + mem_rd: out std_logic; -- Sample memory read + mem_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); -- memory addr. + ch_st_cap_rd: out std_logic_vector(7 downto 0); -- Ch. status cap. read + ch_st_cap_wr: out std_logic_vector(7 downto 0); -- Ch. status cap. write + ch_st_data_rd: out std_logic_vector(7 downto 0)); -- Ch. status data read + end component; + +end rx_package; Index: tags/spdif_rel_1/rtl/vhdl/gen_event_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/gen_event_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/gen_event_reg.vhd (revision 64) @@ -0,0 +1,123 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Generic event register. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.4 2004/07/11 16:19:50 gedra +-- Bug-fix. +-- +-- Revision 1.3 2004/06/06 15:42:20 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.2 2004/06/04 15:55:07 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.1 2004/06/03 17:49:26 gedra +-- Generic event register. Used in both receiver and transmitter. +-- +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +entity gen_event_reg is + generic (DATA_WIDTH: integer:=32); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + evt_wr: in std_logic; -- event register write + evt_rd: in std_logic; -- event register read + evt_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data + event: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector + evt_mask: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask + evt_en: in std_logic; -- irq enable + evt_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data + evt_irq: out std_logic); -- interrupt request +end gen_event_reg; + +architecture rtl of gen_event_reg is + + signal evt_internal, zero: std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + + evt_dout <= evt_internal when evt_rd = '1' else (others => '0'); + zero <= (others => '0'); + +-- IRQ generation: +-- IRQ signal will pulse low when writing to the event register. This will +-- capture situations when not all active events are cleared or an event happens +-- at the same time as it is cleared. + IR: process (clk) + begin + if rising_edge(clk) then + if ((evt_internal and evt_mask) /= zero) and evt_wr = '0' + and evt_en = '1' then + evt_irq <= '1'; + else + evt_irq <= '0'; + end if; + end if; + end process IR; + +-- event register generation + EVTREG: for k in evt_din'range generate + EBIT: process (clk, rst) + begin + if rst = '1' then + evt_internal(k) <= '0'; + else + if rising_edge(clk) then + if event(k)= '1' then -- set event + evt_internal(k) <= '1'; + elsif evt_wr = '1' and evt_din(k) = '1' then -- clear event + evt_internal(k) <= '0'; + end if; + end if; + end if; + end process EBIT; + end generate EVTREG; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_status_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_status_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_status_reg.vhd (revision 64) @@ -0,0 +1,150 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver status register ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.4 2004/06/27 16:16:55 gedra +-- Signal renaming and bug fix. +-- +-- Revision 1.3 2004/06/26 14:14:47 gedra +-- Converted to numeric_std and fixed a few bugs. +-- +-- Revision 1.2 2004/06/16 19:03:10 gedra +-- Added channel status decoding. +-- +-- Revision 1.1 2004/06/05 17:17:12 gedra +-- Recevier status register +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +entity rx_status_reg is + generic (DATA_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- clock + status_rd: in std_logic; -- status register read + lock: in std_logic; -- signal lock status + chas: in std_logic; -- channel A or B select + rx_block_start: in std_logic; -- start of block signal + ch_data: in std_logic; -- channel status/user data + cs_a_en: in std_logic; -- channel status ch. A enable + cs_b_en: in std_logic; -- channel status ch. B enable + status_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); +end rx_status_reg; + +architecture rtl of rx_status_reg is + + signal status_vector : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal cur_pos : integer range 0 to 255; + signal pro_mode : std_logic; + +begin + + status_dout <= status_vector when status_rd = '1' else (others => '0'); + + D32: if DATA_WIDTH = 32 generate + status_vector(31 downto 16) <= (others => '0'); + end generate D32; + + status_vector(0) <= lock; + status_vector(15 downto 7) <= (others => '0'); + +-- extract channel status bits to be used + CDAT: process (wb_clk_i, lock) + begin + if lock = '0' then + cur_pos <= 0; + pro_mode <= '0'; + status_vector(6 downto 1) <= (others => '0'); + else + if rising_edge(wb_clk_i) then + -- bit counter, 0 to 191 + if rx_block_start = '1' then + cur_pos <= 0; + elsif cs_b_en = '1' then -- ch. status #2 comes last, count then + cur_pos <= cur_pos + 1; + end if; + -- extract status bits used in status register + if (chas = '0' and cs_b_en = '1') or + (chas = '1' and cs_a_en = '1') then + case cur_pos is + when 0 => -- PRO bit + status_vector(1) <= ch_data; + pro_mode <= ch_data; + when 1 => -- AUDIO bit + status_vector(2) <= not ch_data; + when 2 => -- emphasis/copy bit + if pro_mode = '1' then + status_vector(5) <= ch_data; + else + status_vector(6) <= ch_data; + end if; + when 3 => -- emphasis + if pro_mode = '1' then + status_vector(4) <= ch_data; + else + status_vector(5) <= ch_data; + end if; + when 4 => -- emphasis + if pro_mode = '1' then + status_vector(3) <= ch_data; + else + status_vector(4) <= ch_data; + end if; + when 5 => -- emphasis + if pro_mode = '0' then + status_vector(3) <= ch_data; + end if; + when others => + null; + end case; + end if; + end if; + end if; + end process CDAT; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_ver_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_ver_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_ver_reg.vhd (revision 64) @@ -0,0 +1,90 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver RxVersion register. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/06/04 15:55:07 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.1 2004/06/03 17:51:41 gedra +-- Receiver version register. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity rx_ver_reg is + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer; + CH_ST_CAPTURE: integer); + port ( + ver_rd: in std_logic; -- version register read + ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); -- read data +end rx_ver_reg; + +architecture rtl of rx_ver_reg is + + signal version : std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + ver_dout <= version when ver_rd = '1' else (others => '0'); + + -- version vector generation + version(3 downto 0) <= "0001"; -- version 1 + G32: if DATA_WIDTH = 32 generate + version(4) <= '1'; + version(31 downto 20) <= (others => '0'); + version(19 downto 16) <= + std_logic_vector(to_unsigned(CH_ST_CAPTURE, 4)); + end generate G32; + G16: if DATA_WIDTH = 16 generate + version(4) <= '0'; + end generate G16; + version(11 downto 5) <= std_logic_vector(to_unsigned(ADDR_WIDTH, 7)); + version(15 downto 12) <= (others => '0'); + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/dpram_rtl.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/dpram_rtl.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/dpram_rtl.vhd (revision 64) @@ -0,0 +1,110 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Dual port ram. This is a RTL implementation. Some synthesis ---- +---- tools like Synplify will automatically instantiate FPGA ---- +---- block ram. Substitute with dpram_altera or dpram_xilinx for ---- +---- Altera or Xilinx implementations using their free SW. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/06/10 18:57:36 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.1 2004/06/09 19:24:31 gedra +-- Generic dual port ram model. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity dpram is + generic (DATA_WIDTH: positive; + RAM_WIDTH: positive); + port ( + clk: in std_logic; + rst: in std_logic; -- reset is optional, not used here + din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + wr_en: in std_logic; + rd_en: in std_logic; + wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); +end dpram; + +--library synplify; -- uncomment this line when using Synplify +architecture rtl of dpram is + + type memory_type is array (2**RAM_WIDTH - 1 downto 0) of + std_logic_vector(DATA_WIDTH - 1 downto 0); + signal memory: memory_type; + signal lrd_addr: std_logic_vector(RAM_WIDTH - 1 downto 0); +-- Enable syn_ramstyle attribute when using Xilinx to enable block ram +-- otherwise you get embedded CLB ram. +-- attribute syn_ramstyle : string; +-- attribute syn_ramstyle of memory : signal is "block_ram"; + +begin + -- Generic ram, good synthesis programs will make block ram out of it... + process(clk) + begin + if rising_edge(clk) then + if wr_en = '1' then + memory(to_integer(unsigned(wr_addr))) <= din; + end if; + end if; + end process; + + process(clk) + begin + if rising_edge(clk) then + if rd_en = '1' then + dout <= memory(to_integer(unsigned(rd_addr))); + end if; + end if; + end process; + +end rtl; + Index: tags/spdif_rel_1/rtl/vhdl/gen_control_reg.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/gen_control_reg.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/gen_control_reg.vhd (revision 64) @@ -0,0 +1,108 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Generic control register. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.3 2004/06/06 15:42:19 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.2 2004/06/04 15:55:07 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.1 2004/06/03 17:47:17 gedra +-- Generic control register. Used in both recevier and transmitter. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +entity gen_control_reg is + generic (DATA_WIDTH: integer; + -- note that this vector is (0 to xx), reverse order + ACTIVE_BIT_MASK: std_logic_vector); + port ( + clk: in std_logic; -- clock + rst: in std_logic; -- reset + ctrl_wr: in std_logic; -- control register write + ctrl_rd: in std_logic; -- control register read + ctrl_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data + ctrl_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data + ctrl_bits: out std_logic_vector(DATA_WIDTH - 1 downto 0)); -- control bits +end gen_control_reg; + +architecture rtl of gen_control_reg is + + signal ctrl_internal: std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + + ctrl_dout <= ctrl_internal when ctrl_rd = '1' else (others => '0'); + ctrl_bits <= ctrl_internal; + +-- control register generation + CTRLREG: for k in ctrl_din'range generate + -- active bits can be written to + ACTIVE: if ACTIVE_BIT_MASK(k) = '1' generate + CBIT: process (clk, rst) + begin + if rst = '1' then + ctrl_internal(k) <= '0'; + else + if rising_edge(clk) then + if ctrl_wr = '1' then + ctrl_internal(k) <= ctrl_din(k); + end if; + end if; + end if; + end process CBIT; + end generate ACTIVE; + -- inactive bits are always 0 + INACTIVE: if ACTIVE_BIT_MASK(k) = '0' generate + ctrl_internal(k) <= '0'; + end generate INACTIVE; + end generate CTRLREG; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/rx_wb_decoder.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/rx_wb_decoder.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/rx_wb_decoder.vhd (revision 64) @@ -0,0 +1,243 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF receiver: Wishbone bus cycle decoder. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/06/24 19:25:03 gedra +-- Added data output. +-- +-- Revision 1.1 2004/06/23 18:09:57 gedra +-- Wishbone bus cycle decoder. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity rx_wb_decoder is + generic (DATA_WIDTH: integer; + ADDR_WIDTH: integer); + port ( + wb_clk_i: in std_logic; -- wishbone clock + wb_rst_i: in std_logic; -- reset signal + wb_sel_i: in std_logic; -- select input + wb_stb_i: in std_logic; -- strobe input + wb_we_i: in std_logic; -- write enable + wb_cyc_i: in std_logic; -- cycle input + wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension + wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address + data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus + wb_ack_o: out std_logic; -- acknowledge + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out + version_rd: out std_logic; -- Version register read + config_rd: out std_logic; -- Config register read + config_wr: out std_logic; -- Config register write + status_rd: out std_logic; -- Status register read + intmask_rd: out std_logic; -- Interrupt mask register read + intmask_wr: out std_logic; -- Interrupt mask register write + intstat_rd: out std_logic; -- Interrupt status register read + intstat_wr: out std_logic; -- Interrupt status register read + mem_rd: out std_logic; -- Sample memory read + mem_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); -- memory addr. + ch_st_cap_rd: out std_logic_vector(7 downto 0); -- Ch. status cap. read + ch_st_cap_wr: out std_logic_vector(7 downto 0); -- Ch. status cap. write + ch_st_data_rd: out std_logic_vector(7 downto 0)); -- Ch. status data read +end rx_wb_decoder; + +architecture rtl of rx_wb_decoder is + + constant REG_RXVERSION : std_logic_vector(6 downto 0) := "0000000"; + constant REG_RXCONFIG : std_logic_vector(6 downto 0) := "0000001"; + constant REG_RXSTATUS : std_logic_vector(6 downto 0) := "0000010"; + constant REG_RXINTMASK : std_logic_vector(6 downto 0) := "0000011"; + constant REG_RXINTSTAT : std_logic_vector(6 downto 0) := "0000100"; + signal iack, iwr, ird : std_logic; + signal acnt: integer range 0 to 2**(ADDR_WIDTH - 1) - 1; + signal all_ones : std_logic_vector(ADDR_WIDTH - 1 downto 0); + signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0); + +begin + + wb_ack_o <= iack; + +-- acknowledge generation + ACK: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + iack <= '0'; + elsif rising_edge(wb_clk_i) then + if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then + case wb_cti_i is + when "010" => -- incrementing burst + case wb_bte_i is -- burst extension + when "00" => -- linear burst + iack <= '1'; + when others => -- all other treated assert classic cycle + iack <= not iack; + end case; + when "111" => -- end of burst + iack <= not iack; + when others => -- all other treated assert classic cycle + iack <= not iack; + end case; + else + iack <= '0'; + end if; + end if; + end process ACK; + +-- write generation + WR: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + iwr <= '0'; + elsif rising_edge(wb_clk_i) then + if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and + wb_we_i = '1' then + case wb_cti_i is + when "010" => -- incrementing burst + case wb_bte_i is -- burst extension + when "00" => -- linear burst + iwr <= '1'; + when others => -- all other treated assert classic cycle + iwr <= not iwr; + end case; + when "111" => -- end of burst + iwr <= not iwr; + when others => -- all other treated assert classic cycle + iwr <= not iwr; + end case; + else + iwr <= '0'; + end if; + end if; + end process WR; + +-- read generation + ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and + wb_we_i = '0' else '0'; + + wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout; + + DREG: process (wb_clk_i) -- clock data from registers + begin + if rising_edge(wb_clk_i) then + rdout <= data_out; + end if; + end process DREG; + +-- sample memory read address. This needs special attention due to read latency + mem_addr <= std_logic_vector(to_unsigned(acnt, ADDR_WIDTH - 1)) when + wb_cti_i = "010" and wb_we_i = '0' and iack = '1' and + wb_bte_i = "00" else wb_adr_i(ADDR_WIDTH - 2 downto 0); + + all_ones(ADDR_WIDTH - 1 downto 0) <= (others => '1'); + + SMA: process (wb_clk_i, wb_rst_i) + begin + if wb_rst_i = '1' then + acnt <= 0; + elsif rising_edge(wb_clk_i) then + if wb_cti_i = "010" and wb_we_i = '0' and wb_bte_i = "00" then + if iack = '0' then + if wb_adr_i = all_ones then + acnt <= 0; + else + acnt <= to_integer(unsigned(wb_adr_i)) + 1; + end if; + else + if acnt < 2**(ADDR_WIDTH - 1) - 1 then + acnt <= acnt + 1; + else + acnt <= 0; + end if; + end if; + end if; + end if; + end process SMA; + +-- read and write strobe generation + + version_rd <= '1' when wb_adr_i(6 downto 0) = REG_RXVERSION and ird = '1' + else '0'; + config_rd <= '1' when wb_adr_i(6 downto 0) = REG_RXCONFIG and ird = '1' + else '0'; + config_wr <= '1' when wb_adr_i(6 downto 0) = REG_RXCONFIG and iwr = '1' + else '0'; + status_rd <= '1' when wb_adr_i(6 downto 0) = REG_RXSTATUS and ird = '1' + else '0'; + intmask_rd <= '1' when wb_adr_i(6 downto 0) = REG_RXINTMASK and ird = '1' + else '0'; + intmask_wr <= '1' when wb_adr_i(6 downto 0) = REG_RXINTMASK and iwr = '1' + else '0'; + intstat_rd <= '1' when wb_adr_i(6 downto 0) = REG_RXINTSTAT and ird = '1' + else '0'; + intstat_wr <= '1' when wb_adr_i(6 downto 0) = REG_RXINTSTAT and iwr = '1' + else '0'; + mem_rd <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and ird = '1' else '0'; + +-- capture register strobes + CR32: if DATA_WIDTH = 32 generate + CRST: for k in 0 to 7 generate + ch_st_cap_rd(k) <= '1' when ird = '1' and wb_adr_i(6 downto 4) = "001" + and wb_adr_i(3 downto 0) = std_logic_vector(to_unsigned(2*k,4)) + else '0'; + ch_st_cap_wr(k) <= '1' when iwr = '1' and wb_adr_i(6 downto 4) = "001" + and wb_adr_i(3 downto 0) = std_logic_vector(to_unsigned(2*k,4)) + else '0'; + ch_st_data_rd(k) <= '1' when ird = '1' and wb_adr_i(6 downto 4) = "001" + and wb_adr_i(3 downto 0) = std_logic_vector(to_unsigned(2*k+1,4)) + else '0'; + end generate CRST; + end generate CR32; + CR16: if DATA_WIDTH = 16 generate + ch_st_cap_rd(7 downto 0) <= (others => '0'); + ch_st_cap_wr(7 downto 0) <= (others => '0'); + ch_st_data_rd(7 downto 0) <= (others => '0'); + end generate CR16; + +end rtl; Index: tags/spdif_rel_1/rtl/vhdl/dpram_altera.vhd =================================================================== --- tags/spdif_rel_1/rtl/vhdl/dpram_altera.vhd (nonexistent) +++ tags/spdif_rel_1/rtl/vhdl/dpram_altera.vhd (revision 64) @@ -0,0 +1,119 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Dual port ram. This version is specific for Altera FPGA's, ---- +---- and uses Altera library to instantiate block ram. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/06/19 09:55:19 gedra +-- Delint'ed and changed name of architecture. +-- +-- Revision 1.1 2004/06/18 18:40:04 gedra +-- Alternate dual port memory implementation for Altera FPGA's. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +library lpm; +use lpm.lpm_components.all; + +entity dpram is + generic (DATA_WIDTH: positive; + RAM_WIDTH: positive); + port ( + clk: in std_logic; + rst: in std_logic; -- reset is optional, not used here + din: in std_logic_vector(DATA_WIDTH - 1 downto 0); + wr_en: in std_logic; + rd_en: in std_logic; + wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0); + dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); +end dpram; + +architecture altera of dpram is + +component lpm_ram_dp + generic ( LPM_WIDTH: positive; + LPM_WIDTHAD: positive; + LPM_NUMWORDS: natural := 0; + LPM_INDATA: string := "REGISTERED"; + LPM_OUTDATA: string := "REGISTERED"; + LPM_RDADDRESS_CONTROL: string := "REGISTERED"; + LPM_WRADDRESS_CONTROL: string := "REGISTERED"; + LPM_FILE: string := "UNUSED"; + LPM_TYPE: string := "LPM_RAM_DP"; + LPM_HINT: string := "UNUSED"); + port ( data: in std_logic_vector(LPM_WIDTH-1 downto 0); + rdaddress, wraddress: in std_logic_vector(LPM_WIDTHAD-1 downto 0); + rdclock, wrclock: in std_logic := '0'; + rden, rdclken, wrclken: in std_logic := '1'; + wren: in std_logic; + q: out std_logic_vector(LPM_WIDTH-1 downto 0)); +end component; + +signal one: std_logic; + +begin + + one <= '1'; + + ram: lpm_ram_dp + generic map(LPM_WIDTH => DATA_WIDTH, + LPM_WIDTHAD => RAM_WIDTH, + LPM_NUMWORDS => 2**RAM_WIDTH) + port map (data => din, + rdaddress => rd_addr, + wraddress => wr_addr, + rdclock => clk, + wrclock => clk, + rden => rd_en, + rdclken => one, + wrclken => one, + wren => wr_en, + q => dout); + +end altera; Index: tags/spdif_rel_1/bench/vhdl/tb_spdif.vhd =================================================================== --- tags/spdif_rel_1/bench/vhdl/tb_spdif.vhd (nonexistent) +++ tags/spdif_rel_1/bench/vhdl/tb_spdif.vhd (revision 64) @@ -0,0 +1,334 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Top-level testbench for both receiver and transmitter. ---- +---- Output from the transmitter is connected to input of recevier---- +---- and checking is done on data transfer and channel status ---- +---- capture. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use work.wb_tb_pack.all; + +entity tb_spdif is + +end tb_spdif; + +architecture behav of tb_spdif is + + component rx_spdif is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64; + CH_ST_CAPTURE: integer range 0 to 8; + WISHBONE_FREQ: natural); + port ( + -- Wishbone interface + wb_clk_i: in std_logic; + wb_rst_i: in std_logic; + wb_sel_i: in std_logic; + wb_stb_i: in std_logic; + wb_we_i: in std_logic; + wb_cyc_i: in std_logic; + wb_bte_i: in std_logic_vector(1 downto 0); + wb_cti_i: in std_logic_vector(2 downto 0); + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); + wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0); + wb_ack_o: out std_logic; + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); + -- Interrupt line + rx_int_o: out std_logic; + -- SPDIF input signal + spdif_rx_i: in std_logic); + end component; + + component tx_spdif + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64; + USER_DATA_BUF: integer range 0 to 1; + CH_STAT_BUF: integer range 0 to 1); + port ( + -- Wishbone interface + wb_clk_i: in std_logic; + wb_rst_i: in std_logic; + wb_sel_i: in std_logic; + wb_stb_i: in std_logic; + wb_we_i: in std_logic; + wb_cyc_i: in std_logic; + wb_bte_i: in std_logic_vector(1 downto 0); + wb_cti_i: in std_logic_vector(2 downto 0); + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); + wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0); + wb_ack_o: out std_logic; + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); + -- Interrupt line + tx_int_o: out std_logic; + -- SPDIF output signal + spdif_tx_o: out std_logic); + end component; + + signal wb_clk_o, wb_rst_o, wb_sel_o, wb_stb_o, wb_we_o : std_logic; + signal wb_cyc_o, wb_ack_i, rx_int_o, spdif_signal : std_logic; + signal tx_int_o, tx_ack, rx_ack : std_logic; + signal wb_bte_o : std_logic_vector(1 downto 0); + signal wb_cti_o : std_logic_vector(2 downto 0); + signal wb_adr_o : std_logic_vector(15 downto 0); + signal wb_dat_i, wb_dat_o, rx_dat_i, tx_dat_i: std_logic_vector(31 downto 0); + signal wb_stb_32bit_rx, wb_stb_32bit_tx : std_logic; + constant RX_VERSION : natural := 16#1000#; + constant RX_CONFIG : natural := 16#1001#; + constant RX_STATUS : natural := 16#1002#; + constant RX_INTMASK : natural := 16#1003#; + constant RX_INTSTAT : natural := 16#1004#; + constant RX_CHSTCAP0: natural := 16#1010#; + constant RX_CHSTDAT0: natural := 16#1011#; + constant RX_CHSTCAP1: natural := 16#1012#; + constant RX_CHSTDAT1: natural := 16#1013#; + constant RX_BUF_BASE: natural := 16#1080#; + constant TX_VERSION : natural := 16#2000#; + constant TX_CONFIG : natural := 16#2001#; + constant TX_CHSTAT : natural := 16#2002#; + constant TX_INTMASK : natural := 16#2003#; + constant TX_INTSTAT : natural := 16#2004#; + constant TX_UD_BASE : natural := 16#2020#; + constant TX_CS_BASE : natural := 16#2040#; + constant TX_BUF_BASE: natural := 16#2080#; + + +begin + + wb_ack_i <= rx_ack or tx_ack; + wb_dat_i <= rx_dat_i or tx_dat_i; + +-- SPDIF recevier in 32bit mode with two capture registers + SRX32: rx_spdif + generic map ( + DATA_WIDTH => 32, + ADDR_WIDTH => 8, -- 128 byte sample buffer + CH_ST_CAPTURE => 2, -- two capture regs. + WISHBONE_FREQ => 33) -- 33 MHz + port map ( + wb_clk_i => wb_clk_o, + wb_rst_i => wb_rst_o, + wb_sel_i => wb_sel_o, + wb_stb_i => wb_stb_32bit_rx, + wb_we_i => wb_we_o, + wb_cyc_i => wb_cyc_o, + wb_bte_i => wb_bte_o, + wb_cti_i => wb_cti_o, + wb_adr_i => wb_adr_o(7 downto 0), + wb_dat_i => wb_dat_o(31 downto 0), + wb_ack_o => rx_ack, + wb_dat_o => rx_dat_i, + rx_int_o => rx_int_o, + spdif_rx_i => spdif_signal); + +-- SPDIF transmitter with all bells and whistles + STX32: tx_spdif + generic map (DATA_WIDTH => 32, + ADDR_WIDTH => 8, + USER_DATA_BUF => 1, + CH_STAT_BUF => 1) + port map ( + -- Wishbone interface + wb_clk_i => wb_clk_o, + wb_rst_i => wb_rst_o, + wb_sel_i => wb_sel_o, + wb_stb_i => wb_stb_32bit_tx, + wb_we_i => wb_we_o, + wb_cyc_i => wb_cyc_o, + wb_bte_i => wb_bte_o, + wb_cti_i => wb_cti_o, + wb_adr_i => wb_adr_o(7 downto 0), + wb_dat_i => wb_dat_o(31 downto 0), + wb_ack_o => tx_ack, + wb_dat_o => tx_dat_i, + tx_int_o => tx_int_o, + spdif_tx_o => spdif_signal); + +-- Main test process + MAIN: process + variable read_32bit : std_logic_vector(31 downto 0); + + -- Make simplified versions of procedures in wb_tb_pack + procedure wb_write_32 ( + constant ADDRESS: in natural; + constant DATA: in natural) is + begin + wb_write(ADDRESS, DATA, wb_adr_o, wb_dat_o(31 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + + procedure wb_check_32 ( + constant ADDRESS: in natural; + constant EXP_DATA : in natural) is + begin + wb_check(ADDRESS, EXP_DATA, wb_adr_o, wb_dat_i(31 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + + procedure wb_read_32 ( + constant ADDRESS: in natural; + variable READ_DATA : out std_logic_vector) is + begin + wb_read(ADDRESS, read_32bit, wb_adr_o, wb_dat_i(31 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + begin + message("Simulation start with system reset."); + wb_rst_o <= '1'; -- system reset + wb_sel_o <= '0'; + wb_stb_o <= '0'; + wb_sel_o <= '0'; + wb_we_o <= '0'; + wb_cyc_o <= '0'; + wb_bte_o <= "00"; + wb_cti_o <= "000"; + wb_adr_o <= (others => '0'); + wb_dat_o <= (others => '0'); + wait for 200 ns; + wb_rst_o <= '0'; + message("Start with checking version register for correct value:"); + wb_check_32(RX_VERSION, 16#00020111#); + message("Check transmitter version register:"); + wb_check_32(TX_VERSION, 16#00003111#); + message("Fill up sample buffer with test signal, ramp up in ch.A, ramp down in ch.B:"); + SGEN: for i in 0 to 63 loop + wb_write_32(TX_BUF_BASE + 2*i, 32768 + i*497); -- channel A + wb_write_32(TX_BUF_BASE + 2*i + 1, 32768 - i*497); -- channel B + end loop; + message("Setup some channel status and user data to be transmitted:"); + wb_write_32(TX_CS_BASE, 16#000000f8#); + wb_write_32(TX_UD_BASE + 5, 16#000000a2#); + message("Enable transmitter:"); + wb_write_32(TX_CONFIG, 16#00000851#); + wait for 4 us; + message("Enable receiver, interrupt on lock:"); + wb_write_32(RX_INTMASK, 16#00000001#); + wb_write_32(RX_CONFIG, 16#00000005#); + wait_for_event("Wait for LOCK interrupt", 120 us, rx_int_o); + message("Check status register:"); + wb_check_32(RX_STATUS, 16#00000001#); + message("Clear LOCK interrupt:"); + wb_write_32(RX_INTSTAT, 16#00000001#); + wb_check_32(RX_INTSTAT, 16#00000000#); + signal_check("rx_int_o", '0', rx_int_o); + message("Enable recevier sample buffer:"); + wb_write_32(RX_CONFIG, 16#00000017#); + wait for 20 us; + message("Enable audio transmission:"); + wb_write_32(TX_CONFIG, 16#00000853#); + message("Enable receiver LSBF/HSBF interrupts:"); + wb_write_32(RX_INTMASK, 16#00000006#); + wait_for_event("Wait for recevier LSBF interrupt", 1.8 ms, rx_int_o); + message("Clear LSBF interrupt:"); + wb_write_32(RX_INTSTAT, 16#00000002#); + wb_check_32(RX_INTSTAT, 16#00000000#); + signal_check("rx_int_o", '0', rx_int_o); + message("Check receiver buffer for correct sample data:"); + SCHK: for i in 0 to 31 loop + wb_check_32(RX_BUF_BASE + 2*i, 32768 + i*497); -- channel A + wb_check_32(RX_BUF_BASE + 2*i + 1, 32768 - i*497); -- channel B + end loop; + wait_for_event("Wait for recevier HSBF interrupt", 1.8 ms, rx_int_o); + message("Clear HSBF interrupt:"); + wb_write_32(RX_INTSTAT, 16#00000004#); + wb_check_32(RX_INTSTAT, 16#00000000#); + signal_check("rx_int_o", '0', rx_int_o); + message("Check receiver buffer for correct sample data:"); + SCHK2: for i in 32 to 63 loop + wb_check_32(RX_BUF_BASE + 2*i, 32768 + i*497); -- channel A + wb_check_32(RX_BUF_BASE + 2*i + 1, 32768 - i*497); -- channel B + end loop; + message("Setup receiver capture register for channel status capture:"); + wb_write_32(RX_CHSTCAP0, 16#00000286#); -- 6 bits from bit 2 + wb_check_32(RX_CHSTCAP0, 16#00000286#); + message("Setup receiver capture register for user data capture:"); + wb_write_32(RX_CHSTCAP1, 16#00002808#); -- 8 bits from bit 40 + message("Enable capture interrupts:"); + wb_write_32(RX_INTMASK, 16#00030000#); + wait_for_event("Wait for receiver CAP0 interrupt", 6 ms, rx_int_o); + message("Check captured bits and clear interrupt:"); + wb_check_32(RX_CHSTDAT0, 16#0000003e#); + wb_write_32(RX_INTSTAT, 16#00010006#); + wb_check_32(RX_INTSTAT, 16#00000000#); + signal_check("rx_int_o", '0', rx_int_o); + wait_for_event("Wait for receiver CAP1 interrupt", 4 ms, rx_int_o); + message("Check captured bits and clear interrupt:"); + wb_check_32(RX_CHSTDAT1, 16#000000a2#); + wb_write_32(RX_INTSTAT, 16#00020006#); + wb_check_32(RX_INTSTAT, 16#00000000#); + signal_check("rx_int_o", '0', rx_int_o); + message("Check that transmitter buffer events were generated:"); + wb_check_32(TX_INTSTAT, 16#0000001e#); + wb_write_32(TX_INTSTAT, 16#0000001e#); + wb_check_32(TX_INTSTAT, 16#00000000#); + + sim_report(""); + report "End of simulation! (ignore this failure)" + severity failure; + wait; + end process MAIN; + +-- Bus strobe generator based on address. 32bit recevier mapped to addr. 0x1000 +-- 32bit transmitter mapped to address 0x2000 + wb_stb_32bit_rx <= '1' when wb_adr_o(15 downto 12) = "0001" else '0'; + wb_stb_32bit_tx <= '1' when wb_adr_o(15 downto 12) = "0010" else '0'; + +-- Clock process, 33Mhz Wishbone master freq. + CLKGEN: process + begin + wb_clk_o <= '0'; + wait for 15.15 ns; + wb_clk_o <= '1'; + wait for 15.15 ns; + end process CLKGEN; + +end behav; + + + Index: tags/spdif_rel_1/bench/vhdl/wb_tb_pack.vhd =================================================================== --- tags/spdif_rel_1/bench/vhdl/wb_tb_pack.vhd (nonexistent) +++ tags/spdif_rel_1/bench/vhdl/wb_tb_pack.vhd (revision 64) @@ -0,0 +1,493 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Wishbone testbench funtions. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.5 2004/07/15 17:43:53 gedra +-- Added string type casting to make ModelSim happy. +-- +-- Revision 1.4 2004/07/12 17:06:08 gedra +-- Test bench update. +-- +-- Revision 1.3 2004/07/11 16:20:16 gedra +-- Improved test bench. +-- +-- Revision 1.2 2004/06/26 14:11:39 gedra +-- Converter to numeric_std and added hex functions +-- +-- Revision 1.1 2004/06/24 19:26:02 gedra +-- Wishbone bus utilities. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use std.textio.all; + +package wb_tb_pack is + + constant WRITE_TIMEOUT : integer := 20; -- Max cycles to wait during write + constant READ_TIMEOUT : integer := 20; -- Max cycles to wait during read + constant TIME_WIDTH : integer := 15; -- Number of chars for time field + + shared variable errors : integer := 0; -- error counter during simulation + shared variable rd_tout : integer; -- read timeout flag used by check() + shared variable no_print : integer := 0; -- no print during check() + + function int_2_hex (value: natural; width: natural) return string; + function slv_2_hex (value: std_logic_vector) return string; + + procedure wb_write ( + constant ADDRESS: in natural; + constant DATA: in natural; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_o: out std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic); + + procedure wb_read ( + constant ADDRESS: in natural; + variable read_data: out std_logic_vector; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_i: in std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic); + + procedure wb_check ( + constant ADDRESS: in natural; + constant EXP_DATA : in natural; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_i: in std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic); + + procedure message ( + constant MSG: in string); -- message to be printed + + procedure wait_for_event ( + constant MSG : in string; -- message + constant TIMEOUT: in time; -- timeout + signal trigger: in std_logic); -- trigger expression + + procedure signal_check ( + constant MSG : in string; -- signal name + constant VALUE: in std_logic; -- expected value + signal sig: in std_logic); -- signal to check + + procedure sim_report ( + constant MSG : in string); + +end wb_tb_pack; + +package body wb_tb_pack is + +-- convert natural to hex format. Number of digits must be specified + function int_2_hex (value: natural; width: natural) return string is + variable tmp: string(1 to width + 2); + variable digit: integer range 0 to 15; + variable invalue: integer; + variable pos: integer; + begin + tmp(1 to 2) := "0x"; + invalue := value; + FL: for i in 1 to width loop + digit := invalue mod 16; + invalue := invalue / 16; + pos := 3 + width - i; + case digit is + when 0 => tmp(pos) := '0'; + when 1 => tmp(pos) := '1'; + when 2 => tmp(pos) := '2'; + when 3 => tmp(pos) := '3'; + when 4 => tmp(pos) := '4'; + when 5 => tmp(pos) := '5'; + when 6 => tmp(pos) := '6'; + when 7 => tmp(pos) := '7'; + when 8 => tmp(pos) := '8'; + when 9 => tmp(pos) := '9'; + when 10 => tmp(pos) := 'a'; + when 11 => tmp(pos) := 'b'; + when 12 => tmp(pos) := 'c'; + when 13 => tmp(pos) := 'd'; + when 14 => tmp(pos) := 'e'; + when 15 => tmp(pos) := 'f'; + when others => tmp(pos) := '?'; + end case; + end loop FL; + return(tmp); + end int_2_hex; + + -- Convert std_logic_vector to hex format. + function slv_2_hex (value: std_logic_vector) return string is + variable tmp: string(1 to value'length + 2); + variable subdigit: std_logic_vector(3 downto 0); + variable digits, pos: integer; + variable actual_length: integer; + variable ext_val: std_logic_vector(value'length + 3 downto 0); + begin + tmp(1 to 2) := "0x"; + ext_val(value'length - 1 downto 0) := value; + ext_val(value'length + 3 downto value'length) := (others => '0'); + -- pad with zero's if length is not a factor of 4 + if value'length mod 4 /= 0 then + actual_length := value'length + 4 - (value'length mod 4); + else + actual_length := value'length; + end if; + digits := actual_length / 4; + -- convert 4 and 4 bits into hex digits + F1: for i in digits downto 1 loop + subdigit(3 downto 0) := ext_val(i * 4 - 1 downto i * 4 - 4); + pos := 3 + digits - i; + case subdigit is + when "0000" => tmp(pos) := '0'; + when "0001" => tmp(pos) := '1'; + when "0010" => tmp(pos) := '2'; + when "0011" => tmp(pos) := '3'; + when "0100" => tmp(pos) := '4'; + when "0101" => tmp(pos) := '5'; + when "0110" => tmp(pos) := '6'; + when "0111" => tmp(pos) := '7'; + when "1000" => tmp(pos) := '8'; + when "1001" => tmp(pos) := '9'; + when "1010" => tmp(pos) := 'a'; + when "1011" => tmp(pos) := 'b'; + when "1100" => tmp(pos) := 'c'; + when "1101" => tmp(pos) := 'd'; + when "1110" => tmp(pos) := 'e'; + when "1111" => tmp(pos) := 'f'; + when others => tmp(pos) := '?'; + end case; + end loop F1; + return(tmp(1 to 2 + digits)); + end slv_2_hex; + +-- Classic Wishbone write cycle + procedure wb_write ( + constant ADDRESS: in natural; + constant DATA: in natural; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_o: out std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic) is + variable txt : line; + variable adr_width, dat_width : natural; + constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); + constant LOW_BUS: std_logic_vector(wb_dat_o'range) := (others => 'L'); + begin + -- determine best width for number printout + if wb_adr_o'length < 9 then + adr_width := 2; + elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then + adr_width := 4; + else + adr_width := 6; + end if; + if wb_dat_o'length < 9 then + dat_width := 2; + elsif wb_dat_o'length < 17 and wb_dat_o'length > 8 then + dat_width := 4; + else + dat_width := 8; + end if; + -- start cycle on positive edge + wait until rising_edge(wb_clk_i); + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + write(txt, string'(" Wrote ")); + write(txt, int_2_hex(DATA, dat_width)); + write(txt, string'(" to addr. ")); + write(txt, int_2_hex(ADDRESS, adr_width)); + wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); + wb_dat_o <= std_logic_vector(to_unsigned(DATA, wb_dat_o'length)); + wb_we_o <= '1'; + wb_cyc_o <= '1'; + wb_sel_o <= '1'; + -- wait for acknowledge + wait until rising_edge(wb_clk_i); + if wb_ack_i /= '1' then + for i in 1 to WRITE_TIMEOUT loop + wait until rising_edge(wb_clk_i); + exit when wb_ack_i = '1'; + if (i = WRITE_TIMEOUT) then + --write(txt, string'("- @ ")); + --write(txt, now, right, DEFAULT_TIMEWIDTH, DEFAULT_TIMEBASE); + write (txt, string'("Warning: No acknowledge recevied!")); + end if; + end loop; + end if; + -- release bus + wb_adr_o <= WEAK_BUS; + wb_dat_o <= LOW_BUS; + wb_we_o <= 'L'; + wb_cyc_o <= 'L'; + wb_sel_o <= 'L'; + writeline(OUTPUT, txt); + end; + +-- Classic Wishbone read cycle + procedure wb_read ( + constant ADDRESS: in natural; + variable read_data : out std_logic_vector; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_i: in std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic) is + variable txt : line; + variable adr_width, dat_width : natural; + constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); + begin + -- determine best width for number printout + if wb_adr_o'length < 9 then + adr_width := 2; + elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then + adr_width := 4; + else + adr_width := 6; + end if; + if wb_dat_i'length < 9 then + dat_width := 2; + elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then + dat_width := 4; + else + dat_width := 8; + end if; + -- start cycle on positive edge + wait until rising_edge(wb_clk_i); + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); + wb_we_o <= '0'; + wb_cyc_o <= '1'; + wb_sel_o <= '1'; + -- wait for acknowledge + wait until rising_edge(wb_clk_i); + rd_tout := 0; + if wb_ack_i /= '1' then + for i in 1 to READ_TIMEOUT loop + wait until rising_edge(wb_clk_i); + exit when wb_ack_i = '1'; + if (i = READ_TIMEOUT) then + write (txt, string'("Warning: WB_read timeout!")); + if no_print = 0 then + writeline(OUTPUT, txt); + end if; + rd_tout := 1; + errors := errors + 1; + end if; + end loop; + end if; + read_data := wb_dat_i; + if rd_tout = 0 then + write(txt, string'(" Read ")); + write(txt, slv_2_hex(wb_dat_i)); + write(txt, string'(" from addr. ")); + write(txt, int_2_hex(ADDRESS, adr_width)); + if no_print = 0 then + writeline(OUTPUT, txt); + end if; + end if; + -- release bus + wb_adr_o <= WEAK_BUS; + wb_we_o <= 'L'; + wb_cyc_o <= 'L'; + wb_sel_o <= 'L'; + end; + +-- Check: A read operation followed by a data compare + procedure wb_check ( + constant ADDRESS: in natural; + constant EXP_DATA : in natural; + signal wb_adr_o: out std_logic_vector; + signal wb_dat_i: in std_logic_vector; + signal wb_cyc_o: out std_logic; + signal wb_sel_o: out std_logic; + signal wb_we_o: out std_logic; + signal wb_clk_i: in std_logic; + signal wb_ack_i: in std_logic) is + variable txt : line; + variable tout : integer; + variable adr_width, dat_width : natural; + constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); + variable read_data : std_logic_vector(wb_dat_i'left downto 0); + begin + no_print := 1; -- stop read() from printing message + wb_read (ADDRESS, read_data, wb_adr_o, wb_dat_i, wb_cyc_o, wb_sel_o, + wb_we_o, wb_clk_i, wb_ack_i); + no_print := 0; + -- determine best width for number printout + if wb_adr_o'length < 9 then + adr_width := 2; + elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then + adr_width := 4; + else + adr_width := 6; + end if; + if wb_dat_i'length < 9 then + dat_width := 2; + elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then + dat_width := 4; + else + dat_width := 8; + end if; + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + + if rd_tout = 0 then + if read_data = std_logic_vector(to_unsigned(EXP_DATA, wb_dat_i'length)) then + write(txt, string'(" Check ")); + write(txt, slv_2_hex(wb_dat_i)); + write(txt, string'(" at addr. ")); + write(txt, int_2_hex(ADDRESS, adr_width)); + write(txt, string'(" - OK!")); + else + write(txt, string'(" Check failed at addr. ")); + write(txt, int_2_hex(ADDRESS, adr_width)); + write(txt, string'("! Got ")); + write(txt, slv_2_hex(wb_dat_i)); + write(txt, string'(", expected ")); + write(txt, int_2_hex(EXP_DATA, dat_width)); + errors := errors + 1; + end if; + writeline(OUTPUT, txt); + else + write(txt, string'(" Read timeout from addr. ")); + write(txt, int_2_hex(ADDRESS, adr_width)); + write(txt, string'(" during check!")); + writeline(OUTPUT, txt); + end if; + end; + +-- display a message with time stamp + procedure message ( + constant MSG: in string) is + variable txt : line; + begin + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + write(txt, string'(" -- ") & MSG); + writeline(OUTPUT, txt); + end; + +-- wait for event to happen, with timeout + procedure wait_for_event ( + constant MSG : in string; -- message + constant TIMEOUT: in time; -- timeout + signal trigger: in std_logic) is -- trigger signal + variable txt : line; + variable t1 : time; + begin + t1 := now; + wait on trigger for timeout; + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + write(txt, string'(" ")); + write(txt, MSG); + if now - t1 >= TIMEOUT then + write(txt, string'(" - Timed out!")); + errors := errors + 1; + else + write(txt, string'(" - OK!")); + end if; + writeline(OUTPUT, txt); + end; + +-- check signal value + procedure signal_check ( + constant MSG : in string; -- signal name + constant VALUE: in std_logic; -- expected value + signal sig: in std_logic) is -- signal to check + variable txt : line; + begin + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + write(txt, string'(" ")); + write(txt, MSG); + write(txt, string'(" ")); + if sig = VALUE then + write(txt, string'("verified to be ")); + else + write(txt, string'("has incorrect value! Expected ")); + errors := errors + 1; + end if; + if VALUE = '1' then + write(txt, string'("1!")); + else + write(txt, string'("0!")); + end if; + writeline(OUTPUT, txt); + end; + +-- Report number of errors encountered during simulation + procedure sim_report ( + constant MSG : in string) is + variable txt : line; + begin + write(txt, string'("@")); + write(txt, now, right, TIME_WIDTH); + write(txt, string'(" Simulation completed with ")); + write(txt, errors); + write(txt, string'(" errors!")); + writeline(OUTPUT, txt); + end; + +end wb_tb_pack; + Index: tags/spdif_rel_1/bench/vhdl/tb_rx_spdif.vhd =================================================================== --- tags/spdif_rel_1/bench/vhdl/tb_rx_spdif.vhd (nonexistent) +++ tags/spdif_rel_1/bench/vhdl/tb_rx_spdif.vhd (revision 64) @@ -0,0 +1,242 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Test bench for SPDIF recevier. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/07/11 16:20:16 gedra +-- Improved test bench. +-- +-- Revision 1.1 2004/06/26 14:12:51 gedra +-- Top level test bench for receiver. NB! Not complete. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use work.wb_tb_pack.all; + + +entity tb_rx_spdif is + +end tb_rx_spdif; + +architecture behav of tb_rx_spdif is + + component rx_spdif is + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64; + CH_ST_CAPTURE: integer range 0 to 8; + WISHBONE_FREQ: natural); + port ( + -- Wishbone interface + wb_clk_i: in std_logic; + wb_rst_i: in std_logic; + wb_sel_i: in std_logic; + wb_stb_i: in std_logic; + wb_we_i: in std_logic; + wb_cyc_i: in std_logic; + wb_bte_i: in std_logic_vector(1 downto 0); + wb_cti_i: in std_logic_vector(2 downto 0); + wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); + wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0); + wb_ack_o: out std_logic; + wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); + -- Interrupt line + rx_int_o: out std_logic; + -- SPDIF input signal + spdif_rx_i: in std_logic); + end component; + + component gen_spdif + generic (Freq: natural); -- Sampling frequency in Hz + port ( -- Bitrate is 64x sampling frequency + reset: in std_logic; + spdif: out std_logic); -- Output bi-phase encoded signal + end component; + + signal wb_clk_o, wb_rst_o, wb_sel_o, wb_stb_o, wb_we_o : std_logic; + signal wb_cyc_o, wb_ack_i, rx_int_o, spdif_rx_i : std_logic; + signal wb_bte_o : std_logic_vector(1 downto 0); + signal wb_cti_o : std_logic_vector(2 downto 0); + signal wb_adr_o : std_logic_vector(15 downto 0); + signal wb_dat_i, wb_dat_o : std_logic_vector(31 downto 0); + signal wb_stb_16bit_rx : std_logic; + constant RX_VERSION : natural := 16#1000#; + constant RX_CONFIG : natural := 16#1001#; + constant RX_STATUS : natural := 16#1002#; + constant RX_INTMASK : natural := 16#1003#; + constant RX_INTSTAT : natural := 16#1004#; + +begin + +-- Minimal SPDIF recevier in 16bit mode + SRX16: rx_spdif + generic map ( + DATA_WIDTH => 16, + ADDR_WIDTH => 8, -- 128 byte sample buffer + CH_ST_CAPTURE => 0, -- no capture in 16bit mode + WISHBONE_FREQ => 33) -- 33 MHz + port map ( + wb_clk_i => wb_clk_o, + wb_rst_i => wb_rst_o, + wb_sel_i => wb_sel_o, + wb_stb_i => wb_stb_16bit_rx, + wb_we_i => wb_we_o, + wb_cyc_i => wb_cyc_o, + wb_bte_i => wb_bte_o, + wb_cti_i => wb_cti_o, + wb_adr_i => wb_adr_o(7 downto 0), + wb_dat_i => wb_dat_o(15 downto 0), + wb_ack_o => wb_ack_i, + wb_dat_o => wb_dat_i(15 downto 0), + rx_int_o => rx_int_o, + spdif_rx_i => spdif_rx_i); + +-- SPDIF 44.1kHz source + SP44: gen_spdif + generic map (FREQ => 44100) + port map (reset => wb_rst_o, + spdif => spdif_rx_i); + +-- Main test process + MAIN: process + variable read_16bit : std_logic_vector(15 downto 0); + + -- Make simplified versions of procedures in wb_tb_pack + procedure wb_write_16 ( + constant ADDRESS: in natural; + constant DATA: in natural) is + begin + wb_write(ADDRESS, DATA, wb_adr_o, wb_dat_o(15 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + + procedure wb_check_16 ( + constant ADDRESS: in natural; + constant EXP_DATA : in natural) is + begin + wb_check(ADDRESS, EXP_DATA, wb_adr_o, wb_dat_i(15 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + + procedure wb_read_16 ( + constant ADDRESS: in natural; + variable READ_DATA : out std_logic_vector) is + begin + wb_read(ADDRESS, read_16bit, wb_adr_o, wb_dat_i(15 downto 0), wb_cyc_o, + wb_sel_o, wb_we_o, wb_clk_o, wb_ack_i); + end; + begin + message("Simulation start with system reset."); + wb_rst_o <= '1'; -- system reset + wb_sel_o <= '0'; + wb_stb_o <= '0'; + wb_sel_o <= '0'; + wb_we_o <= '0'; + wb_cyc_o <= '0'; + wb_bte_o <= "00"; + wb_cti_o <= "000"; + wb_adr_o <= (others => '0'); + wb_dat_o <= (others => '0'); + wait for 200 ns; + wb_rst_o <= '0'; + message("Start with checking version register for correct value:"); + wb_check_16(RX_VERSION, 16#0101#); + message("Enable interrupt on lock:"); + wb_write_16(RX_INTMASK, 16#0001#); + message("Enable receiver:"); + wb_write_16(RX_CONFIG, 16#0005#); + wb_read_16(RX_CONFIG, read_16bit); + wait_for_event("Wait for LOCK interrupt", 60 us, rx_int_o); + message("Check status register:"); + wb_check_16(RX_STATUS, 16#0001#); + message("Clear interrupt:"); + wb_write_16(RX_INTSTAT, 16#0001#); + wb_check_16(RX_INTSTAT, 16#0000#); + signal_check("rx_int_o", '0', rx_int_o); + message("Enable sample buffer"); + wb_write_16(RX_CONFIG, 16#0007#); + message("Enable sample buffer interrupts"); + wb_write_16(RX_INTMASK, 16#0007#); + wait_for_event("Wait for LSBF interrupt", 750 us, rx_int_o); + message("Check LSBF interrupt, and read some data"); + wb_check_16(RX_INTSTAT, 16#0002#); + wb_write_16(RX_INTSTAT, 16#0002#); + wb_check_16(RX_INTSTAT, 16#0000#); + signal_check("rx_int_o", '0', rx_int_o); + wb_read_16(16#1080#, read_16bit); + wb_read_16(16#1081#, read_16bit); + wb_read_16(16#1082#, read_16bit); + wb_read_16(16#1083#, read_16bit); + wait_for_event("Wait for HSBF interrupt", 750 us, rx_int_o); + message("Check HSBF interrupt, and read some data"); + wb_check_16(RX_INTSTAT, 16#0004#); + wb_write_16(RX_INTSTAT, 16#0004#); + wb_check_16(RX_INTSTAT, 16#0000#); + signal_check("rx_int_o", '0', rx_int_o); + + + report "End of simulation! (ignore this failure)" + severity failure; + wait; + + end process MAIN; + +-- Bus strobe generator based on address. 16bit recevier mapped to addr. 0x1000 + wb_stb_16bit_rx <= '1' when wb_adr_o(15 downto 12) = "0001" else '0'; + +-- Clock process, 33Mhz Wishbone master freq. + CLKGEN: process + begin + wb_clk_o <= '0'; + wait for 15.15 ns; + wb_clk_o <= '1'; + wait for 15.15 ns; + end process CLKGEN; + +end behav; + + + Index: tags/spdif_rel_1/bench/vhdl/tb_gen_spdif.vhd =================================================================== --- tags/spdif_rel_1/bench/vhdl/tb_gen_spdif.vhd (nonexistent) +++ tags/spdif_rel_1/bench/vhdl/tb_gen_spdif.vhd (revision 64) @@ -0,0 +1,216 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- A very simple testbench to debug the receiver phase detector ---- +---- and bi-phase decoder. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.3 2004/06/16 19:02:28 gedra +-- Added frame decoder +-- +-- Revision 1.2 2004/06/13 18:10:20 gedra +-- Renamed generic +-- +-- Revision 1.1 2004/06/06 15:44:19 gedra +-- Simple test bench for rx_phase_det.vhd. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +entity tb_gen_spdif is + +end tb_gen_spdif; + +architecture behav of tb_gen_spdif is + + component spdif_source + generic (FREQ: natural); -- Sampling frequency in Hz + port ( -- Bitrate is 64x sampling frequency + reset: in std_logic; + spdif: out std_logic); -- Output bi-phase encoded signal + end component; + + component rx_phase_det + generic (WISHBONE_FREQ: natural); -- WishBone frequency in MHz + port ( + wb_clk_i: in std_logic; + rxen: in std_logic; + spdif: in std_logic; + lock: out std_logic; + rx_data: out std_logic; + rx_data_en: out std_logic; + rx_block_start: out std_logic; + rx_frame_start: out std_logic; + rx_channel_a: out std_logic; + rx_error: out std_logic; + ud_a_en: out std_logic; -- user data ch. A enable + ud_b_en: out std_logic; -- user data ch. B enable + cs_a_en: out std_logic; -- channel status ch. A enable + cs_b_en: out std_logic); -- channel status ch. B enable); + end component; + + component rx_decode + generic (DATA_WIDTH: integer range 16 to 32; + ADDR_WIDTH: integer range 8 to 64); + port ( + wb_clk_i: in std_logic; + conf_rxen: in std_logic; + conf_sample: in std_logic; + conf_valid: in std_logic; + conf_mode: in std_logic_vector(3 downto 0); + conf_blken: in std_logic; + conf_valen: in std_logic; + conf_useren: in std_logic; + conf_staten: in std_logic; + conf_paren: in std_logic; + lock: in std_logic; + rx_data: in std_logic; + rx_data_en: in std_logic; + rx_block_start: in std_logic; + rx_frame_start: in std_logic; + rx_channel_a: in std_logic; + wr_en: out std_logic; + wr_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); + wr_data: out std_logic_vector(DATA_WIDTH - 1 downto 0); + stat_paritya: out std_logic; + stat_parityb: out std_logic; + stat_lsbf: out std_logic; + stat_hsbf: out std_logic); + end component; + + signal reset, spdif, rx_frame_start: std_logic; + signal lock, rx_data, rx_data_en, rx_block_start : std_logic; + signal rx_channel_a, wb_clk_i, rxen, rx_error : std_logic; + signal ud_a_en, ud_b_en, cs_a_en, cs_b_en, zero, one : std_logic; + signal stat_paritya, stat_parityb, stat_lsbf, stat_hsbf : std_logic; + signal wr_en : std_logic; + signal wr_addr: std_logic_vector(6 downto 0); + signal wr_data: std_logic_vector(31 downto 0); + +begin + + zero <= '0'; + one <= '1'; + + -- Soruce generating SPDIF signal used to train the decoder + GS: spdif_source + generic map ( + FREQ => 41000) + port map ( + reset => reset, + spdif => spdif); + + -- SPDIF phase detector and decoder + PD: rx_phase_det + generic map ( + WISHBONE_FREQ => 33) + port map ( + wb_clk_i => wb_clk_i, + rxen => rxen, + spdif => spdif, + lock => lock, + rx_data => rx_data, + rx_data_en => rx_data_en, + rx_block_start => rx_block_start, + rx_frame_start => rx_frame_start, + rx_channel_a => rx_channel_a, + rx_error => rx_error, + ud_a_en => ud_a_en, + ud_b_en => ud_b_en, + cs_a_en => cs_a_en, + cs_b_en => cs_b_en); + + -- frame decoder + FD: rx_decode + generic map ( + DATA_WIDTH => 32, + ADDR_WIDTH => 8) + port map ( + wb_clk_i => wb_clk_i, + conf_rxen => rxen, + conf_sample => rxen, + conf_valid => zero, + conf_mode => "0000", + conf_blken => one, + conf_valen => zero, + conf_useren => zero, + conf_staten => zero, + conf_paren => one, + lock => lock, + rx_data => rx_data, + rx_data_en => rx_data_en, + rx_block_start => rx_block_start, + rx_frame_start => rx_frame_start, + rx_channel_a => rx_channel_a, + wr_en => wr_en, + wr_addr => wr_addr, + wr_data => wr_data, + stat_paritya => stat_paritya, + stat_parityb => stat_parityb, + stat_lsbf => stat_lsbf, + stat_hsbf => stat_hsbf); + + rxen <= not reset; + + -- just generate a reset signal, the rest is waveform studies... + process + begin + reset <= '1'; + wait for 200 ns; + reset <= '0'; + wait for 200 ms; + end process; + + -- assuming a 33MHz Wishbone bus clock + process + begin + wb_clk_i <= '1'; + wait for 15.15 ns; + wb_clk_i <= '0'; + wait for 15.15 ns; + end process; + +end behav; + Index: tags/spdif_rel_1/bench/vhdl/spdif_source.vhd =================================================================== --- tags/spdif_rel_1/bench/vhdl/spdif_source.vhd (nonexistent) +++ tags/spdif_rel_1/bench/vhdl/spdif_source.vhd (revision 64) @@ -0,0 +1,215 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- Generates a SPDIF signal with given sampling rate. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/06/06 15:45:24 gedra +-- Cleaned up lint warnings. +-- +-- Revision 1.1 2004/06/03 17:45:18 gedra +-- SPDIF signal generator. +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +entity spdif_source is + generic (FREQ: natural); -- Sampling frequency in Hz + port ( -- Bitrate is 64x sampling frequency + reset: in std_logic; + spdif: out std_logic); -- Output bi-phase encoded signal +end spdif_source; + +architecture behav of spdif_source is + + constant X_Preamble : std_logic_vector(7 downto 0) := "11100010"; + constant Y_Preamble : std_logic_vector(7 downto 0) := "11100100"; + constant Z_Preamble : std_logic_vector(7 downto 0) := "11101000"; + signal clk, ispdif: std_logic; + signal fcnt : natural range 0 to 191; -- frame counter + signal bcnt : natural range 0 to 63; -- subframe bit counter + signal pcnt : natural range 0 to 63; -- parity counter + signal toggle : integer range 0 to 1; + -- Channel A: sinewave with frequency=Freq/12 + type sine16 is array (0 to 15) of std_logic_vector(15 downto 0); + signal channel_a : sine16 := ((x"8000"),(x"b0fb"),(x"da82"),(x"f641"), + (x"ffff"), (x"f641"), (x"da82"), (x"b0fb"), + (x"8000"), (x"4f04"), (x"257d"), (x"09be"), + (x"0000"), (x"09be"), (x"257d"), (x"4f04")); + -- channel B: sinewave with frequency=Freq/24 + type sine8 is array (0 to 7) of std_logic_vector(15 downto 0); + signal channel_b : sine8 := ((x"8000"), (x"da82"), (x"ffff"), (x"da82"), + (x"8000"), (x"257d"), (x"0000"), (x"257d")); + signal channel_status: std_logic_vector(0 to 191); + +begin + + spdif <= ispdif; + channel_status <= (others => '0'); + +-- Generate SPDIF signal + SGEN: process (clk, reset) + begin + if reset = '1' then + fcnt <= 184; -- start just before block to shorten simulation + bcnt <= 0; + toggle <= 0; + ispdif <= '0'; + pcnt <= 0; + elsif rising_edge(clk) then + if toggle = 1 then + -- frame counter: 0 to 191 + if fcnt < 191 then + if bcnt = 63 then + fcnt <= fcnt + 1; + end if; + else + fcnt <= 0; + end if; + -- subframe bit counter: 0 to 63 + if bcnt < 63 then + bcnt <= bcnt + 1; + else + bcnt <= 0; + end if; + end if; + if toggle = 0 then + toggle <= 1; + else + toggle <= 0; + end if; + -- subframe generation + if fcnt = 0 and bcnt < 4 then + ispdif <= Z_Preamble(7 - 2* bcnt - toggle); + elsif fcnt > 0 and bcnt < 4 then + ispdif <= X_Preamble(7 - 2 * bcnt - toggle); + elsif bcnt > 31 and bcnt < 36 then + ispdif <= Y_Preamble(71 - 2 * bcnt - toggle); + end if; + -- aux data, and 4 LSB are zero + if (bcnt > 3 and bcnt < 12) or (bcnt > 35 and bcnt < 44) then + if toggle = 0 then + ispdif <= not ispdif; + end if; + end if; + -- chanmel A data + if (bcnt > 11) and (bcnt < 28) then + if channel_a(fcnt mod 16)(bcnt - 12) = '0' then + if toggle = 0 then + ispdif <= not ispdif; + end if; + else + ispdif <= not ispdif; + if toggle = 0 then + pcnt <= pcnt + 1; + end if; + end if; + end if; + -- channel B data + if (bcnt > 43) and (bcnt < 60) then + if channel_b(fcnt mod 8)(bcnt - 44) = '0' then + if toggle = 0 then + ispdif <= not ispdif; + end if; + else + ispdif <= not ispdif; + if toggle = 0 then + pcnt <= pcnt + 1; + end if; + end if; + end if; + -- validity bit always 0 + if bcnt = 28 or bcnt = 60 then + if toggle = 0 then + ispdif <= not ispdif; + end if; + end if; + -- user data always 0 + if bcnt = 29 or bcnt = 61 then + if toggle = 0 then + ispdif <= not ispdif; + end if; + end if; + -- channel status bit + if bcnt = 30 or bcnt = 62 then + if channel_status(fcnt) = '0' then + if toggle = 0 then + ispdif <= not ispdif; + end if; + else + ispdif <= not ispdif; + if toggle = 0 then + pcnt <= pcnt + 1; + end if; + end if; + end if; + -- parity bit, even parity + if bcnt = 0 or bcnt = 32 then + pcnt <= 0; + end if; + if bcnt = 31 or bcnt = 63 then + if (pcnt mod 2) = 1 then + ispdif <= not ispdif; + else + if toggle = 0 then + ispdif <= not ispdif; + end if; + end if; + end if; + end if; + end process SGEN; + +-- Clock process, generate a clock based on the desired sampling frequency + CLKG: process + variable t1: time := 1.0e12/real(FREQ*256) * 1 ps; + begin + clk <= '0'; + wait for t1; + clk <= '1'; + wait for t1; + end process CLKG; + +end behav;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.