XILINX FPGA的device dna获取方法和代码

这里就不对device DNA做过多的介绍了,直接上代码

本文分享一个针对XILINX FPGA获取device dna的代码,代码设计为通用设计,不管是57bit的DNA,还是96bit的DNA都可以使用该代码。关于DNA的用途等就不过多的阐述了。

模块接口如下

/*===============================================
//----------- Begin Cut here for device_dna Template ---//
//===============================================
// 获取FPGA device_DNA
//===============================================
device_dna #(
   .NDA_WIDE   (57   )  //DNA位宽 |只能选择57或者96 | 57对应A7系列 96对应UltraScale系列
)your_instance_name(
   .clk        (clk        ),  // input  wire [0         :0] |模块时钟输入
   .reset      (reset      ),  // input  wire [0         :0] |模块复位输入
   .start      (start      ),  // input  wire [0         :0] |开始信号输入
   .valid      (valid      ),  // output wire [0         :0] |返回结果有效标志输出
   .fpga_id    (fpga_id    )   // output wire [NDA_WIDE-1:0] |返回结果输出
);
// INST_TAG_END ------ End device_dna Template ---------
===============================================*/

接口说明如下

NDA_WIDE : DNA位宽             |只能选择57或者96 | 57对应A7系列 96对应UltraScale系列
clk      : 模块时钟输入         |10MHz - 100MHz的时钟都可以(我测试过的时钟范围)
reset    : 模块复位输入         |1: 复位 0: 无效
start    : 开始信号输入         |输入脉冲信号,至少维持一个输入时钟的高电平,模块内部对上升沿检测
valid    : 返回结果有效标志输出  |当返回结果有效时输出一个输入时钟的高电平
fpga_id  : 返回结果输出         |返回结果输出当valid未高时开始有效,直至下一次start上升沿

源码如下

//
// Company:
// Engineer: Zheng LiGuo
//
// Create Date: 2023/07/19
// Design Name: 
// Module Name: device_dna
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
/*===============================================
//----------- Begin Cut here for device_dna Template ---//
//===============================================
// 获取FPGA device_DNA
//===============================================
device_dna #(
   .NDA_WIDE   (57   )  //DNA位宽 |只能选择57或者96 | 57对应A7系列 96对应UltraScale系列
)your_instance_name(
   .clk        (clk        ),  // input  wire [0         :0] |模块时钟输入
   .reset      (reset      ),  // input  wire [0         :0] |模块复位输入
   .start      (start      ),  // input  wire [0         :0] |开始信号输入
   .valid      (valid      ),  // output wire [0         :0] |返回结果有效标志输出
   .fpga_id    (fpga_id    )   // output wire [NDA_WIDE-1:0] |返回结果输出
);
// INST_TAG_END ------ End device_dna Template ---------
===============================================*/
`resetall
`timescale 1ns / 1ps
module device_dna #(
   parameter   [7 :0]   NDA_WIDE   = 57      // DNA位宽 |只能选择57或者96 | 57对应A7系列 96对应UltraScale系列
)(
   input  wire                   clk      ,  // input  wire [0         :0] |模块时钟输入
   input  wire                   reset    ,  // input  wire [0         :0] |模块复位输入

   input  wire                   start    ,  // input  wire [0         :0] |开始信号输入
   output wire                   valid    ,  // output wire [0         :0] |返回结果有效标志输出
   output wire [NDA_WIDE-1:0]    fpga_id     // output wire [NDA_WIDE-1:0] |返回结果输出
);

//===============================================
// wire & reg 申明
//===============================================
   reg  [1:0]           start_r2 = 'd0;   // 开始信号缓存器
   reg                  run      = 'd0;   // 运行标志寄存器
   reg  [7:0]           time_cnt = 'd0;   // 时钟计数器
   reg  [NDA_WIDE-1:0]  dna_r    = 'd0;   // DNA寄存器
   wire     dout ;   //原语模块输出
   wire     read ;   //
   wire     shift;   //

//===============================================
// 时钟计数器标记申明
//===============================================
   localparam  [7:0]    flag_time1  = NDA_WIDE+8;   //读取结束标记点
   localparam  [7:0]    flag_time2  = NDA_WIDE+9;   //输出有效标记点

//===============================================
// 开始信号缓存器 |获取开始信号上升沿
//===============================================
   always @(posedge clk) start_r2 <= {start_r2[0],start};

//===============================================
// 运行标志寄存器 
//===============================================
   always @(posedge clk) begin
      if(reset)
         run <= 'd0;
      else if(start_r2 == 'b01)
         run <= 'd1;
      else if(time_cnt == flag_time1)
         run <= 'd0;
      else
         run <= run;
   end

//===============================================
// 时钟计数器 |辅助对获取的bit计数
//===============================================
   always @(posedge clk) begin
      if(run) begin
         time_cnt <= time_cnt+1;
      end else
         time_cnt <= 'd0;
   end

//===============================================
// NDA寄存器 |寄存读取的DNA数据
//===============================================
   always @(posedge clk) begin
      if(NDA_WIDE == 'd57)
         if(run)
            dna_r <= {dna_r[NDA_WIDE-2:0],dout};
         else
            dna_r <= dna_r;
      else if(NDA_WIDE == 'd96)
         if(run)
            dna_r <= {dout,dna_r[NDA_WIDE-1:1]};
         else
            dna_r <= dna_r;
      else 
         dna_r <= dna_r;
   end

//===============================================
// 原语调用 |根据输入的NDA_WIDE自动选择不同的原语
//===============================================
   generate if (NDA_WIDE == 'd57) begin: Artix_7
      DNA_PORT #(
         .SIM_DNA_VALUE(57'h123456789abcdef)  // Specifies a sample 57-bit DNA value for simulation
      )DNA_PORT_inst (
         .DOUT (dout ), // 1-bit output: DNA output data.
         .CLK  (clk  ), // 1-bit input: Clock input.
         .DIN  ('d0  ), // 1-bit input: User data input pin.
         .READ (read ), // 1-bit input: Active high load DNA, active low read input.
         .SHIFT(shift)  // 1-bit input: Active high shift enable input.
      );
   end else if (NDA_WIDE == 'd96) begin : Ultra_Scale
      DNA_PORTE2 #(
         .SIM_DNA_VALUE(96'hfedcba987654321012345678)  // Specifies a sample 96-bit DNA value for simulation
      ) DNA_PORTE2_inst (
         .DOUT (dout ),   // 1-bit output: DNA output data
         .CLK  (clk  ),     // 1-bit input: Clock input
         .DIN  ('d0  ),     // 1-bit input: User data input pin
         .READ (read ),   // 1-bit input: Active-High load DNA, active-Low read input
         .SHIFT(shift)  // 1-bit input: Active-High shift enable input
      );   
   end else 
      PULLUP PULLUP_inst (
      .O(dout)     // Pullup output (connect directly to top-level port)
      );
   endgenerate

//===============================================
// 驱动原语端口
//===============================================
   assign   read  = (time_cnt == 'd4) ? 'd1 :'d0;
   assign   shift = (time_cnt >= 'd9 && time_cnt <= flag_time1) ? 'd1 :'d0;

//===============================================
// 驱动模块输出端口
//===============================================
   assign   valid = (time_cnt == flag_time2) ? 'd1 : 'd0;
   assign   fpga_id = dna_r;

endmodule

关于仿真

在这里就不提供仿真的激励文件和仿真结果了,需要的朋友可以自行验证。

结束语

如果我的文章有帮助到您,希望能给我点个赞,或者收藏。谢谢

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值