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

Subversion Repositories openmsp430

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

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_execution_unit.v
26
// 
27
// *Module Description:
28
//                       openMSP430 Execution unit
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 104 olivier.gi
// $Rev: 103 $
35 80 olivier.gi
// $LastChangedBy: olivier.girard $
36 104 olivier.gi
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
37 80 olivier.gi
//----------------------------------------------------------------------------
38 104 olivier.gi
`ifdef OMSP_NO_INCLUDE
39
`else
40 80 olivier.gi
`include "openMSP430_defines.v"
41 104 olivier.gi
`endif
42 80 olivier.gi
 
43
module  omsp_execution_unit (
44
 
45
// OUTPUTs
46
    cpuoff,                        // Turns off the CPU
47
    dbg_reg_din,                   // Debug unit CPU register data input
48
    gie,                           // General interrupt enable
49
    mab,                           // Memory address bus
50
    mb_en,                         // Memory bus enable
51
    mb_wr,                         // Memory bus write transfer
52
    mdb_out,                       // Memory data bus output
53
    oscoff,                        // Turns off LFXT1 clock input
54
    pc_sw,                         // Program counter software value
55
    pc_sw_wr,                      // Program counter software write
56
    scg1,                          // System clock generator 1. Turns off the SMCLK
57
 
58
// INPUTs
59
    dbg_halt_st,                   // Halt/Run status from CPU
60
    dbg_mem_dout,                  // Debug unit data output
61
    dbg_reg_wr,                    // Debug unit CPU register write
62
    e_state,                       // Execution state
63
    exec_done,                     // Execution completed
64
    inst_ad,                       // Decoded Inst: destination addressing mode
65
    inst_as,                       // Decoded Inst: source addressing mode
66
    inst_alu,                      // ALU control signals
67
    inst_bw,                       // Decoded Inst: byte width
68
    inst_dest,                     // Decoded Inst: destination (one hot)
69
    inst_dext,                     // Decoded Inst: destination extended instruction word
70
    inst_irq_rst,                  // Decoded Inst: reset interrupt
71
    inst_jmp,                      // Decoded Inst: Conditional jump
72 105 olivier.gi
    inst_mov,                      // Decoded Inst: mov instruction
73 80 olivier.gi
    inst_sext,                     // Decoded Inst: source extended instruction word
74
    inst_so,                       // Decoded Inst: Single-operand arithmetic
75
    inst_src,                      // Decoded Inst: source (one hot)
76
    inst_type,                     // Decoded Instruction type
77
    mclk,                          // Main system clock
78
    mdb_in,                        // Memory data bus input
79
    pc,                            // Program counter
80
    pc_nxt,                        // Next PC value (for CALL & IRQ)
81 111 olivier.gi
    puc_rst                        // Main system reset
82 80 olivier.gi
);
83
 
84
// OUTPUTs
85
//=========
86
output              cpuoff;        // Turns off the CPU
87
output       [15:0] dbg_reg_din;   // Debug unit CPU register data input
88
output              gie;           // General interrupt enable
89
output       [15:0] mab;           // Memory address bus
90
output              mb_en;         // Memory bus enable
91
output        [1:0] mb_wr;         // Memory bus write transfer
92
output       [15:0] mdb_out;       // Memory data bus output
93
output              oscoff;        // Turns off LFXT1 clock input
94
output       [15:0] pc_sw;         // Program counter software value
95
output              pc_sw_wr;      // Program counter software write
96
output              scg1;          // System clock generator 1. Turns off the SMCLK
97
 
