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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [bench/] [verilog/] [msp_debug.v] - Blame information for rev 186

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
// *File Name: msp_debug.v
26
// 
27
// *Module Description:
28
//                      MSP430 core debug utility signals
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 17 olivier.gi
// $Rev: 134 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
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
module msp_debug (
44
 
45
// OUTPUTs
46
    e_state,                       // Execution state
47
    i_state,                       // Instruction fetch state
48
    inst_cycle,                    // Cycle number within current instruction
49
    inst_full,                     // Currently executed instruction (full version)
50
    inst_number,                   // Instruction number since last system reset
51
    inst_pc,                       // Instruction Program counter
52
    inst_short,                    // Currently executed instruction (short version)
53
 
54
// INPUTs
55
    mclk,                          // Main system clock
56 111 olivier.gi
    puc_rst                        // Main system reset
57 2 olivier.gi
);
58
 
59
// OUTPUTs
60
//============
61
output  [8*32-1:0] e_state;        // Execution state
62
output  [8*32-1:0] i_state;        // Instruction fetch state
63
output      [31:0] inst_cycle;     // Cycle number within current instruction
64
output  [8*32-1:0] inst_full;      // Currently executed instruction (full version)
65
output      [31:0] inst_number;    // Instruction number since last system reset
66
output      [15:0] inst_pc;        // Instruction Program counter
67
output  [8*32-1:0] inst_short;     // Currently executed instruction (short version)
68
 
69
// INPUTs
70
//============
71
input              mclk;           // Main system clock
72 111 olivier.gi
input              puc_rst;        // Main system reset
73 2 olivier.gi
 
74
 
75
//=============================================================================
76
// 1) ASCII FORMATING FUNCTIONS
77
//=============================================================================
78
 
79
// This function simply concatenates two strings together, ignorning the NULL
80
// at the end of string2.
81
// The specified number of space will be inserted between string1 and string2
82
function [64*8-1:0] myFormat;
83
 
84
  input [32*8-1:0] string1;
85
  input [32*8-1:0] string2;
86
  input      [3:0] space;
87
 
88
  integer i,j;
89
  begin
90
     myFormat = 0;
91 94 olivier.gi
`ifdef VXL                      // no +:
92
`else
93 2 olivier.gi
     j        = 0;
94
     for ( i=0; i < 32; i=i+1)                      // Copy string2
95
       begin
96
          myFormat[8*i +: 8] = string2[8*i +: 8];
97
          if ((string2[8*i +: 8] == 0) && (j == 0)) j=i;
98
       end
99
 
100
     for ( i=0; i < space; i=i+1)                   // Add spaces
101
       myFormat[8*(j+i) +: 8] = " ";
102
     j=j+space;
103
 
104
     for ( i=0; i < 32; i=i+1)                      // Copy string1
105
       myFormat[8*(j+i) +: 8] = string1[8*i +: 8];
