-- 	Copyright © 2006.	GSI Technology
-- 						Jeff Daugherty
-- 						apps@gsitechnology.com
--  Version: 3.2
--
-- 	FileName: core.vhd
-- 	Unified Sram Core Model for Sync Burst/NBT Sram
--
-- 	Revision History:
--   04/23/02  1.0  1) Created VHDL Core.VHD from Verilog Core.V
--   06/05/02  1.1  1) added new signals, DELAY and tKQX.  These signals will
--                     be used to setup the Clock to Data Invalid  spec.
--   07/17/02  1.2  1) Fixed the JTAG State machine
--                  2) changed the SR register to shift out the MSB and shift
--                     in the LSB
--   09/25/02  1.3  1) Removed all nPE pin features
--                  2) Max number of Core addresses is now dynamic
--                  3) Max width of Core data is now dynamic
--                  4) Removed alll reference of JTAG from core, seperate JTAG
--                     model file: GSI_JTAG
--   01/10/03  1.4  1) Created a Write_Array process to remove race conditions
--                  2) Created a Read_Array proccess to remove race conditions
--   02/20/03  1.5  1) Added We and Waddr to Read_Array sensitivity list.
--                  2) Changed the Read_Array process to look at the last
--                     write's byte write setting and determine where to pull the
--                     read data from, either coherency(byte write on) or the
--                     array(byte write off).
--                  3) Added signal Iscd to fix SCD to the right state for NBT
-- 04/03/03   1.6   1) Added a write clock W_k to trigger the Write_Array function
-- 07/09/03   1.7   1) changed NBT write clock to clock off of we2.
--                  2) Delayed the internal clock by 1ns to control the write
--                  3) changed ce to take into account NBT mode
-- 07/23/03   1.8   1) Changed W_K to ignore the byte writes
-- 08/12/03   1.9   1) updated state machine to include seperate read and write
--                     burst states
--                  2) Changed internal bytewrite signal to ignore nW
-- 10/29/03   2.0   1) updated the state machine, changed reference to suspend
--                     to deselect. 
--                  2) added timing functions to core
-- 03/25/04   2.1   1) Updated state machine.  Added deselect and suspend states
--                  2) Fixed other issues with the state machine
-- 04/28/04   2.2   1) Rearranged state that determins Deselect, Burst and Suspend
--
-- 11/01/05   3.0   1) Created BurstRAM only Model
-- 06/21/06   3.1   1) Added Qswitch to control when the IOs turn on or off
--                  2) Delayed the Qxi inteernal data busses instead of the DQx
--                  external Data busses.
--                  3) Added CLK_i2 to control the setting of Qswitch
--                  4) All these changes removed Negative time issue for some simulations
--07/18/06    3.2   1) Initialized ce and re to 0 so that Qswitch is not
--                     undfined which can cause bus contention on startup.
--
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
library grlib;
use grlib.stdio.all;

ENTITY VHDL_BURST_CORE IS
  GENERIC (
    CONSTANT bank_size : integer ;-- *16M /4 bytes in parallel
    CONSTANT A_size    : integer;
    CONSTANT DQ_size   : integer;
    fname : string := "ram.dat";	-- File to read from
    index : integer := 0);	-- Index
  PORT (
    SIGNAL A     : IN std_logic_vector(A_size - 1 DOWNTO 0);-- address
    SIGNAL DQa   : INOUT std_logic_vector(DQ_size DOWNTO 1);-- byte A data
    SIGNAL DQb   : INOUT std_logic_vector(DQ_size DOWNTO 1);-- byte B data
    SIGNAL DQc   : INOUT std_logic_vector(DQ_size DOWNTO 1);-- byte C data
    SIGNAL DQd   : INOUT std_logic_vector(DQ_size DOWNTO 1);-- byte D data
    SIGNAL DQe   : inout std_logic_vector(DQ_size DOWNTO 1);-- byte E data
    SIGNAL DQf   : inout std_logic_vector(DQ_size DOWNTO 1);-- byte F data
    SIGNAL DQg   : inout std_logic_vector(DQ_size DOWNTO 1);-- byte G data
    SIGNAL DQh   : inout std_logic_vector(DQ_size DOWNTO 1);-- byte H data
    SIGNAL nBa   : IN std_logic;-- bank A write enable
    SIGNAL nBb   : IN std_logic;-- bank B write enable
    SIGNAL nBc   : IN std_logic;-- bank C write enable
    SIGNAL nBd   : IN std_logic;-- bank D write enable
    SIGNAL nBe   : IN std_logic;-- bank E write enable
    SIGNAL nBf   : IN std_logic;-- bank F write enable
    SIGNAL nBg   : IN std_logic;-- bank G write enable
    SIGNAL nBh   : IN std_logic;-- bank H write enable
    SIGNAL CK    : IN std_logic;-- clock
    SIGNAL nBW   : IN std_logic;-- byte write enable
    SIGNAL nGW   : IN std_logic;-- Global write enable
    SIGNAL nE1   : IN std_logic;-- chip enable 1
    SIGNAL E2    : IN std_logic;-- chip enable 2
    SIGNAL nE3   : IN std_logic;-- chip enable 3
    SIGNAL nG    : IN std_logic;-- output enable
    SIGNAL nADV  : IN std_logic;-- Advance not / load
    SIGNAL nADSC : IN std_logic;
    SIGNAL nADSP : IN std_logic;
    SIGNAL ZZ    : IN std_logic;-- power down
    SIGNAL nFT   : IN std_logic;-- Pipeline / Flow through
    SIGNAL nLBO  : IN std_logic;-- Linear Burst Order
    SIGNAL SCD   : IN std_logic;
    SIGNAL HighZ : std_logic_vector(DQ_size downto 1);
    SIGNAL tKQ   : time;
    SIGNAL tKQX  : time);
