1 //----------------------------------------------------------------------------
2 // Copyright (C) 2001 Authors
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
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.
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.
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
23 //----------------------------------------------------------------------------
25 // *File Name: omsp_sfr.v
27 // *Module Description:
28 // Processor Special function register
31 // - Olivier Girard, olgirard@gmail.com
33 //----------------------------------------------------------------------------
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"
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
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
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
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
89 //=============================================================================
90 // 1) PARAMETER DECLARATION
91 //=============================================================================
94 parameter IE1 = 9'h000;
95 parameter IFG1 = 9'h002;
97 // Register one-hot decoder
98 parameter IE1_D = (256'h1 << (IE1 /2));
99 parameter IFG1_D = (256'h1 << (IFG1 /2));
102 //============================================================================
103 // 2) REGISTER DECODER
104 //============================================================================
106 // Register address decode
110 (IE1 /2): reg_dec = IE1_D;
111 (IFG1 /2): reg_dec = IFG1_D;
112 default : reg_dec = {256{1'b0}};
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;
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}};
126 //============================================================================
128 //============================================================================
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];
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];
143 always @ (posedge mclk or posedge puc)
144 if (puc) wdtie <= 1'b0;
145 else if (ie1_wr) wdtie <= ie1_nxt[0];
147 assign ie1 = {3'b000, nmie, 3'b000, wdtie};
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];
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];
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];
169 assign ifg1 = {3'b000, nmiifg, 3'b000, wdtifg};
172 //============================================================================
173 // 4) DATA OUTPUT GENERATION
174 //============================================================================
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]}});
180 wire [15:0] per_dout = ie1_rd |
184 //=============================================================================
185 // 5) WATCHDOG INTERRUPT & RESET
186 //=============================================================================
188 // Watchdog interrupt generation
189 //---------------------------------
190 wire wdt_irq = wdttmsel & wdtifg & wdtie;
193 // Watchdog reset generation
194 //-----------------------------
197 always @ (posedge mclk or posedge por)
198 if (por) wdt_reset <= 1'b0;
199 else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
202 endmodule // omsp_sfr
204 `include "openMSP430_undefines.v"