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;