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

Subversion Repositories spdif_interface

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 42 to Rev 43
    Reverse comparison

Rev 42 → Rev 43

/tags/rx_beta_1/rtl/vhdl/rx_package.vhd
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;
/tags/rx_beta_1/rtl/vhdl/rx_phase_det.vhd
0,0 → 1,380
----------------------------------------------------------------------
---- ----
---- 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.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 <= 0;
last_cnt <= 0;
trans <= '0';
valid <= '0';
preamble <= (ZERO, ZERO, ZERO, ZERO);
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
mp_cnt <= 0;
trans <= '1';
last_cnt <= mp_cnt;
if mp_cnt > maxp then
maxp <= mp_cnt;
end if;
if mp_cnt < minp then
minp <= mp_cnt;
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';
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;
/tags/rx_beta_1/rtl/vhdl/gen_event_reg.vhd
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;
/tags/rx_beta_1/rtl/vhdl/rx_spdif.vhd
0,0 → 1,377
----------------------------------------------------------------------
---- ----
---- 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.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 := 16;
ADDR_WIDTH: integer range 8 to 64 := 8;
CH_ST_CAPTURE: integer range 0 to 8 := 0;
WISHBONE_FREQ: natural:= 33);
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 : std_logic;
signal istat_lock, 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 : 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) 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,
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);
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(32 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 - 1 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 => wb_adr_i(ADDR_WIDTH - 2 downto 0),
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;
 
/tags/rx_beta_1/rtl/vhdl/rx_status_reg.vhd
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;
/tags/rx_beta_1/rtl/vhdl/rx_decode.vhd
0,0 → 1,252
----------------------------------------------------------------------
---- ----
---- 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.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';
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;
/tags/rx_beta_1/rtl/vhdl/rx_cap_reg.vhd
0,0 → 1,184
----------------------------------------------------------------------
---- ----
---- 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.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);
bitlen <= to_integer(unsigned(cap_ctrl_bits(5 downto 0)));
chid <= cap_ctrl_bits(6);
cdata <= cap_ctrl_bits(7);
bitpos <= to_integer(unsigned(cap_ctrl_bits(15 downto 8)));
-- 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';
else
if rising_edge(clk) then
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(0) <= ch_data;
cap_new(31 downto 1) <= cap_new(30 downto 0);
cap_len <= cap_len + 1;
end if;
when "0010" => -- user data channel B
if cdata = '0' and chid = '1' then
cap_new(0) <= ch_data;
cap_new(31 downto 1) <= cap_new(30 downto 0);
cap_len <= cap_len + 1;
end if;
when "0100" => -- channel status ch. A
if cdata = '1' and chid = '0' then
cap_new(0) <= ch_data;
cap_new(31 downto 1) <= cap_new(30 downto 0);
cap_len <= cap_len + 1;
end if;
when "1000" => -- channel status ch. B
if cdata = '1' and chid = '1' then
cap_new(0) <= ch_data;
cap_new(31 downto 1) <= cap_new(30 downto 0);
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;
/tags/rx_beta_1/rtl/vhdl/rx_ver_reg.vhd
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;
/tags/rx_beta_1/rtl/vhdl/dpram_rtl.vhd
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;
 
/tags/rx_beta_1/rtl/vhdl/gen_control_reg.vhd
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;
/tags/rx_beta_1/rtl/vhdl/rx_wb_decoder.vhd
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;
/tags/rx_beta_1/rtl/vhdl/dpram_altera.vhd
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;

powered by: WebSVN 2.1.0

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