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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [actel_m1a3pl_dev_kit/] [rtl/] [verilog/] [openmsp430/] [omsp_register_file.v] - Blame information for rev 85

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 80 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_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: 37 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2009-12-29 21:58:14 +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"

powered by: WebSVN 2.1.0

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