Project

General

Profile

Memcpy data transfer error from FPGA address space to CME... » EMIFA_ifaceMC.vhd

Michele Canepa, 01/21/2014 03:23 AM

 
--- Title: EMIFA_ifaceMC.vhd
--- Description:
---
--- EMIFA interface for OMAP-L138 series CPU platform MODIFIED BY MICHELE CANEPA

--- Date: 18/04/2013
--- Version: 1.00
--- Revisions:
--- 1.00 - Baseline.

library WORK;
library IEEE;
library UNISIM;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use UNISIM.VCOMPONENTS.ALL;
use WORK.MityDSP_L138_pkg.ALL;

entity EMIFA_ifaceMC is
generic (
DECODE_BITS : integer range 1 to 9 := 5;
DECODE_BITS4 : integer range 1 to 5 := 5; -- Custom decode bits. Address space is CS4
. CONFIG : string := "UNKNOWN" -- "MityDSP_L138"
);
port (
ema_clk : in std_logic; -- conditioned by a DCM
-- EMIFA direct-connect signals
i_ema_cs0_n : in std_logic; -- Reserved for SDRAM controller, not used
i_ema_cs2_n : in std_logic; -- Reserved core space, not used
i_ema_cs3_n : in std_logic; -- NAND FLASH space, not used
i_ema_cs4_n : in std_logic; -- Any CPU core space
i_ema_cs5_n : in std_logic; -- Any CPU core space
i_ema_oe_n : in std_logic;
i_ema_we_n : in std_logic;
o_ema_wait_n : out std_logic_vector(1 downto 0);
t_ema_wait : out std_logic;
i_ema_d : in std_logic_vector(15 downto 0);
o_ema_d : out std_logic_vector(15 downto 0);
t_ema_d : out std_logic;
i_ema_a : in std_logic_vector(13 downto 0);
i_ema_ba : in std_logic_vector(1 downto 0);
i_ema_wen_dqm : in std_logic_vector(1 downto 0);
i_ema_cas : in std_logic; -- reserved for SDRAM controller, not used
i_ema_ras : in std_logic; -- reserved for SDRAM controller, not used
i_ema_sdcke : in std_logic; -- reserved for SDRAM controller, not used
i_ema_rnw : in std_logic; -- reserved for SDRAM controller, not used
-- FPGA core interface signals
o_core_be : out std_logic_vector(1 downto 0);
o_core_addr : out std_logic_vector(5 downto 0);
o_core_addr4 : out std_logic_vector(9 downto 0);--Added to give 10 bits addressing.

o_core_cs5 : out std_logic_vector((2**DECODE_BITS)-1 downto 0);
o_core_cs4 : out std_logic_vector((2**DECODE_BITS4)-1 downto 0);-- Decode bits are custom.
o_core_edi : out std_logic_vector(15 downto 0);
i_core_edo5 : in bus16_vector((2**DECODE_BITS)-1 downto 0);
i_core_edo4 : in bus16_vector((2**DECODE_BITS)-1 downto 0);
o_core_rd : out std_logic;
o_core_wr : out std_logic
);
end EMIFA_ifaceMC;

architecture rtl of EMIFA_ifaceMC is

signal be : std_logic_vector(1 downto 0) := (others=>'1');
signal ea : std_logic_vector(14 downto 0) := (others=>'0');
signal cs5_n : std_logic := '1';
signal cs4_n : std_logic := '1';
signal oe_n : std_logic := '1';
signal we_n : std_logic := '1';
signal oe_dly : std_logic := '1';
signal we_dly : std_logic := '1';
signal edi : std_logic_vector(15 downto 0);

-- Caution! Despite disabling shift-register extraction on these signals,
-- setting Global Optimization in Map can still optimize them back into SRL's.
attribute shreg_extract : string;
attribute shreg_extract of be : signal is "no";
attribute shreg_extract of ea : signal is "no";
attribute shreg_extract of edi : signal is "no";

signal cs5 : std_logic_vector((2**DECODE_BITS)-1 downto 0) := (others=>'0');
signal cs4 : std_logic_vector((2**DECODE_BITS4)-1 downto 0) := (others=>'0');-- Modified decode bits
signal rd : std_logic := '0';
signal wr : std_logic := '0';

signal ema_d : std_logic_vector(15 downto 0) := (others=>'0');
attribute shreg_extract of ema_d : signal is "no";

begin -- architecture: rtl

-- register input signals
process (ema_clk)
begin
if rising_edge(ema_clk) then
-- capture byte-enables and address bus
be <= i_ema_wen_dqm;
ea <= i_ema_a & i_ema_ba(1);
-- capture control signals
cs5_n <= i_ema_cs5_n; -- These control signals are NOT inverted here
cs4_n <= i_ema_cs4_n; -- so that the registers can be packed into IOB's.
oe_n <= i_ema_oe_n;
we_n <= i_ema_we_n;
-- one-clock delayed registers
oe_dly <= oe_n;
we_dly <= we_n;
-- capture the data bus
edi <= i_ema_d;
end if;
end process;

-- address decode, ARM chip select space
process (cs5_n, ea)
begin
if cs5_n='0' then
for count in 0 to (2**DECODE_BITS)-1 loop
if ea(DECODE_BITS+5 downto 6) = conv_std_logic_vector(count, DECODE_BITS) then
cs5(count) <= '1';
else
cs5(count) <= '0';
end if;
end loop;
else
cs5 <= (others=>'0');
end if;
end process;

-- address decode, DSP chip select space, modified to be 1024 addresses per module.
process (cs4_n, ea)
begin
if cs4_n='0' then
for count in 0 to (2**DECODE_BITS4)-1 loop
if ea(DECODE_BITS4 +9 downto 10) = conv_std_logic_vector(count, DECODE_BITS4) then
cs4(count) <= '1';
else
cs4(count) <= '0';
end if;
end loop;
else
cs4 <= (others=>'0');
end if;
end process;

-- read/write strobes
rd <= oe_n and not oe_dly;
wr <= not we_n and we_dly;

-- register output signals
process (ema_clk)
begin
if rising_edge(ema_clk) then
o_core_be <= not be; -- invert to positive logic
o_core_addr <= ea(5 downto 0);
o_core_addr4<= ea(9 downto 0); --Modified to 10 bit.
o_core_cs5 <= cs5;
o_core_cs4 <= cs4;
o_core_rd <= rd;
o_core_wr <= wr;
o_core_edi <= edi;
end if;
end process;

-- multiplex module data-out busses
process (ema_clk)
variable ored : std_logic_vector(15 downto 0);
begin
if rising_edge(ema_clk) then
ored := x"0000";
for count in 0 to (2**DECODE_BITS)-1 loop
ored := ored or i_core_edo5(count) or i_core_edo4(count);
end loop;
ema_d <= ored; -- TODO - mux in other "custom" CS spaces???
o_ema_d <= ema_d; -- extra clock should allow packing in IOB
end if;
end process;

t_ema_d <= '0' when (i_ema_oe_n='0' and (i_ema_cs5_n='0' or i_ema_cs4_n='0')) else '1';
t_ema_wait <= '1';

end rtl;
(1-1/3)