From fbadb54b9bf4f5c1920bc35381d40ef988ea1f76 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 17 May 2013 15:32:30 +0200 Subject: Removed test cases that have been moved to yosys-test. https://github.com/cliffordwolf/yosys-tests/ --- tests/openmsp430/rtl/omsp_alu.v | 258 ------- tests/openmsp430/rtl/omsp_and_gate.v | 89 --- tests/openmsp430/rtl/omsp_clock_gate.v | 86 --- tests/openmsp430/rtl/omsp_clock_module.v | 1058 --------------------------- tests/openmsp430/rtl/omsp_clock_mux.v | 192 ----- tests/openmsp430/rtl/omsp_dbg.v | 827 --------------------- tests/openmsp430/rtl/omsp_dbg_hwbrk.v | 282 ------- tests/openmsp430/rtl/omsp_dbg_uart.v | 298 -------- tests/openmsp430/rtl/omsp_execution_unit.v | 420 ----------- tests/openmsp430/rtl/omsp_frontend.v | 966 ------------------------ tests/openmsp430/rtl/omsp_mem_backbone.v | 275 ------- tests/openmsp430/rtl/omsp_multiplier.v | 420 ----------- tests/openmsp430/rtl/omsp_register_file.v | 618 ---------------- tests/openmsp430/rtl/omsp_scan_mux.v | 75 -- tests/openmsp430/rtl/omsp_sfr.v | 353 --------- tests/openmsp430/rtl/omsp_sync_cell.v | 80 -- tests/openmsp430/rtl/omsp_sync_reset.v | 78 -- tests/openmsp430/rtl/omsp_wakeup_cell.v | 108 --- tests/openmsp430/rtl/omsp_watchdog.v | 556 -------------- tests/openmsp430/rtl/openMSP430.v | 584 --------------- tests/openmsp430/rtl/openMSP430_defines.v | 843 --------------------- tests/openmsp430/rtl/openMSP430_undefines.v | 732 ------------------ 22 files changed, 9198 deletions(-) delete mode 100644 tests/openmsp430/rtl/omsp_alu.v delete mode 100644 tests/openmsp430/rtl/omsp_and_gate.v delete mode 100644 tests/openmsp430/rtl/omsp_clock_gate.v delete mode 100644 tests/openmsp430/rtl/omsp_clock_module.v delete mode 100644 tests/openmsp430/rtl/omsp_clock_mux.v delete mode 100644 tests/openmsp430/rtl/omsp_dbg.v delete mode 100644 tests/openmsp430/rtl/omsp_dbg_hwbrk.v delete mode 100644 tests/openmsp430/rtl/omsp_dbg_uart.v delete mode 100644 tests/openmsp430/rtl/omsp_execution_unit.v delete mode 100644 tests/openmsp430/rtl/omsp_frontend.v delete mode 100644 tests/openmsp430/rtl/omsp_mem_backbone.v delete mode 100644 tests/openmsp430/rtl/omsp_multiplier.v delete mode 100644 tests/openmsp430/rtl/omsp_register_file.v delete mode 100644 tests/openmsp430/rtl/omsp_scan_mux.v delete mode 100644 tests/openmsp430/rtl/omsp_sfr.v delete mode 100644 tests/openmsp430/rtl/omsp_sync_cell.v delete mode 100644 tests/openmsp430/rtl/omsp_sync_reset.v delete mode 100644 tests/openmsp430/rtl/omsp_wakeup_cell.v delete mode 100644 tests/openmsp430/rtl/omsp_watchdog.v delete mode 100644 tests/openmsp430/rtl/openMSP430.v delete mode 100644 tests/openmsp430/rtl/openMSP430_defines.v delete mode 100644 tests/openmsp430/rtl/openMSP430_undefines.v (limited to 'tests/openmsp430/rtl') diff --git a/tests/openmsp430/rtl/omsp_alu.v b/tests/openmsp430/rtl/omsp_alu.v deleted file mode 100644 index d1069973..00000000 --- a/tests/openmsp430/rtl/omsp_alu.v +++ /dev/null @@ -1,258 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_alu.v -// -// *Module Description: -// openMSP430 ALU -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_alu ( - -// OUTPUTs - alu_out, // ALU output value - alu_out_add, // ALU adder output value - alu_stat, // ALU Status {V,N,Z,C} - alu_stat_wr, // ALU Status write {V,N,Z,C} - -// INPUTs - dbg_halt_st, // Halt/Run status from CPU - exec_cycle, // Instruction execution cycle - inst_alu, // ALU control signals - inst_bw, // Decoded Inst: byte width - inst_jmp, // Decoded Inst: Conditional jump - inst_so, // Single-operand arithmetic - op_dst, // Destination operand - op_src, // Source operand - status // R2 Status {V,N,Z,C} -); - -// OUTPUTs -//========= -output [15:0] alu_out; // ALU output value -output [15:0] alu_out_add; // ALU adder output value -output [3:0] alu_stat; // ALU Status {V,N,Z,C} -output [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C} - -// INPUTs -//========= -input dbg_halt_st; // Halt/Run status from CPU -input exec_cycle; // Instruction execution cycle -input [11:0] inst_alu; // ALU control signals -input inst_bw; // Decoded Inst: byte width -input [7:0] inst_jmp; // Decoded Inst: Conditional jump -input [7:0] inst_so; // Single-operand arithmetic -input [15:0] op_dst; // Destination operand -input [15:0] op_src; // Source operand -input [3:0] status; // R2 Status {V,N,Z,C} - - -//============================================================================= -// 1) FUNCTIONS -//============================================================================= - -function [4:0] bcd_add; - - input [3:0] X; - input [3:0] Y; - input C_; - - reg [4:0] Z_; - begin - Z_ = {1'b0,X}+{1'b0,Y}+{4'b0,C_}; - if (Z_<5'd10) bcd_add = Z_; - else bcd_add = Z_+5'd6; - end - -endfunction - - -//============================================================================= -// 2) INSTRUCTION FETCH/DECODE CONTROL STATE MACHINE -//============================================================================= -// SINGLE-OPERAND ARITHMETIC: -//----------------------------------------------------------------------------- -// Mnemonic S-Reg, Operation Status bits -// D-Reg, V N Z C -// -// RRC dst C->MSB->...LSB->C * * * * -// RRA dst MSB->MSB->...LSB->C 0 * * * -// SWPB dst Swap bytes - - - - -// SXT dst Bit7->Bit8...Bit15 0 * * * -// PUSH src SP-2->SP, src->@SP - - - - -// CALL dst SP-2->SP, PC+2->@SP, dst->PC - - - - -// RETI TOS->SR, SP+2->SP, TOS->PC, SP+2->SP * * * * -// -//----------------------------------------------------------------------------- -// TWO-OPERAND ARITHMETIC: -//----------------------------------------------------------------------------- -// Mnemonic S-Reg, Operation Status bits -// D-Reg, V N Z C -// -// MOV src,dst src -> dst - - - - -// ADD src,dst src + dst -> dst * * * * -// ADDC src,dst src + dst + C -> dst * * * * -// SUB src,dst dst + ~src + 1 -> dst * * * * -// SUBC src,dst dst + ~src + C -> dst * * * * -// CMP src,dst dst + ~src + 1 * * * * -// DADD src,dst src + dst + C -> dst (decimaly) * * * * -// BIT src,dst src & dst 0 * * * -// BIC src,dst ~src & dst -> dst - - - - -// BIS src,dst src | dst -> dst - - - - -// XOR src,dst src ^ dst -> dst * * * * -// AND src,dst src & dst -> dst 0 * * * -// -//----------------------------------------------------------------------------- -// * the status bit is affected -// - the status bit is not affected -// 0 the status bit is cleared -// 1 the status bit is set -//----------------------------------------------------------------------------- - -// Invert source for substract and compare instructions. -wire op_src_inv_cmd = exec_cycle & (inst_alu[`ALU_SRC_INV]); -wire [15:0] op_src_inv = {16{op_src_inv_cmd}} ^ op_src; - - -// Mask the bit 8 for the Byte instructions for correct flags generation -wire op_bit8_msk = ~exec_cycle | ~inst_bw; -wire [16:0] op_src_in = {1'b0, {op_src_inv[15:8] & {8{op_bit8_msk}}}, op_src_inv[7:0]}; -wire [16:0] op_dst_in = {1'b0, {op_dst[15:8] & {8{op_bit8_msk}}}, op_dst[7:0]}; - -// Clear the source operand (= jump offset) for conditional jumps -wire jmp_not_taken = (inst_jmp[`JL] & ~(status[3]^status[2])) | - (inst_jmp[`JGE] & (status[3]^status[2])) | - (inst_jmp[`JN] & ~status[2]) | - (inst_jmp[`JC] & ~status[0]) | - (inst_jmp[`JNC] & status[0]) | - (inst_jmp[`JEQ] & ~status[1]) | - (inst_jmp[`JNE] & status[1]); -wire [16:0] op_src_in_jmp = op_src_in & {17{~jmp_not_taken}}; - -// Adder / AND / OR / XOR -wire [16:0] alu_add = op_src_in_jmp + op_dst_in; -wire [16:0] alu_and = op_src_in & op_dst_in; -wire [16:0] alu_or = op_src_in | op_dst_in; -wire [16:0] alu_xor = op_src_in ^ op_dst_in; - - -// Incrementer -wire alu_inc = exec_cycle & ((inst_alu[`ALU_INC_C] & status[0]) | - inst_alu[`ALU_INC]); -wire [16:0] alu_add_inc = alu_add + {16'h0000, alu_inc}; - - - -// Decimal adder (DADD) -wire [4:0] alu_dadd0 = bcd_add(op_src_in[3:0], op_dst_in[3:0], status[0]); -wire [4:0] alu_dadd1 = bcd_add(op_src_in[7:4], op_dst_in[7:4], alu_dadd0[4]); -wire [4:0] alu_dadd2 = bcd_add(op_src_in[11:8], op_dst_in[11:8], alu_dadd1[4]); -wire [4:0] alu_dadd3 = bcd_add(op_src_in[15:12], op_dst_in[15:12],alu_dadd2[4]); -wire [16:0] alu_dadd = {alu_dadd3, alu_dadd2[3:0], alu_dadd1[3:0], alu_dadd0[3:0]}; - - -// Shifter for rotate instructions (RRC & RRA) -wire alu_shift_msb = inst_so[`RRC] ? status[0] : - 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]}; - - -// Swap bytes / Extend Sign -wire [16:0] alu_swpb = {1'b0, op_src[7:0],op_src[15:8]}; -wire [16:0] alu_sxt = {1'b0, {8{op_src[7]}},op_src[7:0]}; - - -// Combine short paths toghether to simplify final ALU mux -wire alu_short_thro = ~(inst_alu[`ALU_AND] | - inst_alu[`ALU_OR] | - inst_alu[`ALU_XOR] | - inst_alu[`ALU_SHIFT] | - inst_so[`SWPB] | - inst_so[`SXT]); - -wire [16:0] alu_short = ({17{inst_alu[`ALU_AND]}} & alu_and) | - ({17{inst_alu[`ALU_OR]}} & alu_or) | - ({17{inst_alu[`ALU_XOR]}} & alu_xor) | - ({17{inst_alu[`ALU_SHIFT]}} & alu_shift) | - ({17{inst_so[`SWPB]}} & alu_swpb) | - ({17{inst_so[`SXT]}} & alu_sxt) | - ({17{alu_short_thro}} & op_src_in); - - -// ALU output mux -wire [16:0] alu_out_nxt = (inst_so[`IRQ] | dbg_halt_st | - inst_alu[`ALU_ADD]) ? alu_add_inc : - inst_alu[`ALU_DADD] ? alu_dadd : alu_short; - -assign alu_out = alu_out_nxt[15:0]; -assign alu_out_add = alu_add[15:0]; - - -//----------------------------------------------------------------------------- -// STATUS FLAG GENERATION -//----------------------------------------------------------------------------- - -wire V_xor = inst_bw ? (op_src_in[7] & op_dst_in[7]) : - (op_src_in[15] & op_dst_in[15]); - -wire V = inst_bw ? ((~op_src_in[7] & ~op_dst_in[7] & alu_out[7]) | - ( op_src_in[7] & op_dst_in[7] & ~alu_out[7])) : - ((~op_src_in[15] & ~op_dst_in[15] & alu_out[15]) | - ( op_src_in[15] & op_dst_in[15] & ~alu_out[15])); - -wire N = inst_bw ? alu_out[7] : alu_out[15]; -wire Z = inst_bw ? (alu_out[7:0]==0) : (alu_out==0); -wire C = inst_bw ? alu_out[8] : alu_out_nxt[16]; - -assign alu_stat = inst_alu[`ALU_SHIFT] ? {1'b0, N,Z,op_src_in[0]} : - inst_alu[`ALU_STAT_7] ? {1'b0, N,Z,~Z} : - inst_alu[`ALU_XOR] ? {V_xor,N,Z,~Z} : {V,N,Z,C}; - -assign alu_stat_wr = (inst_alu[`ALU_STAT_F] & exec_cycle) ? 4'b1111 : 4'b0000; - - -endmodule // omsp_alu - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_and_gate.v b/tests/openmsp430/rtl/omsp_and_gate.v deleted file mode 100644 index 7ceeb8d9..00000000 --- a/tests/openmsp430/rtl/omsp_and_gate.v +++ /dev/null @@ -1,89 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_and_gate.v -// -// *Module Description: -// Generic AND gate cell for the openMSP430 -// -// *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 omsp_and_gate ( - -// OUTPUTs - y, // AND gate output - -// INPUTs - a, // AND gate input A - b // AND gate input B -); - -// OUTPUTs -//========= -output y; // AND gate output - -// INPUTs -//========= -input a; // AND gate input A -input b; // AND gate input B - - -//============================================================================= -// 1) SOME COMMENTS ON THIS MODULE -//============================================================================= -// -// In its ASIC version, some combinatorial pathes of the openMSP430 are -// sensitive to glitches, in particular the ones generating the wakeup -// signals. -// To prevent synthesis from optmizing combinatorial clouds into glitchy -// logic, this AND gate module has been instanciated in the critical places. -// -// Make sure that synthesis doesn't ungroup this module. As an alternative, -// a standard cell from the library could also be directly instanciated here -// (don't forget the "dont_touch" attribute) -// -// -//============================================================================= -// 2) AND GATE -//============================================================================= - -assign y = a & b; - - -endmodule // omsp_and_gate - - - diff --git a/tests/openmsp430/rtl/omsp_clock_gate.v b/tests/openmsp430/rtl/omsp_clock_gate.v deleted file mode 100644 index 8ffe8e0d..00000000 --- a/tests/openmsp430/rtl/omsp_clock_gate.v +++ /dev/null @@ -1,86 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_clock_gate.v -// -// *Module Description: -// Generic clock gate cell for the openMSP430 -// -// *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 omsp_clock_gate ( - -// OUTPUTs - gclk, // Gated clock - -// INPUTs - clk, // Clock - enable, // Clock enable - scan_enable // Scan enable (active during scan shifting) -); - -// OUTPUTs -//========= -output gclk; // Gated clock - -// INPUTs -//========= -input clk; // Clock -input enable; // Clock enable -input scan_enable; // Scan enable (active during scan shifting) - - -//============================================================================= -// 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); - -// LATCH the enable signal -reg enable_latch; -always @(clk or enable_in) - if (~clk) - enable_latch <= enable_in; - -// AND gate -assign gclk = (clk & enable_latch); - - -endmodule // omsp_clock_gate - - diff --git a/tests/openmsp430/rtl/omsp_clock_module.v b/tests/openmsp430/rtl/omsp_clock_module.v deleted file mode 100644 index 670c5e59..00000000 --- a/tests/openmsp430/rtl/omsp_clock_module.v +++ /dev/null @@ -1,1058 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_clock_module.v -// -// *Module Description: -// Basic clock module implementation. -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -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 - -// 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 -); - -// 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 - -// 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 - - -//============================================================================= -// 1) WIRES & PARAMETER DECLARATION -//============================================================================= - -// Register base address (must be aligned to decoder bit width) -parameter [14:0] BASE_ADDR = 15'h0050; - -// Decoder bit width (defines how many bits are considered for address decoding) -parameter DEC_WD = 4; - -// Register addresses offset -parameter [DEC_WD-1:0] BCSCTL1 = 'h7, - BCSCTL2 = 'h8; - -// 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}; - -// Register one-hot decoder -parameter [DEC_SZ-1:0] BCSCTL1_D = (BASE_REG << BCSCTL1), - BCSCTL2_D = (BASE_REG << BCSCTL2); - -// Local wire declarations -wire nodiv_mclk; -wire nodiv_mclk_n; -wire nodiv_smclk; - - -//============================================================================ -// 2) REGISTER DECODER -//============================================================================ - -// Local register selection -wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]); - -// Register local address -wire [DEC_WD-1:0] reg_addr = {1'b0, per_addr[DEC_WD-2:0]}; - -// Register address decode -wire [DEC_SZ-1:0] reg_dec = (BCSCTL1_D & {DEC_SZ{(reg_addr==(BCSCTL1 >>1))}}) | - (BCSCTL2_D & {DEC_SZ{(reg_addr==(BCSCTL2 >>1))}}); - -// Read/Write probes -wire reg_lo_write = per_we[0] & reg_sel; -wire reg_hi_write = per_we[1] & reg_sel; -wire reg_read = ~|per_we & reg_sel; - -// Read/Write vectors -wire [DEC_SZ-1:0] reg_hi_wr = reg_dec & {DEC_SZ{reg_hi_write}}; -wire [DEC_SZ-1:0] reg_lo_wr = reg_dec & {DEC_SZ{reg_lo_write}}; -wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}}; - - -//============================================================================ -// 3) REGISTERS -//============================================================================ - -// BCSCTL1 Register -//-------------- -reg [7:0] bcsctl1; -wire bcsctl1_wr = BCSCTL1[0] ? reg_hi_wr[BCSCTL1] : reg_lo_wr[BCSCTL1]; -wire [7:0] bcsctl1_nxt = BCSCTL1[0] ? per_din[15:8] : per_din[7:0]; - -`ifdef ASIC - `ifdef ACLK_DIVIDER -wire [7:0] divax_mask = 8'h30; - `else -wire [7:0] divax_mask = 8'h00; - `endif -`else -wire [7:0] divax_mask = 8'h30; -`endif - -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) bcsctl1 <= 8'h00; - else if (bcsctl1_wr) bcsctl1 <= bcsctl1_nxt & divax_mask; // Mask unused bits - - -// BCSCTL2 Register -//-------------- -reg [7:0] bcsctl2; -wire bcsctl2_wr = BCSCTL2[0] ? reg_hi_wr[BCSCTL2] : reg_lo_wr[BCSCTL2]; -wire [7:0] bcsctl2_nxt = BCSCTL2[0] ? per_din[15:8] : per_din[7:0]; - -`ifdef MCLK_MUX -wire [7:0] selmx_mask = 8'h80; -`else -wire [7:0] selmx_mask = 8'h00; -`endif -`ifdef MCLK_DIVIDER -wire [7:0] divmx_mask = 8'h30; -`else -wire [7:0] divmx_mask = 8'h00; -`endif -`ifdef ASIC - `ifdef SMCLK_MUX -wire [7:0] sels_mask = 8'h08; - `else -wire [7:0] sels_mask = 8'h00; - `endif - `ifdef SMCLK_DIVIDER -wire [7:0] divsx_mask = 8'h06; - `else -wire [7:0] divsx_mask = 8'h00; - `endif -`else -wire [7:0] sels_mask = 8'h08; -wire [7:0] divsx_mask = 8'h06; -`endif - -always @ (posedge 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 - - -//============================================================================ -// 4) DATA OUTPUT GENERATION -//============================================================================ - -// Data output mux -wire [15:0] bcsctl1_rd = {8'h00, (bcsctl1 & {8{reg_rd[BCSCTL1]}})} << (8 & {4{BCSCTL1[0]}}); -wire [15:0] bcsctl2_rd = {8'h00, (bcsctl2 & {8{reg_rd[BCSCTL2]}})} << (8 & {4{BCSCTL2[0]}}); - -wire [15:0] per_dout = bcsctl1_rd | - bcsctl2_rd; - - -//============================================================================= -// 5) DCO_CLK / LFXT_CLK INTERFACES (WAKEUP, ENABLE, ...) -//============================================================================= - -`ifdef ASIC - wire cpuoff_and_mclk_enable; - omsp_and_gate and_cpuoff_mclk_en (.y(cpuoff_and_mclk_enable), .a(cpuoff), .b(mclk_enable)); -`endif - -//----------------------------------------------------------- -// 5.1) HIGH SPEED SYSTEM CLOCK GENERATOR (DCO_CLK) -//----------------------------------------------------------- -// Note1: switching off the DCO osillator is only -// supported in ASIC mode with SCG0 low power mode -// -// Note2: unlike the original MSP430 specification, -// we allow to switch off the DCO even -// if it is selected by MCLK or SMCLK. - -wire por_a; -wire dco_wkup; -wire cpu_en_wkup; - -`ifdef SCG0_EN - - // The DCO oscillator is synchronously disabled if: - // - the cpu pin is disabled (in that case, wait for mclk_enable==0) - // - the debug interface is disabled - // - SCG0 is set (in that case, wait for the mclk_enable==0 if selected by SELMx) - // - // Note that we make extensive use of the AND gate module in order - // to prevent glitch propagation on the wakeup logic cone. - wire cpu_enabled_with_dco; - wire dco_not_enabled_by_dbg; - wire dco_disable_by_scg0; - 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_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)); - - // Register to prevent glitch propagation - reg dco_disable; - always @(posedge nodiv_mclk_n or posedge por) - if (por) dco_disable <= 1'b1; - else dco_disable <= ~dco_enable_nxt; - - // Note that a synchronizer is required if the MCLK mux is included - wire dco_clk_n = ~dco_clk; - `ifdef MCLK_MUX - omsp_sync_cell sync_cell_dco_disable ( - .data_out (dco_enable), - .data_in (~dco_disable), - .clk (dco_clk_n), - .rst (por) - ); - `else - - assign dco_enable = ~dco_disable; - `endif - - // The DCO oscillator will get an asynchronous wakeup if: - // - the MCLK generates a wakeup (only if the MCLK mux selects dco_clk) - // - if the DCO wants to be synchronously enabled (i.e dco_enable_nxt=1) - wire dco_mclk_wkup; - wire dco_en_wkup; - 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; - - // 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 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) - ); - - // The wakeup is asynchronously set, synchronously released - wire dco_wkup_n; - omsp_sync_cell sync_cell_dco_wkup ( - .data_out (dco_wkup_n), - .data_in (dco_wkup_clear), - .clk (dco_clk_n), - .rst (dco_wkup_set_scan) - ); - - 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; -`endif - - -//----------------------------------------------------------- -// 5.2) LOW FREQUENCY CRYSTAL CLOCK GENERATOR (LFXT_CLK) -//----------------------------------------------------------- - -// ASIC MODE -//------------------------------------------------ -// Note: unlike the original MSP430 specification, -// we allow to switch off the LFXT even -// if it is selected by MCLK or SMCLK. -`ifdef ASIC - -`ifdef OSCOFF_EN - - // The LFXT is synchronously disabled if: - // - the cpu pin is disabled (in that case, wait for mclk_enable==0) - // - the debug interface is disabled - // - OSCOFF is set (in that case, wait for the mclk_enable==0 if selected by SELMx) - wire cpu_enabled_with_lfxt; - wire lfxt_not_enabled_by_dbg; - wire lfxt_disable_by_oscoff; - 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_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)); - - // Register to prevent glitch propagation - reg lfxt_disable; - always @(posedge nodiv_mclk_n or posedge por) - if (por) lfxt_disable <= 1'b1; - else lfxt_disable <= ~lfxt_enable_nxt; - - // Synchronize the OSCOFF control signal to the LFXT clock domain - wire lfxt_clk_n = ~lfxt_clk; - omsp_sync_cell sync_cell_lfxt_disable ( - .data_out (lfxt_enable), - .data_in (~lfxt_disable), - .clk (lfxt_clk_n), - .rst (por) - ); - - // The LFXT will get an asynchronous wakeup if: - // - the MCLK generates a wakeup (only if the MCLK mux selects lfxt_clk) - // - if the LFXT wants to be synchronously enabled (i.e lfxt_enable_nxt=1) - wire lfxt_mclk_wkup; - wire lfxt_en_wkup; - 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; - - // 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 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) - ); - - // The wakeup is asynchronously set, synchronously released - wire lfxt_wkup_n; - omsp_sync_cell sync_cell_lfxt_wkup ( - .data_out (lfxt_wkup_n), - .data_in (lfxt_wkup_clear), - .clk (lfxt_clk_n), - .rst (lfxt_wkup_set_scan) - ); - - 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; -`endif - - -// FPGA MODE -//--------------------------------------- -// Synchronize LFXT_CLK & edge detection -`else - -wire lfxt_clk_s; - -omsp_sync_cell sync_cell_lfxt_clk ( - .data_out (lfxt_clk_s), - .data_in (lfxt_clk), - .clk (mclk), - .rst (por) -); - -reg lfxt_clk_dly; - -always @ (posedge mclk or posedge por) - if (por) lfxt_clk_dly <= 1'b0; - else lfxt_clk_dly <= lfxt_clk_s; - -wire lfxt_clk_en = (lfxt_clk_s & ~lfxt_clk_dly) & ~(oscoff & ~bcsctl2[`SELS]); -assign lfxt_enable = 1'b1; -assign lfxt_wkup = 1'b0; -`endif - - -//============================================================================= -// 6) CLOCK GENERATION -//============================================================================= - -//----------------------------------------------------------- -// 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 -// its IDLE state (through the mclk_enable signal) - - -// Synchronize CPU_EN signal to the MCLK domain -//---------------------------------------------- -`ifdef SYNC_CPU_EN - omsp_sync_cell sync_cell_cpu_en ( - .data_out (cpu_en_s), - .data_in (cpu_en), - .clk (nodiv_mclk), - .rst (por) - ); - omsp_and_gate and_cpu_en_wkup (.y(cpu_en_wkup), .a(cpu_en), .b(~cpu_en_s)); -`else - assign cpu_en_s = cpu_en; - assign cpu_en_wkup = 1'b0; -`endif - -// Synchronize CPU_EN signal to the ACLK domain -//---------------------------------------------- -`ifdef LFXT_DOMAIN - wire cpu_en_aux_s; - omsp_sync_cell sync_cell_cpu_aux_en ( - .data_out (cpu_en_aux_s), - .data_in (cpu_en), - .clk (lfxt_clk), - .rst (por) - ); -`else - wire cpu_en_aux_s = cpu_en_s; -`endif - -// Synchronize CPU_EN signal to the SMCLK domain -//---------------------------------------------- -// Note: the synchronizer is only required if there is a SMCLK_MUX -`ifdef ASIC - `ifdef SMCLK_MUX - wire cpu_en_sm_s; - omsp_sync_cell sync_cell_cpu_sm_en ( - .data_out (cpu_en_sm_s), - .data_in (cpu_en), - .clk (nodiv_smclk), - .rst (por) - ); - `else - wire cpu_en_sm_s = cpu_en_s; - `endif -`endif - - -//----------------------------------------------------------- -// 6.2) MCLK GENERATION -//----------------------------------------------------------- - -// Clock MUX -//---------------------------- -`ifdef MCLK_MUX -omsp_clock_mux clock_mux_mclk ( - .clk_out (nodiv_mclk), - .clk_in0 (dco_clk), - .clk_in1 (lfxt_clk), - .reset (por), - .scan_mode (scan_mode), - .select (bcsctl2[`SELMx]) -); -`else -assign nodiv_mclk = dco_clk; -`endif -assign nodiv_mclk_n = ~nodiv_mclk; - - -// Wakeup synchronizer -//---------------------------- -wire mclk_wkup_s; - -`ifdef CPUOFF_EN -omsp_sync_cell sync_cell_mclk_wkup ( - .data_out (mclk_wkup_s), - .data_in (mclk_wkup), - .clk (nodiv_mclk), - .rst (puc_rst) -); -`else - assign mclk_wkup_s = 1'b0; -`endif - - -// Clock Divider -//---------------------------- -// No need for extra synchronizer as bcsctl2 -// comes from the same clock domain. - -`ifdef CPUOFF_EN -wire mclk_active = mclk_enable | mclk_wkup_s | (dbg_en_s & cpu_en_s); -`else -wire mclk_active = 1'b1; -`endif - -`ifdef MCLK_DIVIDER -reg [2:0] mclk_div; -always @ (posedge nodiv_mclk or posedge puc_rst) - 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]); -`else - wire mclk_div_en = mclk_active; -`endif - - -// Generate main system clock -//---------------------------- -`ifdef MCLK_CGATE - -omsp_clock_gate clock_gate_mclk ( - .gclk (mclk), - .clk (nodiv_mclk), - .enable (mclk_div_en), - .scan_enable (scan_enable) -); -`else - assign mclk = nodiv_mclk; -`endif - - -//----------------------------------------------------------- -// 6.3) ACLK GENERATION -//----------------------------------------------------------- - -// ASIC MODE -//---------------------------- -`ifdef ASIC - - `ifdef ACLK_DIVIDER - `ifdef LFXT_DOMAIN - - wire nodiv_aclk = lfxt_clk; - - // Local Reset synchronizer - 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), - .clk (nodiv_aclk), - .rst (puc_rst) - ); - omsp_scan_mux scan_mux_puc_lfxt ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (~puc_lfxt_noscan_n), - .data_out (puc_lfxt_rst) - ); - - // 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) - reg [1:0] divax_s; - reg [1:0] divax_ss; - always @ (posedge nodiv_aclk or posedge puc_lfxt_rst) - if (puc_lfxt_rst) - begin - divax_s <= 2'h0; - divax_ss <= 2'h0; - end - else - begin - 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 - - // Divider - 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]); - - // Clock gate - omsp_clock_gate clock_gate_aclk ( - .gclk (aclk), - .clk (nodiv_aclk), - .enable (aclk_div_en), - .scan_enable (scan_enable) - ); - - `else - `ifdef LFXT_DOMAIN - assign aclk = lfxt_clk; - `else - assign aclk = dco_clk; - `endif - `endif - - - assign aclk_en = 1'b1; - - -// FPGA MODE -//---------------------------- -`else - reg aclk_en; - reg [2:0] aclk_div; - wire aclk_en_nxt = lfxt_clk_en & ((bcsctl1[`DIVAx]==2'b00) ? 1'b1 : - (bcsctl1[`DIVAx]==2'b01) ? aclk_div[0] : - (bcsctl1[`DIVAx]==2'b10) ? &aclk_div[1:0] : - &aclk_div[2:0]); - - always @ (posedge 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) - if (puc_rst) aclk_en <= 1'b0; - else aclk_en <= aclk_en_nxt & cpu_en_s; - - assign aclk = mclk; -`endif - -//----------------------------------------------------------- -// 6.4) SMCLK GENERATION -//----------------------------------------------------------- - -// Clock MUX -//---------------------------- -`ifdef SMCLK_MUX -omsp_clock_mux clock_mux_smclk ( - .clk_out (nodiv_smclk), - .clk_in0 (dco_clk), - .clk_in1 (lfxt_clk), - .reset (por), - .scan_mode (scan_mode), - .select (bcsctl2[`SELS]) -); -`else -assign nodiv_smclk = dco_clk; -`endif - - -// ASIC MODE -//---------------------------- -`ifdef ASIC - `ifdef 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; - omsp_sync_cell sync_cell_puc_sm ( - .data_out (puc_sm_noscan_n), - .data_in (1'b1), - .clk (nodiv_smclk), - .rst (puc_rst) - ); - omsp_scan_mux scan_mux_puc_sm ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (~puc_sm_noscan_n), - .data_out (puc_sm_rst) - ); - - // SCG1 synchronizer - `ifdef SCG1_EN - wire scg1_s; - omsp_sync_cell sync_cell_scg1 ( - .data_out (scg1_s), - .data_in (scg1), - .clk (nodiv_smclk), - .rst (puc_sm_rst) - ); - `else - wire scg1_s = 1'b0; - `endif - - `ifdef SMCLK_DIVIDER - // Local synchronizer for the bcsctl2.DIVSx configuration - // (note that we can live with a full bus synchronizer as - // it won't hurt if we get a wrong DIVSx value for a single clock cycle) - reg [1:0] divsx_s; - reg [1:0] divsx_ss; - always @ (posedge nodiv_smclk or posedge puc_sm_rst) - if (puc_sm_rst) - begin - divsx_s <= 2'h0; - divsx_ss <= 2'h0; - end - else - begin - divsx_s <= bcsctl2[`DIVSx]; - divsx_ss <= divsx_s; - end - `endif - - `else - - wire puc_sm_rst = puc_rst; - wire [1:0] divsx_ss = bcsctl2[`DIVSx]; - wire scg1_s = scg1; - `endif - - - - // Clock Divider - //---------------------------- - `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]); - `else - `ifdef SCG1_EN - wire smclk_div_en = cpu_en_sm_s & ~scg1_s; - `else - wire smclk_div_en = cpu_en_sm_s; - `endif - `endif - - - // Generate sub-system clock - //---------------------------- - `ifdef SMCLK_CGATE - omsp_clock_gate clock_gate_smclk ( - .gclk (smclk), - .clk (nodiv_smclk), - .enable (smclk_div_en), - .scan_enable (scan_enable) - ); - `else - assign smclk = nodiv_smclk; - `endif - - assign smclk_en = 1'b1; - - -// FPGA MODE -//---------------------------- -`else -reg smclk_en; -reg [2:0] smclk_div; - -wire smclk_in = ~scg1 & (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) - if (puc_rst) smclk_en <= 1'b0; - else smclk_en <= smclk_en_nxt & cpu_en_s; - -always @ (posedge 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; - -`endif - -//----------------------------------------------------------- -// 6.5) DEBUG INTERFACE CLOCK GENERATION (DBG_CLK) -//----------------------------------------------------------- - -// Synchronize DBG_EN signal to MCLK domain -//------------------------------------------ -`ifdef DBG_EN -`ifdef SYNC_DBG_EN - wire dbg_en_n_s; - omsp_sync_cell sync_cell_dbg_en ( - .data_out (dbg_en_n_s), - .data_in (~dbg_en), - .clk (mclk), - .rst (por) - ); - 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; -`endif -`else - assign dbg_en_s = 1'b0; - wire dbg_rst_nxt = 1'b0; -`endif - - -// Serial Debug Interface Clock gate -//------------------------------------------------ -`ifdef DBG_EN - `ifdef ASIC - omsp_clock_gate clock_gate_dbg_clk ( - .gclk (dbg_clk), - .clk (mclk), - .enable (dbg_en_s), - .scan_enable (scan_enable) - ); - `else - assign dbg_clk = dco_clk; - `endif -`else - assign dbg_clk = 1'b0; -`endif - - -//============================================================================= -// 7) RESET GENERATION -//============================================================================= -// -// Whenever the reset pin (reset_n) is deasserted, the internal resets of the -// openMSP430 will be released in the following order: -// 1- POR -// 2- DBG_RST (if the sdi interface is enabled, i.e. dbg_en=1) -// 3- PUC -// -// 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 -//------------------------------------------ - -// Asynchronous reset source -assign por_a = !reset_n; -wire por_noscan; - -// Reset Synchronizer -omsp_sync_reset sync_reset_por ( - .rst_s (por_noscan), - .clk (nodiv_mclk), - .rst_a (por_a) -); - -// Scan Reset Mux -`ifdef ASIC -omsp_scan_mux scan_mux_por ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (por_noscan), - .data_out (por) -); -`else - assign por = por_noscan; -`endif - -// Generate synchronized reset for the SDI -//------------------------------------------ -`ifdef DBG_EN - -// Reset Generation -reg dbg_rst_noscan; -always @ (posedge mclk or posedge por) - if (por) dbg_rst_noscan <= 1'b1; - else dbg_rst_noscan <= dbg_rst_nxt; - - // Scan Reset Mux - `ifdef ASIC - omsp_scan_mux scan_mux_dbg_rst ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (dbg_rst_noscan), - .data_out (dbg_rst) - ); - `else - assign dbg_rst = dbg_rst_noscan; - `endif - -`else - wire dbg_rst_noscan = 1'b1; - assign dbg_rst = 1'b1; -`endif - - -// Generate main system reset (PUC_RST) -//-------------------------------------- -wire puc_noscan_n; -wire puc_a_scan; - -// Asynchronous PUC reset -wire puc_a = por | wdt_reset; - -// Synchronous PUC reset -wire puc_s = dbg_cpu_reset | // With the debug interface command - - (dbg_en_s & dbg_rst_noscan & ~puc_noscan_n); // Sequencing making sure PUC is released - // after DBG_RST if the debug interface is - // enabled at power-on-reset time -// Scan Reset Mux -`ifdef ASIC -omsp_scan_mux scan_mux_puc_rst_a ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (puc_a), - .data_out (puc_a_scan) -); -`else - assign puc_a_scan = puc_a; -`endif - -// Reset Synchronizer -// (required because of the asynchronous watchdog reset) -omsp_sync_cell sync_cell_puc ( - .data_out (puc_noscan_n), - .data_in (~puc_s), - .clk (mclk), - .rst (puc_a_scan) -); - -// Scan Reset Mux -`ifdef ASIC -omsp_scan_mux scan_mux_puc_rst ( - .scan_mode (scan_mode), - .data_in_scan (por_a), - .data_in_func (~puc_noscan_n), - .data_out (puc_rst) -); -`else - assign puc_rst = ~puc_noscan_n; -`endif - -// PUC pending set the serial debug interface -assign puc_pnd_set = ~puc_noscan_n; - - -endmodule // omsp_clock_module - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_clock_mux.v b/tests/openmsp430/rtl/omsp_clock_mux.v deleted file mode 100644 index 5f8406ad..00000000 --- a/tests/openmsp430/rtl/omsp_clock_mux.v +++ /dev/null @@ -1,192 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_clock_mux.v -// -// *Module Description: -// Standard clock mux for the openMSP430 -// -// *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 omsp_clock_mux ( - -// OUTPUTs - clk_out, // Clock output - -// INPUTs - clk_in0, // Clock input 0 - clk_in1, // Clock input 1 - reset, // Reset - scan_mode, // Scan mode (clk_in0 is selected in scan mode) - select // Clock selection -); - -// OUTPUTs -//========= -output clk_out; // Clock output - -// INPUTs -//========= -input clk_in0; // Clock input 0 -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 - - -//===========================================================================================================================// -// 1) CLOCK MUX // -//===========================================================================================================================// -// // -// The following (glitch free) clock mux is implemented as following: // -// // -// // -// // -// // -// +-----. +--------+ +--------+ // -// select >>----+-------------O| \ | | | | +-----. // -// | | |---| D Q |---| D Q |--+-------| \ // -// | +-------O| / | | | | | | |O-+ // -// | | +-----' | | | | | +--O| / | // -// | | | /\ | | /\ | | | +-----' | // -// | | +--+--+--+ +--+--+--+ | | | // -// | | O | | | | // -// | | | | | | | +-----. // -// clk_in0 >>----------------------------------+------------+-----------+ +--| \ // -// | | | | |----<< clk_out // -// | | +---------------------------------------+ +--| / // -// | | | | +-----' // -// | +---------------------------------------------+ | // -// | | | | // -// | | +-----. +--------+ +--------+ | | // -// | +-O| \ | | | | | +-----. | // -// | | |---| D Q |---| D Q |--+-------| \ | // -// +--------------| / | | | | | |O-+ // -// +-----' | | | | +--O| / // -// | /\ | | /\ | | +-----' // -// +--+--+--+ +--+--+--+ | // -// O | | // -// | | | // -// clk_in1 >>----------------------------------+------------+-----------+ // -// // -// // -//===========================================================================================================================// - -//----------------------------------------------------------------------------- -// Wire declarations -//----------------------------------------------------------------------------- - -wire in0_select; -reg in0_select_s; -reg in0_select_ss; -wire in0_enable; - -wire in1_select; -reg in1_select_s; -reg in1_select_ss; -wire in1_enable; - -wire clk_in0_inv; -wire clk_in1_inv; -wire gated_clk_in0; -wire gated_clk_in1; - - -//----------------------------------------------------------------------------- -// CLK_IN0 Selection -//----------------------------------------------------------------------------- - -assign in0_select = ~select & ~in1_select_ss; - -always @ (posedge clk_in0_inv or posedge reset) - if (reset) in0_select_s <= 1'b1; - else in0_select_s <= in0_select; - -always @ (posedge clk_in0 or posedge reset) - if (reset) in0_select_ss <= 1'b1; - else in0_select_ss <= in0_select_s; - -assign in0_enable = in0_select_ss | scan_mode; - - -//----------------------------------------------------------------------------- -// CLK_IN1 Selection -//----------------------------------------------------------------------------- - -assign in1_select = select & ~in0_select_ss; - -always @ (posedge clk_in1_inv or posedge reset) - if (reset) in1_select_s <= 1'b0; - else in1_select_s <= in1_select; - -always @ (posedge clk_in1 or posedge reset) - if (reset) in1_select_ss <= 1'b0; - else in1_select_ss <= in1_select_s; - -assign in1_enable = in1_select_ss & ~scan_mode; - - -//----------------------------------------------------------------------------- -// Clock MUX -//----------------------------------------------------------------------------- -// -// IMPORTANT NOTE: -// Because the clock network is a critical part of the design, -// the following combinatorial logic should be replaced with -// direct instanciation of standard cells from target library. -// Don't forget the "dont_touch" attribute to make sure -// synthesis won't mess it up. -// - -// Replace with standard cell INVERTER -assign clk_in0_inv = ~clk_in0; -assign clk_in1_inv = ~clk_in1; - - -// 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); - - - -endmodule // omsp_clock_gate - - - diff --git a/tests/openmsp430/rtl/omsp_dbg.v b/tests/openmsp430/rtl/omsp_dbg.v deleted file mode 100644 index 97e9ede4..00000000 --- a/tests/openmsp430/rtl/omsp_dbg.v +++ /dev/null @@ -1,827 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_dbg.v -// -// *Module Description: -// Debug interface -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 149 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-07-19 22:21:12 +0200 (Thu, 19 Jul 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_dbg ( - -// OUTPUTs - dbg_freeze, // Freeze peripherals - dbg_halt_cmd, // 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 - dbg_reg_wr, // Debug unit CPU register write - dbg_cpu_reset, // Reset CPU from debug interface - dbg_uart_txd, // Debug interface: UART TXD - -// INPUTs - cpu_en_s, // Enable CPU code execution (synchronous) - cpu_id, // CPU ID - dbg_clk, // Debug unit clock - dbg_en_s, // Debug interface enable (synchronous) - dbg_halt_st, // Halt/Run status from CPU - dbg_mem_din, // Debug unit Memory data input - dbg_reg_din, // Debug unit CPU register data input - dbg_rst, // Debug unit reset - dbg_uart_rxd, // Debug interface: UART RXD (asynchronous) - decode_noirq, // Frontend decode instruction - 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_in, // Memory data bus input - eu_mdb_out, // Memory data bus output - exec_done, // Execution completed - fe_mb_en, // Frontend Memory bus enable - fe_mdb_in, // Frontend Memory data bus input - pc, // Program counter - puc_pnd_set // PUC pending set for the serial debug interface -); - -// OUTPUTs -//========= -output dbg_freeze; // Freeze peripherals -output dbg_halt_cmd; // Halt CPU command -output [15:0] dbg_mem_addr; // Debug address for rd/wr access -output [15:0] dbg_mem_dout; // Debug unit data output -output dbg_mem_en; // Debug unit memory enable -output [1:0] dbg_mem_wr; // Debug unit memory write -output dbg_reg_wr; // Debug unit CPU register write -output dbg_cpu_reset; // Reset CPU from debug interface -output dbg_uart_txd; // Debug interface: UART TXD - -// INPUTs -//========= -input cpu_en_s; // Enable CPU code execution (synchronous) -input [31:0] cpu_id; // CPU ID -input dbg_clk; // Debug unit clock -input dbg_en_s; // Debug interface enable (synchronous) -input dbg_halt_st; // Halt/Run status from CPU -input [15:0] dbg_mem_din; // Debug unit Memory data input -input [15:0] dbg_reg_din; // Debug unit CPU register data input -input dbg_rst; // Debug unit reset -input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous) -input decode_noirq; // Frontend decode instruction -input [15: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_in; // Memory data bus input -input [15:0] eu_mdb_out; // Memory data bus output -input exec_done; // Execution completed -input fe_mb_en; // Frontend Memory bus enable -input [15:0] fe_mdb_in; // Frontend Memory data bus input -input [15:0] pc; // Program counter -input puc_pnd_set; // PUC pending set for the serial debug interface - - -//============================================================================= -// 1) WIRE & PARAMETER DECLARATION -//============================================================================= - -// Diverse wires and registers -wire [5:0] dbg_addr; -wire [15:0] dbg_din; -wire dbg_wr; -reg mem_burst; -wire dbg_reg_rd; -wire dbg_mem_rd; -reg dbg_mem_rd_dly; -wire dbg_swbrk; -wire dbg_rd; -reg dbg_rd_rdy; -wire mem_burst_rd; -wire mem_burst_wr; -wire brk0_halt; -wire brk0_pnd; -wire [15:0] brk0_dout; -wire brk1_halt; -wire brk1_pnd; -wire [15:0] brk1_dout; -wire brk2_halt; -wire brk2_pnd; -wire [15:0] brk2_dout; -wire brk3_halt; -wire brk3_pnd; -wire [15:0] brk3_dout; - -// Number of registers -parameter NR_REG = 24; - -// Register addresses -parameter CPU_ID_LO = 6'h00; -parameter CPU_ID_HI = 6'h01; -parameter CPU_CTL = 6'h02; -parameter CPU_STAT = 6'h03; -parameter MEM_CTL = 6'h04; -parameter MEM_ADDR = 6'h05; -parameter MEM_DATA = 6'h06; -parameter MEM_CNT = 6'h07; -`ifdef DBG_HWBRK_0 -parameter BRK0_CTL = 6'h08; -parameter BRK0_STAT = 6'h09; -parameter BRK0_ADDR0 = 6'h0A; -parameter BRK0_ADDR1 = 6'h0B; -`endif -`ifdef DBG_HWBRK_1 -parameter BRK1_CTL = 6'h0C; -parameter BRK1_STAT = 6'h0D; -parameter BRK1_ADDR0 = 6'h0E; -parameter BRK1_ADDR1 = 6'h0F; -`endif -`ifdef DBG_HWBRK_2 -parameter BRK2_CTL = 6'h10; -parameter BRK2_STAT = 6'h11; -parameter BRK2_ADDR0 = 6'h12; -parameter BRK2_ADDR1 = 6'h13; -`endif -`ifdef DBG_HWBRK_3 -parameter BRK3_CTL = 6'h14; -parameter BRK3_STAT = 6'h15; -parameter BRK3_ADDR0 = 6'h16; -parameter BRK3_ADDR1 = 6'h17; -`endif - -// Register one-hot decoder -parameter BASE_D = {{NR_REG-1{1'b0}}, 1'b1}; -parameter CPU_ID_LO_D = (BASE_D << CPU_ID_LO); -parameter CPU_ID_HI_D = (BASE_D << CPU_ID_HI); -parameter CPU_CTL_D = (BASE_D << CPU_CTL); -parameter CPU_STAT_D = (BASE_D << CPU_STAT); -parameter MEM_CTL_D = (BASE_D << MEM_CTL); -parameter MEM_ADDR_D = (BASE_D << MEM_ADDR); -parameter MEM_DATA_D = (BASE_D << MEM_DATA); -parameter MEM_CNT_D = (BASE_D << MEM_CNT); -`ifdef DBG_HWBRK_0 -parameter BRK0_CTL_D = (BASE_D << BRK0_CTL); -parameter BRK0_STAT_D = (BASE_D << BRK0_STAT); -parameter BRK0_ADDR0_D = (BASE_D << BRK0_ADDR0); -parameter BRK0_ADDR1_D = (BASE_D << BRK0_ADDR1); -`endif -`ifdef DBG_HWBRK_1 -parameter BRK1_CTL_D = (BASE_D << BRK1_CTL); -parameter BRK1_STAT_D = (BASE_D << BRK1_STAT); -parameter BRK1_ADDR0_D = (BASE_D << BRK1_ADDR0); -parameter BRK1_ADDR1_D = (BASE_D << BRK1_ADDR1); -`endif -`ifdef DBG_HWBRK_2 -parameter BRK2_CTL_D = (BASE_D << BRK2_CTL); -parameter BRK2_STAT_D = (BASE_D << BRK2_STAT); -parameter BRK2_ADDR0_D = (BASE_D << BRK2_ADDR0); -parameter BRK2_ADDR1_D = (BASE_D << BRK2_ADDR1); -`endif -`ifdef DBG_HWBRK_3 -parameter BRK3_CTL_D = (BASE_D << BRK3_CTL); -parameter BRK3_STAT_D = (BASE_D << BRK3_STAT); -parameter BRK3_ADDR0_D = (BASE_D << BRK3_ADDR0); -parameter BRK3_ADDR1_D = (BASE_D << BRK3_ADDR1); -`endif - - -//============================================================================ -// 2) REGISTER DECODER -//============================================================================ - -// Select Data register during a burst -wire [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr; - -// Register address decode -reg [NR_REG-1:0] reg_dec; -always @(dbg_addr_in) - case (dbg_addr_in) - CPU_ID_LO : reg_dec = CPU_ID_LO_D; - CPU_ID_HI : reg_dec = CPU_ID_HI_D; - CPU_CTL : reg_dec = CPU_CTL_D; - CPU_STAT : reg_dec = CPU_STAT_D; - MEM_CTL : reg_dec = MEM_CTL_D; - MEM_ADDR : reg_dec = MEM_ADDR_D; - MEM_DATA : reg_dec = MEM_DATA_D; - MEM_CNT : reg_dec = MEM_CNT_D; -`ifdef DBG_HWBRK_0 - BRK0_CTL : reg_dec = BRK0_CTL_D; - BRK0_STAT : reg_dec = BRK0_STAT_D; - BRK0_ADDR0: reg_dec = BRK0_ADDR0_D; - BRK0_ADDR1: reg_dec = BRK0_ADDR1_D; -`endif -`ifdef DBG_HWBRK_1 - BRK1_CTL : reg_dec = BRK1_CTL_D; - BRK1_STAT : reg_dec = BRK1_STAT_D; - BRK1_ADDR0: reg_dec = BRK1_ADDR0_D; - BRK1_ADDR1: reg_dec = BRK1_ADDR1_D; -`endif -`ifdef DBG_HWBRK_2 - BRK2_CTL : reg_dec = BRK2_CTL_D; - BRK2_STAT : reg_dec = BRK2_STAT_D; - BRK2_ADDR0: reg_dec = BRK2_ADDR0_D; - BRK2_ADDR1: reg_dec = BRK2_ADDR1_D; -`endif -`ifdef DBG_HWBRK_3 - BRK3_CTL : reg_dec = BRK3_CTL_D; - BRK3_STAT : reg_dec = BRK3_STAT_D; - BRK3_ADDR0: reg_dec = BRK3_ADDR0_D; - BRK3_ADDR1: reg_dec = BRK3_ADDR1_D; -`endif - // pragma coverage off - default: reg_dec = {NR_REG{1'b0}}; - // pragma coverage on - endcase - -// Read/Write probes -wire reg_write = dbg_wr; -wire reg_read = 1'b1; - -// Read/Write vectors -wire [NR_REG-1:0] reg_wr = reg_dec & {NR_REG{reg_write}}; -wire [NR_REG-1:0] reg_rd = reg_dec & {NR_REG{reg_read}}; - - -//============================================================================= -// 3) REGISTER: CORE INTERFACE -//============================================================================= - -// CPU_ID Register -//----------------- -// ------------------------------------------------------------------- -// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 | -// |----------------------------+-----------------+------+-------------| -// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION | -// -------------------------------------------------------------------- -// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 | -// |----------------------------+-------------------------------+------| -// | PMEM_SIZE | DMEM_SIZE | MPY | -// ------------------------------------------------------------------- - -// This register is assigned in the SFR module - - -// CPU_CTL Register -//----------------------------------------------------------------------------- -// 7 6 5 4 3 2 1 0 -// Reserved CPU_RST RST_BRK_EN FRZ_BRK_EN SW_BRK_EN ISTEP RUN HALT -//----------------------------------------------------------------------------- -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; -`else - if (dbg_rst) cpu_ctl <= 4'h2; -`endif - else if (cpu_ctl_wr) cpu_ctl <= dbg_din[6:3]; - -wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000}; - -wire halt_cpu = cpu_ctl_wr & dbg_din[`HALT] & ~dbg_halt_st; -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 -// HWBRK3_PND HWBRK2_PND HWBRK1_PND HWBRK0_PND SWBRK_PND PUC_PND Res. HALT_RUN -//------------------------------------------------------------------------------------ -reg [3:2] cpu_stat; - -wire cpu_stat_wr = reg_wr[CPU_STAT]; -wire [3:2] cpu_stat_set = {dbg_swbrk, puc_pnd_set}; -wire [3:2] cpu_stat_clr = ~dbg_din[3:2]; - -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) cpu_stat <= 2'b00; - else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set); - else cpu_stat <= (cpu_stat | cpu_stat_set); - -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 -//============================================================================= - -// MEM_CTL Register -//----------------------------------------------------------------------------- -// 7 6 5 4 3 2 1 0 -// Reserved B/W MEM/REG RD/WR START -// -// START : - 0 : Do nothing. -// - 1 : Initiate memory transfer. -// -// RD/WR : - 0 : Read access. -// - 1 : Write access. -// -// MEM/REG: - 0 : Memory access. -// - 1 : CPU Register access. -// -// B/W : - 0 : 16 bit access. -// - 1 : 8 bit access (not valid for CPU Registers). -// -//----------------------------------------------------------------------------- -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]; - -wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0}; - -reg mem_start; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) mem_start <= 1'b0; - 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]}; - -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) mem_data <= 16'h0000; - else if (mem_data_wr) mem_data <= dbg_din; - 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 : - (dbg_mem_acc & ~mem_bw) ? 16'h0002 : - (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; - else mem_cnt <= mem_cnt + mem_cnt_dec; - - -//============================================================================= -// 5) BREAKPOINTS / WATCHPOINTS -//============================================================================= - -`ifdef DBG_HWBRK_0 -// Hardware Breakpoint/Watchpoint Register read select -wire [3:0] brk0_reg_rd = {reg_rd[BRK0_ADDR1], - reg_rd[BRK0_ADDR0], - reg_rd[BRK0_STAT], - reg_rd[BRK0_CTL]}; - -// Hardware Breakpoint/Watchpoint Register write select -wire [3:0] brk0_reg_wr = {reg_wr[BRK0_ADDR1], - reg_wr[BRK0_ADDR0], - reg_wr[BRK0_STAT], - reg_wr[BRK0_CTL]}; - -omsp_dbg_hwbrk dbg_hwbr_0 ( - -// OUTPUTs - .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 - .dbg_clk (dbg_clk), // Debug unit clock - .dbg_din (dbg_din), // Debug register data input - .dbg_rst (dbg_rst), // Debug unit reset - .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 - .eu_mdb_in (eu_mdb_in), // Memory data bus input - .eu_mdb_out (eu_mdb_out), // Memory data bus output - .exec_done (exec_done), // Execution completed - .fe_mb_en (fe_mb_en), // Frontend Memory bus enable - .pc (pc) // Program counter -); - -`else -assign brk0_halt = 1'b0; -assign brk0_pnd = 1'b0; -assign brk0_dout = 16'h0000; -`endif - -`ifdef DBG_HWBRK_1 -// Hardware Breakpoint/Watchpoint Register read select -wire [3:0] brk1_reg_rd = {reg_rd[BRK1_ADDR1], - reg_rd[BRK1_ADDR0], - reg_rd[BRK1_STAT], - reg_rd[BRK1_CTL]}; - -// Hardware Breakpoint/Watchpoint Register write select -wire [3:0] brk1_reg_wr = {reg_wr[BRK1_ADDR1], - reg_wr[BRK1_ADDR0], - reg_wr[BRK1_STAT], - reg_wr[BRK1_CTL]}; - -omsp_dbg_hwbrk dbg_hwbr_1 ( - -// OUTPUTs - .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 - .dbg_clk (dbg_clk), // Debug unit clock - .dbg_din (dbg_din), // Debug register data input - .dbg_rst (dbg_rst), // Debug unit reset - .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 - .eu_mdb_in (eu_mdb_in), // Memory data bus input - .eu_mdb_out (eu_mdb_out), // Memory data bus output - .exec_done (exec_done), // Execution completed - .fe_mb_en (fe_mb_en), // Frontend Memory bus enable - .pc (pc) // Program counter -); - -`else -assign brk1_halt = 1'b0; -assign brk1_pnd = 1'b0; -assign brk1_dout = 16'h0000; -`endif - - `ifdef DBG_HWBRK_2 -// Hardware Breakpoint/Watchpoint Register read select -wire [3:0] brk2_reg_rd = {reg_rd[BRK2_ADDR1], - reg_rd[BRK2_ADDR0], - reg_rd[BRK2_STAT], - reg_rd[BRK2_CTL]}; - -// Hardware Breakpoint/Watchpoint Register write select -wire [3:0] brk2_reg_wr = {reg_wr[BRK2_ADDR1], - reg_wr[BRK2_ADDR0], - reg_wr[BRK2_STAT], - reg_wr[BRK2_CTL]}; - -omsp_dbg_hwbrk dbg_hwbr_2 ( - -// OUTPUTs - .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 - .dbg_clk (dbg_clk), // Debug unit clock - .dbg_din (dbg_din), // Debug register data input - .dbg_rst (dbg_rst), // Debug unit reset - .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 - .eu_mdb_in (eu_mdb_in), // Memory data bus input - .eu_mdb_out (eu_mdb_out), // Memory data bus output - .exec_done (exec_done), // Execution completed - .fe_mb_en (fe_mb_en), // Frontend Memory bus enable - .pc (pc) // Program counter -); - -`else -assign brk2_halt = 1'b0; -assign brk2_pnd = 1'b0; -assign brk2_dout = 16'h0000; -`endif - -`ifdef DBG_HWBRK_3 -// Hardware Breakpoint/Watchpoint Register read select -wire [3:0] brk3_reg_rd = {reg_rd[BRK3_ADDR1], - reg_rd[BRK3_ADDR0], - reg_rd[BRK3_STAT], - reg_rd[BRK3_CTL]}; - -// Hardware Breakpoint/Watchpoint Register write select -wire [3:0] brk3_reg_wr = {reg_wr[BRK3_ADDR1], - reg_wr[BRK3_ADDR0], - reg_wr[BRK3_STAT], - reg_wr[BRK3_CTL]}; - -omsp_dbg_hwbrk dbg_hwbr_3 ( - -// OUTPUTs - .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 - .dbg_clk (dbg_clk), // Debug unit clock - .dbg_din (dbg_din), // Debug register data input - .dbg_rst (dbg_rst), // Debug unit reset - .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 - .eu_mdb_in (eu_mdb_in), // Memory data bus input - .eu_mdb_out (eu_mdb_out), // Memory data bus output - .exec_done (exec_done), // Execution completed - .fe_mb_en (fe_mb_en), // Frontend Memory bus enable - .pc (pc) // Program counter -); - -`else -assign brk3_halt = 1'b0; -assign brk3_pnd = 1'b0; -assign brk3_dout = 16'h0000; -`endif - - -//============================================================================ -// 6) DATA OUTPUT GENERATION -//============================================================================ - -wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}}; -wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}}; -wire [15:0] cpu_ctl_rd = {8'h00, cpu_ctl_full} & {16{reg_rd[CPU_CTL]}}; -wire [15:0] cpu_stat_rd = {8'h00, cpu_stat_full} & {16{reg_rd[CPU_STAT]}}; -wire [15:0] mem_ctl_rd = {8'h00, mem_ctl_full} & {16{reg_rd[MEM_CTL]}}; -wire [15:0] mem_data_rd = mem_data & {16{reg_rd[MEM_DATA]}}; -wire [15:0] mem_addr_rd = mem_addr & {16{reg_rd[MEM_ADDR]}}; -wire [15:0] mem_cnt_rd = mem_cnt & {16{reg_rd[MEM_CNT]}}; - -wire [15:0] dbg_dout = cpu_id_lo_rd | - cpu_id_hi_rd | - cpu_ctl_rd | - cpu_stat_rd | - mem_ctl_rd | - mem_data_rd | - mem_addr_rd | - mem_cnt_rd | - brk0_dout | - brk1_dout | - brk2_dout | - brk3_dout; - -// Tell UART/JTAG interface that the data is ready to be read -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) dbg_rd_rdy <= 1'b0; - else if (mem_burst | mem_burst_rd) dbg_rd_rdy <= (dbg_reg_rd | dbg_mem_rd_dly); - else dbg_rd_rdy <= dbg_rd; - - -//============================================================================ -// 7) CPU CONTROL -//============================================================================ - -// Reset CPU -//-------------------------- -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); - - -// Software break -//-------------------------- -assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN]; - - -// Single step -//-------------------------- -reg [1:0] inc_step; -always @(posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) inc_step <= 2'b00; - else if (istep) inc_step <= 2'b11; - else inc_step <= {inc_step[0], 1'b0}; - - -// Run / Halt -//-------------------------- -reg halt_flag; - -wire mem_halt_cpu; -wire mem_run_cpu; - -wire halt_flag_clr = run_cpu | mem_run_cpu; -wire halt_flag_set = halt_cpu | halt_rst | dbg_swbrk | mem_halt_cpu | - brk0_halt | brk1_halt | brk2_halt | brk3_halt; - -always @(posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) halt_flag <= 1'b0; - else if (halt_flag_clr) halt_flag <= 1'b0; - else if (halt_flag_set) halt_flag <= 1'b1; - -wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1]; - - -//============================================================================ -// 8) MEMORY CONTROL -//============================================================================ - -// Control Memory bursts -//------------------------------ - -wire mem_burst_start = (mem_start & |mem_cnt); -wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt); - -// Detect when burst is on going -always @(posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) mem_burst <= 1'b0; - else if (mem_burst_start) mem_burst <= 1'b1; - else if (mem_burst_end) mem_burst <= 1'b0; - -// Control signals for UART/JTAG interface -assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]); -assign mem_burst_wr = (mem_burst_start & mem_ctl[1]); - -// Trigger CPU Register or memory access during a burst -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; - -// 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; -reg [1:0] mem_state_nxt; - -// State machine definition -parameter M_IDLE = 2'h0; -parameter M_SET_BRK = 2'h1; -parameter M_ACCESS_BRK = 2'h2; -parameter M_ACCESS = 2'h3; - -// 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 : - 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; - M_ACCESS : mem_state_nxt = M_IDLE; - // pragma coverage off - default : mem_state_nxt = M_IDLE; - // pragma coverage on - endcase - -// State machine -always @(posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) mem_state <= M_IDLE; - else mem_state <= mem_state_nxt; - -// Utility signals -assign mem_halt_cpu = (mem_state==M_IDLE) & (mem_state_nxt==M_SET_BRK); -assign mem_run_cpu = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE); -assign mem_access = (mem_state==M_ACCESS) | (mem_state==M_ACCESS_BRK); - - -// Interface to CPU Registers and Memory bacbkone -//------------------------------------------------ -assign dbg_mem_addr = mem_addr; -assign dbg_mem_dout = ~mem_bw ? mem_data : - mem_addr[0] ? {mem_data[7:0], 8'h00} : - {8'h00, mem_data[7:0]}; - -assign dbg_reg_wr = mem_access & mem_ctl[1] & mem_ctl[2]; -assign dbg_reg_rd = mem_access & ~mem_ctl[1] & mem_ctl[2]; - -assign dbg_mem_en = mem_access & ~mem_ctl[2]; -assign dbg_mem_rd = dbg_mem_en & ~mem_ctl[1]; - -wire [1:0] dbg_mem_wr_msk = ~mem_bw ? 2'b11 : - mem_addr[0] ? 2'b10 : 2'b01; -assign dbg_mem_wr = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk; - - -// It takes one additional cycle to read from Memory as from registers -always @(posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) dbg_mem_rd_dly <= 1'b0; - else dbg_mem_rd_dly <= dbg_mem_rd; - - -//============================================================================= -// 9) UART COMMUNICATION -//============================================================================= -`ifdef DBG_UART -omsp_dbg_uart dbg_uart_0 ( - -// OUTPUTs - .dbg_addr (dbg_addr), // Debug register address - .dbg_din (dbg_din), // Debug register data input - .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 - .dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read - .dbg_rst (dbg_rst), // Debug unit reset - .dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD - .mem_burst (mem_burst), // Burst on going - .mem_burst_end(mem_burst_end), // End TX/RX burst - .mem_burst_rd (mem_burst_rd), // Start TX burst - .mem_burst_wr (mem_burst_wr), // Start RX burst - .mem_bw (mem_bw) // Burst byte width -); - -`else -assign dbg_addr = 6'h00; -assign dbg_din = 16'h0000; -assign dbg_rd = 1'b0; -assign dbg_uart_txd = 1'b0; -assign dbg_wr = 1'b0; -`endif - - -//============================================================================= -// 10) JTAG COMMUNICATION -//============================================================================= -`ifdef DBG_JTAG -JTAG INTERFACE IS NOT SUPPORTED YET -`else -`endif - -endmodule // dbg - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_dbg_hwbrk.v b/tests/openmsp430/rtl/omsp_dbg_hwbrk.v deleted file mode 100644 index 6f639aee..00000000 --- a/tests/openmsp430/rtl/omsp_dbg_hwbrk.v +++ /dev/null @@ -1,282 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_dbg_hwbrk.v -// -// *Module Description: -// Hardware Breakpoint / Watchpoint module -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 117 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2011-06-23 21:30:51 +0200 (Thu, 23 Jun 2011) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_dbg_hwbrk ( - -// OUTPUTs - 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 - dbg_clk, // Debug unit clock - dbg_din, // Debug register data input - dbg_rst, // Debug unit reset - 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_in, // Memory data bus input - eu_mdb_out, // Memory data bus output - exec_done, // Execution completed - fe_mb_en, // Frontend Memory bus enable - pc // Program counter -); - -// OUTPUTs -//========= -output brk_halt; // Hardware breakpoint command -output brk_pnd; // Hardware break/watch-point pending -output [15:0] brk_dout; // Hardware break/watch-point register data input - -// INPUTs -//========= -input [3:0] brk_reg_rd; // Hardware break/watch-point register read select -input [3:0] brk_reg_wr; // Hardware break/watch-point register write select -input dbg_clk; // Debug unit clock -input [15:0] dbg_din; // Debug register data input -input dbg_rst; // Debug unit reset -input [15: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_in; // Memory data bus input -input [15:0] eu_mdb_out; // Memory data bus output -input exec_done; // Execution completed -input fe_mb_en; // Frontend Memory bus enable -input [15:0] pc; // Program counter - - -//============================================================================= -// 1) WIRE & PARAMETER DECLARATION -//============================================================================= - -wire range_wr_set; -wire range_rd_set; -wire addr1_wr_set; -wire addr1_rd_set; -wire addr0_wr_set; -wire addr0_rd_set; - - -parameter BRK_CTL = 0, - BRK_STAT = 1, - BRK_ADDR0 = 2, - BRK_ADDR1 = 3; - - -//============================================================================= -// 2) CONFIGURATION REGISTERS -//============================================================================= - -// BRK_CTL Register -//----------------------------------------------------------------------------- -// 7 6 5 4 3 2 1 0 -// Reserved RANGE_MODE INST_EN BREAK_EN ACCESS_MODE -// -// ACCESS_MODE: - 00 : Disabled -// - 01 : Detect read access -// - 10 : Detect write access -// - 11 : Detect read/write access -// NOTE: '10' & '11' modes are not supported on the instruction flow -// -// BREAK_EN: - 0 : Watchmode enable -// - 1 : Break enable -// -// INST_EN: - 0 : Checks are done on the execution unit (data flow) -// - 1 : Checks are done on the frontend (instruction flow) -// -// RANGE_MODE: - 0 : Address match on BRK_ADDR0 or BRK_ADDR1 -// - 1 : Address match on BRK_ADDR0->BRK_ADDR1 range -// -//----------------------------------------------------------------------------- -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]}; - -wire [7:0] brk_ctl_full = {3'b000, brk_ctl}; - - -// BRK_STAT Register -//----------------------------------------------------------------------------- -// 7 6 5 4 3 2 1 0 -// Reserved RANGE_WR RANGE_RD ADDR1_WR ADDR1_RD ADDR0_WR ADDR0_RD -//----------------------------------------------------------------------------- -reg [5:0] brk_stat; - -wire brk_stat_wr = brk_reg_wr[BRK_STAT]; -wire [5:0] brk_stat_set = {range_wr_set & `HWBRK_RANGE, - range_rd_set & `HWBRK_RANGE, - addr1_wr_set, addr1_rd_set, - addr0_wr_set, addr0_rd_set}; -wire [5:0] brk_stat_clr = ~dbg_din[5:0]; - -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) brk_stat <= 6'h00; - else if (brk_stat_wr) brk_stat <= ((brk_stat & brk_stat_clr) | brk_stat_set); - else brk_stat <= (brk_stat | brk_stat_set); - -wire [7:0] brk_stat_full = {2'b00, brk_stat}; -wire brk_pnd = |brk_stat; - - -// BRK_ADDR0 Register -//----------------------------------------------------------------------------- -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 -//============================================================================ - -wire [15:0] brk_ctl_rd = {8'h00, brk_ctl_full} & {16{brk_reg_rd[BRK_CTL]}}; -wire [15:0] brk_stat_rd = {8'h00, brk_stat_full} & {16{brk_reg_rd[BRK_STAT]}}; -wire [15:0] brk_addr0_rd = brk_addr0 & {16{brk_reg_rd[BRK_ADDR0]}}; -wire [15:0] brk_addr1_rd = brk_addr1 & {16{brk_reg_rd[BRK_ADDR1]}}; - -wire [15:0] brk_dout = brk_ctl_rd | - brk_stat_rd | - brk_addr0_rd | - brk_addr1_rd; - - -//============================================================================ -// 4) BREAKPOINT / WATCHPOINT GENERATION -//============================================================================ - -// Comparators -//--------------------------- -// 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)) & - brk_ctl[`BRK_RANGE] & `HWBRK_RANGE; - -reg fe_mb_en_buf; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) fe_mb_en_buf <= 1'b0; - else fe_mb_en_buf <= fe_mb_en; - -wire equ_i_addr0 = fe_mb_en_buf & (pc==brk_addr0) & ~brk_ctl[`BRK_RANGE]; -wire equ_i_addr1 = fe_mb_en_buf & (pc==brk_addr1) & ~brk_ctl[`BRK_RANGE]; -wire equ_i_range = fe_mb_en_buf & ((pc>=brk_addr0) & (pc<=brk_addr1)) & - brk_ctl[`BRK_RANGE] & `HWBRK_RANGE; - - -// Detect accesses -//--------------------------- - -// Detect Instruction read access -wire i_addr0_rd = equ_i_addr0 & brk_ctl[`BRK_I_EN]; -wire i_addr1_rd = equ_i_addr1 & brk_ctl[`BRK_I_EN]; -wire i_range_rd = equ_i_range & brk_ctl[`BRK_I_EN]; - -// Detect Execution-Unit write access -wire d_addr0_wr = equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr; -wire d_addr1_wr = equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr; -wire d_range_wr = equ_d_range & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr; - -// Detect DATA read access -// Whenever an "ADD r9. &0x200" instruction is executed, &0x200 will be read -// before being written back. In that case, the read flag should not be set. -// In general, We should here make sure no write access occures during the -// same instruction cycle before setting the read flag. -reg [2:0] d_rd_trig; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) d_rd_trig <= 3'h0; - else if (exec_done) d_rd_trig <= 3'h0; - else d_rd_trig <= {equ_d_range & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr, - equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr, - equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr}; - -wire d_addr0_rd = d_rd_trig[0] & exec_done & ~d_addr0_wr; -wire d_addr1_rd = d_rd_trig[1] & exec_done & ~d_addr1_wr; -wire d_range_rd = d_rd_trig[2] & exec_done & ~d_range_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; -assign addr1_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr1_rd | i_addr1_rd); -assign addr1_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr1_wr; -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 -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_dbg_uart.v b/tests/openmsp430/rtl/omsp_dbg_uart.v deleted file mode 100644 index 319099a5..00000000 --- a/tests/openmsp430/rtl/omsp_dbg_uart.v +++ /dev/null @@ -1,298 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_dbg_uart.v -// -// *Module Description: -// Debug UART communication interface (8N1, Half-duplex) -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_dbg_uart ( - -// OUTPUTs - dbg_addr, // Debug register address - dbg_din, // Debug register data input - 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 - dbg_rd_rdy, // Debug register data is ready for read - dbg_rst, // Debug unit reset - dbg_uart_rxd, // Debug interface: UART RXD - mem_burst, // Burst on going - mem_burst_end, // End TX/RX burst - mem_burst_rd, // Start TX burst - mem_burst_wr, // Start RX burst - mem_bw // Burst byte width -); - -// OUTPUTs -//========= -output [5:0] dbg_addr; // Debug register address -output [15:0] dbg_din; // Debug register data input -output dbg_rd; // Debug register data read -output dbg_uart_txd; // Debug interface: UART TXD -output dbg_wr; // Debug register data write - -// INPUTs -//========= -input dbg_clk; // Debug unit clock -input [15:0] dbg_dout; // Debug register data output -input dbg_rd_rdy; // Debug register data is ready for read -input dbg_rst; // Debug unit reset -input dbg_uart_rxd; // Debug interface: UART RXD -input mem_burst; // Burst on going -input mem_burst_end; // End TX/RX burst -input mem_burst_rd; // Start TX burst -input mem_burst_wr; // Start RX burst -input mem_bw; // Burst byte width - - -//============================================================================= -// 1) UART RECEIVE LINE SYNCHRONIZTION & FILTERING -//============================================================================= - -// Synchronize RXD input -//-------------------------------- -`ifdef SYNC_DBG_UART_RXD - - wire uart_rxd_n; - - omsp_sync_cell sync_cell_uart_rxd ( - .data_out (uart_rxd_n), - .data_in (~dbg_uart_rxd), - .clk (dbg_clk), - .rst (dbg_rst) - ); - wire uart_rxd = ~uart_rxd_n; -`else - wire uart_rxd = dbg_uart_rxd; -`endif - -// RXD input buffer -//-------------------------------- -reg [1:0] rxd_buf; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) rxd_buf <= 2'h3; - else rxd_buf <= {rxd_buf[0], uart_rxd}; - -// Majority decision -//------------------------ -reg rxd_maj; - -wire rxd_maj_nxt = (uart_rxd & rxd_buf[0]) | - (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; - -wire rxd_s = rxd_maj; -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 -//============================================================================= - -// Receive state -//------------------------ -reg [2:0] uart_state; -reg [2:0] uart_state_nxt; - -wire sync_done; -wire xfer_done; -reg [19:0] xfer_buf; -wire [19:0] xfer_buf_nxt; - -// State machine definition -parameter RX_SYNC = 3'h0; -parameter RX_CMD = 3'h1; -parameter RX_DATA1 = 3'h2; -parameter RX_DATA2 = 3'h3; -parameter TX_DATA1 = 3'h4; -parameter TX_DATA2 = 3'h5; - -// State transition -always @(uart_state or xfer_buf_nxt or mem_burst or mem_burst_wr or mem_burst_rd or mem_burst_end or mem_bw) - case (uart_state) - RX_SYNC : uart_state_nxt = RX_CMD; - RX_CMD : uart_state_nxt = mem_burst_wr ? - (mem_bw ? RX_DATA2 : RX_DATA1) : - mem_burst_rd ? - (mem_bw ? TX_DATA2 : TX_DATA1) : - (xfer_buf_nxt[`DBG_UART_WR] ? - (xfer_buf_nxt[`DBG_UART_BW] ? RX_DATA2 : RX_DATA1) : - (xfer_buf_nxt[`DBG_UART_BW] ? TX_DATA2 : TX_DATA1)); - RX_DATA1 : uart_state_nxt = RX_DATA2; - RX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ? - (mem_bw ? RX_DATA2 : RX_DATA1) : - RX_CMD; - TX_DATA1 : uart_state_nxt = TX_DATA2; - TX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ? - (mem_bw ? TX_DATA2 : TX_DATA1) : - RX_CMD; - // pragma coverage off - 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; - else if (xfer_done | sync_done | - mem_burst_wr | mem_burst_rd) uart_state <= uart_state_nxt; - -// Utility signals -wire cmd_valid = (uart_state==RX_CMD) & xfer_done; -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 -//============================================================================= -// After DBG_RST, the host needs to fist send a synchronization character (0x80) -// If this feature doesn't work properly, it is possible to disable it by -// commenting the DBG_UART_AUTO_SYNC define in the openMSP430.inc file. - -reg sync_busy; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) sync_busy <= 1'b0; - else if ((uart_state==RX_SYNC) & rxd_fe) sync_busy <= 1'b1; - else if ((uart_state==RX_SYNC) & rxd_re) sync_busy <= 1'b0; - -assign sync_done = (uart_state==RX_SYNC) & rxd_re & sync_busy; - -`ifdef DBG_UART_AUTO_SYNC - -reg [`DBG_UART_XFER_CNT_W+2:0] sync_cnt; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) sync_cnt <= {{`DBG_UART_XFER_CNT_W{1'b1}}, 3'b000}; - else if (sync_busy | (~sync_busy & sync_cnt[2])) sync_cnt <= sync_cnt+{{`DBG_UART_XFER_CNT_W+2{1'b0}}, 1'b1}; - -wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = sync_cnt[`DBG_UART_XFER_CNT_W+2:3]; -`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; -reg [`DBG_UART_XFER_CNT_W-1:0] xfer_cnt; - -wire txd_start = dbg_rd_rdy | (xfer_done & (uart_state==TX_DATA1)); -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; - else if (xfer_done) xfer_bit <= 4'h0; - else if (xfer_bit_inc) xfer_bit <= xfer_bit+4'h1; - -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) xfer_cnt <= {`DBG_UART_XFER_CNT_W{1'b0}}; - else if (rx_active & rxd_edge) xfer_cnt <= {1'b0, bit_cnt_max[`DBG_UART_XFER_CNT_W-1:1]}; - else if (txd_start | xfer_bit_inc) xfer_cnt <= bit_cnt_max; - else if (|xfer_cnt) xfer_cnt <= xfer_cnt+{`DBG_UART_XFER_CNT_W{1'b1}}; - - -// Receive/Transmit buffer -//------------------------- -assign xfer_buf_nxt = {rxd_s, xfer_buf[19:1]}; - -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) xfer_buf <= 20'h00000; - else if (dbg_rd_rdy) xfer_buf <= {1'b1, dbg_dout[15:8], 2'b01, dbg_dout[7:0], 1'b0}; - else if (xfer_bit_inc) xfer_buf <= xfer_buf_nxt; - - -// 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 -//============================================================================= - -reg [5:0] dbg_addr; - always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) dbg_addr <= 6'h00; - else if (cmd_valid) dbg_addr <= xfer_buf_nxt[`DBG_UART_ADDR]; - -reg dbg_bw; -always @ (posedge dbg_clk or posedge dbg_rst) - if (dbg_rst) dbg_bw <= 1'b0; - else if (cmd_valid) dbg_bw <= xfer_buf_nxt[`DBG_UART_BW]; - -wire dbg_din_bw = mem_burst ? mem_bw : dbg_bw; - -wire [15:0] dbg_din = dbg_din_bw ? {8'h00, xfer_buf_nxt[18:11]} : - {xfer_buf_nxt[18:11], xfer_buf_nxt[9:2]}; -wire dbg_wr = (xfer_done & (uart_state==RX_DATA2)); -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 -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_execution_unit.v b/tests/openmsp430/rtl/omsp_execution_unit.v deleted file mode 100644 index 8a2965e5..00000000 --- a/tests/openmsp430/rtl/omsp_execution_unit.v +++ /dev/null @@ -1,420 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_execution_unit.v -// -// *Module Description: -// openMSP430 Execution unit -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_execution_unit ( - -// OUTPUTs - cpuoff, // Turns off the CPU - dbg_reg_din, // Debug unit CPU register data input - gie, // General interrupt enable - mab, // Memory address bus - mb_en, // Memory bus enable - mb_wr, // Memory bus write transfer - mdb_out, // Memory data bus output - oscoff, // Turns off LFXT1 clock input - pc_sw, // Program counter software value - pc_sw_wr, // Program counter software write - scg0, // System clock generator 1. Turns off the DCO - scg1, // System clock generator 1. Turns off the SMCLK - -// INPUTs - dbg_halt_st, // Halt/Run status from CPU - dbg_mem_dout, // Debug unit data output - dbg_reg_wr, // Debug unit CPU register write - 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 - mclk, // Main system clock - mdb_in, // Memory data bus input - pc, // Program counter - pc_nxt, // Next PC value (for CALL & IRQ) - puc_rst, // Main system reset - scan_enable // Scan enable (active during scan shifting) -); - -// OUTPUTs -//========= -output cpuoff; // Turns off the CPU -output [15:0] dbg_reg_din; // Debug unit CPU register data input -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 [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 -output scg1; // System clock generator 1. Turns off the SMCLK - -// INPUTs -//========= -input dbg_halt_st; // Halt/Run status from CPU -input [15:0] dbg_mem_dout; // Debug unit data output -input dbg_reg_wr; // Debug unit CPU register write -input [3:0] e_state; // Execution state -input exec_done; // Execution completed -input [7:0] inst_ad; // Decoded Inst: destination addressing mode -input [7:0] inst_as; // Decoded Inst: source addressing mode -input [11:0] inst_alu; // ALU control signals -input inst_bw; // Decoded Inst: byte width -input [15:0] inst_dest; // Decoded Inst: destination (one hot) -input [15:0] inst_dext; // Decoded Inst: destination extended instruction word -input inst_irq_rst; // Decoded Inst: reset interrupt -input [7:0] inst_jmp; // Decoded Inst: Conditional jump -input inst_mov; // Decoded Inst: mov instruction -input [15:0] inst_sext; // Decoded Inst: source extended instruction word -input [7:0] inst_so; // Decoded Inst: Single-operand arithmetic -input [15:0] inst_src; // Decoded Inst: source (one hot) -input [2:0] inst_type; // Decoded Instruction type -input mclk; // Main system clock -input [15:0] mdb_in; // Memory data bus input -input [15:0] pc; // Program counter -input [15:0] pc_nxt; // Next PC value (for CALL & IRQ) -input puc_rst; // Main system reset -input scan_enable; // Scan enable (active during scan shifting) - - -//============================================================================= -// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION -//============================================================================= - -wire [15:0] alu_out; -wire [15:0] alu_out_add; -wire [3:0] alu_stat; -wire [3:0] alu_stat_wr; -wire [15:0] op_dst; -wire [15:0] op_src; -wire [15:0] reg_dest; -wire [15:0] reg_src; -wire [15:0] mdb_in_bw; -wire [15:0] mdb_in_val; -wire [3:0] status; - - -//============================================================================= -// 2) REGISTER FILE -//============================================================================= - -wire reg_dest_wr = ((e_state==`E_EXEC) & ( - (inst_type[`INST_TO] & inst_ad[`DIR] & ~inst_alu[`EXEC_NO_WR]) | - (inst_type[`INST_SO] & inst_as[`DIR] & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI])) | - inst_type[`INST_JMP])) | dbg_reg_wr; - -wire reg_sp_wr = (((e_state==`E_IRQ_1) | (e_state==`E_IRQ_3)) & ~inst_irq_rst) | - ((e_state==`E_DST_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ~inst_as[`IDX] & ~((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]))) | - ((e_state==`E_SRC_AD) & ((inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX])) | - ((e_state==`E_SRC_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]))); - -wire reg_sr_wr = (e_state==`E_DST_RD) & inst_so[`RETI]; - -wire reg_sr_clr = (e_state==`E_IRQ_2); - -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]) | - ((e_state==`E_SRC_RD) & inst_so[`RETI]) | - ((e_state==`E_EXEC) & inst_so[`RETI]); - -assign dbg_reg_din = reg_dest; - - -omsp_register_file register_file_0 ( - -// OUTPUTs - .cpuoff (cpuoff), // Turns off the CPU - .gie (gie), // General interrupt enable - .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 - .reg_dest (reg_dest), // Selected register destination content - .reg_src (reg_src), // Selected register source content - .scg0 (scg0), // System clock generator 1. Turns off the DCO - .scg1 (scg1), // System clock generator 1. Turns off the SMCLK - .status (status), // R2 Status {V,N,Z,C} - -// INPUTs - .alu_stat (alu_stat), // ALU Status {V,N,Z,C} - .alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C} - .inst_bw (inst_bw), // Decoded Inst: byte width - .inst_dest (inst_dest), // Register destination selection - .inst_src (inst_src), // Register source selection - .mclk (mclk), // Main system clock - .pc (pc), // Program counter - .puc_rst (puc_rst), // Main system reset - .reg_dest_val (alu_out), // Selected register destination value - .reg_dest_wr (reg_dest_wr), // Write selected register destination - .reg_pc_call (reg_pc_call), // Trigger PC update for a CALL instruction - .reg_sp_val (alu_out_add), // Stack Pointer next value - .reg_sp_wr (reg_sp_wr), // Stack Pointer write - .reg_sr_clr (reg_sr_clr), // Status register clear for interrupts - .reg_sr_wr (reg_sr_wr), // Status Register update for RETI instruction - .reg_incr (reg_incr), // Increment source register - .scan_enable (scan_enable) // Scan enable (active during scan shifting) -); - - -//============================================================================= -// 3) SOURCE OPERAND MUXING -//============================================================================= -// inst_as[`DIR] : Register direct. -> Source is in register -// inst_as[`IDX] : Register indexed. -> Source is in memory, address is register+offset -// inst_as[`INDIR] : Register indirect. -// inst_as[`INDIR_I]: Register indirect autoincrement. -// inst_as[`SYMB] : Symbolic (operand is in memory at address PC+x). -// inst_as[`IMM] : Immediate (operand is next word in the instruction stream). -// inst_as[`ABS] : Absolute (operand is in memory at address x). -// inst_as[`CONST] : Constant. - -wire src_reg_src_sel = (e_state==`E_IRQ_0) | - (e_state==`E_IRQ_2) | - ((e_state==`E_SRC_RD) & ~inst_as[`ABS]) | - ((e_state==`E_SRC_WR) & ~inst_as[`ABS]) | - ((e_state==`E_EXEC) & inst_as[`DIR] & ~inst_type[`INST_JMP]); - -wire src_reg_dest_sel = (e_state==`E_IRQ_1) | - (e_state==`E_IRQ_3) | - ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL])) | - ((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]); - -wire src_mdb_in_val_sel = ((e_state==`E_DST_RD) & inst_so[`RETI]) | - ((e_state==`E_EXEC) & (inst_as[`INDIR] | inst_as[`INDIR_I] | - inst_as[`IDX] | inst_as[`SYMB] | - inst_as[`ABS])); - -wire src_inst_dext_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL])) | - ((e_state==`E_DST_WR) & ~(inst_so[`PUSH] | inst_so[`CALL] | - inst_so[`RETI])); - -wire src_inst_sext_sel = ((e_state==`E_EXEC) & (inst_type[`INST_JMP] | inst_as[`IMM] | - inst_as[`CONST] | inst_so[`RETI])); - - -assign op_src = src_reg_src_sel ? reg_src : - src_reg_dest_sel ? reg_dest : - src_mdb_in_val_sel ? mdb_in_val : - src_inst_dext_sel ? inst_dext : - src_inst_sext_sel ? inst_sext : 16'h0000; - - -//============================================================================= -// 4) DESTINATION OPERAND MUXING -//============================================================================= -// inst_ad[`DIR] : Register direct. -// inst_ad[`IDX] : Register indexed. -// inst_ad[`SYMB] : Symbolic (operand is in memory at address PC+x). -// inst_ad[`ABS] : Absolute (operand is in memory at address x). - - -wire dst_inst_sext_sel = ((e_state==`E_SRC_RD) & (inst_as[`IDX] | inst_as[`SYMB] | - inst_as[`ABS])) | - ((e_state==`E_SRC_WR) & (inst_as[`IDX] | inst_as[`SYMB] | - inst_as[`ABS])); - -wire dst_mdb_in_bw_sel = ((e_state==`E_DST_WR) & inst_so[`RETI]) | - ((e_state==`E_EXEC) & ~(inst_ad[`DIR] | inst_type[`INST_JMP] | - inst_type[`INST_SO]) & ~inst_so[`RETI]); - -wire dst_fffe_sel = (e_state==`E_IRQ_0) | - (e_state==`E_IRQ_1) | - (e_state==`E_IRQ_3) | - ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & ~inst_so[`RETI]) | - ((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]) | - ((e_state==`E_SRC_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & (inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]); - -wire dst_reg_dest_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_ad[`ABS] | inst_so[`RETI])) | - ((e_state==`E_DST_WR) & ~inst_ad[`ABS]) | - ((e_state==`E_EXEC) & (inst_ad[`DIR] | inst_type[`INST_JMP] | - inst_type[`INST_SO]) & ~inst_so[`RETI]); - - -assign op_dst = dbg_halt_st ? dbg_mem_dout : - dst_inst_sext_sel ? inst_sext : - dst_mdb_in_bw_sel ? mdb_in_bw : - dst_reg_dest_sel ? reg_dest : - dst_fffe_sel ? 16'hfffe : 16'h0000; - - -//============================================================================= -// 5) ALU -//============================================================================= - -wire exec_cycle = (e_state==`E_EXEC); - -omsp_alu alu_0 ( - -// OUTPUTs - .alu_out (alu_out), // ALU output value - .alu_out_add (alu_out_add), // ALU adder output value - .alu_stat (alu_stat), // ALU Status {V,N,Z,C} - .alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C} - -// INPUTs - .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU - .exec_cycle (exec_cycle), // Instruction execution cycle - .inst_alu (inst_alu), // ALU control signals - .inst_bw (inst_bw), // Decoded Inst: byte width - .inst_jmp (inst_jmp), // Decoded Inst: Conditional jump - .inst_so (inst_so), // Single-operand arithmetic - .op_dst (op_dst), // Destination operand - .op_src (op_src), // Source operand - .status (status) // R2 Status {V,N,Z,C} -); - - -//============================================================================= -// 6) MEMORY INTERFACE -//============================================================================= - -// Detect memory read/write access -assign mb_en = ((e_state==`E_IRQ_1) & ~inst_irq_rst) | - ((e_state==`E_IRQ_3) & ~inst_irq_rst) | - ((e_state==`E_SRC_RD) & ~inst_as[`IMM]) | - (e_state==`E_SRC_WR) | - ((e_state==`E_EXEC) & inst_so[`RETI]) | - ((e_state==`E_DST_RD) & ~inst_type[`INST_SO] - & ~inst_mov) | - (e_state==`E_DST_WR); - -wire [1:0] mb_wr_msk = inst_alu[`EXEC_NO_WR] ? 2'b00 : - ~inst_bw ? 2'b11 : - alu_out_add[0] ? 2'b10 : 2'b01; -assign mb_wr = ({2{(e_state==`E_IRQ_1)}} | - {2{(e_state==`E_IRQ_3)}} | - {2{(e_state==`E_DST_WR)}} | - {2{(e_state==`E_SRC_WR)}}) & mb_wr_msk; - -// Memory address bus -assign mab = alu_out_add[15:0]; - -// Memory data bus output -reg [15:0] mdb_out_nxt; - -`ifdef CLOCK_GATING -wire mdb_out_nxt_en = (e_state==`E_DST_RD) | - (((e_state==`E_EXEC) & ~inst_so[`CALL]) | - (e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)); -wire mclk_mdb_out_nxt; -omsp_clock_gate clock_gate_mdb_out_nxt (.gclk(mclk_mdb_out_nxt), - .clk (mclk), .enable(mdb_out_nxt_en), .scan_enable(scan_enable)); -`else -wire mclk_mdb_out_nxt = mclk; -`endif - -always @(posedge mclk_mdb_out_nxt or posedge puc_rst) - if (puc_rst) mdb_out_nxt <= 16'h0000; - else if (e_state==`E_DST_RD) mdb_out_nxt <= pc_nxt; -`ifdef CLOCK_GATING - else mdb_out_nxt <= alu_out; -`else - else if ((e_state==`E_EXEC & ~inst_so[`CALL]) | - (e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)) mdb_out_nxt <= alu_out; -`endif - -assign mdb_out = inst_bw ? {2{mdb_out_nxt[7:0]}} : mdb_out_nxt; - -// Format memory data bus input depending on BW -reg mab_lsb; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) mab_lsb <= 1'b0; - else if (mb_en) mab_lsb <= alu_out_add[0]; - -assign mdb_in_bw = ~inst_bw ? mdb_in : - mab_lsb ? {2{mdb_in[15:8]}} : mdb_in; - -// Memory data bus input buffer (buffer after a source read) -reg mdb_in_buf_en; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) mdb_in_buf_en <= 1'b0; - else mdb_in_buf_en <= (e_state==`E_SRC_RD); - -reg mdb_in_buf_valid; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) mdb_in_buf_valid <= 1'b0; - else if (e_state==`E_EXEC) mdb_in_buf_valid <= 1'b0; - else if (mdb_in_buf_en) mdb_in_buf_valid <= 1'b1; - -reg [15:0] mdb_in_buf; - -`ifdef CLOCK_GATING -wire mclk_mdb_in_buf; -omsp_clock_gate clock_gate_mdb_in_buf (.gclk(mclk_mdb_in_buf), - .clk (mclk), .enable(mdb_in_buf_en), .scan_enable(scan_enable)); -`else -wire mclk_mdb_in_buf = mclk; -`endif - -always @(posedge mclk_mdb_in_buf or posedge puc_rst) - if (puc_rst) mdb_in_buf <= 16'h0000; -`ifdef CLOCK_GATING - else mdb_in_buf <= mdb_in_bw; -`else - else if (mdb_in_buf_en) mdb_in_buf <= mdb_in_bw; -`endif - -assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw; - - -endmodule // omsp_execution_unit - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_frontend.v b/tests/openmsp430/rtl/omsp_frontend.v deleted file mode 100644 index 343944bd..00000000 --- a/tests/openmsp430/rtl/omsp_frontend.v +++ /dev/null @@ -1,966 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_frontend.v -// -// *Module Description: -// openMSP430 Instruction fetch and decode unit -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -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) - -// 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) -); - -// OUTPUTs -//========= -output dbg_halt_st; // Halt/Run status from CPU -output decode_noirq; // Frontend decode instruction -output [3:0] e_state; // Execution state -output exec_done; // Execution completed -output [7:0] inst_ad; // Decoded Inst: destination addressing mode -output [7:0] inst_as; // Decoded Inst: source addressing mode -output [11:0] inst_alu; // ALU control signals -output inst_bw; // Decoded Inst: byte width -output [15:0] inst_dest; // Decoded Inst: destination (one hot) -output [15:0] inst_dext; // Decoded Inst: destination extended instruction word -output inst_irq_rst; // Decoded Inst: Reset interrupt -output [7:0] inst_jmp; // Decoded Inst: Conditional jump -output inst_mov; // Decoded Inst: mov instruction -output [15:0] inst_sext; // Decoded Inst: source extended instruction word -output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic -output [15:0] inst_src; // Decoded Inst: source (one hot) -output [2:0] inst_type; // Decoded Instruction type -output [13:0] irq_acc; // Interrupt request accepted (one-hot signal) -output [15:0] mab; // Frontend Memory address bus -output mb_en; // Frontend Memory bus enable -output mclk_enable; // Main System Clock enable -output mclk_wkup; // Main System Clock wake-up (asynchronous) -output nmi_acc; // Non-Maskable interrupt request accepted -output [15:0] pc; // Program counter -output [15:0] pc_nxt; // Next PC value (for CALL & IRQ) - -// INPUTs -//========= -input cpu_en_s; // Enable CPU code execution (synchronous) -input cpuoff; // Turns off the CPU -input dbg_halt_cmd; // Halt CPU command -input [3:0] dbg_reg_sel; // Debug selected register for rd/wr access -input fe_pmem_wait; // Frontend wait for Instruction fetch -input gie; // General interrupt enable -input [13:0] irq; // Maskable interrupts -input mclk; // Main system clock -input [15:0] mdb_in; // Frontend Memory data bus input -input nmi_pnd; // Non-maskable interrupt pending -input nmi_wkup; // NMI Wakeup -input [15:0] pc_sw; // Program counter software value -input pc_sw_wr; // Program counter software write -input puc_rst; // Main system reset -input scan_enable; // Scan enable (active during scan shifting) -input wdt_irq; // Watchdog-timer interrupt -input wdt_wkup; // Watchdog Wakeup -input wkup; // System Wake-up (asynchronous) - - -//============================================================================= -// 1) UTILITY FUNCTIONS -//============================================================================= - -// 16 bits one-hot decoder -function [15:0] one_hot16; - input [3:0] binary; - begin - one_hot16 = 16'h0000; - one_hot16[binary] = 1'b1; - end -endfunction - -// 8 bits one-hot decoder -function [7:0] one_hot8; - input [2:0] binary; - begin - one_hot8 = 8'h00; - one_hot8[binary] = 1'b1; - end -endfunction - - -//============================================================================= -// 2) PARAMETER DEFINITIONS -//============================================================================= - -// -// 2.1) Instruction State machine definitons -//------------------------------------------- - -parameter I_IRQ_FETCH = `I_IRQ_FETCH; -parameter I_IRQ_DONE = `I_IRQ_DONE; -parameter I_DEC = `I_DEC; // New instruction ready for decode -parameter I_EXT1 = `I_EXT1; // 1st Extension word -parameter I_EXT2 = `I_EXT2; // 2nd Extension word -parameter I_IDLE = `I_IDLE; // CPU is in IDLE mode - -// -// 2.2) Execution State machine definitons -//------------------------------------------- - -parameter E_IRQ_0 = `E_IRQ_0; -parameter E_IRQ_1 = `E_IRQ_1; -parameter E_IRQ_2 = `E_IRQ_2; -parameter E_IRQ_3 = `E_IRQ_3; -parameter E_IRQ_4 = `E_IRQ_4; -parameter E_SRC_AD = `E_SRC_AD; -parameter E_SRC_RD = `E_SRC_RD; -parameter E_SRC_WR = `E_SRC_WR; -parameter E_DST_AD = `E_DST_AD; -parameter E_DST_RD = `E_DST_RD; -parameter E_DST_WR = `E_DST_WR; -parameter E_EXEC = `E_EXEC; -parameter E_JUMP = `E_JUMP; -parameter E_IDLE = `E_IDLE; - - -//============================================================================= -// 3) FRONTEND STATE MACHINE -//============================================================================= - -// The wire "conv" is used as state bits to calculate the next response -reg [2:0] i_state; -reg [2:0] i_state_nxt; - -reg [1:0] inst_sz; -wire [1:0] inst_sz_nxt; -wire irq_detect; -wire [2:0] inst_type_nxt; -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; - -// 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) - 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_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 : - 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 : - (inst_sz!=2'b01) ? I_EXT2 : I_DEC; - I_EXT2 : i_state_nxt = I_DEC; - // pragma coverage off - default : i_state_nxt = I_IRQ_FETCH; - // pragma coverage on - endcase - -// State machine -always @(posedge mclk or posedge puc_rst) - if (puc_rst) i_state <= I_IRQ_FETCH; - else i_state <= i_state_nxt; - -// Utility signals -wire decode_noirq = ((i_state==I_DEC) & (exec_done | (e_state==E_IDLE))); -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; -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); - - -//============================================================================= -// 4) INTERRUPT HANDLING & SYSTEM WAKEUP -//============================================================================= - -// -// 4.1) INTERRUPT HANDLING -//----------------------------------------- - -// Detect reset interrupt -reg inst_irq_rst; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) inst_irq_rst <= 1'b1; - 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)); - -`ifdef CLOCK_GATING -wire mclk_irq_num; -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; -`endif - -// Select interrupt vector -reg [3:0] irq_num; -always @(posedge mclk_irq_num or posedge puc_rst) - if (puc_rst) irq_num <= 4'hf; -`ifdef CLOCK_GATING - else irq_num <= nmi_pnd ? 4'he : -`else - else if (irq_detect) irq_num <= nmi_pnd ? 4'he : -`endif - irq[13] ? 4'hd : - irq[12] ? 4'hc : - irq[11] ? 4'hb : - (irq[10] | wdt_irq) ? 4'ha : - irq[9] ? 4'h9 : - irq[8] ? 4'h8 : - irq[7] ? 4'h7 : - irq[6] ? 4'h6 : - irq[5] ? 4'h5 : - irq[4] ? 4'h4 : - irq[3] ? 4'h3 : - irq[2] ? 4'h2 : - irq[1] ? 4'h1 : - irq[0] ? 4'h0 : 4'hf; - -wire [15:0] irq_addr = {11'h7ff, irq_num, 1'b0}; - -// Interrupt request accepted -wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}}; -wire [13:0] irq_acc = irq_acc_all[13:0]; -wire nmi_acc = irq_acc_all[14]; - -// -// 4.2) SYSTEM WAKEUP -//----------------------------------------- -`ifdef CPUOFF_EN - -// Generate the main system clock enable signal - // Keep the clock running if: -wire mclk_enable = inst_irq_rst ? cpu_en_s : // - the RESET interrupt is currently executing - // and if the CPU is enabled - // otherwise if: - ~((cpuoff | ~cpu_en_s) & // - the CPUOFF flag, cpu_en command, instruction - (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)); - -// 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)); - -`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; -`endif - -//============================================================================= -// 5) FETCH INSTRUCTION -//============================================================================= - -// -// 5.1) PROGRAM COUNTER & MEMORY INTERFACE -//----------------------------------------- - -// Program counter -reg [15:0] pc; - -// Compute next PC value -wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0}; -wire [15:0] pc_nxt = pc_sw_wr ? pc_sw : - (i_state==I_IRQ_FETCH) ? irq_addr : - (i_state==I_IRQ_DONE) ? mdb_in : pc_incr; - -`ifdef CLOCK_GATING -wire pc_en = fetch | - pc_sw_wr | - (i_state==I_IRQ_FETCH) | - (i_state==I_IRQ_DONE); -wire mclk_pc; -omsp_clock_gate clock_gate_pc (.gclk(mclk_pc), - .clk (mclk), .enable(pc_en), .scan_enable(scan_enable)); -`else -wire mclk_pc = mclk; -`endif - -always @(posedge mclk_pc or posedge puc_rst) - if (puc_rst) pc <= 16'h0000; - else pc <= pc_nxt; - -// Check if ROM has been busy in order to retry ROM 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); - - -// -// 5.2) INSTRUCTION REGISTER -//-------------------------------- - -// Instruction register -wire [15:0] ir = mdb_in; - -// Detect if source extension word is required -wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]); - -// For the Symbolic addressing mode, add -2 to the extension word in order -// to make up for the PC address -wire [15:0] ext_incr = ((i_state==I_EXT1) & inst_as[`SYMB]) | - ((i_state==I_EXT2) & inst_ad[`SYMB]) | - ((i_state==I_EXT1) & ~inst_as[`SYMB] & - ~(i_state_nxt==I_EXT2) & inst_ad[`SYMB]) ? 16'hfffe : 16'h0000; - -wire [15:0] ext_nxt = ir + ext_incr; - -// Store source extension word -reg [15:0] inst_sext; - -`ifdef CLOCK_GATING -wire inst_sext_en = (decode & is_const) | - (decode & inst_type_nxt[`INST_JMP]) | - ((i_state==I_EXT1) & is_sext); -wire mclk_inst_sext; -omsp_clock_gate clock_gate_inst_sext (.gclk(mclk_inst_sext), - .clk (mclk), .enable(inst_sext_en), .scan_enable(scan_enable)); -`else -wire mclk_inst_sext = mclk; -`endif - -always @(posedge mclk_inst_sext or posedge puc_rst) - if (puc_rst) inst_sext <= 16'h0000; - else if (decode & is_const) inst_sext <= sconst_nxt; - else if (decode & inst_type_nxt[`INST_JMP]) inst_sext <= {{5{ir[9]}},ir[9:0],1'b0}; -`ifdef CLOCK_GATING - else inst_sext <= ext_nxt; -`else - else if ((i_state==I_EXT1) & is_sext) inst_sext <= ext_nxt; -`endif - -// Source extension word is ready -wire inst_sext_rdy = (i_state==I_EXT1) & is_sext; - - -// Store destination extension word -reg [15:0] inst_dext; - -`ifdef CLOCK_GATING -wire inst_dext_en = ((i_state==I_EXT1) & ~is_sext) | - (i_state==I_EXT2); -wire mclk_inst_dext; -omsp_clock_gate clock_gate_inst_dext (.gclk(mclk_inst_dext), - .clk (mclk), .enable(inst_dext_en), .scan_enable(scan_enable)); -`else -wire mclk_inst_dext = mclk; -`endif - -always @(posedge mclk_inst_dext or posedge puc_rst) - if (puc_rst) inst_dext <= 16'h0000; - else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt; -`ifdef CLOCK_GATING - else inst_dext <= ext_nxt; -`else - else if (i_state==I_EXT2) inst_dext <= ext_nxt; -`endif - -// Destination extension word is ready -wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2)); - - -//============================================================================= -// 6) DECODE INSTRUCTION -//============================================================================= - -`ifdef CLOCK_GATING -wire mclk_decode; -omsp_clock_gate clock_gate_decode (.gclk(mclk_decode), - .clk (mclk), .enable(decode), .scan_enable(scan_enable)); -`else -wire mclk_decode = mclk; -`endif - -// -// 6.1) OPCODE: INSTRUCTION TYPE -//---------------------------------------- -// Instructions type is encoded in a one hot fashion as following: -// -// 3'b001: Single-operand arithmetic -// 3'b010: Conditional jump -// 3'b100: Two-operand arithmetic - -reg [2:0] inst_type; -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 - else inst_type <= inst_type_nxt; -`else - else if (decode) inst_type <= inst_type_nxt; -`endif - -// -// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC -//---------------------------------------- -// Instructions are encoded in a one hot fashion as following: -// -// 8'b00000001: RRC -// 8'b00000010: SWPB -// 8'b00000100: RRA -// 8'b00001000: SXT -// 8'b00010000: PUSH -// 8'b00100000: CALL -// 8'b01000000: RETI -// 8'b10000000: IRQ - -reg [7:0] inst_so; -wire [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}}); - -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_so <= 8'h00; -`ifdef CLOCK_GATING - else inst_so <= inst_so_nxt; -`else - else if (decode) inst_so <= inst_so_nxt; -`endif - -// -// 6.3) OPCODE: CONDITIONAL JUMP -//-------------------------------- -// Instructions are encoded in a one hot fashion as following: -// -// 8'b00000001: JNE/JNZ -// 8'b00000010: JEQ/JZ -// 8'b00000100: JNC/JLO -// 8'b00001000: JC/JHS -// 8'b00010000: JN -// 8'b00100000: JGE -// 8'b01000000: JL -// 8'b10000000: JMP - -reg [2:0] inst_jmp_bin; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_jmp_bin <= 3'h0; -`ifdef CLOCK_GATING - else inst_jmp_bin <= ir[12:10]; -`else - else if (decode) inst_jmp_bin <= ir[12:10]; -`endif - -wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}}; - - -// -// 6.4) OPCODE: TWO-OPERAND ARITHMETIC -//------------------------------------- -// Instructions are encoded in a one hot fashion as following: -// -// 12'b000000000001: MOV -// 12'b000000000010: ADD -// 12'b000000000100: ADDC -// 12'b000000001000: SUBC -// 12'b000000010000: SUB -// 12'b000000100000: CMP -// 12'b000001000000: DADD -// 12'b000010000000: BIT -// 12'b000100000000: BIC -// 12'b001000000000: BIS -// 12'b010000000000: XOR -// 12'b100000000000: AND - -wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}}; -wire [11:0] inst_to_nxt = inst_to_1hot[15:4]; - -reg inst_mov; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_mov <= 1'b0; -`ifdef CLOCK_GATING - else inst_mov <= inst_to_nxt[`MOV]; -`else - else if (decode) inst_mov <= inst_to_nxt[`MOV]; -`endif - - -// -// 6.5) SOURCE AND DESTINATION REGISTERS -//--------------------------------------- - -// Destination register -reg [3:0] inst_dest_bin; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_dest_bin <= 4'h0; -`ifdef CLOCK_GATING - else inst_dest_bin <= ir[3:0]; -`else - else if (decode) inst_dest_bin <= ir[3:0]; -`endif - -wire [15:0] inst_dest = dbg_halt_st ? one_hot16(dbg_reg_sel) : - inst_type[`INST_JMP] ? 16'h0001 : - inst_so[`IRQ] | - inst_so[`PUSH] | - inst_so[`CALL] ? 16'h0002 : - one_hot16(inst_dest_bin); - - -// Source register -reg [3:0] inst_src_bin; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_src_bin <= 4'h0; -`ifdef CLOCK_GATING - else inst_src_bin <= ir[11:8]; -`else - else if (decode) inst_src_bin <= ir[11:8]; -`endif - -wire [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin) : - inst_so[`RETI] ? 16'h0002 : - inst_so[`IRQ] ? 16'h0001 : - inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000; - - -// -// 6.6) SOURCE ADDRESSING MODES -//-------------------------------- -// Source addressing modes are encoded in a one hot fashion as following: -// -// 13'b0000000000001: Register direct. -// 13'b0000000000010: Register indexed. -// 13'b0000000000100: Register indirect. -// 13'b0000000001000: Register indirect autoincrement. -// 13'b0000000010000: Symbolic (operand is in memory at address PC+x). -// 13'b0000000100000: Immediate (operand is next word in the instruction stream). -// 13'b0000001000000: Absolute (operand is in memory at address x). -// 13'b0000010000000: Constant 4. -// 13'b0000100000000: Constant 8. -// 13'b0001000000000: Constant 0. -// 13'b0010000000000: Constant 1. -// 13'b0100000000000: Constant 2. -// 13'b1000000000000: Constant -1. - -reg [12:0] inst_as_nxt; - -wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8]; - -always @(src_reg or ir or inst_type_nxt) - begin - if (inst_type_nxt[`INST_JMP]) - inst_as_nxt = 13'b0000000000001; - else if (src_reg==4'h3) // Addressing mode using R3 - case (ir[5:4]) - 2'b11 : inst_as_nxt = 13'b1000000000000; - 2'b10 : inst_as_nxt = 13'b0100000000000; - 2'b01 : inst_as_nxt = 13'b0010000000000; - default: inst_as_nxt = 13'b0001000000000; - endcase - else if (src_reg==4'h2) // Addressing mode using R2 - case (ir[5:4]) - 2'b11 : inst_as_nxt = 13'b0000100000000; - 2'b10 : inst_as_nxt = 13'b0000010000000; - 2'b01 : inst_as_nxt = 13'b0000001000000; - default: inst_as_nxt = 13'b0000000000001; - endcase - else if (src_reg==4'h0) // Addressing mode using R0 - case (ir[5:4]) - 2'b11 : inst_as_nxt = 13'b0000000100000; - 2'b10 : inst_as_nxt = 13'b0000000000100; - 2'b01 : inst_as_nxt = 13'b0000000010000; - default: inst_as_nxt = 13'b0000000000001; - endcase - else // General Addressing mode - case (ir[5:4]) - 2'b11 : inst_as_nxt = 13'b0000000001000; - 2'b10 : inst_as_nxt = 13'b0000000000100; - 2'b01 : inst_as_nxt = 13'b0000000000010; - default: inst_as_nxt = 13'b0000000000001; - endcase - end -assign is_const = |inst_as_nxt[12:7]; - -reg [7:0] inst_as; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_as <= 8'h00; -`ifdef CLOCK_GATING - else inst_as <= {is_const, inst_as_nxt[6:0]}; -`else - else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]}; -`endif - - -// 13'b0000010000000: Constant 4. -// 13'b0000100000000: Constant 8. -// 13'b0001000000000: Constant 0. -// 13'b0010000000000: Constant 1. -// 13'b0100000000000: Constant 2. -// 13'b1000000000000: Constant -1. -always @(inst_as_nxt) - begin - if (inst_as_nxt[7]) sconst_nxt = 16'h0004; - else if (inst_as_nxt[8]) sconst_nxt = 16'h0008; - else if (inst_as_nxt[9]) sconst_nxt = 16'h0000; - else if (inst_as_nxt[10]) sconst_nxt = 16'h0001; - else if (inst_as_nxt[11]) sconst_nxt = 16'h0002; - else if (inst_as_nxt[12]) sconst_nxt = 16'hffff; - else sconst_nxt = 16'h0000; - end - - -// -// 6.7) DESTINATION ADDRESSING MODES -//----------------------------------- -// Destination addressing modes are encoded in a one hot fashion as following: -// -// 8'b00000001: Register direct. -// 8'b00000010: Register indexed. -// 8'b00010000: Symbolic (operand is in memory at address PC+x). -// 8'b01000000: Absolute (operand is in memory at address x). - -reg [7:0] inst_ad_nxt; - -wire [3:0] dest_reg = ir[3:0]; - -always @(dest_reg or ir or inst_type_nxt) - begin - if (~inst_type_nxt[`INST_TO]) - inst_ad_nxt = 8'b00000000; - else if (dest_reg==4'h2) // Addressing mode using R2 - case (ir[7]) - 1'b1 : inst_ad_nxt = 8'b01000000; - default: inst_ad_nxt = 8'b00000001; - endcase - else if (dest_reg==4'h0) // Addressing mode using R0 - case (ir[7]) - 1'b1 : inst_ad_nxt = 8'b00010000; - default: inst_ad_nxt = 8'b00000001; - endcase - else // General Addressing mode - case (ir[7]) - 1'b1 : inst_ad_nxt = 8'b00000010; - default: inst_ad_nxt = 8'b00000001; - endcase - end - -reg [7:0] inst_ad; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_ad <= 8'h00; -`ifdef CLOCK_GATING - else inst_ad <= inst_ad_nxt; -`else - else if (decode) inst_ad <= inst_ad_nxt; -`endif - - -// -// 6.8) REMAINING INSTRUCTION DECODING -//------------------------------------- - -// Operation size -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; - -// 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])} + - {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])}; -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_sz <= 2'b00; -`ifdef CLOCK_GATING - else inst_sz <= inst_sz_nxt; -`else - else if (decode) inst_sz <= inst_sz_nxt; -`endif - - -//============================================================================= -// 7) EXECUTION-UNIT STATE MACHINE -//============================================================================= - -// State machine registers -reg [3:0] e_state; - - -// State machine control signals -//-------------------------------- - -wire src_acalc_pre = inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS]; -wire src_rd_pre = inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM] | inst_so_nxt[`RETI]; -wire dst_acalc_pre = inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]; -wire dst_acalc = inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS]; -wire dst_rd_pre = inst_ad_nxt[`IDX] | inst_so_nxt[`PUSH] | inst_so_nxt[`CALL] | inst_so_nxt[`RETI]; -wire dst_rd = inst_ad[`IDX] | inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI]; - -wire inst_branch = (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI]; - -reg exec_jmp; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) exec_jmp <= 1'b0; - else if (inst_branch & decode) exec_jmp <= 1'b1; - else if (e_state==E_JUMP) exec_jmp <= 1'b0; - -reg exec_dst_wr; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) exec_dst_wr <= 1'b0; - else if (e_state==E_DST_RD) exec_dst_wr <= 1'b1; - else if (e_state==E_DST_WR) exec_dst_wr <= 1'b0; - -reg exec_src_wr; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) exec_src_wr <= 1'b0; - else if (inst_type[`INST_SO] & (e_state==E_SRC_RD)) exec_src_wr <= 1'b1; - else if ((e_state==E_SRC_WR) || (e_state==E_DST_WR)) exec_src_wr <= 1'b0; - -reg exec_dext_rdy; -always @(posedge mclk or posedge puc_rst) - if (puc_rst) exec_dext_rdy <= 1'b0; - else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0; - else if (inst_dext_rdy) exec_dext_rdy <= 1'b1; - -// 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 : - cpuoff ? E_IDLE : - src_acalc_pre ? E_SRC_AD : - src_rd_pre ? E_SRC_RD : - dst_acalc_pre ? E_DST_AD : - dst_rd_pre ? E_DST_RD : E_EXEC; - - -// State machine -//-------------------------------- - -// States Transitions -always @(e_state or dst_acalc or dst_rd or inst_sext_rdy or - inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr or - e_first_state or exec_src_wr) - case(e_state) - E_IDLE : e_state_nxt = e_first_state; - E_IRQ_0 : e_state_nxt = E_IRQ_1; - E_IRQ_1 : e_state_nxt = E_IRQ_2; - E_IRQ_2 : e_state_nxt = E_IRQ_3; - E_IRQ_3 : e_state_nxt = E_IRQ_4; - E_IRQ_4 : e_state_nxt = E_EXEC; - - 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 : - dst_rd ? E_DST_RD : E_EXEC; - - E_DST_AD : e_state_nxt = (inst_dext_rdy | - exec_dext_rdy) ? E_DST_RD : E_DST_AD; - - E_DST_RD : e_state_nxt = E_EXEC; - - E_EXEC : e_state_nxt = exec_dst_wr ? E_DST_WR : - exec_jmp ? E_JUMP : - exec_src_wr ? E_SRC_WR : e_first_state; - - E_JUMP : e_state_nxt = e_first_state; - E_DST_WR : e_state_nxt = exec_jmp ? E_JUMP : e_first_state; - E_SRC_WR : e_state_nxt = e_first_state; - // pragma coverage off - default : e_state_nxt = E_IRQ_0; - // pragma coverage on - endcase - -// State machine -always @(posedge mclk or posedge puc_rst) - if (puc_rst) e_state <= E_IRQ_1; - else e_state <= e_state_nxt; - - -// Frontend State machine control signals -//---------------------------------------- - -wire exec_done = exec_jmp ? (e_state==E_JUMP) : - exec_dst_wr ? (e_state==E_DST_WR) : - exec_src_wr ? (e_state==E_SRC_WR) : (e_state==E_EXEC); - - -//============================================================================= -// 8) EXECUTION-UNIT STATE CONTROL -//============================================================================= - -// -// 8.1) ALU CONTROL SIGNALS -//------------------------------------- -// -// 12'b000000000001: Enable ALU source inverter -// 12'b000000000010: Enable Incrementer -// 12'b000000000100: Enable Incrementer on carry bit -// 12'b000000001000: Select Adder -// 12'b000000010000: Select AND -// 12'b000000100000: Select OR -// 12'b000001000000: Select XOR -// 12'b000010000000: Select DADD -// 12'b000100000000: Update N, Z & C (C=~Z) -// 12'b001000000000: Update all status bits -// 12'b010000000000: Update status bit for XOR instruction -// 12'b100000000000: Don't write to destination - -reg [11:0] inst_alu; - -wire alu_src_inv = inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] | - inst_to_nxt[`CMP] | inst_to_nxt[`BIC] ; - -wire alu_inc = inst_to_nxt[`SUB] | inst_to_nxt[`CMP]; - -wire alu_inc_c = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] | - inst_to_nxt[`SUBC]; - -wire alu_add = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] | - inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] | - 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]; - -wire alu_or = inst_to_nxt[`BIS]; - -wire alu_xor = inst_to_nxt[`XOR]; - -wire alu_dadd = inst_to_nxt[`DADD]; - -wire alu_stat_7 = inst_to_nxt[`BIT] | inst_to_nxt[`AND] | - inst_so_nxt[`SXT]; - -wire alu_stat_f = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] | - inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] | - inst_to_nxt[`CMP] | inst_to_nxt[`DADD] | - inst_to_nxt[`BIT] | inst_to_nxt[`XOR] | - inst_to_nxt[`AND] | - inst_so_nxt[`RRC] | inst_so_nxt[`RRA] | - inst_so_nxt[`SXT]; - -wire alu_shift = inst_so_nxt[`RRC] | inst_so_nxt[`RRA]; - -wire exec_no_wr = inst_to_nxt[`CMP] | inst_to_nxt[`BIT]; - -wire [11:0] inst_alu_nxt = {exec_no_wr, - alu_shift, - alu_stat_f, - alu_stat_7, - alu_dadd, - alu_xor, - alu_or, - alu_and, - alu_add, - alu_inc_c, - alu_inc, - alu_src_inv}; - -always @(posedge mclk_decode or posedge puc_rst) - if (puc_rst) inst_alu <= 12'h000; -`ifdef CLOCK_GATING - else inst_alu <= inst_alu_nxt; -`else - else if (decode) inst_alu <= inst_alu_nxt; -`endif - - -endmodule // omsp_frontend - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_mem_backbone.v b/tests/openmsp430/rtl/omsp_mem_backbone.v deleted file mode 100644 index 299cbff8..00000000 --- a/tests/openmsp430/rtl/omsp_mem_backbone.v +++ /dev/null @@ -1,275 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_mem_backbone.v -// -// *Module Description: -// Memory interface backbone (decoder + arbiter) -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 151 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -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) - -// 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) -); - -// 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) - -// 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) - - -//============================================================================= -// 1) DECODER -//============================================================================= - -// RAM Interface -//------------------ - -// Execution unit access -wire eu_dmem_cen = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) & - (eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1))); -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); - - -// 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; - - -// ROM 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 [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 [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); - - -// 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); - - -// 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]; - -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; - - -// Frontend data Mux -//--------------------------------- -// Whenever the frontend doesn't access the ROM, backup the data - -// Detect whenever the data should be backuped and restored -reg fe_pmem_cen_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; - -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; - -`ifdef CLOCK_GATING -wire mclk_bckup; -omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup), - .clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable)); -`else -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; -`ifdef CLOCK_GATING - else pmem_dout_bckup <= pmem_dout; -`else - else if (fe_pmem_save) pmem_dout_bckup <= pmem_dout; -`endif - -// Mux between the ROM 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 -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}; - -// Mux -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; -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}; - -`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; - - -endmodule // omsp_mem_backbone - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_multiplier.v b/tests/openmsp430/rtl/omsp_multiplier.v deleted file mode 100644 index 4f7b04ca..00000000 --- a/tests/openmsp430/rtl/omsp_multiplier.v +++ /dev/null @@ -1,420 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_multiplier.v -// -// *Module Description: -// 16x16 Hardware multiplier. -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 23 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_multiplier ( - -// OUTPUTs - per_dout, // Peripheral data output - -// INPUTs - mclk, // Main system clock - per_addr, // Peripheral address - per_din, // Peripheral data input - per_en, // Peripheral enable (high active) - per_we, // Peripheral write enable (high active) - puc_rst, // Main system reset - scan_enable // Scan enable (active during scan shifting) -); - -// OUTPUTs -//========= -output [15:0] per_dout; // Peripheral data output - -// INPUTs -//========= -input mclk; // Main system clock -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 puc_rst; // Main system reset -input scan_enable; // Scan enable (active during scan shifting) - - -//============================================================================= -// 1) PARAMETER/REGISTERS & WIRE DECLARATION -//============================================================================= - -// Register base address (must be aligned to decoder bit width) -parameter [14:0] BASE_ADDR = 15'h0130; - -// Decoder bit width (defines how many bits are considered for address decoding) -parameter DEC_WD = 4; - -// Register addresses offset -parameter [DEC_WD-1:0] OP1_MPY = 'h0, - OP1_MPYS = 'h2, - OP1_MAC = 'h4, - OP1_MACS = 'h6, - OP2 = 'h8, - RESLO = 'hA, - RESHI = 'hC, - SUMEXT = 'hE; - -// 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}; - -// Register one-hot decoder -parameter [DEC_SZ-1:0] OP1_MPY_D = (BASE_REG << OP1_MPY), - OP1_MPYS_D = (BASE_REG << OP1_MPYS), - OP1_MAC_D = (BASE_REG << OP1_MAC), - OP1_MACS_D = (BASE_REG << OP1_MACS), - OP2_D = (BASE_REG << OP2), - RESLO_D = (BASE_REG << RESLO), - RESHI_D = (BASE_REG << RESHI), - SUMEXT_D = (BASE_REG << SUMEXT); - - -// Wire pre-declarations -wire result_wr; -wire result_clr; -wire early_read; - - -//============================================================================ -// 2) REGISTER DECODER -//============================================================================ - -// Local register selection -wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]); - -// Register local address -wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0}; - -// Register address decode -wire [DEC_SZ-1:0] reg_dec = (OP1_MPY_D & {DEC_SZ{(reg_addr == OP1_MPY )}}) | - (OP1_MPYS_D & {DEC_SZ{(reg_addr == OP1_MPYS )}}) | - (OP1_MAC_D & {DEC_SZ{(reg_addr == OP1_MAC )}}) | - (OP1_MACS_D & {DEC_SZ{(reg_addr == OP1_MACS )}}) | - (OP2_D & {DEC_SZ{(reg_addr == OP2 )}}) | - (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; - -// Read/Write vectors -wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}}; -wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}}; - - -//============================================================================ -// 3) REGISTERS -//============================================================================ - -// OP1 Register -//----------------- -reg [15:0] op1; - -wire op1_wr = reg_wr[OP1_MPY] | - reg_wr[OP1_MPYS] | - reg_wr[OP1_MAC] | - reg_wr[OP1_MACS]; - -`ifdef CLOCK_GATING -wire mclk_op1; -omsp_clock_gate clock_gate_op1 (.gclk(mclk_op1), - .clk (mclk), .enable(op1_wr), .scan_enable(scan_enable)); -`else -wire mclk_op1 = mclk; -`endif - -always @ (posedge mclk_op1 or posedge puc_rst) - if (puc_rst) op1 <= 16'h0000; -`ifdef CLOCK_GATING - else op1 <= per_din; -`else - else if (op1_wr) op1 <= per_din; -`endif - -wire [15:0] op1_rd = op1; - - -// OP2 Register -//----------------- -reg [15:0] op2; - -wire op2_wr = reg_wr[OP2]; - -`ifdef CLOCK_GATING -wire mclk_op2; -omsp_clock_gate clock_gate_op2 (.gclk(mclk_op2), - .clk (mclk), .enable(op2_wr), .scan_enable(scan_enable)); -`else -wire mclk_op2 = mclk; -`endif - -always @ (posedge mclk_op2 or posedge puc_rst) - if (puc_rst) op2 <= 16'h0000; -`ifdef CLOCK_GATING - else op2 <= per_din; -`else - else if (op2_wr) op2 <= per_din; -`endif - -wire [15:0] op2_rd = op2; - - -// RESLO Register -//----------------- -reg [15:0] reslo; - -wire [15:0] reslo_nxt; -wire reslo_wr = reg_wr[RESLO]; - -`ifdef CLOCK_GATING -wire reslo_en = reslo_wr | result_clr | result_wr; -wire mclk_reslo; -omsp_clock_gate clock_gate_reslo (.gclk(mclk_reslo), - .clk (mclk), .enable(reslo_en), .scan_enable(scan_enable)); -`else -wire mclk_reslo = mclk; -`endif - -always @ (posedge mclk_reslo or posedge puc_rst) - if (puc_rst) reslo <= 16'h0000; - else if (reslo_wr) reslo <= per_din; - else if (result_clr) reslo <= 16'h0000; -`ifdef CLOCK_GATING - else reslo <= reslo_nxt; -`else - else if (result_wr) reslo <= reslo_nxt; -`endif - -wire [15:0] reslo_rd = early_read ? reslo_nxt : reslo; - - -// RESHI Register -//----------------- -reg [15:0] reshi; - -wire [15:0] reshi_nxt; -wire reshi_wr = reg_wr[RESHI]; - -`ifdef CLOCK_GATING -wire reshi_en = reshi_wr | result_clr | result_wr; -wire mclk_reshi; -omsp_clock_gate clock_gate_reshi (.gclk(mclk_reshi), - .clk (mclk), .enable(reshi_en), .scan_enable(scan_enable)); -`else -wire mclk_reshi = mclk; -`endif - -always @ (posedge mclk_reshi or posedge puc_rst) - if (puc_rst) reshi <= 16'h0000; - else if (reshi_wr) reshi <= per_din; - else if (result_clr) reshi <= 16'h0000; -`ifdef CLOCK_GATING - else reshi <= reshi_nxt; -`else - else if (result_wr) reshi <= reshi_nxt; -`endif - -wire [15:0] reshi_rd = early_read ? reshi_nxt : reshi; - - -// SUMEXT Register -//----------------- -reg [1:0] sumext_s; - -wire [1:0] sumext_s_nxt; - -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) sumext_s <= 2'b00; - else if (op2_wr) sumext_s <= 2'b00; - else if (result_wr) sumext_s <= sumext_s_nxt; - -wire [15:0] sumext_nxt = {{14{sumext_s_nxt[1]}}, sumext_s_nxt}; -wire [15:0] sumext = {{14{sumext_s[1]}}, sumext_s}; -wire [15:0] sumext_rd = early_read ? sumext_nxt : sumext; - - -//============================================================================ -// 4) DATA OUTPUT GENERATION -//============================================================================ - -// Data output mux -wire [15:0] op1_mux = op1_rd & {16{reg_rd[OP1_MPY] | - reg_rd[OP1_MPYS] | - reg_rd[OP1_MAC] | - reg_rd[OP1_MACS]}}; -wire [15:0] op2_mux = op2_rd & {16{reg_rd[OP2]}}; -wire [15:0] reslo_mux = reslo_rd & {16{reg_rd[RESLO]}}; -wire [15:0] reshi_mux = reshi_rd & {16{reg_rd[RESHI]}}; -wire [15:0] sumext_mux = sumext_rd & {16{reg_rd[SUMEXT]}}; - -wire [15:0] per_dout = op1_mux | - op2_mux | - reslo_mux | - reshi_mux | - sumext_mux; - - -//============================================================================ -// 5) HARDWARE MULTIPLIER FUNCTIONAL LOGIC -//============================================================================ - -// Multiplier configuration -//-------------------------- - -// Detect signed mode -reg sign_sel; -always @ (posedge mclk_op1 or posedge puc_rst) - if (puc_rst) sign_sel <= 1'b0; -`ifdef CLOCK_GATING - else sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS]; -`else - else if (op1_wr) sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS]; -`endif - - -// Detect accumulate mode -reg acc_sel; -always @ (posedge mclk_op1 or posedge puc_rst) - if (puc_rst) acc_sel <= 1'b0; -`ifdef CLOCK_GATING - else acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS]; -`else - else if (op1_wr) acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS]; -`endif - - -// Detect whenever the RESHI and RESLO registers should be cleared -assign result_clr = op2_wr & ~acc_sel; - -// Combine RESHI & RESLO -wire [31:0] result = {reshi, reslo}; - - -// 16x16 Multiplier (result computed in 1 clock cycle) -//----------------------------------------------------- -`ifdef MPY_16x16 - -// Detect start of a multiplication -reg cycle; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) cycle <= 1'b0; - else cycle <= op2_wr; - -assign result_wr = cycle; - -// Expand the operands to support signed & unsigned operations -wire signed [16:0] op1_xp = {sign_sel & op1[15], op1}; -wire signed [16:0] op2_xp = {sign_sel & op2[15], op2}; - - -// 17x17 signed multiplication -wire signed [33:0] product = op1_xp * op2_xp; - -// Accumulate -wire [32:0] result_nxt = {1'b0, result} + {1'b0, product[31:0]}; - - -// Next register values -assign reslo_nxt = result_nxt[15:0]; -assign reshi_nxt = result_nxt[31:16]; -assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} : - {1'b0, result_nxt[32]}; - - -// Since the MAC is completed within 1 clock cycle, -// an early read can't happen. -assign early_read = 1'b0; - - -// 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) - if (puc_rst) cycle <= 2'b00; - else cycle <= {cycle[0], op2_wr}; - -assign result_wr = |cycle; - - -// Expand the operands to support signed & unsigned operations -wire signed [16:0] op1_xp = {sign_sel & op1[15], op1}; -wire signed [8:0] op2_hi_xp = {sign_sel & op2[15], op2[15:8]}; -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]}; - - -// Next register values -assign reslo_nxt = result_nxt[15:0]; -assign reshi_nxt = result_nxt[31:16]; -assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} : - {1'b0, result_nxt[32] | sumext_s[0]}; - -// Since the MAC is completed within 2 clock cycle, -// an early read can happen during the second cycle. -assign early_read = cycle[1]; - -`endif - - -endmodule // omsp_multiplier - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_register_file.v b/tests/openmsp430/rtl/omsp_register_file.v deleted file mode 100644 index 2ccd2499..00000000 --- a/tests/openmsp430/rtl/omsp_register_file.v +++ /dev/null @@ -1,618 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_register_file.v -// -// *Module Description: -// openMSP430 Register files -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_register_file ( - -// OUTPUTs - cpuoff, // Turns off the CPU - gie, // General interrupt enable - oscoff, // Turns off LFXT1 clock input - pc_sw, // Program counter software value - pc_sw_wr, // Program counter software write - reg_dest, // Selected register destination content - reg_src, // Selected register source content - scg0, // System clock generator 1. Turns off the DCO - scg1, // System clock generator 1. Turns off the SMCLK - status, // R2 Status {V,N,Z,C} - -// INPUTs - alu_stat, // ALU Status {V,N,Z,C} - alu_stat_wr, // ALU Status write {V,N,Z,C} - inst_bw, // Decoded Inst: byte width - inst_dest, // Register destination selection - inst_src, // Register source selection - mclk, // Main system clock - pc, // Program counter - puc_rst, // Main system reset - reg_dest_val, // Selected register destination value - reg_dest_wr, // Write selected register destination - reg_pc_call, // Trigger PC update for a CALL instruction - reg_sp_val, // Stack Pointer next value - reg_sp_wr, // Stack Pointer write - reg_sr_wr, // Status register update for RETI instruction - reg_sr_clr, // Status register clear for interrupts - reg_incr, // Increment source register - scan_enable // Scan enable (active during scan shifting) -); - -// OUTPUTs -//========= -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 -output [15:0] reg_src; // Selected register source content -output scg0; // System clock generator 1. Turns off the DCO -output scg1; // System clock generator 1. Turns off the SMCLK -output [3:0] status; // R2 Status {V,N,Z,C} - -// INPUTs -//========= -input [3:0] alu_stat; // ALU Status {V,N,Z,C} -input [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C} -input inst_bw; // Decoded Inst: byte width -input [15:0] inst_dest; // Register destination selection -input [15:0] inst_src; // Register source selection -input mclk; // Main system clock -input [15:0] pc; // Program counter -input puc_rst; // Main system reset -input [15:0] reg_dest_val; // Selected register destination value -input reg_dest_wr; // Write selected register destination -input reg_pc_call; // Trigger PC update for a CALL instruction -input [15:0] reg_sp_val; // Stack Pointer next value -input reg_sp_wr; // Stack Pointer write -input reg_sr_wr; // Status register update for RETI instruction -input reg_sr_clr; // Status register clear for interrupts -input reg_incr; // Increment source register -input scan_enable; // Scan enable (active during scan shifting) - - -//============================================================================= -// 1) AUTOINCREMENT UNIT -//============================================================================= - -wire [15:0] inst_src_in; -wire [15:0] incr_op = (inst_bw & ~inst_src_in[1]) ? 16'h0001 : 16'h0002; -wire [15:0] reg_incr_val = reg_src+incr_op; - -wire [15:0] reg_dest_val_in = inst_bw ? {8'h00,reg_dest_val[7:0]} : reg_dest_val; - - -//============================================================================= -// 2) SPECIAL REGISTERS (R1/R2/R3) -//============================================================================= - -// Source input selection mask (for interrupt support) -//----------------------------------------------------- - -assign inst_src_in = reg_sr_clr ? 16'h0004 : inst_src; - - -// R0: Program counter -//--------------------- - -wire [15:0] r0 = pc; - -wire [15:0] pc_sw = reg_dest_val_in; -wire pc_sw_wr = (inst_dest[0] & reg_dest_wr) | reg_pc_call; - - -// R1: Stack pointer -//------------------- -reg [15:0] r1; -wire r1_wr = inst_dest[1] & reg_dest_wr; -wire r1_inc = inst_src_in[1] & reg_incr; - -`ifdef CLOCK_GATING -wire r1_en = r1_wr | reg_sp_wr | r1_inc; -wire mclk_r1; -omsp_clock_gate clock_gate_r1 (.gclk(mclk_r1), - .clk (mclk), .enable(r1_en), .scan_enable(scan_enable)); -`else -wire mclk_r1 = mclk; -`endif - -always @(posedge mclk_r1 or posedge puc_rst) - if (puc_rst) r1 <= 16'h0000; - else if (r1_wr) r1 <= reg_dest_val_in & 16'hfffe; - else if (reg_sp_wr) r1 <= reg_sp_val & 16'hfffe; -`ifdef CLOCK_GATING - else r1 <= reg_incr_val & 16'hfffe; -`else - else if (r1_inc) r1 <= reg_incr_val & 16'hfffe; -`endif - - -// R2: Status register -//--------------------- -reg [15:0] r2; -wire r2_wr = (inst_dest[2] & reg_dest_wr) | reg_sr_wr; - -`ifdef CLOCK_GATING // -- WITH CLOCK GATING -- -wire r2_c = alu_stat_wr[0] ? alu_stat[0] : reg_dest_val_in[0]; // C - -wire r2_z = alu_stat_wr[1] ? alu_stat[1] : reg_dest_val_in[1]; // Z - -wire r2_n = alu_stat_wr[2] ? alu_stat[2] : reg_dest_val_in[2]; // N - -wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3]; - -wire r2_v = alu_stat_wr[3] ? alu_stat[3] : reg_dest_val_in[8]; // V - -wire r2_en = |alu_stat_wr | r2_wr | reg_sr_clr; -wire mclk_r2; -omsp_clock_gate clock_gate_r2 (.gclk(mclk_r2), - .clk (mclk), .enable(r2_en), .scan_enable(scan_enable)); - -`else // -- WITHOUT CLOCK GATING -- -wire r2_c = alu_stat_wr[0] ? alu_stat[0] : - r2_wr ? reg_dest_val_in[0] : r2[0]; // C - -wire r2_z = alu_stat_wr[1] ? alu_stat[1] : - r2_wr ? reg_dest_val_in[1] : r2[1]; // Z - -wire r2_n = alu_stat_wr[2] ? alu_stat[2] : - r2_wr ? reg_dest_val_in[2] : r2[2]; // N - -wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3]; - -wire r2_v = alu_stat_wr[3] ? alu_stat[3] : - r2_wr ? reg_dest_val_in[8] : r2[8]; // V - - -wire mclk_r2 = mclk; -`endif - -`ifdef ASIC - `ifdef CPUOFF_EN - wire [15:0] cpuoff_mask = 16'h0010; - `else - wire [15:0] cpuoff_mask = 16'h0000; - `endif - `ifdef OSCOFF_EN - wire [15:0] oscoff_mask = 16'h0020; - `else - wire [15:0] oscoff_mask = 16'h0000; - `endif - `ifdef SCG0_EN - wire [15:0] scg0_mask = 16'h0040; - `else - wire [15:0] scg0_mask = 16'h0000; - `endif - `ifdef SCG1_EN - wire [15:0] scg1_mask = 16'h0080; - `else - wire [15:0] scg1_mask = 16'h0000; - `endif -`else - wire [15:0] cpuoff_mask = 16'h0010; // For the FPGA version: - the CPUOFF mode is emulated - wire [15:0] oscoff_mask = 16'h0020; // - the SCG1 mode is emulated - 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; - else r2 <= {7'h00, r2_v, r2_nxt, r2_n, r2_z, r2_c} & r2_mask; - -assign status = {r2[8], r2[2:0]}; -assign gie = r2[3]; -assign cpuoff = r2[4] | (r2_nxt[4] & r2_wr & cpuoff_mask[4]); -assign oscoff = r2[5]; -assign scg0 = r2[6]; -assign scg1 = r2[7]; - - -// R3: Constant generator -//------------------------------------------------------------- -// Note: the auto-increment feature is not implemented for R3 -// because the @R3+ addressing mode is used for constant -// generation (#-1). -reg [15:0] r3; -wire r3_wr = inst_dest[3] & reg_dest_wr; - -`ifdef CLOCK_GATING -wire r3_en = r3_wr; -wire mclk_r3; -omsp_clock_gate clock_gate_r3 (.gclk(mclk_r3), - .clk (mclk), .enable(r3_en), .scan_enable(scan_enable)); -`else -wire mclk_r3 = mclk; -`endif - -always @(posedge mclk_r3 or posedge puc_rst) - if (puc_rst) r3 <= 16'h0000; -`ifdef CLOCK_GATING - else r3 <= reg_dest_val_in; -`else - else if (r3_wr) r3 <= reg_dest_val_in; -`endif - - -//============================================================================= -// 4) GENERAL PURPOSE REGISTERS (R4...R15) -//============================================================================= - -// R4 -//------------ -reg [15:0] r4; -wire r4_wr = inst_dest[4] & reg_dest_wr; -wire r4_inc = inst_src_in[4] & reg_incr; - -`ifdef CLOCK_GATING -wire r4_en = r4_wr | r4_inc; -wire mclk_r4; -omsp_clock_gate clock_gate_r4 (.gclk(mclk_r4), - .clk (mclk), .enable(r4_en), .scan_enable(scan_enable)); -`else -wire mclk_r4 = mclk; -`endif - -always @(posedge mclk_r4 or posedge puc_rst) - if (puc_rst) r4 <= 16'h0000; - else if (r4_wr) r4 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r4 <= reg_incr_val; -`else - else if (r4_inc) r4 <= reg_incr_val; -`endif - -// R5 -//------------ -reg [15:0] r5; -wire r5_wr = inst_dest[5] & reg_dest_wr; -wire r5_inc = inst_src_in[5] & reg_incr; - -`ifdef CLOCK_GATING -wire r5_en = r5_wr | r5_inc; -wire mclk_r5; -omsp_clock_gate clock_gate_r5 (.gclk(mclk_r5), - .clk (mclk), .enable(r5_en), .scan_enable(scan_enable)); -`else -wire mclk_r5 = mclk; -`endif - -always @(posedge mclk_r5 or posedge puc_rst) - if (puc_rst) r5 <= 16'h0000; - else if (r5_wr) r5 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r5 <= reg_incr_val; -`else - else if (r5_inc) r5 <= reg_incr_val; -`endif - -// R6 -//------------ -reg [15:0] r6; -wire r6_wr = inst_dest[6] & reg_dest_wr; -wire r6_inc = inst_src_in[6] & reg_incr; - -`ifdef CLOCK_GATING -wire r6_en = r6_wr | r6_inc; -wire mclk_r6; -omsp_clock_gate clock_gate_r6 (.gclk(mclk_r6), - .clk (mclk), .enable(r6_en), .scan_enable(scan_enable)); -`else -wire mclk_r6 = mclk; -`endif - -always @(posedge mclk_r6 or posedge puc_rst) - if (puc_rst) r6 <= 16'h0000; - else if (r6_wr) r6 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r6 <= reg_incr_val; -`else - else if (r6_inc) r6 <= reg_incr_val; -`endif - -// R7 -//------------ -reg [15:0] r7; -wire r7_wr = inst_dest[7] & reg_dest_wr; -wire r7_inc = inst_src_in[7] & reg_incr; - -`ifdef CLOCK_GATING -wire r7_en = r7_wr | r7_inc; -wire mclk_r7; -omsp_clock_gate clock_gate_r7 (.gclk(mclk_r7), - .clk (mclk), .enable(r7_en), .scan_enable(scan_enable)); -`else -wire mclk_r7 = mclk; -`endif - -always @(posedge mclk_r7 or posedge puc_rst) - if (puc_rst) r7 <= 16'h0000; - else if (r7_wr) r7 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r7 <= reg_incr_val; -`else - else if (r7_inc) r7 <= reg_incr_val; -`endif - -// R8 -//------------ -reg [15:0] r8; -wire r8_wr = inst_dest[8] & reg_dest_wr; -wire r8_inc = inst_src_in[8] & reg_incr; - -`ifdef CLOCK_GATING -wire r8_en = r8_wr | r8_inc; -wire mclk_r8; -omsp_clock_gate clock_gate_r8 (.gclk(mclk_r8), - .clk (mclk), .enable(r8_en), .scan_enable(scan_enable)); -`else -wire mclk_r8 = mclk; -`endif - -always @(posedge mclk_r8 or posedge puc_rst) - if (puc_rst) r8 <= 16'h0000; - else if (r8_wr) r8 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r8 <= reg_incr_val; -`else - else if (r8_inc) r8 <= reg_incr_val; -`endif - -// R9 -//------------ -reg [15:0] r9; -wire r9_wr = inst_dest[9] & reg_dest_wr; -wire r9_inc = inst_src_in[9] & reg_incr; - -`ifdef CLOCK_GATING -wire r9_en = r9_wr | r9_inc; -wire mclk_r9; -omsp_clock_gate clock_gate_r9 (.gclk(mclk_r9), - .clk (mclk), .enable(r9_en), .scan_enable(scan_enable)); -`else -wire mclk_r9 = mclk; -`endif - -always @(posedge mclk_r9 or posedge puc_rst) - if (puc_rst) r9 <= 16'h0000; - else if (r9_wr) r9 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r9 <= reg_incr_val; -`else - else if (r9_inc) r9 <= reg_incr_val; -`endif - -// R10 -//------------ -reg [15:0] r10; -wire r10_wr = inst_dest[10] & reg_dest_wr; -wire r10_inc = inst_src_in[10] & reg_incr; - -`ifdef CLOCK_GATING -wire r10_en = r10_wr | r10_inc; -wire mclk_r10; -omsp_clock_gate clock_gate_r10 (.gclk(mclk_r10), - .clk (mclk), .enable(r10_en), .scan_enable(scan_enable)); -`else -wire mclk_r10 = mclk; -`endif - -always @(posedge mclk_r10 or posedge puc_rst) - if (puc_rst) r10 <= 16'h0000; - else if (r10_wr) r10 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r10 <= reg_incr_val; -`else - else if (r10_inc) r10 <= reg_incr_val; -`endif - -// R11 -//------------ -reg [15:0] r11; -wire r11_wr = inst_dest[11] & reg_dest_wr; -wire r11_inc = inst_src_in[11] & reg_incr; - -`ifdef CLOCK_GATING -wire r11_en = r11_wr | r11_inc; -wire mclk_r11; -omsp_clock_gate clock_gate_r11 (.gclk(mclk_r11), - .clk (mclk), .enable(r11_en), .scan_enable(scan_enable)); -`else -wire mclk_r11 = mclk; -`endif - -always @(posedge mclk_r11 or posedge puc_rst) - if (puc_rst) r11 <= 16'h0000; - else if (r11_wr) r11 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r11 <= reg_incr_val; -`else - else if (r11_inc) r11 <= reg_incr_val; -`endif - -// R12 -//------------ -reg [15:0] r12; -wire r12_wr = inst_dest[12] & reg_dest_wr; -wire r12_inc = inst_src_in[12] & reg_incr; - -`ifdef CLOCK_GATING -wire r12_en = r12_wr | r12_inc; -wire mclk_r12; -omsp_clock_gate clock_gate_r12 (.gclk(mclk_r12), - .clk (mclk), .enable(r12_en), .scan_enable(scan_enable)); -`else -wire mclk_r12 = mclk; -`endif - -always @(posedge mclk_r12 or posedge puc_rst) - if (puc_rst) r12 <= 16'h0000; - else if (r12_wr) r12 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r12 <= reg_incr_val; -`else - else if (r12_inc) r12 <= reg_incr_val; -`endif - -// R13 -//------------ -reg [15:0] r13; -wire r13_wr = inst_dest[13] & reg_dest_wr; -wire r13_inc = inst_src_in[13] & reg_incr; - -`ifdef CLOCK_GATING -wire r13_en = r13_wr | r13_inc; -wire mclk_r13; -omsp_clock_gate clock_gate_r13 (.gclk(mclk_r13), - .clk (mclk), .enable(r13_en), .scan_enable(scan_enable)); -`else -wire mclk_r13 = mclk; -`endif - -always @(posedge mclk_r13 or posedge puc_rst) - if (puc_rst) r13 <= 16'h0000; - else if (r13_wr) r13 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r13 <= reg_incr_val; -`else - else if (r13_inc) r13 <= reg_incr_val; -`endif - -// R14 -//------------ -reg [15:0] r14; -wire r14_wr = inst_dest[14] & reg_dest_wr; -wire r14_inc = inst_src_in[14] & reg_incr; - -`ifdef CLOCK_GATING -wire r14_en = r14_wr | r14_inc; -wire mclk_r14; -omsp_clock_gate clock_gate_r14 (.gclk(mclk_r14), - .clk (mclk), .enable(r14_en), .scan_enable(scan_enable)); -`else -wire mclk_r14 = mclk; -`endif - -always @(posedge mclk_r14 or posedge puc_rst) - if (puc_rst) r14 <= 16'h0000; - else if (r14_wr) r14 <= reg_dest_val_in; -`ifdef CLOCK_GATING - else r14 <= reg_incr_val; -`else - else if (r14_inc) r14 <= reg_incr_val; -`endif - -// R15 -//------------ -reg [15:0] r15; -wire r15_wr = inst_dest[15] & reg_dest_wr; -wire r15_inc = inst_src_in[15] & reg_incr; - -`ifdef CLOCK_GATING -wire r15_en = r15_wr | r15_inc; -wire mclk_r15; -omsp_clock_gate clock_gate_r15 (.gclk(mclk_r15), - .clk (mclk), .enable(r15_en), .scan_enable(scan_enable)); -`else -wire mclk_r15 = mclk; -`endif - -always @(posedge mclk_r15 or posedge puc_rst) - if (puc_rst) r15 <= 16'h0000; - else if (r15_wr) r15 <= reg_dest_val_in; - `ifdef CLOCK_GATING - else r15 <= reg_incr_val; -`else - else if (r15_inc) r15 <= reg_incr_val; -`endif - - -//============================================================================= -// 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]}}) | - (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]}}) | - (r15 & {16{inst_dest[15]}}); - - -endmodule // omsp_register_file - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_scan_mux.v b/tests/openmsp430/rtl/omsp_scan_mux.v deleted file mode 100644 index 9a906474..00000000 --- a/tests/openmsp430/rtl/omsp_scan_mux.v +++ /dev/null @@ -1,75 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_scan_mux.v -// -// *Module Description: -// Generic mux for scan mode -// -// *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 omsp_scan_mux ( - -// OUTPUTs - data_out, // Scan mux data output - -// INPUTs - data_in_scan, // Selected data input for scan mode - data_in_func, // Selected data input for functional mode - scan_mode // Scan mode -); - -// OUTPUTs -//========= -output data_out; // Scan mux data output - -// INPUTs -//========= -input data_in_scan; // Selected data input for scan mode -input data_in_func; // Selected data input for functional mode -input scan_mode; // Scan mode - - -//============================================================================= -// 1) SCAN MUX -//============================================================================= - -assign data_out = scan_mode ? data_in_scan : data_in_func; - - -endmodule // omsp_scan_mux - - diff --git a/tests/openmsp430/rtl/omsp_sfr.v b/tests/openmsp430/rtl/omsp_sfr.v deleted file mode 100644 index bc8c11a5..00000000 --- a/tests/openmsp430/rtl/omsp_sfr.v +++ /dev/null @@ -1,353 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_sfr.v -// -// *Module Description: -// Processor Special function register -// Non-Maskable Interrupt generation -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_sfr ( - -// OUTPUTs - cpu_id, // CPU ID - nmi_pnd, // NMI Pending - nmi_wkup, // NMI Wakeup - per_dout, // Peripheral data output - wdtie, // Watchdog-timer interrupt enable - wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear - wdtifg_sw_set, // Watchdog-timer interrupt flag software set - -// INPUTs - mclk, // Main system clock - nmi, // Non-maskable interrupt (asynchronous) - nmi_acc, // Non-Maskable interrupt request accepted - per_addr, // Peripheral address - per_din, // Peripheral data input - per_en, // Peripheral enable (high active) - per_we, // Peripheral write enable (high active) - puc_rst, // Main system reset - scan_mode, // Scan mode - wdtifg, // Watchdog-timer interrupt flag - wdtnmies // Watchdog-timer NMI edge selection -); - -// OUTPUTs -//========= -output [31:0] cpu_id; // CPU ID -output nmi_pnd; // NMI Pending -output nmi_wkup; // NMI Wakeup -output [15:0] per_dout; // Peripheral data output -output wdtie; // Watchdog-timer interrupt enable -output wdtifg_sw_clr;// Watchdog-timer interrupt flag software clear -output wdtifg_sw_set;// Watchdog-timer interrupt flag software set - -// INPUTs -//========= -input mclk; // Main system clock -input nmi; // Non-maskable interrupt (asynchronous) -input nmi_acc; // Non-Maskable interrupt request accepted -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 puc_rst; // Main system reset -input scan_mode; // Scan mode -input wdtifg; // Watchdog-timer interrupt flag -input wdtnmies; // Watchdog-timer NMI edge selection - - -//============================================================================= -// 1) PARAMETER DECLARATION -//============================================================================= - -// Register base address (must be aligned to decoder bit width) -parameter [14:0] BASE_ADDR = 15'h0000; - -// Decoder bit width (defines how many bits are considered for address decoding) -parameter DEC_WD = 3; - -// Register addresses offset -parameter [DEC_WD-1:0] IE1 = 'h0, - IFG1 = 'h2, - CPU_ID_LO = 'h4, - CPU_ID_HI = 'h6; - -// 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}; - -// Register one-hot decoder -parameter [DEC_SZ-1:0] IE1_D = (BASE_REG << IE1), - IFG1_D = (BASE_REG << IFG1), - CPU_ID_LO_D = (BASE_REG << CPU_ID_LO), - CPU_ID_HI_D = (BASE_REG << CPU_ID_HI); - - -//============================================================================ -// 2) REGISTER DECODER -//============================================================================ - -// Local register selection -wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]); - -// Register local address -wire [DEC_WD-1:0] reg_addr = {1'b0, per_addr[DEC_WD-2:0]}; - -// Register address decode -wire [DEC_SZ-1:0] reg_dec = (IE1_D & {DEC_SZ{(reg_addr==(IE1 >>1))}}) | - (IFG1_D & {DEC_SZ{(reg_addr==(IFG1 >>1))}}) | - (CPU_ID_LO_D & {DEC_SZ{(reg_addr==(CPU_ID_LO >>1))}}) | - (CPU_ID_HI_D & {DEC_SZ{(reg_addr==(CPU_ID_HI >>1))}}); - -// Read/Write probes -wire reg_lo_write = per_we[0] & reg_sel; -wire reg_hi_write = per_we[1] & reg_sel; -wire reg_read = ~|per_we & reg_sel; - -// Read/Write vectors -wire [DEC_SZ-1:0] reg_hi_wr = reg_dec & {DEC_SZ{reg_hi_write}}; -wire [DEC_SZ-1:0] reg_lo_wr = reg_dec & {DEC_SZ{reg_lo_write}}; -wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}}; - - -//============================================================================ -// 3) REGISTERS -//============================================================================ - -// IE1 Register -//-------------- -wire [7:0] ie1; -wire ie1_wr = IE1[0] ? reg_hi_wr[IE1] : reg_lo_wr[IE1]; -wire [7:0] ie1_nxt = IE1[0] ? per_din[15:8] : per_din[7:0]; - -`ifdef NMI -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 -wire nmie = 1'b0; -`endif - -`ifdef WATCHDOG -reg wdtie; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdtie <= 1'b0; - else if (ie1_wr) wdtie <= ie1_nxt[0]; -`else -wire wdtie = 1'b0; -`endif - -assign ie1 = {3'b000, nmie, 3'b000, wdtie}; - - -// IFG1 Register -//--------------- -wire [7:0] ifg1; - -wire ifg1_wr = IFG1[0] ? reg_hi_wr[IFG1] : reg_lo_wr[IFG1]; -wire [7:0] ifg1_nxt = IFG1[0] ? per_din[15:8] : per_din[7:0]; - -`ifdef NMI -reg nmiifg; -wire nmi_edge; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) nmiifg <= 1'b0; - else if (nmi_edge) nmiifg <= 1'b1; - else if (ifg1_wr) nmiifg <= ifg1_nxt[4]; -`else -wire nmiifg = 1'b0; -`endif - -`ifdef WATCHDOG -assign wdtifg_sw_clr = ifg1_wr & ~ifg1_nxt[0]; -assign wdtifg_sw_set = ifg1_wr & ifg1_nxt[0]; -`else -assign wdtifg_sw_clr = 1'b0; -assign wdtifg_sw_set = 1'b0; -`endif - -assign ifg1 = {3'b000, nmiifg, 3'b000, wdtifg}; - - -// CPU_ID Register (READ ONLY) -//----------------------------- -// ------------------------------------------------------------------- -// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 | -// |----------------------------+-----------------+------+-------------| -// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION | -// -------------------------------------------------------------------- -// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 | -// |----------------------------+-------------------------------+------| -// | PMEM_SIZE | DMEM_SIZE | MPY | -// ------------------------------------------------------------------- - -wire [2:0] cpu_version = `CPU_VERSION; -`ifdef ASIC -wire cpu_asic = 1'b1; -`else -wire cpu_asic = 1'b0; -`endif -wire [4:0] user_version = `USER_VERSION; -wire [6:0] per_space = (`PER_SIZE >> 9); // cpu_id_per * 512 = peripheral space size -`ifdef MULTIPLIER -wire mpy_info = 1'b1; -`else -wire mpy_info = 1'b0; -`endif -wire [8:0] dmem_size = (`DMEM_SIZE >> 7); // cpu_id_dmem * 128 = data memory size -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, - cpu_version}; - - -//============================================================================ -// 4) DATA OUTPUT GENERATION -//============================================================================ - -// Data output mux -wire [15:0] ie1_rd = {8'h00, (ie1 & {8{reg_rd[IE1]}})} << (8 & {4{IE1[0]}}); -wire [15:0] ifg1_rd = {8'h00, (ifg1 & {8{reg_rd[IFG1]}})} << (8 & {4{IFG1[0]}}); -wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}}; -wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}}; - -wire [15:0] per_dout = ie1_rd | - ifg1_rd | - cpu_id_lo_rd | - cpu_id_hi_rd; - - -//============================================================================= -// 5) NMI GENERATION -//============================================================================= -// NOTE THAT THE NMI INPUT IS ASSUMED TO BE NON-GLITCHY -`ifdef NMI - -//----------------------------------- -// Edge selection -//----------------------------------- -wire nmi_pol = nmi ^ wdtnmies; - -//----------------------------------- -// Pulse capture and synchronization -//----------------------------------- -`ifdef SYNC_NMI - `ifdef ASIC - // Glitch free reset for the event capture - reg nmi_capture_rst; - 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 - ); - `else - wire nmi_capture = nmi_pol; - `endif - - // Synchronization - wire nmi_s; - omsp_sync_cell sync_cell_nmi ( - .data_out (nmi_s), - .data_in (nmi_capture), - .clk (mclk), - .rst (puc_rst) - ); - -`else - wire nmi_capture = nmi_pol; - wire nmi_s = nmi_pol; -`endif - -//----------------------------------- -// NMI Pending flag -//----------------------------------- - -// Delay -reg nmi_dly; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) nmi_dly <= 1'b0; - else nmi_dly <= nmi_s; - -// Edge detection -assign nmi_edge = ~nmi_dly & nmi_s; - -// NMI pending -wire nmi_pnd = nmiifg & nmie; - -// NMI wakeup -`ifdef ASIC -wire nmi_wkup; -omsp_and_gate and_nmi_wkup (.y(nmi_wkup), .a(nmi_capture ^ nmi_dly), .b(nmie)); -`else -wire nmi_wkup = 1'b0; -`endif - -`else - -wire nmi_pnd = 1'b0; -wire nmi_wkup = 1'b0; - -`endif - -endmodule // omsp_sfr - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/omsp_sync_cell.v b/tests/openmsp430/rtl/omsp_sync_cell.v deleted file mode 100644 index ece0682a..00000000 --- a/tests/openmsp430/rtl/omsp_sync_cell.v +++ /dev/null @@ -1,80 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_sync_cell.v -// -// *Module Description: -// Generic synchronizer for the openMSP430 -// -// *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 omsp_sync_cell ( - -// OUTPUTs - data_out, // Synchronized data output - -// INPUTs - clk, // Receiving clock - data_in, // Asynchronous data input - rst // Receiving reset (active high) -); - -// OUTPUTs -//========= -output data_out; // Synchronized data output - -// INPUTs -//========= -input clk; // Receiving clock -input data_in; // Asynchronous data input -input rst; // Receiving reset (active high) - - -//============================================================================= -// 1) SYNCHRONIZER -//============================================================================= - -reg [1:0] data_sync; - -always @(posedge clk or posedge rst) - if (rst) data_sync <= 2'b00; - else data_sync <= {data_sync[0], data_in}; - -assign data_out = data_sync[1]; - - -endmodule // omsp_sync_cell - diff --git a/tests/openmsp430/rtl/omsp_sync_reset.v b/tests/openmsp430/rtl/omsp_sync_reset.v deleted file mode 100644 index 15a158b4..00000000 --- a/tests/openmsp430/rtl/omsp_sync_reset.v +++ /dev/null @@ -1,78 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_sync_reset.v -// -// *Module Description: -// Generic reset synchronizer for the openMSP430 -// -// *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 omsp_sync_reset ( - -// OUTPUTs - rst_s, // Synchronized reset - -// INPUTs - clk, // Receiving clock - rst_a // Asynchronous reset -); - -// OUTPUTs -//========= -output rst_s; // Synchronized reset - -// INPUTs -//========= -input clk; // Receiving clock -input rst_a; // Asynchronous reset - - -//============================================================================= -// 1) SYNCHRONIZER -//============================================================================= - -reg [1:0] data_sync; - -always @(posedge clk or posedge rst_a) - if (rst_a) data_sync <= 2'b11; - else data_sync <= {data_sync[0], 1'b0}; - -assign rst_s = data_sync[1]; - - -endmodule // omsp_sync_reset - diff --git a/tests/openmsp430/rtl/omsp_wakeup_cell.v b/tests/openmsp430/rtl/omsp_wakeup_cell.v deleted file mode 100644 index 6e5fcd88..00000000 --- a/tests/openmsp430/rtl/omsp_wakeup_cell.v +++ /dev/null @@ -1,108 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_wakeup_cell.v -// -// *Module Description: -// Generic Wakeup cell -// -// *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 omsp_wakeup_cell ( - -// OUTPUTs - wkup_out, // Wakup signal (asynchronous) - -// INPUTs - scan_clk, // Scan clock - scan_mode, // Scan mode - scan_rst, // Scan reset - wkup_clear, // Glitch free wakeup event clear - wkup_event // Glitch free asynchronous wakeup event -); - -// OUTPUTs -//========= -output wkup_out; // Wakup signal (asynchronous) - -// INPUTs -//========= -input scan_clk; // Scan clock -input scan_mode; // Scan mode -input scan_rst; // Scan reset -input wkup_clear; // Glitch free wakeup event clear -input wkup_event; // Glitch free asynchronous wakeup event - - -//============================================================================= -// 1) AND GATE -//============================================================================= - -// Scan stuff for the ASIC mode -`ifdef ASIC - wire wkup_rst; - omsp_scan_mux scan_mux_rst ( - .scan_mode (scan_mode), - .data_in_scan (scan_rst), - .data_in_func (wkup_clear), - .data_out (wkup_rst) - ); - - wire wkup_clk; - omsp_scan_mux scan_mux_clk ( - .scan_mode (scan_mode), - .data_in_scan (scan_clk), - .data_in_func (wkup_event), - .data_out (wkup_clk) - ); - -`else - wire wkup_rst = wkup_clear; - wire wkup_clk = wkup_event; -`endif - -// Wakeup capture -reg wkup_out; -always @(posedge wkup_clk or posedge wkup_rst) - if (wkup_rst) wkup_out <= 1'b0; - else wkup_out <= 1'b1; - - -endmodule // omsp_wakeup_cell - - - - diff --git a/tests/openmsp430/rtl/omsp_watchdog.v b/tests/openmsp430/rtl/omsp_watchdog.v deleted file mode 100644 index f7cedda0..00000000 --- a/tests/openmsp430/rtl/omsp_watchdog.v +++ /dev/null @@ -1,556 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: omsp_watchdog.v -// -// *Module Description: -// Watchdog Timer -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module omsp_watchdog ( - -// OUTPUTs - per_dout, // Peripheral data output - wdt_irq, // Watchdog-timer interrupt - wdt_reset, // Watchdog-timer reset - wdt_wkup, // Watchdog Wakeup - wdtifg, // Watchdog-timer interrupt flag - wdtnmies, // Watchdog-timer NMI edge selection - -// INPUTs - aclk, // ACLK - aclk_en, // ACLK enable - dbg_freeze, // Freeze Watchdog counter - mclk, // Main system clock - per_addr, // Peripheral address - per_din, // Peripheral data input - per_en, // Peripheral enable (high active) - per_we, // Peripheral write enable (high active) - por, // Power-on reset - puc_rst, // Main system reset - scan_enable, // Scan enable (active during scan shifting) - scan_mode, // Scan mode - smclk, // SMCLK - smclk_en, // SMCLK enable - wdtie, // Watchdog timer interrupt enable - wdtifg_irq_clr, // Watchdog-timer interrupt flag irq accepted clear - wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear - wdtifg_sw_set // Watchdog-timer interrupt flag software set -); - -// OUTPUTs -//========= -output [15:0] per_dout; // Peripheral data output -output wdt_irq; // Watchdog-timer interrupt -output wdt_reset; // Watchdog-timer reset -output wdt_wkup; // Watchdog Wakeup -output wdtifg; // Watchdog-timer interrupt flag -output wdtnmies; // Watchdog-timer NMI edge selection - -// INPUTs -//========= -input aclk; // ACLK -input aclk_en; // ACLK enable -input dbg_freeze; // Freeze Watchdog counter -input mclk; // Main system clock -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 por; // Power-on reset -input puc_rst; // Main system reset -input scan_enable; // Scan enable (active during scan shifting) -input scan_mode; // Scan mode -input smclk; // SMCLK -input smclk_en; // SMCLK enable -input wdtie; // Watchdog timer interrupt enable -input wdtifg_irq_clr; // Clear Watchdog-timer interrupt flag -input wdtifg_sw_clr; // Watchdog-timer interrupt flag software clear -input wdtifg_sw_set; // Watchdog-timer interrupt flag software set - - -//============================================================================= -// 1) PARAMETER DECLARATION -//============================================================================= - -// Register base address (must be aligned to decoder bit width) -parameter [14:0] BASE_ADDR = 15'h0120; - -// Decoder bit width (defines how many bits are considered for address decoding) -parameter DEC_WD = 2; - -// Register addresses offset -parameter [DEC_WD-1:0] WDTCTL = 'h0; - -// 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}; - -// Register one-hot decoder -parameter [DEC_SZ-1:0] WDTCTL_D = (BASE_REG << WDTCTL); - - -//============================================================================ -// 2) REGISTER DECODER -//============================================================================ - -// Local register selection -wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]); - -// Register local address -wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0}; - -// Register address decode -wire [DEC_SZ-1:0] reg_dec = (WDTCTL_D & {DEC_SZ{(reg_addr==WDTCTL)}}); - -// Read/Write probes -wire reg_write = |per_we & reg_sel; -wire reg_read = ~|per_we & reg_sel; - -// Read/Write vectors -wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}}; -wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}}; - - -//============================================================================ -// 3) REGISTERS -//============================================================================ - -// WDTCTL Register -//----------------- -// WDTNMI is not implemented and therefore masked - -reg [7:0] wdtctl; - -wire wdtctl_wr = reg_wr[WDTCTL]; - -`ifdef CLOCK_GATING -wire mclk_wdtctl; -omsp_clock_gate clock_gate_wdtctl (.gclk(mclk_wdtctl), - .clk (mclk), .enable(wdtctl_wr), .scan_enable(scan_enable)); -`else -wire mclk_wdtctl = mclk; -`endif - -`ifdef NMI -parameter [7:0] WDTNMIES_MASK = 8'h40; -`else -parameter [7:0] WDTNMIES_MASK = 8'h00; -`endif - -`ifdef ASIC - `ifdef WATCHDOG_MUX -parameter [7:0] WDTSSEL_MASK = 8'h04; - `else -parameter [7:0] WDTSSEL_MASK = 8'h00; - `endif -`else -parameter [7:0] WDTSSEL_MASK = 8'h04; -`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 - else wdtctl <= per_din[7:0] & WDTCTL_MASK; -`else - else if (wdtctl_wr) wdtctl <= per_din[7:0] & WDTCTL_MASK; -`endif - -wire wdtpw_error = wdtctl_wr & (per_din[15:8]!=8'h5a); -wire wdttmsel = wdtctl[4]; -wire wdtnmies = wdtctl[6]; - - -//============================================================================ -// 4) DATA OUTPUT GENERATION -//============================================================================ - -`ifdef NMI -parameter [7:0] WDTNMI_RD_MASK = 8'h20; -`else -parameter [7:0] WDTNMI_RD_MASK = 8'h00; -`endif -`ifdef WATCHDOG_MUX -parameter [7:0] WDTSSEL_RD_MASK = 8'h00; -`else - `ifdef WATCHDOG_NOMUX_ACLK -parameter [7:0] WDTSSEL_RD_MASK = 8'h04; - `else -parameter [7:0] WDTSSEL_RD_MASK = 8'h00; - `endif -`endif -parameter [7:0] WDTCTL_RD_MASK = WDTNMI_RD_MASK | WDTSSEL_RD_MASK; - -// Data output mux -wire [15:0] wdtctl_rd = {8'h69, wdtctl | WDTCTL_RD_MASK} & {16{reg_rd[WDTCTL]}}; -wire [15:0] per_dout = wdtctl_rd; - - -//============================================================================= -// 5) WATCHDOG TIMER (ASIC IMPLEMENTATION) -//============================================================================= -`ifdef ASIC - -// Watchdog clock source selection -//--------------------------------- -wire wdt_clk; - -`ifdef WATCHDOG_MUX -omsp_clock_mux clock_mux_watchdog ( - .clk_out (wdt_clk), - .clk_in0 (smclk), - .clk_in1 (aclk), - .reset (puc_rst), - .scan_mode (scan_mode), - .select (wdtctl[2]) -); -`else - `ifdef WATCHDOG_NOMUX_ACLK - assign wdt_clk = aclk; - `else - assign wdt_clk = smclk; - `endif -`endif - -// Reset synchronizer for the watchdog local clock domain -//-------------------------------------------------------- - -wire wdt_rst_noscan; -wire wdt_rst; - -// Reset Synchronizer -omsp_sync_reset sync_reset_por ( - .rst_s (wdt_rst_noscan), - .clk (wdt_clk), - .rst_a (puc_rst) -); - -// Scan Reset Mux -omsp_scan_mux scan_mux_wdt_rst ( - .scan_mode (scan_mode), - .data_in_scan (puc_rst), - .data_in_func (wdt_rst_noscan), - .data_out (wdt_rst) -); - - -// Watchog counter clear (synchronization) -//----------------------------------------- - -// Toggle bit whenever the watchog needs to be cleared -reg wdtcnt_clr_toggle; -wire wdtcnt_clr_detect = (wdtctl_wr & per_din[3]); -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdtcnt_clr_toggle <= 1'b0; - else if (wdtcnt_clr_detect) wdtcnt_clr_toggle <= ~wdtcnt_clr_toggle; - -// Synchronization -wire wdtcnt_clr_sync; -omsp_sync_cell sync_cell_wdtcnt_clr ( - .data_out (wdtcnt_clr_sync), - .data_in (wdtcnt_clr_toggle), - .clk (wdt_clk), - .rst (wdt_rst) -); - -// Edge detection -reg wdtcnt_clr_sync_dly; -always @ (posedge wdt_clk or posedge wdt_rst) - if (wdt_rst) wdtcnt_clr_sync_dly <= 1'b0; - else wdtcnt_clr_sync_dly <= wdtcnt_clr_sync; - -wire wdtqn_edge; -wire wdtcnt_clr = (wdtcnt_clr_sync ^ wdtcnt_clr_sync_dly) | wdtqn_edge; - - -// Watchog counter increment (synchronization) -//---------------------------------------------- -wire wdtcnt_incr; - -omsp_sync_cell sync_cell_wdtcnt_incr ( - .data_out (wdtcnt_incr), - .data_in (~wdtctl[7] & ~dbg_freeze), - .clk (wdt_clk), - .rst (wdt_rst) -); - - -// Watchdog 16 bit counter -//-------------------------- -reg [15:0] wdtcnt; - -wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001; - -`ifdef CLOCK_GATING -wire wdtcnt_en = wdtcnt_clr | wdtcnt_incr; -wire wdt_clk_cnt; -omsp_clock_gate clock_gate_wdtcnt (.gclk(wdt_clk_cnt), - .clk (wdt_clk), .enable(wdtcnt_en), .scan_enable(scan_enable)); -`else -wire wdt_clk_cnt = wdt_clk; -`endif - -always @ (posedge wdt_clk_cnt or posedge wdt_rst) - if (wdt_rst) wdtcnt <= 16'h0000; - else if (wdtcnt_clr) wdtcnt <= 16'h0000; -`ifdef CLOCK_GATING - else wdtcnt <= wdtcnt_nxt; -`else - else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt; -`endif - - -// Local synchronizer for the wdtctl.WDTISx -// configuration (note that we can live with -// a full bus synchronizer as it won't hurt -// if we get a wrong WDTISx value for a -// single clock cycle) -//-------------------------------------------- -reg [1:0] wdtisx_s; -reg [1:0] wdtisx_ss; -always @ (posedge wdt_clk_cnt or posedge wdt_rst) - if (wdt_rst) - begin - wdtisx_s <= 2'h0; - wdtisx_ss <= 2'h0; - end - else - begin - wdtisx_s <= wdtctl[1:0]; - wdtisx_ss <= wdtisx_s; - end - - -// Interval selection mux -//-------------------------- -reg wdtqn; - -always @(wdtisx_ss or wdtcnt_nxt) - case(wdtisx_ss) - 2'b00 : wdtqn = wdtcnt_nxt[15]; - 2'b01 : wdtqn = wdtcnt_nxt[13]; - 2'b10 : wdtqn = wdtcnt_nxt[9]; - default: wdtqn = wdtcnt_nxt[6]; - endcase - - -// Watchdog event detection -//----------------------------- - -// Interval end detection -assign wdtqn_edge = (wdtqn & wdtcnt_incr); - -// Toggle bit for the transmition to the MCLK domain -reg wdt_evt_toggle; -always @ (posedge wdt_clk_cnt or posedge wdt_rst) - if (wdt_rst) wdt_evt_toggle <= 1'b0; - else if (wdtqn_edge) wdt_evt_toggle <= ~wdt_evt_toggle; - -// Synchronize in the MCLK domain -wire wdt_evt_toggle_sync; -omsp_sync_cell sync_cell_wdt_evt ( - .data_out (wdt_evt_toggle_sync), - .data_in (wdt_evt_toggle), - .clk (mclk), - .rst (puc_rst) -); - -// Delay for edge detection of the toggle bit -reg wdt_evt_toggle_sync_dly; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdt_evt_toggle_sync_dly <= 1'b0; - else wdt_evt_toggle_sync_dly <= wdt_evt_toggle_sync; - -wire wdtifg_evt = (wdt_evt_toggle_sync_dly ^ wdt_evt_toggle_sync) | wdtpw_error; - - -// Watchdog wakeup generation -//------------------------------------------------------------- - -// Clear wakeup when the watchdog flag is cleared (glitch free) -reg wdtifg_clr_reg; -wire wdtifg_clr; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdtifg_clr_reg <= 1'b1; - else wdtifg_clr_reg <= wdtifg_clr; - -// Set wakeup when the watchdog event is detected (glitch free) -reg wdtqn_edge_reg; -always @ (posedge wdt_clk_cnt or posedge wdt_rst) - if (wdt_rst) wdtqn_edge_reg <= 1'b0; - else wdtqn_edge_reg <= wdtqn_edge; - -// 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 -); - -// When not in HOLD, the watchdog can generate a wakeup when: -// - in interval mode (if interrupts are enabled) -// - in reset mode (always) -reg wdt_wkup_en; -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdt_wkup_en <= 1'b0; - else wdt_wkup_en <= ~wdtctl[7] & (~wdttmsel | (wdttmsel & wdtie)); - -// Make wakeup when not enabled -wire wdt_wkup; -omsp_and_gate and_wdt_wkup (.y(wdt_wkup), .a(wdt_wkup_pre), .b(wdt_wkup_en)); - - -// Watchdog interrupt flag -//------------------------------ -reg wdtifg; - -wire wdtifg_set = wdtifg_evt | wdtifg_sw_set; -assign wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr; - -always @ (posedge mclk or posedge por) - if (por) wdtifg <= 1'b0; - else if (wdtifg_set) wdtifg <= 1'b1; - else if (wdtifg_clr) wdtifg <= 1'b0; - - -// Watchdog interrupt generation -//--------------------------------- -wire wdt_irq = wdttmsel & wdtifg & wdtie; - - -// Watchdog reset generation -//----------------------------- -reg wdt_reset; - -always @ (posedge mclk or posedge por) - if (por) wdt_reset <= 1'b0; - else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel); - - - -//============================================================================= -// 6) WATCHDOG TIMER (FPGA IMPLEMENTATION) -//============================================================================= -`else - -// Watchdog clock source selection -//--------------------------------- -wire clk_src_en = wdtctl[2] ? aclk_en : smclk_en; - - -// Watchdog 16 bit counter -//-------------------------- -reg [15:0] wdtcnt; - -wire wdtifg_evt; -wire wdtcnt_clr = (wdtctl_wr & per_din[3]) | wdtifg_evt; -wire wdtcnt_incr = ~wdtctl[7] & clk_src_en & ~dbg_freeze; - -wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001; - -always @ (posedge mclk or posedge puc_rst) - if (puc_rst) wdtcnt <= 16'h0000; - else if (wdtcnt_clr) wdtcnt <= 16'h0000; - else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt; - - -// Interval selection mux -//-------------------------- -reg wdtqn; - -always @(wdtctl or wdtcnt_nxt) - case(wdtctl[1:0]) - 2'b00 : wdtqn = wdtcnt_nxt[15]; - 2'b01 : wdtqn = wdtcnt_nxt[13]; - 2'b10 : wdtqn = wdtcnt_nxt[9]; - default: wdtqn = wdtcnt_nxt[6]; - endcase - - -// Watchdog event detection -//----------------------------- - -assign wdtifg_evt = (wdtqn & wdtcnt_incr) | wdtpw_error; - - -// Watchdog interrupt flag -//------------------------------ -reg wdtifg; - -wire wdtifg_set = wdtifg_evt | wdtifg_sw_set; -wire wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr; - -always @ (posedge mclk or posedge por) - if (por) wdtifg <= 1'b0; - else if (wdtifg_set) wdtifg <= 1'b1; - else if (wdtifg_clr) wdtifg <= 1'b0; - - -// Watchdog interrupt generation -//--------------------------------- -wire wdt_irq = wdttmsel & wdtifg & wdtie; -wire wdt_wkup = 1'b0; - - -// Watchdog reset generation -//----------------------------- -reg wdt_reset; - -always @ (posedge mclk or posedge por) - if (por) wdt_reset <= 1'b0; - else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel); - - -`endif - - -endmodule // omsp_watchdog - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/openMSP430.v b/tests/openmsp430/rtl/openMSP430.v deleted file mode 100644 index 938548aa..00000000 --- a/tests/openmsp430/rtl/openMSP430.v +++ /dev/null @@ -1,584 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: openMSP430.v -// -// *Module Description: -// openMSP430 Top level file -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 134 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $ -//---------------------------------------------------------------------------- -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_defines.v" -`endif - -module openMSP430 ( - -// OUTPUTs - aclk, // ASIC ONLY: ACLK - aclk_en, // FPGA ONLY: ACLK enable - dbg_freeze, // Freeze peripherals - 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 - -// INPUTs - cpu_en, // Enable CPU code execution (asynchronous and non-glitchy) - dbg_en, // Debug interface enable (asynchronous and non-glitchy) - 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) -); - -// OUTPUTs -//========= -output aclk; // ASIC ONLY: ACLK -output aclk_en; // FPGA ONLY: ACLK enable -output dbg_freeze; // Freeze peripherals -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 [13: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 - - -// INPUTs -//========= -input cpu_en; // Enable CPU code execution (asynchronous and non-glitchy) -input dbg_en; // Debug interface enable (asynchronous and non-glitchy) -input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous) -input dco_clk; // Fast oscillator (fast clock) -input [15:0] dmem_dout; // Data Memory data output -input [13:0] irq; // Maskable interrupts -input 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) - - - -//============================================================================= -// 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 [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 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 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 [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 -//============================================================================= - -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 - -// 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 -); - - -//============================================================================= -// 3) FRONTEND (<=> FETCH & DECODE) -//============================================================================= - -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) - -// 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) -); - - -//============================================================================= -// 4) EXECUTION UNIT -//============================================================================= - -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 - .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 - .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 (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) -); - - -//============================================================================= -// 5) MEMORY BACKBONE -//============================================================================= - -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) - -// 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) -); - - -//============================================================================= -// 6) SPECIAL FUNCTION REGISTERS -//============================================================================= -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 - -// INPUTs - .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 -); - - -//============================================================================= -// 7) WATCHDOG TIMER -//============================================================================= -`ifdef WATCHDOG -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 - -// INPUTs - .aclk (aclk), // ACLK - .aclk_en (aclk_en), // ACLK enable - .dbg_freeze (dbg_freeze), // Freeze Watchdog counter - .mclk (mclk), // Main system clock - .per_addr (per_addr), // Peripheral address - .per_din (per_din), // Peripheral data input - .per_en (per_en), // Peripheral enable (high active) - .per_we (per_we), // Peripheral write enable (high active) - .por (por), // Power-on reset - .puc_rst (puc_rst), // Main system reset - .scan_enable (scan_enable), // Scan enable (active during scan shifting) - .scan_mode (scan_mode), // Scan mode - .smclk (smclk), // SMCLK - .smclk_en (smclk_en), // SMCLK enable - .wdtie (wdtie), // Watchdog-timer interrupt enable - .wdtifg_irq_clr (irq_acc[10]), // Clear Watchdog-timer interrupt flag - .wdtifg_sw_clr (wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear - .wdtifg_sw_set (wdtifg_sw_set) // Watchdog-timer interrupt flag software set -); -`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; -`endif - - -//============================================================================= -// 8) HARDWARE MULTIPLIER -//============================================================================= -`ifdef MULTIPLIER -omsp_multiplier multiplier_0 ( - -// OUTPUTs - .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) -); -`else -assign per_dout_mpy = 16'h0000; -`endif - -//============================================================================= -// 9) PERIPHERALS' OUTPUT BUS -//============================================================================= - -assign per_dout_or = per_dout | - per_dout_clk | - per_dout_sfr | - per_dout_wdog | - per_dout_mpy; - - -//============================================================================= -// 10) DEBUG INTERFACE -//============================================================================= - -`ifdef DBG_EN -omsp_dbg dbg_0 ( - -// OUTPUTs - .dbg_freeze (dbg_freeze), // Freeze peripherals - .dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command - .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_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface - .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 - .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_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 - .eu_mdb_in (eu_mdb_in), // Memory data bus input - .eu_mdb_out (eu_mdb_out), // Memory data bus output - .exec_done (exec_done), // Execution completed - .fe_mb_en (fe_mb_en), // Frontend Memory bus enable - .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_freeze = ~cpu_en_s; -assign dbg_halt_cmd = 1'b0; -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_cpu_reset = 1'b0; -assign dbg_uart_txd = 1'b0; -`endif - - -endmodule // openMSP430 - -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif diff --git a/tests/openmsp430/rtl/openMSP430_defines.v b/tests/openmsp430/rtl/openMSP430_defines.v deleted file mode 100644 index 368f7a5b..00000000 --- a/tests/openmsp430/rtl/openMSP430_defines.v +++ /dev/null @@ -1,843 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: openMSP430_defines.v -// -// *Module Description: -// openMSP430 Configuration file -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 151 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $ -//---------------------------------------------------------------------------- -//`define OMSP_NO_INCLUDE -`ifdef OMSP_NO_INCLUDE -`else -`include "openMSP430_undefines.v" -`endif - -//============================================================================ -//============================================================================ -// BASIC SYSTEM CONFIGURATION -//============================================================================ -//============================================================================ -// -// Note: the sum of program, data and peripheral memory spaces must not -// exceed 64 kB -// - -// Program Memory Size: -// Uncomment the required memory size -//------------------------------------------------------- -//`define PMEM_SIZE_CUSTOM -//`define PMEM_SIZE_59_KB -//`define PMEM_SIZE_55_KB -//`define PMEM_SIZE_54_KB -//`define PMEM_SIZE_51_KB -//`define PMEM_SIZE_48_KB -//`define PMEM_SIZE_41_KB -//`define PMEM_SIZE_32_KB -//`define PMEM_SIZE_24_KB -//`define PMEM_SIZE_16_KB -//`define PMEM_SIZE_12_KB -//`define PMEM_SIZE_8_KB -//`define PMEM_SIZE_4_KB -`define PMEM_SIZE_2_KB -//`define PMEM_SIZE_1_KB - - -// Data Memory Size: -// Uncomment the required memory size -//------------------------------------------------------- -//`define DMEM_SIZE_CUSTOM -//`define DMEM_SIZE_32_KB -//`define DMEM_SIZE_24_KB -//`define DMEM_SIZE_16_KB -//`define DMEM_SIZE_10_KB -//`define DMEM_SIZE_8_KB -//`define DMEM_SIZE_5_KB -//`define DMEM_SIZE_4_KB -//`define DMEM_SIZE_2p5_KB -//`define DMEM_SIZE_2_KB -//`define DMEM_SIZE_1_KB -//`define DMEM_SIZE_512_B -//`define DMEM_SIZE_256_B -`define DMEM_SIZE_128_B - - -// Include/Exclude Hardware Multiplier -`define MULTIPLIER - - -// Include/Exclude Serial Debug interface -`define DBG_EN - - -//============================================================================ -//============================================================================ -// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS) -//============================================================================ -//============================================================================ - -//------------------------------------------------------- -// Custom user version number -//------------------------------------------------------- -// This 5 bit field can be freely used in order to allow -// custom identification of the system through the debug -// interface. -// (see CPU_ID.USER_VERSION field in the documentation) -//------------------------------------------------------- -`define USER_VERSION 5'b00000 - - -//------------------------------------------------------- -// Include/Exclude Watchdog timer -//------------------------------------------------------- -// When excluded, the following functionality will be -// lost: -// - Watchog (both interval and watchdog modes) -// - NMI interrupt edge selection -// - Possibility to generate a software PUC reset -//------------------------------------------------------- -`define WATCHDOG - - -///------------------------------------------------------- -// Include/Exclude Non-Maskable-Interrupt support -//------------------------------------------------------- -`define NMI - - -//------------------------------------------------------- -// Input synchronizers -//------------------------------------------------------- -// In some cases, the asynchronous input ports might -// already be synchronized externally. -// If an extensive CDC design review showed that this -// is really the case, the individual synchronizers -// can be disabled with the following defines. -// -// Notes: -// - all three signals are all sampled in the MCLK domain -// -// - the dbg_en signal reset the debug interface -// when 0. Therefore make sure it is glitch free. -// -//------------------------------------------------------- -`define SYNC_NMI -//`define SYNC_CPU_EN -//`define SYNC_DBG_EN - - -//------------------------------------------------------- -// Peripheral Memory Space: -//------------------------------------------------------- -// The original MSP430 architecture map the peripherals -// from 0x0000 to 0x01FF (i.e. 512B of the memory space). -// The following defines allow you to expand this space -// up to 32 kB (i.e. from 0x0000 to 0x7fff). -// As a consequence, the data memory mapping will be -// shifted up and a custom linker script will therefore -// be required by the GCC compiler. -//------------------------------------------------------- -//`define PER_SIZE_CUSTOM -//`define PER_SIZE_32_KB -//`define PER_SIZE_16_KB -//`define PER_SIZE_8_KB -//`define PER_SIZE_4_KB -//`define PER_SIZE_2_KB -//`define PER_SIZE_1_KB -`define PER_SIZE_512_B - - -//------------------------------------------------------- -// Defines the debugger CPU_CTL.RST_BRK_EN reset value -// (CPU break on PUC reset) -//------------------------------------------------------- -// When defined, the CPU will automatically break after -// a PUC occurrence by default. This is typically useful -// when the program memory can only be initialized through -// the serial debug interface. -//------------------------------------------------------- -`define DBG_RST_BRK_EN - - -//============================================================================ -//============================================================================ -// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! ) -//============================================================================ -//============================================================================ -// -// IMPORTANT NOTE: Please update following configuration options ONLY if -// you have a good reason to do so... and if you know what -// you are doing :-P -// -//============================================================================ - -//------------------------------------------------------- -// Number of hardware breakpoint/watchpoint units -// (each unit contains two hardware addresses available -// for breakpoints or watchpoints): -// - DBG_HWBRK_0 -> Include hardware breakpoints unit 0 -// - DBG_HWBRK_1 -> Include hardware breakpoints unit 1 -// - DBG_HWBRK_2 -> Include hardware breakpoints unit 2 -// - DBG_HWBRK_3 -> Include hardware breakpoints unit 3 -//------------------------------------------------------- -// Please keep in mind that hardware breakpoints only -// make sense whenever the program memory is not an SRAM -// (i.e. Flash/OTP/ROM/...) or when you are interested -// in data breakpoints. -//------------------------------------------------------- -//`define DBG_HWBRK_0 -//`define DBG_HWBRK_1 -//`define DBG_HWBRK_2 -//`define DBG_HWBRK_3 - - -//------------------------------------------------------- -// Enable/Disable the hardware breakpoint RANGE mode -//------------------------------------------------------- -// When enabled this feature allows the hardware breakpoint -// units to stop the cpu whenever an instruction or data -// access lays within an address range. -// Note that this feature is not supported by GDB. -//------------------------------------------------------- -//`define DBG_HWBRK_RANGE - - -//------------------------------------------------------- -// Custom Program/Data and Peripheral Memory Spaces -//------------------------------------------------------- -// The following values are valid only if the -// corresponding *_SIZE_CUSTOM defines are uncommented: -// -// - *_SIZE : size of the section in bytes. -// - *_AWIDTH : address port width, this value must allow -// to address all WORDS of the section -// (i.e. the *_SIZE divided by 2) -//------------------------------------------------------- - -// Custom Program memory (enabled with PMEM_SIZE_CUSTOM) -`define PMEM_CUSTOM_AWIDTH 10 -`define PMEM_CUSTOM_SIZE 2028 - -// 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) -`define PER_CUSTOM_AWIDTH 8 -`define PER_CUSTOM_SIZE 512 - - -//------------------------------------------------------- -// ASIC version -//------------------------------------------------------- -// When uncommented, this define will enable the -// ASIC system configuration section (see below) and -// will activate scan support for production test. -// -// WARNING: if you target an FPGA, leave this define -// commented. -//------------------------------------------------------- -//`define ASIC - - -//============================================================================ -//============================================================================ -// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS/PROFESSIONALS ONLY !!!! ) -//============================================================================ -//============================================================================ -`ifdef ASIC - -//=============================================================== -// FINE GRAINED CLOCK GATING -//=============================================================== - -//------------------------------------------------------- -// When uncommented, this define will enable the fine -// grained clock gating of all registers in the core. -//------------------------------------------------------- -`define CLOCK_GATING - - -//=============================================================== -// LFXT CLOCK DOMAIN -//=============================================================== - -//------------------------------------------------------- -// When uncommented, this define will enable the lfxt_clk -// clock domain. -// When commented out, the whole chip is clocked with dco_clk. -//------------------------------------------------------- -`define LFXT_DOMAIN - - -//=============================================================== -// CLOCK MUXES -//=============================================================== - -//------------------------------------------------------- -// MCLK: Clock Mux -//------------------------------------------------------- -// When uncommented, this define will enable the -// MCLK clock MUX allowing the selection between -// DCO_CLK and LFXT_CLK with the BCSCTL2.SELMx register. -// When commented, DCO_CLK is selected. -//------------------------------------------------------- -`define MCLK_MUX - -//------------------------------------------------------- -// SMCLK: Clock Mux -//------------------------------------------------------- -// When uncommented, this define will enable the -// SMCLK clock MUX allowing the selection between -// DCO_CLK and LFXT_CLK with the BCSCTL2.SELS register. -// When commented, DCO_CLK is selected. -//------------------------------------------------------- -`define SMCLK_MUX - -//------------------------------------------------------- -// WATCHDOG: Clock Mux -//------------------------------------------------------- -// When uncommented, this define will enable the -// Watchdog clock MUX allowing the selection between -// ACLK and SMCLK with the WDTCTL.WDTSSEL register. -// When commented out, ACLK is selected if the -// WATCHDOG_NOMUX_ACLK define is uncommented, SMCLK is -// selected otherwise. -//------------------------------------------------------- -`define WATCHDOG_MUX -//`define WATCHDOG_NOMUX_ACLK - - -//=============================================================== -// CLOCK DIVIDERS -//=============================================================== - -//------------------------------------------------------- -// MCLK: Clock divider -//------------------------------------------------------- -// When uncommented, this define will enable the -// MCLK clock divider (/1/2/4/8) -//------------------------------------------------------- -`define MCLK_DIVIDER - -//------------------------------------------------------- -// SMCLK: Clock divider (/1/2/4/8) -//------------------------------------------------------- -// When uncommented, this define will enable the -// SMCLK clock divider -//------------------------------------------------------- -`define SMCLK_DIVIDER - -//------------------------------------------------------- -// ACLK: Clock divider (/1/2/4/8) -//------------------------------------------------------- -// When uncommented, this define will enable the -// ACLK clock divider -//------------------------------------------------------- -`define ACLK_DIVIDER - - -//=============================================================== -// LOW POWER MODES -//=============================================================== - -//------------------------------------------------------- -// LOW POWER MODE: CPUOFF -//------------------------------------------------------- -// When uncommented, this define will include the -// clock gate allowing to switch off MCLK in -// all low power modes: LPM0, LPM1, LPM2, LPM3, LPM4 -//------------------------------------------------------- -`define CPUOFF_EN - -//------------------------------------------------------- -// LOW POWER MODE: SCG0 -//------------------------------------------------------- -// When uncommented, this define will enable the -// DCO_ENABLE/WKUP port control (always 1 when commented). -// This allows to switch off the DCO oscillator in the -// following low power modes: LPM1, LPM3, LPM4 -//------------------------------------------------------- -`define SCG0_EN - -//------------------------------------------------------- -// LOW POWER MODE: SCG1 -//------------------------------------------------------- -// When uncommented, this define will include the -// clock gate allowing to switch off SMCLK in -// the following low power modes: LPM2, LPM3, LPM4 -//------------------------------------------------------- -`define SCG1_EN - -//------------------------------------------------------- -// LOW POWER MODE: OSCOFF -//------------------------------------------------------- -// When uncommented, this define will include the -// LFXT_CLK clock gate and enable the LFXT_ENABLE/WKUP -// port control (always 1 when commented). -// This allows to switch off the low frequency oscillator -// in the following low power modes: LPM4 -//------------------------------------------------------- -`define OSCOFF_EN - - - -`endif - -//==========================================================================// -//==========================================================================// -//==========================================================================// -//==========================================================================// -//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====// -//==========================================================================// -//==========================================================================// -//==========================================================================// -//==========================================================================// - -// -// PROGRAM, DATA & PERIPHERAL MEMORY CONFIGURATION -//================================================== - -// Program Memory Size -`ifdef PMEM_SIZE_59_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 60416 -`endif -`ifdef PMEM_SIZE_55_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 56320 -`endif -`ifdef PMEM_SIZE_54_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 55296 -`endif -`ifdef PMEM_SIZE_51_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 52224 -`endif -`ifdef PMEM_SIZE_48_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 49152 -`endif -`ifdef PMEM_SIZE_41_KB - `define PMEM_AWIDTH 15 - `define PMEM_SIZE 41984 -`endif -`ifdef PMEM_SIZE_32_KB - `define PMEM_AWIDTH 14 - `define PMEM_SIZE 32768 -`endif -`ifdef PMEM_SIZE_24_KB - `define PMEM_AWIDTH 14 - `define PMEM_SIZE 24576 -`endif -`ifdef PMEM_SIZE_16_KB - `define PMEM_AWIDTH 13 - `define PMEM_SIZE 16384 -`endif -`ifdef PMEM_SIZE_12_KB - `define PMEM_AWIDTH 13 - `define PMEM_SIZE 12288 -`endif -`ifdef PMEM_SIZE_8_KB - `define PMEM_AWIDTH 12 - `define PMEM_SIZE 8192 -`endif -`ifdef PMEM_SIZE_4_KB - `define PMEM_AWIDTH 11 - `define PMEM_SIZE 4096 -`endif -`ifdef PMEM_SIZE_2_KB - `define PMEM_AWIDTH 10 - `define PMEM_SIZE 2048 -`endif -`ifdef PMEM_SIZE_1_KB - `define PMEM_AWIDTH 9 - `define PMEM_SIZE 1024 -`endif -`ifdef PMEM_SIZE_CUSTOM - `define PMEM_AWIDTH `PMEM_CUSTOM_AWIDTH - `define PMEM_SIZE `PMEM_CUSTOM_SIZE -`endif - -// Data Memory Size -`ifdef DMEM_SIZE_32_KB - `define DMEM_AWIDTH 14 - `define DMEM_SIZE 32768 -`endif -`ifdef DMEM_SIZE_24_KB - `define DMEM_AWIDTH 14 - `define DMEM_SIZE 24576 -`endif -`ifdef DMEM_SIZE_16_KB - `define DMEM_AWIDTH 13 - `define DMEM_SIZE 16384 -`endif -`ifdef DMEM_SIZE_10_KB - `define DMEM_AWIDTH 13 - `define DMEM_SIZE 10240 -`endif -`ifdef DMEM_SIZE_8_KB - `define DMEM_AWIDTH 12 - `define DMEM_SIZE 8192 -`endif -`ifdef DMEM_SIZE_5_KB - `define DMEM_AWIDTH 12 - `define DMEM_SIZE 5120 -`endif -`ifdef DMEM_SIZE_4_KB - `define DMEM_AWIDTH 11 - `define DMEM_SIZE 4096 -`endif -`ifdef DMEM_SIZE_2p5_KB - `define DMEM_AWIDTH 11 - `define DMEM_SIZE 2560 -`endif -`ifdef DMEM_SIZE_2_KB - `define DMEM_AWIDTH 10 - `define DMEM_SIZE 2048 -`endif -`ifdef DMEM_SIZE_1_KB - `define DMEM_AWIDTH 9 - `define DMEM_SIZE 1024 -`endif -`ifdef DMEM_SIZE_512_B - `define DMEM_AWIDTH 8 - `define DMEM_SIZE 512 -`endif -`ifdef DMEM_SIZE_256_B - `define DMEM_AWIDTH 7 - `define DMEM_SIZE 256 -`endif -`ifdef DMEM_SIZE_128_B - `define DMEM_AWIDTH 6 - `define DMEM_SIZE 128 -`endif -`ifdef DMEM_SIZE_CUSTOM - `define DMEM_AWIDTH `DMEM_CUSTOM_AWIDTH - `define DMEM_SIZE `DMEM_CUSTOM_SIZE -`endif - -// Peripheral Memory Size -`ifdef PER_SIZE_32_KB - `define PER_AWIDTH 14 - `define PER_SIZE 32768 -`endif -`ifdef PER_SIZE_16_KB - `define PER_AWIDTH 13 - `define PER_SIZE 16384 -`endif -`ifdef PER_SIZE_8_KB - `define PER_AWIDTH 12 - `define PER_SIZE 8192 -`endif -`ifdef PER_SIZE_4_KB - `define PER_AWIDTH 11 - `define PER_SIZE 4096 -`endif -`ifdef PER_SIZE_2_KB - `define PER_AWIDTH 10 - `define PER_SIZE 2048 -`endif -`ifdef PER_SIZE_1_KB - `define PER_AWIDTH 9 - `define PER_SIZE 1024 -`endif -`ifdef PER_SIZE_512_B - `define PER_AWIDTH 8 - `define PER_SIZE 512 -`endif -`ifdef PER_SIZE_CUSTOM - `define PER_AWIDTH `PER_CUSTOM_AWIDTH - `define PER_SIZE `PER_CUSTOM_SIZE -`endif - -// Data Memory Base Adresses -`define DMEM_BASE `PER_SIZE - -// Program & Data Memory most significant address bit (for 16 bit words) -`define PMEM_MSB `PMEM_AWIDTH-1 -`define DMEM_MSB `DMEM_AWIDTH-1 -`define PER_MSB `PER_AWIDTH-1 - -// -// STATES, REGISTER FIELDS, ... -//====================================== - -// Instructions type -`define INST_SO 0 -`define INST_JMP 1 -`define INST_TO 2 - -// Single-operand arithmetic -`define RRC 0 -`define SWPB 1 -`define RRA 2 -`define SXT 3 -`define PUSH 4 -`define CALL 5 -`define RETI 6 -`define IRQ 7 - -// Conditional jump -`define JNE 0 -`define JEQ 1 -`define JNC 2 -`define JC 3 -`define JN 4 -`define JGE 5 -`define JL 6 -`define JMP 7 - -// Two-operand arithmetic -`define MOV 0 -`define ADD 1 -`define ADDC 2 -`define SUBC 3 -`define SUB 4 -`define CMP 5 -`define DADD 6 -`define BIT 7 -`define BIC 8 -`define BIS 9 -`define XOR 10 -`define AND 11 - -// Addressing modes -`define DIR 0 -`define IDX 1 -`define INDIR 2 -`define INDIR_I 3 -`define SYMB 4 -`define IMM 5 -`define ABS 6 -`define CONST 7 - -// Instruction state machine -`define I_IRQ_FETCH 3'h0 -`define I_IRQ_DONE 3'h1 -`define I_DEC 3'h2 -`define I_EXT1 3'h3 -`define I_EXT2 3'h4 -`define I_IDLE 3'h5 - -// Execution state machine -// (swapped E_IRQ_0 and E_IRQ_2 values to suppress glitch generation warning from lint tool) -`define E_IRQ_0 4'h2 -`define E_IRQ_1 4'h1 -`define E_IRQ_2 4'h0 -`define E_IRQ_3 4'h3 -`define E_IRQ_4 4'h4 -`define E_SRC_AD 4'h5 -`define E_SRC_RD 4'h6 -`define E_SRC_WR 4'h7 -`define E_DST_AD 4'h8 -`define E_DST_RD 4'h9 -`define E_DST_WR 4'hA -`define E_EXEC 4'hB -`define E_JUMP 4'hC -`define E_IDLE 4'hD - -// ALU control signals -`define ALU_SRC_INV 0 -`define ALU_INC 1 -`define ALU_INC_C 2 -`define ALU_ADD 3 -`define ALU_AND 4 -`define ALU_OR 5 -`define ALU_XOR 6 -`define ALU_DADD 7 -`define ALU_STAT_7 8 -`define ALU_STAT_F 9 -`define ALU_SHIFT 10 -`define EXEC_NO_WR 11 - -// Debug interface -`define DBG_UART_WR 18 -`define DBG_UART_BW 17 -`define DBG_UART_ADDR 16:11 - -// Debug interface CPU_CTL register -`define HALT 0 -`define RUN 1 -`define ISTEP 2 -`define SW_BRK_EN 3 -`define FRZ_BRK_EN 4 -`define RST_BRK_EN 5 -`define CPU_RST 6 - -// Debug interface CPU_STAT register -`define HALT_RUN 0 -`define PUC_PND 1 -`define SWBRK_PND 3 -`define HWBRK0_PND 4 -`define HWBRK1_PND 5 - -// Debug interface BRKx_CTL register -`define BRK_MODE_RD 0 -`define BRK_MODE_WR 1 -`define BRK_MODE 1:0 -`define BRK_EN 2 -`define BRK_I_EN 3 -`define BRK_RANGE 4 - -// Basic clock module: BCSCTL1 Control Register -`define DIVAx 5:4 - -// Basic clock module: BCSCTL2 Control Register -`define SELMx 7 -`define DIVMx 5:4 -`define SELS 3 -`define DIVSx 2:1 - -// MCLK Clock gate -`ifdef CPUOFF_EN - `define MCLK_CGATE -`else -`ifdef MCLK_DIVIDER - `define MCLK_CGATE -`endif -`endif - -// SMCLK Clock gate -`ifdef SCG1_EN - `define SMCLK_CGATE -`else -`ifdef SMCLK_DIVIDER - `define SMCLK_CGATE -`endif -`endif - -// -// DEBUG INTERFACE EXTRA CONFIGURATION -//====================================== - -// Debug interface: CPU version -`define CPU_VERSION 3'h2 - -// Debug interface: Software breakpoint opcode -`define DBG_SWBRK_OP 16'h4343 - -// Debug UART interface auto data synchronization -// If the following define is commented out, then -// the DBG_UART_BAUD and DBG_DCO_FREQ need to be properly -// defined. -`define DBG_UART_AUTO_SYNC - -// Debug UART interface data rate -// In order to properly setup the UART debug interface, you -// need to specify the DCO_CLK frequency (DBG_DCO_FREQ) and -// the chosen BAUD rate from the UART interface. -// -//`define DBG_UART_BAUD 9600 -//`define DBG_UART_BAUD 19200 -//`define DBG_UART_BAUD 38400 -//`define DBG_UART_BAUD 57600 -//`define DBG_UART_BAUD 115200 -//`define DBG_UART_BAUD 230400 -//`define DBG_UART_BAUD 460800 -//`define DBG_UART_BAUD 576000 -//`define DBG_UART_BAUD 921600 -`define DBG_UART_BAUD 2000000 -`define DBG_DCO_FREQ 20000000 -`define DBG_UART_CNT ((`DBG_DCO_FREQ/`DBG_UART_BAUD)-1) - -// Debug interface selection -// `define DBG_UART -> Enable UART (8N1) debug interface -// `define DBG_JTAG -> DON'T UNCOMMENT, NOT SUPPORTED -// -`define DBG_UART -//`define DBG_JTAG - -// Debug interface input synchronizer -`define SYNC_DBG_UART_RXD - -// Enable/Disable the hardware breakpoint RANGE mode -`ifdef DBG_HWBRK_RANGE - `define HWBRK_RANGE 1'b1 -`else - `define HWBRK_RANGE 1'b0 -`endif - -// Counter width for the debug interface UART -`define DBG_UART_XFER_CNT_W 16 - -// Check configuration -`ifdef DBG_EN - `ifdef DBG_UART - `ifdef DBG_JTAG -CONFIGURATION ERROR: JTAG AND UART DEBUG INTERFACE ARE BOTH ENABLED - `endif - `else - `ifdef DBG_JTAG -CONFIGURATION ERROR: JTAG INTERFACE NOT SUPPORTED - `else -CONFIGURATION ERROR: JTAG OR UART DEBUG INTERFACE SHOULD BE ENABLED - `endif - `endif -`endif - -// -// MULTIPLIER CONFIGURATION -//====================================== - -// If uncommented, the following define selects -// the 16x16 multiplier (1 cycle) instead of the -// default 16x8 multplier (2 cycles) -//`define MPY_16x16 - -//====================================== -// CONFIGURATION CHECKS -//====================================== -`ifdef LFXT_DOMAIN -`else - `ifdef MCLK_MUX -CONFIGURATION ERROR: THE MCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL - `endif - `ifdef SMCLK_MUX -CONFIGURATION ERROR: THE SMCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL - `endif - `ifdef WATCHDOG_MUX -CONFIGURATION ERROR: THE WATCHDOG_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL - `else - `ifdef WATCHDOG_NOMUX_ACLK -CONFIGURATION ERROR: THE WATCHDOG_NOMUX_ACLK CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL - `endif - `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 diff --git a/tests/openmsp430/rtl/openMSP430_undefines.v b/tests/openmsp430/rtl/openMSP430_undefines.v deleted file mode 100644 index a399ae77..00000000 --- a/tests/openmsp430/rtl/openMSP430_undefines.v +++ /dev/null @@ -1,732 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2009 , Olivier Girard -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the authors nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE -// -//---------------------------------------------------------------------------- -// -// *File Name: openMSP430_undefines.v -// -// *Module Description: -// openMSP430 Verilog `undef file -// -// *Author(s): -// - Olivier Girard, olgirard@gmail.com -// -//---------------------------------------------------------------------------- -// $Rev: 23 $ -// $LastChangedBy: olivier.girard $ -// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $ -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// BASIC SYSTEM CONFIGURATION -//---------------------------------------------------------------------------- - -// Program Memory sizes -`ifdef PMEM_SIZE_59_KB -`undef PMEM_SIZE_59_KB -`endif -`ifdef PMEM_SIZE_55_KB -`undef PMEM_SIZE_55_KB -`endif -`ifdef PMEM_SIZE_54_KB -`undef PMEM_SIZE_54_KB -`endif -`ifdef PMEM_SIZE_51_KB -`undef PMEM_SIZE_51_KB -`endif -`ifdef PMEM_SIZE_48_KB -`undef PMEM_SIZE_48_KB -`endif -`ifdef PMEM_SIZE_41_KB -`undef PMEM_SIZE_41_KB -`endif -`ifdef PMEM_SIZE_32_KB -`undef PMEM_SIZE_32_KB -`endif -`ifdef PMEM_SIZE_24_KB -`undef PMEM_SIZE_24_KB -`endif -`ifdef PMEM_SIZE_16_KB -`undef PMEM_SIZE_16_KB -`endif -`ifdef PMEM_SIZE_12_KB -`undef PMEM_SIZE_12_KB -`endif -`ifdef PMEM_SIZE_8_KB -`undef PMEM_SIZE_8_KB -`endif -`ifdef PMEM_SIZE_4_KB -`undef PMEM_SIZE_4_KB -`endif -`ifdef PMEM_SIZE_2_KB -`undef PMEM_SIZE_2_KB -`endif -`ifdef PMEM_SIZE_1_KB -`undef PMEM_SIZE_1_KB -`endif - -// Data Memory sizes -`ifdef DMEM_SIZE_32_KB -`undef DMEM_SIZE_32_KB -`endif -`ifdef DMEM_SIZE_24_KB -`undef DMEM_SIZE_24_KB -`endif -`ifdef DMEM_SIZE_16_KB -`undef DMEM_SIZE_16_KB -`endif -`ifdef DMEM_SIZE_10_KB -`undef DMEM_SIZE_10_KB -`endif -`ifdef DMEM_SIZE_8_KB -`undef DMEM_SIZE_8_KB -`endif -`ifdef DMEM_SIZE_5_KB -`undef DMEM_SIZE_5_KB -`endif -`ifdef DMEM_SIZE_4_KB -`undef DMEM_SIZE_4_KB -`endif -`ifdef DMEM_SIZE_2p5_KB -`undef DMEM_SIZE_2p5_KB -`endif -`ifdef DMEM_SIZE_2_KB -`undef DMEM_SIZE_2_KB -`endif -`ifdef DMEM_SIZE_1_KB -`undef DMEM_SIZE_1_KB -`endif -`ifdef DMEM_SIZE_512_B -`undef DMEM_SIZE_512_B -`endif -`ifdef DMEM_SIZE_256_B -`undef DMEM_SIZE_256_B -`endif -`ifdef DMEM_SIZE_128_B -`undef DMEM_SIZE_128_B -`endif - -// Include/Exclude Hardware Multiplier -`ifdef MULTIPLIER -`undef MULTIPLIER -`endif - -// Include Debug interface -`ifdef DBG_EN -`undef DBG_EN -`endif - - -//---------------------------------------------------------------------------- -// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS) -//---------------------------------------------------------------------------- - -// Peripheral Memory Space: -`ifdef PER_SIZE_32_KB -`undef PER_SIZE_32_KB -`endif -`ifdef PER_SIZE_16_KB -`undef PER_SIZE_16_KB -`endif -`ifdef PER_SIZE_8_KB -`undef PER_SIZE_8_KB -`endif -`ifdef PER_SIZE_4_KB -`undef PER_SIZE_4_KB -`endif -`ifdef PER_SIZE_2_KB -`undef PER_SIZE_2_KB -`endif -`ifdef PER_SIZE_1_KB -`undef PER_SIZE_1_KB -`endif -`ifdef PER_SIZE_512_B -`undef PER_SIZE_512_B -`endif - -// Let the CPU break after a PUC occurrence by default -`ifdef DBG_RST_BRK_EN -`undef DBG_RST_BRK_EN -`endif - -// Custom user version number -`ifdef USER_VERSION -`undef USER_VERSION -`endif - -// Include/Exclude Watchdog timer -`ifdef WATCHDOG -`undef WATCHDOG -`endif - -// Include/Exclude Non-Maskable-Interrupt support -`ifdef NMI -`undef NMI -`endif - -//---------------------------------------------------------------------------- -// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! ) -//---------------------------------------------------------------------------- - -// Number of hardware breakpoint units -`ifdef DBG_HWBRK_0 -`undef DBG_HWBRK_0 -`endif -`ifdef DBG_HWBRK_1 -`undef DBG_HWBRK_1 -`endif -`ifdef DBG_HWBRK_2 -`undef DBG_HWBRK_2 -`endif -`ifdef DBG_HWBRK_3 -`undef DBG_HWBRK_3 -`endif - -// Enable/Disable the hardware breakpoint RANGE mode -`ifdef DBG_HWBRK_RANGE -`undef DBG_HWBRK_RANGE -`endif - -// Input synchronizers -`ifdef SYNC_CPU_EN -`undef SYNC_CPU_EN -`endif -`ifdef SYNC_DBG_EN -`undef SYNC_DBG_EN -`endif -`ifdef SYNC_DBG_UART_RXD -`undef SYNC_DBG_UART_RXD -`endif -`ifdef SYNC_NMI -`undef SYNC_NMI -`endif - -// ASIC version -`ifdef ASIC -`undef ASIC -`endif - - -//---------------------------------------------------------------------------- -// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! ) -//---------------------------------------------------------------------------- - -// Fine grained clock gating -`ifdef CLOCK_GATING -`undef CLOCK_GATING -`endif - -// LFXT clock domain -`ifdef LFXT_DOMAIN -`undef LFXT_DOMAIN -`endif - -// MCLK: Clock Mux -`ifdef MCLK_MUX -`undef MCLK_MUX -`endif - -// SMCLK: Clock Mux -`ifdef SMCLK_MUX -`undef SMCLK_MUX -`endif - -// WATCHDOG: Clock Mux -`ifdef WATCHDOG_MUX -`undef WATCHDOG_MUX -`endif - -// MCLK: Clock divider -`ifdef MCLK_DIVIDER -`undef MCLK_DIVIDER -`endif - -// SMCLK: Clock divider (/1/2/4/8) -`ifdef SMCLK_DIVIDER -`undef SMCLK_DIVIDER -`endif - -// ACLK: Clock divider (/1/2/4/8) -`ifdef ACLK_DIVIDER -`undef ACLK_DIVIDER -`endif - -// LOW POWER MODE: CPUOFF -`ifdef CPUOFF_EN -`undef CPUOFF_EN -`endif - -// LOW POWER MODE: OSCOFF -`ifdef OSCOFF_EN -`undef OSCOFF_EN -`endif - -// LOW POWER MODE: SCG0 -`ifdef SCG0_EN -`undef SCG0_EN -`endif - -// LOW POWER MODE: SCG1 -`ifdef SCG1_EN -`undef SCG1_EN -`endif - - -//==========================================================================// -//==========================================================================// -//==========================================================================// -//==========================================================================// -//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====// -//==========================================================================// -//==========================================================================// -//==========================================================================// -//==========================================================================// - -// Program Memory Size -`ifdef PMEM_AWIDTH -`undef PMEM_AWIDTH -`endif -`ifdef PMEM_SIZE -`undef PMEM_SIZE -`endif - -// Data Memory Size -`ifdef DMEM_AWIDTH -`undef DMEM_AWIDTH -`endif -`ifdef DMEM_SIZE -`undef DMEM_SIZE -`endif - -// Peripheral Memory Size -`ifdef PER_AWIDTH -`undef PER_AWIDTH -`endif -`ifdef PER_SIZE -`undef PER_SIZE -`endif - -// Data Memory Base Adresses -`ifdef DMEM_BASE -`undef DMEM_BASE -`endif - -// Program & Data Memory most significant address bit (for 16 bit words) -`ifdef PMEM_MSB -`undef PMEM_MSB -`endif -`ifdef DMEM_MSB -`undef DMEM_MSB -`endif -`ifdef PER_MSB -`undef PER_MSB -`endif - -// Instructions type -`ifdef INST_SO -`undef INST_SO -`endif -`ifdef INST_JMP -`undef INST_JMP -`endif -`ifdef INST_TO -`undef INST_TO -`endif - -// Single-operand arithmetic -`ifdef RRC -`undef RRC -`endif -`ifdef SWPB -`undef SWPB -`endif -`ifdef RRA -`undef RRA -`endif -`ifdef SXT -`undef SXT -`endif -`ifdef PUSH -`undef PUSH -`endif -`ifdef CALL -`undef CALL -`endif -`ifdef RETI -`undef RETI -`endif -`ifdef IRQ -`undef IRQ -`endif - -// Conditional jump -`ifdef JNE -`undef JNE -`endif -`ifdef JEQ -`undef JEQ -`endif -`ifdef JNC -`undef JNC -`endif -`ifdef JC -`undef JC -`endif -`ifdef JN -`undef JN -`endif -`ifdef JGE -`undef JGE -`endif -`ifdef JL -`undef JL -`endif -`ifdef JMP -`undef JMP -`endif - -// Two-operand arithmetic -`ifdef MOV -`undef MOV -`endif -`ifdef ADD -`undef ADD -`endif -`ifdef ADDC -`undef ADDC -`endif -`ifdef SUBC -`undef SUBC -`endif -`ifdef SUB -`undef SUB -`endif -`ifdef CMP -`undef CMP -`endif -`ifdef DADD -`undef DADD -`endif -`ifdef BIT -`undef BIT -`endif -`ifdef BIC -`undef BIC -`endif -`ifdef BIS -`undef BIS -`endif -`ifdef XOR -`undef XOR -`endif -`ifdef AND -`undef AND -`endif - -// Addressing modes -`ifdef DIR -`undef DIR -`endif -`ifdef IDX -`undef IDX -`endif -`ifdef INDIR -`undef INDIR -`endif -`ifdef INDIR_I -`undef INDIR_I -`endif -`ifdef SYMB -`undef SYMB -`endif -`ifdef IMM -`undef IMM -`endif -`ifdef ABS -`undef ABS -`endif -`ifdef CONST -`undef CONST -`endif - -// Instruction state machine -`ifdef I_IRQ_FETCH -`undef I_IRQ_FETCH -`endif -`ifdef I_IRQ_DONE -`undef I_IRQ_DONE -`endif -`ifdef I_DEC -`undef I_DEC -`endif -`ifdef I_EXT1 -`undef I_EXT1 -`endif -`ifdef I_EXT2 -`undef I_EXT2 -`endif -`ifdef I_IDLE -`undef I_IDLE -`endif - -// Execution state machine -`ifdef E_IRQ_0 -`undef E_IRQ_0 -`endif -`ifdef E_IRQ_1 -`undef E_IRQ_1 -`endif -`ifdef E_IRQ_2 -`undef E_IRQ_2 -`endif -`ifdef E_IRQ_3 -`undef E_IRQ_3 -`endif -`ifdef E_IRQ_4 -`undef E_IRQ_4 -`endif -`ifdef E_SRC_AD -`undef E_SRC_AD -`endif -`ifdef E_SRC_RD -`undef E_SRC_RD -`endif -`ifdef E_SRC_WR -`undef E_SRC_WR -`endif -`ifdef E_DST_AD -`undef E_DST_AD -`endif -`ifdef E_DST_RD -`undef E_DST_RD -`endif -`ifdef E_DST_WR -`undef E_DST_WR -`endif -`ifdef E_EXEC -`undef E_EXEC -`endif -`ifdef E_JUMP -`undef E_JUMP -`endif -`ifdef E_IDLE -`undef E_IDLE -`endif - -// ALU control signals -`ifdef ALU_SRC_INV -`undef ALU_SRC_INV -`endif -`ifdef ALU_INC -`undef ALU_INC -`endif -`ifdef ALU_INC_C -`undef ALU_INC_C -`endif -`ifdef ALU_ADD -`undef ALU_ADD -`endif -`ifdef ALU_AND -`undef ALU_AND -`endif -`ifdef ALU_OR -`undef ALU_OR -`endif -`ifdef ALU_XOR -`undef ALU_XOR -`endif -`ifdef ALU_DADD -`undef ALU_DADD -`endif -`ifdef ALU_STAT_7 -`undef ALU_STAT_7 -`endif -`ifdef ALU_STAT_F -`undef ALU_STAT_F -`endif -`ifdef ALU_SHIFT -`undef ALU_SHIFT -`endif -`ifdef EXEC_NO_WR -`undef EXEC_NO_WR -`endif - -// Debug interface -`ifdef DBG_UART_WR -`undef DBG_UART_WR -`endif -`ifdef DBG_UART_BW -`undef DBG_UART_BW -`endif -`ifdef DBG_UART_ADDR -`undef DBG_UART_ADDR -`endif - -// Debug interface CPU_CTL register -`ifdef HALT -`undef HALT -`endif -`ifdef RUN -`undef RUN -`endif -`ifdef ISTEP -`undef ISTEP -`endif -`ifdef SW_BRK_EN -`undef SW_BRK_EN -`endif -`ifdef FRZ_BRK_EN -`undef FRZ_BRK_EN -`endif -`ifdef RST_BRK_EN -`undef RST_BRK_EN -`endif -`ifdef CPU_RST -`undef CPU_RST -`endif - -// Debug interface CPU_STAT register -`ifdef HALT_RUN -`undef HALT_RUN -`endif -`ifdef PUC_PND -`undef PUC_PND -`endif -`ifdef SWBRK_PND -`undef SWBRK_PND -`endif -`ifdef HWBRK0_PND -`undef HWBRK0_PND -`endif -`ifdef HWBRK1_PND -`undef HWBRK1_PND -`endif - -// Debug interface BRKx_CTL register -`ifdef BRK_MODE_RD -`undef BRK_MODE_RD -`endif -`ifdef BRK_MODE_WR -`undef BRK_MODE_WR -`endif -`ifdef BRK_MODE -`undef BRK_MODE -`endif -`ifdef BRK_EN -`undef BRK_EN -`endif -`ifdef BRK_I_EN -`undef BRK_I_EN -`endif -`ifdef BRK_RANGE -`undef BRK_RANGE -`endif - -// Basic clock module: BCSCTL1 Control Register -`ifdef DIVAx -`undef DIVAx -`endif - -// Basic clock module: BCSCTL2 Control Register -`ifdef SELMx -`undef SELMx -`endif -`ifdef DIVMx -`undef DIVMx -`endif -`ifdef SELS -`undef SELS -`endif -`ifdef DIVSx -`undef DIVSx -`endif - -// MCLK Clock gate -`ifdef MCLK_CGATE -`undef MCLK_CGATE -`endif - -// SMCLK Clock gate -`ifdef SMCLK_CGATE -`undef SMCLK_CGATE -`endif - -// -// DEBUG INTERFACE EXTRA CONFIGURATION -//====================================== - -// Debug interface: CPU version -`ifdef CPU_VERSION -`undef CPU_VERSION -`endif - -// Debug interface: Software breakpoint opcode -`ifdef DBG_SWBRK_OP -`undef DBG_SWBRK_OP -`endif - -// Debug UART interface auto data synchronization -`ifdef DBG_UART_AUTO_SYNC -`undef DBG_UART_AUTO_SYNC -`endif - -// Debug UART interface data rate -`ifdef DBG_UART_BAUD -`undef DBG_UART_BAUD -`endif -`ifdef DBG_DCO_FREQ -`undef DBG_DCO_FREQ -`endif -`ifdef DBG_UART_CNT -`undef DBG_UART_CNT -`endif - -// Debug interface selection -`ifdef DBG_UART -`undef DBG_UART -`endif -`ifdef DBG_JTAG -`undef DBG_JTAG -`endif - -// Enable/Disable the hardware breakpoint RANGE mode -`ifdef HWBRK_RANGE -`undef HWBRK_RANGE -`endif - -// Counter width for the debug interface UART -`ifdef DBG_UART_XFER_CNT_W -`undef DBG_UART_XFER_CNT_W -`endif - -// -// MULTIPLIER CONFIGURATION -//====================================== - -`ifdef MPY_16x16 -`undef MPY_16x16 -`endif -- cgit v1.2.3