]> rtime.felk.cvut.cz Git - fpga/openmsp430.git/blob - core/omsp_sfr.v
OpenMSP430 core verilog source files moved to "core" subdirectory.
[fpga/openmsp430.git] / core / omsp_sfr.v
1 //----------------------------------------------------------------------------
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_sfr.v
26 // 
27 // *Module Description:
28 //                       Processor Special function register
29 //
30 // *Author(s):
31 //              - Olivier Girard,    olgirard@gmail.com
32 //
33 //----------------------------------------------------------------------------
34 // $Rev: 34 $
35 // $LastChangedBy: olivier.girard $
36 // $LastChangedDate: 2009-12-29 20:10:34 +0100 (Tue, 29 Dec 2009) $
37 //----------------------------------------------------------------------------
38 `include "timescale.v"
39 `include "openMSP430_defines.v"
40
41 module  omsp_sfr (
42
43 // OUTPUTs
44     nmie,                         // Non-maskable interrupt enable
45     per_dout,                     // Peripheral data output
46     wdt_irq,                      // Watchdog-timer interrupt
47     wdt_reset,                    // Watchdog-timer reset
48     wdtie,                        // Watchdog-timer interrupt enable
49
50 // INPUTs
51     mclk,                         // Main system clock
52     nmi_acc,                      // Non-Maskable interrupt request accepted
53     per_addr,                     // Peripheral address
54     per_din,                      // Peripheral data input
55     per_en,                       // Peripheral enable (high active)
56     per_wen,                      // Peripheral write enable (high active)
57     por,                          // Power-on reset
58     puc,                          // Main system reset
59     wdtifg_clr,                   // Clear Watchdog-timer interrupt flag
60     wdtifg_set,                   // Set Watchdog-timer interrupt flag
61     wdtpw_error,                  // Watchdog-timer password error
62     wdttmsel                      // Watchdog-timer mode select
63 );
64
65 // OUTPUTs
66 //=========
67 output              nmie;         // Non-maskable interrupt enable
68 output       [15:0] per_dout;     // Peripheral data output
69 output              wdt_irq;      // Watchdog-timer interrupt
70 output              wdt_reset;    // Watchdog-timer reset
71 output              wdtie;        // Watchdog-timer interrupt enable
72
73 // INPUTs
74 //=========
75 input               mclk;         // Main system clock
76 input               nmi_acc;      // Non-Maskable interrupt request accepted
77 input         [7:0] per_addr;     // Peripheral address
78 input        [15:0] per_din;      // Peripheral data input
79 input               per_en;       // Peripheral enable (high active)
80 input         [1:0] per_wen;      // Peripheral write enable (high active)
81 input               por;          // Power-on reset
82 input               puc;          // Main system reset
83 input               wdtifg_clr;   // Clear Watchdog-timer interrupt flag
84 input               wdtifg_set;   // Set Watchdog-timer interrupt flag
85 input               wdtpw_error;  // Watchdog-timer password error
86 input               wdttmsel;     // Watchdog-timer mode select
87
88
89 //=============================================================================
90 // 1)  PARAMETER DECLARATION
91 //=============================================================================
92
93 // Register addresses
94 parameter           IE1        = 9'h000;
95 parameter           IFG1       = 9'h002;
96
97 // Register one-hot decoder
98 parameter           IE1_D      = (256'h1 << (IE1  /2));
99 parameter           IFG1_D     = (256'h1 << (IFG1 /2)); 
100
101
102 //============================================================================
103 // 2)  REGISTER DECODER
104 //============================================================================
105
106 // Register address decode
107 reg  [255:0]  reg_dec; 
108 always @(per_addr)
109   case (per_addr)
110     (IE1  /2):     reg_dec  =  IE1_D;
111     (IFG1 /2):     reg_dec  =  IFG1_D;
112     default  :     reg_dec  =  {256{1'b0}};
113   endcase
114
115 // Read/Write probes
116 wire         reg_lo_write =  per_wen[0] & per_en;
117 wire         reg_hi_write =  per_wen[1] & per_en;
118 wire         reg_read     = ~|per_wen   & per_en;
119
120 // Read/Write vectors
121 wire [255:0] reg_hi_wr    = reg_dec & {256{reg_hi_write}};
122 wire [255:0] reg_lo_wr    = reg_dec & {256{reg_lo_write}};
123 wire [255:0] reg_rd       = reg_dec & {256{reg_read}};
124
125
126 //============================================================================
127 // 3) REGISTERS
128 //============================================================================
129
130 // IE1 Register
131 //--------------
132 wire [7:0] ie1;
133 wire       ie1_wr  = IE1[0] ? reg_hi_wr[IE1/2] : reg_lo_wr[IE1/2];
134 wire [7:0] ie1_nxt = IE1[0] ? per_din[15:8]    : per_din[7:0];
135
136 reg        nmie;
137 always @ (posedge mclk or posedge puc)
138   if (puc)          nmie  <=  1'b0;
139   else if (nmi_acc) nmie  <=  1'b0; 
140   else if (ie1_wr)  nmie  <=  ie1_nxt[4];    
141
142 reg        wdtie;
143 always @ (posedge mclk or posedge puc)
144   if (puc)           wdtie <=  1'b0;
145   else if (ie1_wr)   wdtie <=  ie1_nxt[0];    
146
147 assign  ie1 = {3'b000, nmie, 3'b000, wdtie};
148
149
150 // IFG1 Register
151 //---------------
152 wire [7:0] ifg1;
153 wire       ifg1_wr  = IFG1[0] ? reg_hi_wr[IFG1/2] : reg_lo_wr[IFG1/2];
154 wire [7:0] ifg1_nxt = IFG1[0] ? per_din[15:8]     : per_din[7:0];
155
156 reg        nmiifg;
157 always @ (posedge mclk or posedge puc)
158   if (puc)           nmiifg <=  1'b0;
159   else if (nmi_acc)  nmiifg <=  1'b1;
160   else if (ifg1_wr)  nmiifg <=  ifg1_nxt[4];
161
162 reg        wdtifg;
163 always @ (posedge mclk or posedge por)
164   if (por)                        wdtifg <=  1'b0;
165   else if (wdtifg_set)            wdtifg <=  1'b1;
166   else if (wdttmsel & wdtifg_clr) wdtifg <=  1'b0;
167   else if (ifg1_wr)               wdtifg <=  ifg1_nxt[0];
168
169 assign  ifg1 = {3'b000, nmiifg, 3'b000, wdtifg};
170
171
172 //============================================================================
173 // 4) DATA OUTPUT GENERATION
174 //============================================================================
175
176 // Data output mux
177 wire [15:0] ie1_rd   = (ie1  & {8{reg_rd[IE1/2]}})  << (8 & {4{IE1[0]}});
178 wire [15:0] ifg1_rd  = (ifg1 & {8{reg_rd[IFG1/2]}}) << (8 & {4{IFG1[0]}});
179
180 wire [15:0] per_dout =  ie1_rd   |
181                         ifg1_rd;
182
183
184 //=============================================================================
185 // 5)  WATCHDOG INTERRUPT & RESET
186 //=============================================================================
187
188 // Watchdog interrupt generation
189 //---------------------------------
190 wire    wdt_irq      = wdttmsel & wdtifg & wdtie;
191
192    
193 // Watchdog reset generation
194 //-----------------------------
195 reg     wdt_reset;
196
197 always @ (posedge mclk or posedge por)
198   if (por) wdt_reset <= 1'b0;
199   else     wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
200
201
202 endmodule // omsp_sfr
203
204 `include "openMSP430_undefines.v"