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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_frontend.v] - Blame information for rev 192

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

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2 117 olivier.gi
// Copyright (C) 2009 , Olivier Girard
3 2 olivier.gi
//
4 117 olivier.gi
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions
6
// are met:
7
//     * Redistributions of source code must retain the above copyright
8
//       notice, this list of conditions and the following disclaimer.
9
//     * Redistributions in binary form must reproduce the above copyright
10
//       notice, this list of conditions and the following disclaimer in the
11
//       documentation and/or other materials provided with the distribution.
12
//     * Neither the name of the authors nor the names of its contributors
13
//       may be used to endorse or promote products derived from this software
14
//       without specific prior written permission.
15 2 olivier.gi
//
16 117 olivier.gi
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26
// THE POSSIBILITY OF SUCH DAMAGE
27 2 olivier.gi
//
28
//----------------------------------------------------------------------------
29
//
30 34 olivier.gi
// *File Name: omsp_frontend.v
31 2 olivier.gi
// 
32
// *Module Description:
33
//                       openMSP430 Instruction fetch and decode unit
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39 17 olivier.gi
// $Rev: 192 $
40
// $LastChangedBy: olivier.girard $
41
// $LastChangedDate: 2013-12-17 21:15:28 +0100 (Tue, 17 Dec 2013) $
42
//----------------------------------------------------------------------------
43 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
44
`else
45 23 olivier.gi
`include "openMSP430_defines.v"
46 103 olivier.gi
`endif
47 2 olivier.gi
 
48 34 olivier.gi
module  omsp_frontend (
49 2 olivier.gi
 
50
// OUTPUTs
51 192 olivier.gi
    dbg_halt_st,                    // Halt/Run status from CPU
52
    decode_noirq,                   // Frontend decode instruction
53
    e_state,                        // Execution state
54
    exec_done,                      // Execution completed
55
    inst_ad,                        // Decoded Inst: destination addressing mode
56
    inst_as,                        // Decoded Inst: source addressing mode
57
    inst_alu,                       // ALU control signals
58
    inst_bw,                        // Decoded Inst: byte width
59
    inst_dest,                      // Decoded Inst: destination (one hot)
60
    inst_dext,                      // Decoded Inst: destination extended instruction word
61
    inst_irq_rst,                   // Decoded Inst: Reset interrupt
62
    inst_jmp,                       // Decoded Inst: Conditional jump
63
    inst_mov,                       // Decoded Inst: mov instruction
64
    inst_sext,                      // Decoded Inst: source extended instruction word
65
    inst_so,                        // Decoded Inst: Single-operand arithmetic
66
    inst_src,                       // Decoded Inst: source (one hot)
67
    inst_type,                      // Decoded Instruction type
68
    irq_acc,                        // Interrupt request accepted (one-hot signal)
69
    mab,                            // Frontend Memory address bus
70
    mb_en,                          // Frontend Memory bus enable
71
    mclk_enable,                    // Main System Clock enable
72
    mclk_wkup,                      // Main System Clock wake-up (asynchronous)
73
    nmi_acc,                        // Non-Maskable interrupt request accepted
74
    pc,                             // Program counter
75
    pc_nxt,                         // Next PC value (for CALL & IRQ)
76 2 olivier.gi
 
77
// INPUTs
78 192 olivier.gi
    cpu_en_s,                       // Enable CPU code execution (synchronous)
79
    cpuoff,                         // Turns off the CPU
80
    dbg_halt_cmd,                   // Halt CPU command
81
    dbg_reg_sel,                    // Debug selected register for rd/wr access
82
    fe_pmem_wait,                   // Frontend wait for Instruction fetch
83
    gie,                            // General interrupt enable
84
    irq,                            // Maskable interrupts
85
    mclk,                           // Main system clock
86
    mdb_in,                         // Frontend Memory data bus input
87
    nmi_pnd,                        // Non-maskable interrupt pending
88
    nmi_wkup,                       // NMI Wakeup
89
    pc_sw,                          // Program counter software value
90
    pc_sw_wr,                       // Program counter software write
91
    puc_rst,                        // Main system reset
92
    scan_enable,                    // Scan enable (active during scan shifting)
93
    wdt_irq,                        // Watchdog-timer interrupt
94
    wdt_wkup,                       // Watchdog Wakeup
95
    wkup                            // System Wake-up (asynchronous)
96 2 olivier.gi
);
97
 
98
// OUTPUTs
99
//=========
100 192 olivier.gi
output               dbg_halt_st;   // Halt/Run status from CPU
101
output               decode_noirq;  // Frontend decode instruction
102
output         [3:0] e_state;       // Execution state
103
output               exec_done;     // Execution completed
104
output         [7:0] inst_ad;       // Decoded Inst: destination addressing mode
105
output         [7:0] inst_as;       // Decoded Inst: source addressing mode
106
output        [11:0] inst_alu;      // ALU control signals
107
output               inst_bw;       // Decoded Inst: byte width
108
output        [15:0] inst_dest;     // Decoded Inst: destination (one hot)
109
output        [15:0] inst_dext;     // Decoded Inst: destination extended instruction word
110
output               inst_irq_rst;  // Decoded Inst: Reset interrupt
111
output         [7:0] inst_jmp;      // Decoded Inst: Conditional jump
112
output               inst_mov;      // Decoded Inst: mov instruction
113
output        [15:0] inst_sext;     // Decoded Inst: source extended instruction word
114
output         [7:0] inst_so;       // Decoded Inst: Single-operand arithmetic
115
output        [15:0] inst_src;      // Decoded Inst: source (one hot)
116
output         [2:0] inst_type;     // Decoded Instruction type
117
output [`IRQ_NR-3:0] irq_acc;       // Interrupt request accepted (one-hot signal)
118
output        [15:0] mab;           // Frontend Memory address bus
119
output               mb_en;         // Frontend Memory bus enable
120
output               mclk_enable;   // Main System Clock enable
121
output               mclk_wkup;     // Main System Clock wake-up (asynchronous)
122
output               nmi_acc;       // Non-Maskable interrupt request accepted
123
output        [15:0] pc;            // Program counter
124
output        [15:0] pc_nxt;        // Next PC value (for CALL & IRQ)
125 2 olivier.gi
 