98
// INPUTs
99
//=========
100
input               dbg_halt_st;   // Halt/Run status from CPU
101
input        [15:0] dbg_mem_dout;  // Debug unit data output
102
input               dbg_reg_wr;    // Debug unit CPU register write
103
input         [3:0] e_state;       // Execution state
104
input               exec_done;     // Execution completed
105
input         [7:0] inst_ad;       // Decoded Inst: destination addressing mode
106
input         [7:0] inst_as;       // Decoded Inst: source addressing mode
107
input        [11:0] inst_alu;      // ALU control signals
108
input               inst_bw;       // Decoded Inst: byte width
109
input        [15:0] inst_dest;     // Decoded Inst: destination (one hot)
110
input        [15:0] inst_dext;     // Decoded Inst: destination extended instruction word
111
input               inst_irq_rst;  // Decoded Inst: reset interrupt
112
input         [7:0] inst_jmp;      // Decoded Inst: Conditional jump
113 105 olivier.gi
input               inst_mov;      // Decoded Inst: mov instruction
114 80 olivier.gi
input        [15:0] inst_sext;     // Decoded Inst: source extended instruction word
115
input         [7:0] inst_so;       // Decoded Inst: Single-operand arithmetic
116
input        [15:0] inst_src;      // Decoded Inst: source (one hot)
117
input         [2:0] inst_type;     // Decoded Instruction type
118
input               mclk;          // Main system clock
119
input        [15:0] mdb_in;        // Memory data bus input
120
input        [15:0] pc;            // Program counter
121
input        [15:0] pc_nxt;        // Next PC value (for CALL & IRQ)
122 111 olivier.gi
input               puc_rst;       // Main system reset
123 80 olivier.gi
 
124
 
125
//=============================================================================
126
// 1)  INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
127
//=============================================================================
128
 
129
wire         [15:0] alu_out;
130
wire         [15:0] alu_out_add;
131
wire          [3:0] alu_stat;
132
wire          [3:0] alu_stat_wr;
133
wire         [15:0] op_dst;
134
wire         [15:0] op_src;
135
wire         [15:0] reg_dest;
136
wire         [15:0] reg_src;
137
wire         [15:0] mdb_in_bw;
138
wire         [15:0] mdb_in_val;
139
wire          [3:0] status;
140
 
141
 
142
//=============================================================================
143
// 2)  REGISTER FILE
144
//=============================================================================
145
 
146
wire reg_dest_wr  = ((e_state==`E_EXEC) & (
147
                     (inst_type[`INST_TO] & inst_ad[`DIR] & ~inst_alu[`EXEC_NO_WR])  |
148
                     (inst_type[`INST_SO] & inst_as[`DIR] & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI])) |
149
                      inst_type[`INST_JMP])) | dbg_reg_wr;
150
 
151
wire reg_sp_wr    = (((e_state==`E_IRQ_1) | (e_state==`E_IRQ_3)) & ~inst_irq_rst) |
152 104 olivier.gi
                     ((e_state==`E_DST_RD) & ((inst_so[`PUSH] &  ~inst_as[`IDX] &
153
                                                                ~((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1])) |
154
                                               inst_so[`CALL])) |
155
                     ((e_state==`E_SRC_AD) &  (inst_so[`PUSH] &  inst_as[`IDX])) |
156
                     ((e_state==`E_SRC_RD) &  (inst_so[`PUSH] &  ((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1])));
157 80 olivier.gi
 
158
wire reg_sr_wr    =  (e_state==`E_DST_RD) & inst_so[`RETI];
159
 
160
wire reg_sr_clr   =  (e_state==`E_IRQ_2);
161
 
162
wire reg_pc_call  = ((e_state==`E_EXEC)   & inst_so[`CALL]) |
163
                    ((e_state==`E_DST_WR) & inst_so[`RETI]);
164
 
165
wire reg_incr     =  (exec_done          & inst_as[`INDIR_I]) |
166
                    ((e_state==`E_SRC_RD) & inst_so[`RETI])    |
167
                    ((e_state==`E_EXEC)   & inst_so[`RETI]);
168
 
169
assign dbg_reg_din = reg_dest;
170
 
171
 
