1 //----------------------------------------------------------------------------
2 // Copyright (C) 2001 Authors
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
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.
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.
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
23 //----------------------------------------------------------------------------
25 // *File Name: omsp_frontend.v
27 // *Module Description:
28 // openMSP430 Instruction fetch and decode unit
31 // - Olivier Girard, olgirard@gmail.com
33 //----------------------------------------------------------------------------
35 // $LastChangedBy: olivier.girard $
36 // $LastChangedDate: 2010-02-03 22:12:25 +0100 (Wed, 03 Feb 2010) $
37 //----------------------------------------------------------------------------
38 `include "timescale.v"
39 `include "openMSP430_defines.v"
41 module omsp_frontend (
44 dbg_halt_st, // Halt/Run status from CPU
45 decode_noirq, // Frontend decode instruction
46 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)
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 fe_pmem_wait, // Frontend wait for Instruction fetch
72 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
85 output dbg_halt_st; // Halt/Run status from CPU
86 output decode_noirq; // Frontend decode instruction
87 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)
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 input fe_pmem_wait; // Frontend wait for Instruction fetch
114 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
125 //=============================================================================
126 // 1) FRONTEND STATE MACHINE
127 //=============================================================================
129 // The wire "conv" is used as state bits to calculate the next response
131 reg [2:0] i_state_nxt;
134 wire [1:0] inst_sz_nxt;
136 wire [2:0] inst_type_nxt;
138 reg [15:0] sconst_nxt;
139 reg [3:0] e_state_nxt;
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
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)
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 :
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 :
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;
171 always @(posedge mclk or posedge puc)
172 if (puc) i_state <= I_IRQ_FETCH;
173 else i_state <= i_state_nxt;
176 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);
180 // Debug interface cpu status
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);
187 //=============================================================================
188 // 2) INTERRUPT HANDLING
189 //=============================================================================
191 // Detect nmi interrupt
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;
199 // Detect reset interrupt
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;
205 // Detect other interrupts
206 assign irq_detect = (inst_nmi | ((|irq | wdt_irq) & gie)) & ~dbg_halt_cmd & (exec_done | (i_state==I_IDLE));
208 // Select interrupt vector
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 :
216 (irq[10] | wdt_irq) ? 4'ha :
226 irq[0] ? 4'h0 : 4'hf;
228 wire [15:0] irq_addr = {11'h7ff, irq_num, 1'b0};
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];
236 //=============================================================================
237 // 3) FETCH INSTRUCTION
238 //=============================================================================
241 // 3.1) PROGRAM COUNTER & MEMORY INTERFACE
242 //-----------------------------------------
247 // Compute next PC value
248 wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
249 wire [15:0] pc_nxt = pc_sw_wr ? pc_sw :
250 (i_state==I_IRQ_FETCH) ? irq_addr :
251 (i_state==I_IRQ_DONE) ? mdb_in : pc_incr;
253 always @(posedge mclk or posedge puc)
254 if (puc) pc <= 16'h0000;
257 // Check if ROM has been busy in order to retry ROM access
259 always @(posedge mclk or posedge puc)
260 if (puc) pmem_busy <= 16'h0000;
261 else pmem_busy <= fe_pmem_wait;
264 wire [15:0] mab = pc_nxt;
265 wire mb_en = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~dbg_halt_cmd);
269 // 3.2) INSTRUCTION REGISTER
270 //--------------------------------
272 // Instruction register
273 wire [15:0] ir = mdb_in;
275 // Detect if source extension word is required
276 wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
278 // Detect if destination extension word is required
279 wire is_dext = (inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS]);
281 // For the Symbolic addressing mode, add -2 to the extension word in order
282 // to make up for the PC address
283 wire [15:0] ext_incr = ((i_state==I_EXT1) & inst_as[`SYMB]) |
284 ((i_state==I_EXT2) & inst_ad[`SYMB]) |
285 ((i_state==I_EXT1) & ~inst_as[`SYMB] &
286 ~(i_state_nxt==I_EXT2) & inst_ad[`SYMB]) ? 16'hfffe : 16'h0000;
288 wire [15:0] ext_nxt = ir + ext_incr;
290 // Store source extension word
291 reg [15:0] inst_sext;
292 always @(posedge mclk or posedge puc)
293 if (puc) inst_sext <= 16'h0000;
294 else if (decode & is_const) inst_sext <= sconst_nxt;
295 else if (decode & inst_type_nxt[`INST_JMP]) inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
296 else if ((i_state==I_EXT1) & is_sext) inst_sext <= ext_nxt;
298 // Source extension word is ready
299 wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
302 // Store destination extension word
303 reg [15:0] inst_dext;
304 always @(posedge mclk or posedge puc)
305 if (puc) inst_dext <= 16'h0000;
306 else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
307 else if (i_state==I_EXT2) inst_dext <= ext_nxt;
309 // Destination extension word is ready
310 wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
313 //=============================================================================
314 // 4) DECODE INSTRUCTION
315 //=============================================================================
318 // 4.1) OPCODE: INSTRUCTION TYPE
319 //----------------------------------------
320 // Instructions type is encoded in a one hot fashion as following:
322 // 3'b001: Single-operand arithmetic
323 // 3'b010: Conditional jump
324 // 3'b100: Two-operand arithmetic
327 assign inst_type_nxt = {(ir[15:14]!=2'b00),
329 (ir[15:13]==3'b000)} & {3{~irq_detect}};
331 always @(posedge mclk or posedge puc)
332 if (puc) inst_type <= 3'b000;
333 else if (decode) inst_type <= inst_type_nxt;
336 // 4.2) OPCODE: SINGLE-OPERAND ARITHMETIC
337 //----------------------------------------
338 // Instructions are encoded in a one hot fashion as following:
350 wire [7:0] inst_so_nxt = irq_detect ? 8'h80 : ((8'h01<<ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
352 always @(posedge mclk or posedge puc)
353 if (puc) inst_so <= 8'h00;
354 else if (decode) inst_so <= inst_so_nxt;
357 // 4.3) OPCODE: CONDITIONAL JUMP
358 //--------------------------------
359 // Instructions are encoded in a one hot fashion as following:
361 // 8'b00000001: JNE/JNZ
362 // 8'b00000010: JEQ/JZ
363 // 8'b00000100: JNC/JLO
364 // 8'b00001000: JC/JHS
370 reg [2:0] inst_jmp_bin;
371 always @(posedge mclk or posedge puc)
372 if (puc) inst_jmp_bin <= 3'h0;
373 else if (decode) inst_jmp_bin <= ir[12:10];
375 wire [7:0] inst_jmp = (8'h01<<inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
379 // 4.4) OPCODE: TWO-OPERAND ARITHMETIC
380 //-------------------------------------
381 // Instructions are encoded in a one hot fashion as following:
383 // 12'b000000000001: MOV
384 // 12'b000000000010: ADD
385 // 12'b000000000100: ADDC
386 // 12'b000000001000: SUBC
387 // 12'b000000010000: SUB
388 // 12'b000000100000: CMP
389 // 12'b000001000000: DADD
390 // 12'b000010000000: BIT
391 // 12'b000100000000: BIC
392 // 12'b001000000000: BIS
393 // 12'b010000000000: XOR
394 // 12'b100000000000: AND
396 wire [15:0] inst_to_1hot = (16'h0001<<ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
397 wire [11:0] inst_to_nxt = inst_to_1hot[15:4];
401 // 4.5) SOURCE AND DESTINATION REGISTERS
402 //---------------------------------------
404 // Destination register
405 reg [3:0] inst_dest_bin;
406 always @(posedge mclk or posedge puc)
407 if (puc) inst_dest_bin <= 4'h0;
408 else if (decode) inst_dest_bin <= ir[3:0];
410 wire [15:0] inst_dest = dbg_halt_st ? (16'h0001 << dbg_reg_sel) :
411 inst_type[`INST_JMP] ? 16'h0001 :
414 inst_so[`CALL] ? 16'h0002 :
415 (16'h0001 << inst_dest_bin);
419 reg [3:0] inst_src_bin;
420 always @(posedge mclk or posedge puc)
421 if (puc) inst_src_bin <= 4'h0;
422 else if (decode) inst_src_bin <= ir[11:8];
424 wire [15:0] inst_src = inst_type[`INST_TO] ? (16'h0001 << inst_src_bin) :
425 inst_so[`RETI] ? 16'h0002 :
426 inst_so[`IRQ] ? 16'h0001 :
427 inst_type[`INST_SO] ? (16'h0001 << inst_dest_bin) : 16'h0000;
431 // 4.6) SOURCE ADDRESSING MODES
432 //--------------------------------
433 // Source addressing modes are encoded in a one hot fashion as following:
435 // 13'b0000000000001: Register direct.
436 // 13'b0000000000010: Register indexed.
437 // 13'b0000000000100: Register indirect.
438 // 13'b0000000001000: Register indirect autoincrement.
439 // 13'b0000000010000: Symbolic (operand is in memory at address PC+x).
440 // 13'b0000000100000: Immediate (operand is next word in the instruction stream).
441 // 13'b0000001000000: Absolute (operand is in memory at address x).
442 // 13'b0000010000000: Constant 4.
443 // 13'b0000100000000: Constant 8.
444 // 13'b0001000000000: Constant 0.
445 // 13'b0010000000000: Constant 1.
446 // 13'b0100000000000: Constant 2.
447 // 13'b1000000000000: Constant -1.
449 reg [12:0] inst_as_nxt;
451 wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8];
453 always @(src_reg or ir or inst_type_nxt)
455 if (inst_type_nxt[`INST_JMP])
456 inst_as_nxt = 13'b0000000000001;
457 else if (src_reg==4'h3) // Addressing mode using R3
459 2'b11 : inst_as_nxt = 13'b1000000000000;
460 2'b10 : inst_as_nxt = 13'b0100000000000;
461 2'b01 : inst_as_nxt = 13'b0010000000000;
462 default: inst_as_nxt = 13'b0001000000000;
464 else if (src_reg==4'h2) // Addressing mode using R2
466 2'b11 : inst_as_nxt = 13'b0000100000000;
467 2'b10 : inst_as_nxt = 13'b0000010000000;
468 2'b01 : inst_as_nxt = 13'b0000001000000;
469 default: inst_as_nxt = 13'b0000000000001;
471 else if (src_reg==4'h0) // Addressing mode using R0
473 2'b11 : inst_as_nxt = 13'b0000000100000;
474 2'b10 : inst_as_nxt = 13'b0000000000100;
475 2'b01 : inst_as_nxt = 13'b0000000010000;
476 default: inst_as_nxt = 13'b0000000000001;
478 else // General Addressing mode
480 2'b11 : inst_as_nxt = 13'b0000000001000;
481 2'b10 : inst_as_nxt = 13'b0000000000100;
482 2'b01 : inst_as_nxt = 13'b0000000000010;
483 default: inst_as_nxt = 13'b0000000000001;
486 assign is_const = |inst_as_nxt[12:7];
489 always @(posedge mclk or posedge puc)
490 if (puc) inst_as <= 8'h00;
491 else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
494 // 13'b0000010000000: Constant 4.
495 // 13'b0000100000000: Constant 8.
496 // 13'b0001000000000: Constant 0.
497 // 13'b0010000000000: Constant 1.
498 // 13'b0100000000000: Constant 2.
499 // 13'b1000000000000: Constant -1.
500 always @(inst_as_nxt)
502 if (inst_as_nxt[7]) sconst_nxt = 16'h0004;
503 else if (inst_as_nxt[8]) sconst_nxt = 16'h0008;
504 else if (inst_as_nxt[9]) sconst_nxt = 16'h0000;
505 else if (inst_as_nxt[10]) sconst_nxt = 16'h0001;
506 else if (inst_as_nxt[11]) sconst_nxt = 16'h0002;
507 else if (inst_as_nxt[12]) sconst_nxt = 16'hffff;
508 else sconst_nxt = 16'h0000;
513 // 4.7) DESTINATION ADDRESSING MODES
514 //-----------------------------------
515 // Destination addressing modes are encoded in a one hot fashion as following:
517 // 8'b00000001: Register direct.
518 // 8'b00000010: Register indexed.
519 // 8'b00010000: Symbolic (operand is in memory at address PC+x).
520 // 8'b01000000: Absolute (operand is in memory at address x).
522 reg [7:0] inst_ad_nxt;
524 wire [3:0] dest_reg = ir[3:0];
526 always @(dest_reg or ir or inst_type_nxt)
528 if (~inst_type_nxt[`INST_TO])
529 inst_ad_nxt = 8'b00000000;
530 else if (dest_reg==4'h2) // Addressing mode using R2
532 1'b1 : inst_ad_nxt = 8'b01000000;
533 default: inst_ad_nxt = 8'b00000001;
535 else if (dest_reg==4'h0) // Addressing mode using R0
537 2'b1 : inst_ad_nxt = 8'b00010000;
538 default: inst_ad_nxt = 8'b00000001;
540 else // General Addressing mode
542 2'b1 : inst_ad_nxt = 8'b00000010;
543 default: inst_ad_nxt = 8'b00000001;
548 always @(posedge mclk or posedge puc)
549 if (puc) inst_ad <= 8'h00;
550 else if (decode) inst_ad <= inst_ad_nxt;
554 // 4.8) REMAINING INSTRUCTION DECODING
555 //-------------------------------------
559 always @(posedge mclk or posedge puc)
560 if (puc) inst_bw <= 1'b0;
561 else if (decode) inst_bw <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~dbg_halt_cmd;
563 // Extended instruction size
564 assign inst_sz_nxt = {1'b0, (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
565 {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
566 always @(posedge mclk or posedge puc)
567 if (puc) inst_sz <= 2'b00;
568 else if (decode) inst_sz <= inst_sz_nxt;
571 //=============================================================================
572 // 5) EXECUTION-UNIT STATE MACHINE
573 //=============================================================================
575 // State machine registers
579 // State machine control signals
580 //--------------------------------
582 wire src_acalc_pre = inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS];
583 wire src_rd_pre = inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM] | inst_so_nxt[`RETI];
584 wire dst_acalc_pre = inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS];
585 wire dst_acalc = inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS];
586 wire dst_rd_pre = inst_ad_nxt[`IDX] | inst_so_nxt[`PUSH] | inst_so_nxt[`CALL] | inst_so_nxt[`RETI];
587 wire dst_rd = inst_ad[`IDX] | inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI];
589 wire inst_branch = (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI];
592 always @(posedge mclk or posedge puc)
593 if (puc) exec_jmp <= 1'b0;
594 else if (inst_branch & decode) exec_jmp <= 1'b1;
595 else if (e_state==`E_JUMP) exec_jmp <= 1'b0;
598 always @(posedge mclk or posedge puc)
599 if (puc) exec_dst_wr <= 1'b0;
600 else if (e_state==`E_DST_RD) exec_dst_wr <= 1'b1;
601 else if (e_state==`E_DST_WR) exec_dst_wr <= 1'b0;
604 always @(posedge mclk or posedge puc)
605 if (puc) exec_src_wr <= 1'b0;
606 else if (inst_type[`INST_SO] & (e_state==`E_SRC_RD)) exec_src_wr <= 1'b1;
607 else if ((e_state==`E_SRC_WR) || (e_state==`E_DST_WR)) exec_src_wr <= 1'b0;
610 always @(posedge mclk or posedge puc)
611 if (puc) exec_dext_rdy <= 1'b0;
612 else if (e_state==`E_DST_RD) exec_dext_rdy <= 1'b0;
613 else if (inst_dext_rdy) exec_dext_rdy <= 1'b1;
615 // Execution first state
616 //wire [3:0] e_first_state = dbg_halt_cmd ? `E_IDLE :
617 wire [3:0] e_first_state = ~dbg_halt_st & inst_so_nxt[`IRQ] ? `E_IRQ_0 :
618 dbg_halt_cmd | (i_state==I_IDLE) ? `E_IDLE :
620 src_acalc_pre ? `E_SRC_AD :
621 src_rd_pre ? `E_SRC_RD :
622 dst_acalc_pre ? `E_DST_AD :
623 dst_rd_pre ? `E_DST_RD : `E_EXEC;
627 //--------------------------------
629 // States Transitions
630 always @(e_state or dst_acalc or dst_rd or inst_sext_rdy or
631 inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr or
632 e_first_state or exec_src_wr)
634 `E_IDLE : e_state_nxt = e_first_state;
635 `E_IRQ_0 : e_state_nxt = `E_IRQ_1;
636 `E_IRQ_1 : e_state_nxt = `E_IRQ_2;
637 `E_IRQ_2 : e_state_nxt = `E_IRQ_3;
638 `E_IRQ_3 : e_state_nxt = `E_IRQ_4;
639 `E_IRQ_4 : e_state_nxt = `E_EXEC;
641 `E_SRC_AD : e_state_nxt = inst_sext_rdy ? `E_SRC_RD : `E_SRC_AD;
643 `E_SRC_RD : e_state_nxt = dst_acalc ? `E_DST_AD :
644 dst_rd ? `E_DST_RD : `E_EXEC;
646 `E_DST_AD : e_state_nxt = (inst_dext_rdy |
647 exec_dext_rdy) ? `E_DST_RD : `E_DST_AD;
649 `E_DST_RD : e_state_nxt = `E_EXEC;
651 `E_EXEC : e_state_nxt = exec_dst_wr ? `E_DST_WR :
653 exec_src_wr ? `E_SRC_WR : e_first_state;
655 `E_JUMP : e_state_nxt = e_first_state;
656 `E_DST_WR : e_state_nxt = exec_jmp ? `E_JUMP : e_first_state;
657 `E_SRC_WR : e_state_nxt = e_first_state;
658 default : e_state_nxt = `E_IRQ_0;
662 always @(posedge mclk or posedge puc)
663 if (puc) e_state <= `E_IRQ_1;
664 else e_state <= e_state_nxt;
667 // Frontend State machine control signals
668 //----------------------------------------
670 wire exec_done = exec_jmp ? (e_state==`E_JUMP) :
671 exec_dst_wr ? (e_state==`E_DST_WR) :
672 exec_src_wr ? (e_state==`E_SRC_WR) : (e_state==`E_EXEC);
675 //=============================================================================
676 // 6) EXECUTION-UNIT STATE CONTROL
677 //=============================================================================
680 // 6.1) ALU CONTROL SIGNALS
681 //-------------------------------------
683 // 12'b000000000001: Enable ALU source inverter
684 // 12'b000000000010: Enable Incrementer
685 // 12'b000000000100: Enable Incrementer on carry bit
686 // 12'b000000001000: Select Adder
687 // 12'b000000010000: Select AND
688 // 12'b000000100000: Select OR
689 // 12'b000001000000: Select XOR
690 // 12'b000010000000: Select DADD
691 // 12'b000100000000: Update N, Z & C (C=~Z)
692 // 12'b001000000000: Update all status bits
693 // 12'b010000000000: Update status bit for XOR instruction
694 // 12'b100000000000: Don't write to destination
698 wire alu_src_inv = inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
699 inst_to_nxt[`CMP] | inst_to_nxt[`BIC] ;
701 wire alu_inc = inst_to_nxt[`SUB] | inst_to_nxt[`CMP];
703 wire alu_inc_c = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] |
706 wire alu_add = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
707 inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
708 inst_to_nxt[`CMP] | inst_type_nxt[`INST_JMP] |
712 wire alu_and = inst_to_nxt[`AND] | inst_to_nxt[`BIC] |
715 wire alu_or = inst_to_nxt[`BIS];
717 wire alu_xor = inst_to_nxt[`XOR];
719 wire alu_dadd = inst_to_nxt[`DADD];
721 wire alu_stat_7 = inst_to_nxt[`BIT] | inst_to_nxt[`AND] |
724 wire alu_stat_f = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
725 inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
726 inst_to_nxt[`CMP] | inst_to_nxt[`DADD] |
727 inst_to_nxt[`BIT] | inst_to_nxt[`XOR] |
729 inst_so_nxt[`RRC] | inst_so_nxt[`RRA] |
732 wire alu_shift = inst_so_nxt[`RRC] | inst_so_nxt[`RRA];
734 wire exec_no_wr = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
736 always @(posedge mclk or posedge puc)
737 if (puc) inst_alu <= 12'h000;
738 else if (decode) inst_alu <= {exec_no_wr,
752 endmodule // omsp_frontend
754 `include "openMSP430_undefines.v"