这里就不对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
关于仿真
在这里就不提供仿真的激励文件和仿真结果了,需要的朋友可以自行验证。
结束语
如果我的文章有帮助到您,希望能给我点个赞,或者收藏。谢谢