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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [actel_m1a3pl_dev_kit/] [rtl/] [verilog/] [openmsp430/] [omsp_frontend.v] - Diff between revs 111 and 136

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 111 Rev 136
Line 1... Line 1...
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Copyright (C) 2001 Authors
// Copyright (C) 2009 , Olivier Girard
//
//
// This source file may be used and distributed without restriction provided
// Redistribution and use in source and binary forms, with or without
// that this copyright statement is not removed from the file and that any
// modification, are permitted provided that the following conditions
// derivative work contains the original copyright notice and the associated
// are met:
// disclaimer.
//     * Redistributions of source code must retain the above copyright
//
//       notice, this list of conditions and the following disclaimer.
// This source file is free software; you can redistribute it and/or modify
//     * Redistributions in binary form must reproduce the above copyright
// it under the terms of the GNU Lesser General Public License as published
//       notice, this list of conditions and the following disclaimer in the
// by the Free Software Foundation; either version 2.1 of the License, or
//       documentation and/or other materials provided with the distribution.
// (at your option) any later version.
//     * Neither the name of the authors nor the names of its contributors
//
//       may be used to endorse or promote products derived from this software
// This source is distributed in the hope that it will be useful, but WITHOUT
//       without specific prior written permission.
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// License for more details.
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// You should have received a copy of the GNU Lesser General Public License
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// along with this source; if not, write to the Free Software Foundation,
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
// THE POSSIBILITY OF SUCH DAMAGE
//
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//
//
// *File Name: omsp_frontend.v
// *File Name: omsp_frontend.v
// 
// 
Line 61... Line 66...
    inst_src,                      // Decoded Inst: source (one hot)
    inst_src,                      // Decoded Inst: source (one hot)
    inst_type,                     // Decoded Instruction type
    inst_type,                     // Decoded Instruction type
    irq_acc,                       // Interrupt request accepted (one-hot signal)
    irq_acc,                       // Interrupt request accepted (one-hot signal)
    mab,                           // Frontend Memory address bus
    mab,                           // Frontend Memory address bus
    mb_en,                         // Frontend Memory bus enable
    mb_en,                         // Frontend Memory bus enable
 
    mclk_enable,                   // Main System Clock enable
 
    mclk_wkup,                     // Main System Clock wake-up (asynchronous)
    nmi_acc,                       // Non-Maskable interrupt request accepted
    nmi_acc,                       // Non-Maskable interrupt request accepted
    pc,                            // Program counter
    pc,                            // Program counter
    pc_nxt,                        // Next PC value (for CALL & IRQ)
    pc_nxt,                        // Next PC value (for CALL & IRQ)
 
 
// INPUTs
// INPUTs
Line 75... Line 82...
    fe_pmem_wait,                  // Frontend wait for Instruction fetch
    fe_pmem_wait,                  // Frontend wait for Instruction fetch
    gie,                           // General interrupt enable
    gie,                           // General interrupt enable
    irq,                           // Maskable interrupts
    irq,                           // Maskable interrupts
    mclk,                          // Main system clock
    mclk,                          // Main system clock
    mdb_in,                        // Frontend Memory data bus input
    mdb_in,                        // Frontend Memory data bus input
    nmi_evt,                       // Non-maskable interrupt event
    nmi_pnd,                       // Non-maskable interrupt pending
 
    nmi_wkup,                      // NMI Wakeup
    pc_sw,                         // Program counter software value
    pc_sw,                         // Program counter software value
    pc_sw_wr,                      // Program counter software write
    pc_sw_wr,                      // Program counter software write
    puc_rst,                       // Main system reset
    puc_rst,                       // Main system reset
    wdt_irq                        // Watchdog-timer interrupt
    scan_enable,                   // Scan enable (active during scan shifting)
 
    wdt_irq,                       // Watchdog-timer interrupt
 
    wdt_wkup,                      // Watchdog Wakeup
 
    wkup                           // System Wake-up (asynchronous)
);
);
 
 
// OUTPUTs
// OUTPUTs
//=========
//=========
output              dbg_halt_st;   // Halt/Run status from CPU
output              dbg_halt_st;   // Halt/Run status from CPU
Line 104... Line 115...
output       [15:0] inst_src;      // Decoded Inst: source (one hot)
output       [15:0] inst_src;      // Decoded Inst: source (one hot)
output        [2:0] inst_type;     // Decoded Instruction type
output        [2:0] inst_type;     // Decoded Instruction type
output       [13:0] irq_acc;       // Interrupt request accepted (one-hot signal)
output       [13:0] irq_acc;       // Interrupt request accepted (one-hot signal)
output       [15:0] mab;           // Frontend Memory address bus
output       [15:0] mab;           // Frontend Memory address bus
output              mb_en;         // Frontend Memory bus enable
output              mb_en;         // Frontend Memory bus enable
 
