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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [rtl/] [bplib/] [bpgen/] [sn_4x7segctl.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 wfjm
-- $Id: sn_4x7segctl.vhd 410 2011-09-18 11:23:09Z mueller $
2 2 wfjm
--
3 12 wfjm
-- Copyright 2007-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
--
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 12 wfjm
-- Module Name:    sn_4x7segctl - syn
16
-- Description:    Quad 7 segment display controller (for s3board and nexys2/3)
17 2 wfjm
--
18
-- Dependencies:   -
19
-- Test bench:     -
20
-- Target Devices: generic
21 13 wfjm
-- Tool versions:  xst 8.2, 9.1, 9.2, 11.4, 12.1; ghdl 0.18-0.29
22 2 wfjm
-- Revision History: 
23
-- Date         Rev Version  Comment
24 13 wfjm
-- 2011-09-17   410   1.2.1  now numeric_std clean
25 12 wfjm
-- 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 2 wfjm
-- 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
 
34
library ieee;
35
use ieee.std_logic_1164.all;
36 13 wfjm
use ieee.numeric_std.all;
37 2 wfjm
 
38
use work.slvtypes.all;
39
 
40 12 wfjm
entity sn_4x7segctl is                  -- Quad 7 segment display controller
41 2 wfjm
  generic (
42
    CDWIDTH : positive := 6);           -- clk divider width (must be >= 5)
43
  port (
44
    CLK : in slbit;                     -- clock
45
    DIN : in slv16;                     -- data
46
    DP : in slv4;                       -- decimal points
47
    ANO_N : out slv4;                   -- anodes    (act.low)
48
    SEG_N : out slv8                    -- segements (act.low)
49
  );
50 12 wfjm
end sn_4x7segctl;
51 2 wfjm
 
52 12 wfjm
architecture syn of sn_4x7segctl is
53 2 wfjm
 
54
  type regs_type is record
55 13 wfjm
    cdiv : slv(CDWIDTH-1 downto 0);     -- clock divider counter
56
    dcnt : slv2;                        -- digit counter
57 2 wfjm
  end record regs_type;
58
 
59
  constant regs_init : regs_type := (
60 13 wfjm
    slv(to_unsigned(0,CDWIDTH)),
61 2 wfjm
    (others=>'0')
62
  );
63
 
64
  type hex2segtbl_type is array (0 to 15) of slv7;
65
 
66
  constant hex2segtbl : hex2segtbl_type :=
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
 
88
begin
89
 
90
  assert CDWIDTH >= 5
91
  report "assert(CDWIDTH >= 5): CDWIDTH too small"
92
  severity FAILURE;
93
 
94
  proc_regs: process (CLK)
95
  begin
96
 
97 13 wfjm
    if rising_edge(CLK) then
98 2 wfjm
      R_REGS <= N_REGS;
99
    end if;
100
 
101
  end process proc_regs;
102
 
103
 
104
  proc_next: process (R_REGS, DIN, DP)
105
 
106
    variable r : regs_type := regs_init;
107
    variable n : regs_type := regs_init;
108
    variable cano : slv4 := "0000";
109
    variable chex : slv4 := "0000";
110
    variable cdp  : slbit := '0';
111
 
112
  begin
113
 
114
    r := R_REGS;
115
    n := R_REGS;
116
 
117 13 wfjm
    n.cdiv := slv(unsigned(r.cdiv) - 1);
118 2 wfjm
    if unsigned(r.cdiv) = 0 then
119 13 wfjm
      n.dcnt := slv(unsigned(r.dcnt) + 1);
120 2 wfjm
    end if;
121
 
122
    chex := "0000";
123
    cdp  := '0';
124
 
125
    case r.dcnt is
126
      when "00" => chex := DIN( 3 downto  0);  cdp := DP(0);
127
      when "01" => chex := DIN( 7 downto  4);  cdp := DP(1);
128
      when "10" => chex := DIN(11 downto  8);  cdp := DP(2);
129
      when "11" => chex := DIN(15 downto 12);  cdp := DP(3);
130
      when others => chex := "----";           cdp := '-';
131
    end case;
132
 
133
    -- the logic below ensures that the anode PNP driver transistor is switched
134 12 wfjm
    -- off in the last quarter of the digit cycle.This  prevents 'cross talk'
135
    -- between digits due to transistor turn off delays.
136
    -- For a nexys2 board at 50 MHz observed:
137
    --   no or 4 cycles gap well visible cross talk
138
    --   with 8 cycles still some weak cross talk
139
    --   with 16 cycles none is visible.
140
    --   --> The turn-off delay of the anode driver PNP's this therefore
141
    --       larger 160 ns and below 320 ns.
142
    -- As consquence CDWIDTH should be at least 6 for 50 MHz and 7 for 100 MHz.
143 2 wfjm
 
144
    cano := "1111";
145 12 wfjm
    if r.cdiv(CDWIDTH-1 downto CDWIDTH-2) /= "00" then
146 13 wfjm
      cano(to_integer(unsigned(r.dcnt))) := '0';
147 2 wfjm
    end if;
148
 
149
    N_REGS <= n;
150
 
151
    ANO_N <= cano;
152 13 wfjm
    SEG_N <= not (cdp & hex2segtbl(to_integer(unsigned(chex))));
153 2 wfjm
 
154
  end process proc_next;
155
 
156
end syn;

powered by: WebSVN 2.1.0

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