📄 bcdcounter4.vhd
字号:
--
-- BCDCOUNTER4.VHD
--
-- This is 4 digic BCD up counter.
-- The state machine contains 2 states as follows:
--
-- gate = 1
-- _______________
-- / \
-- | |
-- /---\ | \ / /---\
-- | DONE COUNT |
-- \___// \ | \---/
-- | |
-- \---------------/
-- gate = 0
--
--
-- The state machine is set at DONE state, and waits until the GATE becomes active high.
-- When the GATE does become high, it begins counting the rising edges of the incoming clock
-- until the gate becomes deasserted.
--
--
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
ENTITY BCDCOUNTER4 IS
PORT ( Funknown : IN std_logic;
sys_rst_l : IN std_logic;
GATE : IN std_logic;
ready : OUT std_logic;
data_out : OUT std_logic_vector (15 downto 0);
overflow : OUT std_logic
);
END BCDCOUNTER4;
ARCHITECTURE FREQCOUNTER OF BCDCOUNTER4 IS
CONSTANT HIGH : std_logic := '1';
CONSTANT LOW : std_logic := '0';
SIGNAL state : std_logic_vector (1 downto 0);
SIGNAL prev_state : std_logic_vector (1 downto 0);
SIGNAL one : std_logic_vector (3 downto 0);
SIGNAL ten : std_logic_vector (3 downto 0);
SIGNAL hund : std_logic_vector (3 downto 0);
SIGNAL thou : std_logic_vector (3 downto 0);
SIGNAL one_c : std_logic;
SIGNAL ten_c : std_logic;
SIGNAL hund_c : std_logic;
SIGNAL thou_c : std_logic;
SIGNAL ena_count : std_logic;
BEGIN
data_out <= thou & hund & ten & one;
ready <= NOT ena_count;
-- *******************************************************************************************
-- FREQUENCY COUNTER
-- Counts from 0000 to 9999 (BCD) only when the GATE is high
-- The state machine toggles from "done" state "measure" state. The state machine
-- encoding is one-hot state
-- *******************************************************************************************
-- NEXT STATE ASSIGNMENT
-- One hot Encoding
PROCESS (Funknown, sys_rst_l)
BEGIN
IF (sys_rst_l=LOW) THEN -- power-up initial state is "01"
state <= "01";
ELSIF (Funknown=HIGH and Funknown'EVENT) THEN
state <= prev_state; -- else, assign the next state to present state
END IF;
END PROCESS;
-- NEXT STATE DECODE
SM: PROCESS (state)
VARIABLE local_state : std_logic_vector (1 downto 0);
BEGIN
local_state := "00";
IF (state(0)='1') THEN -- IF GATE is high, goto "measure" state
IF (GATE=HIGH) THEN local_state(1) := '1'; ELSE local_state(0) := '1'; END IF;
ELSIF (state(1)='1') THEN -- if GATE is low, goto "done" state
IF (GATE=LOW) THEN local_state(0) := '1'; ELSE local_state(1) := '1'; END IF;
END IF;
prev_state <= local_state;
END PROCESS SM;
-- OUTPUT DECODE
PROCESS (prev_state)
BEGIN
IF (prev_state(0)='1') THEN ena_count <= LOW;
ELSIF (prev_state(1)='1') THEN ena_count <= HIGH; END IF;
END PROCESS;
-- OVERFLOW GENERATING LATCH
-- This is clocked, as opposed to combinatorial, so that there is no
-- glitch in the overflow output
OVERFLOW_GEN: PROCESS (sys_rst_l, Funknown)
BEGIN
IF (sys_rst_l=LOW) THEN
overflow <= LOW;
ELSIF (Funknown=HIGH and Funknown'EVENT) THEN
IF (one="1001" AND ten="1001" AND hund="1001" AND thou="1001") THEN
overflow <= HIGH;
END IF;
END IF;
END PROCESS OVERFLOW_GEN;
-- *******************************************************************************************
-- BCD COUNTERS
-- Counts from 0000 to 9999
-- only when enabled to count, that is ENA_COUNT='1'
-- *******************************************************************************************
-- ONES PLACE BCD COUNTER
ONE_COUNTER: PROCESS (Funknown, sys_rst_l) BEGIN
IF (sys_rst_l=LOW) THEN
one <= "0000";
ELSIF (Funknown=HIGH AND Funknown'EVENT) THEN
IF (ena_count=HIGH) THEN
IF (one="1001") THEN one <= "0000"; ELSE one <= one + 1; END IF;
END IF;
END IF;
END PROCESS ONE_COUNTER;
-- TENS PLACE BCD COUNTER
TEN_COUNTER: PROCESS (Funknown, sys_rst_l) BEGIN
IF (sys_rst_l=LOW) THEN
ten <= "0000";
ELSIF (Funknown=HIGH AND Funknown'EVENT) THEN
IF (ena_count=HIGH) THEN
IF (ten="1001" and one="1001") THEN ten<="0000";
ELSIF (one="1001") THEN ten <= ten + 1; END IF;
END IF;
END IF;
END PROCESS TEN_COUNTER;
-- HUNDRED PLACE BCD COUNTER
HUND_COUNTER: PROCESS (Funknown, sys_rst_l) BEGIN
IF (sys_rst_l=LOW) THEN
hund <= "0000";
ELSIF (Funknown=HIGH AND Funknown'EVENT) THEN
IF (ena_count=HIGH) THEN
IF (hund="1001" AND ten="1001" AND one="1001") THEN hund<="0000";
ELSIF (ten="1001" AND one="1001") THEN hund <= hund + 1; END IF;
END IF;
END IF;
END PROCESS HUND_COUNTER;
-- THOUSAND PLACE BCD COUNTER
THOU_COUNTER: PROCESS (Funknown, sys_rst_l) BEGIN
IF (sys_rst_l=LOW) THEN
THOU <= "0000";
ELSIF (Funknown=HIGH AND Funknown'EVENT) THEN
IF (ena_count=HIGH) THEN
IF (thou="1001" AND hund="1001" AND ten="1001" AND one="1001" ) THEN thou<="0000";
ELSIF (hund="1001" AND ten="1001" AND one="1001") THEN thou <= thou + 1; END IF;
END IF;
END IF;
END PROCESS THOU_COUNTER;
END FREQCOUNTER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -