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