Line 34... |
Line 34... |
//
|
//
|
// *Author(s):
|
// *Author(s):
|
// - Olivier Girard, olgirard@gmail.com
|
// - Olivier Girard, olgirard@gmail.com
|
//
|
//
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
// $Rev: 136 $
|
// $Rev: 193 $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedDate: 2012-03-22 22:14:16 +0100 (Thu, 22 Mar 2012) $
|
// $LastChangedDate: 2013-12-17 21:16:33 +0100 (Tue, 17 Dec 2013) $
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
`ifdef OMSP_NO_INCLUDE
|
`ifdef OMSP_NO_INCLUDE
|
`else
|
`else
|
`include "openMSP430_defines.v"
|
`include "openMSP430_defines.v"
|
`endif
|
`endif
|
Line 112... |
Line 112... |
output inst_mov; // Decoded Inst: mov instruction
|
output inst_mov; // Decoded Inst: mov instruction
|
output [15:0] inst_sext; // Decoded Inst: source extended instruction word
|
output [15:0] inst_sext; // Decoded Inst: source extended instruction word
|
output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
|
output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
|
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 [`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_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
|
Line 129... |
Line 129... |
input cpuoff; // Turns off the CPU
|
input cpuoff; // Turns off the CPU
|
input dbg_halt_cmd; // Halt CPU command
|
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 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 [`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
|
input nmi_pnd; // Non-maskable interrupt pending
|
input nmi_pnd; // Non-maskable interrupt pending
|
input nmi_wkup; // NMI Wakeup
|
input nmi_wkup; // NMI Wakeup
|
input [15:0] pc_sw; // Program counter software value
|
input [15:0] pc_sw; // Program counter software value
|
Line 147... |
Line 147... |
|
|
//=============================================================================
|
//=============================================================================
|
// 1) UTILITY FUNCTIONS
|
// 1) UTILITY FUNCTIONS
|
//=============================================================================
|
//=============================================================================
|
|
|
|
// 64 bits one-hot decoder
|
|
function [63:0] one_hot64;
|
|
input [5:0] binary;
|
|
begin
|
|
one_hot64 = 64'h0000_0000_0000_0000;
|
|
one_hot64[binary] = 1'b1;
|
|
end
|
|
endfunction
|
|
|
// 16 bits one-hot decoder
|
// 16 bits one-hot decoder
|
function [15:0] one_hot16;
|
function [15:0] one_hot16;
|
input [3:0] binary;
|
input [3:0] binary;
|
begin
|
begin
|
one_hot16 = 16'h0000;
|
one_hot16 = 16'h0000;
|
Line 165... |
Line 174... |
one_hot8 = 8'h00;
|
one_hot8 = 8'h00;
|
one_hot8[binary] = 1'b1;
|
one_hot8[binary] = 1'b1;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
|
// Get IRQ number
|
|
function [5:0] get_irq_num;
|
|
input [62:0] irq_all;
|
|
integer ii;
|
|
begin
|
|
get_irq_num = 6'h3f;
|
|
for (ii = 62; ii >= 0; ii = ii - 1)
|
|
if (&get_irq_num & irq_all[ii]) get_irq_num = ii[5:0];
|
|
end
|
|
endfunction
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// 2) PARAMETER DEFINITIONS
|
// 2) PARAMETER DEFINITIONS
|
//=============================================================================
|
//=============================================================================
|
|
|
Line 284... |
Line 304... |
.clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
|
.clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
|
`else
|
`else
|
wire mclk_irq_num = mclk;
|
wire mclk_irq_num = mclk;
|
`endif
|
`endif
|
|
|
// Select interrupt vector
|
// Combine all IRQs
|
reg [3:0] irq_num;
|
`ifdef IRQ_16
|
|
wire [62:0] irq_all = {nmi_pnd, irq, 48'h0000_0000_0000} |
|
|
`else
|
|
`ifdef IRQ_32
|
|
wire [62:0] irq_all = {nmi_pnd, irq, 32'h0000} |
|
|
`else
|
|
`ifdef IRQ_64
|
|
wire [62:0] irq_all = {nmi_pnd, irq} |
|
|
`endif
|
|
`endif
|
|
`endif
|
|
{1'b0, 3'h0, wdt_irq, {58{1'b0}}};
|
|
|
|
// Select highest priority IRQ
|
|
reg [5:0] irq_num;
|
always @(posedge mclk_irq_num 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 <= 6'h3f;
|
`ifdef CLOCK_GATING
|
`ifdef CLOCK_GATING
|
else irq_num <= nmi_pnd ? 4'he :
|
else
|
`else
|
`else
|
else if (irq_detect) irq_num <= nmi_pnd ? 4'he :
|
else if (irq_detect)
|
`endif
|
`endif
|
irq[13] ? 4'hd :
|
irq_num <= get_irq_num(irq_all);
|
irq[12] ? 4'hc :
|
|
irq[11] ? 4'hb :
|
|
(irq[10] | wdt_irq) ? 4'ha :
|
|
irq[9] ? 4'h9 :
|
|
irq[8] ? 4'h8 :
|
|
irq[7] ? 4'h7 :
|
|
irq[6] ? 4'h6 :
|
|
irq[5] ? 4'h5 :
|
|
irq[4] ? 4'h4 :
|
|
irq[3] ? 4'h3 :
|
|
irq[2] ? 4'h2 :
|
|
irq[1] ? 4'h1 :
|
|
irq[0] ? 4'h0 : 4'hf;
|
|
|
|
wire [15:0] irq_addr = {11'h7ff, irq_num, 1'b0};
|
// Generate selected IRQ vector address
|
|
wire [15:0] irq_addr = {9'h1ff, irq_num, 1'b0};
|
|
|
// Interrupt request accepted
|
// Interrupt request accepted
|
wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}};
|
wire [63:0] irq_acc_all = one_hot64(irq_num) & {64{(i_state==I_IRQ_FETCH)}};
|
wire [13:0] irq_acc = irq_acc_all[13:0];
|
wire [`IRQ_NR-3:0] irq_acc = irq_acc_all[61:64-`IRQ_NR];
|
wire nmi_acc = irq_acc_all[14];
|
wire nmi_acc = irq_acc_all[62];
|
|
|
//
|
//
|
// 4.2) SYSTEM WAKEUP
|
// 4.2) SYSTEM WAKEUP
|
//-----------------------------------------
|
//-----------------------------------------
|
`ifdef CPUOFF_EN
|
`ifdef CPUOFF_EN
|