next up previous contents
Next: G Other Files Up: F VHDL Source Code Previous: F.2 natasha.v

F.3 pointers.v

 

---------------------------------------------------------------
-- P O I N T E R S . V
-- $Id: pointers.v,v 1.3 1995/04/25 07:35:41 sharring Exp $
-- Scott Harrington
-- Duke EE Project Spring/Fall 1994
-- Address Tracing System
--
-- Entity pointers is used by Boris to update the read and write
-- pointers depending on Boris' mode and trigger.
--
-- Use LFSR counters since binary count sequence is not needed.
-- For 15 bit LFSR the XNOR feedback is from the two most significant
-- output bits.  See Xilinx Data Book p. 9-24.
----------------------------------------------------------------

-----------------------
-- I/O descriptions: --
-----------------------

--  Clk: Boris clock (period > half SRAM access time)
--  Ext: selects extract/record mode, synched to CLK
--  Trig: falling edge triggers read/write to SRAM, then ptr increment
--  CS: chip select (enables counting)
--  Almost_Full: WP equals constant threshold word
--  Full: WP and RP became equal in record mode
--  Empty: WP and RP became equal in extract mode
--  Addr: either WP or RP depending on mode

ENTITY pointers IS
    PORT (
        Clk: IN vlbit;
        Trig: IN vlbit;
        Ext: IN vlbit;
        CS: IN vlbit;
        Full: BUFFER vlbit;
        Almost_Full: BUFFER vlbit;
        Empty: BUFFER vlbit;
        Addr: BUFFER vlbit_1d(14 downto 0)
        );
END pointers;

ARCHITECTURE behav OF pointers IS

SIGNAL triglast: vlbit;
SIGNAL trigfalling: vlbit;
SIGNAL extlast: vlbit;
SIGNAL extrising: vlbit;
SIGNAL extfalling: vlbit;
SIGNAL extchanging: vlbit;

-- should we check for full condition?  Not if we just reset wp=rp=0
SIGNAL checkfull: vlbit;
SIGNAL nextaf: vlbit;

-- these become synchronous clear and clock enable inputs to counters
SIGNAL resetrp: vlbit;
SIGNAL resetwp: vlbit;
SIGNAL incrrp: vlbit;
SIGNAL incrwp: vlbit;

SIGNAL rp: vlbit_1d(14 downto 0);
SIGNAL wp: vlbit_1d(14 downto 0);
SIGNAL nextrp: vlbit_1d(14 downto 0);
SIGNAL nextwp: vlbit_1d(14 downto 0);

SIGNAL rpfeedback: vlbit;
SIGNAL wpfeedback: vlbit;

SIGNAL equal: vlbit_1d(7 downto 0);
-- equal(i) is 1 when
-- wp(2i)==rp(2i) and wp(2i+1)==rp(2i+1) and equal(i+1)==1
-- Thus equal(0) = 1 if wp == rp.
SIGNAL equalhiwater: vlbit_1d(7 downto 0);
-- similar to equal except compares WP with hiwater constant
-- equalhiwater(0) = 1 if WP == hiwater
-- The reasoning behind comparing two bits at a time is to convince
-- synthesis to put more stuff into each CLB function generator.

BEGIN

    -- Determine changes in Ext and Trig states
    
    InputChangeProc : PROCESS
    BEGIN
        WAIT UNTIL Clk'EVENT AND Clk = '1';
    triglast <= Trig;
    extlast <= Ext;
    END PROCESS;
    
    trigfalling <= triglast AND NOT Trig;
    extfalling <= extlast AND NOT Ext;
    extrising <= NOT extlast AND Ext;
    extchanging <= extrising OR extfalling;

    -- Reset RP when entering read mode or write mode
    resetrp <= extchanging;
    
    -- Reset WP when entering write mode
    resetwp <= extfalling;

    incrrp <=   Ext   AND trigfalling AND NOT Empty;
    incrwp <= NOT Ext AND trigfalling AND NOT Full;

    -- Implement LFSR counters
    -- Note LFSR lock-up state (all-ones) should never happen
    wpfeedback <= NOT (wp(14) XOR wp(13));
    rpfeedback <= NOT (rp(14) XOR rp(13));

    nextwp(14 downto 0) <= wp(13 downto 0) & wpfeedback;
    nextrp(14 downto 0) <= rp(13 downto 0) & rpfeedback;

    LfsrProc : PROCESS
    BEGIN
        WAIT UNTIL Clk'EVENT AND Clk = '1';
    IF resetwp = '1' THEN
        wp <= "000000000000000";
    ELSIF incrwp = '1' THEN
        wp <= nextwp;
    END IF;
    IF resetrp = '1' THEN
        rp <= "000000000000000";
    ELSIF incrrp = '1' THEN
        rp <= nextrp;
    END IF;
    END PROCESS;

    FullCompareProc : PROCESS(wp, rp, equal)
    BEGIN
        equal(7) <= NOT (wp(14) XOR rp(14));
        FOR i IN 0 to 6 LOOP
            equal(i) <= NOT (wp(2*i+1) XOR rp(2*i+1)) AND
                    NOT (wp(2*i) XOR rp(2*i)) AND
                    equal(i+1);
        END LOOP;
    END PROCESS;

    HiwaterCompareProc : PROCESS(wp, equalhiwater)
    -- Useful hiwater constants (from lfsr.c output):
    -- .1% 2047  = 000011111111111
    -- 25% 16444 = 100000000111100
    -- 50% 16320 = 011111111000000
    -- 75% 17400 = 100001111111000
    -- 90% 1313  = 000010100100001
    -- 95% 4913  = 001001100110001
    CONSTANT hiwater: vlbit_1d(14 downto 0) := "000010100100001";
    BEGIN
        equalhiwater(7) <= NOT (wp(14) XOR hiwater(14));
        FOR i IN 0 to 6 LOOP
            equalhiwater(i) <= NOT (wp(2*i+1) XOR hiwater(2*i+1)) AND
                    NOT (wp(2*i) XOR hiwater(2*i)) AND
                    equalhiwater(i+1);
        END LOOP;
    END PROCESS;

    -- Do not check for full condition right after resetting rp=wp=0
    -- Start checking after the first trigfalling (which causes wp++)
    CheckFullProc : PROCESS(Clk, trigfalling, resetwp)
    BEGIN
        IF resetwp = '1' THEN
        checkfull <= '0';
    ELSIF (Clk'EVENT AND Clk = '1' AND trigfalling = '1') THEN
        checkfull <= '1';
    END IF;
    END PROCESS;

    -- Clock some new full/empty flags
    nextaf <= NOT resetwp AND (equalhiwater(0) OR Almost_Full);
    
    FlagProc : PROCESS
    BEGIN
        WAIT UNTIL Clk'EVENT AND Clk = '1';
    Empty <= equal(0) AND Ext;
    Full <= checkfull AND equal(0) AND NOT Ext;
    Almost_Full <= nextaf;
    END PROCESS;

    -- Multiplex WP and RP to the memory address lines
    Addr <= rp WHEN Ext = '1' ELSE wp;

END behav;


Scott E. Harrington
Sat Apr 29 18:56:25 EDT 1995