OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [rtl/] [verilog/] [components/] [tap/] [tap.v] - Rev 18

Compare with Previous | Blame | View Log

`include "tap_defines.v"
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
// TAP controller 
// -------------- 
// Fully JTAG compliant (IEEE Std 1149.1-2001) 
// Includes mandatory BYPASS register and optional ID register 
// Support for external mandatory BOUNDARY SCAN register 
// Support for external optional MEMORY BIST and DEBUG registers 
 
module tap
(
    // JTAG I/O pads
    tms_pad_i               , // JTAG Test Mode Select pad                    
    tck_pad_i               , // JTAG Test ClocK pad                          
    tck_neg_pad_i           , // JTAG Test ClocK negated pad                          
    trst_neg_pad_i          , // JTAG Test ReSeT negated pad                          
    tdi_pad_i               , // JTAG Test Data Input pad                     
    tdo_pad_o               , // JTAG Test Data Output pad                    
    tdo_padoe_o             , // output enable for JTAG Test Data Output pad 
    // TAP states
    capture_dr_o            ,
    shift_dr_o              ,
    pause_dr_o              , 
    update_dr_o             ,
    run_test_idle_o         , 
    test_logic_reset_o      ,
    // external TAP registers select signals 
    extest_select_o         , 
    sample_preload_select_o ,
    debug_select_o          ,
    mbist_select_o          ,
    // TDO signal for external TAP resgisters 
    tdo_o                   , 
    // TDI signals from external TAP resgisters 
    bscan_tdi_i             , // from boundary scan register 
    debug_tdi_i             , // from debug register (module)
    mbist_tdi_i               // from memory bist register 
) ;
 
 
// JTAG I/O pads
input           tms_pad_i               ; // JTAG Test Mode Select pad
input           tck_pad_i               ; // JTAG Test ClocK pad
input           tck_neg_pad_i           ; // JTAG Test ClocK negated pad
input           trst_neg_pad_i          ; // JTAG Test ReSeT negated pad
input           tdi_pad_i               ; // JTAG Test Data Input pad
output          tdo_pad_o               ; // JTAG Test Data Output pad
output          tdo_padoe_o             ; // output enable for JTAG Test Data Output pad 
// TAP states
output          capture_dr_o            ;
output          shift_dr_o              ;
output          pause_dr_o              ;
output          update_dr_o             ;
output          run_test_idle_o         ;
output          test_logic_reset_o      ;
// external TAP registers select signals 
output          extest_select_o         ;
output          sample_preload_select_o ;
output          debug_select_o          ;
output          mbist_select_o          ;
// TDO signal for external TAP resgisters 
output          tdo_o                   ;
// TDI signals from external TAP resgisters 
input           bscan_tdi_i             ; // from boundary scan register 
input           debug_tdi_i             ; // from debug register (module)
input           mbist_tdi_i             ; // from memory bist register  
 
 
reg             tdo_pad_o               ;
reg             tdo_padoe_o             ;
 
 
 
// internal signals 
reg             test_logic_reset        ;
reg             run_test_idle           ;
reg             select_dr_scan          ;
reg             capture_dr              ;
reg             shift_dr                ;
reg             exit1_dr                ;
reg             pause_dr                ;
reg             exit2_dr                ;
reg             update_dr               ;
reg             select_ir_scan          ;
reg             capture_ir              ;
reg             shift_ir                ;
reg             exit1_ir                ;
reg             pause_ir                ;
reg             exit2_ir                ;
reg             update_ir               ;
 
reg     [ 3: 0] jtag_inst_reg           ;
reg     [ 3: 0] latched_jtag_inst_reg   ;
reg     [31: 0] jtag_id_reg             ;
reg             jtag_bypass_reg         ;
 
reg             extest_select           ;
reg             sample_preload_select   ;
reg             id_reg_select           ;
reg             mbist_select            ;
reg             debug_select            ;
reg             bypass_reg_select       ;
 
reg             tms_q1                  ;
reg             tms_q2                  ;
reg             tms_q3                  ;
reg             tms_q4                  ;
wire            tms_reset               ;
 
 
 
//=============================================================================
//
// TMS Reset control logic 
//      5 consecutive logic '1' on TMS input causes reset 
//      
//=============================================================================
 
// registering TMS 
always @(posedge tck_pad_i)
    begin
        tms_q1 <= tms_pad_i ;
        tms_q2 <= tms_q1    ;
        tms_q3 <= tms_q2    ;
        tms_q4 <= tms_q3    ;
    end
 
// TMS reset 
assign  tms_reset = tms_q1 & tms_q2 & tms_q3 & tms_q4 & tms_pad_i ; 
 
 
//=============================================================================
//
// TAP State Machine 
// 
//=============================================================================
 
// test_logic_reset state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            test_logic_reset <= 1'b1 ;
        else if (tms_reset)
            test_logic_reset <= 1'b1 ;
        else begin
            if (tms_pad_i & (test_logic_reset | select_ir_scan))
                test_logic_reset <= 1'b1 ;
            else
                test_logic_reset <= 1'b0 ;
        end
    end
 
// run_test_idle state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            run_test_idle <= 1'b0 ;
        else if (tms_reset)
            run_test_idle <= 1'b0 ;
        else begin
            if (~tms_pad_i & (test_logic_reset | run_test_idle | update_dr | update_ir))
                run_test_idle <= 1'b1 ;
            else
                run_test_idle <= 1'b0 ;
        end
    end
 
// select_dr_scan state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            select_dr_scan <= 1'b0 ;
        else if (tms_reset)
            select_dr_scan <= 1'b0 ;
        else begin
            if (tms_pad_i & (run_test_idle | update_dr | update_ir))
                select_dr_scan <= 1'b1 ;
            else
                select_dr_scan <= 1'b0 ;
        end
    end
 
// capture_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            capture_dr <= 1'b0 ;
        else if (tms_reset)
            capture_dr <= 1'b0 ;
        else begin
            if (~tms_pad_i & select_dr_scan)
                capture_dr <= 1'b1 ;
            else
                capture_dr <= 1'b0 ;
        end
    end
 
// shift_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            shift_dr <= 1'b0 ;
        else if (tms_reset)
            shift_dr <= 1'b0 ;
        else begin
            if (~tms_pad_i & (capture_dr | shift_dr | exit2_dr))
                shift_dr <= 1'b1 ;
            else
                shift_dr <= 1'b0 ;
        end
    end
 
// exit1_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            exit1_dr <= 1'b0 ;
        else if (tms_reset)
            exit1_dr <= 1'b0 ;
        else begin
            if (tms_pad_i & (capture_dr | shift_dr))
                exit1_dr <= 1'b1 ;
            else
                exit1_dr <= 1'b0 ;
        end
    end
 
// pause_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            pause_dr <= 1'b0 ;
        else if (tms_reset)
            pause_dr <= 1'b0 ;
        else begin
            if (~tms_pad_i & (exit1_dr | pause_dr))
                pause_dr <= 1'b1 ;
            else
                pause_dr <= 1'b0 ;
        end
    end
 
// exit2_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            exit2_dr <= 1'b0 ;
        else if (tms_reset)
            exit2_dr <= 1'b0 ;
        else begin
            if (tms_pad_i & pause_dr)
                exit2_dr <= 1'b1 ;
            else
                exit2_dr <= 1'b0 ;
        end
    end
 
// update_dr state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            update_dr <= 1'b0 ;
        else if (tms_reset)
            update_dr <= 1'b0 ;
        else begin
            if (tms_pad_i & (exit1_dr | exit2_dr))
                update_dr <= 1'b1 ;
            else
                update_dr <= 1'b0 ;
        end
    end
 
// select_ir_scan state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            select_ir_scan <= 1'b0 ;
        else if (tms_reset)
            select_ir_scan <= 1'b0 ;
        else begin
            if (tms_pad_i & select_dr_scan)
                select_ir_scan <= 1'b1 ;
            else
                select_ir_scan <= 1'b0 ;
        end
    end
 
// capture_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            capture_ir <= 1'b0 ;
        else if (tms_reset)
            capture_ir <= 1'b0 ;
        else begin
            if (~tms_pad_i & select_ir_scan)
                capture_ir <= 1'b1 ;
            else
                capture_ir <= 1'b0 ;
        end
    end
 
// shift_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            shift_ir <= 1'b0 ;
        else if (tms_reset)
            shift_ir <= 1'b0 ;
        else begin
            if (~tms_pad_i & (capture_ir | shift_ir | exit2_ir))
                shift_ir <= 1'b1 ;
            else
                shift_ir <= 1'b0 ;
        end
    end
 
// exit1_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            exit1_ir <= 1'b0 ;
        else if (tms_reset)
            exit1_ir <= 1'b0 ;
        else begin
            if (tms_pad_i & (capture_ir | shift_ir))
                exit1_ir <= 1'b1 ;
            else
                exit1_ir <= 1'b0 ;
        end
    end
 
// pause_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            pause_ir <= 1'b0 ;
        else if (tms_reset)
            pause_ir <= 1'b0 ;
        else begin
            if (~tms_pad_i & (exit1_ir | pause_ir))
                pause_ir <= 1'b1 ;
            else
                pause_ir <= 1'b0 ;
        end
    end
 
// exit2_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            exit2_ir <= 1'b0 ;
        else if (tms_reset)
            exit2_ir <= 1'b0 ;
        else begin
            if (tms_pad_i & pause_ir)
                exit2_ir <= 1'b1 ;
            else
                exit2_ir <= 1'b0 ;
        end
    end
 
// update_ir state
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            update_ir <= 1'b0 ;
        else if (tms_reset)
            update_ir <= 1'b0 ;
        else begin
            if (tms_pad_i & (exit1_ir | exit2_ir))
                update_ir <= 1'b1 ;
            else
                update_ir <= 1'b0 ;
        end
    end
 
 
//=============================================================================
//
// JTAG Instruction Register (jtag_inst_reg) 
//      
//=============================================================================
 
// jtag_inst_reg
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            jtag_inst_reg <= 4'b0 ;
        else if (capture_ir)
            jtag_inst_reg <= 4'b0101 ; // This value is fixed for easier fault detection
        else if (shift_ir)
            jtag_inst_reg <= {tdi_pad_i, jtag_inst_reg[3:1]} ;
    end
 
// latched_jtag_inst_reg 
always @(posedge tck_neg_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            latched_jtag_inst_reg <= `TAP_IDCODE ;   // IDCODE selected after reset
        else if (test_logic_reset)
            latched_jtag_inst_reg <= `TAP_IDCODE ;   // IDCODE selected 
        else if (update_ir)
            latched_jtag_inst_reg <= jtag_inst_reg ;
    end
 
 
//=============================================================================
//
// JTAG ID Register (jtag_id_reg) 
//      
//=============================================================================
 
always @(posedge tck_pad_i)
    begin
        if (id_reg_select & shift_dr)
            jtag_id_reg <= {tdi_pad_i, jtag_id_reg[31:1]} ;
        else
            jtag_id_reg <= `TAP_IDCODE_VALUE ;
    end
 
 
