- This provides a CtrlPort access to reading back the device DNA - Available for US+ devices (i.e., RFSoC) and 7-series. Original-commit: 43856f90da01cebc1e4b327f4435966ccd1df602
118 lines
3.0 KiB
Verilog
118 lines
3.0 KiB
Verilog
//
|
|
// Copyright 2023 Ettus Research, a National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
|
|
// Module: device_dna
|
|
//
|
|
// Description:
|
|
//
|
|
// Read back the PL DNA.
|
|
// When reset, this module will shift the PL DNA into an output register.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// DNA_WIDTH: The width of the DNA register. UltraScale(+) devices have a 96-bit
|
|
// DNA, 7-series have a 57-bit DNA. If DNA_WIDTH is smaller than
|
|
// that, only LSBs will be output. If it's larger, then the DNA
|
|
// will be zero-padded.
|
|
// DEVICE_TYPE: Either ULTRASCALE or 7SERIES.
|
|
//
|
|
// Signals:
|
|
//
|
|
// dna: This register will hold the full DNA value.
|
|
// valid: This is low while the DNA value register is being populated. Only
|
|
// when high is the value in `dna' valid.
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
module device_dna #(
|
|
// Number of bits of DNA to output
|
|
parameter DNA_WIDTH = 96,
|
|
// For future use: Different FPGA types have different primitives for reading DNA
|
|
parameter DEVICE_TYPE = "ULTRASCALE"
|
|
)(
|
|
input wire clk,
|
|
input wire rst,
|
|
|
|
// The device DNA
|
|
output reg [DNA_WIDTH-1:0] dna,
|
|
// This output is low while the dna register is being populated
|
|
output wire valid
|
|
);
|
|
|
|
localparam ST_RESET = 2'd0;
|
|
localparam ST_READ = 2'd1;
|
|
localparam ST_SHIFT = 2'd2;
|
|
localparam ST_DONE = 2'd3;
|
|
|
|
localparam MAX_SHIFT = (DEVICE_TYPE == "7SERIES") ? 57 : DNA_WIDTH;
|
|
|
|
reg [1:0] state = ST_RESET;
|
|
reg [$clog2(DNA_WIDTH)-1:0] bit_cnt = 0;
|
|
|
|
wire read;
|
|
wire shift;
|
|
wire dout0;
|
|
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
dna <= {DNA_WIDTH{1'b0}};
|
|
state <= ST_READ;
|
|
end else if (state == ST_READ) begin
|
|
state <= ST_SHIFT;
|
|
bit_cnt <= MAX_SHIFT-1;
|
|
end else if (state == ST_SHIFT) begin
|
|
// Ultrascale shifts the DNA out LSB first, 7-series shifts the DNA out
|
|
// MSB first (cf. UG-470 and UG-570 for 7-series and Ultrascale).
|
|
if (DEVICE_TYPE == "ULTRASCALE") begin
|
|
dna <= { dout0, dna[DNA_WIDTH-1:1] };
|
|
end else if (DEVICE_TYPE == "7SERIES") begin
|
|
dna <= { dna[DNA_WIDTH-2:0], dout0 };
|
|
end
|
|
state <= (bit_cnt == 0) ? ST_DONE : ST_SHIFT;
|
|
bit_cnt <= bit_cnt - 1;
|
|
end else begin
|
|
// Nothing in ST_DONE
|
|
end
|
|
end
|
|
|
|
assign read = state == ST_READ;
|
|
assign shift = state == ST_SHIFT;
|
|
assign valid = state == ST_DONE;
|
|
|
|
if (DEVICE_TYPE == "ULTRASCALE") begin : gen_ultrascale_dna
|
|
|
|
DNA_PORTE2 #(
|
|
.SIM_DNA_VALUE(96'h12F1110_C0D111A0_11C0FFEE)
|
|
) dna_inst (
|
|
.CLK (clk),
|
|
.DIN (1'b0),
|
|
.READ (read),
|
|
.SHIFT(shift),
|
|
.DOUT (dout0)
|
|
);
|
|
|
|
end else if (DEVICE_TYPE == "7SERIES") begin : gen_7series_dna
|
|
|
|
DNA_PORT #(
|
|
.SIM_DNA_VALUE(57'h0D111A0_C0DE00FF)
|
|
) dna_inst (
|
|
.CLK (clk),
|
|
.DIN (1'b0),
|
|
.READ (read),
|
|
.SHIFT(shift),
|
|
.DOUT (dout0)
|
|
);
|
|
|
|
end else begin : gen_assert
|
|
ERROR_invalid_device_type();
|
|
end
|
|
|
|
endmodule
|
|
|
|
`default_nettype wire
|