END VHDL_BURST_CORE;

LIBRARY GSI;
LIBRARY Std;
ARCHITECTURE GSI_BURST_CORE OF VHDL_BURST_CORE IS
  USE GSI.FUNCTIONS.ALL;
  USE Std.textio.ALL;
  TYPE MEMORY_0 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_1 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_2 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_3 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_4 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_5 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_6 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
  TYPE MEMORY_7 IS ARRAY (0 TO bank_size) OF std_logic_vector(DQ_size - 1 DOWNTO 0);
--   ******** Define Sram Operation Mode    **********************
  shared variable bank0 : MEMORY_0 ;
  shared variable bank1 : MEMORY_1 ;
  shared variable bank2 : MEMORY_2 ;
  shared variable bank3 : MEMORY_3 ;
  shared variable bank4 : MEMORY_4 ;
  shared variable bank5 : MEMORY_5 ;
  shared variable bank6 : MEMORY_6 ;
  shared variable bank7 : MEMORY_7 ;
-- ---------------------------------------------------------------
--   	Gated SRAM Clock
-- ---------------------------------------------------------------
  SIGNAL clk_i : std_logic;
  SIGNAL clk_i2 : std_logic;
-- ---------------------------------------------------------------
--   	Combinatorial Logic
-- ---------------------------------------------------------------
  SIGNAL E     : std_logic;-- internal chip enable
  SIGNAL ADV   : std_logic;-- internal address advance
  SIGNAL ADS   : std_logic;
  SIGNAL ADSP  : std_logic;
  SIGNAL ADSC  : std_logic;
  SIGNAL W     : std_logic;
  SIGNAL R     : std_logic;
  SIGNAL W_k   : std_logic;
  SIGNAL R_k   : std_logic;
  SIGNAL BW    : std_logic_vector(7 DOWNTO 0);-- internal byte write enable
  SIGNAL Qai   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- read data
  SIGNAL Qbi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qci   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qdi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qei   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qfi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qgi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Qhi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- read data
  SIGNAL Dai   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- write data
  SIGNAL Dbi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Dci   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Ddi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Dei   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Dfi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Dgi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- .
  SIGNAL Dhi   : std_logic_vector(DQ_size - 1 DOWNTO 0);-- write data
  SIGNAL bwi   : std_logic_vector(7 DOWNTO 0);
  SIGNAL addr0 : std_logic_vector(A_size - 1 DOWNTO 0);-- saved address
  SIGNAL addr1 : std_logic_vector(A_size - 1 DOWNTO 0);-- address buffer 1
  SIGNAL baddr : std_logic_vector(A_size - 1 DOWNTO 0);-- burst memory address
  SIGNAL waddr : std_logic_vector(A_size - 1 DOWNTO 0);-- write memory address
  SIGNAL raddr : std_logic_vector(A_size - 1 DOWNTO 0);-- read memory address
  SIGNAL bcnt  : std_logic_vector(1 DOWNTO 0)  := to_stdlogicvector(0, 2);-- burst counter
  SIGNAL we0   : std_logic := '0';
  SIGNAL re0   : std_logic := '0';
  SIGNAL re1   : std_logic := '0';
  SIGNAL re2   : std_logic := '0';
  SIGNAL ce0   : std_logic := '0';
  SIGNAL ce1   : std_logic := '0';
  SIGNAL ce    : std_logic := '0';
  SIGNAL re    : std_logic := '0';
  SIGNAL oe    : std_logic;
  SIGNAL we    : std_logic;
  SIGNAL Qswitch: std_logic ;
  SIGNAL state : string (9 DOWNTO 1) := "IDLE     ";

  SIGNAL Check_Time : time   := 1 ns;
  SIGNAL DELAY      : time   := 1 ns;
  SIGNAL GUARD      : boolean:= TRUE;