172
omsp_register_file register_file_0 (
173
 
174
// OUTPUTs
175
    .cpuoff       (cpuoff),       // Turns off the CPU
176
    .gie          (gie),          // General interrupt enable
177
    .oscoff       (oscoff),       // Turns off LFXT1 clock input
178
    .pc_sw        (pc_sw),        // Program counter software value
179
    .pc_sw_wr     (pc_sw_wr),     // Program counter software write
180
    .reg_dest     (reg_dest),     // Selected register destination content
181
    .reg_src      (reg_src),      // Selected register source content
182
    .scg1         (scg1),         // System clock generator 1. Turns off the SMCLK
183
    .status       (status),       // R2 Status {V,N,Z,C}
184
 
185
// INPUTs
186
    .alu_stat     (alu_stat),     // ALU Status {V,N,Z,C}
187
    .alu_stat_wr  (alu_stat_wr),  // ALU Status write {V,N,Z,C}
188
    .inst_bw      (inst_bw),      // Decoded Inst: byte width
189
    .inst_dest    (inst_dest),    // Register destination selection
190
    .inst_src     (inst_src),     // Register source selection
191
    .mclk         (mclk),         // Main system clock
192
    .pc           (pc),           // Program counter
193 111 olivier.gi
    .puc_rst      (puc_rst),      // Main system reset
194 80 olivier.gi
    .reg_dest_val (alu_out),      // Selected register destination value
195
    .reg_dest_wr  (reg_dest_wr),  // Write selected register destination
196
    .reg_pc_call  (reg_pc_call),  // Trigger PC update for a CALL instruction
197
    .reg_sp_val   (alu_out_add),  // Stack Pointer next value
198
    .reg_sp_wr    (reg_sp_wr),    // Stack Pointer write
199
    .reg_sr_clr   (reg_sr_clr),   // Status register clear for interrupts
200
    .reg_sr_wr    (reg_sr_wr),    // Status Register update for RETI instruction
201
    .reg_incr     (reg_incr)      // Increment source register
202
);
203
 
204
 
205
//=============================================================================
206
// 3)  SOURCE OPERAND MUXING
207
//=============================================================================
208
// inst_as[`DIR]    : Register direct.   -> Source is in register
209
// inst_as[`IDX]    : Register indexed.  -> Source is in memory, address is register+offset
210
// inst_as[`INDIR]  : Register indirect.
211
// inst_as[`INDIR_I]: Register indirect autoincrement.
212
// inst_as[`SYMB]   : Symbolic (operand is in memory at address PC+x).
213
// inst_as[`IMM]    : Immediate (operand is next word in the instruction stream).
214
// inst_as[`ABS]    : Absolute (operand is in memory at address x).
215
// inst_as[`CONST]  : Constant.
216
 
217
wire src_reg_src_sel    =  (e_state==`E_IRQ_0)                    |
218
                           (e_state==`E_IRQ_2)                    |
219
                          ((e_state==`E_SRC_RD) & ~inst_as[`ABS]) |
220
                          ((e_state==`E_SRC_WR) & ~inst_as[`ABS]) |
221
                          ((e_state==`E_EXEC)   &  inst_as[`DIR] & ~inst_type[`INST_JMP]);
222
 
223
wire src_reg_dest_sel   =  (e_state==`E_IRQ_1)                    |
224
                           (e_state==`E_IRQ_3)                    |
225 104 olivier.gi
                          ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL])) |
226
                          ((e_state==`E_SRC_AD) &  inst_so[`PUSH] & inst_as[`IDX]);
227 80 olivier.gi
 
228
wire src_mdb_in_val_sel = ((e_state==`E_DST_RD) &  inst_so[`RETI])                     |
229
                          ((e_state==`E_EXEC)   & (inst_as[`INDIR] | inst_as[`INDIR_I] |
230
                                                   inst_as[`IDX]   | inst_as[`SYMB]    |
231
                                                   inst_as[`ABS]));
232
 
233
wire src_inst_dext_sel =  ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL])) |
234
                          ((e_state==`E_DST_WR) & ~(inst_so[`PUSH] | inst_so[`CALL]   |
235
                                                    inst_so[`RETI]));
236
 
