Line 34... |
Line 34... |
//
|
//
|
// *Author(s):
|
// *Author(s):
|
// - Olivier Girard, olgirard@gmail.com
|
// - Olivier Girard, olgirard@gmail.com
|
//
|
//
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
// $Rev: 128 $
|
// $Rev: 134 $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedDate: 2011-12-16 22:05:46 +0100 (Fri, 16 Dec 2011) $
|
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
`ifdef OMSP_NO_INCLUDE
|
`ifdef OMSP_NO_INCLUDE
|
`else
|
`else
|
`include "openMSP430_defines.v"
|
`include "openMSP430_defines.v"
|
`endif
|
`endif
|
Line 56... |
Line 56... |
mb_wr, // Memory bus write transfer
|
mb_wr, // Memory bus write transfer
|
mdb_out, // Memory data bus output
|
mdb_out, // Memory data bus output
|
oscoff, // Turns off LFXT1 clock input
|
oscoff, // Turns off LFXT1 clock input
|
pc_sw, // Program counter software value
|
pc_sw, // Program counter software value
|
pc_sw_wr, // Program counter software write
|
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
|
scg1, // System clock generator 1. Turns off the SMCLK
|
|
|
// INPUTs
|
// INPUTs
|
dbg_halt_st, // Halt/Run status from CPU
|
dbg_halt_st, // Halt/Run status from CPU
|
dbg_mem_dout, // Debug unit data output
|
dbg_mem_dout, // Debug unit data output
|
Line 81... |
Line 82... |
inst_type, // Decoded Instruction type
|
inst_type, // Decoded Instruction type
|
mclk, // Main system clock
|
mclk, // Main system clock
|
mdb_in, // Memory data bus input
|
mdb_in, // Memory data bus input
|
pc, // Program counter
|
pc, // Program counter
|
pc_nxt, // Next PC value (for CALL & IRQ)
|
pc_nxt, // Next PC value (for CALL & IRQ)
|
puc_rst // Main system reset
|
puc_rst, // Main system reset
|
|
scan_enable // Scan enable (active during scan shifting)
|
);
|
);
|
|
|
// OUTPUTs
|
// OUTPUTs
|
//=========
|
//=========
|
output cpuoff; // Turns off the CPU
|
output cpuoff; // Turns off the CPU
|
Line 96... |
Line 98... |
output [1:0] mb_wr; // Memory bus write transfer
|
output [1:0] mb_wr; // Memory bus write transfer
|
output [15:0] mdb_out; // Memory data bus output
|
output [15:0] mdb_out; // Memory data bus output
|
output oscoff; // Turns off LFXT1 clock input
|
output oscoff; // Turns off LFXT1 clock input
|
output [15:0] pc_sw; // Program counter software value
|
output [15:0] pc_sw; // Program counter software value
|
output pc_sw_wr; // Program counter software write
|
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
|
output scg1; // System clock generator 1. Turns off the SMCLK
|
|
|
// INPUTs
|
// INPUTs
|
//=========
|
//=========
|
input dbg_halt_st; // Halt/Run status from CPU
|
input dbg_halt_st; // Halt/Run status from CPU
|
Line 123... |
Line 126... |
input mclk; // Main system clock
|
input mclk; // Main system clock
|
input [15:0] mdb_in; // Memory data bus input
|
input [15:0] mdb_in; // Memory data bus input
|
input [15:0] pc; // Program counter
|
input [15:0] pc; // Program counter
|
input [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
|
input [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
|
input puc_rst; // Main system reset
|
input puc_rst; // Main system reset
|
|
input scan_enable; // Scan enable (active during scan shifting)
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
|
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
|
//=============================================================================
|
//=============================================================================
|
Line 180... |
Line 184... |
.oscoff (oscoff), // Turns off LFXT1 clock input
|
.oscoff (oscoff), // Turns off LFXT1 clock input
|
.pc_sw (pc_sw), // Program counter software value
|
.pc_sw (pc_sw), // Program counter software value
|
.pc_sw_wr (pc_sw_wr), // Program counter software write
|
.pc_sw_wr (pc_sw_wr), // Program counter software write
|
.reg_dest (reg_dest), // Selected register destination content
|
.reg_dest (reg_dest), // Selected register destination content
|
.reg_src (reg_src), // Selected register source 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
|
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
|
.status (status), // R2 Status {V,N,Z,C}
|
.status (status), // R2 Status {V,N,Z,C}
|
|
|
// INPUTs
|
// INPUTs
|
.alu_stat (alu_stat), // ALU Status {V,N,Z,C}
|
.alu_stat (alu_stat), // ALU Status {V,N,Z,C}
|
Line 199... |
Line 204... |
.reg_pc_call (reg_pc_call), // Trigger PC update for a CALL instruction
|
.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_val (alu_out_add), // Stack Pointer next value
|
.reg_sp_wr (reg_sp_wr), // Stack Pointer write
|
.reg_sp_wr (reg_sp_wr), // Stack Pointer write
|
.reg_sr_clr (reg_sr_clr), // Status register clear for interrupts
|
.reg_sr_clr (reg_sr_clr), // Status register clear for interrupts
|
.reg_sr_wr (reg_sr_wr), // Status Register update for RETI instruction
|
.reg_sr_wr (reg_sr_wr), // Status Register update for RETI instruction
|
.reg_incr (reg_incr) // Increment source register
|
.reg_incr (reg_incr), // Increment source register
|
|
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
|
);
|
);
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// 3) SOURCE OPERAND MUXING
|
// 3) SOURCE OPERAND MUXING
|
Line 338... |
Line 344... |
// Memory address bus
|
// Memory address bus
|
assign mab = alu_out_add[15:0];
|
assign mab = alu_out_add[15:0];
|
|
|
// Memory data bus output
|
// Memory data bus output
|
reg [15:0] mdb_out_nxt;
|
reg [15:0] mdb_out_nxt;
|
always @(posedge mclk or posedge puc_rst)
|
|
|
`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;
|
if (puc_rst) mdb_out_nxt <= 16'h0000;
|
else if (e_state==`E_DST_RD) mdb_out_nxt <= pc_nxt;
|
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]) |
|
else if ((e_state==`E_EXEC & ~inst_so[`CALL]) |
|
(e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)) mdb_out_nxt <= alu_out;
|
(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;
|
assign mdb_out = inst_bw ? {2{mdb_out_nxt[7:0]}} : mdb_out_nxt;
|
|
|
// Format memory data bus input depending on BW
|
// Format memory data bus input depending on BW
|
reg mab_lsb;
|
reg mab_lsb;
|
Line 368... |
Line 390... |
if (puc_rst) mdb_in_buf_valid <= 1'b0;
|
if (puc_rst) mdb_in_buf_valid <= 1'b0;
|
else if (e_state==`E_EXEC) 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;
|
else if (mdb_in_buf_en) mdb_in_buf_valid <= 1'b1;
|
|
|
reg [15:0] mdb_in_buf;
|
reg [15:0] mdb_in_buf;
|
always @(posedge mclk or posedge puc_rst)
|
|
|
`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;
|
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;
|
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;
|
assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw;
|
|
|
|
|
endmodule // omsp_execution_unit
|
endmodule // omsp_execution_unit
|