-------------------------------------------------------------------------------
-- $Id: lmb_bram_if_cntlr.vhd,v 1.4 2008/10/02 07:47:46 rolandp Exp $
-------------------------------------------------------------------------------
-- DISCLAIMER OF LIABILITY
--
-- This file contains proprietary and confidential information of
-- Xilinx, Inc. ("Xilinx"), that is distributed under a license
-- from Xilinx, and may be used, copied and/or disclosed only
-- pursuant to the terms of a valid license agreement with Xilinx.
--
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION
-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT
-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT,
-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx
-- does not warrant that functions included in the Materials will
-- meet the requirements of Licensee, or that the operation of the
-- Materials will be uninterrupted or error-free, or that defects
-- in the Materials will be corrected. Furthermore, Xilinx does
-- not warrant or make any representations regarding use, or the
-- results of the use, of the Materials in terms of correctness,
-- accuracy, reliability or otherwise.
--
-- Xilinx products are not designed or intended to be fail-safe,
-- or for use in any application requiring fail-safe performance,
-- such as life-support or safety devices or systems, Class III
-- medical devices, nuclear facilities, applications related to
-- the deployment of airbags, or any other applications that could
-- lead to death, personal injury or severe property or
-- environmental damage (individually and collectively, "critical
-- applications"). Customer assumes the sole risk and liability
-- of any use of Xilinx products in critical applications,
-- subject only to applicable laws and regulations governing
-- limitations on product liability.
--
-- Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Xilinx, Inc.
-- All rights reserved.
--
-- This disclaimer and copyright notice must be retained as part
-- of this file at all times.
--
-------------------------------------------------------------------------------
-- Filename: lmb_bram_if_cntlr.vhd
--
-- Description:
--
-- VHDL-Standard: VHDL'93
-------------------------------------------------------------------------------
-- Structure:
-- lmb_bram_if_cntlr.vhd
--
-------------------------------------------------------------------------------
-- Author: goran
-- Revision: $Revision: 1.4 $
-- Date: $Date: 2008/10/02 07:47:46 $
--
-- History:
-- paulo 2002-07-08 First Version
--
-------------------------------------------------------------------------------
-- Naming Conventions:
-- active low signals: "*_n"
-- clock signals: "clk", "clk_div#", "clk_#x"
-- reset signals: "rst", "rst_n"
-- generics: "C_*"
-- user defined types: "*_TYPE"
-- state machine next state: "*_ns"
-- state machine current state: "*_cs"
-- combinatorial signals: "*_com"
-- pipelined or register delay signals: "*_d#"
-- counter signals: "*cnt*"
-- clock enable signals: "*_ce"
-- internal version of output port "*_i"
-- device pins: "*_pin"
-- ports: - Names begin with Uppercase
-- processes: "*_PROCESS"
-- component instantiations: "<ENTITY_>I_<#|FUNC>
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library lmb_bram_if_cntlr_v2_10_b;
use lmb_bram_if_cntlr_v2_10_b.pselect_mask;
entity lmb_bram_if_cntlr is
generic (
C_HIGHADDR : std_logic_vector(0 to 31) := X"00000000";
C_BASEADDR : std_logic_vector(0 to 31) := X"FFFFFFFF";
C_MASK : std_logic_vector(0 to 31) := X"00800000";
C_LMB_AWIDTH : integer := 32;
C_LMB_DWIDTH : integer := 32
);
port (
LMB_Clk : in std_logic := '0';
LMB_Rst : in std_logic := '0';
-- Instruction Bus
LMB_ABus : in std_logic_vector(0 to C_LMB_AWIDTH-1);
LMB_WriteDBus : in std_logic_vector(0 to C_LMB_DWIDTH-1);
LMB_AddrStrobe : in std_logic;
LMB_ReadStrobe : in std_logic;
LMB_WriteStrobe : in std_logic;
LMB_BE : in std_logic_vector(0 to (C_LMB_DWIDTH/8 - 1));
Sl_DBus : out std_logic_vector(0 to C_LMB_DWIDTH-1);
Sl_Ready : out std_logic;
-- ports to memory block
BRAM_Rst_A : out std_logic;
BRAM_Clk_A : out std_logic;
BRAM_Addr_A : out std_logic_vector(0 to C_LMB_AWIDTH-1);
BRAM_EN_A : out std_logic;
BRAM_WEN_A : out std_logic_vector(0 to C_LMB_DWIDTH/8-1);
BRAM_Dout_A : out std_logic_vector(0 to C_LMB_DWIDTH-1);
BRAM_Din_A : in std_logic_vector(0 to C_LMB_DWIDTH-1)
);
end lmb_bram_if_cntlr;
architecture imp of lmb_bram_if_cntlr is
------------------------------------------------------------------------------
-- component declarations
------------------------------------------------------------------------------
component pselect_mask is
generic (
C_AW : integer := 32;
C_BAR : std_logic_vector(0 to 31) := X"00000000";
C_MASK : std_logic_vector(0 to 31) := X"00800000");
port (
A : in std_logic_vector(0 to 31);
CS : out std_logic;
Valid : in std_logic);
end component;
------------------------------------------------------------------------------
-- internal signals
------------------------------------------------------------------------------
signal lmb_select : std_logic;
signal lmb_select_1 : std_logic;
signal lmb_we : std_logic_vector(0 to 3);
signal Sl_Ready_i : std_logic;
signal lmb_addrstrobe_i : std_logic;
signal One : std_logic;
begin -- architecture IMP
-----------------------------------------------------------------------------
-- Top-level port assignments
-- Port A
BRAM_Rst_A <= '0';
BRAM_Clk_A <= LMB_Clk;
BRAM_EN_A <= LMB_AddrStrobe; -- 每个外设都 Enable, 都会输出数据
BRAM_WEN_A <= lmb_we;
BRAM_Dout_A <= LMB_WriteDBus;
Sl_DBus <= BRAM_Din_A;
BRAM_Addr_A <= LMB_ABus;
-----------------------------------------------------------------------------
-- Handling the LMB bus interface
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Writes are pipelined in MB with 5 stage pipeline
-----------------------------------------------------------------------------
Ready_Handling : process (LMB_Clk, LMB_Rst) is
begin -- PROCESS Ready_Handling
if (LMB_Clk'event and LMB_Clk = '1') then -- rising clock edge
if (LMB_Rst = '1') then
Sl_Ready_i <= '0';
lmb_addrstrobe_i <= '0';
else
Sl_Ready_i <= lmb_select; -- 只有选择的外设才会Ready
lmb_addrstrobe_i <= LMB_AddrStrobe; -- 延时一个Clock
end if;
end if;
end process Ready_Handling;
Sl_Ready <= Sl_Ready_i and lmb_addrstrobe_i; -- 只有选择的外设才会Ready
-- 只有选择的外设才会被写入
lmb_we(0) <= LMB_BE(0) and LMB_WriteStrobe and lmb_select;
lmb_we(1) <= LMB_BE(1) and LMB_WriteStrobe and lmb_select;
lmb_we(2) <= LMB_BE(2) and LMB_WriteStrobe and lmb_select;
lmb_we(3) <= LMB_BE(3) and LMB_WriteStrobe and lmb_select;
-----------------------------------------------------------------------------
-- Do the LMB address decoding
-----------------------------------------------------------------------------
One <= '1';
pselect_mask_lmb : pselect_mask
generic map (
C_AW => LMB_ABus'length,
C_BAR => C_BASEADDR,
C_MASK => C_MASK)
port map (
A => LMB_ABus, -- 当前地址
CS => lmb_select, -- 外设选择
Valid => One);
end architecture imp;
-- LMB slave signals
Sl_DBus : in std_logic_vector(0 to (C_LMB_DWIDTH*C_LMB_NUM_SLAVES)-1);
-- 所有外设的输出
Sl_Ready : in std_logic_vector(0 to C_LMB_NUM_SLAVES-1);
-----------------------------------------------------------------------------
-- Drive all the Slave to Master signals
-----------------------------------------------------------------------------
-- 应该只有一个外设Ready ( lmb_select = '1' ) 的外设
-- lmb_select = '0', Sl_Ready = '0'
Ready_ORing : process (Sl_Ready) is
variable i : std_logic;
begin -- process Ready_ORing
i := '0';
for S in Sl_Ready'range loop
i := i or Sl_Ready(S);
end loop; -- S
LMB_Ready <= i;
end process Ready_ORing;
DBus_Oring : process (Sl_Ready, Sl_DBus) is
variable Res : std_logic_vector(0 to C_LMB_DWIDTH-1);
variable Tmp : std_logic_vector(Sl_DBus'range);
variable tmp_or : std_logic;
begin -- process DBus_Oring
if (C_LMB_NUM_SLAVES = 1) then -- 如果只有一个外设
LMB_ReadDBus <= Sl_DBus;
else
-- First gating all data signals with their resp. ready signal
for I in 0 to C_LMB_NUM_SLAVES-1 loop
for J in 0 to C_LMB_DWIDTH-1 loop
tmp(I*C_LMB_DWIDTH + J) := Sl_Ready(I) and Sl_DBus(I*C_LMB_DWIDTH + J);
-- 没有选中的外设, Sl_Ready(I) = '0' 数据被忽略
end loop; -- J
end loop; -- I
-- then oring the tmp signals together
for J in 0 to C_LMB_DWIDTH-1 loop
tmp_or := '0';
for I in 0 to C_LMB_NUM_SLAVES-1 loop
tmp_or := tmp_or or tmp(I*C_LMB_DWIDTH + j);
end loop; -- J
res(J) := tmp_or; -- 所有选择的外设相同数据位 相或
end loop; -- I
LMB_ReadDBus <= Res; -- 最终结果
end if;
end process DBus_Oring;
------------------------------------------------------------
-- 地址解码 ( 掩码, 地址, 基址 )
------------------------------------------------------------
地址[ 掩码为 '1' 的位位置 ] = 基址[ 掩码为 '1' 的位位置 ]
基址 = 0000_0000_0000_0000_0000_0000_0000_0000
( 0x????0000 -- 0x????7FFF ) 有效
掩码 = 0000_0000_0000_0000_1000_0000_0000_0000
地址 = 0000_0000_0000_0000_0000_0000_0000_0000 -- 有效
地址 = 0000_0000_0000_0000_1000_0000_0000_0000 -- 无效
基址 = 0000_0000_0000_0000_1000_0000_0000_0000
( 0x????8000 -- 0x????FFFF ) 有效
掩码 = 0000_0000_0000_0000_1000_0000_0000_0000
地址 = 0000_0000_0000_0000_0000_0000_0000_0000 -- 无效
地址 = 0000_0000_0000_0000_1000_0000_0000_0000 -- 有效
-- Definition of Generics:
-- C_AB -- number of address bits to decode
-- C_AW -- width of address bus
-- C_BAR -- base address of peripheral (peripheral select
-- is asserted when the C_AB most significant
-- address bits match the C_AB most significant
-- C_BAR bits
-- Definition of Ports:
-- A -- address input
-- AValid -- address qualifier
-- PS -- peripheral select
entity pselect_mask is
generic (
C_AW : integer := 32;
C_BAR : std_logic_vector(0 to 31) := "00000000000000100000000000000000";
C_MASK : std_logic_vector(0 to 31) := "00000000000001111100000000000000"
);
port (
A : in std_logic_vector(0 to C_AW-1);
Valid : in std_logic;
CS : out std_logic
);
end entity pselect_mask;
library unisim;
use unisim.all;
architecture imp of pselect_mask is
-- 计算MASK '1' 的位数
function Nr_Of_Ones (S : std_logic_vector) return natural is
variable tmp : natural := 0;
begin -- function Nr_Of_Ones
for I in S'range loop
if (S(I) = '1') then
tmp := tmp + 1;
end if;
end loop; -- I
return tmp;
end function Nr_Of_Ones;
function fix_AB (B : boolean; I : integer) return integer is
begin -- function fix_AB
if (not B) then
return I + 1;
else
return I;
end if;
end function fix_AB;
-- 计算MASK '1' 的位数
constant Nr : integer := Nr_Of_Ones(C_MASK);
constant Use_CIN : boolean := ((Nr mod 4) = 0);
constant AB : integer := fix_AB(Use_CIN, Nr);
signal A_Bus : std_logic_vector(0 to AB); -- 给出的地址
signal BAR : std_logic_vector(0 to AB); -- 基址
begin -- VHDL_RTL
Make_Busses : process (A,Valid) is
variable tmp : natural;
begin -- process Make_Busses
tmp := 0;
A_Bus <= (others => '0');
BAR <= (others => '0');
for I in C_MASK'range loop -- 计算 32 次
if (C_MASK(I) = '1') then -- 掩码中 为'1'的位
A_Bus(tmp) <= A(I); -- 地址
BAR(tmp) <= C_BAR(I); -- 基址
tmp := tmp + 1;
end if;
end loop; -- I
if (not Use_CIN) then -- 没有效果 ? Valid = '1'
BAR(tmp) <= '1';
A_Bus(tmp) <= Valid; -- Valid = '1'
end if;
end process Make_Busses;
CS <= Valid when A_Bus=BAR else '0'; -- Valid = '1'
end imp;
文章评论(0条评论)
登录后参与讨论