URL
https://opencores.org/ocsvn/openmsp430/openmsp430/trunk
Subversion Repositories openmsp430
Compare Revisions
- This comparison shows the changes necessary to convert path
/openmsp430/trunk/fpga/xilinx_diligent_s3board/rtl/verilog/openmsp430
- from Rev 190 to Rev 193
- ↔ Reverse comparison
Rev 190 → Rev 193
/omsp_frontend.v
48,101 → 48,101
module omsp_frontend ( |
|
// OUTPUTs |
dbg_halt_st, // Halt/Run status from CPU |
decode_noirq, // Frontend decode instruction |
e_state, // Execution state |
exec_done, // Execution completed |
inst_ad, // Decoded Inst: destination addressing mode |
inst_as, // Decoded Inst: source addressing mode |
inst_alu, // ALU control signals |
inst_bw, // Decoded Inst: byte width |
inst_dest, // Decoded Inst: destination (one hot) |
inst_dext, // Decoded Inst: destination extended instruction word |
inst_irq_rst, // Decoded Inst: Reset interrupt |
inst_jmp, // Decoded Inst: Conditional jump |
inst_mov, // Decoded Inst: mov instruction |
inst_sext, // Decoded Inst: source extended instruction word |
inst_so, // Decoded Inst: Single-operand arithmetic |
inst_src, // Decoded Inst: source (one hot) |
inst_type, // Decoded Instruction type |
irq_acc, // Interrupt request accepted (one-hot signal) |
mab, // Frontend Memory address bus |
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 |
pc, // Program counter |
pc_nxt, // Next PC value (for CALL & IRQ) |
dbg_halt_st, // Halt/Run status from CPU |
decode_noirq, // Frontend decode instruction |
e_state, // Execution state |
exec_done, // Execution completed |
inst_ad, // Decoded Inst: destination addressing mode |
inst_as, // Decoded Inst: source addressing mode |
inst_alu, // ALU control signals |
inst_bw, // Decoded Inst: byte width |
inst_dest, // Decoded Inst: destination (one hot) |
inst_dext, // Decoded Inst: destination extended instruction word |
inst_irq_rst, // Decoded Inst: Reset interrupt |
inst_jmp, // Decoded Inst: Conditional jump |
inst_mov, // Decoded Inst: mov instruction |
inst_sext, // Decoded Inst: source extended instruction word |
inst_so, // Decoded Inst: Single-operand arithmetic |
inst_src, // Decoded Inst: source (one hot) |
inst_type, // Decoded Instruction type |
irq_acc, // Interrupt request accepted (one-hot signal) |
mab, // Frontend Memory address bus |
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 |
pc, // Program counter |
pc_nxt, // Next PC value (for CALL & IRQ) |
|
// INPUTs |
cpu_en_s, // Enable CPU code execution (synchronous) |
cpuoff, // Turns off the CPU |
dbg_halt_cmd, // Halt CPU command |
dbg_reg_sel, // Debug selected register for rd/wr access |
fe_pmem_wait, // Frontend wait for Instruction fetch |
gie, // General interrupt enable |
irq, // Maskable interrupts |
mclk, // Main system clock |
mdb_in, // Frontend Memory data bus input |
nmi_pnd, // Non-maskable interrupt pending |
nmi_wkup, // NMI Wakeup |
pc_sw, // Program counter software value |
pc_sw_wr, // Program counter software write |
puc_rst, // Main system reset |
scan_enable, // Scan enable (active during scan shifting) |
wdt_irq, // Watchdog-timer interrupt |
wdt_wkup, // Watchdog Wakeup |
wkup // System Wake-up (asynchronous) |
cpu_en_s, // Enable CPU code execution (synchronous) |
cpuoff, // Turns off the CPU |
dbg_halt_cmd, // Halt CPU command |
dbg_reg_sel, // Debug selected register for rd/wr access |
fe_pmem_wait, // Frontend wait for Instruction fetch |
gie, // General interrupt enable |
irq, // Maskable interrupts |
mclk, // Main system clock |
mdb_in, // Frontend Memory data bus input |
nmi_pnd, // Non-maskable interrupt pending |
nmi_wkup, // NMI Wakeup |
pc_sw, // Program counter software value |
pc_sw_wr, // Program counter software write |
puc_rst, // Main system reset |
scan_enable, // Scan enable (active during scan shifting) |
wdt_irq, // Watchdog-timer interrupt |
wdt_wkup, // Watchdog Wakeup |
wkup // System Wake-up (asynchronous) |
); |
|
// OUTPUTs |
//========= |
output dbg_halt_st; // Halt/Run status from CPU |
output decode_noirq; // Frontend decode instruction |
output [3:0] e_state; // Execution state |
output exec_done; // Execution completed |
output [7:0] inst_ad; // Decoded Inst: destination addressing mode |
output [7:0] inst_as; // Decoded Inst: source addressing mode |
output [11:0] inst_alu; // ALU control signals |
output inst_bw; // Decoded Inst: byte width |
output [15:0] inst_dest; // Decoded Inst: destination (one hot) |
output [15:0] inst_dext; // Decoded Inst: destination extended instruction word |
output inst_irq_rst; // Decoded Inst: Reset interrupt |
output [7:0] inst_jmp; // Decoded Inst: Conditional jump |
output inst_mov; // Decoded Inst: mov instruction |
output [15:0] inst_sext; // Decoded Inst: source extended instruction word |
output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic |
output [15:0] inst_src; // Decoded Inst: source (one hot) |
output [2:0] inst_type; // Decoded Instruction type |
output [13:0] irq_acc; // Interrupt request accepted (one-hot signal) |
output [15:0] mab; // Frontend Memory address bus |
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 [15:0] pc; // Program counter |
output [15:0] pc_nxt; // Next PC value (for CALL & IRQ) |
output dbg_halt_st; // Halt/Run status from CPU |
output decode_noirq; // Frontend decode instruction |
output [3:0] e_state; // Execution state |
output exec_done; // Execution completed |
output [7:0] inst_ad; // Decoded Inst: destination addressing mode |
output [7:0] inst_as; // Decoded Inst: source addressing mode |
output [11:0] inst_alu; // ALU control signals |
output inst_bw; // Decoded Inst: byte width |
output [15:0] inst_dest; // Decoded Inst: destination (one hot) |
output [15:0] inst_dext; // Decoded Inst: destination extended instruction word |
output inst_irq_rst; // Decoded Inst: Reset interrupt |
output [7:0] inst_jmp; // Decoded Inst: Conditional jump |
output inst_mov; // Decoded Inst: mov instruction |
output [15:0] inst_sext; // Decoded Inst: source extended instruction word |
output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic |
output [15:0] inst_src; // Decoded Inst: source (one hot) |
output [2:0] inst_type; // Decoded Instruction type |
output [`IRQ_NR-3:0] irq_acc; // Interrupt request accepted (one-hot signal) |
output [15:0] mab; // Frontend Memory address bus |
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 [15:0] pc; // Program counter |
output [15:0] pc_nxt; // Next PC value (for CALL & IRQ) |
|
// INPUTs |
//========= |
input cpu_en_s; // Enable CPU code execution (synchronous) |
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 fe_pmem_wait; // Frontend wait for Instruction fetch |
input gie; // General interrupt enable |
input [13:0] irq; // Maskable interrupts |
input mclk; // Main system clock |
input [15:0] mdb_in; // Frontend Memory data bus input |
input nmi_pnd; // Non-maskable interrupt pending |
input nmi_wkup; // NMI Wakeup |
input [15:0] pc_sw; // Program counter software value |
input pc_sw_wr; // Program counter software write |
input puc_rst; // Main system reset |
input scan_enable; // Scan enable (active during scan shifting) |
input wdt_irq; // Watchdog-timer interrupt |
input wdt_wkup; // Watchdog Wakeup |
input wkup; // System Wake-up (asynchronous) |
input cpu_en_s; // Enable CPU code execution (synchronous) |
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 fe_pmem_wait; // Frontend wait for Instruction fetch |
input gie; // General interrupt enable |
input [`IRQ_NR-3:0] irq; // Maskable interrupts |
input mclk; // Main system clock |
input [15:0] mdb_in; // Frontend Memory data bus input |
input nmi_pnd; // Non-maskable interrupt pending |
input nmi_wkup; // NMI Wakeup |
input [15:0] pc_sw; // Program counter software value |
input pc_sw_wr; // Program counter software write |
input puc_rst; // Main system reset |
input scan_enable; // Scan enable (active during scan shifting) |
input wdt_irq; // Watchdog-timer interrupt |
input wdt_wkup; // Watchdog Wakeup |
input wkup; // System Wake-up (asynchronous) |
|
|
//============================================================================= |
149,6 → 149,15
// 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 |
function [15:0] one_hot16; |
input [3:0] binary; |
157,7 → 166,7
one_hot16[binary] = 1'b1; |
end |
endfunction |
|
|
// 8 bits one-hot decoder |
function [7:0] one_hot8; |
input [2:0] binary; |
166,6 → 175,17
one_hot8[binary] = 1'b1; |
end |
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 |
|
|
//============================================================================= |
286,36 → 306,38
wire mclk_irq_num = mclk; |
`endif |
|
// Select interrupt vector |
reg [3:0] irq_num; |
// Combine all IRQs |
`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) |
if (puc_rst) irq_num <= 4'hf; |
if (puc_rst) irq_num <= 6'h3f; |
`ifdef CLOCK_GATING |
else irq_num <= nmi_pnd ? 4'he : |
else |
`else |
else if (irq_detect) irq_num <= nmi_pnd ? 4'he : |
else if (irq_detect) |
`endif |
irq[13] ? 4'hd : |
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; |
irq_num <= get_irq_num(irq_all); |
|
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 |
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 nmi_acc = irq_acc_all[14]; |
wire [63:0] irq_acc_all = one_hot64(irq_num) & {64{(i_state==I_IRQ_FETCH)}}; |
wire [`IRQ_NR-3:0] irq_acc = irq_acc_all[61:64-`IRQ_NR]; |
wire nmi_acc = irq_acc_all[62]; |
|
// |
// 4.2) SYSTEM WAKEUP |
/omsp_alu.v
97,7 → 97,7
|
reg [4:0] Z_; |
begin |
Z_ = {1'b0,X}+{1'b0,Y}+{4'b0,C_}; |
Z_ = {1'b0,X}+{1'b0,Y}+{4'b0000,C_}; |
if (Z_<5'd10) bcd_add = Z_; |
else bcd_add = Z_+5'd6; |
end |
/openMSP430_defines.v
139,6 → 139,17
|
|
//------------------------------------------------------- |
// Number of available IRQs |
//------------------------------------------------------- |
// Indicates the number of interrupt vectors supported |
// (16, 32 or 64). |
//------------------------------------------------------- |
`define IRQ_16 |
//`define IRQ_32 |
//`define IRQ_64 |
|
|
//------------------------------------------------------- |
// Input synchronizers |
//------------------------------------------------------- |
// In some cases, the asynchronous input ports might |
630,6 → 641,19
`define DMEM_MSB `DMEM_AWIDTH-1 |
`define PER_MSB `PER_AWIDTH-1 |
|
// Number of available IRQs |
`ifdef IRQ_16 |
`define IRQ_NR 16 |
`endif |
`ifdef IRQ_32 |
`define IRQ_NR 32 |
`define IRQ_NR_GE_32 |
`endif |
`ifdef IRQ_64 |
`define IRQ_NR 64 |
`define IRQ_NR_GE_32 |
`endif |
|
// |
// STATES, REGISTER FIELDS, ... |
//====================================== |
851,6 → 875,20
//====================================== |
// CONFIGURATION CHECKS |
//====================================== |
|
`ifdef IRQ_16 |
`ifdef IRQ_32 |
CONFIGURATION ERROR: ONLY ONE OF THE IRQ NUMBER OPTION CAN BE SELECTED |
`endif |
`ifdef IRQ_64 |
CONFIGURATION ERROR: ONLY ONE OF THE IRQ NUMBER OPTION CAN BE SELECTED |
`endif |
`endif |
`ifdef IRQ_32 |
`ifdef IRQ_64 |
CONFIGURATION ERROR: ONLY ONE OF THE IRQ NUMBER OPTION CAN BE SELECTED |
`endif |
`endif |
`ifdef LFXT_DOMAIN |
`else |
`ifdef MCLK_MUX |
/openMSP430.v
114,7 → 114,7
output dmem_cen; // Data Memory chip enable (low active) |
output [15:0] dmem_din; // Data Memory data input |
output [1:0] dmem_wen; // Data Memory write enable (low active) |
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 lfxt_enable; // ASIC ONLY: Low frequency oscillator enable |
output lfxt_wkup; // ASIC ONLY: Low frequency oscillator wake-up (asynchronous) |
output mclk; // Main system clock |
142,7 → 142,7
input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous) |
input dco_clk; // Fast oscillator (fast clock) |
input [15:0] dmem_dout; // Data Memory data output |
input [13:0] irq; // Maskable interrupts |
input [`IRQ_NR-3:0] irq; // Maskable interrupts (14, 30 or 62) |
input lfxt_clk; // Low frequency oscillator (typ 32kHz) |
input nmi; // Non-maskable interrupt (asynchronous and non-glitchy) |
input [15:0] per_dout; // Peripheral data output |
261,7 → 261,7
.puc_rst (puc_rst), // Main system reset |
.smclk (smclk), // SMCLK |
.smclk_en (smclk_en), // SMCLK enable |
|
|
// INPUTs |
.cpu_en (cpu_en), // Enable CPU code execution (asynchronous) |
.cpuoff (cpuoff), // Turns off the CPU |
317,7 → 317,7
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted |
.pc (pc), // Program counter |
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ) |
|
|
// INPUTs |
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous) |
.cpuoff (cpuoff), // Turns off the CPU |
411,7 → 411,7
.pmem_cen (pmem_cen), // Program Memory chip enable (low active) |
.pmem_din (pmem_din), // Program Memory data input (optional) |
.pmem_wen (pmem_wen), // Program Memory write enable (low active) (optional) |
|
|
// INPUTs |
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU |
.dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access |
446,7 → 446,7
.wdtie (wdtie), // Watchdog-timer interrupt enable |
.wdtifg_sw_clr(wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear |
.wdtifg_sw_set(wdtifg_sw_set), // Watchdog-timer interrupt flag software set |
|
|
// INPUTs |
.cpu_nr_inst (cpu_nr_inst), // Current oMSP instance number |
.cpu_nr_total (cpu_nr_total), // Total number of oMSP instances-1 |
471,32 → 471,32
omsp_watchdog watchdog_0 ( |
|
// OUTPUTs |
.per_dout (per_dout_wdog), // Peripheral data output |
.wdt_irq (wdt_irq), // Watchdog-timer interrupt |
.wdt_reset (wdt_reset), // Watchdog-timer reset |
.wdt_wkup (wdt_wkup), // Watchdog Wakeup |
.wdtifg (wdtifg), // Watchdog-timer interrupt flag |
.wdtnmies (wdtnmies), // Watchdog-timer NMI edge selection |
|
.per_dout (per_dout_wdog), // Peripheral data output |
.wdt_irq (wdt_irq), // Watchdog-timer interrupt |
.wdt_reset (wdt_reset), // Watchdog-timer reset |
.wdt_wkup (wdt_wkup), // Watchdog Wakeup |
.wdtifg (wdtifg), // Watchdog-timer interrupt flag |
.wdtnmies (wdtnmies), // Watchdog-timer NMI edge selection |
|
// INPUTs |
.aclk (aclk), // ACLK |
.aclk_en (aclk_en), // ACLK enable |
.dbg_freeze (dbg_freeze), // Freeze Watchdog counter |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.por (por), // Power-on reset |
.puc_rst (puc_rst), // Main system reset |
.scan_enable (scan_enable), // Scan enable (active during scan shifting) |
.scan_mode (scan_mode), // Scan mode |
.smclk (smclk), // SMCLK |
.smclk_en (smclk_en), // SMCLK enable |
.wdtie (wdtie), // Watchdog-timer interrupt enable |
.wdtifg_irq_clr (irq_acc[10]), // Clear Watchdog-timer interrupt flag |
.wdtifg_sw_clr (wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear |
.wdtifg_sw_set (wdtifg_sw_set) // Watchdog-timer interrupt flag software set |
.aclk (aclk), // ACLK |
.aclk_en (aclk_en), // ACLK enable |
.dbg_freeze (dbg_freeze), // Freeze Watchdog counter |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.por (por), // Power-on reset |
.puc_rst (puc_rst), // Main system reset |
.scan_enable (scan_enable), // Scan enable (active during scan shifting) |
.scan_mode (scan_mode), // Scan mode |
.smclk (smclk), // SMCLK |
.smclk_en (smclk_en), // SMCLK enable |
.wdtie (wdtie), // Watchdog-timer interrupt enable |
.wdtifg_irq_clr (irq_acc[`IRQ_NR-6]), // Clear Watchdog-timer interrupt flag |
.wdtifg_sw_clr (wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear |
.wdtifg_sw_set (wdtifg_sw_set) // Watchdog-timer interrupt flag software set |
); |
`else |
assign per_dout_wdog = 16'h0000; |
516,7 → 516,7
|
// OUTPUTs |
.per_dout (per_dout_mpy), // Peripheral data output |
|
|
// INPUTs |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
559,7 → 559,7
.dbg_mem_wr (dbg_mem_wr), // Debug unit memory write |
.dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write |
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD |
|
|
// INPUTs |
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous) |
.cpu_id (cpu_id), // CPU ID |
/openMSP430_undefines.v
166,6 → 166,17
`undef NMI |
`endif |
|
// Number of available IRQs |
`ifdef IRQ_16 |
`undef IRQ_16 |
`endif |
`ifdef IRQ_32 |
`undef IRQ_32 |
`endif |
`ifdef IRQ_64 |
`undef IRQ_64 |
`endif |
|
// Input synchronizers |
`ifdef SYNC_NMI |
`undef SYNC_NMI |
382,6 → 393,14
`undef PER_MSB |
`endif |
|
// Number of available IRQs |
`ifdef IRQ_NR |
`undef IRQ_NR |
`endif |
`ifdef IRQ_NR_GE_32 |
`undef IRQ_NR_GE_32 |
`endif |
|
// Instructions type |
`ifdef INST_SO |
`undef INST_SO |