106 94 olivier.gi
`endif
107 2 olivier.gi
  end
108
endfunction
109
 
110
 
111
//=============================================================================
112
// 2) CONNECTIONS TO MSP430 CORE INTERNALS
113
//=============================================================================
114
 
115 94 olivier.gi
wire  [2:0] i_state_bin = tb_openMSP430.dut.frontend_0.i_state;
116
wire  [3:0] e_state_bin = tb_openMSP430.dut.frontend_0.e_state;
117 2 olivier.gi
 
118 94 olivier.gi
wire        decode      = tb_openMSP430.dut.frontend_0.decode;
119
wire [15:0] ir          = tb_openMSP430.dut.frontend_0.ir;
120
wire        irq_detect  = tb_openMSP430.dut.frontend_0.irq_detect;
121
wire  [3:0] irq_num     = tb_openMSP430.dut.frontend_0.irq_num;
122
wire [15:0] pc          = tb_openMSP430.dut.frontend_0.pc;
123 2 olivier.gi
 
124
 
125
//=============================================================================
126
// 3) GENERATE DEBUG SIGNALS
127
//=============================================================================
128
 
129
// Instruction fetch state
130
//=========================
131
reg [8*32-1:0] i_state;
132
 
133
always @(i_state_bin)
134
    case(i_state_bin)
135
      3'h0    : i_state =  "IRQ_FETCH";
136
      3'h1    : i_state =  "IRQ_DONE";
137
      3'h2    : i_state =  "DEC";
138
      3'h3    : i_state =  "EXT1";
139
      3'h4    : i_state =  "EXT2";
140
      3'h5    : i_state =  "IDLE";
141
      default : i_state =  "XXXXX";
142
    endcase
143
 
144
 
145
// Execution state
146
//=========================
147
 
148
reg [8*32-1:0] e_state;
149
 
150
always @(e_state_bin)
151
    case(e_state_bin)
152 134 olivier.gi
      4'h2    : e_state =  "IRQ_0";
153 2 olivier.gi
      4'h1    : e_state =  "IRQ_1";
154 134 olivier.gi
      4'h0    : e_state =  "IRQ_2";
155 2 olivier.gi
      4'h3    : e_state =  "IRQ_3";
156
      4'h4    : e_state =  "IRQ_4";
157
      4'h5    : e_state =  "SRC_AD";
158
      4'h6    : e_state =  "SRC_RD";
159
      4'h7    : e_state =  "SRC_WR";
160
      4'h8    : e_state =  "DST_AD";
161
      4'h9    : e_state =  "DST_RD";
162
      4'hA    : e_state =  "DST_WR";
163
      4'hB    : e_state =  "EXEC";
164
      4'hC    : e_state =  "JUMP";
165
      4'hD    : e_state =  "IDLE";
166
      default : e_state =  "xxxx";
167
    endcase
168
 
169
 
170
// Count instruction number & cycles
171
//====================================
172
 
173
reg [31:0]  inst_number;
174 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
175
  if (puc_rst)     inst_number  <= 0;
176 2 olivier.gi
  else if (decode) inst_number  <= inst_number+1;
177
 
178
reg [31:0]  inst_cycle;
179 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
180
  if (puc_rst)     inst_cycle <= 0;
181 2 olivier.gi
  else if (decode) inst_cycle <= 0;
182
  else             inst_cycle <= inst_cycle+1;
183
 
184
 
185
// Decode instruction
186
//====================================
187
 
188
// Buffer opcode
189
reg [15:0]  opcode;
190 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
191
  if (puc_rst)     opcode  <= 0;
192 2 olivier.gi
  else if (decode) opcode  <= ir;
193
 
194
// Interrupts
195
reg irq;
196 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
197
  if (puc_rst)     irq     <= 1'b1;
198 2 olivier.gi
  else if (decode) irq     <= irq_detect;
199
 
200
// Instruction type
201
reg [8*32-1:0] inst_type;
202
always @(opcode or irq)
203
  if (irq)
204
    inst_type =  "IRQ";
205
  else
206
    case(opcode[15:13])
207
      3'b000  : inst_type =  "SIG-OP";
208
      3'b001  : inst_type =  "JUMP";
209
      default : inst_type =  "TWO-OP";
210
    endcase
211
 
212
 
213
// Instructions name
214
reg [8*32-1:0] inst_name;
215
always @(opcode or inst_type or irq_num)
216
  if (inst_type=="IRQ")
217
    case(irq_num[3:0])
218
      4'b0000        : inst_name =  "IRQ 0";
219
      4'b0001        : inst_name =  "IRQ 1";
220
      4'b0010        : inst_name =  "IRQ 2";
221
      4'b0011        : inst_name =  "IRQ 3";
222
      4'b0100        : inst_name =  "IRQ 4";
223
      4'b0101        : inst_name =  "IRQ 5";
224
      4'b0110        : inst_name =  "IRQ 6";
225
      4'b0111        : inst_name =  "IRQ 7";
226
      4'b1000        : inst_name =  "IRQ 8";
227
      4'b1001        : inst_name =  "IRQ 9";
228
      4'b1010        : inst_name =  "IRQ 10";
229
      4'b1011        : inst_name =  "IRQ 11";
230
      4'b1100        : inst_name =  "IRQ 12";
231
      4'b1101        : inst_name =  "IRQ 13";
232
      4'b1110        : inst_name =  "NMI";
233
      default        : inst_name =  "RESET";
234
    endcase
235
  else if (inst_type=="SIG-OP")
236
    case(opcode[15:7])
237
      9'b000100_000  : inst_name =  "RRC";
238
      9'b000100_001  : inst_name =  "SWPB";
239
      9'b000100_010  : inst_name =  "RRA";
240
      9'b000100_011  : inst_name =  "SXT";
241
      9'b000100_100  : inst_name =  "PUSH";
242
      9'b000100_101  : inst_name =  "CALL";
243
      9'b000100_110  : inst_name =  "RETI";
244
      default        : inst_name =  "xxxx";
245
    endcase
246
  else if (inst_type=="JUMP")
247
    case(opcode[15:10])
248
      6'b001_000     : inst_name =  "JNE";
249
      6'b001_001     : inst_name =  "JEQ";
250
      6'b001_010     : inst_name =  "JNC";
251
      6'b001_011     : inst_name =  "JC";
252
      6'b001_100     : inst_name =  "JN";
253
      6'b001_101     : inst_name =  "JGE";
254
      6'b001_110     : inst_name =  "JL";
255
      6'b001_111     : inst_name =  "JMP";
256
      default        : inst_name =  "xxxx";
257
    endcase
258
  else if (inst_type=="TWO-OP")
259
    case(opcode[15:12])
260
      4'b0100        : inst_name =  "MOV";
261
      4'b0101        : inst_name =  "ADD";
262
      4'b0110        : inst_name =  "ADDC";
263
      4'b0111        : inst_name =  "SUBC";
264
      4'b1000        : inst_name =  "SUB";
265
      4'b1001        : inst_name =  "CMP";
266
      4'b1010        : inst_name =  "DADD";
267
      4'b1011        : inst_name =  "BIT";
268
      4'b1100        : inst_name =  "BIC";
269
      4'b1101        : inst_name =  "BIS";
270
      4'b1110        : inst_name =  "XOR";
271
      4'b1111        : inst_name =  "AND";
272
      default        : inst_name =  "xxxx";
273
    endcase
274
 
275
// Instructions byte/word mode
276
reg [8*32-1:0] inst_bw;
277
always @(opcode or inst_type)
278
  if (inst_type=="IRQ")
279
    inst_bw =  "";
280
  else if (inst_type=="SIG-OP")
281
    inst_bw =  opcode[6] ? ".B" : "";
282
  else if (inst_type=="JUMP")
283
    inst_bw =  "";
284
  else if (inst_type=="TWO-OP")
285
    inst_bw =  opcode[6] ? ".B" : "";
286
 
287
// Source register
288
reg [8*32-1:0] inst_src;
289
wire     [3:0] src_reg = (inst_type=="SIG-OP") ? opcode[3:0] : opcode[11:8];
290
 
291
always @(src_reg or inst_type)
292
  if (inst_type=="IRQ")
293
    inst_src =  "";
294
  else if (inst_type=="JUMP")
295
    inst_src =  "";
296
  else if ((inst_type=="SIG-OP") || (inst_type=="TWO-OP"))
297
    case(src_reg)
298
      4'b0000 : inst_src =  "r0";
299
      4'b0001 : inst_src =  "r1";
300
      4'b0010 : inst_src =  "r2";
301
      4'b0011 : inst_src =  "r3";
302
      4'b0100 : inst_src =  "r4";
303
      4'b0101 : inst_src =  "r5";
304
      4'b0110 : inst_src =  "r6";
305
      4'b0111 : inst_src =  "r7";
306
      4'b1000 : inst_src =  "r8";
307
      4'b1001 : inst_src =  "r9";
308
      4'b1010 : inst_src =  "r10";
309
      4'b1011 : inst_src =  "r11";
310
      4'b1100 : inst_src =  "r12";
311
      4'b1101 : inst_src =  "r13";
312
      4'b1110 : inst_src =  "r14";
313
      default : inst_src =  "r15";
314
    endcase
315
 
316
// Destination register
317
reg [8*32-1:0] inst_dst;
318
always @(opcode or inst_type)
319
  if (inst_type=="IRQ")
320
    inst_dst =  "";
321
  else if (inst_type=="SIG-OP")
322
    inst_dst =  "";
323
  else if (inst_type=="JUMP")
324
    inst_dst =  "";
325
  else if (inst_type=="TWO-OP")
326
    case(opcode[3:0])
327
      4'b0000 : inst_dst =  "r0";
328
      4'b0001 : inst_dst =  "r1";
329
      4'b0010 : inst_dst =  "r2";
330
      4'b0011 : inst_dst =  "r3";
331
      4'b0100 : inst_dst =  "r4";
332
      4'b0101 : inst_dst =  "r5";
333
      4'b0110 : inst_dst =  "r6";
334
      4'b0111 : inst_dst =  "r7";
335
      4'b1000 : inst_dst =  "r8";
336
      4'b1001 : inst_dst =  "r9";
337
      4'b1010 : inst_dst =  "r10";
338
      4'b1011 : inst_dst =  "r11";
339
      4'b1100 : inst_dst =  "r12";
340
      4'b1101 : inst_dst =  "r13";
341
      4'b1110 : inst_dst =  "r14";
342
      default : inst_dst =  "r15";
343
    endcase
344
 
345
// Source Addressing mode
346
reg [8*32-1:0] inst_as;
347
always @(inst_type or src_reg or opcode or inst_src)
348
  begin
349
  if (inst_type=="IRQ")
350
    inst_as =  "";
351
  else if (inst_type=="JUMP")
352
    inst_as =  "";
353
  else if (src_reg==4'h3) // Addressing mode using R3
354
    case (opcode[5:4])
355
      2'b11  : inst_as =  "#-1";
356
      2'b10  : inst_as =  "#2";
357
      2'b01  : inst_as =  "#1";
358
      default: inst_as =  "#0";
359
    endcase
360
  else if (src_reg==4'h2) // Addressing mode using R2
361
    case (opcode[5:4])
362
      2'b11  : inst_as =  "#8";
363
      2'b10  : inst_as =  "#4";
364
      2'b01  : inst_as =  "&EDE";
365
      default: inst_as =  inst_src;
366
    endcase
367
  else if (src_reg==4'h0) // Addressing mode using R0
368
    case (opcode[5:4])
369
      2'b11  : inst_as =  "#N";
370
      2'b10  : inst_as =  myFormat("@", inst_src, 0);
371
      2'b01  : inst_as =  "EDE";
372
      default: inst_as =  inst_src;
373
    endcase
374
  else                    // General Addressing mode
375
    case (opcode[5:4])
376
      2'b11  : begin
377
               inst_as =  myFormat("@", inst_src, 0);
378
               inst_as =  myFormat(inst_as, "+", 0);
379
               end
380
      2'b10  : inst_as =  myFormat("@", inst_src, 0);
381
      2'b01  : begin
382
               inst_as =  myFormat("x(", inst_src, 0);
383
               inst_as =  myFormat(inst_as, ")", 0);
384
               end
385
      default: inst_as =  inst_src;
386
    endcase
387
  end
388
 
389
// Destination Addressing mode
390
reg [8*32-1:0] inst_ad;
391
always @(opcode or inst_type or inst_dst)
392
  begin
393
     if (inst_type!="TWO-OP")
394
       inst_ad =  "";
395
     else if (opcode[3:0]==4'h2)   // Addressing mode using R2
396
       case (opcode[7])
397
         1'b1   : inst_ad =  "&EDE";
398
         default: inst_ad =  inst_dst;
399
       endcase
400
     else if (opcode[3:0]==4'h0)   // Addressing mode using R0
401
       case (opcode[7])
402
         2'b1   : inst_ad =  "EDE";
403
         default: inst_ad =  inst_dst;
404
       endcase
405
     else                          // General Addressing mode
406
       case (opcode[7])
407
         2'b1   : begin
408
                  inst_ad =  myFormat("x(", inst_dst, 0);
409
                  inst_ad =  myFormat(inst_ad, ")", 0);
410
                  end
411
         default: inst_ad =  inst_dst;
412
       endcase
413
  end
414
 
415
 
416
// Currently executed instruction
417
//================================
418
 
419 94 olivier.gi
wire [8*32-1:0] inst_short = inst_name;
420 2 olivier.gi
 
421 94 olivier.gi
reg  [8*32-1:0] inst_full;
422 2 olivier.gi
always @(inst_type or inst_name or inst_bw or inst_as or inst_ad)
423
  begin
424
     inst_full   = myFormat(inst_name, inst_bw, 0);
425
     inst_full   = myFormat(inst_full, inst_as, 1);
426
     if (inst_type=="TWO-OP")
427
       inst_full = myFormat(inst_full, ",",     0);
428
     inst_full   = myFormat(inst_full, inst_ad, 1);
429
     if (opcode==16'h4303)
430
       inst_full = "NOP";
431
     if (opcode==`DBG_SWBRK_OP)
432
       inst_full = "SBREAK";
433
 
434
  end
435
 
436
 
437
// Instruction program counter
438
//================================
439
 
440
reg  [15:0] inst_pc;
441 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
442
  if (puc_rst)     inst_pc  <=  16'h0000;
443 2 olivier.gi
  else if (decode) inst_pc  <=  pc;
444
 
445
 
446
endmodule // msp_debug
447
 

powered by: WebSVN 2.1.0

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