APS-X84 VHDL/FPGA SYNTHESIS TUTORIAL

LAB #4
VHDL Counter/ Divider

In this Lab we will synthesize a simple circuit which will take the output of the X84 boards 555 timer circuit and using a counter, will divide down the clock by rates which will be programmable via the on board 8255 programmable latchs. We will use an eight bit value (0-255) as the programmable divider range.

The APS-X84 has an on board 555 timer circuit which is made up of U6,R6,R4,C1,C18, and JP7. The function of JP7 is discussed in section 2.1 of the User's Guide and needs to be on. U6 is a 555 timer chip. The R4, R6 and C18 values of 51K,22K & .01uf are used to set the time constant of the oscillator using the equation shown below:

Charge Time= T1= 1.386*(R1C1)= 1.386*(51000*.00000001)=.00070686 secs

Frequency = 1/cycle time = 1/.00070686=1414=1.414Khz

This timer circuit can be used as a slow timer. Coupled with relatively small counter/dividers it can be used to give approximate timing for such things as blinking LEDs, delays and waits which might be in seconds. If we want to use a relatively fast oscillator in our circuit it would take a large divider to get pulse in the seconds range.

Since the TIMER circuit puts out a 1.414Khz rate that means that our clock changes states at 1,414 times per second. This is to fast to see if we sent it directly to the X84 Utility LED. We could divide down the LED with our 8 bit value from our 8255 output pins (input pins to FPGA) which will set up the terminal count of a VHDL counter we could create which will look something like this: l

library IEEE; use IEEE.std_logic_1164.all; library METAMOR; use METAMOR.attributes.all; library SYNOPSYS; use SYNOPSYS.std_logic_arith.all; use SYNOPSYS.std_logic_unsigned.all; library PN_PAK; use PN_PAK.PN_PAK.all; ENTITY X84DEMO IS PORT ( The555In: IN std_logic; DivSigOut: BUFFER std_logic; DivCntIn: IN std_logic_vector(7 downto 0) ); attribute pinnum of DivCntIn : signal is "P10,P9,P8,P7,P6,P5,P4,P3"; attribute pinnum of DivSigOut : signal is "P35"; attribute pinnum of The555In : signal is "P24"; END X84DEMO; ---------------------------------------------------------------- ---------------------------------------------------------------- ARCHITECTURE behave OF X84DEMO IS SIGNAL Count: INTEGER RANGE 0 TO 255; BEGIN DIVIDER: PROCESS BEGIN WAIT UNTIL The555In'EVENT AND The555In = '1'; -- wait til rising edge Count <= Count +1; -- increment counter IF Count >= slvect2int(DivCntIn) THEN DivSigOut <= NOT DivSigOut; -- toggle LED on X84 Count <= 0; -- reinitialize counter END IF; END PROCESS; END behave;

From the highlighted code segment you can see that when ever DivCntIn (8 bit input count latched into our FPGA pins from 8255) is greater than or equal to our COUNTER value (Count) Then we toggle our X84 utility LED whose pin is named DivSigOut. This counter circuit works fine except for one thing. The maximum divided value 1414/255 = 5.54.... This is still too fast for us to observe on the LED. By adding the additional code highlighted below we cause the counter to wait Multiplier counts before incrementing our Count value. This will yield a range of values more suitable for viewing on the LED.

library IEEE; use IEEE.std_logic_1164.all; library METAMOR; use METAMOR.attributes.all; library SYNOPSYS; use SYNOPSYS.std_logic_arith.all; use SYNOPSYS.std_logic_unsigned.all; library PN_PAK; use PN_PAK.PN_PAK.all; ENTITY X84DEMO IS PORT ( The555In: IN std_logic; DivSigOut: BUFFER std_logic; DivCntIn: IN std_logic_vector(7 downto 0) ); attribute pinnum of DivCntIn : signal is "P10,P9,P8,P7,P6,P5,P4,P3"; attribute pinnum of DivSigOut : signal is "P35"; attribute pinnum of The555In : signal is "P24"; END X84DEMO; ---------------------------------------------------------------- ---------------------------------------------------------------- ARCHITECTURE behave OF X84DEMO IS SIGNAL Count: INTEGER RANGE 0 TO 255; SIGNAL MultCnt: INTEGER RANGE 0 TO 255; -- Divide input by Multiplier times the DivCntIn value CONSTANT Multiplier : INTEGER RANGE 0 to 255 := 10; BEGIN DIVIDER: PROCESS BEGIN WAIT UNTIL The555In'EVENT AND The555In = '1'; -- wait til rising edge IF MultCnt >= Multiplier THEN Count <= Count +1; -- increment counter MultCnt <= 0; -- reinitialize Multiplier Counter ELSE MultCnt <= MultCnt + 1; -- Output divided pulse; END IF; IF Count >= slvect2int(DivCntIn) THEN DivSigOut <= NOT DivSigOut; -- toggle LED on X84 Count <= 0; -- reinitialize counter END IF; END PROCESS; END behave;

Click HERE if you wish to return to the AND GATE lab to refamiliarize yourself with the following processes:

1) Open the X84Lab4 project in the Foundation Software projects.

2) Insure the project has been properly synthesized and routed.

3) Insure the X84Lab4.rbt file from the latest route version is stored in the X84Lab4C directory where the X84Lab4.exe file is located.

4) Execute the X84Lab4.exe program and you should see the following screen:

By typing in different values you will be able to make the LED blink at different rates.