--  TIMING FUNCTIONS
  function POSEDGE (SIGNAL s : std_ulogic) return BOOLEAN IS
  begin
    RETURN (s'EVENT AND ((To_X01(s'LAST_VALUE) = '0') OR (s = '1')));
  end; 
  function NEGEDGE (SIGNAL s : std_ulogic) return BOOLEAN IS
  begin
    RETURN (s'EVENT AND ((To_X01(s'LAST_VALUE) = '1') OR (s = '0')) );
  end; 
-- END TIMING FUNCTIONS
  
  PROCEDURE shiftnow (SIGNAL addr1 : INOUT std_logic_vector(A_size - 1 DOWNTO 0);
                      SIGNAL re2   : INOUT std_logic;
                      SIGNAL re1   : INOUT std_logic;
                      SIGNAL ce1   : INOUT std_logic;
                      SIGNAL Dai   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dbi   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dci   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Ddi   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dei   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dfi   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dgi   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0);
                      SIGNAL Dhi   : INOUT std_logic_vector(DQ_size - 1 DOWNTO 0))
  IS
  BEGIN
    addr1 <= baddr;
    re2 <= re1;
    re1 <= re0;
    ce1 <= ce0;
    Dai <= DQa;
    Dbi <= DQb;
    Dci <= DQc;
    Ddi <= DQd;
    Dei <= DQe;
    Dfi <= DQf;
    Dgi <= DQg;
    Dhi <= DQh;
  END;

BEGIN
  PROCESS
  BEGIN
    WAIT UNTIL POSEDGE(CK);
    clk_i  <= NOT ZZ after 100 ps;
    clk_i2 <= NOT ZZ after 200 ps;
    WAIT UNTIL NEGEDGE(CK);
    clk_i  <= '0' after 100 ps;
    clk_i2 <= '0' after 200 ps;
  END PROCESS;

-- ---------------------------------------------------------------
--   	State Machine
-- ---------------------------------------------------------------
  st : PROCESS
    variable tstate : string(9 DOWNTO 1) :="DESELECT ";
    variable twe0 : std_logic := '0';
    variable tre0 : std_logic := '0';
    variable tce0 : std_logic := '0';
  BEGIN
    WAIT UNTIL POSEDGE(CK);
    CASE state IS
      WHEN "DESELECT " =>
        if (E = '1') then
--Checking for ADSC Control
          if (ADSC = '1') then
            shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
            tre0 := R;
            twe0 := W;
            tce0 := '1';
            addr0 <= A;
            bwi <= BW;
            bcnt <= to_stdlogicvector(0, 2);
            tstate := "NEWCYCLE ";
          end if;
--  Checking for ADSP Control
          if (ADSP = '1') then
            shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
            tre0 := R;
            tce0 := '1';
            addr0 <= A;
            bcnt <= to_stdlogicvector(0, 2);
            tstate := "LATEWRITE";
          end if;
        END IF;
-- Checking for Deselect
        if ((E /= '1' and ADSC = '1') or (nADSP and (E2 = '0' or nE3 = '1'))) then
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tstate := "DESELECT ";
          twe0 := '0';
          tre0 := '0';
          tce0 := '0';
        END IF;
-- **************************************************
      WHEN "NEWCYCLE " | "BURST    " | "SUSPBR   " | "LATEWRITE" =>
--Checking for ADSC Control
        if (ADSC = '1') then
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tre0 := R;
          twe0 := W;
          tce0 := '1';
          addr0 <= A;
          bwi <= BW;
          bcnt <= to_stdlogicvector(0, 2);
          tstate := "NEWCYCLE ";
        end if;
--  Checking for ADSP Control
        if (ADSP = '1') then
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tre0 := R;
          tce0 := '1';
          addr0 <= A;
          bcnt <= to_stdlogicvector(0, 2);
          tstate := "LATEWRITE";
        end if;
-- Checking for Deselect
        if ((E /= '1' and nADSC = '0') or (nADSP = '0' and (E2 = '0' or nE3 = '1'))) then
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tstate := "DESELECT ";
          twe0 := '0';
          tre0 := '0';
          tce0 := '0';
        end if;