126
// INPUTs
127
//=========
128 192 olivier.gi
input                cpu_en_s;      // Enable CPU code execution (synchronous)
129
input                cpuoff;        // Turns off the CPU
130
input                dbg_halt_cmd;  // Halt CPU command
131
input          [3:0] dbg_reg_sel;   // Debug selected register for rd/wr access
132
input                fe_pmem_wait;  // Frontend wait for Instruction fetch
133
input                gie;           // General interrupt enable
134
input  [`IRQ_NR-3:0] irq;           // Maskable interrupts
135
input                mclk;          // Main system clock
136
input         [15:0] mdb_in;        // Frontend Memory data bus input
137
input                nmi_pnd;       // Non-maskable interrupt pending
138
input                nmi_wkup;      // NMI Wakeup
139
input         [15:0] pc_sw;         // Program counter software value
140
input                pc_sw_wr;      // Program counter software write
141
input                puc_rst;       // Main system reset
142
input                scan_enable;   // Scan enable (active during scan shifting)
143
input                wdt_irq;       // Watchdog-timer interrupt
144
input                wdt_wkup;      // Watchdog Wakeup
145
input                wkup;          // System Wake-up (asynchronous)
146 2 olivier.gi
 
147
 
148
//=============================================================================
149 111 olivier.gi
// 1)  UTILITY FUNCTIONS
150 85 olivier.gi
//=============================================================================
151
 
152 192 olivier.gi
// 64 bits one-hot decoder
153
function [63:0] one_hot64;
154
   input  [5:0] binary;
155
   begin
156
      one_hot64         = 64'h0000_0000_0000_0000;
157
      one_hot64[binary] =  1'b1;
158
   end
159
endfunction
160
 
161 85 olivier.gi
// 16 bits one-hot decoder
162
function [15:0] one_hot16;
163
   input  [3:0] binary;
164
   begin
165
      one_hot16         = 16'h0000;
166
      one_hot16[binary] =  1'b1;
167
   end
168
endfunction
169 192 olivier.gi
 
170 85 olivier.gi
// 8 bits one-hot decoder
171
function [7:0] one_hot8;
172
   input  [2:0] binary;
173
   begin
174
      one_hot8         = 8'h00;
175
      one_hot8[binary] = 1'b1;
176
   end
177
endfunction
178 192 olivier.gi
 
179
// Get IRQ number
180
function  [5:0] get_irq_num;
181
   input [62:0] irq_all;
182
   integer      ii;
183
   begin
184
      get_irq_num = 6'h3f;
185
      for (ii = 62; ii >= 0; ii = ii - 1)
186
        if (&get_irq_num & irq_all[ii]) get_irq_num = ii[5:0];
187
   end
188
endfunction
189 85 olivier.gi
 
190
 
191
//=============================================================================
192 134 olivier.gi
// 2)  PARAMETER DEFINITIONS
193 2 olivier.gi
//=============================================================================
194
 
195 111 olivier.gi
//
196
// 2.1) Instruction State machine definitons
197
//-------------------------------------------
198
 
199
parameter I_IRQ_FETCH = `I_IRQ_FETCH;
200
parameter I_IRQ_DONE  = `I_IRQ_DONE;
201
parameter I_DEC       = `I_DEC;        // New instruction ready for decode
202
parameter I_EXT1      = `I_EXT1;       // 1st Extension word
203
parameter I_EXT2      = `I_EXT2;       // 2nd Extension word
204
parameter I_IDLE      = `I_IDLE;       // CPU is in IDLE mode
205
 
206
//
207
// 2.2) Execution State machine definitons
208
//-------------------------------------------
209
 
210
parameter E_IRQ_0     = `E_IRQ_0;
211
parameter E_IRQ_1     = `E_IRQ_1;
212
parameter E_IRQ_2     = `E_IRQ_2;
213
parameter E_IRQ_3     = `E_IRQ_3;
214
parameter E_IRQ_4     = `E_IRQ_4;
215
parameter E_SRC_AD    = `E_SRC_AD;
216
parameter E_SRC_RD    = `E_SRC_RD;
217
parameter E_SRC_WR    = `E_SRC_WR;
218
parameter E_DST_AD    = `E_DST_AD;
219
parameter E_DST_RD    = `E_DST_RD;
220
parameter E_DST_WR    = `E_DST_WR;
221
parameter E_EXEC      = `E_EXEC;
222
parameter E_JUMP      = `E_JUMP;
223
parameter E_IDLE      = `E_IDLE;
224
 
225
 
226
//=============================================================================
227
// 3)  FRONTEND STATE MACHINE
228
//=============================================================================
229
 
230 2 olivier.gi
// The wire "conv" is used as state bits to calculate the next response
231
reg  [2:0] i_state;
232
reg  [2:0] i_state_nxt;
233
 
234
reg  [1:0] inst_sz;
235
wire [1:0] inst_sz_nxt;
236
wire       irq_detect;
237
wire [2:0] inst_type_nxt;
238
wire       is_const;
239
reg [15:0] sconst_nxt;
240
reg  [3:0] e_state_nxt;
241 134 olivier.gi
 
242 106 olivier.gi
// CPU on/off through the debug interface or cpu_en port
243
wire   cpu_halt_cmd = dbg_halt_cmd | ~cpu_en_s;
244
 
245 2 olivier.gi
// States Transitions
246 111 olivier.gi
always @(i_state    or inst_sz  or inst_sz_nxt  or pc_sw_wr or exec_done or
247
         irq_detect or cpuoff   or cpu_halt_cmd or e_state)
248 2 olivier.gi
    case(i_state)
249 106 olivier.gi
      I_IDLE     : i_state_nxt = (irq_detect & ~cpu_halt_cmd) ? I_IRQ_FETCH :
250
                                 (~cpuoff    & ~cpu_halt_cmd) ? I_DEC       : I_IDLE;
251 2 olivier.gi
      I_IRQ_FETCH: i_state_nxt =  I_IRQ_DONE;
252
      I_IRQ_DONE : i_state_nxt =  I_DEC;
253
      I_DEC      : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
254 106 olivier.gi
                          (cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE      :
255 111 olivier.gi
                            cpu_halt_cmd & (e_state==E_IDLE)  ? I_IDLE      :
256 2 olivier.gi
                                  pc_sw_wr                    ? I_DEC       :
257 134 olivier.gi
                             ~exec_done & ~(e_state==E_IDLE)  ? I_DEC       :        // Wait in decode state
258 2 olivier.gi
                                  (inst_sz_nxt!=2'b00)        ? I_EXT1      : I_DEC; // until execution is completed
259 134 olivier.gi
      I_EXT1     : i_state_nxt =  pc_sw_wr                    ? I_DEC       :
260 2 olivier.gi
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
261 134 olivier.gi
      I_EXT2     : i_state_nxt =  I_DEC;
262
    // pragma coverage off
263 2 olivier.gi
      default    : i_state_nxt =  I_IRQ_FETCH;
264 134 olivier.gi
    // pragma coverage on
265 2 olivier.gi
    endcase
266
 
267
// State machine
268 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
269
  if (puc_rst) i_state  <= I_IRQ_FETCH;
270
  else         i_state  <= i_state_nxt;
271 2 olivier.gi
 
272
// Utility signals
273 111 olivier.gi
wire   decode_noirq =  ((i_state==I_DEC) &  (exec_done | (e_state==E_IDLE)));
274 53 olivier.gi
wire   decode       =  decode_noirq | irq_detect;
275 111 olivier.gi
wire   fetch        = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
276 2 olivier.gi
 
277
// Debug interface cpu status
278
reg    dbg_halt_st;
279 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
280
  if (puc_rst)  dbg_halt_st <= 1'b0;
281
  else          dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
282 2 olivier.gi
 
283
 
284
//=============================================================================
285 134 olivier.gi
// 4)  INTERRUPT HANDLING & SYSTEM WAKEUP
286 2 olivier.gi
//=============================================================================
287
 
288 134 olivier.gi
//
289
// 4.1) INTERRUPT HANDLING
290
//-----------------------------------------
291 2 olivier.gi
 
292
// Detect reset interrupt
293
reg         inst_irq_rst;
294 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
295
  if (puc_rst)                  inst_irq_rst <= 1'b1;
296 2 olivier.gi
  else if (exec_done)           inst_irq_rst <= 1'b0;
297
 
298
//  Detect other interrupts
299 134 olivier.gi
assign  irq_detect = (nmi_pnd | ((|irq | wdt_irq) & gie)) & ~cpu_halt_cmd & ~dbg_halt_st & (exec_done | (i_state==I_IDLE));
300 2 olivier.gi
 
301 134 olivier.gi
`ifdef CLOCK_GATING
302
wire       mclk_irq_num;
303
omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
304
                                    .clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
305
`else
306
wire       mclk_irq_num = mclk;
307
`endif
308
 
309 192 olivier.gi
// Combine all IRQs
310
`ifdef  IRQ_16
311
wire [62:0] irq_all     = {nmi_pnd, irq, 48'h0000_0000_0000} |
312
`else
313
`ifdef  IRQ_32
314
wire [62:0] irq_all     = {nmi_pnd, irq, 32'h0000}           |
315
`else
316
`ifdef  IRQ_64
317
wire [62:0] irq_all     = {nmi_pnd, irq}                     |
318
`endif
319
`endif
320
`endif
321
                          {1'b0,    3'h0, wdt_irq, {58{1'b0}}};
322
 
323
// Select highest priority IRQ
324
reg  [5:0] irq_num;
325 134 olivier.gi
always @(posedge mclk_irq_num or posedge puc_rst)
326 192 olivier.gi
  if (puc_rst)         irq_num <= 6'h3f;
327 134 olivier.gi
`ifdef CLOCK_GATING
328 192 olivier.gi
  else
329 134 olivier.gi
`else
330 192 olivier.gi
  else if (irq_detect)
331 134 olivier.gi
`endif
332 192 olivier.gi
                       irq_num <= get_irq_num(irq_all);
333 2 olivier.gi
 
334 192 olivier.gi
// Generate selected IRQ vector address
335
wire [15:0] irq_addr    = {9'h1ff, irq_num, 1'b0};
336 2 olivier.gi
 
337
// Interrupt request accepted
338 192 olivier.gi
wire        [63:0] irq_acc_all = one_hot64(irq_num) & {64{(i_state==I_IRQ_FETCH)}};
339
wire [`IRQ_NR-3:0] irq_acc     = irq_acc_all[61:64-`IRQ_NR];
340
wire               nmi_acc     = irq_acc_all[62];
341 2 olivier.gi
 
342 134 olivier.gi
//
343
// 4.2) SYSTEM WAKEUP
344
//-----------------------------------------
345
`ifdef CPUOFF_EN
346 2 olivier.gi
 
347 134 olivier.gi
// Generate the main system clock enable signal
348
                                                    // Keep the clock running if:
349
wire mclk_enable = inst_irq_rst ? cpu_en_s :        //      - the RESET interrupt is currently executing
350
                                                    //        and if the CPU is enabled
351
                                                    // otherwise if:
352
                  ~((cpuoff | ~cpu_en_s) &          //      - the CPUOFF flag, cpu_en command, instruction
353
                   (i_state==I_IDLE) &              //        and execution state machines are all two
354
                   (e_state==E_IDLE));              //        not idle.
355
 
356
 
357
// Wakeup condition from maskable interrupts
358
wire mirq_wkup;
359
omsp_and_gate and_mirq_wkup (.y(mirq_wkup), .a(wkup | wdt_wkup), .b(gie));
360
 
361
// Combined asynchronous wakeup detection from nmi & irq (masked if the cpu is disabled)
362
omsp_and_gate and_mclk_wkup (.y(mclk_wkup), .a(nmi_wkup | mirq_wkup), .b(cpu_en_s));
363
 
364
`else
365
 
366
// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
367
assign  mclk_wkup   = 1'b1;
368
assign  mclk_enable = 1'b1;
369
`endif
370
 
371 2 olivier.gi
//=============================================================================
372 111 olivier.gi
// 5)  FETCH INSTRUCTION
373 2 olivier.gi
//=============================================================================
374
 
375
//
376 111 olivier.gi
// 5.1) PROGRAM COUNTER & MEMORY INTERFACE
377 2 olivier.gi
//-----------------------------------------
378
 
379
// Program counter
380
reg  [15:0] pc;
381
 
382 60 olivier.gi
// Compute next PC value
383
wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
384
wire [15:0] pc_nxt  = pc_sw_wr               ? pc_sw    :
385 2 olivier.gi
                      (i_state==I_IRQ_FETCH) ? irq_addr :
386 60 olivier.gi
                      (i_state==I_IRQ_DONE)  ? mdb_in   :  pc_incr;
387 2 olivier.gi
 
388 134 olivier.gi
`ifdef CLOCK_GATING
389
wire       pc_en  = fetch                  |
390
                    pc_sw_wr               |
391
                    (i_state==I_IRQ_FETCH) |
392
                    (i_state==I_IRQ_DONE);
393
wire       mclk_pc;
394
omsp_clock_gate clock_gate_pc (.gclk(mclk_pc),
395
                               .clk (mclk), .enable(pc_en), .scan_enable(scan_enable));
396
`else
397
wire       mclk_pc = mclk;
398
`endif
399
 
400
always @(posedge mclk_pc or posedge puc_rst)
401 111 olivier.gi
  if (puc_rst)  pc <= 16'h0000;
402
  else          pc <= pc_nxt;
403 2 olivier.gi
 
404
// Check if ROM has been busy in order to retry ROM access
405 33 olivier.gi
reg pmem_busy;
406 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
407
  if (puc_rst)  pmem_busy <= 1'b0;
408
  else          pmem_busy <= fe_pmem_wait;
409 2 olivier.gi
 
410
// Memory interface
411
wire [15:0] mab      = pc_nxt;
412 106 olivier.gi
wire        mb_en    = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~cpu_halt_cmd);
413 2 olivier.gi
 
414
 
415
//
416 111 olivier.gi
// 5.2) INSTRUCTION REGISTER
417 2 olivier.gi
//--------------------------------
418
 
419
// Instruction register
420
wire [15:0] ir  = mdb_in;
421
 
422
// Detect if source extension word is required
423
wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
424
 
425
// For the Symbolic addressing mode, add -2 to the extension word in order
426
// to make up for the PC address
427
wire [15:0] ext_incr = ((i_state==I_EXT1)     &  inst_as[`SYMB]) |
428
                       ((i_state==I_EXT2)     &  inst_ad[`SYMB]) |
429
                       ((i_state==I_EXT1)     & ~inst_as[`SYMB] &
430
                       ~(i_state_nxt==I_EXT2) &  inst_ad[`SYMB])   ? 16'hfffe : 16'h0000;
431
 
432
wire [15:0] ext_nxt  = ir + ext_incr;
433
 
434
// Store source extension word
435
reg [15:0] inst_sext;
436 134 olivier.gi
 
437
`ifdef CLOCK_GATING
438
wire       inst_sext_en  = (decode & is_const)                 |
439
                           (decode & inst_type_nxt[`INST_JMP]) |
440
                           ((i_state==I_EXT1) & is_sext);
441
wire       mclk_inst_sext;
442
omsp_clock_gate clock_gate_inst_sext (.gclk(mclk_inst_sext),
443
                                      .clk (mclk), .enable(inst_sext_en), .scan_enable(scan_enable));
444
`else
445
wire       mclk_inst_sext = mclk;
446
`endif
447
 
448
always @(posedge mclk_inst_sext or posedge puc_rst)
449 111 olivier.gi
  if (puc_rst)                                 inst_sext <= 16'h0000;
450 2 olivier.gi
  else if (decode & is_const)                  inst_sext <= sconst_nxt;
451
  else if (decode & inst_type_nxt[`INST_JMP])  inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
452 134 olivier.gi
`ifdef CLOCK_GATING
453
  else                                         inst_sext <= ext_nxt;
454
`else
455 2 olivier.gi
  else if ((i_state==I_EXT1) & is_sext)        inst_sext <= ext_nxt;
456 134 olivier.gi
`endif
457 2 olivier.gi
 
458
// Source extension word is ready
459
wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
460
 
461
 
462
// Store destination extension word
463
reg [15:0] inst_dext;
464 134 olivier.gi
 
465
`ifdef CLOCK_GATING
466
wire       inst_dext_en  = ((i_state==I_EXT1) & ~is_sext) |
467
                            (i_state==I_EXT2);
468
wire       mclk_inst_dext;
469
omsp_clock_gate clock_gate_inst_dext (.gclk(mclk_inst_dext),
470
                                      .clk (mclk), .enable(inst_dext_en), .scan_enable(scan_enable));
471
`else
472
wire       mclk_inst_dext = mclk;
473
`endif
474
 
475
always @(posedge mclk_inst_dext or posedge puc_rst)
476 111 olivier.gi
  if (puc_rst)                           inst_dext <= 16'h0000;
477 2 olivier.gi
  else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
478 134 olivier.gi
`ifdef CLOCK_GATING
479
  else                                   inst_dext <= ext_nxt;
480
`else
481 2 olivier.gi
  else if  (i_state==I_EXT2)             inst_dext <= ext_nxt;
482 134 olivier.gi
`endif
483 2 olivier.gi
 
484
// Destination extension word is ready
485
wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
486
 
487
 
488
//=============================================================================
489 111 olivier.gi
// 6)  DECODE INSTRUCTION
490 2 olivier.gi
//=============================================================================
491
 
492 134 olivier.gi
`ifdef CLOCK_GATING
493
wire       mclk_decode;
494
omsp_clock_gate clock_gate_decode (.gclk(mclk_decode),
495
                                   .clk (mclk), .enable(decode), .scan_enable(scan_enable));
496
`else
497
wire       mclk_decode = mclk;
498
`endif
499
 
500 2 olivier.gi
//
501 111 olivier.gi
// 6.1) OPCODE: INSTRUCTION TYPE
502 2 olivier.gi
//----------------------------------------
503
// Instructions type is encoded in a one hot fashion as following:
504
//
505
// 3'b001: Single-operand arithmetic
506
// 3'b010: Conditional jump
507
// 3'b100: Two-operand arithmetic
508
 
509
reg  [2:0] inst_type;
510
assign     inst_type_nxt = {(ir[15:14]!=2'b00),
511
                            (ir[15:13]==3'b001),
512
                            (ir[15:13]==3'b000)} & {3{~irq_detect}};
513
 
514 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
515 111 olivier.gi
  if (puc_rst)      inst_type <= 3'b000;
516 134 olivier.gi
`ifdef CLOCK_GATING
517
  else              inst_type <= inst_type_nxt;
518
`else
519 111 olivier.gi
  else if (decode)  inst_type <= inst_type_nxt;
520 134 olivier.gi
`endif
521 2 olivier.gi
 
522
//
523 111 olivier.gi
// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC
524 2 olivier.gi
//----------------------------------------
525
// Instructions are encoded in a one hot fashion as following:
526
//
527
// 8'b00000001: RRC
528
// 8'b00000010: SWPB
529
// 8'b00000100: RRA
530
// 8'b00001000: SXT
531
// 8'b00010000: PUSH
532
// 8'b00100000: CALL
533
// 8'b01000000: RETI
534
// 8'b10000000: IRQ
535
 
536
reg   [7:0] inst_so;
537 85 olivier.gi
wire  [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
538 2 olivier.gi
 
539 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
540 111 olivier.gi
  if (puc_rst)     inst_so <= 8'h00;
541 134 olivier.gi
`ifdef CLOCK_GATING
542
  else             inst_so <= inst_so_nxt;
543
`else
544 2 olivier.gi
  else if (decode) inst_so <= inst_so_nxt;
545 134 olivier.gi
`endif
546 2 olivier.gi
 
547
//
548 111 olivier.gi
// 6.3) OPCODE: CONDITIONAL JUMP
549 2 olivier.gi
//--------------------------------
550
// Instructions are encoded in a one hot fashion as following:
551
//
552
// 8'b00000001: JNE/JNZ
553
// 8'b00000010: JEQ/JZ
554
// 8'b00000100: JNC/JLO
555
// 8'b00001000: JC/JHS
556
// 8'b00010000: JN
557
// 8'b00100000: JGE
558
// 8'b01000000: JL
559
// 8'b10000000: JMP
560
 
561
reg   [2:0] inst_jmp_bin;
562 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
563 111 olivier.gi
  if (puc_rst)     inst_jmp_bin <= 3'h0;
564 134 olivier.gi
`ifdef CLOCK_GATING
565
  else             inst_jmp_bin <= ir[12:10];
566
`else
567 2 olivier.gi
  else if (decode) inst_jmp_bin <= ir[12:10];
568 134 olivier.gi
`endif
569 2 olivier.gi
 
570 85 olivier.gi
wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
571 2 olivier.gi
 
572
 
573
//
574 111 olivier.gi
// 6.4) OPCODE: TWO-OPERAND ARITHMETIC
575 2 olivier.gi
//-------------------------------------
576
// Instructions are encoded in a one hot fashion as following:
577
//
578
// 12'b000000000001: MOV
579
// 12'b000000000010: ADD
580
// 12'b000000000100: ADDC
581
// 12'b000000001000: SUBC
582
// 12'b000000010000: SUB
583
// 12'b000000100000: CMP
584
// 12'b000001000000: DADD
585
// 12'b000010000000: BIT
586
// 12'b000100000000: BIC
587
// 12'b001000000000: BIS
588
// 12'b010000000000: XOR
589
// 12'b100000000000: AND
590
 
591 85 olivier.gi
wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
592 2 olivier.gi
wire [11:0] inst_to_nxt  = inst_to_1hot[15:4];
593
 
594 105 olivier.gi
reg         inst_mov;
595 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
596 111 olivier.gi
  if (puc_rst)     inst_mov <= 1'b0;
597 134 olivier.gi
`ifdef CLOCK_GATING
598
  else             inst_mov <= inst_to_nxt[`MOV];
599
`else
600 105 olivier.gi
  else if (decode) inst_mov <= inst_to_nxt[`MOV];
601 134 olivier.gi
`endif
602 2 olivier.gi
 
603 105 olivier.gi
 
604 2 olivier.gi
//
605 111 olivier.gi
// 6.5) SOURCE AND DESTINATION REGISTERS
606 2 olivier.gi
//---------------------------------------
607
 
608
// Destination register
609
reg [3:0] inst_dest_bin;
610 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
611 111 olivier.gi
  if (puc_rst)     inst_dest_bin <= 4'h0;
612 134 olivier.gi
`ifdef CLOCK_GATING
613
  else             inst_dest_bin <= ir[3:0];
614
`else
615 2 olivier.gi
  else if (decode) inst_dest_bin <= ir[3:0];
616 134 olivier.gi
`endif
617 2 olivier.gi
 
618 85 olivier.gi
wire  [15:0] inst_dest = dbg_halt_st          ? one_hot16(dbg_reg_sel) :
619
                         inst_type[`INST_JMP] ? 16'h0001               :
620 2 olivier.gi
                         inst_so[`IRQ]  |
621
                         inst_so[`PUSH] |
622 85 olivier.gi
                         inst_so[`CALL]       ? 16'h0002               :
623
                                                one_hot16(inst_dest_bin);
624 2 olivier.gi
 
625
 
626
// Source register
627
reg [3:0] inst_src_bin;
628 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
629 111 olivier.gi
  if (puc_rst)     inst_src_bin <= 4'h0;
630 134 olivier.gi
`ifdef CLOCK_GATING
631
  else             inst_src_bin <= ir[11:8];
632
`else
633 2 olivier.gi
  else if (decode) inst_src_bin <= ir[11:8];
634 134 olivier.gi
`endif
635 2 olivier.gi
 
636 85 olivier.gi
wire  [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin)  :
637
                        inst_so[`RETI]      ? 16'h0002                 :
638
                        inst_so[`IRQ]       ? 16'h0001                 :
639
                        inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000;
640 2 olivier.gi
 
641
 
642
//
643 111 olivier.gi
// 6.6) SOURCE ADDRESSING MODES
644 2 olivier.gi
//--------------------------------
645
// Source addressing modes are encoded in a one hot fashion as following:
646
//
647
// 13'b0000000000001: Register direct.
648
// 13'b0000000000010: Register indexed.
649
// 13'b0000000000100: Register indirect.
650
// 13'b0000000001000: Register indirect autoincrement.
651
// 13'b0000000010000: Symbolic (operand is in memory at address PC+x).
652
// 13'b0000000100000: Immediate (operand is next word in the instruction stream).
653
// 13'b0000001000000: Absolute (operand is in memory at address x).
654
// 13'b0000010000000: Constant 4.
655
// 13'b0000100000000: Constant 8.
656
// 13'b0001000000000: Constant 0.
657
// 13'b0010000000000: Constant 1.
658
// 13'b0100000000000: Constant 2.
659
// 13'b1000000000000: Constant -1.
660
 
661
reg [12:0] inst_as_nxt;
662
 
663
wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8];
664
 
665
always @(src_reg or ir or inst_type_nxt)
666
  begin
667
     if (inst_type_nxt[`INST_JMP])
668
       inst_as_nxt =  13'b0000000000001;
669
     else if (src_reg==4'h3) // Addressing mode using R3
670
       case (ir[5:4])
671 134 olivier.gi
         2'b11  : inst_as_nxt =  13'b1000000000000;
672
         2'b10  : inst_as_nxt =  13'b0100000000000;
673
         2'b01  : inst_as_nxt =  13'b0010000000000;
674
         default: inst_as_nxt =  13'b0001000000000;
675 2 olivier.gi
       endcase
676
     else if (src_reg==4'h2) // Addressing mode using R2
677
       case (ir[5:4])
678 134 olivier.gi
         2'b11  : inst_as_nxt =  13'b0000100000000;
679
         2'b10  : inst_as_nxt =  13'b0000010000000;
680
         2'b01  : inst_as_nxt =  13'b0000001000000;
681
         default: inst_as_nxt =  13'b0000000000001;
682 2 olivier.gi
       endcase
683
     else if (src_reg==4'h0) // Addressing mode using R0
684
       case (ir[5:4])
685 134 olivier.gi
         2'b11  : inst_as_nxt =  13'b0000000100000;
686
         2'b10  : inst_as_nxt =  13'b0000000000100;
687
         2'b01  : inst_as_nxt =  13'b0000000010000;
688
         default: inst_as_nxt =  13'b0000000000001;
689 2 olivier.gi
       endcase
690
     else                    // General Addressing mode
691
       case (ir[5:4])
692 134 olivier.gi
         2'b11  : inst_as_nxt =  13'b0000000001000;
693
         2'b10  : inst_as_nxt =  13'b0000000000100;
694
         2'b01  : inst_as_nxt =  13'b0000000000010;
695
         default: inst_as_nxt =  13'b0000000000001;
696 2 olivier.gi
       endcase
697
  end
698
assign    is_const = |inst_as_nxt[12:7];
699
 
700
reg [7:0] inst_as;
701 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
702 111 olivier.gi
  if (puc_rst)     inst_as <= 8'h00;
703 134 olivier.gi
`ifdef CLOCK_GATING
704
  else             inst_as <= {is_const, inst_as_nxt[6:0]};
705
`else
706 2 olivier.gi
  else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
707 134 olivier.gi
`endif
708 2 olivier.gi
 
709
 
710
// 13'b0000010000000: Constant 4.
711
// 13'b0000100000000: Constant 8.
712
// 13'b0001000000000: Constant 0.
713
// 13'b0010000000000: Constant 1.
714
// 13'b0100000000000: Constant 2.
715
// 13'b1000000000000: Constant -1.
716
always @(inst_as_nxt)
717
  begin
718
     if (inst_as_nxt[7])        sconst_nxt = 16'h0004;
719
     else if (inst_as_nxt[8])   sconst_nxt = 16'h0008;
720
     else if (inst_as_nxt[9])   sconst_nxt = 16'h0000;
721
     else if (inst_as_nxt[10])  sconst_nxt = 16'h0001;
722
     else if (inst_as_nxt[11])  sconst_nxt = 16'h0002;
723
     else if (inst_as_nxt[12])  sconst_nxt = 16'hffff;
724
     else                       sconst_nxt = 16'h0000;
725
  end
726
 
727
 
728
//
729 111 olivier.gi
// 6.7) DESTINATION ADDRESSING MODES
730 2 olivier.gi
//-----------------------------------
731
// Destination addressing modes are encoded in a one hot fashion as following:
732
//
733
// 8'b00000001: Register direct.
734
// 8'b00000010: Register indexed.
735
// 8'b00010000: Symbolic (operand is in memory at address PC+x).
736
// 8'b01000000: Absolute (operand is in memory at address x).
737
 
738
reg  [7:0] inst_ad_nxt;
739
 
740
wire [3:0] dest_reg = ir[3:0];
741
 
742
always @(dest_reg or ir or inst_type_nxt)
743
  begin
744
     if (~inst_type_nxt[`INST_TO])
745
       inst_ad_nxt =  8'b00000000;
746
     else if (dest_reg==4'h2)   // Addressing mode using R2
747
       case (ir[7])
748 134 olivier.gi
         1'b1   : inst_ad_nxt =  8'b01000000;
749
         default: inst_ad_nxt =  8'b00000001;
750 2 olivier.gi
       endcase
751
     else if (dest_reg==4'h0)   // Addressing mode using R0
752
       case (ir[7])
753 134 olivier.gi
         1'b1   : inst_ad_nxt =  8'b00010000;
754
         default: inst_ad_nxt =  8'b00000001;
755 2 olivier.gi
       endcase
756
     else                       // General Addressing mode
757
       case (ir[7])
758 134 olivier.gi
         1'b1   : inst_ad_nxt =  8'b00000010;
759
         default: inst_ad_nxt =  8'b00000001;
760 2 olivier.gi
       endcase
761
  end
762
 
763
reg [7:0] inst_ad;
764 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
765 111 olivier.gi
  if (puc_rst)     inst_ad <= 8'h00;
766 134 olivier.gi
`ifdef CLOCK_GATING
767
  else             inst_ad <= inst_ad_nxt;
768
`else
769 2 olivier.gi
  else if (decode) inst_ad <= inst_ad_nxt;
770 134 olivier.gi
`endif
771 2 olivier.gi
 
772
 
773
//
774 111 olivier.gi
// 6.8) REMAINING INSTRUCTION DECODING
775 2 olivier.gi
//-------------------------------------
776
 
777
// Operation size
778
reg       inst_bw;
779 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
780
  if (puc_rst)     inst_bw     <= 1'b0;
781 106 olivier.gi
  else if (decode) inst_bw     <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~cpu_halt_cmd;
782 2 olivier.gi
 
783
// Extended instruction size
784
assign    inst_sz_nxt = {1'b0,  (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
785
                        {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
786 134 olivier.gi
always @(posedge mclk_decode or posedge puc_rst)
787 111 olivier.gi
  if (puc_rst)     inst_sz     <= 2'b00;
788 134 olivier.gi
`ifdef CLOCK_GATING
789
  else             inst_sz     <= inst_sz_nxt;
790
`else
791 2 olivier.gi
  else if (decode) inst_sz     <= inst_sz_nxt;
792 134 olivier.gi
`endif
793 2 olivier.gi
 
794
 
795
//=============================================================================
796 111 olivier.gi
// 7)  EXECUTION-UNIT STATE MACHINE
797 2 olivier.gi
//=============================================================================
798
 
799
// State machine registers
800
reg  [3:0] e_state;
801
 
802
 
803
// State machine control signals
804
//--------------------------------
805
 
806
wire src_acalc_pre =  inst_as_nxt[`IDX]   | inst_as_nxt[`SYMB]    | inst_as_nxt[`ABS];
807
wire src_rd_pre    =  inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM]  | inst_so_nxt[`RETI];
808
wire dst_acalc_pre =  inst_ad_nxt[`IDX]   | inst_ad_nxt[`SYMB]    | inst_ad_nxt[`ABS];
809
wire dst_acalc     =  inst_ad[`IDX]       | inst_ad[`SYMB]        | inst_ad[`ABS];
810
wire dst_rd_pre    =  inst_ad_nxt[`IDX]   | inst_so_nxt[`PUSH]    | inst_so_nxt[`CALL] | inst_so_nxt[`RETI];
811
wire dst_rd        =  inst_ad[`IDX]       | inst_so[`PUSH]        | inst_so[`CALL]     | inst_so[`RETI];
812
 
813
wire inst_branch   =  (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI];
814
 
815
reg exec_jmp;
816 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
817
  if (puc_rst)                   exec_jmp <= 1'b0;
818 2 olivier.gi
  else if (inst_branch & decode) exec_jmp <= 1'b1;
819 111 olivier.gi
  else if (e_state==E_JUMP)      exec_jmp <= 1'b0;
820 2 olivier.gi
 
821
reg exec_dst_wr;
822 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
823
  if (puc_rst)                exec_dst_wr <= 1'b0;
824
  else if (e_state==E_DST_RD) exec_dst_wr <= 1'b1;
825
  else if (e_state==E_DST_WR) exec_dst_wr <= 1'b0;
826 2 olivier.gi
 
827
reg exec_src_wr;
828 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
829
  if (puc_rst)                                         exec_src_wr <= 1'b0;
830
  else if (inst_type[`INST_SO] & (e_state==E_SRC_RD))  exec_src_wr <= 1'b1;
831
  else if ((e_state==E_SRC_WR) || (e_state==E_DST_WR)) exec_src_wr <= 1'b0;
832 2 olivier.gi
 
833
reg exec_dext_rdy;
834 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
835
  if (puc_rst)                exec_dext_rdy <= 1'b0;
836
  else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0;
837
  else if (inst_dext_rdy)     exec_dext_rdy <= 1'b1;
838 2 olivier.gi
 
839
// Execution first state
840 111 olivier.gi
wire [3:0] e_first_state = ~dbg_halt_st  & inst_so_nxt[`IRQ] ? E_IRQ_0  :
841
                            cpu_halt_cmd | (i_state==I_IDLE) ? E_IDLE   :
842
                            cpuoff                           ? E_IDLE   :
843
                            src_acalc_pre                    ? E_SRC_AD :
844
                            src_rd_pre                       ? E_SRC_RD :
845
                            dst_acalc_pre                    ? E_DST_AD :
846
                            dst_rd_pre                       ? E_DST_RD : E_EXEC;
847 2 olivier.gi
 
848
 
849
// State machine
850
//--------------------------------
851
 
852
// States Transitions
853
always @(e_state       or dst_acalc     or dst_rd   or inst_sext_rdy or
854
         inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr   or
855
         e_first_state or exec_src_wr)
856
    case(e_state)
857 111 olivier.gi
      E_IDLE   : e_state_nxt =  e_first_state;
858
      E_IRQ_0  : e_state_nxt =  E_IRQ_1;
859
      E_IRQ_1  : e_state_nxt =  E_IRQ_2;
860
      E_IRQ_2  : e_state_nxt =  E_IRQ_3;
861
      E_IRQ_3  : e_state_nxt =  E_IRQ_4;
862
      E_IRQ_4  : e_state_nxt =  E_EXEC;
863 2 olivier.gi
 
864 111 olivier.gi
      E_SRC_AD : e_state_nxt =  inst_sext_rdy     ? E_SRC_RD : E_SRC_AD;
865 2 olivier.gi
 
866 111 olivier.gi
      E_SRC_RD : e_state_nxt =  dst_acalc         ? E_DST_AD :
867
                                 dst_rd           ? E_DST_RD : E_EXEC;
868 2 olivier.gi
 
869 111 olivier.gi
      E_DST_AD : e_state_nxt =  (inst_dext_rdy |
870
                                 exec_dext_rdy)   ? E_DST_RD : E_DST_AD;
871 2 olivier.gi
 
872 111 olivier.gi
      E_DST_RD : e_state_nxt =  E_EXEC;
873 2 olivier.gi
 
874 111 olivier.gi
      E_EXEC   : e_state_nxt =  exec_dst_wr       ? E_DST_WR :
875
                                exec_jmp          ? E_JUMP   :
876
                                exec_src_wr       ? E_SRC_WR : e_first_state;
877 2 olivier.gi
 
878 111 olivier.gi
      E_JUMP   : e_state_nxt =  e_first_state;
879
      E_DST_WR : e_state_nxt =  exec_jmp          ? E_JUMP   : e_first_state;
880
      E_SRC_WR : e_state_nxt =  e_first_state;
881 134 olivier.gi
    // pragma coverage off
882 111 olivier.gi
      default  : e_state_nxt =  E_IRQ_0;
883 134 olivier.gi
    // pragma coverage on
884 2 olivier.gi
    endcase
885
 
886
// State machine
887 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
888
  if (puc_rst) e_state  <= E_IRQ_1;
889 2 olivier.gi
  else         e_state  <= e_state_nxt;
890
 
891
 
892
// Frontend State machine control signals
893
//----------------------------------------
894
 
895 111 olivier.gi
wire exec_done = exec_jmp        ? (e_state==E_JUMP)   :
896
                 exec_dst_wr     ? (e_state==E_DST_WR) :
897
                 exec_src_wr     ? (e_state==E_SRC_WR) : (e_state==E_EXEC);
898 2 olivier.gi
 
899
 
900
//=============================================================================
901 111 olivier.gi
// 8)  EXECUTION-UNIT STATE CONTROL
902 2 olivier.gi
//=============================================================================
903
 
904
//
905 111 olivier.gi
// 8.1) ALU CONTROL SIGNALS
906 2 olivier.gi
//-------------------------------------
907
//
908
// 12'b000000000001: Enable ALU source inverter
909
// 12'b000000000010: Enable Incrementer
910
// 12'b000000000100: Enable Incrementer on carry bit
911
// 12'b000000001000: Select Adder
912
// 12'b000000010000: Select AND
913
// 12'b000000100000: Select OR
914
// 12'b000001000000: Select XOR
915
// 12'b000010000000: Select DADD
916
// 12'b000100000000: Update N, Z & C (C=~Z)
917
// 12'b001000000000: Update all status bits
918
// 12'b010000000000: Update status bit for XOR instruction
919
// 12'b100000000000: Don't write to destination
920
 
921
reg  [11:0] inst_alu;
922
 
923
wire        alu_src_inv   = inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC] |
924
                            inst_to_nxt[`CMP]  | inst_to_nxt[`BIC] ;
925
 
926
wire        alu_inc       = inst_to_nxt[`SUB]  | inst_to_nxt[`CMP];
927
 
928
wire        alu_inc_c     = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] |
929
                            inst_to_nxt[`SUBC];
930
 
931
wire        alu_add       = inst_to_nxt[`ADD]  | inst_to_nxt[`ADDC]       |
932
                            inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC]       |
933
                            inst_to_nxt[`CMP]  | inst_type_nxt[`INST_JMP] |
934
                            inst_so_nxt[`RETI];
935
 
936
 
937
wire        alu_and       = inst_to_nxt[`AND]  | inst_to_nxt[`BIC]  |
938
                            inst_to_nxt[`BIT];
939
 
940
wire        alu_or        = inst_to_nxt[`BIS];
941
 
942
wire        alu_xor       = inst_to_nxt[`XOR];
943
 
944
wire        alu_dadd      = inst_to_nxt[`DADD];
945
 
946
wire        alu_stat_7    = inst_to_nxt[`BIT]  | inst_to_nxt[`AND]  |
947
                            inst_so_nxt[`SXT];
948
 
949
wire        alu_stat_f    = inst_to_nxt[`ADD]  | inst_to_nxt[`ADDC] |
950
                            inst_to_nxt[`SUB]  | inst_to_nxt[`SUBC] |
951
                            inst_to_nxt[`CMP]  | inst_to_nxt[`DADD] |
952
                            inst_to_nxt[`BIT]  | inst_to_nxt[`XOR]  |
953
                            inst_to_nxt[`AND]  |
954
                            inst_so_nxt[`RRC]  | inst_so_nxt[`RRA]  |
955
                            inst_so_nxt[`SXT];
956
 
957
wire        alu_shift     = inst_so_nxt[`RRC]  | inst_so_nxt[`RRA];
958
 
959
wire        exec_no_wr    = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
960
 
961 134 olivier.gi
wire [11:0] inst_alu_nxt  = {exec_no_wr,
962
                             alu_shift,
963
                             alu_stat_f,
964
                             alu_stat_7,
965
                             alu_dadd,
966
                             alu_xor,
967
                             alu_or,
968
                             alu_and,
969
                             alu_add,
970
                             alu_inc_c,
971
                             alu_inc,
972
                             alu_src_inv};
973
 
974
always @(posedge mclk_decode or posedge puc_rst)
975 111 olivier.gi
  if (puc_rst)     inst_alu <= 12'h000;
976 134 olivier.gi
`ifdef CLOCK_GATING
977
  else             inst_alu <= inst_alu_nxt;
978
`else
979
  else if (decode) inst_alu <= inst_alu_nxt;
980
`endif
981 2 olivier.gi
 
982
 
983 34 olivier.gi
endmodule // omsp_frontend
984 33 olivier.gi
 
985 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
986
`else
987 33 olivier.gi
`include "openMSP430_undefines.v"
988 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

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