237
wire src_inst_sext_sel =  ((e_state==`E_EXEC)   &  (inst_type[`INST_JMP] | inst_as[`IMM] |
238
                                                    inst_as[`CONST]      | inst_so[`RETI]));
239
 
240
 
241
assign op_src = src_reg_src_sel     ?  reg_src    :
242
                src_reg_dest_sel    ?  reg_dest   :
243
                src_mdb_in_val_sel  ?  mdb_in_val :
244
                src_inst_dext_sel   ?  inst_dext  :
245
                src_inst_sext_sel   ?  inst_sext  : 16'h0000;
246
 
247
 
248
//=============================================================================
249
// 4)  DESTINATION OPERAND MUXING
250
//=============================================================================
251
// inst_ad[`DIR]    : Register direct.
252
// inst_ad[`IDX]    : Register indexed.
253
// inst_ad[`SYMB]   : Symbolic (operand is in memory at address PC+x).
254
// inst_ad[`ABS]    : Absolute (operand is in memory at address x).
255
 
256
 
257
wire dst_inst_sext_sel  = ((e_state==`E_SRC_RD) & (inst_as[`IDX] | inst_as[`SYMB] |
258
                                                   inst_as[`ABS]))                |
259
                          ((e_state==`E_SRC_WR) & (inst_as[`IDX] | inst_as[`SYMB] |
260
                                                   inst_as[`ABS]));
261
 
262
wire dst_mdb_in_bw_sel  = ((e_state==`E_DST_WR) &   inst_so[`RETI]) |
263
                          ((e_state==`E_EXEC)   & ~(inst_ad[`DIR] | inst_type[`INST_JMP] |
264
                                                    inst_type[`INST_SO]) & ~inst_so[`RETI]);
265
 
266
wire dst_fffe_sel       =  (e_state==`E_IRQ_0)  |
267
                           (e_state==`E_IRQ_1)  |
268
                           (e_state==`E_IRQ_3)  |
269 104 olivier.gi
                          ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & ~inst_so[`RETI]) |
270
                          ((e_state==`E_SRC_AD) &  inst_so[`PUSH] & inst_as[`IDX]) |
271
                          ((e_state==`E_SRC_RD) &  inst_so[`PUSH] & (inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]);
272 80 olivier.gi
 
273
wire dst_reg_dest_sel   = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_ad[`ABS] | inst_so[`RETI])) |
274
                          ((e_state==`E_DST_WR) &  ~inst_ad[`ABS]) |
275
                          ((e_state==`E_EXEC)   &  (inst_ad[`DIR] | inst_type[`INST_JMP] |
276
                                                    inst_type[`INST_SO]) & ~inst_so[`RETI]);
277
 
278
 
279
assign op_dst = dbg_halt_st        ? dbg_mem_dout  :
280
                dst_inst_sext_sel  ? inst_sext     :
281
                dst_mdb_in_bw_sel  ? mdb_in_bw     :
282
                dst_reg_dest_sel   ? reg_dest      :
283
                dst_fffe_sel       ? 16'hfffe      : 16'h0000;
284
 
285
 
286
//=============================================================================
287
// 5)  ALU
288
//=============================================================================
289
 
290
wire exec_cycle = (e_state==`E_EXEC);
291
 
292
omsp_alu alu_0 (
293
 
294
// OUTPUTs
295
    .alu_out      (alu_out),      // ALU output value
296
    .alu_out_add  (alu_out_add),  // ALU adder output value
297
    .alu_stat     (alu_stat),     // ALU Status {V,N,Z,C}
298
    .alu_stat_wr  (alu_stat_wr),  // ALU Status write {V,N,Z,C}
299
 
300
// INPUTs
301
    .dbg_halt_st  (dbg_halt_st),  // Halt/Run status from CPU
302
    .exec_cycle   (exec_cycle),   // Instruction execution cycle
303
    .inst_alu     (inst_alu),     // ALU control signals
304
    .inst_bw      (inst_bw),      // Decoded Inst: byte width
305
    .inst_jmp     (inst_jmp),     // Decoded Inst: Conditional jump
306
    .inst_so      (inst_so),      // Single-operand arithmetic
307
    .op_dst       (op_dst),       // Destination operand
308
    .op_src       (op_src),       // Source operand
309
    .status       (status)        // R2 Status {V,N,Z,C}
310
);
311
 
