URL
https://opencores.org/ocsvn/xgate/xgate/trunk
Subversion Repositories xgate
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 87 to Rev 88
- ↔ Reverse comparison
Rev 87 → Rev 88
/xgate/trunk/rtl/verilog/xgate_jtag.v
1,115 → 1,227
//////////////////////////////////////////////////////////////////////////////// |
// |
// XGATE Coprocessor - XGATE JTAG Module |
// |
// Author: Robert Hayes |
// rehayes@opencores.org |
// |
// Downloaded from: http://www.opencores.org/projects/xgate..... |
// |
//////////////////////////////////////////////////////////////////////////////// |
// Copyright (c) 2011, Robert Hayes |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// Supplemental terms. |
// * Redistributions of source code must retain the above copyright |
// notice, this list of conditions and the following disclaimer. |
// * Neither the name of the <organization> 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 Robert Hayes ''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 Robert Hayes 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. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
//////////////////////////////////////////////////////////////////////////////// |
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
|
// ----------------------------------------------------------------------------- |
// JTAG TAP Controller |
// ----------------------------------------------------------------------------- |
module xgate_jtag #(parameter IR_BITS = 4) // Number of Instruction Register Bits |
( |
output jtag_tdo, // JTAG Serial Output Data |
output jtag_tdo_en, // JTAG Serial Output Data tri-state enable |
output jtag_tdo, // JTAG Serial Output Data |
output jtag_tdo_en, // JTAG Serial Output Data tri-state enable |
|
input jtag_tdi, // JTAG Serial Input Data |
input jtag_clk, // JTAG Test clock |
input jtag_reset_n, // JTAG Async reset signal |
input jtag_tms // JTAG Test Mode Select |
input jtag_tdi, // JTAG Serial Input Data |
input jtag_clk, // JTAG Test clock |
input jtag_reset_n, // JTAG Async reset signal |
input jtag_tms, // JTAG Test Mode Select |
|
output extest, // JTAG Command for I/O control |
output clamp, // JTAG Command for I/O control |
output highz, // JTAG Command for I/O control |
output force_pul_lo, // JTAG Command for I/O control |
output force_pul_hi, // JTAG Command for I/O control |
|
output sel_bsd, // JTAG select the boundary scan register |
output sel_udi_1, // JTAG select the udi_1 (testmode control) register |
|
output capture_clk, // Shift and input capture clock |
output update_clk, // Load holding register |
output capture_dr, // Enable shift/capture register input loading, |
output update_dr, // Enable holding register input loading |
output shift_dr, // Select eather shift mode or parallel capture mode |
input bsd_so, // Serial data input from boundary scan chain |
input user1_so // Serial data input from user register |
); |
|
|
wire [3:0] jtag_state; |
wire [3:0] next_jtag_state; |
|
wire update_ir; |
wire capture_ir; |
wire shift_ir; |
wire update_dr; |
wire capture_dr; |
wire shift_dr; |
wire [IR_BITS-1:0] ir_reg; |
|
assign jtag_tdo = 1'b1; |
assign jtag_tdo_en = 1'b0; |
|
|
// Define clocks here, future enhansment would be to add scan clock mux |
// update_clk is output I/O clock and control register capture clock |
// capture_clock is input I/O clock and shifting clock |
assign update_clk = !jtag_clk; |
assign capture_clk = jtag_clk; |
|
// --------------------------------------------------------------------------- |
xgate_jtag_sm |
jtag_sm( |
.jtag_state(jtag_state), |
.next_jtag_state(next_jtag_state), |
.update_ir(update_ir), |
.capture_ir(capture_ir), |
.shift_ir(shift_ir), |
.update_dr(update_dr), |
.capture_dr(capture_dr), |
.shift_dr(shift_dr), |
.jtag_clk(jtag_clk), |
.jtag_reset_n(jtag_reset_n), |
.jtag_tms(jtag_tms) |
.jtag_state(jtag_state), |
.next_jtag_state(next_jtag_state), |
.update_ir(update_ir), |
.capture_ir(capture_ir), |
.shift_ir(shift_ir), |
.update_dr(update_dr), |
.capture_dr(capture_dr), |
.shift_dr(shift_dr), |
.capture_clk(capture_clk), |
.jtag_reset_n(jtag_reset_n), |
.jtag_tms(jtag_tms) |
); |
|
// --------------------------------------------------------------------------- |
xgate_jtag_ir #(.IR_BITS(IR_BITS)) |
jtag_ir( |
.update_ir(update_ir), |
.capture_ir(capture_ir), |
.shift_ir(shift_ir), |
.jtag_clk(jtag_clk), |
.jtag_tdi(jtag_tdi), |
.jtag_reset_n(jtag_reset_n), |
.jtag_tms(jtag_tms) |
.ir_reg(ir_reg), |
.ir_so(ir_so), |
.capture_clk(capture_clk), |
.update_clk(update_clk), |
.update_ir(update_ir), |
.capture_ir(capture_ir), |
.shift_ir(shift_ir), |
.jtag_tdi(jtag_tdi), |
.jtag_reset_n(jtag_reset_n) |
); |
|
|
// --------------------------------------------------------------------------- |
bc_2 |
gpio_0_bc2( |
.capture_clk(), |
.update_clk(), |
.capture_en(bsr_capture), |
.update_en(bsr_update), |
.shift_dr(bsr_shift), |
.mode(), |
.si(), |
.data_in(from_core_gpio_0), |
.reset_n(), |
.data_out(to_pad_gpio_0), |
.so(gpio_0_bc2_so) |
); |
xgate_instr_decode #(.IR_BITS(IR_BITS)) |
decoder( |
.bypass(bypass), |
.clamp(clamp), |
.highz(highz), |
.extest(extest), |
.force_pul_lo(force_pul_lo), |
.force_pul_hi(force_pul_hi), |
.sample(sample), |
.idcode(idcode), |
.usercode(usercode), |
.udi_1(udi_1), |
|
.sel_bypass(sel_bypass), |
.sel_bsd(sel_bsd), |
.sel_id(sel_id), |
.sel_udi_1(sel_udi_1), |
|
.ir_reg(ir_reg) |
); |
|
// --------------------------------------------------------------------------- |
xgate_bypass_reg |
tdi_bypass( |
.bypass_so(bypass_so), |
|
.jtag_tdi(jtag_tdi), |
.capture_clk(capture_clk), |
.jtag_reset_n(jtag_reset_n) |
); |
|
// --------------------------------------------------------------------------- |
xgate_id_reg |
chip_id( |
.id_so(id_so), |
|
.jtag_tdi(jtag_tdi), |
.capture_clk(capture_clk), |
.capture_dr(capture_dr), |
.shift_dr(shift_dr), |
.idcode(idcode), |
.usercode(usercode), |
.jtag_reset_n(jtag_reset_n) |
); |
|
// --------------------------------------------------------------------------- |
xgate_tdo_mux |
tdo_out( |
.sel_bypass(sel_bypass), |
.sel_bsd(sel_bsd), |
.sel_id(sel_id), |
.sel_udi_1(sel_udi_1), |
|
.bypass_so(bypass_so), |
.bsd_so(bsd_so), |
.user1_so(user1_so), |
.id_so(id_so), |
.ir_so(ir_so), |
|
.shift_dr(shift_dr), |
.shift_ir(shift_ir), |
.update_clk(update_clk), |
.jtag_reset_n(jtag_reset_n), |
|
.jtag_tdo(jtag_tdo), |
.jtag_tdo_en(jtag_tdo_en) |
); |
|
endmodule // xgate_jtag |
|
|
// ----------------------------------------------------------------------------- |
// JTAG TAP State Machine |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
|
module xgate_jtag_sm |
( |
output reg [3:0] jtag_state, // JTAG State |
output reg [3:0] next_jtag_state, // Pseudo Register for JTAG next state logic |
output reg [3:0] jtag_state, // JTAG State |
output reg [3:0] next_jtag_state, // Pseudo Register for JTAG next state logic |
|
output update_ir, |
output capture_ir, |
output shift_ir, |
output update_ir, |
output capture_ir, |
output shift_ir, |
|
output update_dr, |
output capture_dr, |
output shift_dr, |
output update_dr, |
output capture_dr, |
output shift_dr, |
|
input jtag_clk, // JTAG Test clock |
input jtag_reset_n, // JTAG Async reset signal |
input jtag_tms // JTAG Test Mode Select |
input capture_clk, // JTAG Test clock |
input jtag_reset_n, // JTAG Async reset signal |
input jtag_tms // JTAG Test Mode Select |
); |
|
parameter RESET = 4'b0000, |
RUN_TEST_IDLE = 4'b1000, |
SEL_DR_SCAN = 4'b0001, |
CAPTURE_DR = 4'b0010, |
SHIFT_DR = 4'b0011, |
EXIT1_DR = 4'b0100, |
PAUSE_DR = 4'b0101, |
EXIT2_DR = 4'b0110, |
UPDATE_DR = 4'b0111, |
SEL_IR_SCAN = 4'b1001, |
CAPTURE_IR = 4'b1010, |
SHIFT_IR = 4'b1011, |
EXIT1_IR = 4'b1100, |
PAUSE_IR = 4'b1101, |
EXIT2_IR = 4'b1110, |
UPDATE_IR = 4'b1111; |
parameter RESET = 4'hF, |
RUN_TEST_IDLE = 4'hC, |
SEL_DR_SCAN = 4'h7, |
CAPTURE_DR = 4'h6, |
SHIFT_DR = 4'h2, |
EXIT1_DR = 4'h1, |
PAUSE_DR = 4'h3, |
EXIT2_DR = 4'h0, |
UPDATE_DR = 4'h5, |
SEL_IR_SCAN = 4'h4, |
CAPTURE_IR = 4'hE, |
SHIFT_IR = 4'hA, |
EXIT1_IR = 4'h9, |
PAUSE_IR = 4'hB, |
EXIT2_IR = 4'h8, |
UPDATE_IR = 4'hD; |
|
assign update_ir = jtag_state == UPDATE_IR; |
assign capture_ir = jtag_state == CAPTURE_IR; |
120,14 → 232,14
assign shift_dr = jtag_state == SHIFT_DR; |
|
|
// Define the JTAG State Register |
always @(posedge jtag_clk or negedge jtag_reset_n) |
// Define the JTAG State Register |
always @(posedge capture_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
jtag_state <= RESET; |
else |
jtag_state <= next_jtag_state; |
|
// Define the JTAG State Transitions |
// Define the JTAG State Transitions |
always @* |
begin |
case(jtag_state) |
171,27 → 283,29
|
|
// ----------------------------------------------------------------------------- |
// JTAG TAP Instruction Register |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
|
module xgate_jtag_ir #(parameter IR_BITS = 4) // Number of Instruction Register Bits |
( |
output reg [IR_BITS-1:0] ir_reg, |
output reg [IR_BITS-1:0] ir_reg, |
output ir_so, // IR shift out |
|
input update_ir, |
input capture_ir, |
input shift_ir, |
input update_ir, |
input capture_ir, |
input shift_ir, |
|
input jtag_tdi, // JTAG Serial Input Data |
input jtag_clk, // JTAG Test clock |
input jtag_reset_n, // JTAG Async reset signal |
input jtag_tms // JTAG Test Mode Select |
input jtag_tdi, // JTAG Serial Input Data |
input capture_clk, // JTAG Test clock |
input update_clk, |
input jtag_reset_n // JTAG Async reset signal |
); |
|
reg [IR_BITS-1:0] ir_shift_reg; |
|
// JTAG Instruction Shift Register |
always @(posedge jtag_clk or negedge jtag_reset_n) |
assign ir_so = ir_shift_reg[0]; |
|
// JTAG Instruction Shift Register |
always @(posedge capture_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
ir_shift_reg <= 0; |
else if (capture_ir) |
199,90 → 313,209
else if (shift_ir) |
ir_shift_reg <= {jtag_tdi, ir_shift_reg[(IR_BITS-1):1]}; |
|
// JTAG Instruction Register |
always @(posedge jtag_clk or negedge jtag_reset_n) |
// JTAG Instruction Register |
always @(posedge update_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
ir_reg <= 0; |
ir_reg <= {IR_BITS{1'b1}}; // Make the default instruction BYPASS |
else if (update_ir) |
ir_reg <= ir_shift_reg; |
|
|
endmodule // xgate_jtag_ir |
|
|
// ----------------------------------------------------------------------------- |
// JTAG Bypass Register |
// ----------------------------------------------------------------------------- |
module xgate_bypass_reg |
( |
output reg bypass_so, |
|
input jtag_tdi, // JTAG Serial Input Data |
input capture_clk, // JTAG Test clock |
input jtag_reset_n // JTAG Async reset signal |
); |
|
// JTAG Bypass Register |
always @(posedge capture_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
bypass_so <= 0; |
else |
bypass_so <= jtag_tdi; |
|
endmodule // xgate_bypass_reg |
|
|
// ----------------------------------------------------------------------------- |
|
module test_mode_cntrl #(parameter NUM_BITS = 10) |
// JTAG ID Register |
// ----------------------------------------------------------------------------- |
module xgate_id_reg #(parameter NUM_BITS = 32) |
( |
// OUTPUT |
output so, |
output reg [NUM_BITS-1:0] mode_bits, |
output id_so, |
|
// INPUTs |
input [NUM_BITS-1:0] obs_in, |
input si, |
input capture_clk, |
input update_clk, |
input capture_en, |
input update_en, |
input inst_en, |
input shift_en, |
input reset_n |
input jtag_tdi, // JTAG Serial Input Data |
input capture_clk, |
input capture_dr, |
input shift_dr, |
input idcode, |
input usercode, |
input jtag_reset_n // JTAG Async reset signal |
); |
|
parameter user_code_val = 32'ha596_c3f0; |
parameter version = 4'h1; |
parameter part_num = 16'h1105; |
parameter manufacture_id = 11'h00f; |
|
reg [NUM_BITS-1:0] shift_reg; |
reg [NUM_BITS-1:0] id_shifter; |
|
wire [NUM_BITS-1:0] din_mux = shift_en ? {shift_reg[NUM_BITS-1:1], si} : obs_in; |
wire [NUM_BITS-1:0] cap_mux = capture_en ? shift_reg : din_mux; |
wire [NUM_BITS-1:0] update_mux = update_en ? shift_reg : mode_bits; |
wire [NUM_BITS-1:0] jtag_id = {version, part_num, manufacture_id, 1'b1}; |
wire [NUM_BITS-1:0] sel_mux = ({NUM_BITS{idcode}} & jtag_id) | ({NUM_BITS{usercode}} & user_code_val); |
wire [NUM_BITS-1:0] din_mux = shift_dr ? {jtag_tdi, id_shifter[(NUM_BITS-1):1]} : jtag_id; |
|
always @(posedge capture_clk or negedge reset_n) |
if (!reset_n) |
shift_reg <= 0; |
else if (inst_en) |
shift_reg <= cap_mux; |
wire capture_en = (idcode || usercode) && (capture_dr || shift_dr); |
|
always @(posedge update_clk or negedge reset_n) |
if (!reset_n) |
mode_bits <= 0; |
else if (inst_en) |
mode_bits <= update_mux; |
// JTAG Id Register |
always @(posedge capture_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
id_shifter <= 0; |
else if (capture_en) |
id_shifter <= din_mux; |
|
assign so = shift_reg[NUM_BITS-1]; |
assign id_so = id_shifter[0]; |
|
endmodule // |
endmodule // xgate_id_reg |
|
|
// ----------------------------------------------------------------------------- |
// JTAG Instruction decoder of the IR Register |
// ----------------------------------------------------------------------------- |
module xgate_instr_decode #(parameter IR_BITS = 4) // Number of Instruction Register Bits |
( |
output reg bypass, |
output reg clamp, |
output reg highz, |
output reg extest, |
output reg force_pul_lo, |
output reg force_pul_hi, |
output reg sample, |
output reg idcode, |
output reg usercode, |
output reg udi_1, |
|
output sel_bypass, |
output sel_bsd, |
output sel_id, |
output sel_udi_1, |
|
input [IR_BITS-1:0] ir_reg |
); |
|
assign sel_bypass = bypass || clamp || highz || force_pul_lo || force_pul_hi; |
assign sel_bsd = extest || sample; |
assign sel_id = idcode || usercode; |
assign sel_udi_1 = udi_1; |
|
always @* |
begin |
bypass = 0; |
clamp = 0; |
highz = 0; |
extest = 0; |
force_pul_lo = 0; |
force_pul_hi = 0; |
sample = 0; |
idcode = 0; |
usercode = 0; |
udi_1 = 0; |
casez (ir_reg) |
4'b0110: clamp = 1; |
4'b0101: highz = 1; |
4'b0000: extest = 1; |
4'b1001: force_pul_lo = 1; |
4'b1010: force_pul_hi = 1; |
4'b0111: sample = 1; |
4'b0001: idcode = 1; |
4'b0011: usercode = 1; |
4'b1100: udi_1 = 1; |
default: bypass = 1; |
endcase |
end |
|
endmodule // xgate_instr_decode |
|
|
// ----------------------------------------------------------------------------- |
// JTAG Test Data Output mux |
// ----------------------------------------------------------------------------- |
module xgate_tdo_mux |
( |
input sel_bypass, |
input sel_bsd, |
input sel_id, |
input sel_udi_1, |
|
input bypass_so, |
input bsd_so, |
input id_so, |
input user1_so, |
input ir_so, |
|
input shift_dr, |
input shift_ir, |
input update_clk, |
input jtag_reset_n, |
|
output reg jtag_tdo, |
output reg jtag_tdo_en |
); |
|
wire bypass_gate = shift_dr && sel_bypass && bypass_so; |
wire bsd_gate = shift_dr && sel_bsd && bsd_so; |
wire id_gate = shift_dr && sel_id && id_so; |
wire udi_1_gate = shift_dr && sel_udi_1 && user1_so; |
wire ir_gate = shift_ir && ir_so; |
|
wire jtag_tdo_mux = bypass_gate || bsd_gate || id_gate || udi_1_gate || ir_gate; |
|
// JTAG TDO Retiming Register |
always @(posedge update_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
jtag_tdo <= 0; |
else |
jtag_tdo <= jtag_tdo_mux; |
|
// JTAG Output Enable Register |
always @(posedge update_clk or negedge jtag_reset_n) |
if (!jtag_reset_n) |
jtag_tdo_en <= 0; |
else |
jtag_tdo_en <= shift_dr || shift_ir; |
|
endmodule // xgate_tdo_mux |
|
|
// ----------------------------------------------------------------------------- |
// Boundary Scan Cell #7 |
// ----------------------------------------------------------------------------- |
module bc_7 |
( |
input capture_clk, |
input update_clk, |
input capture_en, |
input update_en, |
input shift_dr, |
input mode1, |
input si, |
input pin_input, |
input control_out, |
input output_data, |
input reset_n, |
( |
input capture_clk, // Shift and input capture clock |
input update_clk, // Load holding register |
input capture_en, // Enable shift/capture register parallel input loading, |
input update_en, // Enable holding register input loading |
input shift_dr, // Select eather shift mode or parallel capture mode |
input mode, // Select test mode or mission mode control of pad |
input si, // Serial data input |
input pin_input, // Mission mode input from pin |
input control_out, // Signal from bc_2 module controlling output enable pin |
input output_data, // mission mode data in from core |
input reset_n, // reset |
|
output ic_input, |
output data_out, |
output reg so |
output data_out, // Final data to pad |
output reg so // Serial data out |
); |
|
reg data_reg; |
reg enable_reg; |
reg control_reg; |
reg so_0; |
|
// Shift register |
always @(posedge capture_clk or negedge reset_n) |
289,7 → 522,7
if (!reset_n) |
so <= 0; |
else if (capture_en) |
so <= shift_dr ? si : ((!control_out || mode1) ? pin_input : output_data); |
so <= shift_dr ? si : ((!control_out || mode) ? pin_input : output_data); |
|
// Holding register |
always @(posedge update_clk or negedge reset_n) |
304,23 → 537,22
|
|
// ----------------------------------------------------------------------------- |
// Boundary Scan Cell #2 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
|
module bc_2 |
( |
input capture_clk, // Shift and input capture clock |
input update_clk, // Load holding register |
input capture_en, // Enable shift/capture register input loading, |
input update_en, // Enable holding register input loading |
input shift_dr, // Select eather shift mode or parallel capture mode |
input mode, // Select test mode or mission mode output |
input si, // Serial data input |
input data_in, // Mission mode input |
input reset_n, // reset |
( |
input capture_clk, // Shift and input capture clock |
input update_clk, // Load holding register |
input capture_en, // Enable shift/capture register parallel input loading |
input update_en, // Enable holding register input loading |
input shift_dr, // Select eather shift mode or parallel capture mode |
input mode, // Select test mode or mission mode control of pad |
input si, // Serial data input |
input data_in, // Mission mode input |
input reset_n, // reset |
|
output data_out, // Final data to pad |
output reg so // Serial data out |
output data_out, // Final data to pad |
output reg so // Serial data out |
); |
|
reg data_reg; |
342,3 → 574,5
assign data_out = mode ? data_reg : data_in; |
|
endmodule // bc_2 |
|
|