output              mclk_enable;   // Main System Clock enable
 
output              mclk_wkup;     // Main System Clock wake-up (asynchronous)
output              nmi_acc;       // Non-Maskable interrupt request accepted
output              nmi_acc;       // Non-Maskable interrupt request accepted
output       [15:0] pc;            // Program counter
output       [15:0] pc;            // Program counter
output       [15:0] pc_nxt;        // Next PC value (for CALL & IRQ)
output       [15:0] pc_nxt;        // Next PC value (for CALL & IRQ)
 
 
// INPUTs
// INPUTs
Line 119... Line 132...
input               fe_pmem_wait;  // Frontend wait for Instruction fetch
input               fe_pmem_wait;  // Frontend wait for Instruction fetch
input               gie;           // General interrupt enable
input               gie;           // General interrupt enable
input        [13:0] irq;           // Maskable interrupts
input        [13:0] irq;           // Maskable interrupts
input               mclk;          // Main system clock
input               mclk;          // Main system clock
input        [15:0] mdb_in;        // Frontend Memory data bus input
input        [15:0] mdb_in;        // Frontend Memory data bus input
input               nmi_evt;       // Non-maskable interrupt event
input               nmi_pnd;       // Non-maskable interrupt pending
 
input               nmi_wkup;      // NMI Wakeup
input        [15:0] pc_sw;         // Program counter software value
input        [15:0] pc_sw;         // Program counter software value
input               pc_sw_wr;      // Program counter software write
input               pc_sw_wr;      // Program counter software write
input               puc_rst;       // Main system reset
input               puc_rst;       // Main system reset
 
input               scan_enable;   // Scan enable (active during scan shifting)
input               wdt_irq;       // Watchdog-timer interrupt
input               wdt_irq;       // Watchdog-timer interrupt
 
input               wdt_wkup;      // Watchdog Wakeup
 
input               wkup;          // System Wake-up (asynchronous)
 
 
 
 
//=============================================================================
//=============================================================================
// 1)  UTILITY FUNCTIONS
// 1)  UTILITY FUNCTIONS
//=============================================================================
//=============================================================================
Line 150... Line 167...
   end
   end