312
 
313
//=============================================================================
314
// 6)  MEMORY INTERFACE
315
//=============================================================================
316
 
317
// Detect memory read/write access
318 105 olivier.gi
assign      mb_en     = ((e_state==`E_IRQ_1)  & ~inst_irq_rst)        |
319
                        ((e_state==`E_IRQ_3)  & ~inst_irq_rst)        |
320
                        ((e_state==`E_SRC_RD) & ~inst_as[`IMM])       |
321
                         (e_state==`E_SRC_WR)                         |
322
                        ((e_state==`E_EXEC)   &  inst_so[`RETI])      |
323
                        ((e_state==`E_DST_RD) & ~inst_type[`INST_SO]
324
                                              & ~inst_mov)            |
325 80 olivier.gi
                         (e_state==`E_DST_WR);
326
 
327
wire  [1:0] mb_wr_msk =  inst_alu[`EXEC_NO_WR]  ? 2'b00 :
328
                        ~inst_bw                ? 2'b11 :
329
                         alu_out_add[0]         ? 2'b10 : 2'b01;
330
assign      mb_wr     = ({2{(e_state==`E_IRQ_1)}}  |
331
                         {2{(e_state==`E_IRQ_3)}}  |
332
                         {2{(e_state==`E_DST_WR)}} |
333
                         {2{(e_state==`E_SRC_WR)}}) & mb_wr_msk;
334
 
335
// Memory address bus
336
assign      mab       = alu_out_add[15:0];
337
 
338
// Memory data bus output
339
reg  [15:0] mdb_out_nxt;
340 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
341
  if (puc_rst)                                        mdb_out_nxt <= 16'h0000;
342 80 olivier.gi
  else if (e_state==`E_DST_RD)                        mdb_out_nxt <= pc_nxt;
343
  else if ((e_state==`E_EXEC & ~inst_so[`CALL]) |
344
           (e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)) mdb_out_nxt <= alu_out;
345
 
346
assign      mdb_out = inst_bw ? {2{mdb_out_nxt[7:0]}} : mdb_out_nxt;
347
 
348
// Format memory data bus input depending on BW
349
reg        mab_lsb;
350 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
351
  if (puc_rst)    mab_lsb <= 1'b0;
352 80 olivier.gi
  else if (mb_en) mab_lsb <= alu_out_add[0];
353
 
354
assign mdb_in_bw  = ~inst_bw ? mdb_in :
355
                     mab_lsb ? {2{mdb_in[15:8]}} : mdb_in;
356
 
357
// Memory data bus input buffer (buffer after a source read)
358
reg         mdb_in_buf_en;
359 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
360
  if (puc_rst)  mdb_in_buf_en <= 1'b0;
361
  else          mdb_in_buf_en <= (e_state==`E_SRC_RD);
362 80 olivier.gi
 
363
reg         mdb_in_buf_valid;
364 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
365
  if (puc_rst)               mdb_in_buf_valid <= 1'b0;
366 80 olivier.gi
  else if (e_state==`E_EXEC) mdb_in_buf_valid <= 1'b0;
367
  else if (mdb_in_buf_en)    mdb_in_buf_valid <= 1'b1;
368
 
369
reg  [15:0] mdb_in_buf;
370 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
371
  if (puc_rst)            mdb_in_buf <= 16'h0000;
372 80 olivier.gi
  else if (mdb_in_buf_en) mdb_in_buf <= mdb_in_bw;
373
 
374
assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw;
375
 
376
 
377
endmodule // omsp_execution_unit
378
 
379 104 olivier.gi
`ifdef OMSP_NO_INCLUDE
380
`else
381 80 olivier.gi
`include "openMSP430_undefines.v"
382 104 olivier.gi
`endif

powered by: WebSVN 2.1.0

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