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; |