|
Counters use sequential logic to count clock pulses. A counter can be implemented implicitly with a Register Inference. The Quartus® II software can infer a counter from an If Statement that specifies a clock edge together with logic that adds or subtracts a value from the signal or variable. The If Statement and additional logic should be inside a Process Statement.
The following example shows a VHDL Design File (.vhd) that includes a variety of 8-bit counters,
controlled by the clk
, clear
, ld
, d
, enable
, and up_down
signals, that are implemented with If
Statements.
ENTITY counters IS PORT ( d : IN INTEGER RANGE 0 TO 255; clk : IN STD_LOGIC; clear : IN STD_LOGIC; ld : IN STD_LOGIC; enable : IN STD_LOGIC; up_down : IN STD_LOGIC; qa : OUT INTEGER RANGE 0 TO 255; qb : OUT INTEGER RANGE 0 TO 255; qc : OUT INTEGER RANGE 0 TO 255; qd : OUT INTEGER RANGE 0 TO 255; qe : OUT INTEGER RANGE 0 TO 255; qf : OUT INTEGER RANGE 0 TO 255; qg : OUT INTEGER RANGE 0 TO 255; qh : OUT INTEGER RANGE 0 TO 255; qi : OUT INTEGER RANGE 0 TO 255; qj : OUT INTEGER RANGE 0 TO 255; qk : OUT INTEGER RANGE 0 TO 255; ql : OUT INTEGER RANGE 0 TO 255; qm : OUT INTEGER RANGE 0 TO 255; qn : OUT INTEGER RANGE 0 TO 255 ); END counters; ARCHITECTURE a OF counters IS BEGIN -- An enable counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF enable = '1' THEN cnt := cnt + 1; END IF; END IF; qa <= cnt; END PROCESS; -- A synchronous load counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF ld = '0' THEN cnt := d; ELSE cnt := cnt + 1; END IF; END IF; qb <= cnt; END PROCESS; -- A synchronous clear counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE cnt := cnt + 1; END IF; END IF; qc <= cnt; END PROCESS; -- An up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN cnt := cnt + direction; END IF; qd <= cnt; END PROCESS; -- A synchronous load enable counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF ld = '0' THEN cnt := d; ELSE IF enable = '1' THEN cnt := cnt + 1; END IF; END IF; END IF; qe <= cnt; END PROCESS; -- An enable up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN IF enable = '1' THEN cnt := cnt + direction; END IF; END IF; qf <= cnt; END PROCESS; -- A synchronous clear enable counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE IF enable = '1' THEN cnt := cnt + 1; END IF; END IF; END IF; qg <= cnt; END PROCESS; -- A synchronous load clear counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE IF ld = '0' THEN cnt := d; ELSE cnt := cnt + 1; END IF; END IF; END IF; qh <= cnt; END PROCESS; -- A synchronous load up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN IF ld = '0' THEN cnt := d; ELSE cnt := cnt + direction; END IF; END IF; qi <= cnt; END PROCESS; -- A synchronous load enable up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN IF ld = '0' THEN cnt := d; ELSE IF enable = '1' THEN cnt := cnt + direction; END IF; END IF; END IF; qj <= cnt; END PROCESS; -- A synchronous clear load enable counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; BEGIN IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE IF ld = '0' THEN cnt := d; ELSE IF enable = '1' THEN cnt := cnt + 1; END IF; END IF; END IF; END IF; qk <= cnt; END PROCESS; -- A synchronous clear up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE cnt := cnt + direction; END IF; END IF; ql <= cnt; END PROCESS; -- A synchronous clear enable up/down counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; VARIABLE direction : INTEGER; BEGIN IF (up_down = '1') THEN direction := 1; ELSE direction := -1; END IF; IF (clk'EVENT AND clk = '1') THEN IF clear = '0' THEN cnt := 0; ELSE IF enable = '1' THEN cnt := cnt + direction; END IF; END IF; END IF; qm <= cnt; END PROCESS; -- A modulus 200 up counter PROCESS (clk) VARIABLE cnt : INTEGER RANGE 0 TO 255; CONSTANT modulus : INTEGER := 200; BEGIN IF (clk'EVENT AND clk = '1') THEN IF cnt = modulus THEN cnt := 0; ELSE cnt := cnt + 1; END IF; END IF; qn <= cnt; END PROCESS; END a;
In this example, all 14 processes are sensitive only to changes on the clk
signal. All other control
signals are synchronous.
The first Process Statement describes an enabled counter. An If Statement describes the clock
edge, and an additional embedded If Statement uses the enable
signal to control counter
operation. At each rising clock edge, the cnt
variable is incremented by 1
and assigned to itself
if the enable
signal is '1
'.
Go to Implementing Registers for information on how to infer registers by specifying clock edges with If Statements. |
The next 12 counters are described in the same manner. An If Statement describes the clock
edge, and one or more embedded If Statement(s) use the enable
, ld
, d
, clear
, and up_down
signals to control counter operation. The last counter uses the constant modulus
declared in the
process to control when the counter is reset to zero. At each clock edge, the counter variable is
cleared; loaded with the value d
; or incremented or decremented by 1, then assigned to itself
based on the value of the control signal(s).
For more information, see the following sections of the IEEE Std 1076-1993 IEEE Standard VHDL Language Reference Manual:
- PLDWorld - |
|
Created by chm2web html help conversion utility. |