---------------------------------------------------------------
-- 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;