endfunction
endfunction
 
 
 
 
//=============================================================================
//=============================================================================
// 2)  Parameter definitions
// 2)  PARAMETER DEFINITIONS
//=============================================================================
//=============================================================================
 
 
//
//
// 2.1) Instruction State machine definitons
// 2.1) Instruction State machine definitons
//-------------------------------------------
//-------------------------------------------
Line 217... Line 234...
                          (cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE      :
                          (cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE      :
                            cpu_halt_cmd & (e_state==E_IDLE)  ? I_IDLE      :
                            cpu_halt_cmd & (e_state==E_IDLE)  ? I_IDLE      :
                                  pc_sw_wr                    ? I_DEC       :
                                  pc_sw_wr                    ? I_DEC       :
                             ~exec_done & ~(e_state==E_IDLE)  ? I_DEC       :        // Wait in decode state
                             ~exec_done & ~(e_state==E_IDLE)  ? I_DEC       :        // Wait in decode state
                                  (inst_sz_nxt!=2'b00)        ? I_EXT1      : I_DEC; // until execution is completed
                                  (inst_sz_nxt!=2'b00)        ? I_EXT1      : I_DEC; // until execution is completed
      I_EXT1     : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
      I_EXT1     : i_state_nxt =  pc_sw_wr                    ? I_DEC       :
                                  pc_sw_wr                    ? I_DEC       :
 
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
      I_EXT2     : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH : I_DEC;
      I_EXT2     : i_state_nxt =  I_DEC;
 
    // pragma coverage off
      default    : i_state_nxt =  I_IRQ_FETCH;
      default    : i_state_nxt =  I_IRQ_FETCH;
 
    // pragma coverage on
    endcase
    endcase
 
 
// State machine
// State machine
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst) i_state  <= I_IRQ_FETCH;
  if (puc_rst) i_state  <= I_IRQ_FETCH;
Line 242... Line 260...
  if (puc_rst)  dbg_halt_st <= 1'b0;
  if (puc_rst)  dbg_halt_st <= 1'b0;
  else          dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
  else          dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
 
 
 
 
//=============================================================================
//=============================================================================
// 4)  INTERRUPT HANDLING
// 4)  INTERRUPT HANDLING & SYSTEM WAKEUP
//=============================================================================
//=============================================================================
 
 
// Detect nmi interrupt
//
reg         inst_nmi;
// 4.1) INTERRUPT HANDLING
always @(posedge mclk or posedge puc_rst)
//-----------------------------------------
  if (puc_rst)                  inst_nmi <= 1'b0;
 
  else if (nmi_evt)             inst_nmi <= 1'b1;
 
  else if (i_state==I_IRQ_DONE) inst_nmi <= 1'b0;
 
 
 
 
 
// Detect reset interrupt
// Detect reset interrupt
reg         inst_irq_rst;
reg         inst_irq_rst;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst)                  inst_irq_rst <= 1'b1;
  if (puc_rst)                  inst_irq_rst <= 1'b1;
  else if (exec_done)           inst_irq_rst <= 1'b0;
  else if (exec_done)           inst_irq_rst <= 1'b0;
 
 
//  Detect other interrupts
//  Detect other interrupts
assign  irq_detect = (inst_nmi | ((|irq | wdt_irq) & gie)) & ~cpu_halt_cmd & ~dbg_halt_st & (exec_done | (i_state==I_IDLE));
assign  irq_detect = (nmi_pnd | ((|irq | wdt_irq) & gie)) & ~cpu_halt_cmd & ~dbg_halt_st & (exec_done | (i_state==I_IDLE));
 
 
 
`ifdef CLOCK_GATING
 
wire       mclk_irq_num;
 
omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
 
                                    .clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
 
`else
 
wire       mclk_irq_num = mclk;
 
`endif
 
 
// Select interrupt vector
// Select interrupt vector
reg  [3:0] irq_num;
reg  [3:0] irq_num;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_irq_num or posedge puc_rst)
  if (puc_rst)         irq_num <= 4'hf;
  if (puc_rst)         irq_num <= 4'hf;
  else if (irq_detect) irq_num <= inst_nmi           ?  4'he :
`ifdef CLOCK_GATING
 
  else                 irq_num <= nmi_pnd            ?  4'he :
 
`else
 
  else if (irq_detect) irq_num <= nmi_pnd            ?  4'he :
 
`endif
                                  irq[13]            ?  4'hd :
                                  irq[13]            ?  4'hd :
                                  irq[12]            ?  4'hc :
                                  irq[12]            ?  4'hc :
                                  irq[11]            ?  4'hb :
                                  irq[11]            ?  4'hb :
                                 (irq[10] | wdt_irq) ?  4'ha :
                                 (irq[10] | wdt_irq) ?  4'ha :
                                  irq[9]             ?  4'h9 :
                                  irq[9]             ?  4'h9 :
Line 289... Line 315...
// Interrupt request accepted
// Interrupt request accepted
wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}};
wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}};
wire [13:0] irq_acc     = irq_acc_all[13:0];
wire [13:0] irq_acc     = irq_acc_all[13:0];
wire        nmi_acc     = irq_acc_all[14];
wire        nmi_acc     = irq_acc_all[14];
 
 
 
//
 
// 4.2) SYSTEM WAKEUP
 
//-----------------------------------------
 
`ifdef CPUOFF_EN
 
 
 
// Generate the main system clock enable signal
 
                                                    // Keep the clock running if:
 
wire mclk_enable = inst_irq_rst ? cpu_en_s :        //      - the RESET interrupt is currently executing
 
                                                    //        and if the CPU is enabled
 
                                                    // otherwise if:
 
                  ~((cpuoff | ~cpu_en_s) &          //      - the CPUOFF flag, cpu_en command, instruction
 
                   (i_state==I_IDLE) &              //        and execution state machines are all two
 
                   (e_state==E_IDLE));              //        not idle.
 
 
 
 
 
// Wakeup condition from maskable interrupts
 
wire mirq_wkup;
 
omsp_and_gate and_mirq_wkup (.y(mirq_wkup), .a(wkup | wdt_wkup), .b(gie));
 
 
 
// Combined asynchronous wakeup detection from nmi & irq (masked if the cpu is disabled)
 
omsp_and_gate and_mclk_wkup (.y(mclk_wkup), .a(nmi_wkup | mirq_wkup), .b(cpu_en_s));
 
 
 
`else
 
 
 
// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
 
assign  mclk_wkup   = 1'b1;
 
assign  mclk_enable = 1'b1;
 
`endif
 
 
//=============================================================================
//=============================================================================
// 5)  FETCH INSTRUCTION
// 5)  FETCH INSTRUCTION
//=============================================================================
//=============================================================================
 
 
Line 307... Line 361...
wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
wire [15:0] pc_nxt  = pc_sw_wr               ? pc_sw    :
wire [15:0] pc_nxt  = pc_sw_wr               ? pc_sw    :
                      (i_state==I_IRQ_FETCH) ? irq_addr :
                      (i_state==I_IRQ_FETCH) ? irq_addr :
                      (i_state==I_IRQ_DONE)  ? mdb_in   :  pc_incr;
                      (i_state==I_IRQ_DONE)  ? mdb_in   :  pc_incr;
 
 
always @(posedge mclk or posedge puc_rst)
`ifdef CLOCK_GATING
 
wire       pc_en  = fetch                  |
 
                    pc_sw_wr               |
 
                    (i_state==I_IRQ_FETCH) |
 
                    (i_state==I_IRQ_DONE);
 
wire       mclk_pc;
 
omsp_clock_gate clock_gate_pc (.gclk(mclk_pc),
 
                               .clk (mclk), .enable(pc_en), .scan_enable(scan_enable));
 
`else
 
wire       mclk_pc = mclk;
 
`endif
 
 
 
always @(posedge mclk_pc or posedge puc_rst)
  if (puc_rst)  pc <= 16'h0000;
  if (puc_rst)  pc <= 16'h0000;
  else          pc <= pc_nxt;
  else          pc <= pc_nxt;
 
 
// Check if ROM has been busy in order to retry ROM access
// Check if ROM has been busy in order to retry ROM access
reg pmem_busy;
reg pmem_busy;
Line 332... Line 398...
wire [15:0] ir  = mdb_in;
wire [15:0] ir  = mdb_in;
 
 
// Detect if source extension word is required
// Detect if source extension word is required
wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
 
 
// Detect if destination extension word is required
 
wire is_dext = (inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS]);
 
 
 
// For the Symbolic addressing mode, add -2 to the extension word in order
// For the Symbolic addressing mode, add -2 to the extension word in order
// to make up for the PC address
// to make up for the PC address
wire [15:0] ext_incr = ((i_state==I_EXT1)     &  inst_as[`SYMB]) |
wire [15:0] ext_incr = ((i_state==I_EXT1)     &  inst_as[`SYMB]) |
                       ((i_state==I_EXT2)     &  inst_ad[`SYMB]) |
                       ((i_state==I_EXT2)     &  inst_ad[`SYMB]) |
                       ((i_state==I_EXT1)     & ~inst_as[`SYMB] &
                       ((i_state==I_EXT1)     & ~inst_as[`SYMB] &
Line 346... Line 409...
 
 
wire [15:0] ext_nxt  = ir + ext_incr;
wire [15:0] ext_nxt  = ir + ext_incr;
 
 
// Store source extension word
// Store source extension word
reg [15:0] inst_sext;
reg [15:0] inst_sext;
always @(posedge mclk or posedge puc_rst)
 
 
`ifdef CLOCK_GATING
 
wire       inst_sext_en  = (decode & is_const)                 |
 
                           (decode & inst_type_nxt[`INST_JMP]) |
 
                           ((i_state==I_EXT1) & is_sext);
 
wire       mclk_inst_sext;
 
omsp_clock_gate clock_gate_inst_sext (.gclk(mclk_inst_sext),
 
                                      .clk (mclk), .enable(inst_sext_en), .scan_enable(scan_enable));
 
`else
 
wire       mclk_inst_sext = mclk;
 
`endif
 
 
 
always @(posedge mclk_inst_sext or posedge puc_rst)
  if (puc_rst)                                 inst_sext <= 16'h0000;
  if (puc_rst)                                 inst_sext <= 16'h0000;
  else if (decode & is_const)                  inst_sext <= sconst_nxt;
  else if (decode & is_const)                  inst_sext <= sconst_nxt;
  else if (decode & inst_type_nxt[`INST_JMP])  inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
  else if (decode & inst_type_nxt[`INST_JMP])  inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
 
