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 193 and 202

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

Rev 193 Rev 202
Line 34... Line 34...
//
//
// *Author(s):
// *Author(s):
//              - Olivier Girard,    olgirard@gmail.com
//              - Olivier Girard,    olgirard@gmail.com
//
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// $Rev: 134 $
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`ifdef OMSP_NO_INCLUDE
`else
`else
`include "openMSP430_defines.v"
`include "openMSP430_defines.v"
`endif
`endif
 
 
module  omsp_frontend (
module  omsp_frontend (
 
 
// OUTPUTs
// OUTPUTs
    dbg_halt_st,                    // Halt/Run status from CPU
    cpu_halt_st,                       // Halt/Run status from CPU
    decode_noirq,                   // Frontend decode instruction
    decode_noirq,                   // Frontend decode instruction
    e_state,                        // Execution state
    e_state,                        // Execution state
    exec_done,                      // Execution completed
    exec_done,                      // Execution completed
    inst_ad,                        // Decoded Inst: destination addressing mode
    inst_ad,                        // Decoded Inst: destination addressing mode
    inst_as,                        // Decoded Inst: source addressing mode
    inst_as,                        // Decoded Inst: source addressing mode
Line 66... 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_dma_enable,                   // DMA Sub-System Clock enable
 
    mclk_dma_wkup,                     // DMA Sub-System Clock wake-up (asynchronous)
    mclk_enable,                    // Main System Clock enable
    mclk_enable,                    // Main System Clock enable
    mclk_wkup,                      // Main System Clock wake-up (asynchronous)
    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
    cpu_en_s,                       // Enable CPU code execution (synchronous)
    cpu_en_s,                       // Enable CPU code execution (synchronous)
 
    cpu_halt_cmd,                      // Halt CPU command
    cpuoff,                         // Turns off the CPU
    cpuoff,                         // Turns off the CPU
    dbg_halt_cmd,                   // Halt CPU command
 
    dbg_reg_sel,                    // Debug selected register for rd/wr access
    dbg_reg_sel,                    // Debug selected register for rd/wr access
 
    dma_en,                            // Direct Memory Access enable (high active)
 
    dma_wkup,                          // DMA Sub-System Wake-up (asynchronous and non-glitchy)
    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
Line 95... Line 99...
    wkup                            // System Wake-up (asynchronous)
    wkup                            // System Wake-up (asynchronous)
);
);
 
 
// OUTPUTs
// OUTPUTs
//=========
//=========
output               dbg_halt_st;   // Halt/Run status from CPU
output               cpu_halt_st;      // Halt/Run status from CPU
output               decode_noirq;  // Frontend decode instruction
output               decode_noirq;  // Frontend decode instruction
output         [3:0] e_state;       // Execution state
output         [3:0] e_state;       // Execution state
output               exec_done;     // Execution completed
output               exec_done;     // Execution completed
output         [7:0] inst_ad;       // Decoded Inst: destination addressing mode
output         [7:0] inst_ad;       // Decoded Inst: destination addressing mode
output         [7:0] inst_as;       // Decoded Inst: source addressing mode
output         [7:0] inst_as;       // Decoded Inst: source addressing mode
Line 115... Line 119...
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 [`IRQ_NR-3:0] irq_acc;       // Interrupt request accepted (one-hot signal)
output [`IRQ_NR-3: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_dma_enable;  // DMA Sub-System Clock enable
 
output               mclk_dma_wkup;    // DMA Sub-System Clock wake-up (asynchronous)
output               mclk_enable;   // Main System Clock enable
output               mclk_enable;   // Main System Clock enable
output               mclk_wkup;     // Main System Clock wake-up (asynchronous)
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
//=========
//=========
input                cpu_en_s;      // Enable CPU code execution (synchronous)
input                cpu_en_s;      // Enable CPU code execution (synchronous)
 
input                cpu_halt_cmd;     // Halt CPU command
input                cpuoff;        // Turns off the CPU
input                cpuoff;        // Turns off the CPU
input                dbg_halt_cmd;  // Halt CPU command
 
input          [3:0] dbg_reg_sel;   // Debug selected register for rd/wr access
input          [3:0] dbg_reg_sel;   // Debug selected register for rd/wr access
 
input                dma_en;           // Direct Memory Access enable (high active)
 
input                dma_wkup;         // DMA Sub-System Wake-up (asynchronous and non-glitchy)
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  [`IRQ_NR-3:0] irq;           // Maskable interrupts
input  [`IRQ_NR-3: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
Line 237... Line 245...
wire [2:0] inst_type_nxt;
wire [2:0] inst_type_nxt;
wire       is_const;
wire       is_const;
reg [15:0] sconst_nxt;
reg [15:0] sconst_nxt;
reg  [3:0] e_state_nxt;
reg  [3:0] e_state_nxt;
 
 
// CPU on/off through the debug interface or cpu_en port
// CPU on/off through an external interface (debug or mstr) or cpu_en port
wire   cpu_halt_cmd = dbg_halt_cmd | ~cpu_en_s;
wire   cpu_halt_req = cpu_halt_cmd | ~cpu_en_s;
 
 
// States Transitions
// States Transitions
always @(i_state    or inst_sz  or inst_sz_nxt  or pc_sw_wr or exec_done or
always @(i_state    or inst_sz  or inst_sz_nxt  or pc_sw_wr or exec_done or
         irq_detect or cpuoff   or cpu_halt_cmd or e_state)
         irq_detect or cpuoff   or cpu_halt_req or e_state)
    case(i_state)
    case(i_state)
      I_IDLE     : i_state_nxt = (irq_detect & ~cpu_halt_cmd) ? I_IRQ_FETCH :
      I_IDLE     : i_state_nxt = (irq_detect & ~cpu_halt_req) ? I_IRQ_FETCH :
                                 (~cpuoff    & ~cpu_halt_cmd) ? I_DEC       : I_IDLE;
                                 (~cpuoff    & ~cpu_halt_req) ? I_DEC       : I_IDLE;
      I_IRQ_FETCH: i_state_nxt =  I_IRQ_DONE;
      I_IRQ_FETCH: i_state_nxt =  I_IRQ_DONE;
      I_IRQ_DONE : i_state_nxt =  I_DEC;
      I_IRQ_DONE : i_state_nxt =  I_DEC;
      I_DEC      : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
      I_DEC      : i_state_nxt =  irq_detect                  ? I_IRQ_FETCH :
                          (cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE      :
                          (cpuoff | cpu_halt_req) & exec_done ? I_IDLE      :
                            cpu_halt_cmd & (e_state==E_IDLE)  ? I_IDLE      :
                            cpu_halt_req & (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 =  pc_sw_wr                    ? I_DEC       :
      I_EXT1     : i_state_nxt =  pc_sw_wr                    ? I_DEC       :
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
                                  (inst_sz!=2'b01)            ? I_EXT2      : I_DEC;
Line 272... Line 280...
// Utility signals
// Utility signals
wire   decode_noirq =  ((i_state==I_DEC) &  (exec_done | (e_state==E_IDLE)));
wire   decode_noirq =  ((i_state==I_DEC) &  (exec_done | (e_state==E_IDLE)));
wire   decode       =  decode_noirq | irq_detect;
wire   decode       =  decode_noirq | irq_detect;
wire   fetch        = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
wire   fetch        = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
 
 
// Debug interface cpu status
// Halt/Run CPU status
reg    dbg_halt_st;
reg    cpu_halt_st;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst)  dbg_halt_st <= 1'b0;
  if (puc_rst)  cpu_halt_st <= 1'b0;
  else          dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
  else          cpu_halt_st <= cpu_halt_req & (i_state_nxt==I_IDLE);
 
 
 
 
//=============================================================================
//=============================================================================
// 4)  INTERRUPT HANDLING & SYSTEM WAKEUP
// 4)  INTERRUPT HANDLING & SYSTEM WAKEUP
//=============================================================================
//=============================================================================
Line 294... Line 302...
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 = (nmi_pnd | ((|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_req & ~cpu_halt_st & (exec_done | (i_state==I_IDLE));
 
 
`ifdef CLOCK_GATING
`ifdef CLOCK_GATING
wire       mclk_irq_num;
wire       mclk_irq_num;
omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
                                    .clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
                                    .clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
`else
`else
 
wire       UNUSED_scan_enable = scan_enable;
wire       mclk_irq_num = mclk;
wire       mclk_irq_num = mclk;
`endif
`endif
 
 
// Combine all IRQs
// Combine all IRQs
`ifdef  IRQ_16
`ifdef  IRQ_16
wire [62:0] irq_all     = {nmi_pnd, irq, 48'h0000_0000_0000} |
wire [62:0] irq_all     = {nmi_pnd, irq, 48'h0000_0000_0000} |
`else
`else
`ifdef  IRQ_32
`ifdef  IRQ_32
wire [62:0] irq_all     = {nmi_pnd, irq, 32'h0000}           |
wire [62:0] irq_all     = {nmi_pnd, irq, 32'h0000_0000}      |
`else
`else
`ifdef  IRQ_64
`ifdef  IRQ_64
wire [62:0] irq_all     = {nmi_pnd, irq}                     |
wire [62:0] irq_all     = {nmi_pnd, irq}                     |
`endif
`endif
`endif
`endif
Line 359... Line 368...
omsp_and_gate and_mirq_wkup (.y(mirq_wkup), .a(wkup | wdt_wkup), .b(gie));
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)
// 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));
omsp_and_gate and_mclk_wkup (.y(mclk_wkup), .a(nmi_wkup | mirq_wkup), .b(cpu_en_s));
 
 
 
// Wakeup condition from DMA interface
 
  `ifdef DMA_IF_EN
 
wire mclk_dma_enable = dma_en & cpu_en_s;
 
omsp_and_gate and_mclk_dma_wkup (.y(mclk_dma_wkup), .a(dma_wkup),             .b(cpu_en_s));
 
  `else
 
assign  mclk_dma_wkup   = 1'b0;
 
assign  mclk_dma_enable = 1'b0;
 
wire    UNUSED_dma_en   = dma_en;
 
wire    UNUSED_dma_wkup = dma_wkup;
 
  `endif
`else
`else
 
 
// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
 
assign  mclk_dma_wkup   = 1'b1;
 
assign  mclk_dma_enable = 1'b1;
assign  mclk_wkup   = 1'b1;
assign  mclk_wkup   = 1'b1;
assign  mclk_enable = 1'b1;
assign  mclk_enable = 1'b1;
 
wire    UNUSED_dma_en   = dma_en;
 
wire    UNUSED_wkup     = wkup;
 
wire    UNUSED_wdt_wkup = wdt_wkup;
 
wire    UNUSED_nmi_wkup = nmi_wkup;
 
wire    UNUSED_dma_wkup = dma_wkup;
`endif
`endif
 
 
//=============================================================================
//=============================================================================
// 5)  FETCH INSTRUCTION
// 5)  FETCH INSTRUCTION
//=============================================================================
//=============================================================================
Line 399... Line 425...
 
 
always @(posedge mclk_pc or posedge puc_rst)
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 Program-Memory has been busy in order to retry Program-Memory access
reg pmem_busy;
reg pmem_busy;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst)  pmem_busy <= 1'b0;
  if (puc_rst)  pmem_busy <= 1'b0;
  else          pmem_busy <= fe_pmem_wait;
  else          pmem_busy <= fe_pmem_wait;
 
 