--  Checking for Burst Start
        if (ADSC = '0' and ADSP = '0' AND ADV = '1') THEN
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tstate := "BURST    ";
          if we0 = '1' then
            twe0 := W;
            tre0 := '0';
            bwi <= BW;
          end if;
          if re0 = '1' then
            twe0 := '0';
            tre0 := R;
          end if;
          tce0 := '1';
          bcnt <= to_stdlogicvector(bcnt + "01", 2);
        end if;
--  Checking for a Suspended Burst
        if (ADSC = '0' and ADSP = '0' AND ADV = '0') THEN
          shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
          tstate := "SUSPBR   ";
          if we0 = '1' or W = '1' then
            twe0 := W;
            tre0 := '0';
            re1 <= '0';
            bwi <= BW;
          elsif re0 = '1' then
            twe0 := '0';
            tre0 := R;
          end if;
          tce0 := '1';
        end if;
      WHEN OTHERS =>
        shiftnow(addr1, re2, re1, ce1, Dai, Dbi, Dci, Ddi, Dei, Dfi, Dgi, Dhi);
        tstate := "DESELECT ";
        twe0 := '0';
        tre0 := '0';
        tce0 := '0';
        bcnt <= to_stdlogicvector(0, 2);
    END CASE;
    state <= tstate;
    we0 <= twe0;
    re0 <= tre0;
    ce0 <= tce0;
  END PROCESS;

 RAMINIT : process
 -- variable MEMA : MEM;
  variable L1 : line;
--  variable FIRST : boolean := true;
  variable ADR : std_logic_vector(19 downto 0);
  variable BUF : std_logic_vector(31 downto 0);
  variable CH : character;
  variable ai : integer := 0;
  variable len : integer := 0;
  file TCF : text open read_mode is fname;
  variable rectype : std_logic_vector(3 downto 0);
  variable recaddr : std_logic_vector(31 downto 0);
  variable reclen  : std_logic_vector(7 downto 0);
  variable recdata : std_logic_vector(0 to 16*8-1);

  begin
    if fname /= "" then