//=============================================================================
//
// JTAG Bypass Register (jtag_bypass_reg) 
//      
//=============================================================================
 
always @(posedge tck_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            jtag_bypass_reg <= 1'b0 ;
        else if (capture_dr)
            jtag_bypass_reg <= 1'b0 ;
        else if (shift_dr)
            jtag_bypass_reg <= tdi_pad_i ;
    end
 
 
//=============================================================================
//
// TAP register selection  
//      
//=============================================================================
 
always @(latched_jtag_inst_reg)
    begin
        extest_select           = 1'b0 ;
        sample_preload_select   = 1'b0 ;
        id_reg_select           = 1'b0 ;
        mbist_select            = 1'b0 ;
        debug_select            = 1'b0 ;
        bypass_reg_select       = 1'b0 ;
 
        case (latched_jtag_inst_reg) 
            `TAP_EXTEST         : extest_select         = 1'b1 ; // External test
            `TAP_SAMPLE_PRELOAD : sample_preload_select = 1'b1 ; // Sample preload
            `TAP_IDCODE         : id_reg_select         = 1'b1 ; // ID Code
            `TAP_MBIST          : mbist_select          = 1'b1 ; // Mbist test
            `TAP_DEBUG          : debug_select          = 1'b1 ; // Debug
            `TAP_BYPASS         : bypass_reg_select     = 1'b1 ; // BYPASS
            default             : bypass_reg_select     = 1'b1 ; // BYPASS
        endcase
    end
 
 
//=============================================================================
//
// Multiplexing JTAG TDO 
//      JTAG outputs have to be registered on falling edge of TCK 
//      
//=============================================================================
 
// JTAG Test Data Output 
always @(posedge tck_neg_pad_i or posedge trst_neg_pad_i)
    begin
        if (trst_neg_pad_i)
            tdo_pad_o <= 1'b1 ;
        else begin
            if (shift_ir)
                tdo_pad_o <= jtag_inst_reg[0] ;
            else begin
                case (latched_jtag_inst_reg)
                    `TAP_IDCODE         : tdo_pad_o <= jtag_id_reg      ;
                    `TAP_DEBUG          : tdo_pad_o <= debug_tdi_i      ;
                    `TAP_SAMPLE_PRELOAD : tdo_pad_o <= bscan_tdi_i      ;
                    `TAP_EXTEST         : tdo_pad_o <= bscan_tdi_i      ;
                    `TAP_MBIST          : tdo_pad_o <= mbist_tdi_i      ;
                    default             : tdo_pad_o <= jtag_bypass_reg  ;
                endcase
            end
        end
    end
 
// output enable for JTAG Test Data Output 
always @(posedge tck_neg_pad_i)
    begin
        tdo_padoe_o <= shift_ir | shift_dr ;
    end
 
 
//=============================================================================
//
// Output assignments for external TAP registers 
//      External registers need to know when they are selected and in which 
//      specific state TAP controller is when operating with Data Register. 
//      
//=============================================================================
 
// TAP data register state assignments 
assign  capture_dr_o        = capture_dr        ;
assign  shift_dr_o          = shift_dr          ;
assign  pause_dr_o          = pause_dr          ;
assign  update_dr_o         = update_dr         ;
assign  run_test_idle_o     = run_test_idle     ;
assign  test_logic_reset_o  = test_logic_reset  ;
 
// external TAP register select assignments 
assign  extest_select_o         = extest_select         ;
assign  sample_preload_select_o = sample_preload_select ;
assign  mbist_select_o          = mbist_select          ;
assign  debug_select_o          = debug_select          ;
 
// TDO for external TAP register assignment 
assign  tdo_o = tdi_pad_i ;
 
 
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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