File: device_dna.v

package info (click to toggle)
uhd 4.9.0.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 184,180 kB
  • sloc: cpp: 262,887; python: 112,011; ansic: 102,670; vhdl: 57,031; tcl: 19,924; xml: 8,581; makefile: 3,028; sh: 2,812; pascal: 230; javascript: 120; csh: 94; asm: 20; perl: 11
file content (117 lines) | stat: -rw-r--r-- 3,076 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//
// 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