OpenCores
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_avnet_lx9microbard/rtl/verilog
    from Rev 200 to Rev 202
    Reverse comparison

Rev 200 → Rev 202

/omsp_system_0.v
21,9 → 21,9
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//----------------------------------------------------------------------------
//
//
// *File Name: omsp_system_1.v
//
//
// *Module Description:
// openMSP430 System 0.
// This core is dedicated to communication and
105,7 → 105,7
input [3:0] switch; // Input switches
output [1:0] led; // LEDs
 
 
//=============================================================================
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
//=============================================================================
186,6 → 186,9
.lfxt_enable (), // ASIC ONLY: Low frequency oscillator enable
.lfxt_wkup (), // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
.mclk (mclk), // Main system clock
.dma_dout (), // Direct Memory Access data output
.dma_ready (), // Direct Memory Access is complete
.dma_resp (), // Direct Memory Access response (0:Okay / 1:Error)
.per_addr (per_addr), // Peripheral address
.per_din (per_din), // Peripheral data input
.per_we (per_we), // Peripheral write enable (high active)
210,6 → 213,12
.dmem_dout (dmem_dout), // Data Memory data output
.irq (irq_bus), // Maskable interrupts
.lfxt_clk (1'b0), // Low frequency oscillator (typ 32kHz)
.dma_addr (15'h0000), // Direct Memory Access address
.dma_din (16'h0000), // Direct Memory Access data input
.dma_en (1'b0), // Direct Memory Access enable (high active)
.dma_priority (1'b0), // Direct Memory Access priority (0:low / 1:high)
.dma_we (2'b00), // Direct Memory Access write byte enable (high active)
.dma_wkup (1'b0), // ASIC ONLY: DMA Sub-System Wake-up (asynchronous and non-glitchy)
.nmi (nmi), // Non-maskable interrupt (asynchronous)
.per_dout (per_dout), // Peripheral data output
.pmem_dout (pmem_dout), // Program Memory data output
257,7 → 266,7
.p6_dout_en (), // Port 6 data output enable
.p6_sel (), // Port 6 function select
.per_dout (per_dout_gpio), // Peripheral data output
 
// INPUTs
.mclk (mclk), // Main system clock
.p1_din (p1_din), // Port 1 data input
374,6 → 383,3
 
 
endmodule // omsp_system_0
 
 
 
/omsp_system_1.v
21,16 → 21,16
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//----------------------------------------------------------------------------
//
//
// *File Name: omsp_system_0.v
//
//
// *Module Description:
// openMSP430 System 1.
// This core is dedicated to computing and can
// only drive two leds on the board.
// It can also read the switches value.
//
//
//
// *Author(s):
// - Olivier Girard, olgirard@gmail.com
//
98,7 → 98,7
input [3:0] switch; // Input switches
output [1:0] led; // LEDs
 
 
//=============================================================================
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
//=============================================================================
177,6 → 177,9
.lfxt_enable (), // ASIC ONLY: Low frequency oscillator enable
.lfxt_wkup (), // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
.mclk (mclk), // Main system clock
.dma_dout (), // Direct Memory Access data output
.dma_ready (), // Direct Memory Access is complete
.dma_resp (), // Direct Memory Access response (0:Okay / 1:Error)
.per_addr (per_addr), // Peripheral address
.per_din (per_din), // Peripheral data input
.per_we (per_we), // Peripheral write enable (high active)
201,6 → 204,12
.dmem_dout (dmem_dout), // Data Memory data output
.irq (irq_bus), // Maskable interrupts
.lfxt_clk (1'b0), // Low frequency oscillator (typ 32kHz)
.dma_addr (15'h0000), // Direct Memory Access address
.dma_din (16'h0000), // Direct Memory Access data input
.dma_en (1'b0), // Direct Memory Access enable (high active)
.dma_priority (1'b0), // Direct Memory Access priority (0:low / 1:high)
.dma_we (2'b00), // Direct Memory Access write byte enable (high active)
.dma_wkup (1'b0), // ASIC ONLY: DMA Sub-System Wake-up (asynchronous and non-glitchy)
.nmi (nmi), // Non-maskable interrupt (asynchronous)
.per_dout (per_dout), // Peripheral data output
.pmem_dout (pmem_dout), // Program Memory data output
248,7 → 257,7
.p6_dout_en (), // Port 6 data output enable
.p6_sel (), // Port 6 function select
.per_dout (per_dout_gpio), // Peripheral data output
 
// INPUTs
.mclk (mclk), // Main system clock
.p1_din (p1_din), // Port 1 data input
340,6 → 349,3
 
 
endmodule // omsp_system_1
 
 
 
/openmsp430/omsp_scan_mux.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_scan_mux.v
//
//
// *Module Description:
// Generic mux for scan mode
//
71,5 → 71,3
 
 
endmodule // omsp_scan_mux
 
 
/openmsp430/omsp_sync_reset.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_sync_reset.v
//
//
// *Module Description:
// Generic reset synchronizer for the openMSP430
//
75,4 → 75,3
 
 
endmodule // omsp_sync_reset
 
/openmsp430/omsp_frontend.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_frontend.v
//
//
// *Module Description:
// openMSP430 Instruction fetch and decode unit
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 134 $
// $Rev: 103 $
// $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
`else
48,101 → 48,109
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)
cpu_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_dma_enable, // DMA Sub-System Clock enable
mclk_dma_wkup, // DMA Sub-System Clock wake-up (asynchronous)
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)
cpu_halt_cmd, // Halt CPU command
cpuoff, // Turns off the CPU
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
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 [`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)
output cpu_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_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_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 [`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)
input cpu_en_s; // Enable CPU code execution (synchronous)
input cpu_halt_cmd; // Halt CPU command
input cpuoff; // Turns off the CPU
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 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)
 
 
//=============================================================================
186,8 → 194,8
if (&get_irq_num & irq_all[ii]) get_irq_num = ii[5:0];
end
endfunction
 
 
//=============================================================================
// 2) PARAMETER DEFINITIONS
//=============================================================================
238,25 → 246,25
wire is_const;
reg [15:0] sconst_nxt;
reg [3:0] e_state_nxt;
// CPU on/off through the debug interface or cpu_en port
wire cpu_halt_cmd = dbg_halt_cmd | ~cpu_en_s;
 
// CPU on/off through an external interface (debug or mstr) or cpu_en port
wire cpu_halt_req = cpu_halt_cmd | ~cpu_en_s;
 
// States Transitions
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)
I_IDLE : i_state_nxt = (irq_detect & ~cpu_halt_cmd) ? I_IRQ_FETCH :
(~cpuoff & ~cpu_halt_cmd) ? I_DEC : I_IDLE;
I_IDLE : i_state_nxt = (irq_detect & ~cpu_halt_req) ? I_IRQ_FETCH :
(~cpuoff & ~cpu_halt_req) ? I_DEC : I_IDLE;
I_IRQ_FETCH: i_state_nxt = I_IRQ_DONE;
I_IRQ_DONE : i_state_nxt = I_DEC;
I_DEC : i_state_nxt = irq_detect ? I_IRQ_FETCH :
(cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE :
cpu_halt_cmd & (e_state==E_IDLE) ? I_IDLE :
(cpuoff | cpu_halt_req) & exec_done ? I_IDLE :
cpu_halt_req & (e_state==E_IDLE) ? I_IDLE :
pc_sw_wr ? I_DEC :
~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
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;
I_EXT2 : i_state_nxt = I_DEC;
// pragma coverage off
274,11 → 282,11
wire decode = decode_noirq | irq_detect;
wire fetch = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
 
// Debug interface cpu status
reg dbg_halt_st;
// Halt/Run CPU status
reg cpu_halt_st;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) dbg_halt_st <= 1'b0;
else dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
if (puc_rst) cpu_halt_st <= 1'b0;
else cpu_halt_st <= cpu_halt_req & (i_state_nxt==I_IDLE);
 
 
//=============================================================================
296,7 → 304,7
else if (exec_done) inst_irq_rst <= 1'b0;
 
// 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
wire mclk_irq_num;
303,7 → 311,8
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;
wire UNUSED_scan_enable = scan_enable;
wire mclk_irq_num = mclk;
`endif
 
// Combine all IRQs
311,7 → 320,7
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} |
wire [62:0] irq_all = {nmi_pnd, irq, 32'h0000_0000} |
`else
`ifdef IRQ_64
wire [62:0] irq_all = {nmi_pnd, irq} |
353,19 → 362,36
(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));
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));
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
 
// 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;
assign mclk_dma_wkup = 1'b1;
assign mclk_dma_enable = 1'b1;
assign mclk_wkup = 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
 
//=============================================================================
401,15 → 427,15
if (puc_rst) pc <= 16'h0000;
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;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) pmem_busy <= 1'b0;
else pmem_busy <= fe_pmem_wait;
 
// Memory interface
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);
 
 
//
510,7 → 536,7
assign inst_type_nxt = {(ir[15:14]!=2'b00),
(ir[15:13]==3'b001),
(ir[15:13]==3'b000)} & {3{~irq_detect}};
 
always @(posedge mclk_decode or posedge puc_rst)
if (puc_rst) inst_type <= 3'b000;
`ifdef CLOCK_GATING
615,7 → 641,7
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 = cpu_halt_st ? one_hot16(dbg_reg_sel) :
inst_type[`INST_JMP] ? 16'h0001 :
inst_so[`IRQ] |
inst_so[`PUSH] |
778,7 → 804,7
reg inst_bw;
always @(posedge mclk or posedge puc_rst)
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
assign inst_sz_nxt = {1'b0, (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
837,8 → 863,8
else if (inst_dext_rdy) exec_dext_rdy <= 1'b1;
 
// Execution first state
wire [3:0] e_first_state = ~dbg_halt_st & inst_so_nxt[`IRQ] ? E_IRQ_0 :
cpu_halt_cmd | (i_state==I_IDLE) ? E_IDLE :
wire [3:0] e_first_state = ~cpu_halt_st & inst_so_nxt[`IRQ] ? E_IRQ_0 :
cpu_halt_req | (i_state==I_IDLE) ? E_IDLE :
cpuoff ? E_IDLE :
src_acalc_pre ? E_SRC_AD :
src_rd_pre ? E_SRC_RD :
863,7 → 889,7
 
E_SRC_AD : e_state_nxt = inst_sext_rdy ? E_SRC_RD : E_SRC_AD;
 
E_SRC_RD : e_state_nxt = dst_acalc ? E_DST_AD :
E_SRC_RD : e_state_nxt = dst_acalc ? E_DST_AD :
dst_rd ? E_DST_RD : E_EXEC;
 
E_DST_AD : e_state_nxt = (inst_dext_rdy |
933,7 → 959,7
inst_to_nxt[`CMP] | inst_type_nxt[`INST_JMP] |
inst_so_nxt[`RETI];
 
 
wire alu_and = inst_to_nxt[`AND] | inst_to_nxt[`BIC] |
inst_to_nxt[`BIT];
 
/openmsp430/omsp_alu.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_alu.v
//
//
// *Module Description:
// openMSP430 ALU
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
191,7 → 191,7
 
// Shifter for rotate instructions (RRC & RRA)
wire alu_shift_msb = inst_so[`RRC] ? status[0] :
inst_bw ? op_src[7] : op_src[15];
inst_bw ? op_src[7] : op_src[15];
wire alu_shift_7 = inst_bw ? alu_shift_msb : op_src[8];
wire [16:0] alu_shift = {1'b0, alu_shift_msb, op_src[15:9], alu_shift_7, op_src[7:1]};
 
250,6 → 250,14
assign alu_stat_wr = (inst_alu[`ALU_STAT_F] & exec_cycle) ? 4'b1111 : 4'b0000;
 
 
// LINT cleanup
wire UNUSED_inst_so_rra = inst_so[`RRA];
wire UNUSED_inst_so_push = inst_so[`PUSH];
wire UNUSED_inst_so_call = inst_so[`CALL];
wire UNUSED_inst_so_reti = inst_so[`RETI];
wire UNUSED_inst_jmp = inst_jmp[`JMP];
wire UNUSED_inst_alu = inst_alu[`EXEC_NO_WR];
 
endmodule // omsp_alu
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_register_file.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_register_file.v
//
//
// *Module Description:
// openMSP430 Register files
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
81,9 → 81,9
 
// OUTPUTs
//=========
output cpuoff; // Turns off the CPU
output gie; // General interrupt enable
output oscoff; // Turns off LFXT1 clock input
output cpuoff; // Turns off the CPU
output gie; // General interrupt enable
output oscoff; // Turns off LFXT1 clock input
output [15:0] pc_sw; // Program counter software value
output pc_sw_wr; // Program counter software write
output [15:0] reg_dest; // Selected register destination content
155,7 → 155,8
omsp_clock_gate clock_gate_r1 (.gclk(mclk_r1),
.clk (mclk), .enable(r1_en), .scan_enable(scan_enable));
`else
wire mclk_r1 = mclk;
wire UNUSED_scan_enable = scan_enable;
wire mclk_r1 = mclk;
`endif
 
always @(posedge mclk_r1 or posedge puc_rst)
168,7 → 169,9
else if (r1_inc) r1 <= reg_incr_val & 16'hfffe;
`endif
 
wire UNUSED_reg_sp_val_0 = reg_sp_val[0];
 
 
// R2: Status register
//---------------------
reg [15:0] r2;
236,9 → 239,9
wire [15:0] scg0_mask = 16'h0000; // - the SCG0 is not supported
wire [15:0] scg1_mask = 16'h0080; // - the SCG1 mode is emulated
`endif
 
wire [15:0] r2_mask = cpuoff_mask | oscoff_mask | scg0_mask | scg1_mask | 16'h010f;
 
always @(posedge mclk_r2 or posedge puc_rst)
if (puc_rst) r2 <= 16'h0000;
else if (reg_sr_clr) r2 <= 16'h0000;
567,7 → 570,7
`ifdef CLOCK_GATING
else r15 <= reg_incr_val;
`else
else if (r15_inc) r15 <= reg_incr_val;
else if (r15_inc) r15 <= reg_incr_val;
`endif
 
 
575,38 → 578,38
// 5) READ MUX
//=============================================================================
 
assign reg_src = (r0 & {16{inst_src_in[0]}}) |
(r1 & {16{inst_src_in[1]}}) |
(r2 & {16{inst_src_in[2]}}) |
(r3 & {16{inst_src_in[3]}}) |
(r4 & {16{inst_src_in[4]}}) |
(r5 & {16{inst_src_in[5]}}) |
(r6 & {16{inst_src_in[6]}}) |
(r7 & {16{inst_src_in[7]}}) |
(r8 & {16{inst_src_in[8]}}) |
(r9 & {16{inst_src_in[9]}}) |
(r10 & {16{inst_src_in[10]}}) |
(r11 & {16{inst_src_in[11]}}) |
(r12 & {16{inst_src_in[12]}}) |
(r13 & {16{inst_src_in[13]}}) |
(r14 & {16{inst_src_in[14]}}) |
assign reg_src = (r0 & {16{inst_src_in[0]}}) |
(r1 & {16{inst_src_in[1]}}) |
(r2 & {16{inst_src_in[2]}}) |
(r3 & {16{inst_src_in[3]}}) |
(r4 & {16{inst_src_in[4]}}) |
(r5 & {16{inst_src_in[5]}}) |
(r6 & {16{inst_src_in[6]}}) |
(r7 & {16{inst_src_in[7]}}) |
(r8 & {16{inst_src_in[8]}}) |
(r9 & {16{inst_src_in[9]}}) |
(r10 & {16{inst_src_in[10]}}) |
(r11 & {16{inst_src_in[11]}}) |
(r12 & {16{inst_src_in[12]}}) |
(r13 & {16{inst_src_in[13]}}) |
(r14 & {16{inst_src_in[14]}}) |
(r15 & {16{inst_src_in[15]}});
 
assign reg_dest = (r0 & {16{inst_dest[0]}}) |
(r1 & {16{inst_dest[1]}}) |
(r2 & {16{inst_dest[2]}}) |
(r3 & {16{inst_dest[3]}}) |
(r4 & {16{inst_dest[4]}}) |
(r5 & {16{inst_dest[5]}}) |
(r6 & {16{inst_dest[6]}}) |
(r7 & {16{inst_dest[7]}}) |
(r8 & {16{inst_dest[8]}}) |
(r9 & {16{inst_dest[9]}}) |
(r10 & {16{inst_dest[10]}}) |
(r11 & {16{inst_dest[11]}}) |
(r12 & {16{inst_dest[12]}}) |
(r13 & {16{inst_dest[13]}}) |
(r14 & {16{inst_dest[14]}}) |
assign reg_dest = (r0 & {16{inst_dest[0]}}) |
(r1 & {16{inst_dest[1]}}) |
(r2 & {16{inst_dest[2]}}) |
(r3 & {16{inst_dest[3]}}) |
(r4 & {16{inst_dest[4]}}) |
(r5 & {16{inst_dest[5]}}) |
(r6 & {16{inst_dest[6]}}) |
(r7 & {16{inst_dest[7]}}) |
(r8 & {16{inst_dest[8]}}) |
(r9 & {16{inst_dest[9]}}) |
(r10 & {16{inst_dest[10]}}) |
(r11 & {16{inst_dest[11]}}) |
(r12 & {16{inst_dest[12]}}) |
(r13 & {16{inst_dest[13]}}) |
(r14 & {16{inst_dest[14]}}) |
(r15 & {16{inst_dest[15]}});
 
 
/openmsp430/omsp_clock_mux.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_mux.v
//
//
// *Module Description:
// Standard clock mux for the openMSP430
//
51,7 → 51,7
clk_in1, // Clock input 1
reset, // Reset
scan_mode, // Scan mode (clk_in0 is selected in scan mode)
select // Clock selection
select_in // Clock selection
);
 
// OUTPUTs
64,7 → 64,7
input clk_in1; // Clock input 1
input reset; // Reset
input scan_mode; // Scan mode (clk_in0 is selected in scan mode)
input select; // Clock selection
input select_in; // Clock selection
 
 
//===========================================================================================================================//
77,7 → 77,7
// //
// //
// +-----. +--------+ +--------+ //
// select >>----+-------------O| \ | | | | +-----. //
// select_in >>----+-------------O| \ | | | | +-----. //
// | | |---| D Q |---| D Q |--+-------| \ //
// | +-------O| / | | | | | | |O-+ //
// | | +-----' | | | | | +--O| / | //
108,7 → 108,7
//-----------------------------------------------------------------------------
// Wire declarations
//-----------------------------------------------------------------------------
 
wire in0_select;
reg in0_select_s;
reg in0_select_ss;
128,9 → 128,9
//-----------------------------------------------------------------------------
// CLK_IN0 Selection
//-----------------------------------------------------------------------------
assign in0_select = ~select & ~in1_select_ss;
 
assign in0_select = ~select_in & ~in1_select_ss;
 
always @ (posedge clk_in0_inv or posedge reset)
if (reset) in0_select_s <= 1'b1;
else in0_select_s <= in0_select;
145,9 → 145,9
//-----------------------------------------------------------------------------
// CLK_IN1 Selection
//-----------------------------------------------------------------------------
assign in1_select = select & ~in0_select_ss;
 
assign in1_select = select_in & ~in0_select_ss;
 
always @ (posedge clk_in1_inv or posedge reset)
if (reset) in1_select_s <= 1'b0;
else in1_select_s <= in1_select;
158,7 → 158,7
 
assign in1_enable = in1_select_ss & ~scan_mode;
 
 
//-----------------------------------------------------------------------------
// Clock MUX
//-----------------------------------------------------------------------------
179,8 → 179,8
// Replace with standard cell NAND2
assign gated_clk_in0 = ~(clk_in0_inv & in0_enable);
assign gated_clk_in1 = ~(clk_in1_inv & in1_enable);
 
 
// Replace with standard cell AND2
assign clk_out = (gated_clk_in0 & gated_clk_in1);
 
187,6 → 187,3
 
 
endmodule // omsp_clock_gate
 
 
 
/openmsp430/omsp_multiplier.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_multiplier.v
//
//
// *Module Description:
// 16x16 Hardware multiplier.
//
135,7 → 135,7
(RESLO_D & {DEC_SZ{(reg_addr == RESLO )}}) |
(RESHI_D & {DEC_SZ{(reg_addr == RESHI )}}) |
(SUMEXT_D & {DEC_SZ{(reg_addr == SUMEXT )}});
 
// Read/Write probes
wire reg_write = |per_we & reg_sel;
wire reg_read = ~|per_we & reg_sel;
152,7 → 152,7
//============================================================================
 
// OP1 Register
//-----------------
//-----------------
reg [15:0] op1;
 
wire op1_wr = reg_wr[OP1_MPY] |
165,7 → 165,8
omsp_clock_gate clock_gate_op1 (.gclk(mclk_op1),
.clk (mclk), .enable(op1_wr), .scan_enable(scan_enable));
`else
wire mclk_op1 = mclk;
wire UNUSED_scan_enable = scan_enable;
wire mclk_op1 = mclk;
`endif
 
always @ (posedge mclk_op1 or posedge puc_rst)
178,9 → 179,9
 
wire [15:0] op1_rd = op1;
 
 
// OP2 Register
//-----------------
//-----------------
reg [15:0] op2;
 
wire op2_wr = reg_wr[OP2];
203,9 → 204,9
 
wire [15:0] op2_rd = op2;
 
 
// RESLO Register
//-----------------
//-----------------
reg [15:0] reslo;
 
wire [15:0] reslo_nxt;
234,7 → 235,7
 
 
// RESHI Register
//-----------------
//-----------------
reg [15:0] reshi;
 
wire [15:0] reshi_nxt;
261,9 → 262,9
 
wire [15:0] reshi_rd = early_read ? reshi_nxt : reshi;
 
 
// SUMEXT Register
//-----------------
//-----------------
reg [1:0] sumext_s;
 
wire [1:0] sumext_s_nxt;
331,10 → 332,10
// Detect whenever the RESHI and RESLO registers should be cleared
assign result_clr = op2_wr & ~acc_sel;
 
// Combine RESHI & RESLO
// Combine RESHI & RESLO
wire [31:0] result = {reshi, reslo};
 
 
// 16x16 Multiplier (result computed in 1 clock cycle)
//-----------------------------------------------------
`ifdef MPY_16x16
374,7 → 375,7
// 16x8 Multiplier (result computed in 2 clock cycles)
//-----------------------------------------------------
`else
 
// Detect start of a multiplication
reg [1:0] cycle;
always @ (posedge mclk or posedge puc_rst)
390,13 → 391,13
wire signed [8:0] op2_lo_xp = { 1'b0, op2[7:0]};
wire signed [8:0] op2_xp = cycle[0] ? op2_hi_xp : op2_lo_xp;
 
 
// 17x9 signed multiplication
wire signed [25:0] product = op1_xp * op2_xp;
 
wire [31:0] product_xp = cycle[0] ? {product[23:0], 8'h00} :
{{8{sign_sel & product[23]}}, product[23:0]};
 
// Accumulate
wire [32:0] result_nxt = {1'b0, result} + {1'b0, product_xp[31:0]};
 
/openmsp430/omsp_dbg_uart.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_dbg_uart.v
//
//
// *Module Description:
// Debug UART communication interface (8N1, Half-duplex)
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
53,7 → 53,7
dbg_rd, // Debug register data read
dbg_uart_txd, // Debug interface: UART TXD
dbg_wr, // Debug register data write
 
// INPUTs
dbg_clk, // Debug unit clock
dbg_dout, // Debug register data output
109,7 → 109,7
`else
wire uart_rxd = dbg_uart_rxd;
`endif
 
// RXD input buffer
//--------------------------------
reg [1:0] rxd_buf;
122,9 → 122,9
reg rxd_maj;
 
wire rxd_maj_nxt = (uart_rxd & rxd_buf[0]) |
(uart_rxd & rxd_buf[1]) |
(rxd_buf[0] & rxd_buf[1]);
(uart_rxd & rxd_buf[1]) |
(rxd_buf[0] & rxd_buf[1]);
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) rxd_maj <= 1'b1;
else rxd_maj <= rxd_maj_nxt;
133,7 → 133,7
wire rxd_fe = rxd_maj & ~rxd_maj_nxt;
wire rxd_re = ~rxd_maj & rxd_maj_nxt;
wire rxd_edge = rxd_maj ^ rxd_maj_nxt;
 
//=============================================================================
// 2) UART STATE MACHINE
//=============================================================================
179,7 → 179,7
default : uart_state_nxt = RX_CMD;
// pragma coverage on
endcase
 
// State machine
always @(posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) uart_state <= RX_SYNC;
191,7 → 191,7
wire rx_active = (uart_state==RX_DATA1) | (uart_state==RX_DATA2) | (uart_state==RX_CMD);
wire tx_active = (uart_state==TX_DATA1) | (uart_state==TX_DATA2);
 
 
//=============================================================================
// 3) UART SYNCHRONIZATION
//=============================================================================
218,12 → 218,12
`else
wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = `DBG_UART_CNT;
`endif
 
 
//=============================================================================
// 4) UART RECEIVE / TRANSMIT
//=============================================================================
 
// Transfer counter
//------------------------
reg [3:0] xfer_bit;
233,7 → 233,7
wire rxd_start = (xfer_bit==4'h0) & rxd_fe & ((uart_state!=RX_SYNC));
wire xfer_bit_inc = (xfer_bit!=4'h0) & (xfer_cnt=={`DBG_UART_XFER_CNT_W{1'b0}});
assign xfer_done = rx_active ? (xfer_bit==4'ha) : (xfer_bit==4'hb);
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) xfer_bit <= 4'h0;
else if (txd_start | rxd_start) xfer_bit <= 4'h1;
260,12 → 260,12
// Generate TXD output
//------------------------
reg dbg_uart_txd;
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) dbg_uart_txd <= 1'b1;
else if (xfer_bit_inc & tx_active) dbg_uart_txd <= xfer_buf[0];
 
 
//=============================================================================
// 5) INTERFACE TO DEBUG REGISTERS
//=============================================================================
288,8 → 288,8
wire dbg_rd = mem_burst ? (xfer_done & (uart_state==TX_DATA2)) :
(cmd_valid & ~xfer_buf_nxt[`DBG_UART_WR]) | mem_burst_rd;
 
 
 
endmodule // omsp_dbg_uart
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_dbg_hwbrk.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_dbg_hwbrk.v
//
//
// *Module Description:
// Hardware Breakpoint / Watchpoint module
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
51,7 → 51,7
brk_halt, // Hardware breakpoint command
brk_pnd, // Hardware break/watch-point pending
brk_dout, // Hardware break/watch-point register data input
 
// INPUTs
brk_reg_rd, // Hardware break/watch-point register read select
brk_reg_wr, // Hardware break/watch-point register write select
96,13 → 96,13
wire addr0_wr_set;
wire addr0_rd_set;
 
 
parameter BRK_CTL = 0,
BRK_STAT = 1,
BRK_ADDR0 = 2,
BRK_ADDR1 = 3;
 
 
//=============================================================================
// 2) CONFIGURATION REGISTERS
//=============================================================================
131,7 → 131,7
reg [4:0] brk_ctl;
 
wire brk_ctl_wr = brk_reg_wr[BRK_CTL];
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) brk_ctl <= 5'h00;
else if (brk_ctl_wr) brk_ctl <= {`HWBRK_RANGE & dbg_din[4], dbg_din[3:0]};
138,7 → 138,7
 
wire [7:0] brk_ctl_full = {3'b000, brk_ctl};
 
 
// BRK_STAT Register
//-----------------------------------------------------------------------------
// 7 6 5 4 3 2 1 0
167,23 → 167,23
reg [15:0] brk_addr0;
 
wire brk_addr0_wr = brk_reg_wr[BRK_ADDR0];
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) brk_addr0 <= 16'h0000;
else if (brk_addr0_wr) brk_addr0 <= dbg_din;
 
 
// BRK_ADDR1/DATA0 Register
//-----------------------------------------------------------------------------
reg [15:0] brk_addr1;
 
wire brk_addr1_wr = brk_reg_wr[BRK_ADDR1];
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) brk_addr1 <= 16'h0000;
else if (brk_addr1_wr) brk_addr1 <= dbg_din;
 
 
//============================================================================
// 3) DATA OUTPUT GENERATION
//============================================================================
198,7 → 198,7
brk_addr0_rd |
brk_addr1_rd;
 
 
//============================================================================
// 4) BREAKPOINT / WATCHPOINT GENERATION
//============================================================================
207,10 → 207,10
//---------------------------
// Note: here the comparison logic is instanciated several times in order
// to improve the timings, at the cost of a bit more area.
 
wire equ_d_addr0 = eu_mb_en & (eu_mab==brk_addr0) & ~brk_ctl[`BRK_RANGE];
wire equ_d_addr1 = eu_mb_en & (eu_mab==brk_addr1) & ~brk_ctl[`BRK_RANGE];
wire equ_d_range = eu_mb_en & ((eu_mab>=brk_addr0) & (eu_mab<=brk_addr1)) &
wire equ_d_range = eu_mb_en & ((eu_mab>=brk_addr0) & (eu_mab<=brk_addr1)) &
brk_ctl[`BRK_RANGE] & `HWBRK_RANGE;
 
 
237,7 → 237,7
wire d_addr0_rd = equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr;
wire d_addr1_rd = equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr;
wire d_range_rd = equ_d_range & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr;
 
// Set flags
assign addr0_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr0_rd | i_addr0_rd);
assign addr0_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr0_wr;
246,11 → 246,11
assign range_rd_set = brk_ctl[`BRK_MODE_RD] & (d_range_rd | i_range_rd);
assign range_wr_set = brk_ctl[`BRK_MODE_WR] & d_range_wr;
 
 
// Break CPU
assign brk_halt = brk_ctl[`BRK_EN] & |brk_stat_set;
 
 
endmodule // omsp_dbg_hwbrk
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_dbg_i2c.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_dbg_i2c.v
//
//
// *Module Description:
// Debug I2C Slave communication interface
//
61,7 → 61,6
dbg_i2c_broadcast, // Debug interface: I2C Broadcast Address (for multicore systems)
dbg_i2c_scl, // Debug interface: I2C SCL
dbg_i2c_sda_in, // Debug interface: I2C SDA IN
dbg_rd_rdy, // Debug register data is ready for read
dbg_rst, // Debug unit reset
mem_burst, // Burst on going
mem_burst_end, // End TX/RX burst
86,7 → 85,6
input [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
input dbg_i2c_scl; // Debug interface: I2C SCL
input dbg_i2c_sda_in; // Debug interface: I2C SDA IN
input dbg_rd_rdy; // Debug register data is ready for read
input dbg_rst; // Debug unit reset
input mem_burst; // Burst on going
input mem_burst_end; // End TX/RX burst
120,7 → 118,7
);
wire sda_in_sync = ~sda_in_sync_n;
 
 
// SCL/SDA input buffers
//--------------------------------
 
141,7 → 139,7
wire scl = (scl_sync & scl_buf[0]) |
(scl_sync & scl_buf[1]) |
(scl_buf[0] & scl_buf[1]);
 
wire sda_in = (sda_in_sync & sda_in_buf[0]) |
(sda_in_sync & sda_in_buf[1]) |
(sda_in_buf[0] & sda_in_buf[1]);
179,7 → 177,7
 
wire scl_sample = scl_re_dly[1];
 
 
//=============================================================================
// 2) I2C START & STOP CONDITION DETECTION
//=============================================================================
195,7 → 193,7
//-----------------
 
wire stop_detect = sda_in_re & scl;
 
//-----------------
// I2C Slave Active
//-----------------
213,8 → 211,8
 
wire i2c_active = i2c_active_seq & ~stop_detect;
wire i2c_init = ~i2c_active | start_detect;
 
 
//=============================================================================
// 3) I2C STATE MACHINE
//=============================================================================
228,7 → 226,7
wire shift_rx_done;
wire shift_tx_done;
reg dbg_rd;
 
// State machine definition
parameter RX_ADDR = 3'h0;
parameter RX_ADDR_ACK = 3'h1;
270,7 → 268,7
default : i2c_state_nxt = RX_ADDR;
// pragma coverage on
endcase
 
// State machine
always @(posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) i2c_state <= RX_ADDR;
297,9 → 295,9
wire shift_buf_tx_en = shift_tx_en_pre & scl_fe & (shift_buf!=9'h100);
 
wire [7:0] shift_tx_val;
wire [8:0] shift_buf_nxt = shift_buf_rx_init ? 9'h001 : // RX Init
shift_buf_tx_init ? {shift_tx_val, 1'b1} : // TX Init
 
wire [8:0] shift_buf_nxt = shift_buf_rx_init ? 9'h001 : // RX Init
shift_buf_tx_init ? {shift_tx_val, 1'b1} : // TX Init
shift_buf_rx_en ? {shift_buf[7:0], sda_in} : // RX Shift
shift_buf_tx_en ? {shift_buf[7:0], 1'b0} : // TX Shift
shift_buf[8:0]; // Hold
314,10 → 312,14
(shift_buf[7:1] != dbg_i2c_broadcast[6:0]) &&
`endif
(shift_buf[7:1] != dbg_i2c_addr[6:0]));
`ifdef DBG_I2C_BROADCAST
`else
wire [6:0] UNUSED_dbg_i2c_broadcast = dbg_i2c_broadcast;
`endif
 
// Utility signals
wire shift_rx_data_done = shift_rx_done & (i2c_state==RX_DATA);
wire shift_tx_data_done = shift_tx_done;
wire shift_rx_data_done = shift_rx_done & (i2c_state==RX_DATA);
wire shift_tx_data_done = shift_tx_done;
 
 
//=============================================================================
331,8 → 333,8
else if (scl_fe) dbg_i2c_sda_out <= ~((i2c_state_nxt==RX_ADDR_ACK) ||
(i2c_state_nxt==RX_DATA_ACK) ||
(shift_buf_tx_en & ~shift_buf[8]));
 
 
//=============================================================================
// 6) DEBUG INTERFACE STATE MACHINE
//=============================================================================
387,7 → 389,7
default : dbg_state_nxt = RX_CMD;
// pragma coverage on
endcase
 
// State machine
always @(posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) dbg_state <= RX_CMD;
436,7 → 438,7
if (dbg_rst) dbg_din_hi <= 8'h00;
else if (rx_lo_valid) dbg_din_hi <= 8'h00;
else if (rx_hi_valid) dbg_din_hi <= shift_buf[7:0];
 
assign dbg_din = {dbg_din_hi, dbg_din_lo};
 
 
454,12 → 456,12
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) dbg_rd <= 1'b0;
else dbg_rd <= (mem_burst & mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_LO)) :
(mem_burst & ~mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_HI)) :
(mem_burst & ~mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_HI)) :
cmd_valid ? ~shift_buf[7] :
1'b0;
 
 
// Debug register data read value
// Debug register data read value
assign shift_tx_val = (dbg_state==TX_BYTE_HI) ? dbg_dout[15:8] :
dbg_dout[7:0];
 
/openmsp430/omsp_sfr.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_sfr.v
//
//
// *Module Description:
// Processor Special function register
// Non-Maskable Interrupt generation
37,9 → 37,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
171,8 → 171,8
reg nmie;
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) nmie <= 1'b0;
else if (nmi_acc) nmie <= 1'b0;
else if (ie1_wr) nmie <= ie1_nxt[4];
else if (nmi_acc) nmie <= 1'b0;
else if (ie1_wr) nmie <= ie1_nxt[4];
`else
wire nmie = 1'b0;
`endif
181,9 → 181,9
reg wdtie;
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) wdtie <= 1'b0;
else if (ie1_wr) wdtie <= ie1_nxt[0];
else if (ie1_wr) wdtie <= ie1_nxt[0];
`else
wire wdtie = 1'b0;
wire wdtie = 1'b0;
`endif
 
assign ie1 = {3'b000, nmie, 3'b000, wdtie};
247,11 → 247,11
wire [5:0] pmem_size = (`PMEM_SIZE >> 10); // cpu_id_pmem * 1024 = program memory size
 
assign cpu_id = {pmem_size,
dmem_size,
mpy_info,
per_space,
user_version,
cpu_asic,
dmem_size,
mpy_info,
per_space,
user_version,
cpu_asic,
cpu_version};
 
 
305,19 → 305,20
always @(posedge mclk or posedge puc_rst)
if (puc_rst) nmi_capture_rst <= 1'b1;
else nmi_capture_rst <= ifg1_wr & ~ifg1_nxt[4];
 
// NMI event capture
wire nmi_capture;
omsp_wakeup_cell wakeup_cell_nmi (
.wkup_out (nmi_capture), // Wakup signal (asynchronous)
.scan_clk (mclk), // Scan clock
.scan_mode (scan_mode), // Scan mode
.scan_rst (puc_rst), // Scan reset
.wkup_clear (nmi_capture_rst), // Glitch free wakeup event clear
.wkup_event (nmi_pol) // Glitch free asynchronous wakeup event
.wkup_out (nmi_capture), // Wakup signal (asynchronous)
.scan_clk (mclk), // Scan clock
.scan_mode (scan_mode), // Scan mode
.scan_rst (puc_rst), // Scan reset
.wkup_clear (nmi_capture_rst), // Glitch free wakeup event clear
.wkup_event (nmi_pol) // Glitch free asynchronous wakeup event
);
`else
wire nmi_capture = nmi_pol;
wire UNUSED_scan_mode = scan_mode;
wire nmi_capture = nmi_pol;
`endif
 
// Synchronization
330,8 → 331,9
);
 
`else
wire nmi_capture = nmi_pol;
wire nmi_s = nmi_pol;
wire UNUSED_scan_mode = scan_mode;
wire nmi_capture = nmi_pol;
wire nmi_s = nmi_pol;
`endif
 
//-----------------------------------
360,11 → 362,17
 
`else
 
wire nmi_pnd = 1'b0;
wire nmi_wkup = 1'b0;
 
wire nmi_pnd = 1'b0;
wire nmi_wkup = 1'b0;
wire UNUSED_scan_mode = scan_mode;
wire UNUSED_nmi = nmi;
wire UNUSED_nmi_acc = nmi_acc;
wire UNUSED_wdtnmies = wdtnmies;
`endif
 
// LINT cleanup
wire [7:0] UNUSED_per_din_15_8 = per_din[15:8];
 
endmodule // omsp_sfr
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_wakeup_cell.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_wakeup_cell.v
//
//
// *Module Description:
// Generic Wakeup cell
//
/openmsp430/omsp_clock_gate.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_gate.v
//
//
// *Module Description:
// Generic clock gate cell for the openMSP430
//
66,7 → 66,7
//=============================================================================
// CLOCK GATE: LATCH + AND
//=============================================================================
 
// Enable clock gate during scan shift
// (the gate itself is checked with the scan capture cycle)
wire enable_in = (enable | scan_enable);
82,5 → 82,3
 
 
endmodule // omsp_clock_gate
 
 
/openmsp430/omsp_dbg.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_dbg.v
//
//
// *Module Description:
// Debug interface
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
58,7 → 58,7
dbg_mem_wr, // Debug unit memory write
dbg_reg_wr, // Debug unit CPU register write
dbg_uart_txd, // Debug interface: UART TXD
 
// INPUTs
cpu_en_s, // Enable CPU code execution (synchronous)
cpu_id, // CPU ID
131,7 → 131,7
wire [5:0] dbg_addr;
wire [15:0] dbg_din;
wire dbg_wr;
reg mem_burst;
reg mem_burst;
wire dbg_reg_rd;
wire dbg_mem_rd;
reg dbg_mem_rd_dly;
152,7 → 152,7
wire brk3_halt;
wire brk3_pnd;
wire [15:0] brk3_dout;
 
// Number of registers
parameter NR_REG = 25;
 
236,7 → 236,7
wire [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr;
 
// Register address decode
reg [NR_REG-1:0] reg_dec;
reg [NR_REG-1:0] reg_dec;
always @(dbg_addr_in)
case (dbg_addr_in)
CPU_ID_LO : reg_dec = CPU_ID_LO_D;
291,7 → 291,7
//=============================================================================
 
// CPU_ID Register
//-----------------
//-----------------
// -------------------------------------------------------------------
// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 |
// |----------------------------+-----------------+------+-------------|
324,7 → 324,7
reg [6:3] cpu_ctl;
 
wire cpu_ctl_wr = reg_wr[CPU_CTL];
 
always @ (posedge dbg_clk or posedge dbg_rst)
`ifdef DBG_RST_BRK_EN
if (dbg_rst) cpu_ctl <= 4'h6;
339,7 → 339,7
wire run_cpu = cpu_ctl_wr & dbg_din[`RUN] & dbg_halt_st;
wire istep = cpu_ctl_wr & dbg_din[`ISTEP] & dbg_halt_st;
 
 
// CPU_STAT Register
//------------------------------------------------------------------------------------
// 7 6 5 4 3 2 1 0
359,7 → 359,7
wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
cpu_stat, 1'b0, dbg_halt_st};
 
 
//=============================================================================
// 4) REGISTER: MEMORY INTERFACE
//=============================================================================
385,7 → 385,7
reg [3:1] mem_ctl;
 
wire mem_ctl_wr = reg_wr[MEM_CTL];
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) mem_ctl <= 3'h0;
else if (mem_ctl_wr) mem_ctl <= dbg_din[3:1];
398,19 → 398,19
else mem_start <= mem_ctl_wr & dbg_din[0];
 
wire mem_bw = mem_ctl[3];
 
// MEM_DATA Register
//------------------
//------------------
reg [15:0] mem_data;
reg [15:0] mem_addr;
wire mem_access;
 
wire mem_data_wr = reg_wr[MEM_DATA];
 
wire [15:0] dbg_mem_din_bw = ~mem_bw ? dbg_mem_din :
mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
{8'h00, dbg_mem_din[7:0]};
mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
{8'h00, dbg_mem_din[7:0]};
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) mem_data <= 16'h0000;
else if (mem_data_wr) mem_data <= dbg_din;
417,32 → 417,32
else if (dbg_reg_rd) mem_data <= dbg_reg_din;
else if (dbg_mem_rd_dly) mem_data <= dbg_mem_din_bw;
 
 
// MEM_ADDR Register
//------------------
//------------------
reg [15:0] mem_cnt;
 
wire mem_addr_wr = reg_wr[MEM_ADDR];
wire dbg_mem_acc = (|dbg_mem_wr | (dbg_rd_rdy & ~mem_ctl[2]));
wire dbg_reg_acc = ( dbg_reg_wr | (dbg_rd_rdy & mem_ctl[2]));
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
(mem_burst & dbg_mem_acc & ~mem_bw) ? 16'h0002 :
(mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'h0001 : 16'h0000;
 
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
(mem_burst & dbg_mem_acc & ~mem_bw) ? 16'h0002 :
(mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'h0001 : 16'h0000;
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) mem_addr <= 16'h0000;
else if (mem_addr_wr) mem_addr <= dbg_din;
else mem_addr <= mem_addr + mem_addr_inc;
 
// MEM_CNT Register
//------------------
//------------------
 
wire mem_cnt_wr = reg_wr[MEM_CNT];
 
wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
(mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'hffff : 16'h0000;
 
always @ (posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) mem_cnt <= 16'h0000;
else if (mem_cnt_wr) mem_cnt <= dbg_din;
472,7 → 472,7
.brk_halt (brk0_halt), // Hardware breakpoint command
.brk_pnd (brk0_pnd), // Hardware break/watch-point pending
.brk_dout (brk0_dout), // Hardware break/watch-point register data input
 
// INPUTs
.brk_reg_rd (brk0_reg_rd), // Hardware break/watch-point register read select
.brk_reg_wr (brk0_reg_wr), // Hardware break/watch-point register write select
487,9 → 487,13
);
 
`else
assign brk0_halt = 1'b0;
assign brk0_pnd = 1'b0;
assign brk0_dout = 16'h0000;
assign brk0_halt = 1'b0;
assign brk0_pnd = 1'b0;
assign brk0_dout = 16'h0000;
wire [15:0] UNUSED_eu_mab = eu_mab;
wire UNUSED_eu_mb_en = eu_mb_en;
wire [1:0] UNUSED_eu_mb_wr = eu_mb_wr;
wire [15:0] UNUSED_pc = pc;
`endif
 
`ifdef DBG_HWBRK_1
511,7 → 515,7
.brk_halt (brk1_halt), // Hardware breakpoint command
.brk_pnd (brk1_pnd), // Hardware break/watch-point pending
.brk_dout (brk1_dout), // Hardware break/watch-point register data input
 
// INPUTs
.brk_reg_rd (brk1_reg_rd), // Hardware break/watch-point register read select
.brk_reg_wr (brk1_reg_wr), // Hardware break/watch-point register write select
550,7 → 554,7
.brk_halt (brk2_halt), // Hardware breakpoint command
.brk_pnd (brk2_pnd), // Hardware break/watch-point pending
.brk_dout (brk2_dout), // Hardware break/watch-point register data input
 
// INPUTs
.brk_reg_rd (brk2_reg_rd), // Hardware break/watch-point register read select
.brk_reg_wr (brk2_reg_wr), // Hardware break/watch-point register write select
589,7 → 593,7
.brk_halt (brk3_halt), // Hardware breakpoint command
.brk_pnd (brk3_pnd), // Hardware break/watch-point pending
.brk_dout (brk3_dout), // Hardware break/watch-point register data input
 
// INPUTs
.brk_reg_rd (brk3_reg_rd), // Hardware break/watch-point register read select
.brk_reg_wr (brk3_reg_wr), // Hardware break/watch-point register write select
653,12 → 657,12
//--------------------------
wire dbg_cpu_reset = cpu_ctl[`CPU_RST];
 
 
// Break after reset
//--------------------------
wire halt_rst = cpu_ctl[`RST_BRK_EN] & dbg_en_s & puc_pnd_set;
 
 
// Freeze peripherals
//--------------------------
wire dbg_freeze = dbg_halt_st & (cpu_ctl[`FRZ_BRK_EN] | ~cpu_en_s);
677,7 → 681,7
else if (istep) inc_step <= 2'b11;
else inc_step <= {inc_step[0], 1'b0};
 
 
// Run / Halt
//--------------------------
reg halt_flag;
696,7 → 700,7
 
wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
 
 
//============================================================================
// 8) MEMORY CONTROL
//============================================================================
718,7 → 722,7
assign mem_burst_wr = (mem_burst_start & mem_ctl[1]);
 
// Trigger CPU Register or memory access during a burst
reg mem_startb;
reg mem_startb;
always @(posedge dbg_clk or posedge dbg_rst)
if (dbg_rst) mem_startb <= 1'b0;
else mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
726,7 → 730,7
// Combine single and burst memory start of sequence
wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
 
 
// Memory access state machine
//------------------------------
reg [1:0] mem_state;
741,7 → 745,7
// State transition
always @(mem_state or mem_seq_start or dbg_halt_st)
case (mem_state)
M_IDLE : mem_state_nxt = ~mem_seq_start ? M_IDLE :
M_IDLE : mem_state_nxt = ~mem_seq_start ? M_IDLE :
dbg_halt_st ? M_ACCESS : M_SET_BRK;
M_SET_BRK : mem_state_nxt = dbg_halt_st ? M_ACCESS_BRK : M_SET_BRK;
M_ACCESS_BRK : mem_state_nxt = M_IDLE;
785,7 → 789,7
if (dbg_rst) dbg_mem_rd_dly <= 1'b0;
else dbg_mem_rd_dly <= dbg_mem_rd;
 
 
//=============================================================================
// 9) UART COMMUNICATION
//=============================================================================
798,7 → 802,7
.dbg_rd (dbg_rd), // Debug register data read
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
.dbg_wr (dbg_wr), // Debug register data write
 
// INPUTs
.dbg_clk (dbg_clk), // Debug unit clock
.dbg_dout (dbg_dout), // Debug register data output
813,13 → 817,17
);
 
`else
assign dbg_uart_txd = 1'b1;
assign dbg_uart_txd = 1'b1;
 
wire UNUSED_dbg_uart_rxd = dbg_uart_rxd;
 
 
`ifdef DBG_I2C
`else
assign dbg_addr = 6'h00;
assign dbg_din = 16'h0000;
assign dbg_rd = 1'b0;
assign dbg_wr = 1'b0;
assign dbg_addr = 6'h00;
assign dbg_din = 16'h0000;
assign dbg_rd = 1'b0;
assign dbg_wr = 1'b0;
`endif
`endif
 
843,7 → 851,6
.dbg_i2c_broadcast (dbg_i2c_broadcast), // Debug interface: I2C Broadcast Address (for multicore systems)
.dbg_i2c_scl (dbg_i2c_scl), // Debug interface: I2C SCL
.dbg_i2c_sda_in (dbg_i2c_sda_in), // Debug interface: I2C SDA IN
.dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read
.dbg_rst (dbg_rst), // Debug unit reset
.mem_burst (mem_burst), // Burst on going
.mem_burst_end (mem_burst_end), // End TX/RX burst
853,7 → 860,13
);
 
`else
assign dbg_i2c_sda_out = 1'b1;
assign dbg_i2c_sda_out = 1'b1;
 
wire [6:0] UNUSED_dbg_i2c_addr = dbg_i2c_addr;
wire [6:0] UNUSED_dbg_i2c_broadcast = dbg_i2c_broadcast;
wire UNUSED_dbg_i2c_scl = dbg_i2c_scl;
wire UNUSED_dbg_i2c_sda_in = dbg_i2c_sda_in;
wire UNUSED_dbg_rd_rdy = dbg_rd_rdy;
`endif
 
endmodule // omsp_dbg
/openmsp430/filelist.f
0,0 → 1,60
//=============================================================================
// Copyright (C) 2001 Authors
//
// This source file may be used and distributed without restriction provided
// that this copyright statement is not removed from the file and that any
// derivative work contains the original copyright notice and the associated
// disclaimer.
//
// This source file is free software; you can redistribute it and/or modify0
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This source is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this source; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//-----------------------------------------------------------------------------
//
// File Name: filelist.f
//
// Author(s):
// - Olivier Girard, olgirard@gmail.com
//
//-----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//=============================================================================
 
//=============================================================================
// Module specific modules
//=============================================================================
../../../rtl/verilog/openMSP430_defines.v
../../../rtl/verilog/openMSP430.v
../../../rtl/verilog/omsp_frontend.v
../../../rtl/verilog/omsp_execution_unit.v
../../../rtl/verilog/omsp_register_file.v
../../../rtl/verilog/omsp_alu.v
../../../rtl/verilog/omsp_sfr.v
../../../rtl/verilog/omsp_clock_module.v
../../../rtl/verilog/omsp_mem_backbone.v
../../../rtl/verilog/omsp_watchdog.v
../../../rtl/verilog/omsp_dbg.v
../../../rtl/verilog/omsp_dbg_uart.v
../../../rtl/verilog/omsp_dbg_i2c.v
../../../rtl/verilog/omsp_dbg_hwbrk.v
../../../rtl/verilog/omsp_multiplier.v
../../../rtl/verilog/omsp_sync_reset.v
../../../rtl/verilog/omsp_sync_cell.v
../../../rtl/verilog/omsp_scan_mux.v
../../../rtl/verilog/omsp_and_gate.v
../../../rtl/verilog/omsp_wakeup_cell.v
../../../rtl/verilog/omsp_clock_gate.v
../../../rtl/verilog/omsp_clock_mux.v
/openmsp430/omsp_clock_module.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_module.v
//
//
// *Module Description:
// Basic clock module implementation.
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
48,87 → 48,93
module omsp_clock_module (
 
// OUTPUTs
aclk, // ACLK
aclk_en, // ACLK enable
cpu_en_s, // Enable CPU code execution (synchronous)
dbg_clk, // Debug unit clock
dbg_en_s, // Debug interface enable (synchronous)
dbg_rst, // Debug unit reset
dco_enable, // Fast oscillator enable
dco_wkup, // Fast oscillator wake-up (asynchronous)
lfxt_enable, // Low frequency oscillator enable
lfxt_wkup, // Low frequency oscillator wake-up (asynchronous)
mclk, // Main system clock
per_dout, // Peripheral data output
por, // Power-on reset
puc_pnd_set, // PUC pending set for the serial debug interface
puc_rst, // Main system reset
smclk, // SMCLK
smclk_en, // SMCLK enable
aclk, // ACLK
aclk_en, // ACLK enable
cpu_en_s, // Enable CPU code execution (synchronous)
cpu_mclk, // Main system CPU only clock
dma_mclk, // Main system DMA and/or CPU clock
dbg_clk, // Debug unit clock
dbg_en_s, // Debug interface enable (synchronous)
dbg_rst, // Debug unit reset
dco_enable, // Fast oscillator enable
dco_wkup, // Fast oscillator wake-up (asynchronous)
lfxt_enable, // Low frequency oscillator enable
lfxt_wkup, // Low frequency oscillator wake-up (asynchronous)
per_dout, // Peripheral data output
por, // Power-on reset
puc_pnd_set, // PUC pending set for the serial debug interface
puc_rst, // Main system reset
smclk, // SMCLK
smclk_en, // SMCLK enable
 
// INPUTs
cpu_en, // Enable CPU code execution (asynchronous)
cpuoff, // Turns off the CPU
dbg_cpu_reset, // Reset CPU from debug interface
dbg_en, // Debug interface enable (asynchronous)
dco_clk, // Fast oscillator (fast clock)
lfxt_clk, // Low frequency oscillator (typ 32kHz)
mclk_enable, // Main System Clock enable
mclk_wkup, // Main System Clock wake-up (asynchronous)
oscoff, // Turns off LFXT1 clock input
per_addr, // Peripheral address
per_din, // Peripheral data input
per_en, // Peripheral enable (high active)
per_we, // Peripheral write enable (high active)
reset_n, // Reset Pin (low active, asynchronous)
scan_enable, // Scan enable (active during scan shifting)
scan_mode, // Scan mode
scg0, // System clock generator 1. Turns off the DCO
scg1, // System clock generator 1. Turns off the SMCLK
wdt_reset // Watchdog-timer reset
cpu_en, // Enable CPU code execution (asynchronous)
cpuoff, // Turns off the CPU
dbg_cpu_reset, // Reset CPU from debug interface
dbg_en, // Debug interface enable (asynchronous)
dco_clk, // Fast oscillator (fast clock)
lfxt_clk, // Low frequency oscillator (typ 32kHz)
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_wkup, // Main System Clock wake-up (asynchronous)
oscoff, // Turns off LFXT1 clock input
per_addr, // Peripheral address
per_din, // Peripheral data input
per_en, // Peripheral enable (high active)
per_we, // Peripheral write enable (high active)
reset_n, // Reset Pin (low active, asynchronous)
scan_enable, // Scan enable (active during scan shifting)
scan_mode, // Scan mode
scg0, // System clock generator 1. Turns off the DCO
scg1, // System clock generator 1. Turns off the SMCLK
wdt_reset // Watchdog-timer reset
);
 
// OUTPUTs
//=========
output aclk; // ACLK
output aclk_en; // ACLK enable
output cpu_en_s; // Enable CPU code execution (synchronous)
output dbg_clk; // Debug unit clock
output dbg_en_s; // Debug unit enable (synchronous)
output dbg_rst; // Debug unit reset
output dco_enable; // Fast oscillator enable
output dco_wkup; // Fast oscillator wake-up (asynchronous)
output lfxt_enable; // Low frequency oscillator enable
output lfxt_wkup; // Low frequency oscillator wake-up (asynchronous)
output mclk; // Main system clock
output [15:0] per_dout; // Peripheral data output
output por; // Power-on reset
output puc_pnd_set; // PUC pending set for the serial debug interface
output puc_rst; // Main system reset
output smclk; // SMCLK
output smclk_en; // SMCLK enable
output aclk; // ACLK
output aclk_en; // ACLK enable
output cpu_en_s; // Enable CPU code execution (synchronous)
output cpu_mclk; // Main system CPU only clock
output dma_mclk; // Main system DMA and/or CPU clock
output dbg_clk; // Debug unit clock
output dbg_en_s; // Debug unit enable (synchronous)
output dbg_rst; // Debug unit reset
output dco_enable; // Fast oscillator enable
output dco_wkup; // Fast oscillator wake-up (asynchronous)
output lfxt_enable; // Low frequency oscillator enable
output lfxt_wkup; // Low frequency oscillator wake-up (asynchronous)
output [15:0] per_dout; // Peripheral data output
output por; // Power-on reset
output puc_pnd_set; // PUC pending set for the serial debug interface
output puc_rst; // Main system reset
output smclk; // SMCLK
output smclk_en; // SMCLK enable
 
// INPUTs
//=========
input cpu_en; // Enable CPU code execution (asynchronous)
input cpuoff; // Turns off the CPU
input dbg_cpu_reset;// Reset CPU from debug interface
input dbg_en; // Debug interface enable (asynchronous)
input dco_clk; // Fast oscillator (fast clock)
input lfxt_clk; // Low frequency oscillator (typ 32kHz)
input mclk_enable; // Main System Clock enable
input mclk_wkup; // Main System Clock wake-up (asynchronous)
input oscoff; // Turns off LFXT1 clock input
input [13:0] per_addr; // Peripheral address
input [15:0] per_din; // Peripheral data input
input per_en; // Peripheral enable (high active)
input [1:0] per_we; // Peripheral write enable (high active)
input reset_n; // Reset Pin (low active, asynchronous)
input scan_enable; // Scan enable (active during scan shifting)
input scan_mode; // Scan mode
input scg0; // System clock generator 1. Turns off the DCO
input scg1; // System clock generator 1. Turns off the SMCLK
input wdt_reset; // Watchdog-timer reset
input cpu_en; // Enable CPU code execution (asynchronous)
input cpuoff; // Turns off the CPU
input dbg_cpu_reset; // Reset CPU from debug interface
input dbg_en; // Debug interface enable (asynchronous)
input dco_clk; // Fast oscillator (fast clock)
input lfxt_clk; // Low frequency oscillator (typ 32kHz)
input mclk_dma_enable; // DMA Sub-System Clock enable
input mclk_dma_wkup; // DMA Sub-System Clock wake-up (asynchronous)
input mclk_enable; // Main System Clock enable
input mclk_wkup; // Main System Clock wake-up (asynchronous)
input oscoff; // Turns off LFXT1 clock input
input [13:0] per_addr; // Peripheral address
input [15:0] per_din; // Peripheral data input
input per_en; // Peripheral enable (high active)
input [1:0] per_we; // Peripheral write enable (high active)
input reset_n; // Reset Pin (low active, asynchronous)
input scan_enable; // Scan enable (active during scan shifting)
input scan_mode; // Scan mode
input scg0; // System clock generator 1. Turns off the DCO
input scg1; // System clock generator 1. Turns off the SMCLK
input wdt_reset; // Watchdog-timer reset
 
 
//=============================================================================
196,17 → 202,55
 
`ifdef ASIC_CLOCKING
`ifdef ACLK_DIVIDER
wire [7:0] divax_mask = 8'h30;
wire [7:0] divax_mask = 8'h30;
`else
wire [7:0] divax_mask = 8'h00;
wire [7:0] divax_mask = 8'h00;
`endif
`ifdef DMA_IF_EN
`ifdef CPUOFF_EN
wire [7:0] dma_cpuoff_mask = 8'h01;
`else
wire [7:0] dma_cpuoff_mask = 8'h00;
`endif
`ifdef OSCOFF_EN
wire [7:0] dma_oscoff_mask = 8'h02;
`else
wire [7:0] dma_oscoff_mask = 8'h00;
`endif
`ifdef SCG0_EN
wire [7:0] dma_scg0_mask = 8'h04;
`else
wire [7:0] dma_scg0_mask = 8'h00;
`endif
`ifdef SCG1_EN
wire [7:0] dma_scg1_mask = 8'h08;
`else
wire [7:0] dma_scg1_mask = 8'h00;
`endif
`else
wire [7:0] dma_cpuoff_mask = 8'h00;
wire [7:0] dma_scg0_mask = 8'h00;
wire [7:0] dma_scg1_mask = 8'h00;
wire [7:0] dma_oscoff_mask = 8'h00;
`endif
`else
wire [7:0] divax_mask = 8'h30;
wire [7:0] divax_mask = 8'h30;
wire [7:0] dma_cpuoff_mask = 8'h00;
wire [7:0] dma_scg0_mask = 8'h00;
`ifdef DMA_IF_EN
wire [7:0] dma_oscoff_mask = 8'h02;
wire [7:0] dma_scg1_mask = 8'h08;
`else
wire [7:0] dma_oscoff_mask = 8'h00;
wire [7:0] dma_scg1_mask = 8'h00;
`endif
`endif
 
always @ (posedge mclk or posedge puc_rst)
always @ (posedge dma_mclk or posedge puc_rst)
if (puc_rst) bcsctl1 <= 8'h00;
else if (bcsctl1_wr) bcsctl1 <= bcsctl1_nxt & divax_mask; // Mask unused bits
else if (bcsctl1_wr) bcsctl1 <= bcsctl1_nxt & (divax_mask |
dma_cpuoff_mask | dma_oscoff_mask |
dma_scg0_mask | dma_scg1_mask ); // Mask unused bits
 
 
// BCSCTL2 Register
241,7 → 285,7
wire [7:0] divsx_mask = 8'h06;
`endif
 
always @ (posedge mclk or posedge puc_rst)
always @ (posedge dma_mclk or posedge puc_rst)
if (puc_rst) bcsctl2 <= 8'h00;
else if (bcsctl2_wr) bcsctl2 <= bcsctl2_nxt & ( sels_mask | divsx_mask |
selmx_mask | divmx_mask); // Mask unused bits
265,9 → 309,79
 
`ifdef ASIC_CLOCKING
wire cpuoff_and_mclk_enable;
omsp_and_gate and_cpuoff_mclk_en (.y(cpuoff_and_mclk_enable), .a(cpuoff), .b(mclk_enable));
wire cpuoff_and_mclk_dma_enable;
wire cpuoff_and_mclk_dma_wkup;
`ifdef CPUOFF_EN
omsp_and_gate and_cpuoff_mclk_en (.y(cpuoff_and_mclk_enable), .a(cpuoff), .b(mclk_enable));
`ifdef DMA_IF_EN
omsp_and_gate and_cpuoff_mclk_dma_en (.y(cpuoff_and_mclk_dma_enable), .a(bcsctl1[`DMA_CPUOFF]), .b(mclk_dma_enable));
omsp_and_gate and_cpuoff_mclk_dma_wkup (.y(cpuoff_and_mclk_dma_wkup), .a(bcsctl1[`DMA_CPUOFF]), .b(mclk_dma_wkup));
`else
assign cpuoff_and_mclk_dma_enable = 1'b0;
assign cpuoff_and_mclk_dma_wkup = 1'b0;
`endif
`else
assign cpuoff_and_mclk_enable = 1'b0;
assign cpuoff_and_mclk_dma_enable = 1'b0;
assign cpuoff_and_mclk_dma_wkup = 1'b0;
wire UNUSED_cpuoff = cpuoff;
`endif
 
wire scg0_and_mclk_dma_enable;
wire scg0_and_mclk_dma_wkup;
`ifdef DMA_IF_EN
`ifdef SCG0_EN
omsp_and_gate and_scg0_mclk_dma_en (.y(scg0_and_mclk_dma_enable), .a(bcsctl1[`DMA_SCG0]), .b(mclk_dma_enable));
omsp_and_gate and_scg0_mclk_dma_wkup (.y(scg0_and_mclk_dma_wkup), .a(bcsctl1[`DMA_SCG0]), .b(mclk_dma_wkup));
`else
assign scg0_and_mclk_dma_enable = 1'b0;
assign scg0_and_mclk_dma_wkup = 1'b0;
wire UNUSED_scg0_mclk_dma_wkup = mclk_dma_wkup;
`endif
`else
assign scg0_and_mclk_dma_enable = 1'b0;
assign scg0_and_mclk_dma_wkup = 1'b0;
`endif
 
wire scg1_and_mclk_dma_enable;
wire scg1_and_mclk_dma_wkup;
`ifdef DMA_IF_EN
`ifdef SCG1_EN
omsp_and_gate and_scg1_mclk_dma_en (.y(scg1_and_mclk_dma_enable), .a(bcsctl1[`DMA_SCG1]), .b(mclk_dma_enable));
omsp_and_gate and_scg1_mclk_dma_wkup (.y(scg1_and_mclk_dma_wkup), .a(bcsctl1[`DMA_SCG1]), .b(mclk_dma_wkup));
`else
assign scg1_and_mclk_dma_enable = 1'b0;
assign scg1_and_mclk_dma_wkup = 1'b0;
wire UNUSED_scg1_mclk_dma_wkup = mclk_dma_wkup;
`endif
`else
assign scg1_and_mclk_dma_enable = 1'b0;
assign scg1_and_mclk_dma_wkup = 1'b0;
`endif
 
wire oscoff_and_mclk_dma_enable;
wire oscoff_and_mclk_dma_wkup;
`ifdef DMA_IF_EN
`ifdef OSCOFF_EN
omsp_and_gate and_oscoff_mclk_dma_en (.y(oscoff_and_mclk_dma_enable), .a(bcsctl1[`DMA_OSCOFF]), .b(mclk_dma_enable));
omsp_and_gate and_oscoff_mclk_dma_wkup (.y(oscoff_and_mclk_dma_wkup), .a(bcsctl1[`DMA_OSCOFF]), .b(mclk_dma_wkup));
`else
assign oscoff_and_mclk_dma_enable = 1'b0;
assign oscoff_and_mclk_dma_wkup = 1'b0;
wire UNUSED_oscoff_mclk_dma_wkup= mclk_dma_wkup;
`endif
`else
assign oscoff_and_mclk_dma_enable = 1'b0;
assign oscoff_and_mclk_dma_wkup = 1'b0;
wire UNUSED_mclk_dma_wkup = mclk_dma_wkup;
`endif
`else
wire UNUSED_cpuoff = cpuoff;
wire UNUSED_mclk_enable = mclk_enable;
wire UNUSED_mclk_dma_wkup = mclk_dma_wkup;
`endif
 
 
//-----------------------------------------------------------
// 5.1) HIGH SPEED SYSTEM CLOCK GENERATOR (DCO_CLK)
//-----------------------------------------------------------
297,7 → 411,7
wire dco_disable_by_cpu_en;
wire dco_enable_nxt;
omsp_and_gate and_dco_dis1 (.y(cpu_enabled_with_dco), .a(~bcsctl2[`SELMx]), .b(cpuoff_and_mclk_enable));
omsp_and_gate and_dco_dis2 (.y(dco_not_enabled_by_dbg), .a(~dbg_en_s), .b(~cpu_enabled_with_dco));
omsp_and_gate and_dco_dis2 (.y(dco_not_enabled_by_dbg), .a(~dbg_en_s), .b(~(cpu_enabled_with_dco | scg0_and_mclk_dma_enable)));
omsp_and_gate and_dco_dis3 (.y(dco_disable_by_scg0), .a(scg0), .b(dco_not_enabled_by_dbg));
omsp_and_gate and_dco_dis4 (.y(dco_disable_by_cpu_en), .a(~cpu_en_s), .b(~mclk_enable));
omsp_and_gate and_dco_dis5 (.y(dco_enable_nxt), .a(~dco_disable_by_scg0), .b(~dco_disable_by_cpu_en));
318,7 → 432,6
.rst (por)
);
`else
 
assign dco_enable = ~dco_disable;
`endif
 
330,25 → 443,25
omsp_and_gate and_dco_mclk_wkup (.y(dco_mclk_wkup), .a(mclk_wkup), .b(~bcsctl2[`SELMx]));
omsp_and_gate and_dco_en_wkup (.y(dco_en_wkup), .a(~dco_enable), .b(dco_enable_nxt));
 
wire dco_wkup_set = dco_mclk_wkup | dco_en_wkup | cpu_en_wkup;
wire dco_wkup_set = dco_mclk_wkup | scg0_and_mclk_dma_wkup | dco_en_wkup | cpu_en_wkup;
 
// Scan MUX for the asynchronous SET
wire dco_wkup_set_scan;
omsp_scan_mux scan_mux_dco_wkup (
.scan_mode (scan_mode),
.data_in_scan (por_a),
.data_in_func (dco_wkup_set | por),
.data_out (dco_wkup_set_scan)
);
.scan_mode (scan_mode),
.data_in_scan (por_a),
.data_in_func (dco_wkup_set | por),
.data_out (dco_wkup_set_scan)
);
 
// Scan MUX to increase coverage
// Scan MUX to increase coverage
wire dco_wkup_clear;
omsp_scan_mux scan_mux_dco_wkup_clear (
.scan_mode (scan_mode),
.data_in_scan (dco_wkup_set),
.data_in_func (1'b1),
.data_out (dco_wkup_clear)
);
.scan_mode (scan_mode),
.data_in_scan (dco_wkup_set),
.data_in_func (1'b1),
.data_out (dco_wkup_clear)
);
 
// The wakeup is asynchronously set, synchronously released
wire dco_wkup_n;
362,8 → 475,10
omsp_and_gate and_dco_wkup (.y(dco_wkup), .a(~dco_wkup_n), .b(cpu_en));
 
`else
assign dco_enable = 1'b1;
assign dco_wkup = 1'b1;
assign dco_enable = 1'b1;
assign dco_wkup = 1'b1;
wire UNUSED_scg0 = scg0;
wire UNUSED_cpu_en_wkup1 = cpu_en_wkup;
`endif
 
 
390,7 → 505,7
wire lfxt_disable_by_cpu_en;
wire lfxt_enable_nxt;
omsp_and_gate and_lfxt_dis1 (.y(cpu_enabled_with_lfxt), .a(bcsctl2[`SELMx]), .b(cpuoff_and_mclk_enable));
omsp_and_gate and_lfxt_dis2 (.y(lfxt_not_enabled_by_dbg), .a(~dbg_en_s), .b(~cpu_enabled_with_lfxt));
omsp_and_gate and_lfxt_dis2 (.y(lfxt_not_enabled_by_dbg), .a(~dbg_en_s), .b(~(cpu_enabled_with_lfxt | oscoff_and_mclk_dma_enable)));
omsp_and_gate and_lfxt_dis3 (.y(lfxt_disable_by_oscoff), .a(oscoff), .b(lfxt_not_enabled_by_dbg));
omsp_and_gate and_lfxt_dis4 (.y(lfxt_disable_by_cpu_en), .a(~cpu_en_s), .b(~mclk_enable));
omsp_and_gate and_lfxt_dis5 (.y(lfxt_enable_nxt), .a(~lfxt_disable_by_oscoff), .b(~lfxt_disable_by_cpu_en));
418,25 → 533,25
omsp_and_gate and_lfxt_mclk_wkup (.y(lfxt_mclk_wkup), .a(mclk_wkup), .b(bcsctl2[`SELMx]));
omsp_and_gate and_lfxt_en_wkup (.y(lfxt_en_wkup), .a(~lfxt_enable), .b(lfxt_enable_nxt));
 
wire lfxt_wkup_set = lfxt_mclk_wkup | lfxt_en_wkup | cpu_en_wkup;
wire lfxt_wkup_set = lfxt_mclk_wkup | oscoff_and_mclk_dma_wkup | lfxt_en_wkup | cpu_en_wkup;
 
// Scan MUX for the asynchronous SET
wire lfxt_wkup_set_scan;
omsp_scan_mux scan_mux_lfxt_wkup (
.scan_mode (scan_mode),
.data_in_scan (por_a),
.data_in_func (lfxt_wkup_set | por),
.data_out (lfxt_wkup_set_scan)
);
.scan_mode (scan_mode),
.data_in_scan (por_a),
.data_in_func (lfxt_wkup_set | por),
.data_out (lfxt_wkup_set_scan)
);
 
// Scan MUX to increase coverage
// Scan MUX to increase coverage
wire lfxt_wkup_clear;
omsp_scan_mux scan_mux_lfxt_wkup_clear (
.scan_mode (scan_mode),
.data_in_scan (lfxt_wkup_set),
.data_in_func (1'b1),
.data_out (lfxt_wkup_clear)
);
.scan_mode (scan_mode),
.data_in_scan (lfxt_wkup_set),
.data_in_func (1'b1),
.data_out (lfxt_wkup_clear)
);
 
// The wakeup is asynchronously set, synchronously released
wire lfxt_wkup_n;
450,8 → 565,11
omsp_and_gate and_lfxt_wkup (.y(lfxt_wkup), .a(~lfxt_wkup_n), .b(cpu_en));
 
`else
assign lfxt_enable = 1'b1;
assign lfxt_wkup = 1'b0;
assign lfxt_enable = 1'b1;
assign lfxt_wkup = 1'b0;
wire UNUSED_oscoff = oscoff;
wire UNUSED_cpuoff_and_mclk_enable = cpuoff_and_mclk_enable;
wire UNUSED_cpu_en_wkup2 = cpu_en_wkup;
`endif
 
 
465,22 → 583,22
omsp_sync_cell sync_cell_lfxt_clk (
.data_out (lfxt_clk_s),
.data_in (lfxt_clk),
.clk (mclk),
.clk (nodiv_mclk),
.rst (por)
);
 
reg lfxt_clk_dly;
always @ (posedge mclk or posedge por)
 
always @ (posedge nodiv_mclk or posedge por)
if (por) lfxt_clk_dly <= 1'b0;
else lfxt_clk_dly <= lfxt_clk_s;
else lfxt_clk_dly <= lfxt_clk_s;
 
wire lfxt_clk_en = (lfxt_clk_s & ~lfxt_clk_dly) & ~(oscoff & ~bcsctl2[`SELS]);
wire lfxt_clk_en = (lfxt_clk_s & ~lfxt_clk_dly) & (~oscoff | (mclk_dma_enable & bcsctl1[`DMA_OSCOFF]));
assign lfxt_enable = 1'b1;
assign lfxt_wkup = 1'b0;
`endif
`endif
 
 
//=============================================================================
// 6) CLOCK GENERATION
//=============================================================================
487,7 → 605,7
 
//-----------------------------------------------------------
// 6.1) GLOBAL CPU ENABLE
//-----------------------------------------------------------
//----------------------------------------------------------
// ACLK and SMCLK are directly switched-off
// with the cpu_en pin (after synchronization).
// MCLK will be switched off once the CPU reaches
554,19 → 672,30
.clk_in1 (lfxt_clk),
.reset (por),
.scan_mode (scan_mode),
.select (bcsctl2[`SELMx])
.select_in (bcsctl2[`SELMx])
);
`else
assign nodiv_mclk = dco_clk;
`endif
assign nodiv_mclk_n = ~nodiv_mclk;
 
 
// Wakeup synchronizer
//----------------------------
wire cpuoff_and_mclk_dma_wkup_s;
wire mclk_wkup_s;
 
`ifdef CPUOFF_EN
`ifdef DMA_IF_EN
omsp_sync_cell sync_cell_mclk_dma_wkup (
.data_out (cpuoff_and_mclk_dma_wkup_s),
.data_in (cpuoff_and_mclk_dma_wkup),
.clk (nodiv_mclk),
.rst (puc_rst)
);
`else
assign cpuoff_and_mclk_dma_wkup_s = 1'b0;
`endif
omsp_sync_cell sync_cell_mclk_wkup (
.data_out (mclk_wkup_s),
.data_in (mclk_wkup),
574,7 → 703,9
.rst (puc_rst)
);
`else
assign mclk_wkup_s = 1'b0;
assign cpuoff_and_mclk_dma_wkup_s = 1'b0;
assign mclk_wkup_s = 1'b0;
wire UNUSED_mclk_wkup = mclk_wkup;
`endif
 
 
584,11 → 715,13
// comes from the same clock domain.
 
`ifdef CPUOFF_EN
wire mclk_active = mclk_enable | mclk_wkup_s | (dbg_en_s & cpu_en_s);
wire mclk_active = mclk_enable | mclk_wkup_s | (dbg_en_s & cpu_en_s);
wire mclk_dma_active = cpuoff_and_mclk_dma_enable | cpuoff_and_mclk_dma_wkup_s | mclk_active;
`else
wire mclk_active = 1'b1;
wire mclk_active = 1'b1;
wire mclk_dma_active = 1'b1;
`endif
 
`ifdef MCLK_DIVIDER
reg [2:0] mclk_div;
always @ (posedge nodiv_mclk or posedge puc_rst)
595,12 → 728,17
if (puc_rst) mclk_div <= 3'h0;
else if ((bcsctl2[`DIVMx]!=2'b00)) mclk_div <= mclk_div+3'h1;
 
wire mclk_div_en = mclk_active & ((bcsctl2[`DIVMx]==2'b00) ? 1'b1 :
(bcsctl2[`DIVMx]==2'b01) ? mclk_div[0] :
(bcsctl2[`DIVMx]==2'b10) ? &mclk_div[1:0] :
&mclk_div[2:0]);
wire mclk_div_sel = (bcsctl2[`DIVMx]==2'b00) ? 1'b1 :
(bcsctl2[`DIVMx]==2'b01) ? mclk_div[0] :
(bcsctl2[`DIVMx]==2'b10) ? &mclk_div[1:0] :
&mclk_div[2:0] ;
 
wire mclk_div_en = mclk_active & mclk_div_sel;
wire mclk_dma_div_en = mclk_dma_active & mclk_div_sel;
 
`else
wire mclk_div_en = mclk_active;
wire mclk_div_en = mclk_active;
wire mclk_dma_div_en = mclk_dma_active;
`endif
 
 
609,13 → 747,24
`ifdef MCLK_CGATE
 
omsp_clock_gate clock_gate_mclk (
.gclk (mclk),
.gclk (cpu_mclk),
.clk (nodiv_mclk),
.enable (mclk_div_en),
.scan_enable (scan_enable)
);
`ifdef DMA_IF_EN
omsp_clock_gate clock_gate_dma_mclk (
.gclk (dma_mclk),
.clk (nodiv_mclk),
.enable (mclk_dma_div_en),
.scan_enable (scan_enable)
);
`else
assign dma_mclk = cpu_mclk;
`endif
`else
assign mclk = nodiv_mclk;
assign cpu_mclk = nodiv_mclk;
assign dma_mclk = nodiv_mclk;
`endif
 
 
632,9 → 781,12
 
wire nodiv_aclk = lfxt_clk;
 
// Synchronizers
//------------------------------------------------------
 
// Local Reset synchronizer
wire puc_lfxt_noscan_n;
wire puc_lfxt_rst;
wire puc_lfxt_noscan_n;
omsp_sync_cell sync_cell_puc_lfxt (
.data_out (puc_lfxt_noscan_n),
.data_in (1'b1),
648,6 → 800,19
.data_out (puc_lfxt_rst)
);
 
// If the OSCOFF mode is enabled synchronize OSCOFF signal
wire oscoff_s;
`ifdef OSCOFF_EN
omsp_sync_cell sync_cell_oscoff (
.data_out (oscoff_s),
.data_in (oscoff),
.clk (nodiv_aclk),
.rst (puc_lfxt_rst)
);
`else
assign oscoff_s = 1'b0;
`endif
 
// Local synchronizer for the bcsctl1.DIVAx configuration
// (note that we can live with a full bus synchronizer as
// it won't hurt if we get a wrong DIVAx value for a single clock cycle)
656,45 → 821,58
always @ (posedge nodiv_aclk or posedge puc_lfxt_rst)
if (puc_lfxt_rst)
begin
divax_s <= 2'h0;
divax_ss <= 2'h0;
divax_s <= 2'h0;
divax_ss <= 2'h0;
end
else
begin
divax_s <= bcsctl1[`DIVAx];
divax_ss <= divax_s;
divax_s <= bcsctl1[`DIVAx];
divax_ss <= divax_s;
end
 
// If the OSCOFF mode is enabled synchronize OSCOFF signal
wire oscoff_s;
`ifdef OSCOFF_EN
omsp_sync_cell sync_cell_oscoff (
.data_out (oscoff_s),
.data_in (oscoff),
.clk (nodiv_aclk),
.rst (puc_lfxt_rst)
);
`else
assign oscoff_s = 1'b0;
`endif
`else
wire puc_lfxt_rst = puc_rst;
wire nodiv_aclk = dco_clk;
wire [1:0] divax_ss = bcsctl1[`DIVAx];
wire oscoff_s = oscoff;
`endif
`endif
 
// Divider
// Wakeup synchronizer
//----------------------------
wire oscoff_and_mclk_dma_enable_s;
 
`ifdef OSCOFF_EN
`ifdef DMA_IF_EN
omsp_sync_cell sync_cell_aclk_dma_wkup (
.data_out (oscoff_and_mclk_dma_enable_s),
.data_in (oscoff_and_mclk_dma_wkup | oscoff_and_mclk_dma_enable),
.clk (nodiv_aclk),
.rst (puc_lfxt_rst)
);
`else
assign oscoff_and_mclk_dma_enable_s = 1'b0;
`endif
`else
assign oscoff_and_mclk_dma_enable_s = 1'b0;
`endif
 
// Clock Divider
//----------------------------
 
wire aclk_active = cpu_en_aux_s & (~oscoff_s | oscoff_and_mclk_dma_enable_s);
 
reg [2:0] aclk_div;
always @ (posedge nodiv_aclk or posedge puc_lfxt_rst)
if (puc_lfxt_rst) aclk_div <= 3'h0;
else if ((divax_ss!=2'b00)) aclk_div <= aclk_div+3'h1;
 
wire aclk_div_en = cpu_en_aux_s & ~oscoff_s & ((divax_ss==2'b00) ? 1'b1 :
(divax_ss==2'b01) ? aclk_div[0] :
(divax_ss==2'b10) ? &aclk_div[1:0] :
&aclk_div[2:0]);
wire aclk_div_sel = ((divax_ss==2'b00) ? 1'b1 :
(divax_ss==2'b01) ? aclk_div[0] :
(divax_ss==2'b10) ? &aclk_div[1:0] :
&aclk_div[2:0]);
 
wire aclk_div_en = aclk_active & aclk_div_sel;
 
// Clock gate
omsp_clock_gate clock_gate_aclk (
.gclk (aclk),
703,18 → 881,23
.scan_enable (scan_enable)
);
 
`else
`else
`ifdef LFXT_DOMAIN
assign aclk = lfxt_clk;
assign aclk = lfxt_clk;
`else
assign aclk = dco_clk;
assign aclk = dco_clk;
`endif
wire UNUSED_cpu_en_aux_s = cpu_en_aux_s;
`endif
 
assign aclk_en = 1'b1;
`ifdef LFXT_DOMAIN
`else
wire UNUSED_lfxt_clk = lfxt_clk;
`endif
 
assign aclk_en = 1'b1;
 
 
// FPGA MODE
//----------------------------
`else
725,17 → 908,21
(bcsctl1[`DIVAx]==2'b10) ? &aclk_div[1:0] :
&aclk_div[2:0]);
 
always @ (posedge mclk or posedge puc_rst)
always @ (posedge nodiv_mclk or posedge puc_rst)
if (puc_rst) aclk_div <= 3'h0;
else if ((bcsctl1[`DIVAx]!=2'b00) & lfxt_clk_en) aclk_div <= aclk_div+3'h1;
 
always @ (posedge mclk or posedge puc_rst)
always @ (posedge nodiv_mclk or posedge puc_rst)
if (puc_rst) aclk_en <= 1'b0;
else aclk_en <= aclk_en_nxt & cpu_en_s;
 
assign aclk = mclk;
assign aclk = nodiv_mclk;
 
wire UNUSED_scan_enable = scan_enable;
wire UNUSED_scan_mode = scan_mode;
`endif
 
 
//-----------------------------------------------------------
// 6.4) SMCLK GENERATION
//-----------------------------------------------------------
749,7 → 936,7
.clk_in1 (lfxt_clk),
.reset (por),
.scan_mode (scan_mode),
.select (bcsctl2[`SELS])
.select_in (bcsctl2[`SELS])
);
`else
assign nodiv_smclk = dco_clk;
761,11 → 948,11
`ifdef ASIC_CLOCKING
`ifdef SMCLK_MUX
 
// Synchronizers
// SMCLK_MUX Synchronizers
//------------------------------------------------------
// When the SMCLK MUX is enabled, the reset and DIVSx
// and SCG1 signals must be synchronized, otherwise not.
 
// Local Reset synchronizer
wire puc_sm_noscan_n;
wire puc_sm_rst;
783,8 → 970,8
);
 
// SCG1 synchronizer
wire scg1_s;
`ifdef SCG1_EN
wire scg1_s;
omsp_sync_cell sync_cell_scg1 (
.data_out (scg1_s),
.data_in (scg1),
792,7 → 979,9
.rst (puc_sm_rst)
);
`else
wire scg1_s = 1'b0;
assign scg1_s = 1'b0;
wire UNUSED_scg1 = scg1;
wire UNUSED_puc_sm_rst = puc_sm_rst;
`endif
 
`ifdef SMCLK_DIVIDER
804,47 → 993,79
always @ (posedge nodiv_smclk or posedge puc_sm_rst)
if (puc_sm_rst)
begin
divsx_s <= 2'h0;
divsx_ss <= 2'h0;
end
divsx_s <= 2'h0;
divsx_ss <= 2'h0;
end
else
begin
divsx_s <= bcsctl2[`DIVSx];
divsx_ss <= divsx_s;
end
begin
divsx_s <= bcsctl2[`DIVSx];
divsx_ss <= divsx_s;
end
`endif
`else
 
`else
 
wire puc_sm_rst = puc_rst;
wire [1:0] divsx_ss = bcsctl2[`DIVSx];
wire scg1_s = scg1;
`endif
 
// Wakeup synchronizer
//----------------------------
wire scg1_and_mclk_dma_enable_s;
 
`ifdef SCG1_EN
`ifdef DMA_IF_EN
`ifdef SMCLK_MUX
omsp_sync_cell sync_cell_smclk_dma_wkup (
.data_out (scg1_and_mclk_dma_enable_s),
.data_in (scg1_and_mclk_dma_wkup | scg1_and_mclk_dma_enable),
.clk (nodiv_smclk),
.rst (puc_sm_rst)
);
`else
wire scg1_and_mclk_dma_wkup_s;
omsp_sync_cell sync_cell_smclk_dma_wkup (
.data_out (scg1_and_mclk_dma_wkup_s),
.data_in (scg1_and_mclk_dma_wkup),
.clk (nodiv_smclk),
.rst (puc_sm_rst)
);
assign scg1_and_mclk_dma_enable_s = scg1_and_mclk_dma_wkup_s | scg1_and_mclk_dma_enable;
`endif
`else
assign scg1_and_mclk_dma_enable_s = 1'b0;
`endif
`else
assign scg1_and_mclk_dma_enable_s = 1'b0;
`endif
 
 
// Clock Divider
//----------------------------
`ifdef SCG1_EN
wire smclk_active = cpu_en_sm_s & (~scg1_s | scg1_and_mclk_dma_enable_s);
`else
wire smclk_active = cpu_en_sm_s;
`endif
 
`ifdef SMCLK_DIVIDER
 
reg [2:0] smclk_div;
always @ (posedge nodiv_smclk or posedge puc_sm_rst)
if (puc_sm_rst) smclk_div <= 3'h0;
else if ((divsx_ss!=2'b00)) smclk_div <= smclk_div+3'h1;
 
wire smclk_div_en = cpu_en_sm_s & ~scg1_s & ((divsx_ss==2'b00) ? 1'b1 :
(divsx_ss==2'b01) ? smclk_div[0] :
(divsx_ss==2'b10) ? &smclk_div[1:0] :
&smclk_div[2:0]);
wire smclk_div_sel = ((divsx_ss==2'b00) ? 1'b1 :
(divsx_ss==2'b01) ? smclk_div[0] :
(divsx_ss==2'b10) ? &smclk_div[1:0] :
&smclk_div[2:0]);
 
wire smclk_div_en = smclk_active & smclk_div_sel;
`else
`ifdef SCG1_EN
wire smclk_div_en = cpu_en_sm_s & ~scg1_s;
`else
wire smclk_div_en = cpu_en_sm_s;
`endif
wire smclk_div_en = smclk_active;
`endif
 
 
// Generate sub-system clock
//----------------------------
`ifdef SMCLK_CGATE
857,7 → 1078,7
`else
assign smclk = nodiv_smclk;
`endif
 
assign smclk_en = 1'b1;
 
 
867,22 → 1088,23
reg smclk_en;
reg [2:0] smclk_div;
 
wire smclk_in = ~scg1 & (bcsctl2[`SELS] ? lfxt_clk_en : 1'b1);
wire smclk_in = (scg1 & ~(mclk_dma_enable & bcsctl1[`DMA_SCG1])) ? 1'b0 :
bcsctl2[`SELS] ? lfxt_clk_en : 1'b1;
 
wire smclk_en_nxt = smclk_in & ((bcsctl2[`DIVSx]==2'b00) ? 1'b1 :
(bcsctl2[`DIVSx]==2'b01) ? smclk_div[0] :
(bcsctl2[`DIVSx]==2'b10) ? &smclk_div[1:0] :
&smclk_div[2:0]);
always @ (posedge mclk or posedge puc_rst)
 
always @ (posedge nodiv_mclk or posedge puc_rst)
if (puc_rst) smclk_en <= 1'b0;
else smclk_en <= smclk_en_nxt & cpu_en_s;
 
always @ (posedge mclk or posedge puc_rst)
always @ (posedge nodiv_mclk or posedge puc_rst)
if (puc_rst) smclk_div <= 3'h0;
else if ((bcsctl2[`DIVSx]!=2'b00) & smclk_in) smclk_div <= smclk_div+3'h1;
 
wire smclk = mclk;
wire smclk = nodiv_mclk;
 
`endif
 
898,21 → 1120,23
omsp_sync_cell sync_cell_dbg_en (
.data_out (dbg_en_n_s),
.data_in (~dbg_en),
.clk (mclk),
.clk (cpu_mclk),
.rst (por)
);
assign dbg_en_s = ~dbg_en_n_s;
wire dbg_rst_nxt = dbg_en_n_s;
assign dbg_en_s = ~dbg_en_n_s;
wire dbg_rst_nxt = dbg_en_n_s;
`else
assign dbg_en_s = dbg_en;
wire dbg_rst_nxt = ~dbg_en;
assign dbg_en_s = dbg_en;
wire dbg_rst_nxt = ~dbg_en;
`endif
`else
assign dbg_en_s = 1'b0;
wire dbg_rst_nxt = 1'b0;
assign dbg_en_s = 1'b0;
wire dbg_rst_nxt = 1'b0;
wire UNUSED_dbg_en = dbg_en;
`endif
 
 
 
// Serial Debug Interface Clock gate
//------------------------------------------------
`ifdef DBG_EN
919,7 → 1143,7
`ifdef ASIC_CLOCKING
omsp_clock_gate clock_gate_dbg_clk (
.gclk (dbg_clk),
.clk (mclk),
.clk (cpu_mclk),
.enable (dbg_en_s),
.scan_enable (scan_enable)
);
944,7 → 1168,7
// Note: releasing the DBG_RST before PUC is particularly important in order
// to allow the sdi interface to halt the cpu immediately after a PUC.
//
 
// Generate synchronized POR to MCLK domain
//------------------------------------------
 
977,7 → 1201,7
 
// Reset Generation
reg dbg_rst_noscan;
always @ (posedge mclk or posedge por)
always @ (posedge cpu_mclk or posedge por)
if (por) dbg_rst_noscan <= 1'b1;
else dbg_rst_noscan <= dbg_rst_nxt;
 
1030,7 → 1254,7
omsp_sync_cell sync_cell_puc (
.data_out (puc_noscan_n),
.data_in (~puc_s),
.clk (mclk),
.clk (cpu_mclk),
.rst (puc_a_scan)
);
 
/openmsp430/omsp_watchdog.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_watchdog.v
//
//
// *Module Description:
// Watchdog Timer
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
157,7 → 157,7
// WDTCTL Register
//-----------------
// WDTNMI is not implemented and therefore masked
 
reg [7:0] wdtctl;
 
wire wdtctl_wr = reg_wr[WDTCTL];
167,7 → 167,8
omsp_clock_gate clock_gate_wdtctl (.gclk(mclk_wdtctl),
.clk (mclk), .enable(wdtctl_wr), .scan_enable(scan_enable));
`else
wire mclk_wdtctl = mclk;
wire UNUSED_scan_enable = scan_enable;
wire mclk_wdtctl = mclk;
`endif
 
`ifdef NMI
187,7 → 188,7
`endif
 
parameter [7:0] WDTCTL_MASK = (8'b1001_0011 | WDTSSEL_MASK | WDTNMIES_MASK);
 
always @ (posedge mclk_wdtctl or posedge puc_rst)
if (puc_rst) wdtctl <= 8'h00;
`ifdef CLOCK_GATING
242,19 → 243,21
.clk_in1 (aclk),
.reset (puc_rst),
.scan_mode (scan_mode),
.select (wdtctl[2])
.select_in (wdtctl[2])
);
`else
`ifdef WATCHDOG_NOMUX_ACLK
assign wdt_clk = aclk;
assign wdt_clk = aclk;
wire UNUSED_smclk = smclk;
`else
assign wdt_clk = smclk;
wire UNUSED_aclk = aclk;
assign wdt_clk = smclk;
`endif
`endif
 
// Reset synchronizer for the watchdog local clock domain
//--------------------------------------------------------
 
wire wdt_rst_noscan;
wire wdt_rst;
 
272,8 → 275,8
.data_in_func (wdt_rst_noscan),
.data_out (wdt_rst)
);
 
 
// Watchog counter clear (synchronization)
//-----------------------------------------
 
423,12 → 426,12
// Watchdog wakeup cell
wire wdt_wkup_pre;
omsp_wakeup_cell wakeup_cell_wdog (
.wkup_out (wdt_wkup_pre), // Wakup signal (asynchronous)
.scan_clk (mclk), // Scan clock
.scan_mode (scan_mode), // Scan mode
.scan_rst (puc_rst), // Scan reset
.wkup_clear (wdtifg_clr_reg), // Glitch free wakeup event clear
.wkup_event (wdtqn_edge_reg) // Glitch free asynchronous wakeup event
.wkup_out (wdt_wkup_pre), // Wakup signal (asynchronous)
.scan_clk (mclk), // Scan clock
.scan_mode (scan_mode), // Scan mode
.scan_rst (puc_rst), // Scan reset
.wkup_clear (wdtifg_clr_reg), // Glitch free wakeup event clear
.wkup_event (wdtqn_edge_reg) // Glitch free asynchronous wakeup event
);
 
// When not in HOLD, the watchdog can generate a wakeup when:
471,7 → 474,11
else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
 
 
// LINT cleanup
wire UNUSED_smclk_en = smclk_en;
wire UNUSED_aclk_en = aclk_en;
 
 
//=============================================================================
// 6) WATCHDOG TIMER (FPGA IMPLEMENTATION)
//=============================================================================
497,7 → 504,7
else if (wdtcnt_clr) wdtcnt <= 16'h0000;
else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt;
 
 
// Interval selection mux
//--------------------------
reg wdtqn;
545,9 → 552,13
else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
 
 
// LINT cleanup
wire UNUSED_scan_mode = scan_mode;
wire UNUSED_smclk = smclk;
wire UNUSED_aclk = aclk;
`endif
wire [15:0] UNUSED_per_din = per_din;
 
 
endmodule // omsp_watchdog
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_mem_backbone.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_mem_backbone.v
//
//
// *Module Description:
// Memory interface backbone (decoder + arbiter)
//
48,165 → 48,279
module omsp_mem_backbone (
 
// OUTPUTs
dbg_mem_din, // Debug unit Memory data input
dmem_addr, // Data Memory address
dmem_cen, // Data Memory chip enable (low active)
dmem_din, // Data Memory data input
dmem_wen, // Data Memory write enable (low active)
eu_mdb_in, // Execution Unit Memory data bus input
fe_mdb_in, // Frontend Memory data bus input
fe_pmem_wait, // Frontend wait for Instruction fetch
per_addr, // Peripheral address
per_din, // Peripheral data input
per_we, // Peripheral write enable (high active)
per_en, // Peripheral enable (high active)
pmem_addr, // Program Memory address
pmem_cen, // Program Memory chip enable (low active)
pmem_din, // Program Memory data input (optional)
pmem_wen, // Program Memory write enable (low active) (optional)
cpu_halt_cmd, // Halt CPU command
dbg_mem_din, // Debug unit Memory data input
dmem_addr, // Data Memory address
dmem_cen, // Data Memory chip enable (low active)
dmem_din, // Data Memory data input
dmem_wen, // Data Memory write enable (low active)
eu_mdb_in, // Execution Unit Memory data bus input
fe_mdb_in, // Frontend Memory data bus input
fe_pmem_wait, // Frontend wait for Instruction fetch
dma_dout, // Direct Memory Access data output
dma_ready, // Direct Memory Access is complete
dma_resp, // Direct Memory Access response (0:Okay / 1:Error)
per_addr, // Peripheral address
per_din, // Peripheral data input
per_we, // Peripheral write enable (high active)
per_en, // Peripheral enable (high active)
pmem_addr, // Program Memory address
pmem_cen, // Program Memory chip enable (low active)
pmem_din, // Program Memory data input (optional)
pmem_wen, // Program Memory write enable (low active) (optional)
 
// INPUTs
dbg_halt_st, // Halt/Run status from CPU
dbg_mem_addr, // Debug address for rd/wr access
dbg_mem_dout, // Debug unit data output
dbg_mem_en, // Debug unit memory enable
dbg_mem_wr, // Debug unit memory write
dmem_dout, // Data Memory data output
eu_mab, // Execution Unit Memory address bus
eu_mb_en, // Execution Unit Memory bus enable
eu_mb_wr, // Execution Unit Memory bus write transfer
eu_mdb_out, // Execution Unit Memory data bus output
fe_mab, // Frontend Memory address bus
fe_mb_en, // Frontend Memory bus enable
mclk, // Main system clock
per_dout, // Peripheral data output
pmem_dout, // Program Memory data output
puc_rst, // Main system reset
scan_enable // Scan enable (active during scan shifting)
cpu_halt_st, // Halt/Run status from CPU
dbg_halt_cmd, // Debug interface Halt CPU command
dbg_mem_addr, // Debug address for rd/wr access
dbg_mem_dout, // Debug unit data output
dbg_mem_en, // Debug unit memory enable
dbg_mem_wr, // Debug unit memory write
dmem_dout, // Data Memory data output
eu_mab, // Execution Unit Memory address bus
eu_mb_en, // Execution Unit Memory bus enable
eu_mb_wr, // Execution Unit Memory bus write transfer
eu_mdb_out, // Execution Unit Memory data bus output
fe_mab, // Frontend Memory address bus
fe_mb_en, // Frontend Memory bus enable
mclk, // Main system clock
dma_addr, // Direct Memory Access address
dma_din, // Direct Memory Access data input
dma_en, // Direct Memory Access enable (high active)
dma_priority, // Direct Memory Access priority (0:low / 1:high)
dma_we, // Direct Memory Access write byte enable (high active)
per_dout, // Peripheral data output
pmem_dout, // Program Memory data output
puc_rst, // Main system reset
scan_enable // Scan enable (active during scan shifting)
);
 
// OUTPUTs
//=========
output [15:0] dbg_mem_din; // Debug unit Memory data input
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
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 [15:0] eu_mdb_in; // Execution Unit Memory data bus input
output [15:0] fe_mdb_in; // Frontend Memory data bus input
output fe_pmem_wait; // Frontend wait for Instruction fetch
output [13:0] per_addr; // Peripheral address
output [15:0] per_din; // Peripheral data input
output [1:0] per_we; // Peripheral write enable (high active)
output per_en; // Peripheral enable (high active)
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
output pmem_cen; // Program Memory chip enable (low active)
output [15:0] pmem_din; // Program Memory data input (optional)
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
output cpu_halt_cmd; // Halt CPU command
output [15:0] dbg_mem_din; // Debug unit Memory data input
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
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 [15:0] eu_mdb_in; // Execution Unit Memory data bus input
output [15:0] fe_mdb_in; // Frontend Memory data bus input
output fe_pmem_wait; // Frontend wait for Instruction fetch
output [15:0] dma_dout; // Direct Memory Access data output
output dma_ready; // Direct Memory Access is complete
output dma_resp; // Direct Memory Access response (0:Okay / 1:Error)
output [13:0] per_addr; // Peripheral address
output [15:0] per_din; // Peripheral data input
output [1:0] per_we; // Peripheral write enable (high active)
output per_en; // Peripheral enable (high active)
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
output pmem_cen; // Program Memory chip enable (low active)
output [15:0] pmem_din; // Program Memory data input (optional)
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
 
// INPUTs
//=========
input dbg_halt_st; // Halt/Run status from CPU
input [15:0] dbg_mem_addr; // Debug address for rd/wr access
input [15:0] dbg_mem_dout; // Debug unit data output
input dbg_mem_en; // Debug unit memory enable
input [1:0] dbg_mem_wr; // Debug unit memory write
input [15:0] dmem_dout; // Data Memory data output
input [14:0] eu_mab; // Execution Unit Memory address bus
input eu_mb_en; // Execution Unit Memory bus enable
input [1:0] eu_mb_wr; // Execution Unit Memory bus write transfer
input [15:0] eu_mdb_out; // Execution Unit Memory data bus output
input [14:0] fe_mab; // Frontend Memory address bus
input fe_mb_en; // Frontend Memory bus enable
input mclk; // Main system clock
input [15:0] per_dout; // Peripheral data output
input [15:0] pmem_dout; // Program Memory data output
input puc_rst; // Main system reset
input scan_enable; // Scan enable (active during scan shifting)
input cpu_halt_st; // Halt/Run status from CPU
input dbg_halt_cmd; // Debug interface Halt CPU command
input [15:1] dbg_mem_addr; // Debug address for rd/wr access
input [15:0] dbg_mem_dout; // Debug unit data output
input dbg_mem_en; // Debug unit memory enable
input [1:0] dbg_mem_wr; // Debug unit memory write
input [15:0] dmem_dout; // Data Memory data output
input [14:0] eu_mab; // Execution Unit Memory address bus
input eu_mb_en; // Execution Unit Memory bus enable
input [1:0] eu_mb_wr; // Execution Unit Memory bus write transfer
input [15:0] eu_mdb_out; // Execution Unit Memory data bus output
input [14:0] fe_mab; // Frontend Memory address bus
input fe_mb_en; // Frontend Memory bus enable
input mclk; // Main system clock
input [15:1] dma_addr; // Direct Memory Access address
input [15:0] dma_din; // Direct Memory Access data input
input dma_en; // Direct Memory Access enable (high active)
input dma_priority; // Direct Memory Access priority (0:low / 1:high)
input [1:0] dma_we; // Direct Memory Access write byte enable (high active)
input [15:0] per_dout; // Peripheral data output
input [15:0] pmem_dout; // Program Memory data output
input puc_rst; // Main system reset
input scan_enable; // Scan enable (active during scan shifting)
 
wire ext_mem_en;
wire [15:0] ext_mem_din;
wire ext_dmem_sel;
wire ext_dmem_en;
wire ext_pmem_sel;
wire ext_pmem_en;
wire ext_per_sel;
wire ext_per_en;
 
 
//=============================================================================
// 1) DECODER
//=============================================================================
 
// RAM Interface
//------------------
//------------------------------------------
// Arbiter between DMA and Debug interface
//------------------------------------------
`ifdef DMA_IF_EN
 
// Debug-interface always stops the CPU
// Master interface stops the CPU in priority mode
assign cpu_halt_cmd = dbg_halt_cmd | (dma_en & dma_priority);
 
// Return ERROR response if address lays outside the memory spaces (Peripheral, Data & Program memories)
assign dma_resp = ~dbg_mem_en & ~(ext_dmem_sel | ext_pmem_sel | ext_per_sel) & dma_en;
 
// Master interface access is ready when the memory access occures
assign dma_ready = ~dbg_mem_en & (ext_dmem_en | ext_pmem_en | ext_per_en | dma_resp);
 
// Use delayed version of 'dma_ready' to mask the 'dma_dout' data output
// when not accessed and reduce toggle rate (thus power consumption)
reg dma_ready_dly;
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) dma_ready_dly <= 1'b0;
else dma_ready_dly <= dma_ready;
 
// Mux between debug and master interface
assign ext_mem_en = dbg_mem_en | dma_en;
wire [1:0] ext_mem_wr = dbg_mem_en ? dbg_mem_wr : dma_we;
wire [15:1] ext_mem_addr = dbg_mem_en ? dbg_mem_addr : dma_addr;
wire [15:0] ext_mem_dout = dbg_mem_en ? dbg_mem_dout : dma_din;
 
// External interface read data
assign dbg_mem_din = ext_mem_din;
assign dma_dout = ext_mem_din & {16{dma_ready_dly}};
 
 
`else
// Debug-interface always stops the CPU
assign cpu_halt_cmd = dbg_halt_cmd;
 
// Master interface access is always ready with error response when excluded
assign dma_resp = 1'b1;
assign dma_ready = 1'b1;
 
// Debug interface only
assign ext_mem_en = dbg_mem_en;
wire [1:0] ext_mem_wr = dbg_mem_wr;
wire [15:1] ext_mem_addr = dbg_mem_addr;
wire [15:0] ext_mem_dout = dbg_mem_dout;
 
// External interface read data
assign dbg_mem_din = ext_mem_din;
assign dma_dout = 16'h0000;
 
// LINT Cleanup
wire [15:1] UNUSED_dma_addr = dma_addr;
wire [15:0] UNUSED_dma_din = dma_din;
wire UNUSED_dma_en = dma_en;
wire UNUSED_dma_priority = dma_priority;
wire [1:0] UNUSED_dma_we = dma_we;
 
`endif
 
//------------------------------------------
// DATA-MEMORY Interface
//------------------------------------------
parameter DMEM_END = `DMEM_BASE+`DMEM_SIZE;
 
// Execution unit access
wire eu_dmem_cen = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) &
(eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1)));
wire eu_dmem_sel = (eu_mab>=(`DMEM_BASE>>1)) &
(eu_mab< ( DMEM_END >>1));
wire eu_dmem_en = eu_mb_en & eu_dmem_sel;
wire [15:0] eu_dmem_addr = {1'b0, eu_mab}-(`DMEM_BASE>>1);
 
// Debug interface access
wire dbg_dmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
(dbg_mem_addr[15:1]<((`DMEM_BASE+`DMEM_SIZE)>>1)));
wire [15:0] dbg_dmem_addr = {1'b0, dbg_mem_addr[15:1]}-(`DMEM_BASE>>1);
// Front-end access
// -- not allowed to execute from data memory --
 
// RAM Interface
wire [`DMEM_MSB:0] dmem_addr = ~dbg_dmem_cen ? dbg_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
wire dmem_cen = dbg_dmem_cen & eu_dmem_cen;
wire [1:0] dmem_wen = ~(dbg_mem_wr | eu_mb_wr);
wire [15:0] dmem_din = ~dbg_dmem_cen ? dbg_mem_dout : eu_mdb_out;
// External Master/Debug interface access
assign ext_dmem_sel = (ext_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
(ext_mem_addr[15:1]< ( DMEM_END >>1));
assign ext_dmem_en = ext_mem_en & ext_dmem_sel & ~eu_dmem_en;
wire [15:0] ext_dmem_addr = {1'b0, ext_mem_addr[15:1]}-(`DMEM_BASE>>1);
 
 
// ROM Interface
//------------------
// Data-Memory Interface
wire dmem_cen = ~(ext_dmem_en | eu_dmem_en);
wire [1:0] dmem_wen = ext_dmem_en ? ~ext_mem_wr : ~eu_mb_wr;
wire [`DMEM_MSB:0] dmem_addr = ext_dmem_en ? ext_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
wire [15:0] dmem_din = ext_dmem_en ? ext_mem_dout : eu_mdb_out;
 
 
//------------------------------------------
// PROGRAM-MEMORY Interface
//------------------------------------------
 
parameter PMEM_OFFSET = (16'hFFFF-`PMEM_SIZE+1);
 
// Execution unit access (only read access are accepted)
wire eu_pmem_cen = ~(eu_mb_en & ~|eu_mb_wr & (eu_mab>=(PMEM_OFFSET>>1)));
wire eu_pmem_sel = (eu_mab>=(PMEM_OFFSET>>1));
wire eu_pmem_en = eu_mb_en & ~|eu_mb_wr & eu_pmem_sel;
wire [15:0] eu_pmem_addr = eu_mab-(PMEM_OFFSET>>1);
 
// Front-end access
wire fe_pmem_cen = ~(fe_mb_en & (fe_mab>=(PMEM_OFFSET>>1)));
wire fe_pmem_sel = (fe_mab>=(PMEM_OFFSET>>1));
wire fe_pmem_en = fe_mb_en & fe_pmem_sel;
wire [15:0] fe_pmem_addr = fe_mab-(PMEM_OFFSET>>1);
 
// Debug interface access
wire dbg_pmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(PMEM_OFFSET>>1)));
wire [15:0] dbg_pmem_addr = {1'b0, dbg_mem_addr[15:1]}-(PMEM_OFFSET>>1);
// External Master/Debug interface access
assign ext_pmem_sel = (ext_mem_addr[15:1]>=(PMEM_OFFSET>>1));
assign ext_pmem_en = ext_mem_en & ext_pmem_sel & ~eu_pmem_en & ~fe_pmem_en;
wire [15:0] ext_pmem_addr = {1'b0, ext_mem_addr[15:1]}-(PMEM_OFFSET>>1);
 
// ROM Interface (Execution unit has priority)
wire [`PMEM_MSB:0] pmem_addr = ~dbg_pmem_cen ? dbg_pmem_addr[`PMEM_MSB:0] :
~eu_pmem_cen ? eu_pmem_addr[`PMEM_MSB:0] : fe_pmem_addr[`PMEM_MSB:0];
wire pmem_cen = fe_pmem_cen & eu_pmem_cen & dbg_pmem_cen;
wire [1:0] pmem_wen = ~dbg_mem_wr;
wire [15:0] pmem_din = dbg_mem_dout;
 
wire fe_pmem_wait = (~fe_pmem_cen & ~eu_pmem_cen);
// Program-Memory Interface (Execution unit has priority over the Front-end)
wire pmem_cen = ~(fe_pmem_en | eu_pmem_en | ext_pmem_en);
wire [1:0] pmem_wen = ext_pmem_en ? ~ext_mem_wr : 2'b11;
wire [`PMEM_MSB:0] pmem_addr = ext_pmem_en ? ext_pmem_addr[`PMEM_MSB:0] :
eu_pmem_en ? eu_pmem_addr[`PMEM_MSB:0] : fe_pmem_addr[`PMEM_MSB:0];
wire [15:0] pmem_din = ext_mem_dout;
 
wire fe_pmem_wait = (fe_pmem_en & eu_pmem_en);
 
// Peripherals
//--------------------
wire dbg_per_en = dbg_mem_en & (dbg_mem_addr[15:1]<(`PER_SIZE>>1));
wire eu_per_en = eu_mb_en & (eu_mab<(`PER_SIZE>>1));
 
wire [15:0] per_din = dbg_mem_en ? dbg_mem_dout : eu_mdb_out;
wire [1:0] per_we = dbg_mem_en ? dbg_mem_wr : eu_mb_wr;
wire per_en = dbg_mem_en ? dbg_per_en : eu_per_en;
wire [`PER_MSB:0] per_addr_mux = dbg_mem_en ? dbg_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
wire [14:0] per_addr_ful = {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
wire [13:0] per_addr = per_addr_ful[13:0];
//------------------------------------------
// PERIPHERALS Interface
//------------------------------------------
 
// Execution unit access
wire eu_per_sel = (eu_mab<(`PER_SIZE>>1));
wire eu_per_en = eu_mb_en & eu_per_sel;
 
// Front-end access
// -- not allowed to execute from peripherals memory space --
 
// External Master/Debug interface access
assign ext_per_sel = (ext_mem_addr[15:1]<(`PER_SIZE>>1));
assign ext_per_en = ext_mem_en & ext_per_sel & ~eu_per_en;
 
// Peripheral Interface
wire per_en = ext_per_en | eu_per_en;
wire [1:0] per_we = ext_per_en ? ext_mem_wr : eu_mb_wr;
wire [`PER_MSB:0] per_addr_mux = ext_per_en ? ext_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
wire [14:0] per_addr_ful = {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
wire [13:0] per_addr = per_addr_ful[13:0];
wire [15:0] per_din = ext_per_en ? ext_mem_dout : eu_mdb_out;
 
// Register peripheral data read path
reg [15:0] per_dout_val;
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) per_dout_val <= 16'h0000;
else per_dout_val <= per_dout;
if (puc_rst) per_dout_val <= 16'h0000;
else per_dout_val <= per_dout;
 
 
//------------------------------------------
// Frontend data Mux
//---------------------------------
// Whenever the frontend doesn't access the ROM, backup the data
//------------------------------------------
// Whenever the frontend doesn't access the program memory, backup the data
 
// Detect whenever the data should be backuped and restored
reg fe_pmem_cen_dly;
reg fe_pmem_en_dly;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) fe_pmem_cen_dly <= 1'b0;
else fe_pmem_cen_dly <= fe_pmem_cen;
if (puc_rst) fe_pmem_en_dly <= 1'b0;
else fe_pmem_en_dly <= fe_pmem_en;
 
wire fe_pmem_save = ( fe_pmem_cen & ~fe_pmem_cen_dly) & ~dbg_halt_st;
wire fe_pmem_restore = (~fe_pmem_cen & fe_pmem_cen_dly) | dbg_halt_st;
wire fe_pmem_save = (~fe_pmem_en & fe_pmem_en_dly) & ~cpu_halt_st;
wire fe_pmem_restore = ( fe_pmem_en & ~fe_pmem_en_dly) | cpu_halt_st;
 
`ifdef CLOCK_GATING
wire mclk_bckup;
213,60 → 327,59
omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup),
.clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable));
`else
wire mclk_bckup = mclk;
wire UNUSED_scan_enable = scan_enable;
wire mclk_bckup = mclk;
`endif
 
reg [15:0] pmem_dout_bckup;
always @(posedge mclk_bckup or posedge puc_rst)
if (puc_rst) pmem_dout_bckup <= 16'h0000;
if (puc_rst) pmem_dout_bckup <= 16'h0000;
`ifdef CLOCK_GATING
else pmem_dout_bckup <= pmem_dout;
else pmem_dout_bckup <= pmem_dout;
`else
else if (fe_pmem_save) pmem_dout_bckup <= pmem_dout;
else if (fe_pmem_save) pmem_dout_bckup <= pmem_dout;
`endif
 
// Mux between the ROM data and the backup
// Mux between the Program memory data and the backup
reg pmem_dout_bckup_sel;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) pmem_dout_bckup_sel <= 1'b0;
else if (fe_pmem_save) pmem_dout_bckup_sel <= 1'b1;
else if (fe_pmem_restore) pmem_dout_bckup_sel <= 1'b0;
 
assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
 
 
//------------------------------------------
// Execution-Unit data Mux
//---------------------------------
//------------------------------------------
 
// Select between peripherals, RAM and ROM
// Select between Peripherals, Program and Data memories
reg [1:0] eu_mdb_in_sel;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) eu_mdb_in_sel <= 2'b00;
else eu_mdb_in_sel <= {~eu_pmem_cen, per_en};
if (puc_rst) eu_mdb_in_sel <= 2'b00;
else eu_mdb_in_sel <= {eu_pmem_en, eu_per_en};
 
// Mux
assign eu_mdb_in = eu_mdb_in_sel[1] ? pmem_dout :
eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
assign eu_mdb_in = eu_mdb_in_sel[1] ? pmem_dout :
eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
 
// Debug interface data Mux
//---------------------------------
 
// Select between peripherals, RAM and ROM
`ifdef DBG_EN
reg [1:0] dbg_mem_din_sel;
//------------------------------------------
// External Master/Debug interface data Mux
//------------------------------------------
 
// Select between Peripherals, Program and Data memories
reg [1:0] ext_mem_din_sel;
always @(posedge mclk or posedge puc_rst)
if (puc_rst) dbg_mem_din_sel <= 2'b00;
else dbg_mem_din_sel <= {~dbg_pmem_cen, dbg_per_en};
if (puc_rst) ext_mem_din_sel <= 2'b00;
else ext_mem_din_sel <= {ext_pmem_en, ext_per_en};
 
`else
wire [1:0] dbg_mem_din_sel = 2'b00;
`endif
// Mux
assign dbg_mem_din = dbg_mem_din_sel[1] ? pmem_dout :
dbg_mem_din_sel[0] ? per_dout_val : dmem_dout;
assign ext_mem_din = ext_mem_din_sel[1] ? pmem_dout :
ext_mem_din_sel[0] ? per_dout_val : dmem_dout;
 
 
endmodule // omsp_mem_backbone
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_execution_unit.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_execution_unit.v
//
//
// *Module Description:
// openMSP430 Execution unit
//
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 174 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2013-01-30 22:18:42 +0100 (Wed, 30 Jan 2013) $
// $Rev$
// $LastChangedBy$
// $LastChangedDate$
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
90,14 → 90,14
 
// OUTPUTs
//=========
output cpuoff; // Turns off the CPU
output cpuoff; // Turns off the CPU
output [15:0] dbg_reg_din; // Debug unit CPU register data input
output gie; // General interrupt enable
output gie; // General interrupt enable
output [15:0] mab; // Memory address bus
output mb_en; // Memory bus enable
output [1:0] mb_wr; // Memory bus write transfer
output [15:0] mdb_out; // Memory data bus output
output oscoff; // Turns off LFXT1 clock input
output oscoff; // Turns off LFXT1 clock input
output [15:0] pc_sw; // Program counter software value
output pc_sw_wr; // Program counter software write
output scg0; // System clock generator 1. Turns off the DCO
166,7 → 166,7
 
wire reg_sr_clr = (e_state==`E_IRQ_2);
 
wire reg_pc_call = ((e_state==`E_EXEC) & inst_so[`CALL]) |
wire reg_pc_call = ((e_state==`E_EXEC) & inst_so[`CALL]) |
((e_state==`E_DST_WR) & inst_so[`RETI]);
 
wire reg_incr = (exec_done & inst_as[`INDIR_I]) |
415,6 → 415,15
assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw;
 
 
// LINT cleanup
wire UNUSED_inst_ad_idx = inst_ad[`IDX];
wire UNUSED_inst_ad_indir = inst_ad[`INDIR];
wire UNUSED_inst_ad_indir_i = inst_ad[`INDIR_I];
wire UNUSED_inst_ad_symb = inst_ad[`SYMB];
wire UNUSED_inst_ad_imm = inst_ad[`IMM];
wire UNUSED_inst_ad_const = inst_ad[`CONST];
 
 
endmodule // omsp_execution_unit
 
`ifdef OMSP_NO_INCLUDE
/openmsp430/omsp_and_gate.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_and_gate.v
//
//
// *Module Description:
// Generic AND gate cell for the openMSP430
//
84,6 → 84,3
 
 
endmodule // omsp_and_gate
 
 
 
/openmsp430/openMSP430_defines.v
26,9 → 26,9
// THE POSSIBILITY OF SUCH DAMAGE
//
//----------------------------------------------------------------------------
//
//
// *File Name: openMSP430_defines.v
//
//
// *Module Description:
// openMSP430 Configuration file
//
133,6 → 133,12
 
 
//-------------------------------------------------------
// Include/Exclude DMA interface support
//-------------------------------------------------------
//`define DMA_IF_EN
 
 
//-------------------------------------------------------
// Include/Exclude Non-Maskable-Interrupt support
//-------------------------------------------------------
`define NMI
281,15 → 287,15
// (i.e. the *_SIZE divided by 2)
//-------------------------------------------------------
 
// Custom Program memory (enabled with PMEM_SIZE_CUSTOM)
// Custom Program memory (enabled with PMEM_SIZE_CUSTOM)
`define PMEM_CUSTOM_AWIDTH 10
`define PMEM_CUSTOM_SIZE 2048
 
// Custom Data memory (enabled with DMEM_SIZE_CUSTOM)
// Custom Data memory (enabled with DMEM_SIZE_CUSTOM)
`define DMEM_CUSTOM_AWIDTH 6
`define DMEM_CUSTOM_SIZE 128
 
// Custom Peripheral memory (enabled with PER_SIZE_CUSTOM)
// Custom Peripheral memory (enabled with PER_SIZE_CUSTOM)
`define PER_CUSTOM_AWIDTH 8
`define PER_CUSTOM_SIZE 512
 
777,6 → 783,10
 
// Basic clock module: BCSCTL1 Control Register
`define DIVAx 5:4
`define DMA_CPUOFF 0
`define DMA_SCG0 1
`define DMA_SCG1 2
`define DMA_OSCOFF 3
 
// Basic clock module: BCSCTL2 Control Register
`define SELMx 7
807,7 → 817,10
//======================================
 
// Debug interface: CPU version
`define CPU_VERSION 3'h2
// 1 - FPGA support only (Pre-BSD licence era)
// 2 - Add ASIC support
// 3 - Add DMA interface support
`define CPU_VERSION 3'h3
 
// Debug interface: Software breakpoint opcode
`define DBG_SWBRK_OP 16'h4343
871,7 → 884,7
// the 16x16 multiplier (1 cycle) instead of the
// default 16x8 multplier (2 cycles)
//`define MPY_16x16
 
//======================================
// CONFIGURATION CHECKS
//======================================
896,7 → 909,7
`endif
`ifdef SMCLK_MUX
CONFIGURATION ERROR: THE SMCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
`endif
`endif
`ifdef WATCHDOG_MUX
CONFIGURATION ERROR: THE WATCHDOG_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
`else
906,5 → 919,5
`endif
`ifdef OSCOFF_EN
CONFIGURATION ERROR: THE OSCOFF LOW POWER MODE CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
`endif
`endif
`endif
/openmsp430/openMSP430.v
36,9 → 36,9
// - Olivier Girard, olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 175 $
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2013-01-30 22:21:42 +0100 (Wed, 30 Jan 2013) $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//----------------------------------------------------------------------------
`ifdef OMSP_NO_INCLUDE
`else
48,109 → 48,127
module openMSP430 (
 
// OUTPUTs
aclk, // ASIC ONLY: ACLK
aclk_en, // FPGA ONLY: ACLK enable
dbg_freeze, // Freeze peripherals
dbg_i2c_sda_out, // Debug interface: I2C SDA OUT
dbg_uart_txd, // Debug interface: UART TXD
dco_enable, // ASIC ONLY: Fast oscillator enable
dco_wkup, // ASIC ONLY: Fast oscillator wake-up (asynchronous)
dmem_addr, // Data Memory address
dmem_cen, // Data Memory chip enable (low active)
dmem_din, // Data Memory data input
dmem_wen, // Data Memory write enable (low active)
irq_acc, // Interrupt request accepted (one-hot signal)
lfxt_enable, // ASIC ONLY: Low frequency oscillator enable
lfxt_wkup, // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
mclk, // Main system clock
per_addr, // Peripheral address
per_din, // Peripheral data input
per_we, // Peripheral write enable (high active)
per_en, // Peripheral enable (high active)
pmem_addr, // Program Memory address
pmem_cen, // Program Memory chip enable (low active)
pmem_din, // Program Memory data input (optional)
pmem_wen, // Program Memory write enable (low active) (optional)
puc_rst, // Main system reset
smclk, // ASIC ONLY: SMCLK
smclk_en, // FPGA ONLY: SMCLK enable
aclk, // ASIC ONLY: ACLK
aclk_en, // FPGA ONLY: ACLK enable
dbg_freeze, // Freeze peripherals
dbg_i2c_sda_out, // Debug interface: I2C SDA OUT
dbg_uart_txd, // Debug interface: UART TXD
dco_enable, // ASIC ONLY: Fast oscillator enable
dco_wkup, // ASIC ONLY: Fast oscillator wake-up (asynchronous)
dmem_addr, // Data Memory address
dmem_cen, // Data Memory chip enable (low active)
dmem_din, // Data Memory data input
dmem_wen, // Data Memory write byte enable (low active)
irq_acc, // Interrupt request accepted (one-hot signal)
lfxt_enable, // ASIC ONLY: Low frequency oscillator enable
lfxt_wkup, // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
mclk, // Main system clock
dma_dout, // Direct Memory Access data output
dma_ready, // Direct Memory Access is complete
dma_resp, // Direct Memory Access response (0:Okay / 1:Error)
per_addr, // Peripheral address
per_din, // Peripheral data input
per_en, // Peripheral enable (high active)
per_we, // Peripheral write byte enable (high active)
pmem_addr, // Program Memory address
pmem_cen, // Program Memory chip enable (low active)
pmem_din, // Program Memory data input (optional)
pmem_wen, // Program Memory write byte enable (low active) (optional)
puc_rst, // Main system reset
smclk, // ASIC ONLY: SMCLK
smclk_en, // FPGA ONLY: SMCLK enable
 
// INPUTs
cpu_en, // Enable CPU code execution (asynchronous and non-glitchy)
dbg_en, // Debug interface enable (asynchronous and non-glitchy)
dbg_i2c_addr, // Debug interface: I2C Address
dbg_i2c_broadcast, // Debug interface: I2C Broadcast Address (for multicore systems)
dbg_i2c_scl, // Debug interface: I2C SCL
dbg_i2c_sda_in, // Debug interface: I2C SDA IN
dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
dco_clk, // Fast oscillator (fast clock)
dmem_dout, // Data Memory data output
irq, // Maskable interrupts
lfxt_clk, // Low frequency oscillator (typ 32kHz)
nmi, // Non-maskable interrupt (asynchronous)
per_dout, // Peripheral data output
pmem_dout, // Program Memory data output
reset_n, // Reset Pin (low active, asynchronous and non-glitchy)
scan_enable, // ASIC ONLY: Scan enable (active during scan shifting)
scan_mode, // ASIC ONLY: Scan mode
wkup // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
cpu_en, // Enable CPU code execution (asynchronous and non-glitchy)
dbg_en, // Debug interface enable (asynchronous and non-glitchy)
dbg_i2c_addr, // Debug interface: I2C Address
dbg_i2c_broadcast, // Debug interface: I2C Broadcast Address (for multicore systems)
dbg_i2c_scl, // Debug interface: I2C SCL
dbg_i2c_sda_in, // Debug interface: I2C SDA IN
dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
dco_clk, // Fast oscillator (fast clock)
dmem_dout, // Data Memory data output
irq, // Maskable interrupts
lfxt_clk, // Low frequency oscillator (typ 32kHz)
dma_addr, // Direct Memory Access address
dma_din, // Direct Memory Access data input
dma_en, // Direct Memory Access enable (high active)
dma_priority, // Direct Memory Access priority (0:low / 1:high)
dma_we, // Direct Memory Access write byte enable (high active)
dma_wkup, // ASIC ONLY: DMA Sub-System Wake-up (asynchronous and non-glitchy)
nmi, // Non-maskable interrupt (asynchronous)
per_dout, // Peripheral data output
pmem_dout, // Program Memory data output
reset_n, // Reset Pin (low active, asynchronous and non-glitchy)
scan_enable, // ASIC ONLY: Scan enable (active during scan shifting)
scan_mode, // ASIC ONLY: Scan mode
wkup // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
);
 
// PARAMETERs
//============
parameter INST_NR = 8'h00; // Current oMSP instance number (for multicore systems)
parameter TOTAL_NR = 8'h00; // Total number of oMSP instances-1 (for multicore systems)
parameter INST_NR = 8'h00; // Current oMSP instance number (for multicore systems)
parameter TOTAL_NR = 8'h00; // Total number of oMSP instances-1 (for multicore systems)
 
// OUTPUTs
//============
output aclk; // ASIC ONLY: ACLK
output aclk_en; // FPGA ONLY: ACLK enable
output dbg_freeze; // Freeze peripherals
output dbg_i2c_sda_out; // Debug interface: I2C SDA OUT
output dbg_uart_txd; // Debug interface: UART TXD
output dco_enable; // ASIC ONLY: Fast oscillator enable
output dco_wkup; // ASIC ONLY: Fast oscillator wake-up (asynchronous)
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
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 [`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
output [13:0] per_addr; // Peripheral address
output [15:0] per_din; // Peripheral data input
output [1:0] per_we; // Peripheral write enable (high active)
output per_en; // Peripheral enable (high active)
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
output pmem_cen; // Program Memory chip enable (low active)
output [15:0] pmem_din; // Program Memory data input (optional)
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
output puc_rst; // Main system reset
output smclk; // ASIC ONLY: SMCLK
output smclk_en; // FPGA ONLY: SMCLK enable
output aclk; // ASIC ONLY: ACLK
output aclk_en; // FPGA ONLY: ACLK enable
output dbg_freeze; // Freeze peripherals
output dbg_i2c_sda_out; // Debug interface: I2C SDA OUT
output dbg_uart_txd; // Debug interface: UART TXD
output dco_enable; // ASIC ONLY: Fast oscillator enable
output dco_wkup; // ASIC ONLY: Fast oscillator wake-up (asynchronous)
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
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 byte enable (low active)
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
output [15:0] dma_dout; // Direct Memory Access data output
output dma_ready; // Direct Memory Access is complete
output dma_resp; // Direct Memory Access response (0:Okay / 1:Error)
output [13:0] per_addr; // Peripheral address
output [15:0] per_din; // Peripheral data input
output per_en; // Peripheral enable (high active)
output [1:0] per_we; // Peripheral write byte enable (high active)
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
output pmem_cen; // Program Memory chip enable (low active)
output [15:0] pmem_din; // Program Memory data input (optional)
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
output puc_rst; // Main system reset
output smclk; // ASIC ONLY: SMCLK
output smclk_en; // FPGA ONLY: SMCLK enable
 
 
// INPUTs
//============
input cpu_en; // Enable CPU code execution (asynchronous and non-glitchy)
input dbg_en; // Debug interface enable (asynchronous and non-glitchy)
input [6:0] dbg_i2c_addr; // Debug interface: I2C Address
input [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
input dbg_i2c_scl; // Debug interface: I2C SCL
input dbg_i2c_sda_in; // Debug interface: I2C SDA IN
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 [`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
input [15:0] pmem_dout; // Program Memory data output
input reset_n; // Reset Pin (active low, asynchronous and non-glitchy)
input scan_enable; // ASIC ONLY: Scan enable (active during scan shifting)
input scan_mode; // ASIC ONLY: Scan mode
input wkup; // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
input cpu_en; // Enable CPU code execution (asynchronous and non-glitchy)
input dbg_en; // Debug interface enable (asynchronous and non-glitchy)
input [6:0] dbg_i2c_addr; // Debug interface: I2C Address
input [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
input dbg_i2c_scl; // Debug interface: I2C SCL
input dbg_i2c_sda_in; // Debug interface: I2C SDA IN
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 [`IRQ_NR-3:0] irq; // Maskable interrupts (14, 30 or 62)
input lfxt_clk; // Low frequency oscillator (typ 32kHz)
input [15:1] dma_addr; // Direct Memory Access address
input [15:0] dma_din; // Direct Memory Access data input
input dma_en; // Direct Memory Access enable (high active)
input dma_priority; // Direct Memory Access priority (0:low / 1:high)
input [1:0] dma_we; // Direct Memory Access write byte enable (high active)
input dma_wkup; // ASIC ONLY: DMA Wake-up (asynchronous and non-glitchy)
input nmi; // Non-maskable interrupt (asynchronous and non-glitchy)
input [15:0] per_dout; // Peripheral data output
input [15:0] pmem_dout; // Program Memory data output
input reset_n; // Reset Pin (active low, asynchronous and non-glitchy)
input scan_enable; // ASIC ONLY: Scan enable (active during scan shifting)
input scan_mode; // ASIC ONLY: Scan mode
input wkup; // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
 
 
 
158,85 → 176,91
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
//=============================================================================
 
wire [7:0] inst_ad;
wire [7:0] inst_as;
wire [11:0] inst_alu;
wire inst_bw;
wire inst_irq_rst;
wire inst_mov;
wire [15:0] inst_dest;
wire [15:0] inst_dext;
wire [15:0] inst_sext;
wire [7:0] inst_so;
wire [15:0] inst_src;
wire [2:0] inst_type;
wire [7:0] inst_jmp;
wire [3:0] e_state;
wire exec_done;
wire decode_noirq;
wire cpu_en_s;
wire cpuoff;
wire oscoff;
wire scg0;
wire scg1;
wire por;
wire gie;
wire mclk_enable;
wire mclk_wkup;
wire [31:0] cpu_id;
wire [7:0] cpu_nr_inst = INST_NR;
wire [7:0] cpu_nr_total = TOTAL_NR;
wire [7:0] inst_ad;
wire [7:0] inst_as;
wire [11:0] inst_alu;
wire inst_bw;
wire inst_irq_rst;
wire inst_mov;
wire [15:0] inst_dest;
wire [15:0] inst_dext;
wire [15:0] inst_sext;
wire [7:0] inst_so;
wire [15:0] inst_src;
wire [2:0] inst_type;
wire [7:0] inst_jmp;
wire [3:0] e_state;
wire exec_done;
wire decode_noirq;
wire cpu_en_s;
wire cpuoff;
wire oscoff;
wire scg0;
wire scg1;
wire por;
wire gie;
wire cpu_mclk;
wire dma_mclk;
wire mclk_dma_enable;
wire mclk_dma_wkup;
wire mclk_enable;
wire mclk_wkup;
wire [31:0] cpu_id;
wire [7:0] cpu_nr_inst = INST_NR;
wire [7:0] cpu_nr_total = TOTAL_NR;
 
wire [15:0] eu_mab;
wire [15:0] eu_mdb_in;
wire [15:0] eu_mdb_out;
wire [1:0] eu_mb_wr;
wire eu_mb_en;
wire [15:0] fe_mab;
wire [15:0] fe_mdb_in;
wire fe_mb_en;
wire fe_pmem_wait;
wire [15:0] eu_mab;
wire [15:0] eu_mdb_in;
wire [15:0] eu_mdb_out;
wire [1:0] eu_mb_wr;
wire eu_mb_en;
wire [15:0] fe_mab;
wire [15:0] fe_mdb_in;
wire fe_mb_en;
wire fe_pmem_wait;
 
wire pc_sw_wr;
wire [15:0] pc_sw;
wire [15:0] pc;
wire [15:0] pc_nxt;
wire pc_sw_wr;
wire [15:0] pc_sw;
wire [15:0] pc;
wire [15:0] pc_nxt;
 
wire nmi_acc;
wire nmi_pnd;
wire nmi_wkup;
wire nmi_acc;
wire nmi_pnd;
wire nmi_wkup;
 
wire wdtie;
wire wdtnmies;
wire wdtifg;
wire wdt_irq;
wire wdt_wkup;
wire wdt_reset;
wire wdtifg_sw_clr;
wire wdtifg_sw_set;
wire wdtie;
wire wdtnmies;
wire wdtifg;
wire wdt_irq;
wire wdt_wkup;
wire wdt_reset;
wire wdtifg_sw_clr;
wire wdtifg_sw_set;
 
wire dbg_clk;
wire dbg_rst;
wire dbg_en_s;
wire dbg_halt_st;
wire dbg_halt_cmd;
wire dbg_mem_en;
wire dbg_reg_wr;
wire dbg_cpu_reset;
wire [15:0] dbg_mem_addr;
wire [15:0] dbg_mem_dout;
wire [15:0] dbg_mem_din;
wire [15:0] dbg_reg_din;
wire [1:0] dbg_mem_wr;
wire puc_pnd_set;
wire dbg_clk;
wire dbg_rst;
wire dbg_en_s;
wire dbg_halt_cmd;
wire dbg_mem_en;
wire dbg_reg_wr;
wire dbg_cpu_reset;
wire [15:0] dbg_mem_addr;
wire [15:0] dbg_mem_dout;
wire [15:0] dbg_mem_din;
wire [15:0] dbg_reg_din;
wire [1:0] dbg_mem_wr;
 
wire [15:0] per_dout_or;
wire [15:0] per_dout_sfr;
wire [15:0] per_dout_wdog;
wire [15:0] per_dout_mpy;
wire [15:0] per_dout_clk;
wire cpu_halt_st;
wire cpu_halt_cmd;
wire puc_pnd_set;
 
wire [15:0] per_dout_or;
wire [15:0] per_dout_sfr;
wire [15:0] per_dout_wdog;
wire [15:0] per_dout_mpy;
wire [15:0] per_dout_clk;
 
 
//=============================================================================
// 2) GLOBAL CLOCK & RESET MANAGEMENT
//=============================================================================
244,47 → 268,52
omsp_clock_module clock_module_0 (
 
// OUTPUTs
.aclk (aclk), // ACLK
.aclk_en (aclk_en), // ACLK enablex
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
.dbg_clk (dbg_clk), // Debug unit clock
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
.dbg_rst (dbg_rst), // Debug unit reset
.dco_enable (dco_enable), // Fast oscillator enable
.dco_wkup (dco_wkup), // Fast oscillator wake-up (asynchronous)
.lfxt_enable (lfxt_enable), // Low frequency oscillator enable
.lfxt_wkup (lfxt_wkup), // Low frequency oscillator wake-up (asynchronous)
.mclk (mclk), // Main system clock
.per_dout (per_dout_clk), // Peripheral data output
.por (por), // Power-on reset
.puc_pnd_set (puc_pnd_set), // PUC pending set for the serial debug interface
.puc_rst (puc_rst), // Main system reset
.smclk (smclk), // SMCLK
.smclk_en (smclk_en), // SMCLK enable
.aclk (aclk), // ACLK
.aclk_en (aclk_en), // ACLK enablex
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
.cpu_mclk (cpu_mclk), // Main system CPU only clock
.dma_mclk (dma_mclk), // Main system DMA and/or CPU clock
.dbg_clk (dbg_clk), // Debug unit clock
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
.dbg_rst (dbg_rst), // Debug unit reset
.dco_enable (dco_enable), // Fast oscillator enable
.dco_wkup (dco_wkup), // Fast oscillator wake-up (asynchronous)
.lfxt_enable (lfxt_enable), // Low frequency oscillator enable
.lfxt_wkup (lfxt_wkup), // Low frequency oscillator wake-up (asynchronous)
.per_dout (per_dout_clk), // Peripheral data output
.por (por), // Power-on reset
.puc_pnd_set (puc_pnd_set), // PUC pending set for the serial debug interface
.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
.dbg_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface
.dbg_en (dbg_en), // Debug interface enable (asynchronous)
.dco_clk (dco_clk), // Fast oscillator (fast clock)
.lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz)
.mclk_enable (mclk_enable), // Main System Clock enable
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
.oscoff (oscoff), // Turns off LFXT1 clock input
.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)
.reset_n (reset_n), // Reset Pin (low active, asynchronous)
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
.scan_mode (scan_mode), // Scan mode
.scg0 (scg0), // System clock generator 1. Turns off the DCO
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
.wdt_reset (wdt_reset) // Watchdog-timer reset
.cpu_en (cpu_en), // Enable CPU code execution (asynchronous)
.cpuoff (cpuoff), // Turns off the CPU
.dbg_cpu_reset (dbg_cpu_reset), // Reset CPU from debug interface
.dbg_en (dbg_en), // Debug interface enable (asynchronous)
.dco_clk (dco_clk), // Fast oscillator (fast clock)
.lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz)
.mclk_dma_enable (mclk_dma_enable), // DMA Sub-System Clock enable
.mclk_dma_wkup (mclk_dma_wkup), // DMA Sub-System Clock wake-up (asynchronous)
.mclk_enable (mclk_enable), // Main System Clock enable
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
.oscoff (oscoff), // Turns off LFXT1 clock input
.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)
.reset_n (reset_n), // Reset Pin (low active, asynchronous)
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
.scan_mode (scan_mode), // Scan mode
.scg0 (scg0), // System clock generator 1. Turns off the DCO
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
.wdt_reset (wdt_reset) // Watchdog-timer reset
);
 
assign mclk = dma_mclk;
 
 
//=============================================================================
// 3) FRONTEND (<=> FETCH & DECODE)
//=============================================================================
292,51 → 321,55
omsp_frontend frontend_0 (
 
// OUTPUTs
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
.decode_noirq (decode_noirq), // Frontend decode instruction
.e_state (e_state), // Execution state
.exec_done (exec_done), // Execution completed
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
.inst_as (inst_as), // Decoded Inst: source addressing mode
.inst_alu (inst_alu), // ALU control signals
.inst_bw (inst_bw), // Decoded Inst: byte width
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
.inst_irq_rst (inst_irq_rst), // Decoded Inst: Reset interrupt
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
.inst_mov (inst_mov), // Decoded Inst: mov instruction
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
.inst_src (inst_src), // Decoded Inst: source (one hot)
.inst_type (inst_type), // Decoded Instruction type
.irq_acc (irq_acc), // Interrupt request accepted
.mab (fe_mab), // Frontend Memory address bus
.mb_en (fe_mb_en), // Frontend Memory bus enable
.mclk_enable (mclk_enable), // Main System Clock enable
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
.pc (pc), // Program counter
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
.cpu_halt_st (cpu_halt_st), // Halt/Run status from CPU
.decode_noirq (decode_noirq), // Frontend decode instruction
.e_state (e_state), // Execution state
.exec_done (exec_done), // Execution completed
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
.inst_as (inst_as), // Decoded Inst: source addressing mode
.inst_alu (inst_alu), // ALU control signals
.inst_bw (inst_bw), // Decoded Inst: byte width
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
.inst_irq_rst (inst_irq_rst), // Decoded Inst: Reset interrupt
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
.inst_mov (inst_mov), // Decoded Inst: mov instruction
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
.inst_src (inst_src), // Decoded Inst: source (one hot)
.inst_type (inst_type), // Decoded Instruction type
.irq_acc (irq_acc), // Interrupt request accepted
.mab (fe_mab), // Frontend Memory address bus
.mb_en (fe_mb_en), // Frontend Memory bus enable
.mclk_dma_enable (mclk_dma_enable), // DMA Sub-System Clock enable
.mclk_dma_wkup (mclk_dma_wkup), // DMA Sub-System Clock wake-up (asynchronous)
.mclk_enable (mclk_enable), // Main System Clock enable
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
.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
.dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
.dbg_reg_sel (dbg_mem_addr[3:0]), // Debug selected register for rd/wr access
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
.gie (gie), // General interrupt enable
.irq (irq), // Maskable interrupts
.mclk (mclk), // Main system clock
.mdb_in (fe_mdb_in), // Frontend Memory data bus input
.nmi_pnd (nmi_pnd), // Non-maskable interrupt pending
.nmi_wkup (nmi_wkup), // NMI Wakeup
.pc_sw (pc_sw), // Program counter software value
.pc_sw_wr (pc_sw_wr), // Program counter software write
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
.wdt_irq (wdt_irq), // Watchdog-timer interrupt
.wdt_wkup (wdt_wkup), // Watchdog Wakeup
.wkup (wkup) // System Wake-up (asynchronous)
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
.cpu_halt_cmd (cpu_halt_cmd), // Halt CPU command
.cpuoff (cpuoff), // Turns off the CPU
.dbg_reg_sel (dbg_mem_addr[3:0]), // Debug selected register for rd/wr access
.dma_en (dma_en), // Direct Memory Access enable (high active)
.dma_wkup (dma_wkup), // DMA Sub-System Wake-up (asynchronous and non-glitchy)
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
.gie (gie), // General interrupt enable
.irq (irq), // Maskable interrupts
.mclk (cpu_mclk), // Main system clock
.mdb_in (fe_mdb_in), // Frontend Memory data bus input
.nmi_pnd (nmi_pnd), // Non-maskable interrupt pending
.nmi_wkup (nmi_wkup), // NMI Wakeup
.pc_sw (pc_sw), // Program counter software value
.pc_sw_wr (pc_sw_wr), // Program counter software write
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
.wdt_irq (wdt_irq), // Watchdog-timer interrupt
.wdt_wkup (wdt_wkup), // Watchdog Wakeup
.wkup (wkup) // System Wake-up (asynchronous)
);
 
 
347,44 → 380,44
omsp_execution_unit execution_unit_0 (
 
// OUTPUTs
.cpuoff (cpuoff), // Turns off the CPU
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
.gie (gie), // General interrupt enable
.mab (eu_mab), // Memory address bus
.mb_en (eu_mb_en), // Memory bus enable
.mb_wr (eu_mb_wr), // Memory bus write transfer
.mdb_out (eu_mdb_out), // Memory data bus output
.oscoff (oscoff), // Turns off LFXT1 clock input
.pc_sw (pc_sw), // Program counter software value
.pc_sw_wr (pc_sw_wr), // Program counter software write
.scg0 (scg0), // System clock generator 1. Turns off the DCO
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
.cpuoff (cpuoff), // Turns off the CPU
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
.mab (eu_mab), // Memory address bus
.mb_en (eu_mb_en), // Memory bus enable
.mb_wr (eu_mb_wr), // Memory bus write transfer
.mdb_out (eu_mdb_out), // Memory data bus output
.oscoff (oscoff), // Turns off LFXT1 clock input
.pc_sw (pc_sw), // Program counter software value
.pc_sw_wr (pc_sw_wr), // Program counter software write
.scg0 (scg0), // System clock generator 1. Turns off the DCO
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
 
// INPUTs
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
.e_state (e_state), // Execution state
.exec_done (exec_done), // Execution completed
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
.inst_as (inst_as), // Decoded Inst: source addressing mode
.inst_alu (inst_alu), // ALU control signals
.inst_bw (inst_bw), // Decoded Inst: byte width
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
.inst_irq_rst (inst_irq_rst), // Decoded Inst: reset interrupt
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
.inst_mov (inst_mov), // Decoded Inst: mov instruction
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
.inst_src (inst_src), // Decoded Inst: source (one hot)
.inst_type (inst_type), // Decoded Instruction type
.mclk (mclk), // Main system clock
.mdb_in (eu_mdb_in), // Memory data bus input
.pc (pc), // Program counter
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
.dbg_halt_st (cpu_halt_st), // Halt/Run status from CPU
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
.e_state (e_state), // Execution state
.exec_done (exec_done), // Execution completed
.gie (gie), // General interrupt enable
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
.inst_as (inst_as), // Decoded Inst: source addressing mode
.inst_alu (inst_alu), // ALU control signals
.inst_bw (inst_bw), // Decoded Inst: byte width
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
.inst_irq_rst (inst_irq_rst), // Decoded Inst: reset interrupt
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
.inst_mov (inst_mov), // Decoded Inst: mov instruction
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
.inst_src (inst_src), // Decoded Inst: source (one hot)
.inst_type (inst_type), // Decoded Instruction type
.mclk (cpu_mclk), // Main system clock
.mdb_in (eu_mdb_in), // Memory data bus input
.pc (pc), // Program counter
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
);
 
 
395,43 → 428,54
omsp_mem_backbone mem_backbone_0 (
 
// OUTPUTs
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
.dmem_addr (dmem_addr), // Data Memory address
.dmem_cen (dmem_cen), // Data Memory chip enable (low active)
.dmem_din (dmem_din), // Data Memory data input
.dmem_wen (dmem_wen), // Data Memory write enable (low active)
.eu_mdb_in (eu_mdb_in), // Execution Unit Memory data bus input
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
.per_addr (per_addr), // Peripheral address
.per_din (per_din), // Peripheral data input
.per_we (per_we), // Peripheral write enable (high active)
.per_en (per_en), // Peripheral enable (high active)
.pmem_addr (pmem_addr), // Program Memory address
.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)
.cpu_halt_cmd (cpu_halt_cmd), // Halt CPU command
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
.dmem_addr (dmem_addr), // Data Memory address
.dmem_cen (dmem_cen), // Data Memory chip enable (low active)
.dmem_din (dmem_din), // Data Memory data input
.dmem_wen (dmem_wen), // Data Memory write enable (low active)
.eu_mdb_in (eu_mdb_in), // Execution Unit Memory data bus input
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
.dma_dout (dma_dout), // Direct Memory Access data output
.dma_ready (dma_ready), // Direct Memory Access is complete
.dma_resp (dma_resp), // Direct Memory Access response (0:Okay / 1:Error)
.per_addr (per_addr), // Peripheral address
.per_din (per_din), // Peripheral data input
.per_we (per_we), // Peripheral write enable (high active)
.per_en (per_en), // Peripheral enable (high active)
.pmem_addr (pmem_addr), // Program Memory address
.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
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
.dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
.dmem_dout (dmem_dout), // Data Memory data output
.eu_mab (eu_mab[15:1]), // Execution Unit Memory address bus
.eu_mb_en (eu_mb_en), // Execution Unit Memory bus enable
.eu_mb_wr (eu_mb_wr), // Execution Unit Memory bus write transfer
.eu_mdb_out (eu_mdb_out), // Execution Unit Memory data bus output
.fe_mab (fe_mab[15:1]), // Frontend Memory address bus
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
.mclk (mclk), // Main system clock
.per_dout (per_dout_or), // Peripheral data output
.pmem_dout (pmem_dout), // Program Memory data output
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
.cpu_halt_st (cpu_halt_st), // Halt/Run status from CPU
.dbg_halt_cmd (dbg_halt_cmd), // Debug interface Halt CPU command
.dbg_mem_addr (dbg_mem_addr[15:1]), // Debug address for rd/wr access
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
.dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
.dmem_dout (dmem_dout), // Data Memory data output
.eu_mab (eu_mab[15:1]), // Execution Unit Memory address bus
.eu_mb_en (eu_mb_en), // Execution Unit Memory bus enable
.eu_mb_wr (eu_mb_wr), // Execution Unit Memory bus write transfer
.eu_mdb_out (eu_mdb_out), // Execution Unit Memory data bus output
.fe_mab (fe_mab[15:1]), // Frontend Memory address bus
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
.mclk (dma_mclk), // Main system clock
.dma_addr (dma_addr), // Direct Memory Access address
.dma_din (dma_din), // Direct Memory Access data input
.dma_en (dma_en), // Direct Memory Access enable (high active)
.dma_priority (dma_priority), // Direct Memory Access priority (0:low / 1:high)
.dma_we (dma_we), // Direct Memory Access write byte enable (high active)
.per_dout (per_dout_or), // Peripheral data output
.pmem_dout (pmem_dout), // Program Memory data output
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
);
 
wire UNUSED_fe_mab_0 = fe_mab[0];
 
//=============================================================================
// 6) SPECIAL FUNCTION REGISTERS
439,28 → 483,28
omsp_sfr sfr_0 (
 
// OUTPUTs
.cpu_id (cpu_id), // CPU ID
.nmi_pnd (nmi_pnd), // NMI Pending
.nmi_wkup (nmi_wkup), // NMI Wakeup
.per_dout (per_dout_sfr), // Peripheral data output
.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
.cpu_id (cpu_id), // CPU ID
.nmi_pnd (nmi_pnd), // NMI Pending
.nmi_wkup (nmi_wkup), // NMI Wakeup
.per_dout (per_dout_sfr), // Peripheral data output
.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
.mclk (mclk), // Main system clock
.nmi (nmi), // Non-maskable interrupt (asynchronous)
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
.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)
.puc_rst (puc_rst), // Main system reset
.scan_mode (scan_mode), // Scan mode
.wdtifg (wdtifg), // Watchdog-timer interrupt flag
.wdtnmies (wdtnmies) // Watchdog-timer NMI edge selection
.cpu_nr_inst (cpu_nr_inst), // Current oMSP instance number
.cpu_nr_total (cpu_nr_total), // Total number of oMSP instances-1
.mclk (dma_mclk), // Main system clock
.nmi (nmi), // Non-maskable interrupt (asynchronous)
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
.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)
.puc_rst (puc_rst), // Main system reset
.scan_mode (scan_mode), // Scan mode
.wdtifg (wdtifg), // Watchdog-timer interrupt flag
.wdtnmies (wdtnmies) // Watchdog-timer NMI edge selection
);
 
 
471,40 → 515,44
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[`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
.aclk (aclk), // ACLK
.aclk_en (aclk_en), // ACLK enable
.dbg_freeze (dbg_freeze), // Freeze Watchdog counter
.mclk (dma_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;
assign wdt_irq = 1'b0;
assign wdt_reset = 1'b0;
assign wdt_wkup = 1'b0;
assign wdtifg = 1'b0;
assign wdtnmies = 1'b0;
assign per_dout_wdog = 16'h0000;
assign wdt_irq = 1'b0;
assign wdt_reset = 1'b0;
assign wdt_wkup = 1'b0;
assign wdtifg = 1'b0;
assign wdtnmies = 1'b0;
wire UNUSED_por = por;
wire UNUSED_wdtie = wdtie;
wire UNUSED_wdtifg_sw_clr = wdtifg_sw_clr;
wire UNUSED_wdtifg_sw_set = wdtifg_sw_set;
`endif
 
 
515,16 → 563,16
omsp_multiplier multiplier_0 (
 
// OUTPUTs
.per_dout (per_dout_mpy), // Peripheral data output
.per_dout (per_dout_mpy), // Peripheral data output
 
// INPUTs
.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)
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
.mclk (dma_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)
.puc_rst (puc_rst), // Main system reset
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
);
`else
assign per_dout_mpy = 16'h0000;
549,53 → 597,67
omsp_dbg dbg_0 (
 
// OUTPUTs
.dbg_cpu_reset (dbg_cpu_reset), // Reset CPU from debug interface
.dbg_freeze (dbg_freeze), // Freeze peripherals
.dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
.dbg_i2c_sda_out (dbg_i2c_sda_out), // Debug interface: I2C SDA OUT
.dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
.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
.dbg_cpu_reset (dbg_cpu_reset), // Reset CPU from debug interface
.dbg_freeze (dbg_freeze), // Freeze peripherals
.dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
.dbg_i2c_sda_out (dbg_i2c_sda_out), // Debug interface: I2C SDA OUT
.dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
.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
.cpu_nr_inst (cpu_nr_inst), // Current oMSP instance number
.cpu_nr_total (cpu_nr_total), // Total number of oMSP instances-1
.dbg_clk (dbg_clk), // Debug unit clock
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
.dbg_i2c_addr (dbg_i2c_addr), // Debug interface: I2C Address
.dbg_i2c_broadcast (dbg_i2c_broadcast), // Debug interface: I2C Broadcast Address (for multicore systems)
.dbg_i2c_scl (dbg_i2c_scl), // Debug interface: I2C SCL
.dbg_i2c_sda_in (dbg_i2c_sda_in), // Debug interface: I2C SDA IN
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
.dbg_rst (dbg_rst), // Debug unit reset
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous)
.decode_noirq (decode_noirq), // Frontend decode instruction
.eu_mab (eu_mab), // Execution-Unit Memory address bus
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
.pc (pc), // Program counter
.puc_pnd_set (puc_pnd_set) // PUC pending set for the serial debug interface
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
.cpu_id (cpu_id), // CPU ID
.cpu_nr_inst (cpu_nr_inst), // Current oMSP instance number
.cpu_nr_total (cpu_nr_total), // Total number of oMSP instances-1
.dbg_clk (dbg_clk), // Debug unit clock
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
.dbg_halt_st (cpu_halt_st), // Halt/Run status from CPU
.dbg_i2c_addr (dbg_i2c_addr), // Debug interface: I2C Address
.dbg_i2c_broadcast (dbg_i2c_broadcast), // Debug interface: I2C Broadcast Address (for multicore systems)
.dbg_i2c_scl (dbg_i2c_scl), // Debug interface: I2C SCL
.dbg_i2c_sda_in (dbg_i2c_sda_in), // Debug interface: I2C SDA IN
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
.dbg_rst (dbg_rst), // Debug unit reset
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous)
.decode_noirq (decode_noirq), // Frontend decode instruction
.eu_mab (eu_mab), // Execution-Unit Memory address bus
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
.pc (pc), // Program counter
.puc_pnd_set (puc_pnd_set) // PUC pending set for the serial debug interface
);
 
`else
assign dbg_cpu_reset = 1'b0;
assign dbg_freeze = ~cpu_en_s;
assign dbg_halt_cmd = 1'b0;
assign dbg_i2c_sda_out = 1'b1;
assign dbg_mem_addr = 16'h0000;
assign dbg_mem_dout = 16'h0000;
assign dbg_mem_en = 1'b0;
assign dbg_mem_wr = 2'b00;
assign dbg_reg_wr = 1'b0;
assign dbg_uart_txd = 1'b1;
assign dbg_cpu_reset = 1'b0;
assign dbg_freeze = ~cpu_en_s;
assign dbg_halt_cmd = 1'b0;
assign dbg_i2c_sda_out = 1'b1;
assign dbg_mem_addr = 16'h0000;
assign dbg_mem_dout = 16'h0000;
assign dbg_mem_en = 1'b0;
assign dbg_mem_wr = 2'b00;
assign dbg_reg_wr = 1'b0;
assign dbg_uart_txd = 1'b1;
wire UNUSED_decode_noirq = decode_noirq;
wire [31:0] UNUSED_cpu_id = cpu_id;
wire UNUSED_eu_mab_0 = eu_mab[0];
wire UNUSED_dbg_clk = dbg_clk;
wire UNUSED_dbg_rst = dbg_rst;
wire UNUSED_dbg_en_s = dbg_en_s;
wire [15:0] UNUSED_dbg_mem_din = dbg_mem_din;
wire [15:0] UNUSED_dbg_reg_din = dbg_reg_din;
wire UNUSED_puc_pnd_set = puc_pnd_set;
wire [6:0] UNUSED_dbg_i2c_addr = dbg_i2c_addr;
wire [6:0] UNUSED_dbg_i2c_broadcast = dbg_i2c_broadcast;
wire UNUSED_dbg_i2c_scl = dbg_i2c_scl;
wire UNUSED_dbg_i2c_sda_in = dbg_i2c_sda_in;
wire UNUSED_dbg_uart_rxd = dbg_uart_rxd;
`endif
 
 
/openmsp430/openMSP430_undefines.v
26,9 → 26,9
// THE POSSIBILITY OF SUCH DAMAGE
//
//----------------------------------------------------------------------------
//
//
// *File Name: openMSP430_undefines.v
//
//
// *Module Description:
// openMSP430 Verilog `undef file
//
161,6 → 161,11
`undef WATCHDOG
`endif
 
// Include/Exclude DMA interface support
`ifdef DMA_IF_EN
`undef DMA_IF_EN
`endif
 
// Include/Exclude Non-Maskable-Interrupt support
`ifdef NMI
`undef NMI
705,6 → 710,18
`ifdef DIVAx
`undef DIVAx
`endif
`ifdef DMA_CPUOFF
`undef DMA_CPUOFF
`endif
`ifdef DMA_SCG0
`undef DMA_SCG0
`endif
`ifdef DMA_SCG1
`undef DMA_SCG1
`endif
`ifdef DMA_OSCOFF
`undef DMA_OSCOFF
`endif
 
// Basic clock module: BCSCTL2 Control Register
`ifdef SELMx
/openmsp430/omsp_sync_cell.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_sync_cell.v
//
//
// *Module Description:
// Generic synchronizer for the openMSP430
//
77,4 → 77,3
 
 
endmodule // omsp_sync_cell
 
/omsp_uart.v
28,7 → 28,7
//----------------------------------------------------------------------------
//
// *File Name: omsp_uart.v
//
//
// *Module Description:
// Simple full duplex UART (8N1 protocol).
//
97,7 → 97,7
DATA_TX = 'h4,
DATA_RX = 'h5;
 
 
// Register one-hot decoder utilities
parameter DEC_SZ = (1 << DEC_WD);
parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
104,11 → 104,11
 
// Register one-hot decoder
parameter [DEC_SZ-1:0] CTRL_D = (BASE_REG << CTRL),
STATUS_D = (BASE_REG << STATUS),
BAUD_LO_D = (BASE_REG << BAUD_LO),
BAUD_HI_D = (BASE_REG << BAUD_HI),
DATA_TX_D = (BASE_REG << DATA_TX),
DATA_RX_D = (BASE_REG << DATA_RX);
STATUS_D = (BASE_REG << STATUS),
BAUD_LO_D = (BASE_REG << BAUD_LO),
BAUD_HI_D = (BASE_REG << BAUD_HI),
DATA_TX_D = (BASE_REG << DATA_TX),
DATA_RX_D = (BASE_REG << DATA_RX);
 
 
//============================================================================
209,7 → 209,7
assign status = {status_tx_empty_pnd, status_tx_pnd, status_rx_ovflw_pnd, status_rx_pnd,
status_tx_full, status_tx_busy, 1'b0, status_rx_busy};
 
 
// BAUD_LO Register
//-----------------
reg [7:0] baud_lo;
235,8 → 235,8
 
 
wire [15:0] baudrate = {baud_hi, baud_lo};
 
 
// DATA_TX Register
//-----------------
reg [7:0] data_tx;
286,7 → 286,7
 
wire uclk_en = ctrl_smclk_sel ? smclk_en : 1'b1;
 
 
//=============================================================================
// 5) UART RECEIVE LINE SYNCHRONIZTION & FILTERING
//=============================================================================
297,13 → 297,12
 
omsp_sync_cell sync_cell_uart_rxd (
.data_out (uart_rxd_sync_n),
.data_meta (),
.data_in (~uart_rxd),
.clk (mclk),
.rst (puc_rst)
);
wire uart_rxd_sync = ~uart_rxd_sync_n;
 
// RXD input buffer
//--------------------------------
reg [1:0] rxd_buf;
319,7 → 318,7
{1'b0, rxd_buf[0]} +
{1'b0, rxd_buf[1]};
wire rxd_maj_nxt = (rxd_maj_cnt>=2'b10);
 
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) rxd_maj <= 1'b1;
else rxd_maj <= rxd_maj_nxt;
327,11 → 326,11
wire rxd_s = rxd_maj;
wire rxd_fe = rxd_maj & ~rxd_maj_nxt;
 
 
//=============================================================================
// 6) UART RECEIVE
//=============================================================================
 
// RX Transfer counter
//------------------------
reg [3:0] rxfer_bit;
399,13 → 398,13
//-----------------------------
reg txfer_triggered;
wire txfer_start;
 
always @ (posedge mclk or posedge puc_rst)
if (puc_rst) txfer_triggered <= 1'b0;
else if (data_tx_wr) txfer_triggered <= 1'b1;
else if (txfer_start) txfer_triggered <= 1'b0;
 
 
// TX Transfer counter
//------------------------
reg [3:0] txfer_bit;
453,7 → 452,7
 
assign uart_txd = txfer_buf[0];
 
 
// Status flags
//-------------------------
 
486,6 → 485,5
assign irq_uart_tx = (status_tx_pnd & ctrl_ien_tx) |
(status_tx_empty_pnd & ctrl_ien_tx_empty);
 
 
endmodule // uart
 

powered by: WebSVN 2.1.0

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