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

Subversion Repositories openmsp430

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

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

powered by: WebSVN 2.1.0

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