📄 ipic_if.vhd
字号:
Row_addr : out std_logic_vector(0 to C_DDR_AWIDTH-1);
Col_addr : out std_logic_vector(0 to C_DDR_AWIDTH-1);
Bank_addr : out std_logic_vector(0 to C_DDR_BANK_AWIDTH-1);
Pend_rdreq : out std_logic;
Pend_wrreq : out std_logic;
Same_row : out std_logic;
Same_bank : out std_logic;
Clk : in std_logic;
Rst : in std_logic
);
end entity ipic_if;
-----------------------------------------------------------------------------
-- Architecture section
-----------------------------------------------------------------------------
architecture imp of ipic_if is
-----------------------------------------------------------------------------
-- Constant declarations
-----------------------------------------------------------------------------
-- calculate the unused address bits based on ddr data width
-- this is then used to calculate the address bit slices for the bank, row, and
-- column addresses
constant ADDR_OFFSET : integer := log2(C_DDR_DWIDTH/8);
constant COLADDR_STARTBIT : integer := C_IPIF_AWIDTH - (C_DDR_COL_AWIDTH+ADDR_OFFSET);
constant COLADDR_ENDBIT : integer := COLADDR_STARTBIT + C_DDR_COL_AWIDTH-2; -- A0 not used
constant ROWADDR_STARTBIT : integer := COLADDR_STARTBIT - C_DDR_AWIDTH;
constant ROWADDR_ENDBIT : integer := ROWADDR_STARTBIT + C_DDR_AWIDTH-1;
constant BANKADDR_STARTBIT : integer := ROWADDR_STARTBIT - C_DDR_BANK_AWIDTH;
constant BANKADDR_ENDBIT : integer := BANKADDR_STARTBIT + C_DDR_BANK_AWIDTH-1;
--constant ZERO_COL_PAD : std_logic_vector(0 to C_DDR_AWIDTH-C_DDR_COL_AWIDTH-1)
-- := (others => '0');
-- Allow seperate assignment for A10 = '0'
constant ZERO_COL_PAD : std_logic_vector(0 to C_DDR_AWIDTH-C_DDR_COL_AWIDTH-2)
:= (others => '0');
-----------------------------------------------------------------------------
-- Signal declarations
-----------------------------------------------------------------------------
-- internal versions of output signals
signal row_addr_i : std_logic_vector(0 to C_DDR_AWIDTH-1);
signal bank_addr_i : std_logic_vector(0 to C_DDR_BANK_AWIDTH-1);
signal same_row_i : std_logic;
signal same_bank_i : std_logic;
signal ip2bus_retry_i : std_logic;
signal pend_wrreq_i : std_logic;
signal pend_rdreq_i : std_logic;
signal comb_Bus2IP_CS_i : std_logic;
-- Same_row and Same_bank signals
signal last_row_lsb : std_logic;
signal last_bank_lsb : std_logic;
-- Xfer qualifiers rising edge detect signals
signal wrreq_d1, wrreq_re : std_logic;
signal rdreq_d1, rdreq_re : std_logic;
-----------------------------------------------------------------------------
-- Component declarations
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Begin architecture
-----------------------------------------------------------------------------
begin -- architecture imp
-- assign output signals
Row_addr <= row_addr_i;
Bank_addr <= bank_addr_i;
Same_row <= same_row_i;
Same_bank <= same_bank_i;
IP2Bus_Retry <= ip2bus_retry_i;
Pend_rdreq <= pend_rdreq_i;
Pend_wrreq <= pend_wrreq_i;
Comb_Bus2IP_CS <= comb_Bus2IP_CS_i;
-- Only generate burst signal if C_INCLUDE_BURSTS=1
W_BURST: if C_INCLUDE_BURSTS = 1 generate
Burst <= Bus2IP_Burst or Bus2IP_IBurst;
end generate W_BURST;
WO_BURST : if C_INCLUDE_BURSTS = 0 generate
Burst <= '0';
end generate WO_BURST;
-- determine bank, row, and column addresses
bank_addr_i <= Bus2IP_Addr(BANKADDR_STARTBIT to BANKADDR_ENDBIT);
row_addr_i <= Bus2IP_Addr(ROWADDR_STARTBIT to ROWADDR_ENDBIT);
COL_WIDTH_ELT_10: if (C_DDR_COL_AWIDTH <= 10) generate
Col_addr <= ZERO_COL_PAD & '0' & Bus2IP_Addr(COLADDR_STARTBIT to COLADDR_ENDBIT) & '0';
end generate COL_WIDTH_ELT_10;
COL_WIDTH_11: if (C_DDR_COL_AWIDTH = 11) generate
-- Support larger memory devices, allow use column address bits beyond A10
-- Make sure A10 is = '0' to disable auto precharge
Col_addr <= ZERO_COL_PAD & Bus2IP_Addr(COLADDR_STARTBIT) & '0' &
Bus2IP_Addr(COLADDR_STARTBIT+1 to COLADDR_ENDBIT) & '0';
end generate COL_WIDTH_11;
-- Zero column address padding
COL_WIDTH_12: if (C_DDR_COL_AWIDTH >= 12 and C_DDR_AWIDTH-2 < C_DDR_COL_AWIDTH) generate
-- Support larger memory devices, allow use column address bits beyond A10
-- Make sure A10 is = '0' to disable auto precharge
Col_addr <= Bus2IP_Addr(COLADDR_STARTBIT to COLADDR_STARTBIT+(C_DDR_COL_AWIDTH-11)) &
'0' & Bus2IP_Addr(COLADDR_STARTBIT+(C_DDR_COL_AWIDTH-10) to COLADDR_ENDBIT) & '0';
end generate COL_WIDTH_12;
-- With column address padding
COL_WIDTH_12_PAD: if (C_DDR_COL_AWIDTH >= 12 and C_DDR_AWIDTH-2 >= C_DDR_COL_AWIDTH) generate
-- Support larger memory devices, allow use column address bits beyond A10
-- Make sure A10 is = '0' to disable auto precharge
Col_addr <= ZERO_COL_PAD & Bus2IP_Addr(COLADDR_STARTBIT to COLADDR_STARTBIT+(C_DDR_COL_AWIDTH-11)) &
'0' & Bus2IP_Addr(COLADDR_STARTBIT+(C_DDR_COL_AWIDTH-10) to COLADDR_ENDBIT) & '0';
end generate COL_WIDTH_12_PAD;
-- when an ACK is received, register the bank address LSB and row address LSB
-- then compare to current bank address LSB and row address LSB to see if in
-- same row and same bank
LAST_BNKRW_PROCESS: process(Clk)
begin
if Clk'event and Clk = '1' then
if Rst = RESET_ACTIVE then
last_row_lsb <= '0';
last_bank_lsb <= '0';
else
last_row_lsb <= row_addr_i(C_DDR_AWIDTH-1);
last_bank_lsb <= bank_addr_i(C_DDR_BANK_AWIDTH-1);
end if;
end if;
end process LAST_BNKRW_PROCESS;
same_row_i <= '1' when last_row_lsb = row_addr_i(C_DDR_AWIDTH-1)
else '0';
same_bank_i <= '1' when last_bank_lsb = bank_addr_i(C_DDR_BANK_AWIDTH-1)
else '0';
XFERSIGS_RE_PROCESS: process(Clk)
begin
if Clk'event and Clk='1' then
if Rst=RESET_ACTIVE then
wrreq_d1 <= '0';
rdreq_d1 <= '0';
else
wrreq_d1 <= Bus2IP_WrReq;
rdreq_d1 <= Bus2IP_RdReq;
end if;
end if;
end process XFERSIGS_RE_PROCESS;
wrreq_re <= Bus2IP_WrReq and not(wrreq_d1);
rdreq_re <= Bus2IP_RdReq and not(rdreq_d1);
-- Generate DDR controller combined CS
comb_Bus2IP_CS_i <= or_reduce (Bus2IP_CS);
-- generate RdAck, WrAck, ErrAck and Retry signals
IP2Bus_WrAddrAck <= Wr_addrAck;
IP2Bus_RdAddrAck <= Rd_addrAck;
IP2Bus_RdAck <= (RdAck and comb_Bus2IP_CS_i);
IP2Bus_data <= Read_data;
-- Removed comb_Bus2IP_CS AND with WrAck to improve timing
IP2Bus_WrAck <= WrAck;
-- ErrAck is set to ground
IP2Bus_ErrAck <= '0';
IPIC_wrdata <= Bus2IP_data;
IPIC_be <= Bus2IP_BE;
-- Generate ECC signals if C_INCLUDE_ECC_SUPPORT = 1
W_ECC_LOGIC: if C_INCLUDE_ECC_SUPPORT = 1 generate
ECC_chk_bits_rd_out <= ECC_chk_bits_rd_in;
ECC_chk_bits_wr_out <= ECC_chk_bits_wr_in;
end generate W_ECC_LOGIC;
TOUTSUP_PROCESS: process(Clk)
begin
if Clk'event and Clk = '1' then
if Rst = RESET_ACTIVE then
IP2Bus_ToutSup <= '0';
else
IP2Bus_ToutSup <= ToutSup;
end if;
end if;
end process TOUTSUP_PROCESS;
RETRY_PROCESS: process(Clk)
begin
if Clk'event and Clk = '1' then
if Rst = RESET_ACTIVE then
ip2bus_retry_i <= '0';
else
ip2bus_retry_i <= Retry or not(Init_done);
end if;
end if;
end process RETRY_PROCESS;
BUSY_PROCESS: process(Clk)
begin
if Clk'event and Clk = '1' then
if Rst = RESET_ACTIVE then
IP2Bus_Busy <= '0';
else
IP2Bus_Busy <= Retry or not(Init_done);
end if;
end if;
end process BUSY_PROCESS;
-- determine pending read and write requests
PEND_REQ_PROCESS: process(Clk)
begin
if Clk'event and Clk='1' then
if Rst = RESET_ACTIVE then
pend_rdreq_i <= '0';
pend_wrreq_i <= '0';
else
if Reset_pendrdreq = RESET_ACTIVE or comb_Bus2IP_CS_i = '0' then
pend_rdreq_i <= '0';
elsif rdreq_re = '1' then
pend_rdreq_i <= '1';
end if;
if Reset_pendwrreq = RESET_ACTIVE or comb_Bus2IP_CS_i = '0' then
pend_wrreq_i <= '0';
elsif wrreq_re = '1' then
pend_wrreq_i <= '1';
end if;
end if;
end if;
end process PEND_REQ_PROCESS;
end imp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -