uc_interface.vhd
来自「可编程器件厂商Xilinx的用于设计SMBus 控制器的源程序」· VHDL 代码 · 共 457 行
VHD
457 行
-- File: uC_interface.vhd
--
-- Author: Jennifer Jenkins
-- Xilinx
-- Purpose: Description of an interface with a Hitachi SH7750 uC
-- bus to internal module registers
-- to be used for control of an SMBUS bus as master/slave with
-- transmit and receive modes.
--
--
-- Created: 6-23-00 ALS
-- This file created from the Motorola uC interface file used in the I2C design
-- Note that the use of the CS_N signal eliminates the need for a base address
-- therefore, only 8 bits of address bus are needed.
--
-- Modified: 8-10-00 JRH
-- Changed to reflect unknown number of uC wait states and Tsu/Thold wait states.
--
-- Modified: 8-14-00 JRH
-- Changed addresses for MADR, MBCR, MBSR, MBDR to even numbers.
library IEEE;
use IEEE.std_logic_1164.all;
entity uC_interface is
port(
-- SH7750 parallel bus interface
clk : in STD_LOGIC;
reset : in STD_LOGIC;
addr_bus : in STD_LOGIC_VECTOR (7 downto 0);
data_bus : inout STD_LOGIC_VECTOR (7 downto 0);
cs_n : in STD_LOGIC; -- chip select, active low
bs_n : in STD_LOGIC; -- bus cycle, active low
-- Directional pins
rd_n : in STD_LOGIC; -- Active low write
we_n : in STD_LOGIC; -- Active low read
rd_wrn : in STD_LOGIC; -- active high read, active low write
rdy_n : out STD_LOGIC; -- Active low ready signal, if high a wait state is inserted
irq : out STD_LOGIC; -- Interrupt request, active low
-- Internal SMBUS Bus Registers
-- Address Register (Contains slave address)
madr : inout STD_LOGIC_VECTOR(7 downto 0);
-- Control Register
men : inout STD_LOGIC; -- SMBUS Enable bit
mien : inout STD_LOGIC; -- interrupt enable
msta : inout STD_LOGIC; -- Master/Slave bit
mtx : inout STD_LOGIC; -- Master read/write
txak : inout STD_LOGIC; -- acknowledge bit
rsta : inout STD_LOGIC; -- repeated start
mbcr_wr : out STD_LOGIC; -- indicates that the control reg has been written
rsta_rst : in STD_LOGIC; -- input to modify rsta bit in contol register
-- Status Register
mcf : in STD_LOGIC; -- end of data transfer
maas : in STD_LOGIC; -- addressed as slave
mbb : in STD_LOGIC; -- bus busy
mal : in STD_LOGIC; -- arbitration lost
srw : in STD_LOGIC; -- slave read/write
mif : in STD_LOGIC; -- interrupt pending
rxak : in STD_LOGIC; -- received acknowledge
mal_bit_reset : out STD_LOGIC; -- indicates that the MAL bit should be reset
mif_bit_reset : out STD_LOGIC; -- indicates that the MIF bit should be reset
men_bit_reset : in STD_LOGIC; -- indicates that the MEN bit should be reset
msta_rst : in STD_LOGIC; -- resets the MSTA bit if arbitration is lost
-- Data Register
mbdr_micro : inout STD_LOGIC_VECTOR (7 downto 0);
mbdr_smbus : in STD_LOGIC_VECTOR (7 downto 0);
mbdr_read : out STD_LOGIC
);
end uC_interface;
architecture BEHAVIOUR of uC_interface is
-- Constant Declarations
constant RESET_ACTIVE : STD_LOGIC := '0';
-- Register Addresses (5 Total):
-- Address Register (8Ch)
constant MADR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10001100";
-- Control Register (90h)
constant MBCR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10010000";
-- Status Register (92h)
constant MBSR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10010010";
-- Data I/O Register (94h)
constant MBDR_ADDR : STD_LOGIC_VECTOR(7 downto 0) := "10010100";
-- State Machine Signals
type STATE_TYPE is (IDLE, ADDR_VALID, READ_WRITE);
-- Signal Declarations
-- Internal handshaking lines for microprocessor
signal wen_int : STD_LOGIC;
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
-- State signals for target state machine
signal prs_state, next_state : STATE_TYPE;
-- Register Enable Lines
signal addr_en : std_logic; -- smbus address register is selected
signal cntrl_en : std_logic; -- control register is selected
signal stat_en : std_logic; -- status register is selected
signal data_en : std_logic; -- data register is selected
begin
-- Interrupt signal to uProcessor
irq <= '0' when (mien = '1') and (mif = '1') else 'Z';
-- Bi-directional Data bus
data_bus <= data_out when (rd_n = '0' and cs_n = '0') else (others => 'Z');
data_in <= data_bus;
-- Process: SYNCH_INPUTS
-- Function: To register value of WE_N
--SYNCH_INPUTS: process(reset, clk)
-- begin
-- if reset = RESET_ACTIVE then
-- wen_int <= '1';
--
-- elsif clk'event and clk = '1' then
-- wen_int <= we_n;
--
-- end if;
--
-- end process;
-- Process: SEQUENTIAL
-- Function: Synchronize target state machine
SEQUENTIAL: 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;
-- Process: COMBINATIONAL
-- Function: Contains the synchronous target state machine to mediate
-- the handshaking taking place with the uProc parallel bus
COMBINATIONAL: process (prs_state, cs_n, bs_n, rd_wrn, we_n, rd_n)
begin
next_state <= prs_state;
rdy_n <= '1';
case prs_state is
------------- IDLE State (00) -------------
when IDLE =>
-- Wait for assertion of chip select and bus cycle
if cs_n = '0' and bs_n = '0' then
-- Since both CS_N and BS_N were asserted, this
-- module is being addressed
-- next clock (state) contains valid data
next_state <= ADDR_VALID;
end if;
------------ ADDR_VALID State (01) --------------
when ADDR_VALID =>
-- register enables are decided in this state
if (rd_wrn = '0' and we_n = '0') or (rd_wrn = '1' and rd_n = '0') then
next_state <= READ_WRITE;
end if;
---------- READ_WRITE State (10) ------------
when READ_WRITE =>
rdy_n <= '0';
-- Read or write from enabled register
-- go back to IDLE
if (rd_wrn = '0' and we_n = '1') or (rd_wrn = '1' and rd_n = '1') then
next_state <= IDLE;
end if;
-------- Default State ----------
when others =>
next_state <= IDLE;
end case;
end process;
-- Process: ADDR_DECODE
-- Function: Mapping address from uProc to enable appropriate register
ADDR_DECODE: process (reset, clk, prs_state)
begin
if reset = RESET_ACTIVE then
addr_en <= '0';
cntrl_en <= '0';
stat_en <= '0';
data_en <= '0';
-- Synchronize with rising edge of clock
elsif clk'event and (clk = '1') then
-- SMBUS bus is specified by uProc and address is stable
if (prs_state = ADDR_VALID) then
-- Check appropriate register address
case addr_bus(7 downto 0) is
when MADR_ADDR => addr_en <= '1';
cntrl_en <= '0';
stat_en <= '0';
data_en <= '0';
when MBCR_ADDR => cntrl_en <= '1';
addr_en <= '0';
stat_en <= '0';
data_en <= '0';
when MBSR_ADDR => stat_en <= '1';
addr_en <= '0';
cntrl_en <= '0';
data_en <= '0';
when MBDR_ADDR => data_en <= '1';
addr_en <= '0';
cntrl_en <= '0';
stat_en <= '0';
when others => addr_en <= '0';
cntrl_en <= '0';
stat_en <= '0';
data_en <= '0';
end case;
else
-- this device is not addressed
addr_en <= '0';
cntrl_en <= '0';
stat_en <= '0';
data_en <= '0';
end if;
end if;
end process;
-- Process: DATA_DIR
-- Function: Read from or write to appropriate registers specified
-- by uProc address
DATA_DIR: process(clk, reset, msta_rst, rsta_rst)
begin
-- Initialize all internal registers upon reset
if reset = RESET_ACTIVE then
-- Address Register
madr <= (others => '0');
-- Control Register
men <= '0';
mien <= '0';
msta <= '0';
mtx <= '0';
txak <= '0';
rsta <= '0';
mbcr_wr <= '0';
-- Status Register
mal_bit_reset <= '0';
mif_bit_reset <= '0';
-- Data Register
mbdr_micro <= (others => '0');
mbdr_read <= '0';
-- Initialize data bus
data_out <= (others => '0');
-- Check for rising edge of clock
elsif clk'event and (clk = '1') then
if (prs_state = IDLE) then
-- reset signals that indicate read from mbdr or write to mbcr
mbcr_wr <= '0';
mbdr_read <= '0';
-- Check for data transfer state
elsif (prs_state = READ_WRITE) then
-- Address register
if addr_en = '1' then
if rd_wrn = '0' then
-- uC write
madr <= data_in(7 downto 1) & '0';
else
-- since RD_N is used as output enable, set data out bus
-- to this register
data_out <= madr;
end if;
end if;
-- Control Register
if cntrl_en = '1' then
if rd_wrn = '0' then
-- uC write
mbcr_wr <= '1';
men <= data_in(7);
mien <= data_in(6);
msta <= data_in(5);
mtx <= data_in(4);
txak <= data_in(3);
rsta <= data_in(2);
else
-- uC read
mbcr_wr <= '0';
-- since RD_N is used as output enable, set data out bus
-- to this register
data_out <= men & mien & msta & mtx &
txak & rsta & "0" & "0";
end if;
else
mbcr_wr <= '0';
end if;
-- Status Register
if stat_en = '1' then
if rd_wrn = '0' then
-- uC write to these bits generates a reset
if data_in(4) = '0' then
mal_bit_reset <= '1';
end if;
if data_in(2) = '0' then
mif_bit_reset <= '1';
end if;
else
mal_bit_reset <= '0';
mif_bit_reset <= '0';
-- since RD_N is used as output enable, set data out bus
-- to this register
data_out <= mcf & maas & mbb & mal &
"0" & srw & mif & rxak;
end if;
else
mal_bit_reset <= '0';
mif_bit_reset <= '0';
end if;
-- Data Register
if data_en = '1' then
if rd_wrn = '0' then
-- uC write
mbdr_read <= '0';
mbdr_micro <= data_in;
else
-- uC Read
mbdr_read <= '1';
-- since RD_N is used as output enable, set data out bus
-- to this register
data_out <= mbdr_smbus;
end if;
else
mbdr_read <= '0';
end if;
end if;
-- if arbitration is lost, the SMBUS Control component will generate a reset for the
-- MSTA bit to force the design to slave mode
-- will do this reset synchronously
if msta_rst = '1' then
msta <= '0';
end if;
--If a repeated start has been completed by the smbus master, reset the rsta bit
--This prevents the repeated start from continually reoccurring
if rsta_rst = RESET_ACTIVE then
rsta <= '0';
end if;
--If a repeated start has been completed by the smbus master, reset the rsta bit
--This prevents the repeated start from continually reoccurring
if men_bit_reset = RESET_ACTIVE then
men <= '0';
end if;
end if;
end process;
end BEHAVIOUR;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?