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
- from Rev 200 to Rev 202
- ↔ Reverse comparison
Rev 200 → Rev 202
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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]; |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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]}}); |
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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]}; |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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]; |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/openmsp430/omsp_wakeup_cell.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_wakeup_cell.v |
// |
// |
// *Module Description: |
// Generic Wakeup cell |
// |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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) |
); |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
/xilinx_avnet_lx9microbard/rtl/verilog/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 |
|
/xilinx_avnet_lx9microbard/sim/rtl_sim/src/submit.f
21,9 → 21,9
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
//----------------------------------------------------------------------------- |
// |
// |
// File Name: submit.f |
// |
// |
// Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
53,9 → 53,9
//============================================================================= |
+libext+.v |
|
-y /opt/Xilinx/14.2/ISE_DS/ISE/verilog/src/unisims/ |
-y /opt/Xilinx/14.2/ISE_DS/ISE/verilog/src/simprims/ |
-y /opt/Xilinx/14.2/ISE_DS/ISE/verilog/src/XilinxCoreLib/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/unisims/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/simprims/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/XilinxCoreLib/ |
|
|
//============================================================================= |
99,4 → 99,3
../../../rtl/verilog/openmsp430/omsp_clock_mux.v |
../../../rtl/verilog/openmsp430/periph/omsp_gpio.v |
../../../rtl/verilog/openmsp430/periph/omsp_timerA.v |
|
/xilinx_avnet_lx9microbard/software/leds/linker.x
1,14 → 1,17
/* Default linker script, for normal executables */ |
OUTPUT_FORMAT("elf32-msp430") |
OUTPUT_ARCH("msp430") |
MEMORY |
{ |
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x800 |
text (rx) : ORIGIN = 0xc000, LENGTH = 0x4000-0x20 |
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20 |
MEMORY { |
sfr : ORIGIN = 0x0000, LENGTH = 0x0010 |
peripheral_8bit : ORIGIN = 0x0010, LENGTH = 0x00f0 |
peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 |
ram (wx) : ORIGIN = 0x0200, LENGTH = 0x0800 |
rom (rx) : ORIGIN = 0xC000, LENGTH = 0x4000-0x20 |
vectors : ORIGIN = 0xffe0, LENGTH = 0x0020 |
} |
REGION_ALIAS("REGION_TEXT", text); |
REGION_ALIAS("REGION_DATA", data); |
REGION_ALIAS("REGION_TEXT", rom); |
REGION_ALIAS("REGION_DATA", ram); |
PROVIDE (__info_segment_size = 0x80); |
__WDTCTL = 0x0120; |
__MPY = 0x0130; |
__MPYS = 0x0132; |
22,142 → 25,160
SECTIONS |
{ |
/* Read-only sections, merged into text segment. */ |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.rela.init : { *(.rela.init) } |
.rel.text : |
{ |
*(.rel.text) |
*(.rel.text.*) |
*(.rel.gnu.linkonce.t*) |
} |
.rela.text : |
{ |
*(.rela.text) |
*(.rela.text.*) |
*(.rela.gnu.linkonce.t*) |
} |
.rel.fini : { *(.rel.fini) } |
.rel.fini : { *(.rel.fini) } |
.rela.fini : { *(.rela.fini) } |
.rel.rodata : |
{ |
*(.rel.rodata) |
*(.rel.rodata.*) |
*(.rel.gnu.linkonce.r*) |
} |
.rela.rodata : |
{ |
*(.rela.rodata) |
*(.rela.rodata.*) |
*(.rela.gnu.linkonce.r*) |
} |
.rel.data : |
{ |
*(.rel.data) |
*(.rel.data.*) |
*(.rel.gnu.linkonce.d*) |
} |
.rela.data : |
{ |
*(.rela.data) |
*(.rela.data.*) |
*(.rela.gnu.linkonce.d*) |
} |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.bss : { *(.rel.bss) } |
.rela.bss : { *(.rela.bss) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* Internal text space. */ |
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } |
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } |
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } |
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } |
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } |
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } |
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } |
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* .any.{text,rodata,data,bss}{,.*} sections are treated as orphans and |
* placed in output sections with available space by linker. Do not list |
* them here, or the linker will not consider them orphans. */ |
.text : |
{ |
. = ALIGN(2); |
*(.init) |
*(.init0) /* Start here after reset. */ |
*(.init1) |
*(.init2) /* Copy data loop */ |
*(.init3) |
*(.init4) /* Clear bss */ |
*(.init5) |
*(.init6) /* C++ constructors. */ |
*(.init7) |
*(.init8) |
*(.init9) /* Call main(). */ |
__ctors_start = . ; |
*(.ctors) |
__ctors_end = . ; |
__dtors_start = . ; |
*(.dtors) |
__dtors_end = . ; |
. = ALIGN(2); |
*(.text) |
. = ALIGN(2); |
*(.text.*) |
. = ALIGN(2); |
*(.fini9) /* */ |
*(.fini8) |
*(.fini7) |
*(.fini6) /* C++ destructors. */ |
*(.fini5) |
*(.fini4) |
*(.fini3) |
*(.fini2) |
*(.fini1) |
*(.fini0) /* Infinite loop after program termination. */ |
*(.fini) |
} > text |
. = ALIGN(2); |
KEEP(*(.init .init.*)) |
KEEP(*(.init0)) /* Start here after reset. */ |
KEEP(*(.init1)) /* User definable. */ |
KEEP(*(.init2)) /* Initialize stack. */ |
KEEP(*(.init3)) /* Initialize hardware, user definable. */ |
KEEP(*(.init4)) /* Copy data to .data, clear bss. */ |
KEEP(*(.init5)) /* User definable. */ |
KEEP(*(.init6)) /* C++ constructors. */ |
KEEP(*(.init7)) /* User definable. */ |
KEEP(*(.init8)) /* User definable. */ |
KEEP(*(.init9)) /* Call main(). */ |
KEEP(*(.fini9)) /* Falls into here after main(). User definable. */ |
KEEP(*(.fini8)) /* User definable. */ |
KEEP(*(.fini7)) /* User definable. */ |
KEEP(*(.fini6)) /* C++ destructors. */ |
KEEP(*(.fini5)) /* User definable. */ |
KEEP(*(.fini4)) /* User definable. */ |
KEEP(*(.fini3)) /* User definable. */ |
KEEP(*(.fini2)) /* User definable. */ |
KEEP(*(.fini1)) /* User definable. */ |
KEEP(*(.fini0)) /* Infinite loop after program termination. */ |
KEEP(*(.fini .fini.*)) |
. = ALIGN(2); |
__ctors_start = .; |
KEEP(*(.ctors)) |
__ctors_end = .; |
__dtors_start = .; |
KEEP(*(.dtors)) |
__dtors_end = .; |
. = ALIGN(2); |
*(.text .text.* .gnu.linkonce.t.*) |
*(.near.text .near.text.*) |
} > REGION_TEXT |
.rodata : |
{ |
. = ALIGN(2); |
*(.rodata .rodata.* .gnu.linkonce.r.*) |
. = ALIGN(2); |
} > text |
*(.near.rodata .near.rodata.*) |
} > REGION_TEXT |
. = ALIGN(2); |
_etext = .; /* Past last read-only (loadable) segment */ |
.data : AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata) ) |
.data : |
{ |
. = ALIGN(2); |
PROVIDE (__data_start = .) ; |
. = ALIGN(2); |
*(.data) |
. = ALIGN(2); |
*(.gnu.linkonce.d*) |
. = ALIGN(2); |
_edata = . ; |
} > data |
PROVIDE (__data_load_start = LOADADDR(.data) ); |
PROVIDE (__data_size = SIZEOF(.data) ); |
.bss SIZEOF(.data) + ADDR(.data) : |
PROVIDE (__datastart = .) ; |
*(.data .data.* .gnu.linkonce.d.*) |
*(.near.data .near.data.*) |
. = ALIGN(2); |
_edata = .; /* Past last read-write (loadable) segment */ |
} > REGION_DATA AT > REGION_TEXT |
__data_load_start = LOADADDR(.data); |
__data_size = SIZEOF(.data); |
.bss : |
{ |
PROVIDE (__bss_start = .) ; |
*(.bss) |
__bss_start = .; |
*(.bss .bss.*) |
*(.near.bss .near.bss.*) |
*(COMMON) |
PROVIDE (__bss_end = .) ; |
_end = . ; |
} > data |
PROVIDE (__bss_size = SIZEOF(.bss) ); |
.noinit SIZEOF(.bss) + ADDR(.bss) : |
. = ALIGN(2); |
__bss_end = .; |
} > REGION_DATA |
__bss_size = SIZEOF(.bss); |
.noinit : |
{ |
PROVIDE (__noinit_start = .) ; |
*(.noinit) |
*(COMMON) |
PROVIDE (__noinit_end = .) ; |
_end = . ; |
} > data |
.vectors : |
. = ALIGN(2); |
__noinit_start = .; |
*(.noinit .noinit.*) |
. = ALIGN(2); |
__noinit_end = .; |
} > REGION_DATA |
. = ALIGN(2); |
_end = .; /* Past last write (loadable) segment */ |
|
/* Values placed in the first 32 entries of a 64-entry interrupt vector |
* table. This exists because the FRAM chips place the BSL and JTAG |
* passwords at specific offsets that technically fall within the |
* interrupt table, but for which no MCU has a corresponding interrupt. |
* See https://sourceforge.net/tracker/?func=detail&aid=3554291&group_id=42303&atid=432701 */ |
PROVIDE(__vte_0 = 0xffff); |
PROVIDE(__vte_1 = 0xffff); |
PROVIDE(__vte_2 = 0xffff); |
PROVIDE(__vte_3 = 0xffff); |
PROVIDE(__vte_4 = 0xffff); |
PROVIDE(__vte_5 = 0xffff); |
PROVIDE(__vte_6 = 0xffff); |
PROVIDE(__vte_7 = 0xffff); |
PROVIDE(__vte_8 = 0xffff); |
PROVIDE(__vte_9 = 0xffff); |
PROVIDE(__vte_10 = 0xffff); |
PROVIDE(__vte_11 = 0xffff); |
PROVIDE(__vte_12 = 0xffff); |
PROVIDE(__vte_13 = 0xffff); |
PROVIDE(__vte_14 = 0xffff); |
PROVIDE(__vte_15 = 0xffff); |
PROVIDE(__vte_16 = 0xffff); |
PROVIDE(__vte_17 = 0xffff); |
PROVIDE(__vte_18 = 0xffff); |
PROVIDE(__vte_19 = 0xffff); |
PROVIDE(__vte_20 = 0xffff); |
PROVIDE(__vte_21 = 0xffff); |
PROVIDE(__vte_22 = 0xffff); |
PROVIDE(__vte_23 = 0xffff); |
PROVIDE(__vte_24 = 0xffff); |
PROVIDE(__vte_25 = 0xffff); |
PROVIDE(__vte_26 = 0xffff); |
PROVIDE(__vte_27 = 0xffff); |
PROVIDE(__vte_28 = 0xffff); |
PROVIDE(__vte_29 = 0xffff); |
PROVIDE(__vte_30 = 0xffff); |
PROVIDE(__vte_31 = 0xffff); |
.vectors : |
{ |
PROVIDE (__vectors_start = .) ; |
*(.vectors*) |
_vectors_end = . ; |
__vectors_start = .; |
KEEP(*(.vectors*)) |
_vectors_end = .; |
} > vectors |
/* Legacy section, prefer .far.text */ |
. = ALIGN(2); |
_efartext = .; /* Past last read-only (loadable) segment */ |
. = ALIGN(2); |
_far_end = .; /* Past last write (loadable) segment */ |
/* Stabs for profiling information*/ |
.profiler 0 : { *(.profiler) } |
/* Stabs debugging sections. */ |
188,7 → 209,14
.debug_str 0 : { *(.debug_str) } |
.debug_loc 0 : { *(.debug_loc) } |
.debug_macinfo 0 : { *(.debug_macinfo) } |
PROVIDE (__stack = ORIGIN(data) + LENGTH(data)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
/* DWARF 3 */ |
.debug_pubtypes 0 : { *(.debug_pubtypes) } |
.debug_ranges 0 : { *(.debug_ranges) } |
/* __stack is the only symbol that the user can override */ |
PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatastart = _etext) ; |
PROVIDE (__romdataend = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatacopysize = SIZEOF(.data)); |
} |
/xilinx_diligent_s3board/rtl/verilog/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 |
|
|
/xilinx_diligent_s3board/rtl/verilog/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 |
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_frontend.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_frontend.v |
// |
// |
// *Module Description: |
// openMSP430 Instruction fetch and decode unit |
// |
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]; |
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_alu.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_alu.v |
// |
// |
// *Module Description: |
// openMSP430 ALU |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_register_file.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_register_file.v |
// |
// |
// *Module Description: |
// openMSP430 Register files |
// |
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]}}); |
|
|
/xilinx_diligent_s3board/rtl/verilog/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 |
|
|
|
/xilinx_diligent_s3board/rtl/verilog/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]}; |
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_dbg_uart.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg_uart.v |
// |
// |
// *Module Description: |
// Debug UART communication interface (8N1, Half-duplex) |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_dbg_hwbrk.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg_hwbrk.v |
// |
// |
// *Module Description: |
// Hardware Breakpoint / Watchpoint module |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/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]; |
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_sfr.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_sfr.v |
// |
// |
// *Module Description: |
// Processor Special function register |
// Non-Maskable Interrupt generation |
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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_wakeup_cell.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_wakeup_cell.v |
// |
// |
// *Module Description: |
// Generic Wakeup cell |
// |
/xilinx_diligent_s3board/rtl/verilog/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 |
|
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_dbg.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg.v |
// |
// |
// *Module Description: |
// Debug interface |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_clock_module.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_clock_module.v |
// |
// |
// *Module Description: |
// Basic clock module implementation. |
// |
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) |
); |
|
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_watchdog.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_watchdog.v |
// |
// |
// *Module Description: |
// Watchdog Timer |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/omsp_execution_unit.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_execution_unit.v |
// |
// |
// *Module Description: |
// openMSP430 Execution unit |
// |
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 |
/xilinx_diligent_s3board/rtl/verilog/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 |
|
|
|
/xilinx_diligent_s3board/rtl/verilog/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 |
/xilinx_diligent_s3board/rtl/verilog/openmsp430/openMSP430.v
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 |
|
|
/xilinx_diligent_s3board/rtl/verilog/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 |
/xilinx_diligent_s3board/rtl/verilog/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 |
|
/xilinx_diligent_s3board/rtl/verilog/openMSP430_fpga.v
21,9 → 21,9
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
//---------------------------------------------------------------------------- |
// |
// |
// *File Name: openMSP430_fpga.v |
// |
// |
// *Module Description: |
// openMSP430 FPGA Top-level for the Diligent |
// Spartan-3 starter kit. |
334,7 → 334,7
wire hw_uart_txd; |
wire hw_uart_rxd; |
|
|
|
// Others |
wire reset_pin; |
|
362,12 → 362,12
.CLK90 (), |
.CLK180 (), |
.CLK270 (), |
.CLK2X (), |
.CLK2X (), |
.CLK2X180 (), |
.CLKDV (), |
.CLKFX (dcm_clk), |
.CLKFX180 (), |
.PSDONE (), |
.PSDONE (), |
.STATUS (), |
.LOCKED (dcm_locked), |
|
402,30 → 402,30
DCM dcm_adv_clk_main ( |
|
// OUTPUTs |
.CLKDV (dcm_clk), |
.CLKFX (), |
.CLKFX180 (), |
.CLK0 (CLK0_BUF), |
.CLK2X (), |
.CLK2X180 (), |
.CLK90 (), |
.CLK180 (), |
.CLK270 (), |
.LOCKED (dcm_locked), |
.PSDONE (), |
.CLKDV (dcm_clk), |
.CLKFX (), |
.CLKFX180 (), |
.CLK0 (CLK0_BUF), |
.CLK2X (), |
.CLK2X180 (), |
.CLK90 (), |
.CLK180 (), |
.CLK270 (), |
.LOCKED (dcm_locked), |
.PSDONE (), |
.STATUS (), |
|
// INPUTs |
.CLKFB (CLKFB_IN), |
.CLKIN (clk_50M_in), |
.PSEN (1'b0), |
.PSINCDEC (1'b0), |
.DSSEN (1'b0), |
.PSCLK (1'b0), |
.RST (reset_pin) |
.CLKFB (CLKFB_IN), |
.CLKIN (clk_50M_in), |
.PSEN (1'b0), |
.PSINCDEC (1'b0), |
.DSSEN (1'b0), |
.PSCLK (1'b0), |
.RST (reset_pin) |
); |
BUFG CLK0_BUFG_INST ( |
.I(CLK0_BUF), |
.I(CLK0_BUF), |
.O(CLKFB_IN) |
); |
|
444,19 → 444,19
defparam dcm_adv_clk_main.FACTORY_JF = 16'h8080; |
defparam dcm_adv_clk_main.PHASE_SHIFT = 0; |
defparam dcm_adv_clk_main.STARTUP_WAIT = "FALSE"; |
// synopsys translate_on |
// synopsys translate_on |
`endif |
|
|
|
//wire dcm_locked = 1'b1; |
//wire reset_n; |
|
|
//reg dcm_clk; |
//always @(posedge clk_50M_in) |
// if (~reset_n) dcm_clk <= 1'b0; |
// else dcm_clk <= ~dcm_clk; |
|
|
|
// Clock buffers |
//------------------------ |
BUFG buf_sys_clock (.O(clk_sys), .I(dcm_clk)); |
473,7 → 473,7
// Release the reset only, if the DCM is locked |
assign reset_n = reset_pin_n & dcm_locked; |
|
//Include the startup device |
//Include the startup device |
wire gsr_tb; |
wire gts_tb; |
STARTUP_SPARTAN3 xstartup (.CLK(clk_sys), .GSR(gsr_tb), .GTS(gts_tb)); |
501,6 → 501,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) |
525,6 → 528,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 |
572,7 → 581,7
.p6_dout_en (), // Port 6 data output enable |
.p6_sel (), // Port 6 function select |
.per_dout (per_dout_dio), // Peripheral data output |
|
|
// INPUTs |
.mclk (mclk), // Main system clock |
.p1_din (p1_din), // Port 1 data input |
626,7 → 635,7
.taclk (taclk) // TACLK external timer clock (SLOW) |
); |
|
|
|
// |
// Four-Digit, Seven-Segment LED Display driver |
//---------------------------------------------- |
690,7 → 699,7
per_dout_tA | |
per_dout_7seg | |
per_dout_uart; |
|
|
// |
// Assign interrupts |
//------------------------------- |
891,7 → 900,7
OBUF LED2_PIN (.I(p3_dout[2] & p3_dout_en[2]), .O(LED2)); |
OBUF LED1_PIN (.I(p3_dout[1] & p3_dout_en[1]), .O(LED1)); |
OBUF LED0_PIN (.I(p3_dout[0] & p3_dout_en[0]), .O(LED0)); |
|
|
// Push Button Switches |
//---------------------- |
IBUF BTN2_PIN (.O(), .I(BTN2)); |
949,7 → 958,7
IBUF UART_RXD_A_PIN (.O(), .I(UART_RXD_A)); |
OBUF UART_TXD_A_PIN (.I(1'b0), .O(UART_TXD_A)); |
|
|
|
// PS/2 Mouse/Keyboard Port |
//-------------------------- |
IOBUF PS2_D_PIN (.O(), .I(1'b0), .T(1'b1), .IO(PS2_D)); |
1026,4 → 1035,3
|
|
endmodule // openMSP430_fpga |
|
/xilinx_diligent_s3board/rtl/verilog/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 |
|
/xilinx_diligent_s3board/sim/rtl_sim/src/submit.f
21,9 → 21,9
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
//----------------------------------------------------------------------------- |
// |
// |
// File Name: submit.f |
// |
// |
// Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
48,9 → 48,9
//============================================================================= |
+libext+.v |
|
-y /opt/Xilinx/12.2/ISE_DS/ISE/verilog/src/unisims/ |
-y /opt/Xilinx/12.2/ISE_DS/ISE/verilog/src/simprims/ |
-y /opt/Xilinx/12.2/ISE_DS/ISE/verilog/src/XilinxCoreLib/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/unisims/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/simprims/ |
-y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/XilinxCoreLib/ |
|
|
//============================================================================= |
97,4 → 97,3
../../../rtl/verilog/openmsp430/omsp_clock_mux.v |
../../../rtl/verilog/openmsp430/periph/omsp_gpio.v |
../../../rtl/verilog/openmsp430/periph/omsp_timerA.v |
|
/xilinx_diligent_s3board/software/leds/linker.x
1,14 → 1,17
/* Default linker script, for normal executables */ |
OUTPUT_FORMAT("elf32-msp430") |
OUTPUT_ARCH("msp430") |
MEMORY |
{ |
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x400 |
text (rx) : ORIGIN = 0xf000, LENGTH = 0x1000-0x20 |
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20 |
MEMORY { |
sfr : ORIGIN = 0x0000, LENGTH = 0x0010 |
peripheral_8bit : ORIGIN = 0x0010, LENGTH = 0x00f0 |
peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 |
ram (wx) : ORIGIN = 0x0200, LENGTH = 0x0400 |
rom (rx) : ORIGIN = 0xF000, LENGTH = 0x1000-0x20 |
vectors : ORIGIN = 0xffe0, LENGTH = 0x0020 |
} |
REGION_ALIAS("REGION_TEXT", text); |
REGION_ALIAS("REGION_DATA", data); |
REGION_ALIAS("REGION_TEXT", rom); |
REGION_ALIAS("REGION_DATA", ram); |
PROVIDE (__info_segment_size = 0x80); |
__WDTCTL = 0x0120; |
__MPY = 0x0130; |
__MPYS = 0x0132; |
22,142 → 25,160
SECTIONS |
{ |
/* Read-only sections, merged into text segment. */ |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.rela.init : { *(.rela.init) } |
.rel.text : |
{ |
*(.rel.text) |
*(.rel.text.*) |
*(.rel.gnu.linkonce.t*) |
} |
.rela.text : |
{ |
*(.rela.text) |
*(.rela.text.*) |
*(.rela.gnu.linkonce.t*) |
} |
.rel.fini : { *(.rel.fini) } |
.rel.fini : { *(.rel.fini) } |
.rela.fini : { *(.rela.fini) } |
.rel.rodata : |
{ |
*(.rel.rodata) |
*(.rel.rodata.*) |
*(.rel.gnu.linkonce.r*) |
} |
.rela.rodata : |
{ |
*(.rela.rodata) |
*(.rela.rodata.*) |
*(.rela.gnu.linkonce.r*) |
} |
.rel.data : |
{ |
*(.rel.data) |
*(.rel.data.*) |
*(.rel.gnu.linkonce.d*) |
} |
.rela.data : |
{ |
*(.rela.data) |
*(.rela.data.*) |
*(.rela.gnu.linkonce.d*) |
} |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.bss : { *(.rel.bss) } |
.rela.bss : { *(.rela.bss) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* Internal text space. */ |
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } |
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } |
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } |
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } |
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } |
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } |
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } |
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* .any.{text,rodata,data,bss}{,.*} sections are treated as orphans and |
* placed in output sections with available space by linker. Do not list |
* them here, or the linker will not consider them orphans. */ |
.text : |
{ |
. = ALIGN(2); |
*(.init) |
*(.init0) /* Start here after reset. */ |
*(.init1) |
*(.init2) /* Copy data loop */ |
*(.init3) |
*(.init4) /* Clear bss */ |
*(.init5) |
*(.init6) /* C++ constructors. */ |
*(.init7) |
*(.init8) |
*(.init9) /* Call main(). */ |
__ctors_start = . ; |
*(.ctors) |
__ctors_end = . ; |
__dtors_start = . ; |
*(.dtors) |
__dtors_end = . ; |
. = ALIGN(2); |
*(.text) |
. = ALIGN(2); |
*(.text.*) |
. = ALIGN(2); |
*(.fini9) /* */ |
*(.fini8) |
*(.fini7) |
*(.fini6) /* C++ destructors. */ |
*(.fini5) |
*(.fini4) |
*(.fini3) |
*(.fini2) |
*(.fini1) |
*(.fini0) /* Infinite loop after program termination. */ |
*(.fini) |
} > text |
. = ALIGN(2); |
KEEP(*(.init .init.*)) |
KEEP(*(.init0)) /* Start here after reset. */ |
KEEP(*(.init1)) /* User definable. */ |
KEEP(*(.init2)) /* Initialize stack. */ |
KEEP(*(.init3)) /* Initialize hardware, user definable. */ |
KEEP(*(.init4)) /* Copy data to .data, clear bss. */ |
KEEP(*(.init5)) /* User definable. */ |
KEEP(*(.init6)) /* C++ constructors. */ |
KEEP(*(.init7)) /* User definable. */ |
KEEP(*(.init8)) /* User definable. */ |
KEEP(*(.init9)) /* Call main(). */ |
KEEP(*(.fini9)) /* Falls into here after main(). User definable. */ |
KEEP(*(.fini8)) /* User definable. */ |
KEEP(*(.fini7)) /* User definable. */ |
KEEP(*(.fini6)) /* C++ destructors. */ |
KEEP(*(.fini5)) /* User definable. */ |
KEEP(*(.fini4)) /* User definable. */ |
KEEP(*(.fini3)) /* User definable. */ |
KEEP(*(.fini2)) /* User definable. */ |
KEEP(*(.fini1)) /* User definable. */ |
KEEP(*(.fini0)) /* Infinite loop after program termination. */ |
KEEP(*(.fini .fini.*)) |
. = ALIGN(2); |
__ctors_start = .; |
KEEP(*(.ctors)) |
__ctors_end = .; |
__dtors_start = .; |
KEEP(*(.dtors)) |
__dtors_end = .; |
. = ALIGN(2); |
*(.text .text.* .gnu.linkonce.t.*) |
*(.near.text .near.text.*) |
} > REGION_TEXT |
.rodata : |
{ |
. = ALIGN(2); |
*(.rodata .rodata.* .gnu.linkonce.r.*) |
. = ALIGN(2); |
} > text |
*(.near.rodata .near.rodata.*) |
} > REGION_TEXT |
. = ALIGN(2); |
_etext = .; /* Past last read-only (loadable) segment */ |
.data : AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata) ) |
.data : |
{ |
. = ALIGN(2); |
PROVIDE (__data_start = .) ; |
. = ALIGN(2); |
*(.data) |
. = ALIGN(2); |
*(.gnu.linkonce.d*) |
. = ALIGN(2); |
_edata = . ; |
} > data |
PROVIDE (__data_load_start = LOADADDR(.data) ); |
PROVIDE (__data_size = SIZEOF(.data) ); |
.bss SIZEOF(.data) + ADDR(.data) : |
PROVIDE (__datastart = .) ; |
*(.data .data.* .gnu.linkonce.d.*) |
*(.near.data .near.data.*) |
. = ALIGN(2); |
_edata = .; /* Past last read-write (loadable) segment */ |
} > REGION_DATA AT > REGION_TEXT |
__data_load_start = LOADADDR(.data); |
__data_size = SIZEOF(.data); |
.bss : |
{ |
PROVIDE (__bss_start = .) ; |
*(.bss) |
__bss_start = .; |
*(.bss .bss.*) |
*(.near.bss .near.bss.*) |
*(COMMON) |
PROVIDE (__bss_end = .) ; |
_end = . ; |
} > data |
PROVIDE (__bss_size = SIZEOF(.bss) ); |
.noinit SIZEOF(.bss) + ADDR(.bss) : |
. = ALIGN(2); |
__bss_end = .; |
} > REGION_DATA |
__bss_size = SIZEOF(.bss); |
.noinit : |
{ |
PROVIDE (__noinit_start = .) ; |
*(.noinit) |
*(COMMON) |
PROVIDE (__noinit_end = .) ; |
_end = . ; |
} > data |
.vectors : |
. = ALIGN(2); |
__noinit_start = .; |
*(.noinit .noinit.*) |
. = ALIGN(2); |
__noinit_end = .; |
} > REGION_DATA |
. = ALIGN(2); |
_end = .; /* Past last write (loadable) segment */ |
|
/* Values placed in the first 32 entries of a 64-entry interrupt vector |
* table. This exists because the FRAM chips place the BSL and JTAG |
* passwords at specific offsets that technically fall within the |
* interrupt table, but for which no MCU has a corresponding interrupt. |
* See https://sourceforge.net/tracker/?func=detail&aid=3554291&group_id=42303&atid=432701 */ |
PROVIDE(__vte_0 = 0xffff); |
PROVIDE(__vte_1 = 0xffff); |
PROVIDE(__vte_2 = 0xffff); |
PROVIDE(__vte_3 = 0xffff); |
PROVIDE(__vte_4 = 0xffff); |
PROVIDE(__vte_5 = 0xffff); |
PROVIDE(__vte_6 = 0xffff); |
PROVIDE(__vte_7 = 0xffff); |
PROVIDE(__vte_8 = 0xffff); |
PROVIDE(__vte_9 = 0xffff); |
PROVIDE(__vte_10 = 0xffff); |
PROVIDE(__vte_11 = 0xffff); |
PROVIDE(__vte_12 = 0xffff); |
PROVIDE(__vte_13 = 0xffff); |
PROVIDE(__vte_14 = 0xffff); |
PROVIDE(__vte_15 = 0xffff); |
PROVIDE(__vte_16 = 0xffff); |
PROVIDE(__vte_17 = 0xffff); |
PROVIDE(__vte_18 = 0xffff); |
PROVIDE(__vte_19 = 0xffff); |
PROVIDE(__vte_20 = 0xffff); |
PROVIDE(__vte_21 = 0xffff); |
PROVIDE(__vte_22 = 0xffff); |
PROVIDE(__vte_23 = 0xffff); |
PROVIDE(__vte_24 = 0xffff); |
PROVIDE(__vte_25 = 0xffff); |
PROVIDE(__vte_26 = 0xffff); |
PROVIDE(__vte_27 = 0xffff); |
PROVIDE(__vte_28 = 0xffff); |
PROVIDE(__vte_29 = 0xffff); |
PROVIDE(__vte_30 = 0xffff); |
PROVIDE(__vte_31 = 0xffff); |
.vectors : |
{ |
PROVIDE (__vectors_start = .) ; |
*(.vectors*) |
_vectors_end = . ; |
__vectors_start = .; |
KEEP(*(.vectors*)) |
_vectors_end = .; |
} > vectors |
/* Legacy section, prefer .far.text */ |
. = ALIGN(2); |
_efartext = .; /* Past last read-only (loadable) segment */ |
. = ALIGN(2); |
_far_end = .; /* Past last write (loadable) segment */ |
/* Stabs for profiling information*/ |
.profiler 0 : { *(.profiler) } |
/* Stabs debugging sections. */ |
188,7 → 209,14
.debug_str 0 : { *(.debug_str) } |
.debug_loc 0 : { *(.debug_loc) } |
.debug_macinfo 0 : { *(.debug_macinfo) } |
PROVIDE (__stack = ORIGIN(data) + LENGTH(data)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
/* DWARF 3 */ |
.debug_pubtypes 0 : { *(.debug_pubtypes) } |
.debug_ranges 0 : { *(.debug_ranges) } |
/* __stack is the only symbol that the user can override */ |
PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatastart = _etext) ; |
PROVIDE (__romdataend = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatacopysize = SIZEOF(.data)); |
} |
/xilinx_diligent_s3board/software/hw_uart/linker.x
1,14 → 1,17
/* Default linker script, for normal executables */ |
OUTPUT_FORMAT("elf32-msp430") |
OUTPUT_ARCH("msp430") |
MEMORY |
{ |
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x400 |
text (rx) : ORIGIN = 0xf000, LENGTH = 0x1000-0x20 |
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20 |
MEMORY { |
sfr : ORIGIN = 0x0000, LENGTH = 0x0010 |
peripheral_8bit : ORIGIN = 0x0010, LENGTH = 0x00f0 |
peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 |
ram (wx) : ORIGIN = 0x0200, LENGTH = 0x0400 |
rom (rx) : ORIGIN = 0xF000, LENGTH = 0x1000-0x20 |
vectors : ORIGIN = 0xffe0, LENGTH = 0x0020 |
} |
REGION_ALIAS("REGION_TEXT", text); |
REGION_ALIAS("REGION_DATA", data); |
REGION_ALIAS("REGION_TEXT", rom); |
REGION_ALIAS("REGION_DATA", ram); |
PROVIDE (__info_segment_size = 0x80); |
__WDTCTL = 0x0120; |
__MPY = 0x0130; |
__MPYS = 0x0132; |
22,142 → 25,160
SECTIONS |
{ |
/* Read-only sections, merged into text segment. */ |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.rela.init : { *(.rela.init) } |
.rel.text : |
{ |
*(.rel.text) |
*(.rel.text.*) |
*(.rel.gnu.linkonce.t*) |
} |
.rela.text : |
{ |
*(.rela.text) |
*(.rela.text.*) |
*(.rela.gnu.linkonce.t*) |
} |
.rel.fini : { *(.rel.fini) } |
.rel.fini : { *(.rel.fini) } |
.rela.fini : { *(.rela.fini) } |
.rel.rodata : |
{ |
*(.rel.rodata) |
*(.rel.rodata.*) |
*(.rel.gnu.linkonce.r*) |
} |
.rela.rodata : |
{ |
*(.rela.rodata) |
*(.rela.rodata.*) |
*(.rela.gnu.linkonce.r*) |
} |
.rel.data : |
{ |
*(.rel.data) |
*(.rel.data.*) |
*(.rel.gnu.linkonce.d*) |
} |
.rela.data : |
{ |
*(.rela.data) |
*(.rela.data.*) |
*(.rela.gnu.linkonce.d*) |
} |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.bss : { *(.rel.bss) } |
.rela.bss : { *(.rela.bss) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* Internal text space. */ |
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } |
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } |
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } |
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } |
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } |
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } |
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } |
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* .any.{text,rodata,data,bss}{,.*} sections are treated as orphans and |
* placed in output sections with available space by linker. Do not list |
* them here, or the linker will not consider them orphans. */ |
.text : |
{ |
. = ALIGN(2); |
*(.init) |
*(.init0) /* Start here after reset. */ |
*(.init1) |
*(.init2) /* Copy data loop */ |
*(.init3) |
*(.init4) /* Clear bss */ |
*(.init5) |
*(.init6) /* C++ constructors. */ |
*(.init7) |
*(.init8) |
*(.init9) /* Call main(). */ |
__ctors_start = . ; |
*(.ctors) |
__ctors_end = . ; |
__dtors_start = . ; |
*(.dtors) |
__dtors_end = . ; |
. = ALIGN(2); |
*(.text) |
. = ALIGN(2); |
*(.text.*) |
. = ALIGN(2); |
*(.fini9) /* */ |
*(.fini8) |
*(.fini7) |
*(.fini6) /* C++ destructors. */ |
*(.fini5) |
*(.fini4) |
*(.fini3) |
*(.fini2) |
*(.fini1) |
*(.fini0) /* Infinite loop after program termination. */ |
*(.fini) |
} > text |
. = ALIGN(2); |
KEEP(*(.init .init.*)) |
KEEP(*(.init0)) /* Start here after reset. */ |
KEEP(*(.init1)) /* User definable. */ |
KEEP(*(.init2)) /* Initialize stack. */ |
KEEP(*(.init3)) /* Initialize hardware, user definable. */ |
KEEP(*(.init4)) /* Copy data to .data, clear bss. */ |
KEEP(*(.init5)) /* User definable. */ |
KEEP(*(.init6)) /* C++ constructors. */ |
KEEP(*(.init7)) /* User definable. */ |
KEEP(*(.init8)) /* User definable. */ |
KEEP(*(.init9)) /* Call main(). */ |
KEEP(*(.fini9)) /* Falls into here after main(). User definable. */ |
KEEP(*(.fini8)) /* User definable. */ |
KEEP(*(.fini7)) /* User definable. */ |
KEEP(*(.fini6)) /* C++ destructors. */ |
KEEP(*(.fini5)) /* User definable. */ |
KEEP(*(.fini4)) /* User definable. */ |
KEEP(*(.fini3)) /* User definable. */ |
KEEP(*(.fini2)) /* User definable. */ |
KEEP(*(.fini1)) /* User definable. */ |
KEEP(*(.fini0)) /* Infinite loop after program termination. */ |
KEEP(*(.fini .fini.*)) |
. = ALIGN(2); |
__ctors_start = .; |
KEEP(*(.ctors)) |
__ctors_end = .; |
__dtors_start = .; |
KEEP(*(.dtors)) |
__dtors_end = .; |
. = ALIGN(2); |
*(.text .text.* .gnu.linkonce.t.*) |
*(.near.text .near.text.*) |
} > REGION_TEXT |
.rodata : |
{ |
. = ALIGN(2); |
*(.rodata .rodata.* .gnu.linkonce.r.*) |
. = ALIGN(2); |
} > text |
*(.near.rodata .near.rodata.*) |
} > REGION_TEXT |
. = ALIGN(2); |
_etext = .; /* Past last read-only (loadable) segment */ |
.data : AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata) ) |
.data : |
{ |
. = ALIGN(2); |
PROVIDE (__data_start = .) ; |
. = ALIGN(2); |
*(.data) |
. = ALIGN(2); |
*(.gnu.linkonce.d*) |
. = ALIGN(2); |
_edata = . ; |
} > data |
PROVIDE (__data_load_start = LOADADDR(.data) ); |
PROVIDE (__data_size = SIZEOF(.data) ); |
.bss SIZEOF(.data) + ADDR(.data) : |
PROVIDE (__datastart = .) ; |
*(.data .data.* .gnu.linkonce.d.*) |
*(.near.data .near.data.*) |
. = ALIGN(2); |
_edata = .; /* Past last read-write (loadable) segment */ |
} > REGION_DATA AT > REGION_TEXT |
__data_load_start = LOADADDR(.data); |
__data_size = SIZEOF(.data); |
.bss : |
{ |
PROVIDE (__bss_start = .) ; |
*(.bss) |
__bss_start = .; |
*(.bss .bss.*) |
*(.near.bss .near.bss.*) |
*(COMMON) |
PROVIDE (__bss_end = .) ; |
_end = . ; |
} > data |
PROVIDE (__bss_size = SIZEOF(.bss) ); |
.noinit SIZEOF(.bss) + ADDR(.bss) : |
. = ALIGN(2); |
__bss_end = .; |
} > REGION_DATA |
__bss_size = SIZEOF(.bss); |
.noinit : |
{ |
PROVIDE (__noinit_start = .) ; |
*(.noinit) |
*(COMMON) |
PROVIDE (__noinit_end = .) ; |
_end = . ; |
} > data |
.vectors : |
. = ALIGN(2); |
__noinit_start = .; |
*(.noinit .noinit.*) |
. = ALIGN(2); |
__noinit_end = .; |
} > REGION_DATA |
. = ALIGN(2); |
_end = .; /* Past last write (loadable) segment */ |
|
/* Values placed in the first 32 entries of a 64-entry interrupt vector |
* table. This exists because the FRAM chips place the BSL and JTAG |
* passwords at specific offsets that technically fall within the |
* interrupt table, but for which no MCU has a corresponding interrupt. |
* See https://sourceforge.net/tracker/?func=detail&aid=3554291&group_id=42303&atid=432701 */ |
PROVIDE(__vte_0 = 0xffff); |
PROVIDE(__vte_1 = 0xffff); |
PROVIDE(__vte_2 = 0xffff); |
PROVIDE(__vte_3 = 0xffff); |
PROVIDE(__vte_4 = 0xffff); |
PROVIDE(__vte_5 = 0xffff); |
PROVIDE(__vte_6 = 0xffff); |
PROVIDE(__vte_7 = 0xffff); |
PROVIDE(__vte_8 = 0xffff); |
PROVIDE(__vte_9 = 0xffff); |
PROVIDE(__vte_10 = 0xffff); |
PROVIDE(__vte_11 = 0xffff); |
PROVIDE(__vte_12 = 0xffff); |
PROVIDE(__vte_13 = 0xffff); |
PROVIDE(__vte_14 = 0xffff); |
PROVIDE(__vte_15 = 0xffff); |
PROVIDE(__vte_16 = 0xffff); |
PROVIDE(__vte_17 = 0xffff); |
PROVIDE(__vte_18 = 0xffff); |
PROVIDE(__vte_19 = 0xffff); |
PROVIDE(__vte_20 = 0xffff); |
PROVIDE(__vte_21 = 0xffff); |
PROVIDE(__vte_22 = 0xffff); |
PROVIDE(__vte_23 = 0xffff); |
PROVIDE(__vte_24 = 0xffff); |
PROVIDE(__vte_25 = 0xffff); |
PROVIDE(__vte_26 = 0xffff); |
PROVIDE(__vte_27 = 0xffff); |
PROVIDE(__vte_28 = 0xffff); |
PROVIDE(__vte_29 = 0xffff); |
PROVIDE(__vte_30 = 0xffff); |
PROVIDE(__vte_31 = 0xffff); |
.vectors : |
{ |
PROVIDE (__vectors_start = .) ; |
*(.vectors*) |
_vectors_end = . ; |
__vectors_start = .; |
KEEP(*(.vectors*)) |
_vectors_end = .; |
} > vectors |
/* Legacy section, prefer .far.text */ |
. = ALIGN(2); |
_efartext = .; /* Past last read-only (loadable) segment */ |
. = ALIGN(2); |
_far_end = .; /* Past last write (loadable) segment */ |
/* Stabs for profiling information*/ |
.profiler 0 : { *(.profiler) } |
/* Stabs debugging sections. */ |
188,7 → 209,14
.debug_str 0 : { *(.debug_str) } |
.debug_loc 0 : { *(.debug_loc) } |
.debug_macinfo 0 : { *(.debug_macinfo) } |
PROVIDE (__stack = ORIGIN(data) + LENGTH(data)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
/* DWARF 3 */ |
.debug_pubtypes 0 : { *(.debug_pubtypes) } |
.debug_ranges 0 : { *(.debug_ranges) } |
/* __stack is the only symbol that the user can override */ |
PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatastart = _etext) ; |
PROVIDE (__romdataend = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatacopysize = SIZEOF(.data)); |
} |
/altera_de1_board/rtl/verilog/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 |
|
|
/altera_de1_board/rtl/verilog/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 |
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_frontend.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_frontend.v |
// |
// |
// *Module Description: |
// openMSP430 Instruction fetch and decode unit |
// |
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]; |
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_alu.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_alu.v |
// |
// |
// *Module Description: |
// openMSP430 ALU |
// |
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 |
/altera_de1_board/rtl/verilog/openmsp430/omsp_register_file.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_register_file.v |
// |
// |
// *Module Description: |
// openMSP430 Register files |
// |
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]}}); |
|
|
/altera_de1_board/rtl/verilog/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 |
|
|
|
/altera_de1_board/rtl/verilog/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]}; |
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_dbg_uart.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg_uart.v |
// |
// |
// *Module Description: |
// Debug UART communication interface (8N1, Half-duplex) |
// |
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 |
/altera_de1_board/rtl/verilog/openmsp430/omsp_dbg_hwbrk.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg_hwbrk.v |
// |
// |
// *Module Description: |
// Hardware Breakpoint / Watchpoint module |
// |
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 |
/altera_de1_board/rtl/verilog/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]; |
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_sfr.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_sfr.v |
// |
// |
// *Module Description: |
// Processor Special function register |
// Non-Maskable Interrupt generation |
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 |
/altera_de1_board/rtl/verilog/openmsp430/omsp_wakeup_cell.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_wakeup_cell.v |
// |
// |
// *Module Description: |
// Generic Wakeup cell |
// |
/altera_de1_board/rtl/verilog/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 |
|
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_dbg.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_dbg.v |
// |
// |
// *Module Description: |
// Debug interface |
// |
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 |
/altera_de1_board/rtl/verilog/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 |
/altera_de1_board/rtl/verilog/openmsp430/omsp_clock_module.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_clock_module.v |
// |
// |
// *Module Description: |
// Basic clock module implementation. |
// |
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) |
); |
|
/altera_de1_board/rtl/verilog/openmsp430/omsp_watchdog.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_watchdog.v |
// |
// |
// *Module Description: |
// Watchdog Timer |
// |
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 |
/altera_de1_board/rtl/verilog/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 |
/altera_de1_board/rtl/verilog/openmsp430/omsp_execution_unit.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_execution_unit.v |
// |
// |
// *Module Description: |
// openMSP430 Execution unit |
// |
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 |
/altera_de1_board/rtl/verilog/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 |
|
|
|
/altera_de1_board/rtl/verilog/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 |
/altera_de1_board/rtl/verilog/openmsp430/openMSP430.v
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 |
|
|
/altera_de1_board/rtl/verilog/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 |
/altera_de1_board/rtl/verilog/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 |
|
/altera_de1_board/rtl/verilog/OpenMSP430_fpga.v
308,6 → 308,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) |
332,6 → 335,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 |
693,4 → 702,3
|
|
endmodule |
|
/altera_de1_board/software/memledtest/link.ld
1,14 → 1,17
/* Default linker script, for normal executables */ |
OUTPUT_FORMAT("elf32-msp430") |
OUTPUT_ARCH("msp430") |
MEMORY |
{ |
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x400 |
text (rx) : ORIGIN = 0xf000, LENGTH = 0x1000-0x20 |
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20 |
MEMORY { |
sfr : ORIGIN = 0x0000, LENGTH = 0x0010 |
peripheral_8bit : ORIGIN = 0x0010, LENGTH = 0x00f0 |
peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 |
ram (wx) : ORIGIN = 0x0200, LENGTH = 0x0400 |
rom (rx) : ORIGIN = 0xF000, LENGTH = 0x1000-0x20 |
vectors : ORIGIN = 0xffe0, LENGTH = 0x0020 |
} |
REGION_ALIAS("REGION_TEXT", text); |
REGION_ALIAS("REGION_DATA", data); |
REGION_ALIAS("REGION_TEXT", rom); |
REGION_ALIAS("REGION_DATA", ram); |
PROVIDE (__info_segment_size = 0x80); |
__WDTCTL = 0x0120; |
__MPY = 0x0130; |
__MPYS = 0x0132; |
22,142 → 25,160
SECTIONS |
{ |
/* Read-only sections, merged into text segment. */ |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.rela.init : { *(.rela.init) } |
.rel.text : |
{ |
*(.rel.text) |
*(.rel.text.*) |
*(.rel.gnu.linkonce.t*) |
} |
.rela.text : |
{ |
*(.rela.text) |
*(.rela.text.*) |
*(.rela.gnu.linkonce.t*) |
} |
.rel.fini : { *(.rel.fini) } |
.rel.fini : { *(.rel.fini) } |
.rela.fini : { *(.rela.fini) } |
.rel.rodata : |
{ |
*(.rel.rodata) |
*(.rel.rodata.*) |
*(.rel.gnu.linkonce.r*) |
} |
.rela.rodata : |
{ |
*(.rela.rodata) |
*(.rela.rodata.*) |
*(.rela.gnu.linkonce.r*) |
} |
.rel.data : |
{ |
*(.rel.data) |
*(.rel.data.*) |
*(.rel.gnu.linkonce.d*) |
} |
.rela.data : |
{ |
*(.rela.data) |
*(.rela.data.*) |
*(.rela.gnu.linkonce.d*) |
} |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.bss : { *(.rel.bss) } |
.rela.bss : { *(.rela.bss) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* Internal text space. */ |
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } |
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } |
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } |
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } |
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } |
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } |
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } |
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* .any.{text,rodata,data,bss}{,.*} sections are treated as orphans and |
* placed in output sections with available space by linker. Do not list |
* them here, or the linker will not consider them orphans. */ |
.text : |
{ |
. = ALIGN(2); |
*(.init) |
*(.init0) /* Start here after reset. */ |
*(.init1) |
*(.init2) /* Copy data loop */ |
*(.init3) |
*(.init4) /* Clear bss */ |
*(.init5) |
*(.init6) /* C++ constructors. */ |
*(.init7) |
*(.init8) |
*(.init9) /* Call main(). */ |
__ctors_start = . ; |
*(.ctors) |
__ctors_end = . ; |
__dtors_start = . ; |
*(.dtors) |
__dtors_end = . ; |
. = ALIGN(2); |
*(.text) |
. = ALIGN(2); |
*(.text.*) |
. = ALIGN(2); |
*(.fini9) /* */ |
*(.fini8) |
*(.fini7) |
*(.fini6) /* C++ destructors. */ |
*(.fini5) |
*(.fini4) |
*(.fini3) |
*(.fini2) |
*(.fini1) |
*(.fini0) /* Infinite loop after program termination. */ |
*(.fini) |
} > text |
. = ALIGN(2); |
KEEP(*(.init .init.*)) |
KEEP(*(.init0)) /* Start here after reset. */ |
KEEP(*(.init1)) /* User definable. */ |
KEEP(*(.init2)) /* Initialize stack. */ |
KEEP(*(.init3)) /* Initialize hardware, user definable. */ |
KEEP(*(.init4)) /* Copy data to .data, clear bss. */ |
KEEP(*(.init5)) /* User definable. */ |
KEEP(*(.init6)) /* C++ constructors. */ |
KEEP(*(.init7)) /* User definable. */ |
KEEP(*(.init8)) /* User definable. */ |
KEEP(*(.init9)) /* Call main(). */ |
KEEP(*(.fini9)) /* Falls into here after main(). User definable. */ |
KEEP(*(.fini8)) /* User definable. */ |
KEEP(*(.fini7)) /* User definable. */ |
KEEP(*(.fini6)) /* C++ destructors. */ |
KEEP(*(.fini5)) /* User definable. */ |
KEEP(*(.fini4)) /* User definable. */ |
KEEP(*(.fini3)) /* User definable. */ |
KEEP(*(.fini2)) /* User definable. */ |
KEEP(*(.fini1)) /* User definable. */ |
KEEP(*(.fini0)) /* Infinite loop after program termination. */ |
KEEP(*(.fini .fini.*)) |
. = ALIGN(2); |
__ctors_start = .; |
KEEP(*(.ctors)) |
__ctors_end = .; |
__dtors_start = .; |
KEEP(*(.dtors)) |
__dtors_end = .; |
. = ALIGN(2); |
*(.text .text.* .gnu.linkonce.t.*) |
*(.near.text .near.text.*) |
} > REGION_TEXT |
.rodata : |
{ |
. = ALIGN(2); |
*(.rodata .rodata.* .gnu.linkonce.r.*) |
. = ALIGN(2); |
} > text |
*(.near.rodata .near.rodata.*) |
} > REGION_TEXT |
. = ALIGN(2); |
_etext = .; /* Past last read-only (loadable) segment */ |
.data : AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata) ) |
.data : |
{ |
. = ALIGN(2); |
PROVIDE (__data_start = .) ; |
. = ALIGN(2); |
*(.data) |
. = ALIGN(2); |
*(.gnu.linkonce.d*) |
. = ALIGN(2); |
_edata = . ; |
} > data |
PROVIDE (__data_load_start = LOADADDR(.data) ); |
PROVIDE (__data_size = SIZEOF(.data) ); |
.bss SIZEOF(.data) + ADDR(.data) : |
PROVIDE (__datastart = .) ; |
*(.data .data.* .gnu.linkonce.d.*) |
*(.near.data .near.data.*) |
. = ALIGN(2); |
_edata = .; /* Past last read-write (loadable) segment */ |
} > REGION_DATA AT > REGION_TEXT |
__data_load_start = LOADADDR(.data); |
__data_size = SIZEOF(.data); |
.bss : |
{ |
PROVIDE (__bss_start = .) ; |
*(.bss) |
__bss_start = .; |
*(.bss .bss.*) |
*(.near.bss .near.bss.*) |
*(COMMON) |
PROVIDE (__bss_end = .) ; |
_end = . ; |
} > data |
PROVIDE (__bss_size = SIZEOF(.bss) ); |
.noinit SIZEOF(.bss) + ADDR(.bss) : |
. = ALIGN(2); |
__bss_end = .; |
} > REGION_DATA |
__bss_size = SIZEOF(.bss); |
.noinit : |
{ |
PROVIDE (__noinit_start = .) ; |
*(.noinit) |
*(COMMON) |
PROVIDE (__noinit_end = .) ; |
_end = . ; |
} > data |
.vectors : |
. = ALIGN(2); |
__noinit_start = .; |
*(.noinit .noinit.*) |
. = ALIGN(2); |
__noinit_end = .; |
} > REGION_DATA |
. = ALIGN(2); |
_end = .; /* Past last write (loadable) segment */ |
|
/* Values placed in the first 32 entries of a 64-entry interrupt vector |
* table. This exists because the FRAM chips place the BSL and JTAG |
* passwords at specific offsets that technically fall within the |
* interrupt table, but for which no MCU has a corresponding interrupt. |
* See https://sourceforge.net/tracker/?func=detail&aid=3554291&group_id=42303&atid=432701 */ |
PROVIDE(__vte_0 = 0xffff); |
PROVIDE(__vte_1 = 0xffff); |
PROVIDE(__vte_2 = 0xffff); |
PROVIDE(__vte_3 = 0xffff); |
PROVIDE(__vte_4 = 0xffff); |
PROVIDE(__vte_5 = 0xffff); |
PROVIDE(__vte_6 = 0xffff); |
PROVIDE(__vte_7 = 0xffff); |
PROVIDE(__vte_8 = 0xffff); |
PROVIDE(__vte_9 = 0xffff); |
PROVIDE(__vte_10 = 0xffff); |
PROVIDE(__vte_11 = 0xffff); |
PROVIDE(__vte_12 = 0xffff); |
PROVIDE(__vte_13 = 0xffff); |
PROVIDE(__vte_14 = 0xffff); |
PROVIDE(__vte_15 = 0xffff); |
PROVIDE(__vte_16 = 0xffff); |
PROVIDE(__vte_17 = 0xffff); |
PROVIDE(__vte_18 = 0xffff); |
PROVIDE(__vte_19 = 0xffff); |
PROVIDE(__vte_20 = 0xffff); |
PROVIDE(__vte_21 = 0xffff); |
PROVIDE(__vte_22 = 0xffff); |
PROVIDE(__vte_23 = 0xffff); |
PROVIDE(__vte_24 = 0xffff); |
PROVIDE(__vte_25 = 0xffff); |
PROVIDE(__vte_26 = 0xffff); |
PROVIDE(__vte_27 = 0xffff); |
PROVIDE(__vte_28 = 0xffff); |
PROVIDE(__vte_29 = 0xffff); |
PROVIDE(__vte_30 = 0xffff); |
PROVIDE(__vte_31 = 0xffff); |
.vectors : |
{ |
PROVIDE (__vectors_start = .) ; |
*(.vectors*) |
_vectors_end = . ; |
__vectors_start = .; |
KEEP(*(.vectors*)) |
_vectors_end = .; |
} > vectors |
/* Legacy section, prefer .far.text */ |
. = ALIGN(2); |
_efartext = .; /* Past last read-only (loadable) segment */ |
. = ALIGN(2); |
_far_end = .; /* Past last write (loadable) segment */ |
/* Stabs for profiling information*/ |
.profiler 0 : { *(.profiler) } |
/* Stabs debugging sections. */ |
188,7 → 209,14
.debug_str 0 : { *(.debug_str) } |
.debug_loc 0 : { *(.debug_loc) } |
.debug_macinfo 0 : { *(.debug_macinfo) } |
PROVIDE (__stack = ORIGIN(data) + LENGTH(data)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
/* DWARF 3 */ |
.debug_pubtypes 0 : { *(.debug_pubtypes) } |
.debug_ranges 0 : { *(.debug_ranges) } |
/* __stack is the only symbol that the user can override */ |
PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatastart = _etext) ; |
PROVIDE (__romdataend = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatacopysize = SIZEOF(.data)); |
} |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
/actel_m1a3pl_dev_kit/rtl/verilog/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]; |
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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]}}); |
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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]}; |
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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]; |
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/openmsp430/omsp_wakeup_cell.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_wakeup_cell.v |
// |
// |
// *Module Description: |
// Generic Wakeup cell |
// |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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) |
); |
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/openmsp430/omsp_mem_backbone.v
28,7 → 28,7
//---------------------------------------------------------------------------- |
// |
// *File Name: omsp_mem_backbone.v |
// |
// |
// *Module Description: |
// Memory interface backbone (decoder + arbiter) |
// |
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,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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
|
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
/actel_m1a3pl_dev_kit/rtl/verilog/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 |
|
/actel_m1a3pl_dev_kit/rtl/verilog/openMSP430_fpga.v
21,9 → 21,9
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
//---------------------------------------------------------------------------- |
// |
// |
// *File Name: openMSP430_fpga.v |
// |
// |
// *Module Description: |
// openMSP430 FPGA Top-level |
// (targeting an Actel ProASIC3L). |
37,7 → 37,7
// $LastChangedDate: 2009-12-29 21:58:14 +0100 (Tue, 29 Dec 2009) $ |
//---------------------------------------------------------------------------- |
`include "openMSP430_defines.v" |
|
|
module openMSP430_fpga ( |
|
// OUTPUTs |
123,7 → 123,7
wire [15:0] per_dout_dac_x; |
wire [15:0] per_dout_dac_y; |
|
|
|
//============================================================================= |
// 2) PLL & CLOCK GENERATION |
//============================================================================= |
149,7 → 149,7
wire [4:0] ocdiv = W-5'h01; |
wire [6:0] findiv = N-7'h01; |
wire [6:0] fbdiv = M-7'h01; |
|
|
PLL #(.VCOFREQUENCY(FVCO)) pll_0 ( |
|
// PLL Inputs |
285,7 → 285,7
// 1.5 V +- 5% | 24 43.75 | 33.75 87.5 | 67.5 175 | 135 350 | |
//-------------+---------------+---------------+--------------+---------------+ |
|
|
|
//============================================================================= |
// 3) PROGRAM AND DATA MEMORIES |
//============================================================================= |
296,7 → 296,7
pmem_2kB pmem_hi (.WD(pmem_din[15:8]), .RD(pmem_dout[15:8]), .WEN(pmem_wen[1] | pmem_cen), .REN(~pmem_wen[1] | pmem_cen), .WADDR(pmem_addr) , .RADDR(pmem_addr), .RWCLK(mclk), .RESET(~puc_rst)); |
pmem_2kB pmem_lo (.WD(pmem_din[7:0]), .RD(pmem_dout[7:0]), .WEN(pmem_wen[0] | pmem_cen), .REN(~pmem_wen[0] | pmem_cen), .WADDR(pmem_addr) , .RADDR(pmem_addr), .RWCLK(mclk), .RESET(~puc_rst)); |
|
|
|
//============================================================================= |
// 4) OPENMSP430 |
//============================================================================= |
319,10 → 319,13
.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_en (per_en), // Peripheral enable (high active) |
.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) |
343,6 → 346,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 |
362,7 → 371,7
//----------------------------------- |
|
dac_spi_if #(1, 9'h190) dac_spi_if_x ( |
|
|
// OUTPUTs |
.cntrl1 (cntrl1), // Control value 1 |
.cntrl2 (cntrl2), // Control value 2 |
370,7 → 379,7
.per_dout (per_dout_dac_x), // Peripheral data output |
.sclk (sclk_x), // SPI Serial Clock |
.sync_n (sync_n_x), // SPI Frame synchronization signal (low active) |
|
|
// INPUTs |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
381,7 → 390,7
); |
|
dac_spi_if #(1, 9'h1A0) dac_spi_if_y ( |
|
|
// OUTPUTs |
.cntrl1 (), // Control value 1 |
.cntrl2 (), // Control value 2 |
389,7 → 398,7
.per_dout (per_dout_dac_y), // Peripheral data output |
.sclk (sclk_y), // SPI Serial Clock |
.sync_n (sync_n_y), // SPI Frame synchronization signal (low active) |
|
|
// INPUTs |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
432,7 → 441,7
.p6_dout_en (), // Port 6 data output enable |
.p6_sel (), // Port 6 function select |
.per_dout (per_dout_dio), // Peripheral data output |
|
|
// INPUTs |
.mclk (mclk), // Main system clock |
.p1_din (p1_din), // Port 1 data input |
494,7 → 503,7
per_dout_tA | |
per_dout_dac_x | |
per_dout_dac_y; |
|
|
// |
// Assign interrupts |
//------------------------------- |
525,6 → 534,5
|
assign led = {cntrl1, p1_dout[0], p1_dout[0], cntrl2}; |
|
|
|
endmodule // openMSP430_fpga |
|
/actel_m1a3pl_dev_kit/software/spacewar/linker.x
1,14 → 1,17
/* Default linker script, for normal executables */ |
OUTPUT_FORMAT("elf32-msp430") |
OUTPUT_ARCH("msp430") |
MEMORY |
{ |
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x100 |
text (rx) : ORIGIN = 0xf000, LENGTH = 0x1000-0x20 |
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20 |
MEMORY { |
sfr : ORIGIN = 0x0000, LENGTH = 0x0010 |
peripheral_8bit : ORIGIN = 0x0010, LENGTH = 0x00f0 |
peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 |
ram (wx) : ORIGIN = 0x0200, LENGTH = 0x0100 |
rom (rx) : ORIGIN = 0xF000, LENGTH = 0x1000-0x20 |
vectors : ORIGIN = 0xffe0, LENGTH = 0x0020 |
} |
REGION_ALIAS("REGION_TEXT", text); |
REGION_ALIAS("REGION_DATA", data); |
REGION_ALIAS("REGION_TEXT", rom); |
REGION_ALIAS("REGION_DATA", ram); |
PROVIDE (__info_segment_size = 0x80); |
__WDTCTL = 0x0120; |
__MPY = 0x0130; |
__MPYS = 0x0132; |
22,142 → 25,160
SECTIONS |
{ |
/* Read-only sections, merged into text segment. */ |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.hash : { *(.hash) } |
.dynsym : { *(.dynsym) } |
.dynstr : { *(.dynstr) } |
.gnu.version : { *(.gnu.version) } |
.gnu.version_d : { *(.gnu.version_d) } |
.gnu.version_r : { *(.gnu.version_r) } |
.rel.init : { *(.rel.init) } |
.rela.init : { *(.rela.init) } |
.rel.text : |
{ |
*(.rel.text) |
*(.rel.text.*) |
*(.rel.gnu.linkonce.t*) |
} |
.rela.text : |
{ |
*(.rela.text) |
*(.rela.text.*) |
*(.rela.gnu.linkonce.t*) |
} |
.rel.fini : { *(.rel.fini) } |
.rel.fini : { *(.rel.fini) } |
.rela.fini : { *(.rela.fini) } |
.rel.rodata : |
{ |
*(.rel.rodata) |
*(.rel.rodata.*) |
*(.rel.gnu.linkonce.r*) |
} |
.rela.rodata : |
{ |
*(.rela.rodata) |
*(.rela.rodata.*) |
*(.rela.gnu.linkonce.r*) |
} |
.rel.data : |
{ |
*(.rel.data) |
*(.rel.data.*) |
*(.rel.gnu.linkonce.d*) |
} |
.rela.data : |
{ |
*(.rela.data) |
*(.rela.data.*) |
*(.rela.gnu.linkonce.d*) |
} |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.bss : { *(.rel.bss) } |
.rela.bss : { *(.rela.bss) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* Internal text space. */ |
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } |
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } |
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } |
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } |
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } |
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } |
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } |
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } |
.rel.ctors : { *(.rel.ctors) } |
.rela.ctors : { *(.rela.ctors) } |
.rel.dtors : { *(.rel.dtors) } |
.rela.dtors : { *(.rela.dtors) } |
.rel.got : { *(.rel.got) } |
.rela.got : { *(.rela.got) } |
.rel.plt : { *(.rel.plt) } |
.rela.plt : { *(.rela.plt) } |
/* .any.{text,rodata,data,bss}{,.*} sections are treated as orphans and |
* placed in output sections with available space by linker. Do not list |
* them here, or the linker will not consider them orphans. */ |
.text : |
{ |
. = ALIGN(2); |
*(.init) |
*(.init0) /* Start here after reset. */ |
*(.init1) |
*(.init2) /* Copy data loop */ |
*(.init3) |
*(.init4) /* Clear bss */ |
*(.init5) |
*(.init6) /* C++ constructors. */ |
*(.init7) |
*(.init8) |
*(.init9) /* Call main(). */ |
__ctors_start = . ; |
*(.ctors) |
__ctors_end = . ; |
__dtors_start = . ; |
*(.dtors) |
__dtors_end = . ; |
. = ALIGN(2); |
*(.text) |
. = ALIGN(2); |
*(.text.*) |
. = ALIGN(2); |
*(.fini9) /* */ |
*(.fini8) |
*(.fini7) |
*(.fini6) /* C++ destructors. */ |
*(.fini5) |
*(.fini4) |
*(.fini3) |
*(.fini2) |
*(.fini1) |
*(.fini0) /* Infinite loop after program termination. */ |
*(.fini) |
} > text |
. = ALIGN(2); |
KEEP(*(.init .init.*)) |
KEEP(*(.init0)) /* Start here after reset. */ |
KEEP(*(.init1)) /* User definable. */ |
KEEP(*(.init2)) /* Initialize stack. */ |
KEEP(*(.init3)) /* Initialize hardware, user definable. */ |
KEEP(*(.init4)) /* Copy data to .data, clear bss. */ |
KEEP(*(.init5)) /* User definable. */ |
KEEP(*(.init6)) /* C++ constructors. */ |
KEEP(*(.init7)) /* User definable. */ |
KEEP(*(.init8)) /* User definable. */ |
KEEP(*(.init9)) /* Call main(). */ |
KEEP(*(.fini9)) /* Falls into here after main(). User definable. */ |
KEEP(*(.fini8)) /* User definable. */ |
KEEP(*(.fini7)) /* User definable. */ |
KEEP(*(.fini6)) /* C++ destructors. */ |
KEEP(*(.fini5)) /* User definable. */ |
KEEP(*(.fini4)) /* User definable. */ |
KEEP(*(.fini3)) /* User definable. */ |
KEEP(*(.fini2)) /* User definable. */ |
KEEP(*(.fini1)) /* User definable. */ |
KEEP(*(.fini0)) /* Infinite loop after program termination. */ |
KEEP(*(.fini .fini.*)) |
. = ALIGN(2); |
__ctors_start = .; |
KEEP(*(.ctors)) |
__ctors_end = .; |
__dtors_start = .; |
KEEP(*(.dtors)) |
__dtors_end = .; |
. = ALIGN(2); |
*(.text .text.* .gnu.linkonce.t.*) |
*(.near.text .near.text.*) |
} > REGION_TEXT |
.rodata : |
{ |
. = ALIGN(2); |
*(.rodata .rodata.* .gnu.linkonce.r.*) |
. = ALIGN(2); |
} > text |
*(.near.rodata .near.rodata.*) |
} > REGION_TEXT |
. = ALIGN(2); |
_etext = .; /* Past last read-only (loadable) segment */ |
.data : AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata) ) |
.data : |
{ |
. = ALIGN(2); |
PROVIDE (__data_start = .) ; |
. = ALIGN(2); |
*(.data) |
. = ALIGN(2); |
*(.gnu.linkonce.d*) |
. = ALIGN(2); |
_edata = . ; |
} > data |
PROVIDE (__data_load_start = LOADADDR(.data) ); |
PROVIDE (__data_size = SIZEOF(.data) ); |
.bss SIZEOF(.data) + ADDR(.data) : |
PROVIDE (__datastart = .) ; |
*(.data .data.* .gnu.linkonce.d.*) |
*(.near.data .near.data.*) |
. = ALIGN(2); |
_edata = .; /* Past last read-write (loadable) segment */ |
} > REGION_DATA AT > REGION_TEXT |
__data_load_start = LOADADDR(.data); |
__data_size = SIZEOF(.data); |
.bss : |
{ |
PROVIDE (__bss_start = .) ; |
*(.bss) |
__bss_start = .; |
*(.bss .bss.*) |
*(.near.bss .near.bss.*) |
*(COMMON) |
PROVIDE (__bss_end = .) ; |
_end = . ; |
} > data |
PROVIDE (__bss_size = SIZEOF(.bss) ); |
.noinit SIZEOF(.bss) + ADDR(.bss) : |
. = ALIGN(2); |
__bss_end = .; |
} > REGION_DATA |
__bss_size = SIZEOF(.bss); |
.noinit : |
{ |
PROVIDE (__noinit_start = .) ; |
*(.noinit) |
*(COMMON) |
PROVIDE (__noinit_end = .) ; |
_end = . ; |
} > data |
.vectors : |
. = ALIGN(2); |
__noinit_start = .; |
*(.noinit .noinit.*) |
. = ALIGN(2); |
__noinit_end = .; |
} > REGION_DATA |
. = ALIGN(2); |
_end = .; /* Past last write (loadable) segment */ |
|
/* Values placed in the first 32 entries of a 64-entry interrupt vector |
* table. This exists because the FRAM chips place the BSL and JTAG |
* passwords at specific offsets that technically fall within the |
* interrupt table, but for which no MCU has a corresponding interrupt. |
* See https://sourceforge.net/tracker/?func=detail&aid=3554291&group_id=42303&atid=432701 */ |
PROVIDE(__vte_0 = 0xffff); |
PROVIDE(__vte_1 = 0xffff); |
PROVIDE(__vte_2 = 0xffff); |
PROVIDE(__vte_3 = 0xffff); |
PROVIDE(__vte_4 = 0xffff); |
PROVIDE(__vte_5 = 0xffff); |
PROVIDE(__vte_6 = 0xffff); |
PROVIDE(__vte_7 = 0xffff); |
PROVIDE(__vte_8 = 0xffff); |
PROVIDE(__vte_9 = 0xffff); |
PROVIDE(__vte_10 = 0xffff); |
PROVIDE(__vte_11 = 0xffff); |
PROVIDE(__vte_12 = 0xffff); |
PROVIDE(__vte_13 = 0xffff); |
PROVIDE(__vte_14 = 0xffff); |
PROVIDE(__vte_15 = 0xffff); |
PROVIDE(__vte_16 = 0xffff); |
PROVIDE(__vte_17 = 0xffff); |
PROVIDE(__vte_18 = 0xffff); |
PROVIDE(__vte_19 = 0xffff); |
PROVIDE(__vte_20 = 0xffff); |
PROVIDE(__vte_21 = 0xffff); |
PROVIDE(__vte_22 = 0xffff); |
PROVIDE(__vte_23 = 0xffff); |
PROVIDE(__vte_24 = 0xffff); |
PROVIDE(__vte_25 = 0xffff); |
PROVIDE(__vte_26 = 0xffff); |
PROVIDE(__vte_27 = 0xffff); |
PROVIDE(__vte_28 = 0xffff); |
PROVIDE(__vte_29 = 0xffff); |
PROVIDE(__vte_30 = 0xffff); |
PROVIDE(__vte_31 = 0xffff); |
.vectors : |
{ |
PROVIDE (__vectors_start = .) ; |
*(.vectors*) |
_vectors_end = . ; |
__vectors_start = .; |
KEEP(*(.vectors*)) |
_vectors_end = .; |
} > vectors |
/* Legacy section, prefer .far.text */ |
. = ALIGN(2); |
_efartext = .; /* Past last read-only (loadable) segment */ |
. = ALIGN(2); |
_far_end = .; /* Past last write (loadable) segment */ |
/* Stabs for profiling information*/ |
.profiler 0 : { *(.profiler) } |
/* Stabs debugging sections. */ |
188,7 → 209,14
.debug_str 0 : { *(.debug_str) } |
.debug_loc 0 : { *(.debug_loc) } |
.debug_macinfo 0 : { *(.debug_macinfo) } |
PROVIDE (__stack = ORIGIN(data) + LENGTH(data)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
/* DWARF 3 */ |
.debug_pubtypes 0 : { *(.debug_pubtypes) } |
.debug_ranges 0 : { *(.debug_ranges) } |
/* __stack is the only symbol that the user can override */ |
PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram)); |
PROVIDE (__data_start_rom = _etext) ; |
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatastart = _etext) ; |
PROVIDE (__romdataend = _etext + SIZEOF (.data)) ; |
PROVIDE (__romdatacopysize = SIZEOF(.data)); |
} |