📄 disp4_muxed.vhd
字号:
--
-- DISP4_MUXED.VHD
--
-- This is a 4 digit 7-segment LED display driver
-- The display and segment is time-multiplxed. Thus at any given
-- time there is only on segment begin turned on.
-- There are 2 state machines which controls the displaying:
-- one for the cycling of the segments of a digit, and the second to
-- cycle through the digits.
--
-- You will need COMMON CATHODE (same negative) 7 segment displays
--
--
-- Inputs
-- clk_disp std_logic display clock, this is the clock
-- which cycles through the segments
-- clk_ref std_logic This is the clock rate at which,
-- data is latched into the internal
-- latch.
-- sys_rst_l std_logic asynchronous active low reset. When
-- applied, all 4 digits displays 0, and
-- the state machines are reset
-- data_in std_logic_vector This is a 16 bit input bus, which provides
-- the 4 BCD digit data to display
-- dp_in std_logic_vector This is a 2 bit bus which selects the
-- decimal point to be turned on
-- 00=none, 01=tens, 10=hunds, 11=thousands place
-- load std_logic Active high signal, caseuses the data on
-- data_in and dp_in bus to be latched into
-- an internal latch synchronously to ref_clk
--
-- Outputs:
-- gate0_l std_logic Active low signal which selects ones digit
-- 7degment LED display
-- gate1_l std_logic Active low signal which selects tens digit
-- 7degment LED display
-- gate2_l std_logic Active low signal which selects hundreds digit
-- 7degment LED display
-- gate3_l std_logic Active low signal which selects thousands digit
-- 7degment LED display
-- digit_out_l std_logic_vector Active low vector which turns on the selected
-- segment. The msb is the dp, followed by g,f,
-- and the lsb is segment a
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
ENTITY disp4_muxed IS
PORT ( clk_disp : IN std_logic;
clk_ref : IN std_logic;
sys_rst_l : IN std_logic;
data_in : IN std_logic_vector (15 downto 0);
dp_in : IN std_logic_vector ( 1 downto 0);
load : IN std_logic;
gate0_l : OUT std_logic;
gate1_l : OUT std_logic;
gate2_l : OUT std_logic;
gate3_l : OUT std_logic;
digit_out_l: OUT std_logic_vector (7 downto 0) -- MSB=dp, g, f, e, .., LSB=a
);
END disp4_muxed;
ARCHITECTURE RTL OF disp4_muxed IS
TYPE allowed_seg_states IS (seg_a,seg_b,seg_c,seg_d,seg_e,seg_f,seg_g,seg_dp);
TYPE allowed_digit_states IS (digit_o, digit_t, digit_h, digit_k);
SIGNAL state_seg : allowed_seg_states;
SIGNAL state_digit : allowed_digit_states;
SIGNAL nibble : std_logic_vector (3 downto 0);
SIGNAL nibble2seg : std_logic_vector (6 downto 0);
SIGNAL indata : std_logic_vector (15 downto 0);
SIGNAL indp : std_logic_vector (1 downto 0);
SIGNAL selected_dp : std_logic;
CONSTANT LOW : std_logic := '0';
CONSTANT HIGH : std_logic := '1';
SIGNAL x,y : std_logic_vector (1 downto 0);
BEGIN
-- Input Data Latch
-- Latches the data on the data_in bus synchronously to the cyl
-- when LOAD is active high.
data_in_latch : PROCESS (sys_rst_l, clk_ref)
BEGIN
IF (sys_rst_l=LOW) THEN -- upon system reset, clear asynchronously
indata <= "0000000000000000";
indp <= "00";
ELSIF (clk_ref=HIGH and clk_ref'EVENT) THEN -- on every rising edge of clk
IF (load=HIGH) THEN -- if load is high, load the data
indata <= data_in;
indp <= dp_in;
END IF;
END IF;
END PROCESS data_in_latch;
-- **********************************************************************
--
-- Digit State Machine
--
-- **********************************************************************
-- (Next State assigment and Next State Decode)
DIGIT_SM : PROCESS (sys_rst_l, clk_disp)
VARIABLE digit_state : allowed_digit_states;
BEGIN
IF (sys_rst_l=LOW) THEN
digit_state := digit_o;
ELSIF (clk_disp=HIGH and clk_disp'EVENT) THEN
CASE (digit_state) IS
WHEN digit_o =>
IF (state_seg = seg_g) THEN digit_state := digit_t; END IF;
WHEN digit_t =>
IF (state_seg = seg_g) THEN digit_state := digit_h; END IF;
WHEN digit_h =>
IF (state_seg = seg_g) THEN digit_state := digit_k; END IF;
WHEN digit_k =>
IF (state_seg = seg_g) THEN digit_state := digit_o; END IF;
END CASE;
END IF;
state_digit <= digit_state;
END PROCESS DIGIT_SM;
-- DIGIT DECODE
-- Decode the digit_select output depending on the state of "state_digit"
-- Select the mux to the bin2seg logic.
digit_decode : PROCESS (state_digit)
VARIABLE gates : std_logic_vector (3 downto 0);
VARIABLE dp : std_logic;
BEGIN
gates := "1111";
dp := '0';
CASE (state_digit) IS
WHEN digit_o =>
nibble <= indata(3 downto 0);
gates := "1110";
WHEN digit_t =>
nibble <= indata(7 downto 4);
gates := "1101";
IF (indp="01") THEN dp := '1'; END IF;
WHEN digit_h =>
nibble <= indata(11 downto 8);
gates := "1011";
IF (indp="10") THEN dp := '1'; END IF;
WHEN digit_k =>
nibble <= indata(15 downto 12);
gates := "0111";
IF (indp="11") THEN dp := '1'; END IF;
END CASE;
gate0_l <= gates(0);
gate1_l <= gates(1);
gate2_l <= gates(2);
gate3_l <= gates(3);
selected_dp <= dp;
END PROCESS digit_decode;
-- **********************************************************************
--
-- LED Segment State Machine
--
-- **********************************************************************
-- Next State decode and State assignment
PROCESS (clk_disp, sys_rst_l)
VARIABLE seg_state : allowed_seg_states;
BEGIN
IF (sys_rst_l=LOW) THEN
seg_state := seg_a;
ELSIF (clk_disp=HIGH AND clk_disp'EVENT) THEN
CASE (seg_state) IS
WHEN seg_a =>
seg_state := seg_b;
WHEN seg_b =>
seg_state := seg_c;
WHEN seg_c =>
seg_state := seg_d;
WHEN seg_d =>
seg_state := seg_e;
WHEN seg_e =>
seg_state := seg_f;
WHEN seg_f =>
seg_state := seg_g;
WHEN seg_g =>
seg_state := seg_dp;
WHEN seg_dp =>
seg_state := seg_a;
END CASE;
END IF;
state_seg <= seg_state;
END PROCESS;
seg_decode: PROCESS (state_seg)
VARIABLE segments : std_logic_vector (7 downto 0);
BEGIN
segments := "11111111"; -- segments all off, initially
CASE (state_seg) IS
WHEN seg_a =>
segments(0) := NOT nibble2seg(0);
WHEN seg_b =>
segments(1) := NOT nibble2seg(1);
WHEN seg_c =>
segments(2) := NOT nibble2seg(2);
WHEN seg_d =>
segments(3) := NOT nibble2seg(3);
WHEN seg_e =>
segments(4) := NOT nibble2seg(4);
WHEN seg_f =>
segments(5) := NOT nibble2seg(5);
WHEN seg_g =>
segments(6) := NOT nibble2seg(6);
WHEN seg_dp =>
segments(7) := NOT selected_dp;
END CASE;
digit_out_l <= segments;
END PROCESS seg_decode;
-- **********************************************************************
-- BIN2SEG
-- BCD to 7 segment converter
-- Converts combinatorially, 4 bit BCD into 7 degment LED segment
-- display. The output vector has the following configuration
--
-- f
-- --- An active high indicatges that, the particular
-- e| g |a segment is ON
-- |---|
-- d| |b
-- --- If BCD input is >9, then a dash is displayed, (g on)
-- c
-- **********************************************************************
BCD2SEG: PROCESS (nibble)
VARIABLE segment : std_logic_vector (6 downto 0);
BEGIN
CASE (nibble) IS
WHEN "0000" =>
segment := "0111111";
WHEN "0001" =>
segment := "0000011";
WHEN "0010" =>
segment := "1101101";
WHEN "0011" =>
segment := "1100111";
WHEN "0100" =>
segment := "1011011";
WHEN "0101" =>
segment := "1110110";
WHEN "0110" =>
segment := "1111110";
WHEN "0111" =>
segment := "0100011";
WHEN "1000" =>
segment := "1111111";
WHEN "1001" =>
segment := "1110011";
WHEN OTHERS =>
segment := "1000000";
END CASE;
nibble2seg(6 downto 0) <= segment;
END PROCESS BCD2SEG;
END RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -