OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.5/] [rtl/] [bplib/] [s3board/] [s3_dispdrv.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wfjm
-- $Id: s3_dispdrv.vhd 314 2010-07-09 17:38:41Z mueller $
2
--
3
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
-- 
14
------------------------------------------------------------------------------
15
-- Module Name:    s3_dispdrv - syn
16
-- Description:    s3board: 7 segment display driver
17
--
18
-- Dependencies:   -
19
-- Test bench:     -
20
-- Target Devices: generic
21
-- Tool versions:  xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26
22
-- Revision History: 
23
-- Date         Rev Version  Comment
24
-- 2010-04-17   278   1.1.1  renamed from dispdrv
25
-- 2010-03-29   272   1.1    add all ANO off time to allow to driver turn-off
26
--                           delay and to avoid cross talk between digits
27
-- 2007-12-16   101   1.0.1  use _N for active low
28
-- 2007-09-16    83   1.0    Initial version 
29
------------------------------------------------------------------------------
30
 
31
library ieee;
32
use ieee.std_logic_1164.all;
33
use ieee.std_logic_arith.all;
34
 
35
use work.slvtypes.all;
36
 
37
entity s3_dispdrv is                    -- 7 segment display driver
38
  generic (
39
    CDWIDTH : positive := 6);           -- clk divider width (must be >= 5)
40
  port (
41
    CLK : in slbit;                     -- clock
42
    DIN : in slv16;                     -- data
43
    DP : in slv4;                       -- decimal points
44
    ANO_N : out slv4;                   -- anodes    (act.low)
45
    SEG_N : out slv8                    -- segements (act.low)
46
  );
47
end s3_dispdrv;
48
 
49
architecture syn of s3_dispdrv is
50
 
51
  type regs_type is record
52
    cdiv : std_logic_vector(CDWIDTH-1 downto 0); -- clock divider counter
53
    dcnt : slv2;                                 -- digit counter
54
  end record regs_type;
55
 
56
  constant regs_init : regs_type := (
57
    conv_std_logic_vector(0,CDWIDTH),
58
    (others=>'0')
59
  );
60
 
61
  type hex2segtbl_type is array (0 to 15) of slv7;
62
 
63
  constant hex2segtbl : hex2segtbl_type :=
64
     ("0111111",                        -- 0: "0000"
65
      "0000110",                        -- 1: "0001"
66
      "1011011",                        -- 2: "0010"
67
      "1001111",                        -- 3: "0011"
68
      "1100110",                        -- 4: "0100"
69
      "1101101",                        -- 5: "0101"
70
      "1111101",                        -- 6: "0110"
71
      "0000111",                        -- 7: "0111"
72
      "1111111",                        -- 8: "1000"
73
      "1101111",                        -- 9: "1001"
74
      "1110111",                        -- a: "1010"
75
      "1111100",                        -- b: "1011"
76
      "0111001",                        -- c: "1100"
77
      "1011110",                        -- d: "1101"
78
      "1111001",                        -- e: "1110"
79
      "1110001"                         -- f: "1111"
80
      );
81
 
82
  signal R_REGS : regs_type := regs_init;  -- state registers
83
  signal N_REGS : regs_type := regs_init;  -- next value state regs
84
 
85
begin
86
 
87
  assert CDWIDTH >= 5
88
  report "assert(CDWIDTH >= 5): CDWIDTH too small"
89
  severity FAILURE;
90
 
91
  proc_regs: process (CLK)
92
  begin
93
 
94
    if CLK'event and CLK='1' then
95
      R_REGS <= N_REGS;
96
    end if;
97
 
98
  end process proc_regs;
99
 
100
 
101
  proc_next: process (R_REGS, DIN, DP)
102
 
103
    variable r : regs_type := regs_init;
104
    variable n : regs_type := regs_init;
105
    variable cano : slv4 := "0000";
106
    variable chex : slv4 := "0000";
107
    variable cdp  : slbit := '0';
108
 
109
  begin
110
 
111
    r := R_REGS;
112
    n := R_REGS;
113
 
114
    n.cdiv := unsigned(r.cdiv) - 1;
115
    if unsigned(r.cdiv) = 0 then
116
      n.dcnt := unsigned(r.dcnt) + 1;
117
    end if;
118
 
119
    chex := "0000";
120
    cdp  := '0';
121
 
122
    case r.dcnt is
123
      when "00" => chex := DIN( 3 downto  0);  cdp := DP(0);
124
      when "01" => chex := DIN( 7 downto  4);  cdp := DP(1);
125
      when "10" => chex := DIN(11 downto  8);  cdp := DP(2);
126
      when "11" => chex := DIN(15 downto 12);  cdp := DP(3);
127
      when others => chex := "----";           cdp := '-';
128
    end case;
129
 
130
    -- the logic below ensures that the anode PNP driver transistor is switched
131
    -- off 16 cycles before the cathode drivers change. This  prevents 'cross
132
    -- talk' between digits due to transistor turn off delays. With no or 4
133
    -- cycles gap one gets well visible cross talk, with 8 cycles still some
134
    -- weak cross talk. With 16 cycles (at 50MHz) none is visible. The
135
    -- turn-off delay of the anode driver PNP's this therefore larger 160 ns 
136
    -- and below 320 ns.
137
    -- As consquence CDWIDTH should be at least 5, better 6.
138
 
139
    cano := "1111";
140
    if unsigned(r.cdiv) >= 16 then
141
      cano(conv_integer(unsigned(r.dcnt))) := '0';
142
    end if;
143
 
144
    N_REGS <= n;
145
 
146
    ANO_N <= cano;
147
    SEG_N <= not (cdp & hex2segtbl(conv_integer(unsigned(chex))));
148
 
149
  end process proc_next;
150
 
151
end syn;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.