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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [xilinx_diligent_s3board/] [rtl/] [verilog/] [openmsp430/] [omsp_frontend.v] - Blame information for rev 54

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_frontend.v
26 2 olivier.gi
// 
27
// *Module Description:
28
//                       openMSP430 Instruction fetch and decode unit
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 17 olivier.gi
// $Rev: 54 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2010-01-27 19:25:43 +0100 (Wed, 27 Jan 2010) $
37
//----------------------------------------------------------------------------
38 23 olivier.gi
`include "timescale.v"
39
`include "openMSP430_defines.v"
40 2 olivier.gi
 
41 34 olivier.gi
module  omsp_frontend (
42 2 olivier.gi
 
43
// OUTPUTs
44
    dbg_halt_st,                   // Halt/Run status from CPU
45 54 olivier.gi
    decode_noirq,                  // Frontend decode instruction
46 2 olivier.gi
    e_state,                       // Execution state
47
    exec_done,                     // Execution completed
48
    inst_ad,                       // Decoded Inst: destination addressing mode
49
    inst_as,                       // Decoded Inst: source addressing mode
50
    inst_alu,                      // ALU control signals
51
    inst_bw,                       // Decoded Inst: byte width
52
    inst_dest,                     // Decoded Inst: destination (one hot)
53
    inst_dext,                     // Decoded Inst: destination extended instruction word
54
    inst_irq_rst,                  // Decoded Inst: Reset interrupt
55
    inst_jmp,                      // Decoded Inst: Conditional jump
56
    inst_sext,                     // Decoded Inst: source extended instruction word
57
    inst_so,                       // Decoded Inst: Single-operand arithmetic
58
    inst_src,                      // Decoded Inst: source (one hot)
59
    inst_type,                     // Decoded Instruction type
60
    irq_acc,                       // Interrupt request accepted (one-hot signal)
61
    mab,                           // Frontend Memory address bus
62
    mb_en,                         // Frontend Memory bus enable
63
    nmi_acc,                       // Non-Maskable interrupt request accepted
64
    pc,                            // Program counter
65
    pc_nxt,                        // Next PC value (for CALL & IRQ)
66
 
67
// INPUTs
68
    cpuoff,                        // Turns off the CPU
69
    dbg_halt_cmd,                  // Halt CPU command
70
    dbg_reg_sel,                   // Debug selected register for rd/wr access
71 33 olivier.gi
    fe_pmem_wait,                  // Frontend wait for Instruction fetch
72 2 olivier.gi
    gie,                           // General interrupt enable
73
    irq,                           // Maskable interrupts
74
    mclk,                          // Main system clock
75
    mdb_in,                        // Frontend Memory data bus input
76
    nmi_evt,                       // Non-maskable interrupt event
77
    pc_sw,                         // Program counter software value
78
    pc_sw_wr,                      // Program counter software write
79
    puc,                           // Main system reset
80
    wdt_irq                        // Watchdog-timer interrupt
81
);
82
 
83
// OUTPUTs
84
//=========
85
output              dbg_halt_st;   // Halt/Run status from CPU
86 54 olivier.gi
output              decode_noirq;  // Frontend decode instruction
87 2 olivier.gi
output        [3:0] e_state;       // Execution state
88
output              exec_done;     // Execution completed
89
output        [7:0] inst_ad;       // Decoded Inst: destination addressing mode
90
output        [7:0] inst_as;       // Decoded Inst: source addressing mode
91
output       [11:0] inst_alu;      // ALU control signals
92
output              inst_bw;       // Decoded Inst: byte width
93
output       [15:0] inst_dest;     // Decoded Inst: destination (one hot)
94
output       [15:0] inst_dext;     // Decoded Inst: destination extended instruction word
95
output              inst_irq_rst;  // Decoded Inst: Reset interrupt
96
output        [7:0] inst_jmp;      // Decoded Inst: Conditional jump
97
output       [15:0] inst_sext;     // Decoded Inst: source extended instruction word
98
output        [7:0] inst_so;       // Decoded Inst: Single-operand arithmetic
99
output       [15:0] inst_src;      // Decoded Inst: source (one hot)
100
output        [2:0] inst_type;     // Decoded Instruction type
101
output       [13:0] irq_acc;       // Interrupt request accepted (one-hot signal)
102
output       [15:0] mab;           // Frontend Memory address bus
103
output              mb_en;         // Frontend Memory bus enable
104
output              nmi_acc;       // Non-Maskable interrupt request accepted
105
output       [15:0] pc;            // Program counter
106
output       [15:0] pc_nxt;        // Next PC value (for CALL & IRQ)
107
 