// Memory interface
// Memory interface
wire [15:0] mab      = pc_nxt;
wire [15:0] mab      = pc_nxt;
wire        mb_en    = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~cpu_halt_cmd);
wire        mb_en    = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (cpu_halt_st & ~cpu_halt_req);
 
 
 
 
//
//
// 5.2) INSTRUCTION REGISTER
// 5.2) INSTRUCTION REGISTER
//--------------------------------
//--------------------------------
Line 613... Line 639...
  else             inst_dest_bin <= ir[3:0];
  else             inst_dest_bin <= ir[3:0];
`else
`else
  else if (decode) inst_dest_bin <= ir[3:0];
  else if (decode) inst_dest_bin <= ir[3:0];
`endif
`endif
 
 
wire  [15:0] inst_dest = dbg_halt_st          ? one_hot16(dbg_reg_sel) :
wire  [15:0] inst_dest = cpu_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] |
                         inst_so[`CALL]       ? 16'h0002               :
                         inst_so[`CALL]       ? 16'h0002               :
                                                one_hot16(inst_dest_bin);
                                                one_hot16(inst_dest_bin);
Line 776... Line 802...
 
 
// Operation size
// Operation size
reg       inst_bw;
reg       inst_bw;
always @(posedge mclk or posedge puc_rst)
always @(posedge mclk or posedge puc_rst)
  if (puc_rst)     inst_bw     <= 1'b0;
  if (puc_rst)     inst_bw     <= 1'b0;
  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_req;
 
 
