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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [xilinx_diligent_s3board/] [rtl/] [verilog/] [driver_7segment.v] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2001 Authors
3
//
4
// This source file may be used and distributed without restriction provided
5
// that this copyright statement is not removed from the file and that any
6
// derivative work contains the original copyright notice and the associated
7
// disclaimer.
8
//
9
// This source file is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation; either version 2.1 of the License, or
12
// (at your option) any later version.
13
//
14
// This source is distributed in the hope that it will be useful, but WITHOUT
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
// License for more details.
18
//
19
// You should have received a copy of the GNU Lesser General Public License
20
// along with this source; if not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
//
23
//----------------------------------------------------------------------------
24
//
25
// *File Name: driver_7segment.v
26
// 
27
// *Module Description:
28
//                      Driver for the four-digit, seven-segment LED display.
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 16 olivier.gi
// $Rev: 111 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2011-05-20 22:39:02 +0200 (Fri, 20 May 2011) $
37
//----------------------------------------------------------------------------
38 2 olivier.gi
 
39
module  driver_7segment (
40
 
41
// OUTPUTs
42
    per_dout,                       // Peripheral data output
43
    seg_a,                          // Segment A control
44
    seg_b,                          // Segment B control
45
    seg_c,                          // Segment C control
46
    seg_d,                          // Segment D control
47
    seg_e,                          // Segment E control
48
    seg_f,                          // Segment F control
49
    seg_g,                          // Segment G control
50
    seg_dp,                         // Segment DP control
51
    seg_an0,                        // Anode 0 control
52
    seg_an1,                        // Anode 1 control
53
    seg_an2,                        // Anode 2 control
54
    seg_an3,                        // Anode 3 control
55
 
56
// INPUTs
57
    mclk,                           // Main system clock
58
    per_addr,                       // Peripheral address
59
    per_din,                        // Peripheral data input
60
    per_en,                         // Peripheral enable (high active)
61 109 olivier.gi
    per_we,                         // Peripheral write enable (high active)
62 111 olivier.gi
    puc_rst                         // Main system reset
63 2 olivier.gi
);
64
 
65
// OUTPUTs
66
//=========
67
output      [15:0] per_dout;        // Peripheral data output
68
output             seg_a;           // Segment A control
69
output             seg_b;           // Segment B control
70
output             seg_c;           // Segment C control
71
output             seg_d;           // Segment D control
72
output             seg_e;           // Segment E control
73
output             seg_f;           // Segment F control
74
output             seg_g;           // Segment G control
75
output             seg_dp;          // Segment DP control
76
output             seg_an0;         // Anode 0 control
77
output             seg_an1;         // Anode 1 control
78
output             seg_an2;         // Anode 2 control
79
output             seg_an3;         // Anode 3 control
80
 
81
// INPUTs
82
//=========
83
input              mclk;            // Main system clock
84 111 olivier.gi
input       [13:0] per_addr;        // Peripheral address
85 2 olivier.gi
input       [15:0] per_din;         // Peripheral data input
86
input              per_en;          // Peripheral enable (high active)
87 109 olivier.gi
input        [1:0] per_we;          // Peripheral write enable (high active)
88 111 olivier.gi
input              puc_rst;         // Main system reset
89 2 olivier.gi
 
90
 
91
//=============================================================================
92
// 1)  PARAMETER DECLARATION
93
//=============================================================================
94
 
95 111 olivier.gi
// Register base address (must be aligned to decoder bit width)
96
parameter       [14:0] BASE_ADDR   = 15'h0090;
97 2 olivier.gi
 
98 111 olivier.gi
// Decoder bit width (defines how many bits are considered for address decoding)
99
parameter              DEC_WD      =  2;
100
 
101
// Register addresses offset
102
parameter [DEC_WD-1:0] DIGIT0      =  'h0,
103
                       DIGIT1      =  'h1,
104
                       DIGIT2      =  'h2,
105
                       DIGIT3      =  'h3;
106
 
107 2 olivier.gi
 
108 111 olivier.gi
// Register one-hot decoder utilities
109
parameter              DEC_SZ      =  2**DEC_WD;
110
parameter [DEC_SZ-1:0] BASE_REG    =  {{DEC_SZ-1{1'b0}}, 1'b1};
111
 
112 2 olivier.gi
// Register one-hot decoder
113 111 olivier.gi
parameter [DEC_SZ-1:0] DIGIT0_D  = (BASE_REG << DIGIT0),
114
                       DIGIT1_D  = (BASE_REG << DIGIT1),
115
                       DIGIT2_D  = (BASE_REG << DIGIT2),
116
                       DIGIT3_D  = (BASE_REG << DIGIT3);
117 2 olivier.gi
 
118
 
119
//============================================================================
120
// 2)  REGISTER DECODER
121
//============================================================================
122
 
123 111 olivier.gi
// Local register selection
124
wire              reg_sel      =  per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
125
 
126
// Register local address
127
wire [DEC_WD-1:0] reg_addr     =  {1'b0, per_addr[DEC_WD-2:0]};
128
 
129 2 olivier.gi
// Register address decode
130 111 olivier.gi
wire [DEC_SZ-1:0] reg_dec      = (DIGIT0_D  &  {DEC_SZ{(reg_addr==(DIGIT0 >>1))}}) |
131
                                 (DIGIT1_D  &  {DEC_SZ{(reg_addr==(DIGIT1 >>1))}}) |
132
                                 (DIGIT2_D  &  {DEC_SZ{(reg_addr==(DIGIT2 >>1))}}) |
133
                                 (DIGIT3_D  &  {DEC_SZ{(reg_addr==(DIGIT3 >>1))}});
134 2 olivier.gi
 
135
// Read/Write probes
136 111 olivier.gi
wire              reg_lo_write =  per_we[0] & reg_sel;
137
wire              reg_hi_write =  per_we[1] & reg_sel;
138
wire              reg_read     = ~|per_we   & reg_sel;
139 2 olivier.gi
 
140
// Read/Write vectors
141 111 olivier.gi
wire [DEC_SZ-1:0] reg_hi_wr    = reg_dec & {DEC_SZ{reg_hi_write}};
142
wire [DEC_SZ-1:0] reg_lo_wr    = reg_dec & {DEC_SZ{reg_lo_write}};
143
wire [DEC_SZ-1:0] reg_rd       = reg_dec & {DEC_SZ{reg_read}};
144 2 olivier.gi
 
145
 
146
//============================================================================
147
// 3) REGISTERS
148
//============================================================================
149
 
150
// DIGIT0 Register
151
//-----------------
152
reg  [7:0] digit0;
153
 
154 111 olivier.gi
wire       digit0_wr  = DIGIT0[0] ? reg_hi_wr[DIGIT0] : reg_lo_wr[DIGIT0];
155
wire [7:0] digit0_nxt = DIGIT0[0] ? per_din[15:8]     : per_din[7:0];
156 2 olivier.gi
 
157 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
158
  if (puc_rst)        digit0 <=  8'h00;
159 2 olivier.gi
  else if (digit0_wr) digit0 <=  digit0_nxt;
160
 
161
 
162
// DIGIT1 Register
163
//-----------------
164
reg  [7:0] digit1;
165
 
166 111 olivier.gi
wire       digit1_wr  = DIGIT1[0] ? reg_hi_wr[DIGIT1] : reg_lo_wr[DIGIT1];
167
wire [7:0] digit1_nxt = DIGIT1[0] ? per_din[15:8]     : per_din[7:0];
168 2 olivier.gi
 
169 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
170
  if (puc_rst)        digit1 <=  8'h00;
171 2 olivier.gi
  else if (digit1_wr) digit1 <=  digit1_nxt;
172
 
173
 
174
// DIGIT2 Register
175
//-----------------
176
reg  [7:0] digit2;
177
 
178 111 olivier.gi
wire       digit2_wr  = DIGIT2[0] ? reg_hi_wr[DIGIT2] : reg_lo_wr[DIGIT2];
179
wire [7:0] digit2_nxt = DIGIT2[0] ? per_din[15:8]     : per_din[7:0];
180 2 olivier.gi
 
181 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
182
  if (puc_rst)        digit2 <=  8'h00;
183 2 olivier.gi
  else if (digit2_wr) digit2 <=  digit2_nxt;
184
 
185
 
186
// DIGIT3 Register
187
//-----------------
188
reg  [7:0] digit3;
189
 
190 111 olivier.gi
wire       digit3_wr  = DIGIT3[0] ? reg_hi_wr[DIGIT3] : reg_lo_wr[DIGIT3];
191
wire [7:0] digit3_nxt = DIGIT3[0] ? per_din[15:8]     : per_din[7:0];
192 2 olivier.gi
 
193 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
194
  if (puc_rst)        digit3 <=  8'h00;
195 2 olivier.gi
  else if (digit3_wr) digit3 <=  digit3_nxt;
196
 
197
 
198
//============================================================================
199
// 4) DATA OUTPUT GENERATION
200
//============================================================================
201
 
202
// Data output mux
203 111 olivier.gi
wire [15:0] digit0_rd   = (digit0  & {8{reg_rd[DIGIT0]}})  << (8 & {4{DIGIT0[0]}});
204
wire [15:0] digit1_rd   = (digit1  & {8{reg_rd[DIGIT1]}})  << (8 & {4{DIGIT1[0]}});
205
wire [15:0] digit2_rd   = (digit2  & {8{reg_rd[DIGIT2]}})  << (8 & {4{DIGIT2[0]}});
206
wire [15:0] digit3_rd   = (digit3  & {8{reg_rd[DIGIT3]}})  << (8 & {4{DIGIT3[0]}});
207 2 olivier.gi
 
208
wire [15:0] per_dout  =  digit0_rd  |
209
                         digit1_rd  |
210
                         digit2_rd  |
211
                         digit3_rd;
212
 
213
 
214
//============================================================================
215
// 5) FOUR-DIGIT, SEVEN-SEGMENT LED DISPLAY DRIVER
216
//============================================================================
217
 
218
// Anode selection
219
//------------------
220
 
221
// Free running counter
222
reg [23:0] anode_cnt;
223 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
224
if (puc_rst) anode_cnt <=  24'h00_0000;
225
else         anode_cnt <=  anode_cnt+24'h00_0001;
226 2 olivier.gi
 
227
// Anode selection
228
wire [3:0] seg_an  = (4'h1 << anode_cnt[17:16]);
229
wire       seg_an0 = ~seg_an[0];
230
wire       seg_an1 = ~seg_an[1];
231
wire       seg_an2 = ~seg_an[2];
232
wire       seg_an3 = ~seg_an[3];
233
 
234
 
235
// Segment selection
236
//----------------------------
237
 
238
wire [7:0] digit  = seg_an[0] ? digit0 :
239
                    seg_an[1] ? digit1 :
240
                    seg_an[2] ? digit2 :
241
                                digit3;
242
 
243
wire       seg_a  = ~digit[7];
244
wire       seg_b  = ~digit[6];
245
wire       seg_c  = ~digit[5];
246
wire       seg_d  = ~digit[4];
247
wire       seg_e  = ~digit[3];
248
wire       seg_f  = ~digit[2];
249
wire       seg_g  = ~digit[1];
250
wire       seg_dp = ~digit[0];
251
 
252
 
253
endmodule // driver_7segment
254
 
255
 
256
 
257
 
258
 
259
 
260
 
261
 

powered by: WebSVN 2.1.0

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