]> rtime.felk.cvut.cz Git - fpga/openmsp430.git/blob - omsp_register_file.v
66d8458b80d414b7756e8b3622c4b191e150add1
[fpga/openmsp430.git] / omsp_register_file.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_register_file.v
26 // 
27 // *Module Description:
28 //                       openMSP430 Register files
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_register_file (
42
43 // OUTPUTs
44     cpuoff,                       // Turns off the CPU
45     gie,                          // General interrupt enable
46     oscoff,                       // Turns off LFXT1 clock input
47     pc_sw,                        // Program counter software value
48     pc_sw_wr,                     // Program counter software write
49     reg_dest,                     // Selected register destination content
50     reg_src,                      // Selected register source content
51     scg1,                         // System clock generator 1. Turns off the SMCLK
52     status,                       // R2 Status {V,N,Z,C}
53
54 // INPUTs
55     alu_stat,                     // ALU Status {V,N,Z,C}
56     alu_stat_wr,                  // ALU Status write {V,N,Z,C}
57     inst_bw,                      // Decoded Inst: byte width
58     inst_dest,                    // Register destination selection
59     inst_src,                     // Register source selection
60     mclk,                         // Main system clock
61     pc,                           // Program counter
62     puc,                          // Main system reset
63     reg_dest_val,                 // Selected register destination value
64     reg_dest_wr,                  // Write selected register destination
65     reg_pc_call,                  // Trigger PC update for a CALL instruction
66     reg_sp_val,                   // Stack Pointer next value
67     reg_sp_wr,                    // Stack Pointer write
68     reg_sr_wr,                    // Status register update for RETI instruction
69     reg_sr_clr,                   // Status register clear for interrupts
70     reg_incr                      // Increment source register
71 );
72
73 // OUTPUTs
74 //=========
75 output              cpuoff;       // Turns off the CPU
76 output              gie;          // General interrupt enable
77 output              oscoff;       // Turns off LFXT1 clock input
78 output       [15:0] pc_sw;        // Program counter software value
79 output              pc_sw_wr;     // Program counter software write
80 output       [15:0] reg_dest;     // Selected register destination content
81 output       [15:0] reg_src;      // Selected register source content
82 output              scg1;         // System clock generator 1. Turns off the SMCLK
83 output        [3:0] status;       // R2 Status {V,N,Z,C}
84
85 // INPUTs
86 //=========
87 input         [3:0] alu_stat;     // ALU Status {V,N,Z,C}
88 input         [3:0] alu_stat_wr;  // ALU Status write {V,N,Z,C}
89 input               inst_bw;      // Decoded Inst: byte width
90 input        [15:0] inst_dest;    // Register destination selection
91 input        [15:0] inst_src;     // Register source selection
92 input               mclk;         // Main system clock
93 input        [15:0] pc;           // Program counter
94 input               puc;          // Main system reset
95 input        [15:0] reg_dest_val; // Selected register destination value
96 input               reg_dest_wr;  // Write selected register destination
97 input               reg_pc_call;  // Trigger PC update for a CALL instruction
98 input        [15:0] reg_sp_val;   // Stack Pointer next value
99 input               reg_sp_wr;    // Stack Pointer write
100 input               reg_sr_wr;    // Status register update for RETI instruction
101 input               reg_sr_clr;   // Status register clear for interrupts
102 input               reg_incr;     // Increment source register
103
104
105 //=============================================================================
106 // 1)  AUTOINCREMENT UNIT
107 //=============================================================================
108
109 wire [15:0] incr_op         = inst_bw ? 16'h0001 : 16'h0002;
110 wire [15:0] reg_incr_val    = reg_src+incr_op;
111
112 wire [15:0] reg_dest_val_in = inst_bw ? {8'h00,reg_dest_val[7:0]} : reg_dest_val;
113
114
115 //=============================================================================
116 // 2)  SPECIAL REGISTERS (R1/R2/R3)
117 //=============================================================================
118
119 // Source input selection mask (for interrupt support)
120 //-----------------------------------------------------
121
122 wire [15:0] inst_src_in = reg_sr_clr ? 16'h0004 : inst_src;
123
124
125 // R0: Program counter
126 //---------------------
127
128 wire [15:0] r0       = pc;
129
130 wire [15:0] pc_sw    = reg_dest_val_in;
131 wire        pc_sw_wr = (inst_dest[0] & reg_dest_wr) | reg_pc_call;
132
133
134 // R1: Stack pointer
135 //-------------------
136 reg [15:0] r1;
137 wire       r1_wr  = inst_dest[1] & reg_dest_wr;
138 wire       r1_inc = inst_src_in[1]  & reg_incr;
139
140 always @(posedge mclk or posedge puc)
141   if (puc)            r1 <= 16'h0000;
142   else if (r1_wr)     r1 <= reg_dest_val_in & 16'hfffe;
143   else if (reg_sp_wr) r1 <= reg_sp_val      & 16'hfffe;
144   else if (r1_inc)    r1 <= reg_incr_val    & 16'hfffe;
145
146
147 // R2: Status register
148 //---------------------
149 reg  [15:0] r2;
150 wire        r2_wr  = (inst_dest[2] & reg_dest_wr) | reg_sr_wr;
151
152 wire        r2_c   = alu_stat_wr[0] ? alu_stat[0]       :
153                      r2_wr          ? reg_dest_val_in[0]   : r2[0]; // C
154
155 wire        r2_z   = alu_stat_wr[1] ? alu_stat[1]       :
156                      r2_wr          ? reg_dest_val_in[1]   : r2[1]; // Z
157
158 wire        r2_n   = alu_stat_wr[2] ? alu_stat[2]       :
159                      r2_wr          ? reg_dest_val_in[2]   : r2[2]; // N
160
161 wire  [7:3] r2_nxt = r2_wr          ? reg_dest_val_in[7:3] : r2[7:3];
162
163 wire        r2_v   = alu_stat_wr[3] ? alu_stat[3]       :
164                      r2_wr          ? reg_dest_val_in[8]   : r2[8]; // V
165
166
167 always @(posedge mclk or posedge puc)
168   if (puc)             r2 <= 16'h0000;
169   else if (reg_sr_clr) r2 <= 16'h0000;
170   else                 r2 <= {7'h00, r2_v, r2_nxt, r2_n, r2_z, r2_c};
171
172 assign status = {r2[8], r2[2:0]};
173 assign gie    =  r2[3];
174 assign cpuoff =  r2[4] | (r2_nxt[4] & r2_wr);
175 assign oscoff =  r2[5];
176 assign scg1   =  r2[7];
177
178
179 // R3: Constant generator
180 //------------------------
181 reg [15:0] r3;
182 wire       r3_wr  = inst_dest[3] & reg_dest_wr;
183 wire       r3_inc = inst_src_in[3]  & reg_incr;
184
185 always @(posedge mclk or posedge puc)
186   if (puc)         r3 <= 16'h0000;
187   else if (r3_wr)  r3 <= reg_dest_val_in;
188   else if (r3_inc) r3 <= reg_incr_val;
189
190
191 //=============================================================================
192 // 4)  GENERAL PURPOSE REGISTERS (R4...R15)
193 //=============================================================================
194
195 // R4
196 reg [15:0] r4;
197 wire       r4_wr  = inst_dest[4] & reg_dest_wr;
198 wire       r4_inc = inst_src_in[4]  & reg_incr;
199 always @(posedge mclk or posedge puc)
200   if (puc)          r4  <= 16'h0000;
201   else if (r4_wr)   r4  <= reg_dest_val_in;
202   else if (r4_inc)  r4  <= reg_incr_val;
203
204 // R5
205 reg [15:0] r5;
206 wire       r5_wr  = inst_dest[5] & reg_dest_wr;
207 wire       r5_inc = inst_src_in[5]  & reg_incr;
208 always @(posedge mclk or posedge puc)
209   if (puc)          r5  <= 16'h0000;
210   else if (r5_wr)   r5  <= reg_dest_val_in;
211   else if (r5_inc)  r5  <= reg_incr_val;
212
213 // R6
214 reg [15:0] r6;
215 wire       r6_wr  = inst_dest[6] & reg_dest_wr;
216 wire       r6_inc = inst_src_in[6]  & reg_incr;
217 always @(posedge mclk or posedge puc)
218   if (puc)          r6  <= 16'h0000;
219   else if (r6_wr)   r6  <= reg_dest_val_in;
220   else if (r6_inc)  r6  <= reg_incr_val;
221
222 // R7
223 reg [15:0] r7;
224 wire       r7_wr  = inst_dest[7] & reg_dest_wr;
225 wire       r7_inc = inst_src_in[7]  & reg_incr;
226 always @(posedge mclk or posedge puc)
227   if (puc)          r7  <= 16'h0000;
228   else if (r7_wr)   r7  <= reg_dest_val_in;
229   else if (r7_inc)  r7  <= reg_incr_val;
230
231 // R8
232 reg [15:0] r8;
233 wire       r8_wr  = inst_dest[8] & reg_dest_wr;
234 wire       r8_inc = inst_src_in[8]  & reg_incr;
235 always @(posedge mclk or posedge puc)
236   if (puc)          r8  <= 16'h0000;
237   else if (r8_wr)   r8  <= reg_dest_val_in;
238   else if (r8_inc)  r8  <= reg_incr_val;
239
240 // R9
241 reg [15:0] r9;
242 wire       r9_wr  = inst_dest[9] & reg_dest_wr;
243 wire       r9_inc = inst_src_in[9]  & reg_incr;
244 always @(posedge mclk or posedge puc)
245   if (puc)          r9  <= 16'h0000;
246   else if (r9_wr)   r9  <= reg_dest_val_in;
247   else if (r9_inc)  r9  <= reg_incr_val;
248
249 // R10
250 reg [15:0] r10;
251 wire       r10_wr  = inst_dest[10] & reg_dest_wr;
252 wire       r10_inc = inst_src_in[10]  & reg_incr;
253 always @(posedge mclk or posedge puc)
254   if (puc)          r10 <= 16'h0000;
255   else if (r10_wr)  r10 <= reg_dest_val_in;
256   else if (r10_inc) r10 <= reg_incr_val;
257
258 // R11
259 reg [15:0] r11;
260 wire       r11_wr  = inst_dest[11] & reg_dest_wr;
261 wire       r11_inc = inst_src_in[11]  & reg_incr;
262 always @(posedge mclk or posedge puc)
263   if (puc)          r11 <= 16'h0000;
264   else if (r11_wr)  r11 <= reg_dest_val_in;
265   else if (r11_inc) r11 <= reg_incr_val;
266
267 // R12
268 reg [15:0] r12;
269 wire       r12_wr  = inst_dest[12] & reg_dest_wr;
270 wire       r12_inc = inst_src_in[12]  & reg_incr;
271 always @(posedge mclk or posedge puc)
272   if (puc)          r12 <= 16'h0000;
273   else if (r12_wr)  r12 <= reg_dest_val_in;
274   else if (r12_inc) r12 <= reg_incr_val;
275
276 // R13
277 reg [15:0] r13;
278 wire       r13_wr  = inst_dest[13] & reg_dest_wr;
279 wire       r13_inc = inst_src_in[13]  & reg_incr;
280 always @(posedge mclk or posedge puc)
281   if (puc)          r13 <= 16'h0000;
282   else if (r13_wr)  r13 <= reg_dest_val_in;
283   else if (r13_inc) r13 <= reg_incr_val;
284
285 // R14
286 reg [15:0] r14;
287 wire       r14_wr  = inst_dest[14] & reg_dest_wr;
288 wire       r14_inc = inst_src_in[14]  & reg_incr;
289 always @(posedge mclk or posedge puc)
290   if (puc)          r14 <= 16'h0000;
291   else if (r14_wr)  r14 <= reg_dest_val_in;
292   else if (r14_inc) r14 <= reg_incr_val;
293
294 // R15
295 reg [15:0] r15;
296 wire       r15_wr  = inst_dest[15] & reg_dest_wr;
297 wire       r15_inc = inst_src_in[15]  & reg_incr;
298 always @(posedge mclk or posedge puc)
299   if (puc)          r15 <= 16'h0000;
300   else if (r15_wr)  r15 <= reg_dest_val_in;
301   else if (r15_inc) r15 <= reg_incr_val;
302
303
304 //=============================================================================
305 // 5)  READ MUX
306 //=============================================================================
307
308 assign reg_src  = (r0      & {16{inst_src_in[0]}})   | 
309                   (r1      & {16{inst_src_in[1]}})   | 
310                   (r2      & {16{inst_src_in[2]}})   | 
311                   (r3      & {16{inst_src_in[3]}})   | 
312                   (r4      & {16{inst_src_in[4]}})   | 
313                   (r5      & {16{inst_src_in[5]}})   | 
314                   (r6      & {16{inst_src_in[6]}})   | 
315                   (r7      & {16{inst_src_in[7]}})   | 
316                   (r8      & {16{inst_src_in[8]}})   | 
317                   (r9      & {16{inst_src_in[9]}})   | 
318                   (r10     & {16{inst_src_in[10]}})  | 
319                   (r11     & {16{inst_src_in[11]}})  | 
320                   (r12     & {16{inst_src_in[12]}})  | 
321                   (r13     & {16{inst_src_in[13]}})  | 
322                   (r14     & {16{inst_src_in[14]}})  | 
323                   (r15     & {16{inst_src_in[15]}});
324
325 assign reg_dest = (r0      & {16{inst_dest[0]}})  | 
326                   (r1      & {16{inst_dest[1]}})  | 
327                   (r2      & {16{inst_dest[2]}})  | 
328                   (r3      & {16{inst_dest[3]}})  | 
329                   (r4      & {16{inst_dest[4]}})  | 
330                   (r5      & {16{inst_dest[5]}})  | 
331                   (r6      & {16{inst_dest[6]}})  | 
332                   (r7      & {16{inst_dest[7]}})  | 
333                   (r8      & {16{inst_dest[8]}})  | 
334                   (r9      & {16{inst_dest[9]}})  | 
335                   (r10     & {16{inst_dest[10]}}) | 
336                   (r11     & {16{inst_dest[11]}}) | 
337                   (r12     & {16{inst_dest[12]}}) | 
338                   (r13     & {16{inst_dest[13]}}) | 
339                   (r14     & {16{inst_dest[14]}}) | 
340                   (r15     & {16{inst_dest[15]}});
341
342
343 endmodule // omsp_register_file
344
345 `include "openMSP430_undefines.v"