--      if clear = 1 then MEMA := (others => X"00"); end if;
      L1:= new string'("");	--'
      while not endfile(TCF) loop
        readline(TCF,L1);
        if (L1'length /= 0) then	--'
          while (not (L1'length=0)) and (L1(L1'left) = ' ') loop
            std.textio.read(L1,CH);
          end loop;

          if L1'length > 0 then	--'
            read(L1, ch);
            if (ch = 'S') or (ch = 's') then
              hread(L1, rectype);
              hread(L1, reclen);
	      len := to_integer(reclen)-1;
	      recaddr := (others => '0');
	      case rectype is 
		when "0001" =>
                  hread(L1, recaddr(15 downto 0));
		when "0010" =>
                  hread(L1, recaddr(23 downto 0));
		when "0011" =>
                  hread(L1, recaddr);
		  recaddr(31 downto 20) := (others => '0');
		when others => next;
	      end case;
              hread(L1, recdata);
--              if index = 6 then
--	        ai := to_integer(recaddr);
-- 	        for i in 0 to 15 loop
--                  MEMA(ai+i) := recdata((i*8) to (i*8+7));
--	        end loop;
--              elsif (index = 4) or (index = 5) then
	        ai := to_integer(recaddr)/4;
 	        for i in 0 to 3 loop
                    bank0(ai+i) := '0' & recdata((i*32+index*16) to (i*32+index*16+7));
                    bank1(ai+i) := '0' & recdata((i*32+index*16+8) to (i*32+index*16+15));
	        end loop;
--              else 
--	        ai := conv_integer(recaddr)/4;
-- 	        for i in 0 to 3 loop
--                  MEMA(ai+i) := recdata((i*32+index*8) to (i*32+index*8+7));
--	        end loop;
--              end if;
            end if;
          end if;
        end if;
      end loop;
    end if;
    wait;
  end process;

-- ---------------------------------------------------------------
--               Data IO Logic
-- ---------------------------------------------------------------
  Write_Array: process (W_k)
  begin  -- process Write_Array
    IF (POSEDGE(W_k)) THEN
      IF (we = '1') THEN
        IF bwi(0) = '1' THEN
          bank0(to_integer(waddr)) := Dai;
        END IF;
        IF bwi(1) = '1' THEN
          bank1(to_integer(waddr)) := Dbi;
        END IF;
        IF bwi(2) = '1' THEN
          bank2(to_integer(waddr)) := Dci;
        END IF;
        IF bwi(3) = '1' THEN
          bank3(to_integer(waddr)) := Ddi;
        END IF;
        IF bwi(4) = '1' THEN
          bank4(to_integer(waddr)) := Dei;
        END IF;
        IF bwi(5) = '1' THEN
          bank5(to_integer(waddr)) := Dfi;
        END IF;
        IF bwi(6) = '1'  THEN
          bank6(to_integer(waddr)) := Dgi;
        END IF;
        IF bwi(7) = '1'  THEN
          bank7(to_integer(waddr)) := Dhi;
        END IF;
      END IF;
    END IF;
  end process Write_Array;

  Read_Array: process (r_k)
  begin  -- process Read_Array
    IF (we = '0') then
      Qai <= transport bank0(to_integer(raddr)) after DELAY - 200 ps;
      Qbi <= transport bank1(to_integer(raddr)) after DELAY - 200 ps;
      Qci <= transport bank2(to_integer(raddr)) after DELAY - 200 ps;
      Qdi <= transport bank3(to_integer(raddr)) after DELAY - 200 ps;
      Qei <= transport bank4(to_integer(raddr)) after DELAY - 200 ps;
      Qfi <= transport bank5(to_integer(raddr)) after DELAY - 200 ps;
      Qgi <= transport bank6(to_integer(raddr)) after DELAY - 200 ps;
      Qhi <= transport bank7(to_integer(raddr)) after DELAY - 200 ps;
    END IF;
end process Read_Array;

-- check it -t option is active and set correctly
time_ck : process (CLK_i)
begin
  check_time <= CK'last_event;
  assert check_time /= 0 ns report "Resolution needs to be set to 100ps for modelSIM use vsim -t 100ps <>" severity FAILURE;
end process time_ck;

ADS_SET : process (CLK_i)
begin
  if posedge(clk_i) then
    ADS  <= ADSP OR ADSC;
  end if;
end process ADS_SET;

q_switch : process (CLK_i2)
begin                                 --read clock controls outputs
  Qswitch <= transport re and ce after DELAY - 200 ps;
end process q_switch;


E     <= (NOT nE1 AND E2 AND NOT nE3);
ADV   <=  not nADV;
ADSP  <=  NOT nADSP AND ( E2 or NOT nE3);
ADSC  <=  NOT nADSC AND ( not nE1 or E2 or NOT nE3);
W     <= (NOT nGW OR NOT nBW );
W_k   <=((NOT ADSP or not ADSC) AND (NOT nGW OR NOT nBW )) and clk_i after 100 ps;
R     <=  nGW and nBW;
R_k   <= (TERNARY((ADS or ADV) and not W, TERNARY( nFT, re1, re0), '0') and clk_i) after 100 ps;
BW(0) <=  not nGW or (NOT nBa and not nBW);
BW(1) <=  not nGW or (NOT nBb and not nBW);
BW(2) <=  not nGW or (NOT nBc and not nBW);
BW(3) <=  not nGW or (NOT nBd and not nBW);
BW(4) <=  not nGW or (NOT nBe and not nBW);
BW(5) <=  not nGW or (NOT nBf and not nBW);
BW(6) <=  not nGW or (NOT nBg and not nBW);
BW(7) <=  not nGW or (NOT nBh and not nBW);
baddr <=  to_stdlogicvector(TERNARY(nLBO, addr0(A_size - 1 DOWNTO 2) & (bcnt(1) XOR addr0(1)) &
                                   (bcnt(0) XOR addr0(0)), addr0(A_size - 1 DOWNTO 2) & (addr0(1 DOWNTO 0) + bcnt)), A_size);

waddr <=  to_stdlogicvector(TERNARY(not ADV, addr0, baddr), A_size);
raddr <=  to_stdlogicvector(TERNARY(nFT, addr1, baddr), A_size);
we    <=  we0;
re    <=  TERNARY(nFT, re1, re0);
ce    <= (TERNARY(not SCD AND re2 = '1', ce1, ce0));
oe    <=  re AND ce;

DELAY <=  TERNARY(nG OR not ((we and re) or oe) OR ZZ, tKQ, tKQX);

DQa   <=  GUARDED TERNARY(Qswitch, Qai, HighZ);
DQb   <=  GUARDED TERNARY(Qswitch, Qbi, HighZ);
DQc   <=  GUARDED TERNARY(Qswitch, Qci, HighZ);
DQd   <=  GUARDED TERNARY(Qswitch, Qdi, HighZ);
DQe   <=  GUARDED TERNARY(Qswitch, Qei, HighZ);
DQf   <=  GUARDED TERNARY(Qswitch, Qfi, HighZ);
DQg   <=  GUARDED TERNARY(Qswitch, Qgi, HighZ);
DQh   <=  GUARDED TERNARY(Qswitch, Qhi, HighZ);
END GSI_BURST_CORE;

