⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 userbscan.v

📁 xilinx FPGA上使用jtag接口作为用户IO的源码。支持任意位宽度。
💻 V
字号:


/*
   Author : ycc
   userbscan 将JTAG user串行扫描信号变为并行。
   DRCK   : user jtag 时钟
   SEL    : user jtag 选通信号
   SHIFT  : user jtag 移位状态指示信号
   UPDATE : user jtag 移位结束信号
   以上信号皆在 DRCK 驱动下变化。

   clk    : 外部时钟,该时钟应该足够快,能检测出一个 DRCK 周期的脉冲
   data   : 数据输出
   databack : 数据回读
   wr     : 在 clk 驱动下的移位结束信号

   DATA_WIDTH : 数据宽度,默认为 16 bits
   
   note : ChipScope use the same JTAG chain. 
   how to use?
   
   you must initlize BSCAN_*** and userbscan:
   BSCAN_SPARTAN2 BSCAN_SPARTAN2_inst (      .DRCK1(DRCK1),     // Data register output for USER1 functions      .DRCK2(DRCK2),     // Data register output for USER2 functions      .RESET(RESET),     // Reset output from TAP controller      .SEL1(SEL1),       // USER1 active output      .SEL2(SEL2),       // USER2 active output      .SHIFT(SHIFT),     // SHIFT output from TAP controller      .TDI(TDI),         // TDI output from TAP controller      .UPDATE(UPDATE),   // UPDATE output from TAP controller      .TDO1(TDO1),       // Data input for USER1 function      .TDO2(TDO2)        // Data input for USER2 function   );
   wire [7:0] bscan_data;
   wire [7:0] bscan_databack;

   userbscan #(8) userbscan_inst (
      .DRCK     ( DRCK2 ),
      .SEL      ( SEL2 ),
      .SHIFT    ( SHIFT ),
      .UPDATE   ( UPDATE ),
      .TDI      ( TDI ),
      .TDO      ( TDO2 ),
      .clk      ( clk ),
      .data     ( bscan_data ),
      .databack ( bscan_databack ),
      .wr       ( bscan_wr )
   );   
   
*/

module userbscan(DRCK,SEL,SHIFT,UPDATE,TDI,TDO,clk,data,databack,wr);
   parameter DATA_WIDTH = 8;
   input     DRCK,SEL,SHIFT,UPDATE,TDI ;
   output    TDO ;
   input     clk;
   output    wr;
   output reg  [ DATA_WIDTH-1 : 0 ] data ;     
   input       [ DATA_WIDTH-1 : 0 ] databack ;     

   reg         [ DATA_WIDTH-1 : 0 ] databack_d ;     
   reg         [ DATA_WIDTH-1 : 0 ] usr_bscan = 'h55aa;

   //推荐使用 bufg 来过滤 DRCK 时钟
   wire DRCKbuf;
   BUFG BUFG_inst_DRCK(
      .I( DRCK    ),
      .O( DRCKbuf )
   );

   // 串行移位逻辑

   assign TDO = usr_bscan[0];
   always@(posedge DRCKbuf) begin
      if(SEL)begin    
         if(SHIFT)  begin
            //移位状态时,将TDI移入最高位
            usr_bscan <= { TDI,usr_bscan[7:1] };
         end else begin       
            //在非移位状态下,总是捕获数据
            usr_bscan <= databack_d;    
         end
      end
   end

   //在 clk 驱动下, DRCK 的下降沿捕获数据到捕获缓冲寄存器 databack_d
   //防止在捕获外部数据时竞争冒险
   reg  DRCK_d,DRCK_dd;
   always@(posedge clk) begin
      DRCK_d  <= DRCKbuf;
      DRCK_dd <= DRCK_d;
   end
   wire DRCK_f = ( ~DRCK_d && DRCK_dd );
   always@(posedge clk) begin
      if( SEL && ~SHIFT && DRCK_f) databack_d <= databack ;
   end

/*
   检测 UPDATE 的上升下降沿
   上升沿将移位寄存器数据同步给输出寄存器
   下降沿输出给外部逻辑
*/

   reg UPDATE_d,UPDATE_dd;
   always@(posedge clk) begin
      UPDATE_d <= UPDATE;
      UPDATE_dd <= UPDATE_d;
   end
   wire UPDATE_r = (  UPDATE_d & ~UPDATE_dd) ;
   wire UPDATE_f = ( ~UPDATE_d &  UPDATE_dd) ;

   always@(posedge clk) begin
      if (SEL==1'b1 && UPDATE_r) begin
         data <= usr_bscan;
      end
   end
   assign wr = UPDATE_f ;

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -