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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [rtl/] [verilog/] [omsp_de0_nano_soc_led_key_sw.v] - Blame information for rev 221

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 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: omsp_de0_nano_soc_led_key_sw.v
26
//
27
// *Module Description:
28
//                      Custom peripheral for the DE0 Nano SoC board
29
//                      for driving LEDs and reading SWITCHES and KEYs (i.e. buttons)
30
//
31
// *Author(s):
32
//              - Olivier Girard,    olgirard@gmail.com
33
//
34
//----------------------------------------------------------------------------
35
// $Rev$
36
// $LastChangedBy$
37
// $LastChangedDate$
38
//----------------------------------------------------------------------------
39
 
40
module  omsp_de0_nano_soc_led_key_sw (
41
 
42
// OUTPUTs
43
    irq_key,                        // Key/Button interrupt
44
    irq_sw,                         // Switch interrupt
45
    led,                            // LED output control
46
    per_dout,                       // Peripheral data output
47
 
48
// INPUTs
49
    mclk,                           // Main system clock
50
    key,                            // key/button inputs
51
    sw,                             // switches inputs
52
    per_addr,                       // Peripheral address
53
    per_din,                        // Peripheral data input
54
    per_en,                         // Peripheral enable (high active)
55
    per_we,                         // Peripheral write enable (high active)
56
    puc_rst                         // Main system reset
57
);
58
 
59
// OUTPUTs
60
//=========
61
output             irq_key;         // Key/Button interrupt
62
output             irq_sw;          // Switch interrupt
63
output       [7:0] led;             // LED output control
64
output      [15:0] per_dout;        // Peripheral data output
65
 
66
// INPUTs
67
//=========
68
input              mclk;            // Main system clock
69
input        [1:0] key;             // key/button inputs
70
input        [3:0] sw;              // switches inputs
71
input       [13:0] per_addr;        // Peripheral address
72
input       [15:0] per_din;         // Peripheral data input
73
input              per_en;          // Peripheral enable (high active)
74
input        [1:0] per_we;          // Peripheral write enable (high active)
75
input              puc_rst;         // Main system reset
76
 
77
 
78
//=============================================================================
79
// 1)  PARAMETER DECLARATION
80
//=============================================================================
81
 
82
// Register base address (must be aligned to decoder bit width)
83
parameter       [14:0] BASE_ADDR         = 15'h0090;
84
 
85
// Decoder bit width (defines how many bits are considered for address decoding)
86
parameter              DEC_WD            =  3;
87
 
88
// Register addresses offset
89
parameter [DEC_WD-1:0] LED_CTRL          =  'h0,
90
                       KEY_SW_VAL        =  'h1,
91
                       KEY_SW_IRQ_EN     =  'h2,
92
                       KEY_SW_IRQ_EDGE   =  'h3,
93
                       KEY_SW_IRQ_VAL    =  'h4;
94
 
95
 
