1 |
2 |
trurl |
--------------------------------------------------------------------
|
2 |
|
|
--!
|
3 |
|
|
--! PDP-8 Processor
|
4 |
|
|
--!
|
5 |
|
|
--! \brief
|
6 |
|
|
--! NEXYS2 Wrapper: Seven Segment Display
|
7 |
|
|
--!
|
8 |
|
|
--! \details
|
9 |
|
|
--! This package displays 12-bit data in octal on the Nexys2
|
10 |
|
|
--! Seven Segment display.
|
11 |
|
|
--!
|
12 |
|
|
--! The data to be displayed is selected by the rotary switch
|
13 |
|
|
--! (swROT) in another package.
|
14 |
|
|
--!
|
15 |
|
|
--! \file
|
16 |
|
|
--! nexys2_disp.vhd
|
17 |
|
|
--!
|
18 |
|
|
--! \author
|
19 |
|
|
--! Rob Doyle - doyle (at) cox (dot) net
|
20 |
|
|
--!
|
21 |
|
|
--------------------------------------------------------------------
|
22 |
|
|
--
|
23 |
|
|
-- Copyright (C) 2011, 2012 Rob Doyle
|
24 |
|
|
--
|
25 |
|
|
-- This source file may be used and distributed without
|
26 |
|
|
-- restriction provided that this copyright statement is not
|
27 |
|
|
-- removed from the file and that any derivative work contains
|
28 |
|
|
-- the original copyright notice and the associated disclaimer.
|
29 |
|
|
--
|
30 |
|
|
-- This source file is free software; you can redistribute it
|
31 |
|
|
-- and/or modify it under the terms of the GNU Lesser General
|
32 |
|
|
-- Public License as published by the Free Software Foundation;
|
33 |
|
|
-- version 2.1 of the License.
|
34 |
|
|
--
|
35 |
|
|
-- This source is distributed in the hope that it will be
|
36 |
|
|
-- useful, but WITHOUT ANY WARRANTY; without even the implied
|
37 |
|
|
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
38 |
|
|
-- PURPOSE. See the GNU Lesser General Public License for more
|
39 |
|
|
-- details.
|
40 |
|
|
--
|
41 |
|
|
-- You should have received a copy of the GNU Lesser General
|
42 |
|
|
-- Public License along with this source; if not, download it
|
43 |
|
|
-- from http://www.gnu.org/licenses/lgpl.txt
|
44 |
|
|
--
|
45 |
|
|
--------------------------------------------------------------------
|
46 |
|
|
--
|
47 |
|
|
-- Comments are formatted for doxygen
|
48 |
|
|
--
|
49 |
|
|
|
50 |
|
|
library ieee; --! IEEE Library
|
51 |
|
|
use ieee.std_logic_1164.all; --! IEEE 1164
|
52 |
|
|
use ieee.numeric_std.all; --! IEEE Std Logic Unsigned
|
53 |
|
|
use work.nexys2_types.all; --! Nexys2 Board types
|
54 |
|
|
|
55 |
|
|
--
|
56 |
|
|
--! NEXYS2 Seven Segment Display Entity
|
57 |
|
|
--
|
58 |
|
|
|
59 |
|
|
entity eNEXYS2_DISP is port (
|
60 |
|
|
clk : in std_logic; --! Clock
|
61 |
|
|
rst : in std_logic; --! Reset
|
62 |
|
|
dispData : in dispDat_t; --! Data to be displayed
|
63 |
|
|
dispSeg_L : out dispSeg_t; --! Segment Drivers
|
64 |
|
|
dispDig_L : out dispDig_t --! Digit Drivers
|
65 |
|
|
);
|
66 |
|
|
end eNEXYS2_DISP;
|
67 |
|
|
|
68 |
|
|
--
|
69 |
|
|
--! NEXYS2 Seven Segment Display RTL
|
70 |
|
|
--
|
71 |
|
|
|
72 |
|
|
architecture rtl of eNEXYS2_DISP is
|
73 |
|
|
|
74 |
|
|
subtype dispVal_t is std_logic_vector(0 to 3); --! Hex/Octal Data
|
75 |
|
|
|
76 |
|
|
signal currDig : dispDig_t; --! Current Display Digit
|
77 |
|
|
signal nextDig : dispDig_t; --! Next Display Digit
|
78 |
|
|
signal dispSeg : dispSeg_t; --! Display Segment
|
79 |
|
|
signal dispVal : dispVal_t; --! Display Data
|
80 |
|
|
|
81 |
|
|
--!
|
82 |
|
|
--! Four Digit Display Definition
|
83 |
|
|
--!
|
84 |
|
|
|
85 |
|
|
constant dispDig0 : dispDig_t := "1000"; --! Digit 0
|
86 |
|
|
constant dispDig1 : dispDig_t := "0100"; --! Digit 1
|
87 |
|
|
constant dispDig2 : dispDig_t := "0010"; --! Digit 2
|
88 |
|
|
constant dispDig3 : dispDig_t := "0001"; --! Digit 3
|
89 |
|
|
|
90 |
|
|
--!
|
91 |
|
|
--! Seven Segment Display Definition
|
92 |
|
|
--!
|
93 |
|
|
|
94 |
|
|
constant dispSeg0 : dispSeg_t := "11111100"; --! Digit 0
|
95 |
|
|
constant dispSeg1 : dispSeg_t := "01100000"; --! Digit 1
|
96 |
|
|
constant dispSeg2 : dispSeg_t := "11011010"; --! Digit 2
|
97 |
|
|
constant dispSeg3 : dispSeg_t := "11110010"; --! Digit 3
|
98 |
|
|
constant dispSeg4 : dispSeg_t := "01100110"; --! Digit 4
|
99 |
|
|
constant dispSeg5 : dispSeg_t := "10110110"; --! Digit 5
|
100 |
|
|
constant dispSeg6 : dispSeg_t := "10111110"; --! Digit 6
|
101 |
|
|
constant dispSeg7 : dispSeg_t := "11100000"; --! Digit 7
|
102 |
|
|
constant dispSeg8 : dispSeg_t := "11111110"; --! Digit 8
|
103 |
|
|
constant dispSeg9 : dispSeg_t := "11110110"; --! Digit 9
|
104 |
|
|
constant dispSegA : dispSeg_t := "11101110"; --! Digit A
|
105 |
|
|
constant dispSegB : dispSeg_t := "00111110"; --! Digit B
|
106 |
|
|
constant dispSegC : dispSeg_t := "10011100"; --! Digit C
|
107 |
|
|
constant dispSegD : dispSeg_t := "01111010"; --! Digit D
|
108 |
|
|
constant dispSegE : dispSeg_t := "10011110"; --! Digit E
|
109 |
|
|
constant dispSegF : dispSeg_t := "10001110"; --! Digit F
|
110 |
|
|
constant dispSegN : dispSeg_t := "00000000"; --! Digit ?
|
111 |
|
|
|
112 |
|
|
begin
|
113 |
|
|
|
114 |
|
|
--
|
115 |
|
|
--! State Machine that walks though the four digits
|
116 |
|
|
--
|
117 |
|
|
|
118 |
|
|
DISP_MACHINE : process(clk, rst)
|
119 |
|
|
subtype div_t is integer range 0 to 8191;
|
120 |
|
|
variable clkDiv : div_t;
|
121 |
|
|
begin
|
122 |
|
|
if rst = '1' then
|
123 |
|
|
clkDiv := 0;
|
124 |
|
|
currDig <= dispDig0;
|
125 |
|
|
elsif rising_edge(clk) then
|
126 |
|
|
if clkDiv = 8191 then
|
127 |
|
|
clkDiv := 0;
|
128 |
|
|
currDig <= nextDig;
|
129 |
|
|
else
|
130 |
|
|
clkDiv := clkDiv + 1;
|
131 |
|
|
end if;
|
132 |
|
|
end if;
|
133 |
|
|
end process DISP_MACHINE;
|
134 |
|
|
|
135 |
|
|
--
|
136 |
|
|
-- Next State
|
137 |
|
|
--
|
138 |
|
|
|
139 |
|
|
with currDig select
|
140 |
|
|
nextDig <= dispDig1 when dispDig0,
|
141 |
|
|
dispDig2 when dispDig1,
|
142 |
|
|
dispDig3 when dispDig2,
|
143 |
|
|
dispDig0 when dispDig3,
|
144 |
|
|
dispDig0 when others;
|
145 |
|
|
|
146 |
|
|
--
|
147 |
|
|
-- Select Digit Data
|
148 |
|
|
--
|
149 |
|
|
|
150 |
|
|
with currDig select
|
151 |
|
|
dispVal <= dispData( 0 to 3) when dispDig0,
|
152 |
|
|
dispData( 4 to 7) when dispDig1,
|
153 |
|
|
dispData( 8 to 11) when dispDig2,
|
154 |
|
|
dispData(12 to 15) when dispDig3,
|
155 |
|
|
"1111" when others;
|
156 |
|
|
|
157 |
|
|
--
|
158 |
|
|
-- Seven Segment Decoder
|
159 |
|
|
--
|
160 |
|
|
|
161 |
|
|
with dispVal select
|
162 |
|
|
dispSeg <= dispSeg0 when "0000", --! 0
|
163 |
|
|
dispSeg1 when "0001", --! 1
|
164 |
|
|
dispSeg2 when "0010", --! 2
|
165 |
|
|
dispSeg3 when "0011", --! 3
|
166 |
|
|
dispSeg4 when "0100", --! 4
|
167 |
|
|
dispSeg5 when "0101", --! 5
|
168 |
|
|
dispSeg6 when "0110", --! 6
|
169 |
|
|
dispSeg7 when "0111", --! 7
|
170 |
|
|
dispSeg8 when "1000", --! 8
|
171 |
|
|
dispSeg9 when "1001", --! 9
|
172 |
|
|
dispSegA when "1010", --! A
|
173 |
|
|
dispSegB when "1011", --! B
|
174 |
|
|
dispSegC when "1100", --! C
|
175 |
|
|
dispSegD when "1101", --! D
|
176 |
|
|
dispSegE when "1110", --! E
|
177 |
|
|
dispSegF when "1111", --! F
|
178 |
|
|
dispSegN when others;
|
179 |
|
|
|
180 |
|
|
--
|
181 |
|
|
-- The hardware is all negative logic
|
182 |
|
|
--
|
183 |
|
|
|
184 |
|
|
dispDig_L <= not(currDig);
|
185 |
|
|
dispSeg_L <= not(dispSeg);
|
186 |
|
|
|
187 |
|
|
end rtl;
|