?? apbmodel.vhd
字號:
-- ********************************************************************/
-- Copyright 2007 Actel Corporation. All rights reserved.
-- IP Engineering
--
-- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
-- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED
-- IN ADVANCE IN WRITING.
--
-- File: apbmodel.vhd
--
-- Description: Simple APB Bus Controller
-- Simple model of APB slave device
--
-- Rev: 2.3 01Mar07 IPB : Production Release
--
-- Notes:
--
-- *********************************************************************/
library IEEE;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.misc.all;
use work.textio.all;
use work.support.all;
entity APBModel is
generic ( ID : integer range 0 to 15;
DEBUG : integer range 0 to 1;
AWIDTH : integer range 1 to 16;
DWIDTH : integer range 8 to 32
);
port ( PCLK : in std_logic;
PRESETN : in std_logic;
-- APB Interface
PENABLE : in std_logic;
PWRITE : in std_logic;
PSEL : in std_logic;
PADDR : in std_logic_vector( AWIDTH-1 downto 0);
PWDATA : in std_logic_vector( DWIDTH-1 downto 0);
PRDATA : out std_logic_vector( DWIDTH-1 downto 0);
PREADY : out std_logic
);
end APBModel;
architecture Model of APBModel is
constant DEPTH : integer := (2 ** AWIDTH);
subtype RWORD is std_logic_vector (DWIDTH-1 downto 0);
type RAM_ARRAY is array ( INTEGER range <>) of RWORD;
signal PENABLE_D0 : std_logic;
signal PENABLE_D1 : std_logic;
signal PENABLE_D2 : std_logic;
signal PWRITE_D0 : std_logic;
signal PWRITE_D1 : std_logic;
signal PWRITE_D2 : std_logic;
signal PSEL_D0 : std_logic;
signal PSEL_D1 : std_logic;
signal PSEL_D2 : std_logic;
signal PADDR_D0 : std_logic_vector(AWIDTH-1 downto 0);
signal PADDR_D1 : std_logic_vector(AWIDTH-1 downto 0);
signal PADDR_D2 : std_logic_vector(AWIDTH-1 downto 0);
signal PWDATA_D0 : std_logic_vector(DWIDTH-1 downto 0);
signal PWDATA_D1 : std_logic_vector(DWIDTH-1 downto 0);
signal PWDATA_D2 : std_logic_vector(DWIDTH-1 downto 0);
begin
PREADY <= '1'; -- ready is not supported on APB
--------------------------------------------------------------------------------
-- The RAM block for storing data
PRAM:
process(PCLK)
variable RAM : RAM_ARRAY( 0 to DEPTH-1);variable iaddr : INTEGER := 0;
variable RDATA : RWORD;begin if PCLK'event and PCLK='1' and PRESETN='1' then if PSEL='1' then
iaddr := conv_integer(PADDR);
if PENABLE='1' and PWRITE='1' then
RAM(iaddr) := PWDATA;
if debug>0 then
printf("APBM: Slot %d Write %04h=%04h ",fmt(ID)&fmt(iaddr)&fmt(PWDATA));
end if;
end if;
if PWRITE='0' then
RDATA := RAM(iaddr);
PRDATA <= RDATA;
if PENABLE='1' and DEBUG>0 then
printf("APBM: Slot %d Read %04h=%04h ",fmt(ID)&fmt(iaddr)&fmt(RDATA));
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------
-- APB Protocol Checks
PENABLE_D0 <= PENABLE;
PWRITE_D0 <= PWRITE;
PSEL_D0 <= PSEL;
PADDR_D0 <= clean(PADDR);
PWDATA_D0 <= clean(PWDATA);
process(PCLK)
variable ERR : BOOLEAN;begin if PCLK'event and PCLK='1' and PRESETN='1' then
PENABLE_D1 <= PENABLE_D0;
PENABLE_D2 <= PENABLE_D1;
PWRITE_D1 <= PWRITE_D0;
PWRITE_D2 <= PWRITE_D1;
PSEL_D1 <= PSEL_D0;
PSEL_D2 <= PSEL_D1;
PADDR_D1 <= PADDR_D0;
PADDR_D2 <= PADDR_D1;
PWDATA_D1 <= PWDATA_D0;
PWDATA_D2 <= PWDATA_D1;
ERR := FALSE;
-- second cycle
if PENABLE_D0='1' and PSEL_D0='1' then
if PADDR_D0/=PADDR_D1 then
printf("APM:%d Address not stable in both cycles",fmt(ID));
ERR := TRUE;
end if;
if PWRITE_D0/=PWRITE_D1 then
printf("APM:%d PWRITE not stable in both cycles",fmt(ID));
ERR := TRUE;
end if;
if PSEL_D0/=PSEL_D1 then
printf("APM:%d PSEL not stable in both cycles",fmt(ID));
ERR := TRUE;
end if;
if PWDATA_D0/=PWDATA_D1 and PWRITE_D0='1' then
printf("APM:%d PWDATA not stable in both cycles",fmt(ID));
ERR := TRUE;
end if;
if PSEL_D1/='1' then
printf("APM:%d PSEL was not active in cycle before PENABLE",fmt(ID));
ERR := TRUE;
end if;
end if;
-- General Checks
if PENABLE_D0='1' and PENABLE_D1='1' then
printf("APM:%d PENABLE active for more than one clocks",fmt(ID));
ERR := TRUE;
end if;
if PSEL_D0='1' and PSEL_D1='1' and PSEL_D2='1' then
printf("APM:%d PSEL active for more than two clocks",fmt(ID));
ERR := TRUE;
end if;
if ERR then
assert FALSE
report "APB Protocol violation"
severity ERROR;
end if;
end if;
end process;
end Model;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -