原创 microblaze lmb bram

2010-12-22 10:59 2855 9 9 分类: FPGA/CPLD
entity lmb_v10 is
generic (
C_LMB_NUM_SLAVES : integer := 4;
C_LMB_DWIDTH : integer := 32;
C_LMB_AWIDTH : integer := 32;
C_EXT_RESET_HIGH : integer := 1
);
port (
-- Global Ports
LMB_Clk : in std_logic; -- LMB Clock
SYS_Rst : in std_logic; -- External System Reset
LMB_Rst : out std_logic; -- LMB Reset
-- LMB master signals
M_ABus : in std_logic_vector(0 to C_LMB_AWIDTH-1);
M_ReadStrobe : in std_logic;
M_WriteStrobe : in std_logic;
M_AddrStrobe : in std_logic;
M_DBus : in std_logic_vector(0 to C_LMB_DWIDTH-1);
M_BE : in std_logic_vector(0 to (C_LMB_DWIDTH+7)/8-1); -- Master Byte Enables
-- 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);
-- LMB output signals
LMB_ABus : out std_logic_vector(0 to C_LMB_AWIDTH-1);
LMB_ReadStrobe : out std_logic;
LMB_WriteStrobe : out std_logic;
LMB_AddrStrobe : out std_logic;
LMB_ReadDBus : out std_logic_vector(0 to C_LMB_DWIDTH-1);
LMB_WriteDBus : out std_logic_vector(0 to C_LMB_DWIDTH-1);
LMB_Ready : out std_logic;
LMB_BE : out std_logic_vector(0 to (C_LMB_DWIDTH+7)/8-1)
);
end entity lmb_v10;
-----------------------------------------------------------------------------
-- Drive all Master to Slave signals
-----------------------------------------------------------------------------
LMB_ABus <= M_ABus;
LMB_ReadStrobe <= M_ReadStrobe;
LMB_WriteStrobe <= M_WriteStrobe;
LMB_AddrStrobe <= M_AddrStrobe;
LMB_BE <= M_BE;
LMB_WriteDBus <= M_DBus;
-----------------------------------------------------------------------------
-- Drive all the Slave to Master signals
-----------------------------------------------------------------------------
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);
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;
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;

-----------------------------------------------------------------------------
-- Top-level port assignments
-- Port A
BRAM_Rst_A <= '0';
BRAM_Clk_A <= LMB_Clk;
BRAM_EN_A <= LMB_AddrStrobe;
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;
lmb_addrstrobe_i <= LMB_AddrStrobe;
end if;
end if;
end process Ready_Handling;
Sl_Ready <= Sl_Ready_i and lmb_addrstrobe_i;

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 => '1');
-----------------------------------------------------------------------------
-- pselect_mask
-----------------------------------------------------------------------------
Make_Busses : process (LMB_ABus) is
variable tmp : natural;
begin -- process Make_Busses
tmp := 0;
A_Bus <= (others => '0');
BAR <= (others => '0');
for I in C_MASK'range loop
if (C_MASK(I) = '1') then
A_Bus(tmp) <= LMB_ABus(I);
BAR(tmp) <= C_BASEADDR(I);
tmp := tmp + 1;
end if;
end loop; -- I
if (not Use_CIN) then
BAR(tmp) <= '1';
A_Bus(tmp) <= '1';
end if;
end process Make_Busses;
LMB_SELECT <= '1' when A_Bus=BAR else '0';
MASK : 000001100000000
**
BASE : 000001000000000
**
ADDR : 000001100000000 -- '0'
**
ADDR : 0000010XXXXXXXX -- '1'
**
ADDR : 000000010000000 -- '0'
**
ADDR : 000000110000000 -- '0'





**

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条