96
// Register one-hot decoder utilities
97
parameter              DEC_SZ            =  2**DEC_WD;
98
parameter [DEC_SZ-1:0] BASE_REG          =  {{DEC_SZ-1{1'b0}}, 1'b1};
99
 
100
// Register one-hot decoder
101
parameter [DEC_SZ-1:0] LED_CTRL_D        = (BASE_REG << LED_CTRL       ),
102
                       KEY_SW_VAL_D      = (BASE_REG << KEY_SW_VAL     ),
103
                       KEY_SW_IRQ_EN_D   = (BASE_REG << KEY_SW_IRQ_EN  ),
104
                       KEY_SW_IRQ_EDGE_D = (BASE_REG << KEY_SW_IRQ_EDGE),
105
                       KEY_SW_IRQ_VAL_D  = (BASE_REG << KEY_SW_IRQ_VAL );
106
 
107
//============================================================================
108
// 2)  REGISTER DECODER
109
//============================================================================
110
 
111
// Local register selection
112
wire              reg_sel      =  per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
113
 
114
// Register local address
115
wire [DEC_WD-1:0] reg_addr     =  {1'b0, per_addr[DEC_WD-2:0]};
116
 
117
// Register address decode
118
wire [DEC_SZ-1:0] reg_dec      = (LED_CTRL_D        &  {DEC_SZ{(reg_addr==(LED_CTRL        >>1))}}) |
119
                                 (KEY_SW_VAL_D      &  {DEC_SZ{(reg_addr==(KEY_SW_VAL      >>1))}}) |
120
                                 (KEY_SW_IRQ_EN_D   &  {DEC_SZ{(reg_addr==(KEY_SW_IRQ_EN   >>1))}}) |
121
                                 (KEY_SW_IRQ_EDGE_D &  {DEC_SZ{(reg_addr==(KEY_SW_IRQ_EDGE >>1))}}) |
122
                                 (KEY_SW_IRQ_VAL_D  &  {DEC_SZ{(reg_addr==(KEY_SW_IRQ_VAL  >>1))}});
123
 
124
// Read/Write probes
125
wire              reg_lo_write =  per_we[0] & reg_sel;
126
wire              reg_hi_write =  per_we[1] & reg_sel;
127
wire              reg_read     = ~|per_we   & reg_sel;
128
 
129
// Read/Write vectors
130
wire [DEC_SZ-1:0] reg_hi_wr    = reg_dec & {DEC_SZ{reg_hi_write}};
131
wire [DEC_SZ-1:0] reg_lo_wr    = reg_dec & {DEC_SZ{reg_lo_write}};
132
wire [DEC_SZ-1:0] reg_rd       = reg_dec & {DEC_SZ{reg_read}};
133
 
134
 
135
//============================================================================
136
// 3) REGISTERS
137
//============================================================================
138
 
139
// LED Control Register
140
//----------------------
141
reg  [7:0] led_ctrl;
142
 
143
wire       led_ctrl_wr  = LED_CTRL[0] ? reg_hi_wr[LED_CTRL] : reg_lo_wr[LED_CTRL];
144
wire [7:0] led_ctrl_nxt = LED_CTRL[0] ? per_din[15:8]       : per_din[7:0];
145
 
146
always @ (posedge mclk or posedge puc_rst)
147
  if (puc_rst)          led_ctrl <=  8'h00;
148
  else if (led_ctrl_wr) led_ctrl <=  led_ctrl_nxt;
149
 
150
assign led = led_ctrl;
151
 
152
// KEY_SW_VAL Register
153
//---------------------
154
 
155
// Synchronize and debounce the input signals
156
wire [1:0] key_deb;
157
wire [3:0] sw_deb;
158
sync_debouncer_10ms sync_debouncer_10ms_key1 (.signal_debounced(key_deb[1]), .clk_50mhz(mclk), .rst(puc_rst), .signal_async(key[1]));
159
sync_debouncer_10ms sync_debouncer_10ms_key0 (.signal_debounced(key_deb[0]), .clk_50mhz(mclk), .rst(puc_rst), .signal_async(key[0]));
160
sync_debouncer_10ms sync_debouncer_10ms_sw3  (.signal_debounced(sw_deb[3]),  .clk_50mhz(mclk), .rst(puc_rst), .signal_async(sw[3]));
161
sync_debouncer_10ms sync_debouncer_10ms_sw2  (.signal_debounced(sw_deb[2]),  .clk_50mhz(mclk), .rst(puc_rst), .signal_async(sw[2]));
162
sync_debouncer_10ms sync_debouncer_10ms_sw1  (.signal_debounced(sw_deb[1]),  .clk_50mhz(mclk), .rst(puc_rst), .signal_async(sw[1]));
163
sync_debouncer_10ms sync_debouncer_10ms_sw0  (.signal_debounced(sw_deb[0]),  .clk_50mhz(mclk), .rst(puc_rst), .signal_async(sw[0]));
164
 
165
wire [7:0] key_sw_val = {1'b0,      1'b0,      key_deb[1], key_deb[0],
166
                         sw_deb[3], sw_deb[2], sw_deb[1],  sw_deb[0] };
167
 
168
 
169
// KEY_SW_IRQ_EN Register
170
//----------------------
171
reg  [7:0] key_sw_irq_en;
172
 
173
wire       key_sw_irq_en_wr  = KEY_SW_IRQ_EN[0] ? reg_hi_wr[KEY_SW_IRQ_EN] : reg_lo_wr[KEY_SW_IRQ_EN];
174
wire [7:0] key_sw_irq_en_nxt = KEY_SW_IRQ_EN[0] ? per_din[15:8]            : per_din[7:0];
175
 
176
always @ (posedge mclk or posedge puc_rst)
177
  if (puc_rst)               key_sw_irq_en <=  8'h00;
178
  else if (key_sw_irq_en_wr) key_sw_irq_en <=  key_sw_irq_en_nxt & 8'h3F;
179
 
180
 
181
// KEY_SW_IRQ_EDGE Register
182
//--------------------------
183
reg  [7:0] key_sw_irq_edge;
184
 
185
wire       key_sw_irq_edge_wr  = KEY_SW_IRQ_EDGE[0] ? reg_hi_wr[KEY_SW_IRQ_EDGE] : reg_lo_wr[KEY_SW_IRQ_EDGE];
186
wire [7:0] key_sw_irq_edge_nxt = KEY_SW_IRQ_EDGE[0] ? per_din[15:8]              : per_din[7:0];
187
 
188
always @ (posedge mclk or posedge puc_rst)
189
  if (puc_rst)                 key_sw_irq_edge <=  8'h00;
190
  else if (key_sw_irq_edge_wr) key_sw_irq_edge <=  key_sw_irq_edge_nxt & 8'h3F;
191
 
192
 
193
// KEY_SW_IRQ_VAL Register
194
//-------------------------
195
reg  [7:0] key_sw_irq_val;
196
 
197
wire       key_sw_irq_val_wr  = KEY_SW_IRQ_VAL[0] ? reg_hi_wr[KEY_SW_IRQ_VAL] : reg_lo_wr[KEY_SW_IRQ_VAL];
198
wire [7:0] key_sw_irq_val_nxt = KEY_SW_IRQ_VAL[0] ? per_din[15:8]              : per_din[7:0];
199
 
200
wire [5:0] key_sw_irq_clr     = key_sw_irq_val_nxt[5:0] & {6{key_sw_irq_val_wr}}; // Clear IRQ flag when 1 is writen
201
wire [5:0] key_sw_irq_set;
202
 
203
always @ (posedge mclk or posedge puc_rst)
204
  if (puc_rst) key_sw_irq_val <=  8'h00;
205
  else         key_sw_irq_val <= {2'b00, (key_sw_irq_set | (~key_sw_irq_clr & key_sw_irq_val[5:0]))}; // IRQ set has priority over clear
206
 
207
assign  irq_key = |key_sw_irq_val[5:4];
208
assign  irq_sw  = |key_sw_irq_val[3:0];
209
 
210
//============================================================================
211
// 4) DATA OUTPUT GENERATION
212
//============================================================================
213
 
214
// Data output mux
215
wire [15:0] led_ctrl_rd        = (led_ctrl        & {8{reg_rd[LED_CTRL]}})        << (8 & {4{LED_CTRL[0]}});
216
wire [15:0] key_sw_val_rd      = (key_sw_val      & {8{reg_rd[KEY_SW_VAL]}})      << (8 & {4{KEY_SW_VAL[0]}});
217
wire [15:0] key_sw_irq_en_rd   = (key_sw_irq_en   & {8{reg_rd[KEY_SW_IRQ_EN]}})   << (8 & {4{KEY_SW_IRQ_EN[0]}});
218
wire [15:0] key_sw_irq_edge_rd = (key_sw_irq_edge & {8{reg_rd[KEY_SW_IRQ_EDGE]}}) << (8 & {4{KEY_SW_IRQ_EDGE[0]}});
219
wire [15:0] key_sw_irq_val_rd  = (key_sw_irq_val  & {8{reg_rd[KEY_SW_IRQ_VAL]}})  << (8 & {4{KEY_SW_IRQ_VAL[0]}});
220
 
221
wire [15:0] per_dout           =  led_ctrl_rd        |
222
                                  key_sw_val_rd      |
223
                                  key_sw_irq_en_rd   |
224
                                  key_sw_irq_edge_rd |
225
                                  key_sw_irq_val_rd;
226
 
227
 
228
//============================================================================
229
// 5) IRQ GENERATION
230
//============================================================================
231
 
232
// Delay debounced signal for edge detection
233
reg  [5:0] key_sw_deb_dly;
234
always @ (posedge mclk or posedge puc_rst)
235
  if (puc_rst) key_sw_deb_dly <=  6'h00;
236
  else         key_sw_deb_dly <=  key_sw_val[5:0];
237
 
238
wire [5:0] key_sw_posedge = ~key_sw_val[5:0] &  key_sw_deb_dly;
239
wire [5:0] key_sw_negedge =  key_sw_val[5:0] & ~key_sw_deb_dly;
240
wire [5:0] key_sw_edge    = (key_sw_posedge  &  key_sw_irq_edge[5:0]) |
241
                            (key_sw_negedge  & ~key_sw_irq_edge[5:0]);
242
 
243
assign key_sw_irq_set =  key_sw_irq_en[5:0] & key_sw_edge;
244
 
245
 
246
endmodule // omsp_de0_nano_soc_led_key_sw

powered by: WebSVN 2.1.0

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