`ifdef CLOCK_GATING
 
  else                                         inst_sext <= ext_nxt;
 
`else
  else if ((i_state==I_EXT1) & is_sext)        inst_sext <= ext_nxt;
  else if ((i_state==I_EXT1) & is_sext)        inst_sext <= ext_nxt;
 
`endif
 
 
// Source extension word is ready
// Source extension word is ready
wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
 
 
 
 
// Store destination extension word
// Store destination extension word
reg [15:0] inst_dext;
reg [15:0] inst_dext;
always @(posedge mclk or posedge puc_rst)
 
 
`ifdef CLOCK_GATING
 
wire       inst_dext_en  = ((i_state==I_EXT1) & ~is_sext) |
 
                            (i_state==I_EXT2);
 
wire       mclk_inst_dext;
 
omsp_clock_gate clock_gate_inst_dext (.gclk(mclk_inst_dext),
 
                                      .clk (mclk), .enable(inst_dext_en), .scan_enable(scan_enable));
 
`else
 
wire       mclk_inst_dext = mclk;
 
`endif
 
 
 
always @(posedge mclk_inst_dext or posedge puc_rst)
  if (puc_rst)                           inst_dext <= 16'h0000;
  if (puc_rst)                           inst_dext <= 16'h0000;
  else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
  else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
 
`ifdef CLOCK_GATING
 
  else                                   inst_dext <= ext_nxt;
 
`else
  else if  (i_state==I_EXT2)             inst_dext <= ext_nxt;
  else if  (i_state==I_EXT2)             inst_dext <= ext_nxt;
 
`endif
 
 
// Destination extension word is ready
// Destination extension word is ready
wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
 
 
 
 
//=============================================================================
//=============================================================================
// 6)  DECODE INSTRUCTION
// 6)  DECODE INSTRUCTION
//=============================================================================
//=============================================================================
 
 
 
`ifdef CLOCK_GATING
 
wire       mclk_decode;
 
omsp_clock_gate clock_gate_decode (.gclk(mclk_decode),
 
                                   .clk (mclk), .enable(decode), .scan_enable(scan_enable));
 