108
// INPUTs
109
//=========
110
input               cpuoff;        // Turns off the CPU
111
input               dbg_halt_cmd;  // Halt CPU command
112
input         [3:0] dbg_reg_sel;   // Debug selected register for rd/wr access
113 33 olivier.gi
input               fe_pmem_wait;  // Frontend wait for Instruction fetch
114 2 olivier.gi
input               gie;           // General interrupt enable
115
input        [13:0] irq;           // Maskable interrupts
116
input               mclk;          // Main system clock
117
input        [15:0] mdb_in;        // Frontend Memory data bus input
118
input               nmi_evt;       // Non-maskable interrupt event
119
input        [15:0] pc_sw;         // Program counter software value
120
input               pc_sw_wr;      // Program counter software write
121
input               puc;           // Main system reset
122
input               wdt_irq;       // Watchdog-timer interrupt
123
 
124
 
125
//=============================================================================
126
// 1)  FRONTEND STATE MACHINE
127
//=============================================================================
128
 
129
// The wire "conv" is used as state bits to calculate the next response
130
reg  [2:0] i_state;
131
reg  [2:0] i_state_nxt;
132
 
133
reg  [1:0] inst_sz;
134
wire [1:0] inst_sz_nxt;
135
wire       irq_detect;
136
wire [2:0] inst_type_nxt;
137
wire       is_const;
138
reg [15:0] sconst_nxt;
139
reg  [3:0] e_state_nxt;
140
 
141
// State machine definitons
142
parameter I_IRQ_FETCH = 3'h0;
143
parameter I_IRQ_DONE  = 3'h1;
144
parameter I_DEC       = 3'h2; // New instruction ready for decode
145
parameter I_EXT1      = 3'h3; // 1st Extension word
146
parameter I_EXT2      = 3'h4; // 2nd Extension word
147
parameter I_IDLE      = 3'h5; // CPU is in IDLE mode
148
 
149
// States Transitions
150
always @(i_state   or inst_sz    or inst_sz_nxt or pc_sw_wr     or exec_done or
151
         exec_done or irq_detect or cpuoff      or dbg_halt_cmd or e_state)
152
    case(i_state)
153
      I_IDLE     : i_state_nxt = (irq_detect & ~dbg_halt_cmd) ? I_IRQ_FETCH :
154
                                 (~cpuoff    & ~dbg_halt_cmd) ? I_DEC       : I_IDLE;
155
      I_IRQ_FETCH: i_state_nxt =  I_IRQ_DONE;
156
      I_IRQ_DONE : i_state_nxt =  I_DEC;
157
      I_DEC      : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
158
                          (cpuoff | dbg_halt_cmd) & exec_done ? I_IDLE      :
159
                            dbg_halt_cmd & (e_state==`E_IDLE) ? I_IDLE      :
160
                                  pc_sw_wr                    ? I_DEC       :
161
                             ~exec_done & ~(e_state==`E_IDLE) ? I_DEC       :        // Wait in decode state
