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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_register_file.v] - Blame information for rev 103

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

powered by: WebSVN 2.1.0

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