`else
 
wire       mclk_decode = mclk;
 
`endif
 
 
//
//
// 6.1) OPCODE: INSTRUCTION TYPE
// 6.1) OPCODE: INSTRUCTION TYPE
//----------------------------------------
//----------------------------------------
// Instructions type is encoded in a one hot fashion as following:
// Instructions type is encoded in a one hot fashion as following:
//
//
Line 385... Line 487...
reg  [2:0] inst_type;
reg  [2:0] inst_type;
assign     inst_type_nxt = {(ir[15:14]!=2'b00),
assign     inst_type_nxt = {(ir[15:14]!=2'b00),
                            (ir[15:13]==3'b001),
                            (ir[15:13]==3'b001),
                            (ir[15:13]==3'b000)} & {3{~irq_detect}};
                            (ir[15:13]==3'b000)} & {3{~irq_detect}};
 
 
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)      inst_type <= 3'b000;
  if (puc_rst)      inst_type <= 3'b000;
 
`ifdef CLOCK_GATING
 
  else              inst_type <= inst_type_nxt;
 
`else
  else if (decode)  inst_type <= inst_type_nxt;
  else if (decode)  inst_type <= inst_type_nxt;
 
`endif
 
 
//
//
// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC
// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC
//----------------------------------------
//----------------------------------------
// Instructions are encoded in a one hot fashion as following:
// Instructions are encoded in a one hot fashion as following:
Line 406... Line 512...
// 8'b10000000: IRQ
// 8'b10000000: IRQ
 
 
reg   [7:0] inst_so;
reg   [7:0] inst_so;
wire  [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
wire  [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
 
 
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_so <= 8'h00;
  if (puc_rst)     inst_so <= 8'h00;
 
`ifdef CLOCK_GATING
 
  else             inst_so <= inst_so_nxt;
 
`else
  else if (decode) inst_so <= inst_so_nxt;
  else if (decode) inst_so <= inst_so_nxt;
 
`endif
 
 
//
//
// 6.3) OPCODE: CONDITIONAL JUMP
// 6.3) OPCODE: CONDITIONAL JUMP
//--------------------------------
//--------------------------------
// Instructions are encoded in a one hot fashion as following:
// Instructions are encoded in a one hot fashion as following:
Line 425... Line 535...
// 8'b00100000: JGE
// 8'b00100000: JGE
// 8'b01000000: JL
// 8'b01000000: JL
// 8'b10000000: JMP
// 8'b10000000: JMP
 
 
reg   [2:0] inst_jmp_bin;
reg   [2:0] inst_jmp_bin;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_jmp_bin <= 3'h0;
  if (puc_rst)     inst_jmp_bin <= 3'h0;
 
`ifdef CLOCK_GATING
 
  else             inst_jmp_bin <= ir[12:10];
 
`else
  else if (decode) inst_jmp_bin <= ir[12:10];
  else if (decode) inst_jmp_bin <= ir[12:10];
 
`endif
 
 
wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
 
 
 
 
//
//
Line 454... Line 568...
 
 
wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
wire [11:0] inst_to_nxt  = inst_to_1hot[15:4];
wire [11:0] inst_to_nxt  = inst_to_1hot[15:4];
 
 
reg         inst_mov;
reg         inst_mov;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_mov <= 1'b0;
  if (puc_rst)     inst_mov <= 1'b0;
 
`ifdef CLOCK_GATING
 
  else             inst_mov <= inst_to_nxt[`MOV];
 
`else
  else if (decode) inst_mov <= inst_to_nxt[`MOV];
  else if (decode) inst_mov <= inst_to_nxt[`MOV];
 
`endif
 
 
 
 
//
//
// 6.5) SOURCE AND DESTINATION REGISTERS
// 6.5) SOURCE AND DESTINATION REGISTERS
//---------------------------------------
//---------------------------------------
 
 
// Destination register
// Destination register
reg [3:0] inst_dest_bin;
reg [3:0] inst_dest_bin;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_dest_bin <= 4'h0;
  if (puc_rst)     inst_dest_bin <= 4'h0;
 
`ifdef CLOCK_GATING
 
  else             inst_dest_bin <= ir[3:0];
 
`else
  else if (decode) inst_dest_bin <= ir[3:0];
  else if (decode) inst_dest_bin <= ir[3:0];
 
`endif
 
 
wire  [15:0] inst_dest = dbg_halt_st          ? one_hot16(dbg_reg_sel) :
wire  [15:0] inst_dest = dbg_halt_st          ? one_hot16(dbg_reg_sel) :
                         inst_type[`INST_JMP] ? 16'h0001               :
                         inst_type[`INST_JMP] ? 16'h0001               :
                         inst_so[`IRQ]  |
                         inst_so[`IRQ]  |
                         inst_so[`PUSH] |
                         inst_so[`PUSH] |
Line 479... Line 601...
                                                one_hot16(inst_dest_bin);
                                                one_hot16(inst_dest_bin);
 
 
 
 
// Source register
// Source register
reg [3:0] inst_src_bin;
reg [3:0] inst_src_bin;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_src_bin <= 4'h0;
  if (puc_rst)     inst_src_bin <= 4'h0;
 
`ifdef CLOCK_GATING
 
  else             inst_src_bin <= ir[11:8];
 
`else
  else if (decode) inst_src_bin <= ir[11:8];
  else if (decode) inst_src_bin <= ir[11:8];
 
`endif
 
 
wire  [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin)  :
wire  [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin)  :
                        inst_so[`RETI]      ? 16'h0002                 :
                        inst_so[`RETI]      ? 16'h0002                 :
                        inst_so[`IRQ]       ? 16'h0001                 :
                        inst_so[`IRQ]       ? 16'h0001                 :
                        inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000;
                        inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000;
Line 548... Line 674...
       endcase
       endcase
  end
  end
assign    is_const = |inst_as_nxt[12:7];
assign    is_const = |inst_as_nxt[12:7];
 
 
reg [7:0] inst_as;
reg [7:0] inst_as;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_as <= 8'h00;
  if (puc_rst)     inst_as <= 8'h00;
 
`ifdef CLOCK_GATING
 
  else             inst_as <= {is_const, inst_as_nxt[6:0]};
 
`else
  else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
  else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
 
`endif
 
 
 
 
// 13'b0000010000000: Constant 4.
// 13'b0000010000000: Constant 4.
// 13'b0000100000000: Constant 8.
// 13'b0000100000000: Constant 8.
// 13'b0001000000000: Constant 0.
// 13'b0001000000000: Constant 0.
Line 607... Line 737...
         default: inst_ad_nxt =  8'b00000001;
         default: inst_ad_nxt =  8'b00000001;
       endcase
       endcase
  end
  end
 
 
reg [7:0] inst_ad;
reg [7:0] inst_ad;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_ad <= 8'h00;
  if (puc_rst)     inst_ad <= 8'h00;
 
`ifdef CLOCK_GATING
 
  else             inst_ad <= inst_ad_nxt;
 
`else
  else if (decode) inst_ad <= inst_ad_nxt;
  else if (decode) inst_ad <= inst_ad_nxt;
 
`endif
 
 
 
 
//
//
// 6.8) REMAINING INSTRUCTION DECODING
// 6.8) REMAINING INSTRUCTION DECODING
//-------------------------------------
//-------------------------------------
Line 625... Line 759...
  else if (decode) inst_bw     <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~cpu_halt_cmd;
  else if (decode) inst_bw     <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~cpu_halt_cmd;
 
 
// Extended instruction size
// Extended instruction size
assign    inst_sz_nxt = {1'b0,  (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
assign    inst_sz_nxt = {1'b0,  (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
                        {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
                        {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
  if (puc_rst)     inst_sz     <= 2'b00;
  if (puc_rst)     inst_sz     <= 2'b00;
 
`ifdef CLOCK_GATING
 
  else             inst_sz     <= inst_sz_nxt;
 
`else
  else if (decode) inst_sz     <= inst_sz_nxt;
  else if (decode) inst_sz     <= inst_sz_nxt;
 
`endif
 
 
 
 
//=============================================================================
//=============================================================================
// 7)  EXECUTION-UNIT STATE MACHINE
// 7)  EXECUTION-UNIT STATE MACHINE
//=============================================================================
//=============================================================================
Line 716... Line 854...
                                exec_src_wr       ? E_SRC_WR : e_first_state;
                                exec_src_wr       ? E_SRC_WR : e_first_state;
 
 
      E_JUMP   : e_state_nxt =  e_first_state;
      E_JUMP   : e_state_nxt =  e_first_state;
      E_DST_WR : e_state_nxt =  exec_jmp          ? E_JUMP   : e_first_state;
      E_DST_WR : e_state_nxt =  exec_jmp          ? E_JUMP   : e_first_state;
      E_SRC_WR : e_state_nxt =  e_first_state;
      E_SRC_WR : e_state_nxt =  e_first_state;
 
    // pragma coverage off
      default  : e_state_nxt =  E_IRQ_0;
      default  : e_state_nxt =  E_IRQ_0;
 
    // pragma coverage on
    endcase
    endcase
 
 
// State machine
// State machine
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst) e_state  <= E_IRQ_1;
  if (puc_rst) e_state  <= E_IRQ_1;
Line 794... Line 934...
 
 
wire        alu_shift     = inst_so_nxt[`RRC]  | inst_so_nxt[`RRA];
wire        alu_shift     = inst_so_nxt[`RRC]  | inst_so_nxt[`RRA];
 
 
wire        exec_no_wr    = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
wire        exec_no_wr    = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
 
 
always @(posedge mclk or posedge puc_rst)
wire [11:0] inst_alu_nxt  = {exec_no_wr,
  if (puc_rst)     inst_alu <= 12'h000;
 
  else if (decode) inst_alu <= {exec_no_wr,
 
                                alu_shift,
                                alu_shift,
                                alu_stat_f,
                                alu_stat_f,
                                alu_stat_7,
                                alu_stat_7,
                                alu_dadd,
                                alu_dadd,
                                alu_xor,
                                alu_xor,
Line 809... Line 947...
                                alu_add,
                                alu_add,
                                alu_inc_c,
                                alu_inc_c,
                                alu_inc,
                                alu_inc,
                                alu_src_inv};
                                alu_src_inv};
 
 
 
always @(posedge mclk_decode or posedge puc_rst)
 
  if (puc_rst)     inst_alu <= 12'h000;
 
`ifdef CLOCK_GATING
 
  else             inst_alu <= inst_alu_nxt;
 
`else
 
  else if (decode) inst_alu <= inst_alu_nxt;
 
`endif
 
 
 
 
endmodule // omsp_frontend
endmodule // omsp_frontend
 
 
`ifdef OMSP_NO_INCLUDE
`ifdef OMSP_NO_INCLUDE
`else
`else

powered by: WebSVN 2.1.0

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