162
                                  (inst_sz_nxt!=2'b00)        ? I_EXT1      : I_DEC; // until execution is completed
163
      I_EXT1     : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
164
                                  pc_sw_wr                    ? I_DEC       :
165
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
166
      I_EXT2     : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH : I_DEC;
167
      default    : i_state_nxt =  I_IRQ_FETCH;
168
    endcase
169
 
170
// State machine
171
always @(posedge mclk or posedge puc)
172
  if (puc) i_state  <= I_IRQ_FETCH;
173
  else     i_state  <= i_state_nxt;
174
 
175
// Utility signals
176 54 olivier.gi
wire   decode_noirq =  ((i_state==I_DEC) &  (exec_done | (e_state==`E_IDLE)));
177
wire   decode       =  decode_noirq | irq_detect;
178
wire   fetch        = ~((i_state==I_DEC) & ~(exec_done | (e_state==`E_IDLE))) & ~(e_state_nxt==`E_IDLE);
179 2 olivier.gi
 
180
// Debug interface cpu status
181
reg    dbg_halt_st;
182
always @(posedge mclk or posedge puc)
183
  if (puc)  dbg_halt_st <= 1'b0;
184
  else      dbg_halt_st <= dbg_halt_cmd & (i_state_nxt==I_IDLE);
185
 
186
 
187
//=============================================================================
188
// 2)  INTERRUPT HANDLING
189
//=============================================================================
190
 
191
// Detect nmi interrupt
192
reg         inst_nmi;
193
always @(posedge mclk or posedge puc)
194
  if (puc)                      inst_nmi <= 1'b0;
195
  else if (nmi_evt)             inst_nmi <= 1'b1;
196
  else if (i_state==I_IRQ_DONE) inst_nmi <= 1'b0;
197
 
198
 
199
// Detect reset interrupt
200
reg         inst_irq_rst;
201
always @(posedge mclk or posedge puc)
202
  if (puc)                      inst_irq_rst <= 1'b1;
203
  else if (exec_done)           inst_irq_rst <= 1'b0;
204
 
205
//  Detect other interrupts
206
assign  irq_detect = (inst_nmi | ((|irq | wdt_irq) & gie)) & ~dbg_halt_cmd & (exec_done | (i_state==I_IDLE));
207
 
208
// Select interrupt vector
209
reg  [3:0] irq_num;
210
always @(posedge mclk or posedge puc)
211
  if (puc)             irq_num <= 4'hf;
212
  else if (irq_detect) irq_num <= inst_nmi           ?  4'he :
213
                                  irq[13]            ?  4'hd :
214
                                  irq[12]            ?  4'hc :
215
                                  irq[11]            ?  4'hb :
216
                                 (irq[10] | wdt_irq) ?  4'ha :
217
                                  irq[9]             ?  4'h9 :
218
                                  irq[8]             ?  4'h8 :
219
                                  irq[7]             ?  4'h7 :
220
                                  irq[6]             ?  4'h6 :
221
                                  irq[5]             ?  4'h5 :
222
                                  irq[4]             ?  4'h4 :
223
                                  irq[3]             ?  4'h3 :
224
                                  irq[2]             ?  4'h2 :
225
                                  irq[1]             ?  4'h1 :
226
                                  irq[0]             ?  4'h0 : 4'hf;
227
 
228
wire [15:0] irq_addr    = {11'h7ff, irq_num, 1'b0};
229
 
230
// Interrupt request accepted
231
wire [15:0] irq_acc_all = (16'h0001 << irq_num) & {16{(i_state==I_IRQ_FETCH)}};
232
wire [13:0] irq_acc     = irq_acc_all[13:0];
233
wire        nmi_acc     = irq_acc_all[14];
234
 
235
 
236
//=============================================================================
237
// 3)  FETCH INSTRUCTION
238
//=============================================================================
239
 
240
//
241
// 3.1) PROGRAM COUNTER & MEMORY INTERFACE
242
//-----------------------------------------
243
 
244
// Program counter
245
reg  [15:0] pc;
246
 
247
// Detect if PC needs to be incremented
248
wire        pc_inc = (~pc_sw_wr & fetch) & ~(i_state==I_IRQ_FETCH) & ~(i_state==I_IRQ_DONE);
249
 
250
// Mux between software update and old PC
251
wire [15:0] pc_sel  = pc_sw_wr               ? pc_sw    :
252
                      (i_state==I_IRQ_FETCH) ? irq_addr :
253
                      (i_state==I_IRQ_DONE)  ? mdb_in   :  pc;
254
 
255
// Compute next PC value
256
wire [15:0] pc_nxt  = pc_sel + {14'h0000, pc_inc, 1'b0};
257
 
258
always @(posedge mclk or posedge puc)
259
  if (puc)  pc <= 16'h0000;
260
  else      pc <= pc_nxt;
261
 
262
// Check if ROM has been busy in order to retry ROM access
263 33 olivier.gi
reg pmem_busy;
264 2 olivier.gi
always @(posedge mclk or posedge puc)
265 33 olivier.gi
  if (puc)  pmem_busy <= 16'h0000;
266
  else      pmem_busy <= fe_pmem_wait;
267 2 olivier.gi
 
268
// Memory interface
269
wire [15:0] mab      = pc_nxt;
270 33 olivier.gi
wire        mb_en    = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~dbg_halt_cmd);
271 2 olivier.gi
 
272
 
273
//
274
// 3.2) INSTRUCTION REGISTER
275
//--------------------------------
276
 
277
// Instruction register
278
wire [15:0] ir  = mdb_in;
279
 
280
// Detect if source extension word is required
281
wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
282
 
283
// Detect if destination extension word is required
284
wire is_dext = (inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS]);
285
 
286
// For the Symbolic addressing mode, add -2 to the extension word in order
287
// to make up for the PC address
288
wire [15:0] ext_incr = ((i_state==I_EXT1)     &  inst_as[`SYMB]) |
289
                       ((i_state==I_EXT2)     &  inst_ad[`SYMB]) |
290
                       ((i_state==I_EXT1)     & ~inst_as[`SYMB] &
291
                       ~(i_state_nxt==I_EXT2) &  inst_ad[`SYMB])   ? 16'hfffe : 16'h0000;
292
 
293
wire [15:0] ext_nxt  = ir + ext_incr;
294
 
295
// Store source extension word
296
reg [15:0] inst_sext;
297
always @(posedge mclk or posedge puc)
298
  if (puc)                                     inst_sext <= 16'h0000;
299
  else if (decode & is_const)                  inst_sext <= sconst_nxt;
300
  else if (decode & inst_type_nxt[`INST_JMP])  inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
