?? uc_interface.vhd
字號:
-- *****************************************************************************
-- uc_interface.vhd
--
-- Created: 9/15/00 ALS
-- This file provides the 8051 external data memory bus interface
-- for the SPI Master.
--
-- Revised: 12/12/02 JRH
-- *****************************************************************************
library IEEE;
use IEEE.std_logic_1164.all;
entity uC_interface is
generic (UC_ADDRESS : std_logic_vector(15 downto 8):= "00000000" );
port(
-- 8051 bus interface
clk : in std_logic;
reset : in std_logic;
addr_data : inout std_logic_vector (7 downto 0); -- multiplexed address/data bus
addr : in std_logic_vector (7 downto 0); -- high byte of address
ale_n : in std_logic; -- address latch enable, active low
psen_n : in std_logic; -- program store enable, active low
-- directional pins
rd_n : in std_logic; -- active low read strobe
wr_n : in std_logic; -- active low write strobe
int_n : inout std_logic; -- active low interrupt request
-- internal spi signals
-- interface to spi_control_sm
spien : inout std_logic; -- enables the spi interface logic
start : inout std_logic; -- start transfer
done : in std_logic; -- byte transfer is complete
rcv_load : in std_logic; -- load control signal to spi receive register
spissr : inout std_logic_vector(7 downto 0); -- uc slave select register
ss_n : in std_logic; -- internal version of ss_n being output
ss_in_int : in std_logic; -- internal sampled version of ss_in_n needed by
-- uc to generate an interrupt
xmit_empty : in std_logic; -- flag indicating that spitr is empty
xmit_empty_reset: inout std_logic; -- xmit empty flag reset when spitr is written
rcv_full : in std_logic; -- flag indicating that spirr has new data
rcv_full_reset : inout std_logic; -- rcv full flag reset when spirr is read
-- interface to sck_logic;
clkdiv : inout std_logic_vector(1 downto 0); -- sets the clock divisor for sck clock
cpha : inout std_logic; -- sets clock phase for output sck clock
cpol : inout std_logic; -- sets clock polarity for output sck clock
-- interface to receive and transmit shift registers
spitr : inout std_logic_vector (7 downto 0); -- data to transmit on spi bus
rcv_cpol : inout std_logic; -- clock polarity for incoming data
receive_data: in std_logic_vector (7 downto 0) -- data received from SPI bus
);
end uC_interface;
architecture BEHAVIOUR of uC_interface is
--**************************** Constants ***************************************
constant RESET_ACTIVE : STD_LOGIC := '0';
-- Base Address for SPI Module (addr_bus[15:8])
constant BASE_ADDR : STD_LOGIC_VECTOR(15 downto 8) := UC_ADDRESS;
-- Register Addresses (5 Total):
-- Status Register (BASE + 80h)
constant SPISR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10000000";
-- Control Register (BASE + 84h)
constant SPICR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10000100";
-- Slave Select Register (BASE + 88h)
constant SPISSR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10001000";
-- Transmit Data Register (BASE + 8Ah)
constant SPITR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10001010";
-- Receive Data Register (BASE + 8Eh)
constant SPIRR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10001110";
--**************************** Signal Definitions ***************************************
-- Internal handshaking lines for microprocessor
signal data_out : STD_LOGIC_VECTOR(7 downto 0); -- holds the data to be output on the data bus
signal data_in : STD_LOGIC_VECTOR(7 downto 0); -- holds the data to be input to the chip
signal data_oe : STD_LOGIC; -- allows data to be output on the data bus
-- State signals for target state machine
type STATE_TYPE is (IDLE, ADDR_DECODE, DATA_TRS, END_CYCLE);
signal prs_state, next_state : STATE_TYPE;
-- Address match
signal address_match : std_logic;
-- Register Enable Lines
signal cntrl_en : std_logic; -- control register is addressed
signal stat_en : std_logic; -- status register is addressed
signal xmit_en : std_logic; -- transmit data register is addressed
signal rcv_en : std_logic; -- receive data register is addressed
signal ssel_en : std_logic; -- slave select register is addressed
-- Register reset lines
signal spierr_reset : STD_LOGIC; -- writing 0 this bit in the status register
-- generates a reset to the bit
signal int_reset : STD_LOGIC; -- writing 0 this bit in the status register
-- generates a reset to the bit
-- low byte address lines
signal address_low : STD_LOGIC_VECTOR(7 downto 0);
-- receive data register
signal spirr : STD_LOGIC_VECTOR(7 downto 0); -- data received from SPI bus
-- control register signals
signal inten : STD_LOGIC; -- interrupt enable
-- status register signals
signal dt : STD_LOGIC; -- data transferring bit
signal spierr : STD_LOGIC; -- spi error bit
signal bb : STD_LOGIC; -- bus busy bit
begin
--************************** Bi-directional Data Bus **********************************
-- Bi-directional Data bus
addr_data <= data_out when (data_oe = '1') else (others => 'Z');
data_in <= addr_data when wr_n = '0' else (others => '0');
--************************** uC Interface State Machine *******************************
-- Register process registers next state signals
-- Return to IDLE state whenever RESET is asserted
UC_SM_REGS: process (clk, reset)
begin
if reset = RESET_ACTIVE then
prs_state <= IDLE;
elsif clk'event and clk = '1' then
prs_state <= next_state;
end if;
end process;
-- Combinatorial process determines next state logic
COMBINATIONAL: process (prs_state, ale_n, rd_n, wr_n, address_match, psen_n)
begin
next_state <= prs_state;
data_oe <= '0';
case prs_state is
--****************** IDLE State *********************
when IDLE =>
-- Wait for falling edge of ALE_N with PSEN_N negated
if ale_n = '0' and psen_n = '1' then
-- falling edge of ALE_N
next_state <= ADDR_DECODE;
end if;
--****************** ADDR_DECODE State *****************
when ADDR_DECODE =>
-- Check that this module is being address
if address_match = '1' then
-- Wait for rd_n or wr_n to be asserted
if rd_n = '0' or wr_n = '0' then
next_state <= DATA_TRS;
end if;
else
-- this module is not being addressed
next_state <= IDLE;
end if;
--****************** DATA_TRS State *********************
when DATA_TRS =>
-- Read or write from enabled register (see uC_regs process)
-- if read cycle, assert the data output enable
if rd_n = '0' then
data_oe <= '1';
end if;
-- wait until rd_n and wr_n negates before ending cycle
if rd_n = '1' and wr_n = '1' then
next_state <= END_CYCLE;
end if;
--****************** END_CYCLE State ********************
when END_CYCLE =>
-- Wait for negation of ale_n
if (ale_n = '1') then
next_state <= IDLE;
end if;
end case;
end process;
--************************** Address Registers **********************************
-- This process registers the low byte of address from the multiplexed address/data bus
-- on the falling edge of ale
address_regs: process(reset, ale_n)
begin
if reset = RESET_ACTIVE then
address_low <= (others => '0');
elsif ale_n'event and ale_n = '0' then
address_low <= addr_data;
end if;
end process;
--************************** Address Decode **********************************
-- This process decodes the address and sets enables for the registers
address_decode: process (reset, clk)
begin
if reset = RESET_ACTIVE then
address_match <= '0'; -- signal indicating that base address matches
xmit_en <= '0'; -- xmit data register enable
rcv_en <= '0'; -- receive data register enable
cntrl_en <= '0'; -- control register enable
stat_en <= '0'; -- status register enable
ssel_en <= '0'; -- slave select register enable
-- Synchronize with rising edge of clock
elsif clk'event and (clk = '1') then
if ale_n = '0' and addr = BASE_ADDR and psen_n = '1' then
-- base address matches and address is stable
address_match <= '1';
-- Check appropriate register address
case address_low(7 downto 0) is
when SPISR_ADDR => -- status register has been addressed
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -