w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
sn_7segctl.vhd
Go to the documentation of this file.
1-- $Id: sn_7segctl.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: sn_7segctl - syn
7-- Description: 7 segment display controller (for s3board,nexys,basys)
8--
9-- Dependencies: -
10-- Test bench: -
11-- Target Devices: generic
12-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
13--
14-- Synthesized (xst):
15-- Date Rev ise Target flop lutl lutm slic t peri
16-- 2015-01-24 637 14.7 131013 xc6slx16-2 9 27 0 16 s 3.1 ns DC=3
17-- 2015-01-24 637 14.7 131013 xc6slx16-2 8 19 0 9 s 3.1 ns DC=2
18-- 2015-01-24 410 14.7 131013 xc6slx16-2 8 19 0 8 s 3.1 ns
19
20-- Revision History:
21-- Date Rev Version Comment
22-- 2015-01-24 637 1.3 renamed from sn_4x7segctl; add DCWIDTH,
23-- allow 4(DC=2) or 8(DC=3) digit display
24-- 2011-09-17 410 1.2.1 now numeric_std clean
25-- 2011-07-30 400 1.2 digit dark in last quarter (not 16 clocks)
26-- 2011-07-08 390 1.1.2 renamed from s3_dispdrv
27-- 2010-04-17 278 1.1.1 renamed from dispdrv
28-- 2010-03-29 272 1.1 add all ANO off time to allow to driver turn-off
29-- delay and to avoid cross talk between digits
30-- 2007-12-16 101 1.0.1 use _N for active low
31-- 2007-09-16 83 1.0 Initial version
32------------------------------------------------------------------------------
33
34library ieee;
35use ieee.std_logic_1164.all;
36use ieee.numeric_std.all;
37
38use work.slvtypes.all;
39
40entity sn_7segctl is -- 7 segment display controller
41 generic (
42 DCWIDTH : positive := 2; -- digit counter width (2 or 3)
43 CDWIDTH : positive := 6); -- clk divider width (must be >= 5)
44 port (
45 CLK : in slbit; -- clock
46 DIN : in slv(4*(2**DCWIDTH)-1 downto 0); -- data 16 or 32
47 DP : in slv((2**DCWIDTH)-1 downto 0); -- decimal points 4 or 8
48 ANO_N : out slv((2**DCWIDTH)-1 downto 0); -- anodes (act.low) 4 or 8
49 SEG_N : out slv8 -- segements (act.low)
50 );
51end sn_7segctl;
52
53architecture syn of sn_7segctl is
54 type regs_type is record
55 cdiv : slv(CDWIDTH-1 downto 0); -- clock divider counter
56 dcnt : slv(DCWIDTH-1 downto 0); -- digit counter
57 end record regs_type;
58
59 constant regs_init : regs_type := (
60 slv(to_unsigned(0,CDWIDTH)), -- cdiv
61 slv(to_unsigned(0,DCWIDTH)) -- dcnt
62 );
63
64 type hex2segtbl_type is array (0 to 15) of slv7;
65
67 ("0111111", -- 0: "0000"
68 "0000110", -- 1: "0001"
69 "1011011", -- 2: "0010"
70 "1001111", -- 3: "0011"
71 "1100110", -- 4: "0100"
72 "1101101", -- 5: "0101"
73 "1111101", -- 6: "0110"
74 "0000111", -- 7: "0111"
75 "1111111", -- 8: "1000"
76 "1101111", -- 9: "1001"
77 "1110111", -- a: "1010"
78 "1111100", -- b: "1011"
79 "0111001", -- c: "1100"
80 "1011110", -- d: "1101"
81 "1111001", -- e: "1110"
82 "1110001" -- f: "1111"
83 );
84
85 signal R_REGS : regs_type := regs_init; -- state registers
86 signal N_REGS : regs_type := regs_init; -- next value state regs
87 signal CHEX : slv4 := (others=>'0'); -- current hex number
88 signal CDP : slbit := '0'; -- current decimal point
89
90begin
91
92 assert DCWIDTH=2 or DCWIDTH=3
93 report "assert(DCWIDTH=2 or DCWIDTH=3): unsupported DCWIDTH"
94 severity failure;
95
96 assert CDWIDTH >= 5
97 report "assert(CDWIDTH >= 5): CDWIDTH too small"
98 severity failure;
99
100 proc_regs: process (CLK)
101 begin
102
103 if rising_edge(CLK) then
104 R_REGS <= N_REGS;
105 end if;
106
107 end process proc_regs;
108
109
110 proc_next: process (R_REGS, CHEX, CDP)
111
112 variable r : regs_type := regs_init;
113 variable n : regs_type := regs_init;
114 variable cano : slv((2**DCWIDTH)-1 downto 0) := (others=>'0');
115
116 begin
117
118 r := R_REGS;
119 n := R_REGS;
120
121 n.cdiv := slv(unsigned(r.cdiv) - 1);
122 if unsigned(r.cdiv) = 0 then
123 n.dcnt := slv(unsigned(r.dcnt) + 1);
124 end if;
125
126 -- the logic below ensures that the anode PNP driver transistor is switched
127 -- off in the last quarter of the digit cycle.This prevents 'cross talk'
128 -- between digits due to transistor turn off delays.
129 -- For a nexys2 board at 50 MHz observed:
130 -- no or 4 cycles gap well visible cross talk
131 -- with 8 cycles still some weak cross talk
132 -- with 16 cycles none is visible.
133 -- --> The turn-off delay of the anode driver PNP's this therefore
134 -- larger 160 ns and below 320 ns.
135 -- As consquence CDWIDTH should be at least 6 for 50 MHz and 7 for 100 MHz.
136
137 cano := (others=>'1');
138 if r.cdiv(CDWIDTH-1 downto CDWIDTH-2) /= "00" then
139 cano(to_integer(unsigned(r.dcnt))) := '0';
140 end if;
141
142 N_REGS <= n;
143
144 ANO_N <= cano;
145 SEG_N <= not (CDP & hex2segtbl(to_integer(unsigned(CHEX))));
146
147 end process proc_next;
148
149 proc_mux: process (R_REGS, DIN, DP)
150 begin
151 CDP <= DP(to_integer(unsigned(R_REGS.dcnt)));
152 CHEX(0) <= DIN(0+4*to_integer(unsigned(R_REGS.dcnt)));
153 CHEX(1) <= DIN(1+4*to_integer(unsigned(R_REGS.dcnt)));
154 CHEX(2) <= DIN(2+4*to_integer(unsigned(R_REGS.dcnt)));
155 CHEX(3) <= DIN(3+4*to_integer(unsigned(R_REGS.dcnt)));
156 end process proc_mux;
157
158end syn;
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 6 downto 0) slv7
Definition: slvtypes.vhd:39
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 7 downto 0) slv8
Definition: slvtypes.vhd:40
std_logic_vector slv
Definition: slvtypes.vhd:31
slv4 :=( others => '0') CHEX
Definition: sn_7segctl.vhd:87
slbit := '0' CDP
Definition: sn_7segctl.vhd:88
regs_type := regs_init N_REGS
Definition: sn_7segctl.vhd:86
regs_type := regs_init R_REGS
Definition: sn_7segctl.vhd:85
( 0 to 15) slv7 hex2segtbl_type
Definition: sn_7segctl.vhd:64
hex2segtbl_type :=( "0111111", "0000110", "1011011", "1001111", "1100110", "1101101", "1111101", "0000111", "1111111", "1101111", "1110111", "1111100", "0111001", "1011110", "1111001", "1110001") hex2segtbl
Definition: sn_7segctl.vhd:66
regs_type :=( slv( to_unsigned( 0, CDWIDTH) ), slv( to_unsigned( 0, DCWIDTH) )) regs_init
Definition: sn_7segctl.vhd:59
in DIN slv( 4*( 2** DCWIDTH)- 1 downto 0)
Definition: sn_7segctl.vhd:46
out ANO_N slv(( 2** DCWIDTH)- 1 downto 0)
Definition: sn_7segctl.vhd:48
DCWIDTH positive := 2
Definition: sn_7segctl.vhd:42
in CLK slbit
Definition: sn_7segctl.vhd:45
CDWIDTH positive := 6
Definition: sn_7segctl.vhd:43
out SEG_N slv8
Definition: sn_7segctl.vhd:50
in DP slv(( 2** DCWIDTH)- 1 downto 0)
Definition: sn_7segctl.vhd:47