301
  else if ((i_state==I_EXT1) & is_sext)        inst_sext <= ext_nxt;
302
 
303
// Source extension word is ready
304
wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
305
 
306
 
307
// Store destination extension word
308
reg [15:0] inst_dext;
309
always @(posedge mclk or posedge puc)
310
  if (puc)                               inst_dext <= 16'h0000;
311
  else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
312
  else if  (i_state==I_EXT2)             inst_dext <= ext_nxt;
313
 
314
// Destination extension word is ready
315
wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
316
 
317
 
318
//=============================================================================
319
// 4)  DECODE INSTRUCTION
320
//=============================================================================
321
 
322
//
323
// 4.1) OPCODE: INSTRUCTION TYPE
324
//----------------------------------------
325
// Instructions type is encoded in a one hot fashion as following:
326
//
327
// 3'b001: Single-operand arithmetic
328
// 3'b010: Conditional jump
329
// 3'b100: Two-operand arithmetic
330
 
331
reg  [2:0] inst_type;
332
assign     inst_type_nxt = {(ir[15:14]!=2'b00),
333
                            (ir[15:13]==3'b001),
334
                            (ir[15:13]==3'b000)} & {3{~irq_detect}};
335
 
336
always @(posedge mclk or posedge puc)
337
  if (puc)                      inst_type <= 3'b000;
338
  else if (decode)              inst_type <= inst_type_nxt;
339
 
340
//
341
// 4.2) OPCODE: SINGLE-OPERAND ARITHMETIC
342
//----------------------------------------
343
// Instructions are encoded in a one hot fashion as following:
344
//
345
// 8'b00000001: RRC
346
// 8'b00000010: SWPB
347
// 8'b00000100: RRA
348
// 8'b00001000: SXT
349
// 8'b00010000: PUSH
350
// 8'b00100000: CALL
351
// 8'b01000000: RETI
352
// 8'b10000000: IRQ
353
 
354
reg   [7:0] inst_so;
355
wire  [7:0] inst_so_nxt = irq_detect ? 8'h80 : ((8'h01<<ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
356
 
357
always @(posedge mclk or posedge puc)
358
  if (puc)         inst_so <= 8'h00;
359
  else if (decode) inst_so <= inst_so_nxt;
360
 
361
//
362
// 4.3) OPCODE: CONDITIONAL JUMP
363
//--------------------------------
364
// Instructions are encoded in a one hot fashion as following:
365
//
366
// 8'b00000001: JNE/JNZ
367
// 8'b00000010: JEQ/JZ
368
// 8'b00000100: JNC/JLO
369
// 8'b00001000: JC/JHS
370
// 8'b00010000: JN
371
// 8'b00100000: JGE
372
// 8'b01000000: JL
373
// 8'b10000000: JMP
374
 
375
reg   [2:0] inst_jmp_bin;
376
always @(posedge mclk or posedge puc)
377
  if (puc)         inst_jmp_bin <= 3'h0;
378
  else if (decode) inst_jmp_bin <= ir[12:10];
379
 
380
wire [7:0] inst_jmp = (8'h01<<inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
381
 
382
 
383
//
384
// 4.4) OPCODE: TWO-OPERAND ARITHMETIC
385
//-------------------------------------
386
// Instructions are encoded in a one hot fashion as following:
387
//
388
// 12'b000000000001: MOV
389
// 12'b000000000010: ADD
390
// 12'b000000000100: ADDC
391
// 12'b000000001000: SUBC
392
// 12'b000000010000: SUB
393
// 12'b000000100000: CMP
394
// 12'b000001000000: DADD
395
// 12'b000010000000: BIT
396
// 12'b000100000000: BIC
397
// 12'b001000000000: BIS
398
// 12'b010000000000: XOR
399
// 12'b100000000000: AND
400
 
401
wire [15:0] inst_to_1hot = (16'h0001<<ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
402
wire [11:0] inst_to_nxt  = inst_to_1hot[15:4];
403
 
404
 
405
//
406
// 4.5) SOURCE AND DESTINATION REGISTERS
407
//---------------------------------------
408
 
409
// Destination register
410
reg [3:0] inst_dest_bin;
411
always @(posedge mclk or posedge puc)
412
  if (puc)         inst_dest_bin <= 4'h0;
413
  else if (decode) inst_dest_bin <= ir[3:0];
414
 
415
wire  [15:0] inst_dest = dbg_halt_st          ? (16'h0001 << dbg_reg_sel) :
416
                         inst_type[`INST_JMP] ? 16'h0001                  :
417
                         inst_so[`IRQ]  |
418
                         inst_so[`PUSH] |
419
                         inst_so[`CALL]       ? 16'h0002                  :
420
                                                (16'h0001 << inst_dest_bin);
421
 
422
 
423
// Source register
424
reg [3:0] inst_src_bin;
425
always @(posedge mclk or posedge puc)
426
  if (puc)         inst_src_bin <= 4'h0;
427
  else if (decode) inst_src_bin <= ir[11:8];
428
 
429
wire  [15:0] inst_src = inst_type[`INST_TO] ? (16'h0001 << inst_src_bin)  :
430
                        inst_so[`RETI]      ? 16'h0002                    :
431
                        inst_so[`IRQ]       ? 16'h0001                    :
432
                        inst_type[`INST_SO] ? (16'h0001 << inst_dest_bin) : 16'h0000;
433
 
434
 
435
//
436
// 4.6) SOURCE ADDRESSING MODES
437
//--------------------------------
438
// Source addressing modes are encoded in a one hot fashion as following:
439
//
440
// 13'b0000000000001: Register direct.
441
// 13'b0000000000010: Register indexed.
442
// 13'b0000000000100: Register indirect.
443
// 13'b0000000001000: Register indirect autoincrement.
444
// 13'b0000000010000: Symbolic (operand is in memory at address PC+x).
445
// 13'b0000000100000: Immediate (operand is next word in the instruction stream).
446
// 13'b0000001000000: Absolute (operand is in memory at address x).
447
// 13'b0000010000000: Constant 4.
448
// 13'b0000100000000: Constant 8.
449
// 13'b0001000000000: Constant 0.
450
// 13'b0010000000000: Constant 1.
451
// 13'b0100000000000: Constant 2.
452
// 13'b1000000000000: Constant -1.
453
 
454
reg [12:0] inst_as_nxt;
455
 
456
wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8];
457
 
458
always @(src_reg or ir or inst_type_nxt)
459
  begin
460
     if (inst_type_nxt[`INST_JMP])
461
       inst_as_nxt =  13'b0000000000001;
462
     else if (src_reg==4'h3) // Addressing mode using R3
463
       case (ir[5:4])
464
         2'b11  : inst_as_nxt =  13'b1000000000000;
465
         2'b10  : inst_as_nxt =  13'b0100000000000;
466
         2'b01  : inst_as_nxt =  13'b0010000000000;
467
         default: inst_as_nxt =  13'b0001000000000;
468
       endcase
469
     else if (src_reg==4'h2) // Addressing mode using R2
470
       case (ir[5:4])
471
         2'b11  : inst_as_nxt =  13'b0000100000000;
472
         2'b10  : inst_as_nxt =  13'b0000010000000;
473
         2'b01  : inst_as_nxt =  13'b0000001000000;
474
         default: inst_as_nxt =  13'b0000000000001;
475
       endcase
476
     else if (src_reg==4'h0) // Addressing mode using R0
477
       case (ir[5:4])
478
         2'b11  : inst_as_nxt =  13'b0000000100000;
479
         2'b10  : inst_as_nxt =  13'b0000000000100;
480
         2'b01  : inst_as_nxt =  13'b0000000010000;
481
         default: inst_as_nxt =  13'b0000000000001;
482
       endcase
483
     else                    // General Addressing mode
484
       case (ir[5:4])
485
         2'b11  : inst_as_nxt =  13'b0000000001000;
486
         2'b10  : inst_as_nxt =  13'b0000000000100;
487
         2'b01  : inst_as_nxt =  13'b0000000000010;
488
         default: inst_as_nxt =  13'b0000000000001;
489
       endcase
490
  end
491
assign    is_const = |inst_as_nxt[12:7];
492
 
493
reg [7:0] inst_as;
494
always @(posedge mclk or posedge puc)
495
  if (puc)         inst_as <= 8'h00;
496
  else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
497
 
498
 
499
// 13'b0000010000000: Constant 4.
500
// 13'b0000100000000: Constant 8.
501
// 13'b0001000000000: Constant 0.
502
// 13'b0010000000000: Constant 1.
503
// 13'b0100000000000: Constant 2.
504
// 13'b1000000000000: Constant -1.
505
always @(inst_as_nxt)
506
  begin
507
     if (inst_as_nxt[7])        sconst_nxt = 16'h0004;
508
     else if (inst_as_nxt[8])   sconst_nxt = 16'h0008;
509
     else if (inst_as_nxt[9])   sconst_nxt = 16'h0000;
510
     else if (inst_as_nxt[10])  sconst_nxt = 16'h0001;
511
     else if (inst_as_nxt[11])  sconst_nxt = 16'h0002;
512
     else if (inst_as_nxt[12])  sconst_nxt = 16'hffff;
513
     else                       sconst_nxt = 16'h0000;
514
  end
515
 
516
 
517
//
518
// 4.7) DESTINATION ADDRESSING MODES
519
//-----------------------------------
520
// Destination addressing modes are encoded in a one hot fashion as following:
521
//
522
// 8'b00000001: Register direct.
523
// 8'b00000010: Register indexed.
524
// 8'b00010000: Symbolic (operand is in memory at address PC+x).
525
// 8'b01000000: Absolute (operand is in memory at address x).
526
 
527
reg  [7:0] inst_ad_nxt;
528
 
529
wire [3:0] dest_reg = ir[3:0];
530
 
531
always @(dest_reg or ir or inst_type_nxt)
532
  begin
533
     if (~inst_type_nxt[`INST_TO])
534
       inst_ad_nxt =  8'b00000000;
535
     else if (dest_reg==4'h2)   // Addressing mode using R2
536
       case (ir[7])
537
         1'b1   : inst_ad_nxt =  8'b01000000;
538
         default: inst_ad_nxt =  8'b00000001;
539
       endcase
540
     else if (dest_reg==4'h0)   // Addressing mode using R0
541
       case (ir[7])
542
         2'b1   : inst_ad_nxt =  8'b00010000;
543
         default: inst_ad_nxt =  8'b00000001;
544
       endcase
545
     else                       // General Addressing mode
546
       case (ir[7])
547
         2'b1   : inst_ad_nxt =  8'b00000010;
548
         default: inst_ad_nxt =  8'b00000001;
549
       endcase
550
  end
551
 
552
reg [7:0] inst_ad;
553
always @(posedge mclk or posedge puc)
554
  if (puc)         inst_ad <= 8'h00;
555
  else if (decode) inst_ad <= inst_ad_nxt;
556
 
557
 
558
//
559
// 4.8) REMAINING INSTRUCTION DECODING
560
//-------------------------------------
561
 
562
// Operation size
563
reg       inst_bw;
564
always @(posedge mclk or posedge puc)
565
  if (puc)         inst_bw     <= 1'b0;
566
  else if (decode) inst_bw     <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~dbg_halt_cmd;
567
 
568
// Extended instruction size
569
assign    inst_sz_nxt = {1'b0,  (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
570
                        {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
571
always @(posedge mclk or posedge puc)
572
  if (puc)         inst_sz     <= 2'b00;
573
  else if (decode) inst_sz     <= inst_sz_nxt;
574
 
575
 
576
//=============================================================================
577
// 5)  EXECUTION-UNIT STATE MACHINE
578
//=============================================================================
579
 
580
// State machine registers
581
reg  [3:0] e_state;
582
 
583
 
584
// State machine control signals
585
//--------------------------------
586
 
587
wire src_acalc_pre =  inst_as_nxt[`IDX]   | inst_as_nxt[`SYMB]    | inst_as_nxt[`ABS];
588
wire src_rd_pre    =  inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM]  | inst_so_nxt[`RETI];
589
wire dst_acalc_pre =  inst_ad_nxt[`IDX]   | inst_ad_nxt[`SYMB]    | inst_ad_nxt[`ABS];
590
wire dst_acalc     =  inst_ad[`IDX]       | inst_ad[`SYMB]        | inst_ad[`ABS];
591
wire dst_rd_pre    =  inst_ad_nxt[`IDX]   | inst_so_nxt[`PUSH]    | inst_so_nxt[`CALL] | inst_so_nxt[`RETI];
592
wire dst_rd        =  inst_ad[`IDX]       | inst_so[`PUSH]        | inst_so[`CALL]     | inst_so[`RETI];
593
 
594
wire inst_branch   =  (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI];
595
 
596
reg exec_jmp;
597
always @(posedge mclk or posedge puc)
598
  if (puc)                       exec_jmp <= 1'b0;
599
  else if (inst_branch & decode) exec_jmp <= 1'b1;
600
  else if (e_state==`E_JUMP)     exec_jmp <= 1'b0;
601
 
602
reg exec_dst_wr;
603
always @(posedge mclk or posedge puc)
604
  if (puc)                     exec_dst_wr <= 1'b0;
605
  else if (e_state==`E_DST_RD) exec_dst_wr <= 1'b1;
606
  else if (e_state==`E_DST_WR) exec_dst_wr <= 1'b0;
607
 
608
reg exec_src_wr;
609
always @(posedge mclk or posedge puc)
610
  if (puc)                                               exec_src_wr <= 1'b0;
611
  else if (inst_type[`INST_SO] & (e_state==`E_SRC_RD))   exec_src_wr <= 1'b1;
612
  else if ((e_state==`E_SRC_WR) || (e_state==`E_DST_WR)) exec_src_wr <= 1'b0;
613
 
614
reg exec_dext_rdy;
615
always @(posedge mclk or posedge puc)
616
  if (puc)                     exec_dext_rdy <= 1'b0;
617
  else if (e_state==`E_DST_RD) exec_dext_rdy <= 1'b0;
618
  else if (inst_dext_rdy)      exec_dext_rdy <= 1'b1;
619
 
620
// Execution first state
621
//wire [3:0] e_first_state = dbg_halt_cmd        ? `E_IDLE   :
622
wire [3:0] e_first_state = ~dbg_halt_st  & inst_so_nxt[`IRQ] ? `E_IRQ_0  :
623
                            dbg_halt_cmd | (i_state==I_IDLE) ? `E_IDLE   :
624
                            cpuoff                           ? `E_IDLE   :
625
                            src_acalc_pre                    ? `E_SRC_AD :
626
                            src_rd_pre                       ? `E_SRC_RD :
627
                            dst_acalc_pre                    ? `E_DST_AD :
628
                            dst_rd_pre                       ? `E_DST_RD : `E_EXEC;
629
 
630
 
631
// State machine
632
//--------------------------------
633
 
634
// States Transitions
635
always @(e_state       or dst_acalc     or dst_rd   or inst_sext_rdy or
636
         inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr   or
637
         e_first_state or exec_src_wr)
638
    case(e_state)
639
      `E_IDLE   : e_state_nxt =  e_first_state;
640
      `E_IRQ_0  : e_state_nxt =  `E_IRQ_1;
641
      `E_IRQ_1  : e_state_nxt =  `E_IRQ_2;
642
      `E_IRQ_2  : e_state_nxt =  `E_IRQ_3;
643
      `E_IRQ_3  : e_state_nxt =  `E_IRQ_4;
644
      `E_IRQ_4  : e_state_nxt =  `E_EXEC;
645
 
646
      `E_SRC_AD : e_state_nxt =  inst_sext_rdy     ? `E_SRC_RD : `E_SRC_AD;
647
 
648
      `E_SRC_RD : e_state_nxt =  dst_acalc         ? `E_DST_AD :
649
                                 dst_rd            ? `E_DST_RD : `E_EXEC;
650
 
651
      `E_DST_AD : e_state_nxt =  (inst_dext_rdy |
652
                                 exec_dext_rdy)    ? `E_DST_RD : `E_DST_AD;
653
 
654
      `E_DST_RD : e_state_nxt =  `E_EXEC;
655
 
656
      `E_EXEC   : e_state_nxt =  exec_dst_wr       ? `E_DST_WR :
657
                                exec_jmp           ? `E_JUMP   :
658
                                exec_src_wr        ? `E_SRC_WR : e_first_state;
659
 
660
      `E_JUMP   : e_state_nxt =  e_first_state;
661
      `E_DST_WR : e_state_nxt =  exec_jmp           ? `E_JUMP   : e_first_state;
662
      `E_SRC_WR : e_state_nxt =  e_first_state;
663
      default  : e_state_nxt =  `E_IRQ_0;
664
    endcase
665
 
666
// State machine
667
always @(posedge mclk or posedge puc)
668
  if (puc)     e_state  <= `E_IRQ_1;
669
  else         e_state  <= e_state_nxt;
670
 
671
 
672
// Frontend State machine control signals
673
//----------------------------------------
674
 
675
wire exec_done = exec_jmp        ? (e_state==`E_JUMP)   :
676
                 exec_dst_wr     ? (e_state==`E_DST_WR) :
677
                 exec_src_wr     ? (e_state==`E_SRC_WR) : (e_state==`E_EXEC);
678
 
679
 
680
//=============================================================================
681
// 6)  EXECUTION-UNIT STATE CONTROL
682
//=============================================================================
683
 
684
//
685
// 6.1) ALU CONTROL SIGNALS
686
//-------------------------------------
687
//
688
// 12'b000000000001: Enable ALU source inverter
689
// 12'b000000000010: Enable Incrementer
690
// 12'b000000000100: Enable Incrementer on carry bit
691
// 12'b000000001000: Select Adder
692
// 12'b000000010000: Select AND
693
// 12'b000000100000: Select OR
694
// 12'b000001000000: Select XOR
695
// 12'b000010000000: Select DADD
696
// 12'b000100000000: Update N, Z & C (C=~Z)
697
// 12'b001000000000: Update all status bits
698
// 12'b010000000000: Update status bit for XOR instruction
699
// 12'b100000000000: Don't write to destination
700
 
701
reg  [11:0] inst_alu;
702
 
703
wire        alu_src_inv   = inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC] |
704
                            inst_to_nxt[`CMP]  | inst_to_nxt[`BIC] ;
705
 
706
wire        alu_inc       = inst_to_nxt[`SUB]  | inst_to_nxt[`CMP];
707
 
708
wire        alu_inc_c     = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] |
709
                            inst_to_nxt[`SUBC];
710
 
711
wire        alu_add       = inst_to_nxt[`ADD]  | inst_to_nxt[`ADDC]       |
712
                            inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC]       |
713
                            inst_to_nxt[`CMP]  | inst_type_nxt[`INST_JMP] |
714
                            inst_so_nxt[`RETI];
715
 
716
 
717
wire        alu_and       = inst_to_nxt[`AND]  | inst_to_nxt[`BIC]  |
718
                            inst_to_nxt[`BIT];
719
 
720
wire        alu_or        = inst_to_nxt[`BIS];
721
 
722
wire        alu_xor       = inst_to_nxt[`XOR];
723
 
724
wire        alu_dadd      = inst_to_nxt[`DADD];
725
 
726
wire        alu_stat_7    = inst_to_nxt[`BIT]  | inst_to_nxt[`AND]  |
727
                            inst_so_nxt[`SXT];
728
 
729
wire        alu_stat_f    = inst_to_nxt[`ADD]  | inst_to_nxt[`ADDC] |
730
                            inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC] |
731
                            inst_to_nxt[`CMP]  | inst_to_nxt[`DADD] |
732
                            inst_to_nxt[`BIT]  | inst_to_nxt[`XOR]  |
733
                            inst_to_nxt[`AND]  |
734
                            inst_so_nxt[`RRC]  | inst_so_nxt[`RRA]  |
735
                            inst_so_nxt[`SXT];
736
 
737
wire        alu_shift     = inst_so_nxt[`RRC]  | inst_so_nxt[`RRA];
738
 
739
wire        exec_no_wr    = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
740
 
741
always @(posedge mclk or posedge puc)
742
  if (puc)         inst_alu <= 12'h000;
743
  else if (decode) inst_alu <= {exec_no_wr,
744
                                alu_shift,
745
                                alu_stat_f,
746
                                alu_stat_7,
747
                                alu_dadd,
748
                                alu_xor,
749
                                alu_or,
750
                                alu_and,
751
                                alu_add,
752
                                alu_inc_c,
753
                                alu_inc,
754
                                alu_src_inv};
755
 
756
 
757 34 olivier.gi
endmodule // omsp_frontend
758 33 olivier.gi
 
759
`include "openMSP430_undefines.v"

powered by: WebSVN 2.1.0

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