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

Subversion Repositories openmsp430

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

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

powered by: WebSVN 2.1.0

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