// 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_decode or posedge puc_rst)
always @(posedge mclk_decode or posedge puc_rst)
Line 835... Line 861...
  if (puc_rst)                exec_dext_rdy <= 1'b0;
  if (puc_rst)                exec_dext_rdy <= 1'b0;
  else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0;
  else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0;
  else if (inst_dext_rdy)     exec_dext_rdy <= 1'b1;
  else if (inst_dext_rdy)     exec_dext_rdy <= 1'b1;
 
 
// Execution first state
// Execution first state
wire [3:0] e_first_state = ~dbg_halt_st  & inst_so_nxt[`IRQ] ? E_IRQ_0  :
wire [3:0] e_first_state = ~cpu_halt_st  & inst_so_nxt[`IRQ] ? E_IRQ_0  :
                            cpu_halt_cmd | (i_state==I_IDLE) ? E_IDLE   :
                            cpu_halt_req | (i_state==I_IDLE) ? E_IDLE   :
                            cpuoff                           ? E_IDLE   :
                            cpuoff                           ? E_IDLE   :
                            src_acalc_pre                    ? E_SRC_AD :
                            src_acalc_pre                    ? E_SRC_AD :
                            src_rd_pre                       ? E_SRC_RD :
                            src_rd_pre                       ? E_SRC_RD :
                            dst_acalc_pre                    ? E_DST_AD :
                            dst_acalc_pre                    ? E_DST_AD :
                            dst_rd_pre                       ? E_DST_RD : E_EXEC;
                            dst_rd_pre                       ? E_DST_RD : E_EXEC;

powered by: WebSVN 2.1.0

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