-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
--
-- Entity: Digilent Peritherial Module: Pmod_SSD
--
-- Description:
--
-- This module drives a dual-digit 7-segment display (Pmod_SSD). The module
-- expects two binary encoded 4-bit ``Digit<i>`` signals and drives a 2x6 bit
-- Pmod connector (7 anode bits, 1 cathode bit).
--
-- .. code-block:: none
--
-- Segment Pos./ Index
-- AAA | 000
-- F B | 5 1
-- F B | 5 1
-- GGG | 666
-- E C | 4 2
-- E C | 4 2
-- DDD DOT | 333 7
--
-- License:
-- =============================================================================
-- Copyright 2007-2016 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.utils.all;
use PoC.physical.all;
use PoC.components.all;
use PoC.io.all;
use PoC.pmod.all;
entity [docs]pmod_SSD is
generic (
CLOCK_FREQ : FREQ := 100 MHz;
REFRESH_RATE : FREQ := 1 kHz
);
port (
Clock : in std_logic;
Digit0 : in std_logic_vector(3 downto 0);
Digit1 : in std_logic_vector(3 downto 0);
SSD : out T_PMOD_SSD_PINS
);
end entity;
architecture [docs]rtl of pmod_SSD is
constant REFRESHTIMER_MAX : positive := TimingToCycles(to_time(REFRESH_RATE), CLOCK_FREQ) - 1;
constant REFRESHTIMER_BITS : positive := log2ceilnz(REFRESHTIMER_MAX) + 1;
signal RefreshTimer_rst : std_logic;
signal RefreshTimer_s : signed(REFRESHTIMER_BITS - 1 downto 0) := to_signed(REFRESHTIMER_MAX, REFRESHTIMER_BITS);
signal CathodeSelect_en : std_logic;
signal CathodeSelect_r : std_logic := '0';
signal Digit : std_logic_vector(3 downto 0);
signal Segments : std_logic_vector(6 downto 0);
begin
-- generate a < 1 kHz enable to toggle the CathodeSelect register
RefreshTimer_s <= downcounter_next(cnt => RefreshTimer_s, rst => RefreshTimer_rst, INIT => REFRESHTIMER_MAX) when rising_edge(Clock);
RefreshTimer_rst <= downcounter_neg(cnt => RefreshTimer_s);
-- generate a cathode select signal, based on a T-FF
CathodeSelect_en <= RefreshTimer_rst;
CathodeSelect_r <= fftre(q => CathodeSelect_r, t => CathodeSelect_en) when rising_edge(Clock);
Digit <= mux(CathodeSelect_r, Digit0, Digit1);
Segments <= io_7SegmentDisplayEncoding(Digit);
SSD.AnodeA <= Segments(0);
SSD.AnodeB <= Segments(1);
SSD.AnodeC <= Segments(2);
SSD.AnodeD <= Segments(3);
SSD.AnodeE <= Segments(4);
SSD.AnodeF <= Segments(5);
SSD.AnodeG <= Segments(6);
SSD.Cathode <= CathodeSelect_r;
end architecture;