📄 dsp_interface.vhd
字号:
-- File: dsp_interface.vhd
-- (c) Copyright 2003 Xilinx, Inc
-- All rights reserved
--
-- Author: John Hubbard
-- Xilinx
-- Purpose: Description of an interface with an Analog Devices ADSP-281xN DSP
-- bus to internal CF+ interface registers. The DSP is configured
-- in Full Memory Mode and the DSP uses the I/O Space to access the
-- CF+ interface registers.
--
-- Created: 2/24/2003 JRH
-- Modified: 6/20/2003 JRH
library IEEE;
use IEEE.std_logic_1164.all;
entity dsp_interface is
port(
-- **** ADSP-281xN I/O space interface ****
-- inputs
dsp_clk : in std_logic; -- clkout of DSP
dsp_addr : in std_logic_vector (10 downto 0);
dsp_ioms_n : in std_logic; -- I/O Memory Select, active low
dsp_rd_n : in std_logic; -- Read strobe, active low
dsp_wr_n : in std_logic; -- Read strobe, active low
-- inouts
--########################################################
-- Change this vector to (15 downto 0) for 16 bit I/O Space modes
dsp_data : inout std_logic_vector (7 downto 0);
--########################################################
-- **** I/O Interface internal control signals ****
-- inputs
level_pulse_n : in std_logic; -- level or pulse mode IRQ from LevelREQ bit in COR
io_reset : in std_logic; -- reset from the CF+ interface
--########################################################
-- Change this vector to (15 downto 0) for 16 bit I/O Space modes
io_data_w : in std_logic_vector(7 downto 0); -- I/O initerface write data byte
--########################################################
io_addr : in std_logic_vector(10 downto 0); -- host address to I/O space
io_read_n : in std_logic;
io_write_n : in std_logic;
iowr_n : in std_logic;
-- outputs
io_irq_pending : out std_logic; -- for INT bit of CSR
io_irq_n : out std_logic; -- new data has been written to any register by the DSP
io_wait_n : out std_logic;
inpack_n : out std_logic;
io_read_valid : out std_logic; -- indicates I/O register read data is valid
--########################################################
-- Change this vector to (15 downto 0) for 16 bit I/O Space modes
io_data_r : out std_logic_vector(7 downto 0) -- I/O initerface read data byte
--########################################################
);
end dsp_interface;
architecture behave of dsp_interface is
-- **************************** Constant Declarations ****************************
-- **** Register Addresses for the DSP interface ****
constant ADDRESS_REG_ADDR : std_logic_vector(10 downto 0) := "00000000001"; -- Address Register (001h)
constant DATA_REG_ADDR : std_logic_vector(10 downto 0) := "00000000010"; -- Data Register (002h)
constant STATUS_REG_ADDR : std_logic_vector(10 downto 0) := "00000000011"; -- Status Register (003h)
-- **** Register Addresses for the CF+ interface ****
constant CF_ADDR_REG : std_logic_vector(10 downto 0) := "10000000000"; -- Address Register (400h)
constant CF_DATA_REG : std_logic_vector(10 downto 0) := "10000000001"; -- Data Register (401h)
constant CF_STATUS_REG : std_logic_vector(10 downto 0) := "10000000010"; -- Status Register (402h)
-- **** Counter terminal count ****
constant IRQ_TERM_COUNT : std_logic_vector(5 downto 0) := "100111"; -- Count to 39 to get 0.5us pulse per spec
-- **************************** State Machine Signals ****************************
type STATE_TYPE is (IDLE_STATE, DSP_ADDR_STATE, DSP_DATA_READ_STATE, DSP_DATA_WRITE_STATE, CF_ADDR_STATE, CF_DATA_WRITE_STATE, CF_DATA_READ_STATE);
-- ****************************** Signal Declarations ****************************
-- Internal Registers
--########################################################
-- Change these vectors to (15 downto 0) for 16 bit I/O Space modes
signal io_addr_reg : std_logic_vector(7 downto 0); -- holds address from the CF+ interface
signal io_data_reg : std_logic_vector(7 downto 0); -- holds data to/from the CF+ interface
signal io_status_reg : std_logic_vector(7 downto 0); -- holds status of the I/O Space interface
signal data_in : std_logic_vector(7 downto 0); -- receives data from the DSP interface
signal data_out : std_logic_vector(7 downto 0); -- sends data to the DSP interface
--########################################################
-- State signals for target state machine
signal prs_state, next_state : STATE_TYPE;
-- Register Enable Lines
signal dsp_addr_en : std_logic; -- DSP address bus specifies the address register
signal dsp_data_en : std_logic; -- DSP address bus specifies the data register
signal dsp_status_en : std_logic; -- DSP address bus specifies the status register
signal io_addr_en : std_logic; -- CF+ address specifies the address register
signal io_data_en : std_logic; -- CF+ address specifies the data register
signal io_status_en : std_logic; -- CF+ address specifies the status register
-- State machine control signals
signal dsp_address_match : std_logic; -- the device is being addressed by the DSP
signal io_address_match : std_logic; -- the device is being addressed by the CF+
signal dsp_data_done : std_logic; -- the device has received and written data from DSP
signal io_data_done : std_logic; -- the device has received and written data from CF+ interface
-- CF+ Interface synchronized signals
signal io_write_n_sync : std_logic; -- synchronized io_write_n to the DSP clock
signal io_read_n_sync : std_logic; -- synchronized io_read_n to the DSP clock
-- Counter signals
signal irq_count_en : std_logic; -- counter enable
signal irq_count_clr : std_logic; -- counter reset
signal irq_count : std_logic_vector (5 downto 0); -- counter result
component upcnt6
port(
cnt_en : in std_logic; -- Count enable
clr : in std_logic; -- Active low clear
clk : in std_logic; -- Clock
qout : inout std_logic_vector (5 downto 0)
);
end component;
begin
--*************** I/O Read Acknowledge signal for CF+ interface ***************
inpack_n <= '0' when (io_read_n = '0' and (io_addr(10 downto 0) = CF_ADDR_REG or io_addr(10 downto 0) = CF_DATA_REG or io_addr(10 downto 0) = CF_STATUS_REG)) else
'1';
--****************** I/O Space Busy signal for CF+ interface ******************
io_wait_n <= dsp_ioms_n; -- I/O Space is busy with DSP access
--******************** Bi-Directional DSP Data Bus Control ********************
dsp_data <= data_out when (prs_state = DSP_DATA_READ_STATE and dsp_ioms_n = '0') else (others => 'Z');
data_in <= dsp_data when dsp_wr_n = '0' else (others => '0');
--************* Synchronize CF+ interface signals with DSP Clock **************
synchronize_cf: process (dsp_clk, io_reset)
begin
if io_reset = '0' then
io_write_n_sync <= '1';
io_read_n_sync <= '1';
io_read_valid <= '0';
elsif (dsp_clk'event and dsp_clk = '1') then
io_write_n_sync <= io_write_n;
io_read_n_sync <= io_read_n;
if prs_state = CF_DATA_READ_STATE then
io_read_valid <= '1';
else
io_read_valid <= '0';
end if;
end if;
end process;
--************* Sequential portion of DSP Interface State Machine *************
sequential: process (dsp_clk, io_reset)
begin
if io_reset = '0' then
prs_state <= IDLE_STATE;
elsif (dsp_clk'event and dsp_clk = '1') then -- state machine runs on falling edge of DSP clock
prs_state <= next_state;
end if;
end process;
--************ Combinatorial portion of DSP Interface State Machine ***********
-- Contains the synchronous DSP Interface state machine to mediate
-- the handshaking taking place with the DSP I/O Space bus
combinatorial: process (prs_state, dsp_address_match, dsp_ioms_n, dsp_wr_n, dsp_rd_n, dsp_data_done, io_write_n_sync, io_read_n_sync, io_address_match, io_read_n)
begin
next_state <= prs_state;
case prs_state is
------------- IDLE_STATE (000) -------------
when IDLE_STATE =>
if dsp_ioms_n = '0' then -- device is selected by DSP
next_state <= DSP_ADDR_STATE;
elsif (io_write_n_sync = '0' or io_read_n_sync = '0') then -- device is selected by CF+
next_state <= CF_ADDR_STATE;
else
next_state <= IDLE_STATE;
end if;
------------ DSP_ADDR_STATE (001) --------------
when DSP_ADDR_STATE =>
-- Check that this module is being addressed for read
if (dsp_address_match = '1' and dsp_ioms_n = '0' and dsp_rd_n = '0') then
next_state <= DSP_DATA_READ_STATE; -- this module is being addressed
-- Check that this module is being addressed for write
elsif (dsp_address_match = '1' and dsp_ioms_n = '0' and dsp_wr_n = '0') then
next_state <= DSP_DATA_WRITE_STATE; -- this module is being addressed
-- write signal not present, but device is addressed
elsif (dsp_address_match = '1' and dsp_ioms_n = '0' and dsp_wr_n = '1' and dsp_rd_n = '1') then
next_state <= DSP_ADDR_STATE;
-- this module is not being addressed
else
next_state <= IDLE_STATE;
end if;
---------- DSP_DATA_READ_STATE (010)------------
when DSP_DATA_READ_STATE =>
-- Write to enabled register
if (dsp_data_done = '1' or dsp_ioms_n = '1') then
next_state <= IDLE_STATE;
else
next_state <= DSP_DATA_READ_STATE;
end if;
---------- DSP_DATA_WRITE_STATE (011)------------
when DSP_DATA_WRITE_STATE =>
-- Write to enabled register
if (dsp_data_done = '1' or dsp_wr_n = '1') then
next_state <= IDLE_STATE;
else
next_state <= DSP_DATA_WRITE_STATE;
end if;
---------- CF_ADDR_STATE (100)------------
when CF_ADDR_STATE =>
-- Write to enabled register
if (io_address_match = '1' and io_write_n_sync = '0') then
next_state <= CF_DATA_WRITE_STATE;
elsif (io_address_match = '1' and io_read_n_sync = '0') then
next_state <= CF_DATA_READ_STATE;
else
next_state <= CF_ADDR_STATE;
end if;
---------- CF_DATA_WRITE_STATE (101)------------
when CF_DATA_WRITE_STATE =>
-- Write to enabled register
if io_write_n_sync = '1' then
next_state <= IDLE_STATE;
else
next_state <= CF_DATA_WRITE_STATE;
end if;
---------- CF_DATA_READ_STATE (110)------------
when CF_DATA_READ_STATE =>
-- Write to enabled register
if io_read_n_sync = '1' then
next_state <= IDLE_STATE;
else
next_state <= CF_DATA_READ_STATE;
end if;
end case;
end process;
--*********************** DSP Address Decode *************************
dsp_addr_decode: process (io_reset, dsp_clk, prs_state, dsp_addr)
begin
if io_reset = '0' then
dsp_addr_en <= '0';
dsp_data_en <= '0';
dsp_status_en <= '0';
dsp_address_match <= '0';
elsif (dsp_clk'event and dsp_clk = '0') then
if prs_state = DSP_ADDR_STATE then
case dsp_addr(10 downto 0) is
when ADDRESS_REG_ADDR =>
dsp_addr_en <= '1';
dsp_data_en <= '0';
dsp_status_en <= '0';
dsp_address_match <= '1';
when DATA_REG_ADDR =>
dsp_addr_en <= '0';
dsp_data_en <= '1';
dsp_status_en <= '0';
dsp_address_match <= '1';
when STATUS_REG_ADDR =>
dsp_addr_en <= '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -