Xilinx的FPGA,每个器件都有一个专门的ID,,每个都不一样,Xilinx也形象的把这个ID叫做DNA。7系列以及之前FPGA的DNA有57bit
有时为了将程序绑定器件,防止程序被复制,如果获取器件的DNA
一种方式是通过JTAG,这种方式实用价值不高,就不做展示了,另外一种方式就是通过源语进行读取
下面展示一些 内联代码片
。
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.
);```
这里提供一个小Demo供参考
```c
-- reduce clock speed to 20 MHz max. Should work for all Xilinx families supporting DNA_PORT
CLK_DIV2_GEN: process(CLK)
begin
if rising_edge(CLK) then
if(SYNC_RESET = '1') then
CNTR <= 0;
elsif(CNTR = (CLK_DIV-1)) then
CNTR <= 0;
CLK_DIV2 <= not CLK_DIV2;
else
CNTR <= CNTR + 1;
end if;
end if;
end process;
-- state machine. counts from 0 to 60
STATE_001: process(CLK)
begin
if rising_edge(CLK) then
if(SYNC_RESET = '1') then
STATE <= 0;
elsif(CLK_DIV2 = '0') and (CNTR = (CLK_DIV-1)) then
-- rising edge of CLK_DIV2
if(STATE < 60) then
STATE <= STATE + 1;
end if;
end if;
end if;
end process;
-- read the DNA
DNA_READ_001: process(CLK)
begin
if rising_edge(CLK) then
if(SYNC_RESET = '1') then
DNA_READ <= '0';
elsif(CLK_DIV2 = '1') and (CNTR = (CLK_DIV-1)) then
-- falling edge of CLK_DIV2
if(STATE = 1) then
DNA_READ <= '1';
else
DNA_READ <= '0';
end if;
end if;
end if;
end process;
SHIFT_GEN: process(CLK)
begin
if rising_edge(CLK) then
if(CLK_DIV2 = '1') and (CNTR = (CLK_DIV-1)) then
-- note the falling edge of CLK_DIV2, as per Xilinx recommendation
-- shift 55 times
if(STATE = 2) then
DNA_SHIFT <= '1';
elsif(STATE = 58) then
DNA_SHIFT <= '0';
end if;
end if;
end if;
end process;
--DNA_PORT_inst : DNA_PORT
--generic map (
-- SIM_DNA_VALUE => "0" & x"DCBA9876543210" -- 57-bit constant Specifies a DNA value for simulation purposes (the actual value
-- -- will be specific to the particular device used).
--)
--port map (
-- DOUT => DNA_DOUT, -- 1-bit Serial shifted output data
-- CLK => CLK_DIV2, -- 1-bit Clock input
-- DIN => '0', -- 1-bit Data input to the shift register
-- READ => DNA_READ, -- 1-bit Synchronous load of the shift register with the Device DNA data
-- SHIFT => DNA_SHIFT -- 1-bit Active high shift enable input
--);
DNA_PORT_inst : DNA_PORT
generic map (
SIM_DNA_VALUE => "0" & x"DCBA9876543210" -- 57-bit constant Specifies a DNA value for simulation purposes (the actual value
-- will be specific to the particular device used).
)
port map (
DOUT => DNA_DOUT, -- 1-bit Serial shifted output data
CLK => CLK_DIV2, -- 1-bit Clock input
DIN => '0', -- 1-bit Data input to the shift register
READ => DNA_READ, -- 1-bit Synchronous load of the shift register with the Device DNA data
SHIFT => DNA_SHIFT -- 1-bit Active high shift enable input
);
ID_001: process(CLK)
begin
if rising_edge(CLK) then
if(CLK_DIV2 = '0') and (CNTR = (CLK_DIV-1)) then
-- rising edge of CLK_DIV2
if (DNA_SHIFT = '1') or (STATE = 58) then
ID(0) <= DNA_DOUT;
ID(56 downto 1) <= ID(55 downto 0);
end if;
end if;
end if;
end process;
ID_002: process(CLK)
begin
if rising_edge(CLK) then
if(SYNC_RESET = '1') then
ID_VALID_OUT <= '0';
ID_SAMPLE_CLK_OUT <= '0';
elsif (STATE = 58) and (CLK_DIV2 = '0') and (CNTR = (CLK_DIV-1)) then
-- just read last bit.
ID_VALID_OUT <= '1';
ID_SAMPLE_CLK_OUT <= '1';
else
ID_SAMPLE_CLK_OUT <= '0';
end if;
end if;
end process;
ID_OUT <= ID;
实际产品生产过程中,可以考虑将DNA存储在一个ROM中,上电遍历一遍所有的ID,如果有吻合的,工程正常运行,如果无吻合的,直接给系统复位即可