欲观原文,请君移步
Xilinx FPGA都有一个独特的 ID ,也就是 Device DNA ,这个 ID 相当于我们的身份证,在 FPGA 芯片生产的时候就已经固定在芯片的 eFuse 寄存器中,具有不可修改的属性。
在xilinx 7series 和 7series 以前,ID 都是 57bit 的,但是在 Xilinx 的 Ultraslace 架构下是 96bit 。
获取 Device DNA
JTAG获取
Vivado 中通过 JTAG 查看 DNA PORT信息。
Primitive 获取
Xilinx 的提供的 DNA_PORT Primitive模型和时序图如下
7系列(A7/K7/Z7/V7)的FPGA使用如下原语
DNA_PORT #(
.SIM_DNA_VALUE(57'h000000000000000) // 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(DIN), // 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.
);
Ultraslace系列(VU+/VU/KU+/KU)的FPGA使用如下原语
DNA_PORTE2 #(
.SIM_DNA_VALUE(96'h000000000000000000000000) // 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(DIN), // 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
);
仿真
仿真程序如下所示(小编使用 7 系列FPGA)
module DNA_capture(
input sys_clk,
input dna_rdy,
output [56:0] dna_data,
output dna_valid
);
wire dna_dout;
wire dna_read;
wire dna_shift;
reg [56:0] dna_reg = 0;
reg [7:0] dna_cnt = 0;
DNA_PORT #(
.SIM_DNA_VALUE(57'h123456789abcdef) // Specifies a sample 57-bit DNA value for simulation
)
DNA_PORT_inst (
.DOUT(dna_dout), // 1-bit output: DNA output data.
.CLK(sys_clk), // 1-bit input: Clock input.
.DIN(1'b0), // 1-bit input: User data input pin.
.READ(dna_read), // 1-bit input: Active high load DNA, active low read input.
.SHIFT(dna_shift) // 1-bit input: Active high shift enable input.
);
always@(posedge sys_clk)
if(dna_rdy)begin
if(dna_cnt == 7'd103)
dna_cnt <= dna_cnt;
else
dna_cnt <= dna_cnt + 1'b1;
end
assign dna_read = dna_cnt == 8'd20;
//
assign dna_shift = (dna_cnt >= 8'd45) && (dna_cnt <= (8'd45+8'd57-1));
always @ (posedge sys_clk)
begin
if(dna_shift)begin
dna_reg[56:0] <= {dna_reg[55:0],dna_dout};
end
end
assign dna_data = dna_reg;
assign dna_valid = dna_cnt == (8'd45+8'd57-1);
endmodule
实现
小编所使用开发板为zc7035,读出该芯片的DNA为如下所示,与JTAG读出一致。
那么 DNA 到底在芯片什么位置呢?
应用
情景1
用户在逻辑上可以通过特定的接口把这个 Device DNA 读取出来,经过一系列加密算法之后和预先在外部 Flash 存储的一串加密后的字节串做比较,这个 flash 存储的加密后的字节串也是由该DNA经过加密后得到,FPGA 加载程序后可以先从FPGA 读出该段字节做比较,如果相同,则让 FPGA 启动相应的逻辑,如不同,则代表该FPGA没有经过用户授权,用户逻辑上可以关闭FPGA的逻辑功能甚至可以通过一些手段让硬件损坏。流程如下:
-
器件上电,加载程序,进行FPGA配置。
-
读取FPGA DNA,并将其发送给加密算法。
-
加密算法生成有效的结果。
-
比较结果和存储的校验值,如果结果和存储的校验值相同,则程序可以正常运行。否则,禁止程序运行,或设置定时炸弹,破坏外部设备。
情景2
开发项目需双方公司协作过程中,经常会出现 A 公司向 B 公司申请工程源码。然而工程源码中存在商业价值高或保密性较高的软核部分。传统的代码加密机制如 ngc, edif, dcp 等封装,ip 封装很难做到将原核保护的作用。A 公司仍然可以拿到 B 公司工程源码中的高价值软核,虽然无法知道软核的内部结构,但是参考外部接口及源码中的逻辑即可知道其操作用法,将软核复制,应用于自身公司的其他产品中。在商业竞争过程中,这是十分不利于 B 公司的情况。
所以在所有的高商业价值的软核或者 dcp 模块中,再进行封装一层 DNA 授权小功能块,该模块的功能为检测 FPGA DNA 号,与授权的 DNA 号进行对比,两者一致后生成授权标志信号,逻辑可以利用此标志信号做到代码只有在授权时才能正常工作的情况。由于每片 FPGA 的 DNA 号具有唯一性和不可更改性,将该模块封装后外部无修改接口,做到用户即使拿到功能源码,里面的内核也不可复制到其他 FPGA 上运行,以达到保护知识产权的作用。
参考链接
- 关于 Xilinx-FPGA 的 DNA 的使用场景和读取方法
https://blog.csdn.net/ladywn/article/details/84393123
- Xilinx FPGA的程序加密方法
http://xilinx.eetrend.com/d6-xilinx/article/2018-03/12713.html