08-06-2009 02:21 AM
Hi
I have some problems when I am learning the LMB BRAM interface Controller(v2.00a)
I can not understand the code of it.
library ieee;
use ieee.std_logic_1164.all;
library proc_common_v1_00_c;
use proc_common_v1_00_c.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;
begin -- architecture IMP
-----------------------------------------------------------------------------
-- Top-level port assignments
-- Port A
BRAM_Rst_A <= '0';
BRAM_Clk_A <= LMB_Clk;
BRAM_EN_A <= '1';
BRAM_WEN_A <= lmb_we;
BRAM_Dout_A <= LMB_WriteDBus;
Sl_DBus <= BRAM_Din_A;
BRAM_Addr_A <= LMB_ABus;
------------------------------------------------------------------------------
--the code below, I can not understand
------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- 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_Rst = '1') then
Sl_Ready <= '0';
elsif (LMB_Clk'event and LMB_Clk = '1') then -- rising clock edge
Sl_Ready <= lmb_select;
end if;
end process Ready_Handling;
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
-----------------------------------------------------------------------------
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 => LMB_AddrStrobe);
end architecture imp;
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;
-----------------------------------------------------------------------------
-- Architecture section
-----------------------------------------------------------------------------
library unisim;
use unisim.all;
architecture imp of pselect_mask is
-- component LUT4
-- generic(
-- INIT : bit_vector := X"0000"
-- );
-- port (
-- O : out std_logic;
-- I0 : in std_logic := '0';
-- I1 : in std_logic := '0';
-- I2 : in std_logic := '0';
-- I3 : in std_logic := '0');
-- end component;
-- component MUXCY is
-- port (
-- O : out std_logic;
-- CI : in std_logic;
-- DI : in std_logic;
-- S : in std_logic
-- );
-- end component MUXCY;
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;
constant Nr : integer := Nr_Of_Ones(C_MASK);
constant Use_CIN : boolean := ((Nr mod 4) = 0);
constant AB : integer := fix_AB(Use_CIN, Nr);
attribute INIT : string;
constant NUM_LUTS : integer := (AB-1)/4+1;
-- signal lut_out : std_logic_vector(0 to NUM_LUTS-1);
-- signal carry_chain : std_logic_vector(0 to NUM_LUTS);
-- function to initialize LUT within pselect
type int4 is array (3 downto 0) of integer;
function pselect_init_lut(i : integer;
AB : integer;
NUM_LUTS : integer;
C_AW : integer;
C_BAR : std_logic_vector(0 to 31))
return bit_vector is
variable init_vector : bit_vector(15 downto 0) := X"0001";
variable j : integer := 0;
variable val_in : int4;
begin
for j in 0 to 3 loop
if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) then
val_in(j) := conv_integer(C_BAR(i*4+j));
else val_in(j) := 0;
end if;
end loop;
init_vector := To_bitvector(conv_std_logic_vector(2**(val_in(3)*8+
val_in(2)*4+val_in(1)*2+val_in(0)*1),16));
return init_vector;
end pselect_init_lut;
signal A_Bus : std_logic_vector(0 to AB);
signal BAR : std_logic_vector(0 to AB);
-------------------------------------------------------------------------------
-- Begin architecture section
-------------------------------------------------------------------------------
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
if (C_MASK(I) = '1') then
A_Bus(tmp) <= A(I);
BAR(tmp) <= C_BAR(I);
tmp := tmp + 1;
end if;
end loop; -- I
if (not Use_CIN) then
BAR(tmp) <= '1';
A_Bus(tmp) <= Valid;
end if;
end process Make_Busses;
-- More_Than_3_Bits : if (AB > 3) generate
-- Using_CIn: if (Use_CIN) generate
-- carry_chain(0) <= Valid;
-- end generate Using_CIn;
-- No_CIn: if (not Use_CIN) generate
-- carry_chain(0) <= '1';
-- end generate No_CIn;
-- GEN_DECODE : for i in 0 to NUM_LUTS-1 generate
-- signal lut_in : std_logic_vector(3 downto 0);
-- begin
-- GEN_LUT_INPUTS : for j in 0 to 3 generate
-- -- Generate to assign address bits to LUT4 inputs
-- GEN_INPUT : if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) generate
-- lut_in(j) <= A_Bus(i*4+j);
-- end generate;
-- -- Generate to assign zeros to remaining LUT4 inputs
-- GEN_ZEROS : if not(i < NUM_LUTS-1 or j <= ((AB-1) mod 4)) generate
-- lut_in(j) <= '0';
-- end generate;
-- end generate;
---------------------------------------------------------------------------------
---- RTL version without LUT instantiation for XST
---------------------------------------------------------------------------------
-- lut_out(i) <= (lut_in(0) xnor BAR(i*4+0)) and
-- (lut_in(1) xnor BAR(i*4+1)) and
-- (lut_in(2) xnor BAR(i*4+2)) and
-- (lut_in(3) xnor BAR(i*4+3));
---------------------------------------------------------------------------------
---- Structural version with LUT instantiation for Synplicity (when RLOC is
---- desired for placing LUT
---------------------------------------------------------------------------------
---- LUT4_I : LUT4
---- generic map(
---- -- Function init_lut is used to generate INIT value for LUT4
---- INIT => pselect_init_lut(i,C_AB,NUM_LUTS,C_AW,C_BAR)
---- )
---- port map (
---- O => lut_out(i), -- [out]
---- I0 => lut_in(0), -- [in]
---- I1 => lut_in(1), -- [in]
---- I2 => lut_in(2), -- [in]
---- I3 => lut_in(3)); -- [in]
---------------------------------------------------------------------------------
-- MUXCY_I : MUXCY
-- port map (
-- O => carry_chain(i+1), --[out]
-- CI => carry_chain(i), --[in]
-- DI => '0', --[in]
-- S => lut_out(i) --[in]
-- );
-- end generate;
-- CS <= carry_chain(NUM_LUTS); -- assign end of carry chain to output
-- end generate More_Than_3_Bits;
-- Less_than_4_bits: if (AB < 4) generate
CS <= Valid when A_Bus=BAR else '0';
-- end generate Less_than_4_bits;
end imp;
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;
-----------------------------------------------------------------------------
-- Architecture section
-----------------------------------------------------------------------------
library unisim;
use unisim.all;
architecture imp of pselect_mask is
-- component LUT4
-- generic(
-- INIT : bit_vector := X"0000"
-- );
-- port (
-- O : out std_logic;
-- I0 : in std_logic := '0';
-- I1 : in std_logic := '0';
-- I2 : in std_logic := '0';
-- I3 : in std_logic := '0');
-- end component;
-- component MUXCY is
-- port (
-- O : out std_logic;
-- CI : in std_logic;
-- DI : in std_logic;
-- S : in std_logic
-- );
-- end component MUXCY;
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;
constant Nr : integer := Nr_Of_Ones(C_MASK);
constant Use_CIN : boolean := ((Nr mod 4) = 0);
constant AB : integer := fix_AB(Use_CIN, Nr);
attribute INIT : string;
constant NUM_LUTS : integer := (AB-1)/4+1;
-- signal lut_out : std_logic_vector(0 to NUM_LUTS-1);
-- signal carry_chain : std_logic_vector(0 to NUM_LUTS);
-- function to initialize LUT within pselect
type int4 is array (3 downto 0) of integer;
function pselect_init_lut(i : integer;
AB : integer;
NUM_LUTS : integer;
C_AW : integer;
C_BAR : std_logic_vector(0 to 31))
return bit_vector is
variable init_vector : bit_vector(15 downto 0) := X"0001";
variable j : integer := 0;
variable val_in : int4;
begin
for j in 0 to 3 loop
if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) then
val_in(j) := conv_integer(C_BAR(i*4+j));
else val_in(j) := 0;
end if;
end loop;
init_vector := To_bitvector(conv_std_logic_vector(2**(val_in(3)*8+
val_in(2)*4+val_in(1)*2+val_in(0)*1),16));
return init_vector;
end pselect_init_lut;
signal A_Bus : std_logic_vector(0 to AB);
signal BAR : std_logic_vector(0 to AB);
-------------------------------------------------------------------------------
-- Begin architecture section
-------------------------------------------------------------------------------
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
if (C_MASK(I) = '1') then
A_Bus(tmp) <= A(I);
BAR(tmp) <= C_BAR(I);
tmp := tmp + 1;
end if;
end loop; -- I
if (not Use_CIN) then
BAR(tmp) <= '1';
A_Bus(tmp) <= Valid;
end if;
end process Make_Busses;
-- More_Than_3_Bits : if (AB > 3) generate
-- Using_CIn: if (Use_CIN) generate
-- carry_chain(0) <= Valid;
-- end generate Using_CIn;
-- No_CIn: if (not Use_CIN) generate
-- carry_chain(0) <= '1';
-- end generate No_CIn;
-- GEN_DECODE : for i in 0 to NUM_LUTS-1 generate
-- signal lut_in : std_logic_vector(3 downto 0);
-- begin
-- GEN_LUT_INPUTS : for j in 0 to 3 generate
-- -- Generate to assign address bits to LUT4 inputs
-- GEN_INPUT : if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) generate
-- lut_in(j) <= A_Bus(i*4+j);
-- end generate;
-- -- Generate to assign zeros to remaining LUT4 inputs
-- GEN_ZEROS : if not(i < NUM_LUTS-1 or j <= ((AB-1) mod 4)) generate
-- lut_in(j) <= '0';
-- end generate;
-- end generate;
---------------------------------------------------------------------------------
---- RTL version without LUT instantiation for XST
---------------------------------------------------------------------------------
-- lut_out(i) <= (lut_in(0) xnor BAR(i*4+0)) and
-- (lut_in(1) xnor BAR(i*4+1)) and
-- (lut_in(2) xnor BAR(i*4+2)) and
-- (lut_in(3) xnor BAR(i*4+3));
---------------------------------------------------------------------------------
---- Structural version with LUT instantiation for Synplicity (when RLOC is
---- desired for placing LUT
---------------------------------------------------------------------------------
---- LUT4_I : LUT4
---- generic map(
---- -- Function init_lut is used to generate INIT value for LUT4
---- INIT => pselect_init_lut(i,C_AB,NUM_LUTS,C_AW,C_BAR)
---- )
---- port map (
---- O => lut_out(i), -- [out]
---- I0 => lut_in(0), -- [in]
---- I1 => lut_in(1), -- [in]
---- I2 => lut_in(2), -- [in]
---- I3 => lut_in(3)); -- [in]
---------------------------------------------------------------------------------
-- MUXCY_I : MUXCY
-- port map (
-- O => carry_chain(i+1), --[out]
-- CI => carry_chain(i), --[in]
-- DI => '0', --[in]
-- S => lut_out(i) --[in]
-- );
-- end generate;
-- CS <= carry_chain(NUM_LUTS); -- assign end of carry chain to output
-- end generate More_Than_3_Bits;
-- Less_than_4_bits: if (AB < 4) generate
CS <= Valid when A_Bus=BAR else '0';
-- end generate Less_than_4_bits;
end imp;
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;
-----------------------------------------------------------------------------
-- Architecture section
-----------------------------------------------------------------------------
library unisim;
use unisim.all;
architecture imp of pselect_mask is
-- component LUT4
-- generic(
-- INIT : bit_vector := X"0000"
-- );
-- port (
-- O : out std_logic;
-- I0 : in std_logic := '0';
-- I1 : in std_logic := '0';
-- I2 : in std_logic := '0';
-- I3 : in std_logic := '0');
-- end component;
-- component MUXCY is
-- port (
-- O : out std_logic;
-- CI : in std_logic;
-- DI : in std_logic;
-- S : in std_logic
-- );
-- end component MUXCY;
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;
constant Nr : integer := Nr_Of_Ones(C_MASK);
constant Use_CIN : boolean := ((Nr mod 4) = 0);
constant AB : integer := fix_AB(Use_CIN, Nr);
attribute INIT : string;
constant NUM_LUTS : integer := (AB-1)/4+1;
-- signal lut_out : std_logic_vector(0 to NUM_LUTS-1);
-- signal carry_chain : std_logic_vector(0 to NUM_LUTS);
-- function to initialize LUT within pselect
type int4 is array (3 downto 0) of integer;
function pselect_init_lut(i : integer;
AB : integer;
NUM_LUTS : integer;
C_AW : integer;
C_BAR : std_logic_vector(0 to 31))
return bit_vector is
variable init_vector : bit_vector(15 downto 0) := X"0001";
variable j : integer := 0;
variable val_in : int4;
begin
for j in 0 to 3 loop
if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) then
val_in(j) := conv_integer(C_BAR(i*4+j));
else val_in(j) := 0;
end if;
end loop;
init_vector := To_bitvector(conv_std_logic_vector(2**(val_in(3)*8+
val_in(2)*4+val_in(1)*2+val_in(0)*1),16));
return init_vector;
end pselect_init_lut;
signal A_Bus : std_logic_vector(0 to AB);
signal BAR : std_logic_vector(0 to AB);
-------------------------------------------------------------------------------
-- Begin architecture section
-------------------------------------------------------------------------------
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
if (C_MASK(I) = '1') then
A_Bus(tmp) <= A(I);
BAR(tmp) <= C_BAR(I);
tmp := tmp + 1;
end if;
end loop; -- I
if (not Use_CIN) then
BAR(tmp) <= '1';
A_Bus(tmp) <= Valid;
end if;
end process Make_Busses;
-- More_Than_3_Bits : if (AB > 3) generate
-- Using_CIn: if (Use_CIN) generate
-- carry_chain(0) <= Valid;
-- end generate Using_CIn;
-- No_CIn: if (not Use_CIN) generate
-- carry_chain(0) <= '1';
-- end generate No_CIn;
-- GEN_DECODE : for i in 0 to NUM_LUTS-1 generate
-- signal lut_in : std_logic_vector(3 downto 0);
-- begin
-- GEN_LUT_INPUTS : for j in 0 to 3 generate
-- -- Generate to assign address bits to LUT4 inputs
-- GEN_INPUT : if i < NUM_LUTS-1 or j <= ((AB-1) mod 4) generate
-- lut_in(j) <= A_Bus(i*4+j);
-- end generate;
-- -- Generate to assign zeros to remaining LUT4 inputs
-- GEN_ZEROS : if not(i < NUM_LUTS-1 or j <= ((AB-1) mod 4)) generate
-- lut_in(j) <= '0';
-- end generate;
-- end generate;
---------------------------------------------------------------------------------
---- RTL version without LUT instantiation for XST
---------------------------------------------------------------------------------
-- lut_out(i) <= (lut_in(0) xnor BAR(i*4+0)) and
-- (lut_in(1) xnor BAR(i*4+1)) and
-- (lut_in(2) xnor BAR(i*4+2)) and
-- (lut_in(3) xnor BAR(i*4+3));
---------------------------------------------------------------------------------
---- Structural version with LUT instantiation for Synplicity (when RLOC is
---- desired for placing LUT
---------------------------------------------------------------------------------
---- LUT4_I : LUT4
---- generic map(
---- -- Function init_lut is used to generate INIT value for LUT4
---- INIT => pselect_init_lut(i,C_AB,NUM_LUTS,C_AW,C_BAR)
---- )
---- port map (
---- O => lut_out(i), -- [out]
---- I0 => lut_in(0), -- [in]
---- I1 => lut_in(1), -- [in]
---- I2 => lut_in(2), -- [in]
---- I3 => lut_in(3)); -- [in]
---------------------------------------------------------------------------------
-- MUXCY_I : MUXCY
-- port map (
-- O => carry_chain(i+1), --[out]
-- CI => carry_chain(i), --[in]
-- DI => '0', --[in]
-- S => lut_out(i) --[in]
-- );
-- end generate;
-- CS <= carry_chain(NUM_LUTS); -- assign end of carry chain to output
-- end generate More_Than_3_Bits;
-- Less_than_4_bits: if (AB < 4) generate
CS <= Valid when A_Bus=BAR else '0';
-- end generate Less_than_4_bits;
end imp;
I had read the datasheet of LMB BRAM Interface Controller,however,I could not find imformation in detail about the components in LMB BRAM Interface Controller. Especially,I want to konw the function of the pselect_mask and the LMB address decoding.
Thank you!
03-20-2011 04:29 AM
03-22-2011 02:48 AM
Hi,
Since this is about an EDK IP core, I believe you'll receive better assistance on EDK board. I'll move it to the EDK board. Thanks.
-Vivian
03-22-2011 08:33 AM - edited 03-22-2011 08:33 AM
Hi,
I think it would be better if you can specify in more details the things you don't understand.
The c_mask handling? or the pselect_mask core? or the VHDL coding of c_mask?
Göran