feat: add FPGA raw jitter capture design with SPI register interface
This commit is contained in:
parent
3ee8a5c3db
commit
0332d8eb33
13 changed files with 936 additions and 2 deletions
34
fpga/rtl/entropy_gen.v
Normal file
34
fpga/rtl/entropy_gen.v
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// One generator: two rings of different lengths whose enhanced outputs are XORed, plus
|
||||
// the intermediate signals exposed for jitter characterization. All four are sampled
|
||||
// every clock.
|
||||
module entropy_gen #(
|
||||
parameter LENGTH_A = 12,
|
||||
parameter LENGTH_B = 10
|
||||
) (
|
||||
input wire clk,
|
||||
input wire enable,
|
||||
output wire [3:0] samples // {pair XOR, enhanced B, enhanced A, single tap of A}
|
||||
);
|
||||
|
||||
wire ring_a_tap, ring_a_enhanced, ring_b_tap, ring_b_enhanced;
|
||||
|
||||
ring_osc #(.LENGTH(LENGTH_A)) ring_a (
|
||||
.enable(enable), .first_tap(ring_a_tap), .enhanced(ring_a_enhanced)
|
||||
);
|
||||
ring_osc #(.LENGTH(LENGTH_B)) ring_b (
|
||||
.enable(enable), .first_tap(ring_b_tap), .enhanced(ring_b_enhanced)
|
||||
);
|
||||
|
||||
(* keep *) wire pair_xor = ring_a_enhanced ^ ring_b_enhanced;
|
||||
|
||||
// sample_raw catches the asynchronous ring signals and may go metastable;
|
||||
// sample_sync resolves it. The SDC file cuts timing into sample_raw.
|
||||
reg [3:0] sample_raw, sample_sync;
|
||||
always @(posedge clk) begin
|
||||
sample_raw <= {pair_xor, ring_b_enhanced, ring_a_enhanced, ring_a_tap};
|
||||
sample_sync <= sample_raw;
|
||||
end
|
||||
|
||||
assign samples = sample_sync;
|
||||
|
||||
endmodule
|
||||
67
fpga/rtl/raw_capture.v
Normal file
67
fpga/rtl/raw_capture.v
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Captures one burst of sampled bits into block RAM for offline analysis. Keeps every
|
||||
// decimation-th sample of the selected source and packs them MSB first into bytes.
|
||||
module raw_capture #(
|
||||
parameter ADDR_WIDTH = 15 // 2^15 bytes = 256 Kbit per burst
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire [3:0] samples,
|
||||
input wire [1:0] source,
|
||||
input wire [15:0] decimation, // 0 and 1 both mean every sample
|
||||
input wire start,
|
||||
output reg busy,
|
||||
output reg done,
|
||||
input wire [ADDR_WIDTH-1:0] read_addr,
|
||||
output reg [7:0] read_data
|
||||
);
|
||||
|
||||
reg [7:0] buffer [0:(1 << ADDR_WIDTH) - 1];
|
||||
|
||||
reg [15:0] sample_count;
|
||||
reg [2:0] bit_count;
|
||||
reg [6:0] partial_byte;
|
||||
reg [ADDR_WIDTH-1:0] next_addr;
|
||||
reg write_enable;
|
||||
reg [ADDR_WIDTH-1:0] write_addr;
|
||||
reg [7:0] write_data;
|
||||
|
||||
wire keep_sample = (sample_count == 16'd0);
|
||||
wire count_wraps = (decimation <= 16'd1) || (sample_count == decimation - 16'd1);
|
||||
wire new_bit = samples[source];
|
||||
|
||||
always @(posedge clk) begin
|
||||
write_enable <= 1'b0;
|
||||
if (reset) begin
|
||||
busy <= 1'b0;
|
||||
done <= 1'b0;
|
||||
end else if (start) begin
|
||||
busy <= 1'b1;
|
||||
done <= 1'b0;
|
||||
sample_count <= 16'd0;
|
||||
bit_count <= 3'd0;
|
||||
next_addr <= {ADDR_WIDTH{1'b0}};
|
||||
end else if (busy) begin
|
||||
sample_count <= count_wraps ? 16'd0 : sample_count + 16'd1;
|
||||
if (keep_sample) begin
|
||||
partial_byte <= {partial_byte[5:0], new_bit};
|
||||
bit_count <= bit_count + 3'd1;
|
||||
if (bit_count == 3'd7) begin
|
||||
write_enable <= 1'b1;
|
||||
write_addr <= next_addr;
|
||||
write_data <= {partial_byte, new_bit};
|
||||
next_addr <= next_addr + 1'b1;
|
||||
if (&next_addr) begin
|
||||
busy <= 1'b0;
|
||||
done <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (write_enable) buffer[write_addr] <= write_data;
|
||||
read_data <= buffer[read_addr];
|
||||
end
|
||||
|
||||
endmodule
|
||||
43
fpga/rtl/ring_osc.v
Normal file
43
fpga/rtl/ring_osc.v
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Free-running ring oscillator built from LCELL buffers so synthesis keeps every stage.
|
||||
// Three evenly spaced taps are XORed into an "enhanced" output at three times the ring
|
||||
// frequency, which triples the chance that a sample lands on a jittery edge.
|
||||
module ring_osc #(
|
||||
parameter LENGTH = 12 // stages in the ring; exactly one of them inverts
|
||||
) (
|
||||
input wire enable, // low stops the ring (all stages settle high)
|
||||
output wire first_tap,
|
||||
output wire enhanced
|
||||
);
|
||||
|
||||
`ifdef SIM
|
||||
// Behavioural stand-in: independent taps toggling at random intervals, enough to
|
||||
// exercise the synchronous logic downstream. It has no physical meaning.
|
||||
reg [2:0] taps = 3'b000;
|
||||
always begin
|
||||
#(1 + {$random} % 7);
|
||||
if (enable) taps[{$random} % 3] = ~taps[{$random} % 3];
|
||||
else taps = 3'b111;
|
||||
end
|
||||
assign first_tap = taps[0];
|
||||
assign enhanced = ^taps;
|
||||
`else
|
||||
// No keep attribute here: each lcell is already one logic cell, and keep on these
|
||||
// nets makes Quartus insert a second cell per stage.
|
||||
wire [LENGTH-1:0] stage;
|
||||
|
||||
lcell inverting_stage (.in(~(stage[LENGTH-1] & enable)), .out(stage[0]));
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 1; i < LENGTH; i = i + 1) begin : delay_stage
|
||||
lcell buffer (.in(stage[i-1]), .out(stage[i]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
(* keep *) wire tap_xor = stage[0] ^ stage[LENGTH/3] ^ stage[(2*LENGTH)/3];
|
||||
|
||||
assign first_tap = stage[0];
|
||||
assign enhanced = tap_xor;
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
69
fpga/rtl/spi_slave.v
Normal file
69
fpga/rtl/spi_slave.v
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// SPI mode 0 slave, oversampled in the system clock domain (SCK must stay below about a
|
||||
// tenth of clk). MISO changes a few clk cycles after each SCK falling edge, which leaves
|
||||
// enough margin for the master's next rising edge at 8 MHz SCK with a 120 MHz clk.
|
||||
module spi_slave (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire sck,
|
||||
input wire mosi,
|
||||
input wire ss_n,
|
||||
output wire miso,
|
||||
output wire selected, // ss_n asserted (synchronized)
|
||||
output reg rx_valid, // pulse: rx_byte holds a complete byte
|
||||
output reg [7:0] rx_byte,
|
||||
output reg rx_is_first, // rx_byte is the first byte of the transaction
|
||||
input wire [7:0] tx_byte, // sampled when the next byte starts shifting out
|
||||
output reg tx_loaded // pulse: tx_byte was taken
|
||||
);
|
||||
|
||||
reg [2:0] sck_history, ss_n_history;
|
||||
reg [1:0] mosi_history;
|
||||
|
||||
always @(posedge clk) begin
|
||||
sck_history <= {sck_history[1:0], sck};
|
||||
ss_n_history <= {ss_n_history[1:0], ss_n};
|
||||
mosi_history <= {mosi_history[0], mosi};
|
||||
end
|
||||
|
||||
wire sck_rising = (sck_history[2:1] == 2'b01);
|
||||
wire sck_falling = (sck_history[2:1] == 2'b10);
|
||||
wire mosi_bit = mosi_history[1];
|
||||
assign selected = ~ss_n_history[1];
|
||||
|
||||
reg [2:0] bit_count;
|
||||
reg [6:0] rx_shift;
|
||||
reg [7:0] tx_shift;
|
||||
reg expecting_first;
|
||||
|
||||
assign miso = tx_shift[7];
|
||||
|
||||
always @(posedge clk) begin
|
||||
rx_valid <= 1'b0;
|
||||
tx_loaded <= 1'b0;
|
||||
if (reset || !selected) begin
|
||||
bit_count <= 3'd0;
|
||||
expecting_first <= 1'b1;
|
||||
tx_shift <= 8'h00; // MISO is don't-care during the command byte
|
||||
end else begin
|
||||
if (sck_rising) begin
|
||||
rx_shift <= {rx_shift[5:0], mosi_bit};
|
||||
bit_count <= bit_count + 3'd1;
|
||||
if (bit_count == 3'd7) begin
|
||||
rx_valid <= 1'b1;
|
||||
rx_byte <= {rx_shift, mosi_bit};
|
||||
rx_is_first <= expecting_first;
|
||||
expecting_first <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (sck_falling) begin
|
||||
if (bit_count == 3'd0) begin
|
||||
tx_shift <= tx_byte;
|
||||
tx_loaded <= 1'b1;
|
||||
end else begin
|
||||
tx_shift <= {tx_shift[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
85
fpga/rtl/strix.v
Normal file
85
fpga/rtl/strix.v
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// STRIX top level for the Arduino MKR Vidor 4000. Port names match the Vidor constraints
|
||||
// in strix.qsf; unused board pins are left out and stay tri-stated.
|
||||
module strix (
|
||||
input wire iCLK, // 48 MHz from the SAMD21 (GCLK0)
|
||||
|
||||
inout wire [14:0] bMKR_D, // header D0-D14, shared with the SAMD21
|
||||
inout wire [6:0] bMKR_A, // header A0-A6, shared with the SAMD21
|
||||
|
||||
// NINA-W102 WiFi module
|
||||
inout wire bWM_PIO1, // NINA MISO
|
||||
inout wire bWM_PIO7, // NINA ACK (GPIO33)
|
||||
inout wire bWM_PIO27, // NINA GPIO0
|
||||
inout wire bWM_PIO28, // NINA SS (GPIO5)
|
||||
inout wire bWM_PIO29, // NINA SCK
|
||||
inout wire bWM_PIO36, // NINA MOSI
|
||||
input wire iWM_TX,
|
||||
inout wire oWM_RX,
|
||||
inout wire oWM_RESET,
|
||||
|
||||
output wire oSAM_INT // interrupt line to the SAMD21
|
||||
);
|
||||
|
||||
// Clock and reset
|
||||
|
||||
wire clk, pll_locked;
|
||||
|
||||
sys_pll pll (.inclk0(iCLK), .c0(clk), .locked(pll_locked));
|
||||
|
||||
reg [2:0] reset_pipe = 3'b111;
|
||||
always @(posedge clk or negedge pll_locked)
|
||||
if (!pll_locked) reset_pipe <= 3'b111;
|
||||
else reset_pipe <= {reset_pipe[1:0], 1'b0};
|
||||
wire reset = reset_pipe[2];
|
||||
|
||||
// NINA pass-through: the SAMD21 talks to the WiFi module as if wired directly.
|
||||
|
||||
wire sam_nina_mosi = bMKR_D[8]; // SERCOM1
|
||||
wire sam_nina_sck = bMKR_D[9];
|
||||
wire sam_nina_ss = bMKR_D[5];
|
||||
wire sam_nina_gpio0 = bMKR_D[6];
|
||||
wire sam_nina_resetn = bMKR_D[7];
|
||||
wire sam_uart_tx = bMKR_D[14];
|
||||
|
||||
assign bWM_PIO36 = sam_nina_mosi;
|
||||
assign bWM_PIO29 = sam_nina_sck;
|
||||
assign bWM_PIO28 = sam_nina_ss;
|
||||
assign bWM_PIO27 = sam_nina_gpio0;
|
||||
assign oWM_RESET = sam_nina_resetn;
|
||||
assign oWM_RX = sam_uart_tx;
|
||||
assign bWM_PIO1 = 1'bz; // inputs from NINA
|
||||
assign bWM_PIO7 = 1'bz;
|
||||
|
||||
wire nina_miso = bWM_PIO1; // to D10
|
||||
wire nina_ack = bWM_PIO7; // to D4
|
||||
wire nina_uart_tx = iWM_TX; // to D13
|
||||
|
||||
// STRIX SPI link on SAMD21 SERCOM0 alternate pins: A3 MOSI, A4 SCK, A5 SS, A6 MISO.
|
||||
|
||||
wire strix_mosi = bMKR_A[3];
|
||||
wire strix_sck = bMKR_A[4];
|
||||
wire strix_ss_n = bMKR_A[5];
|
||||
wire strix_miso, capture_done;
|
||||
|
||||
strix_core core (
|
||||
.clk(clk), .reset(reset),
|
||||
.spi_sck(strix_sck), .spi_mosi(strix_mosi), .spi_ss_n(strix_ss_n),
|
||||
.spi_miso(strix_miso), .capture_done(capture_done)
|
||||
);
|
||||
|
||||
assign oSAM_INT = capture_done;
|
||||
|
||||
// Header pins driven by the FPGA; all others are inputs.
|
||||
|
||||
genvar d;
|
||||
generate
|
||||
for (d = 0; d < 15; d = d + 1) begin : header_d
|
||||
assign bMKR_D[d] = (d == 4) ? nina_ack :
|
||||
(d == 10) ? nina_miso :
|
||||
(d == 13) ? nina_uart_tx : 1'bz;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign bMKR_A = {strix_miso, 6'bzzzzzz};
|
||||
|
||||
endmodule
|
||||
130
fpga/rtl/strix_core.v
Normal file
130
fpga/rtl/strix_core.v
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// Board-independent STRIX logic: entropy generator, raw capture and the SPI register
|
||||
// interface to the SAMD21.
|
||||
//
|
||||
// SPI protocol (mode 0, one transaction per ss_n low period): the first byte is a command,
|
||||
// bit 7 = read (1) or write (0), bits 6:0 = register address. A write stores the following
|
||||
// byte(s) in that register. A read returns the register in every following byte; DATA
|
||||
// advances through the capture buffer with each byte, continuing across transactions.
|
||||
module strix_core #(
|
||||
parameter CAPTURE_ADDR_WIDTH = 15
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire spi_sck,
|
||||
input wire spi_mosi,
|
||||
input wire spi_ss_n,
|
||||
output wire spi_miso,
|
||||
output wire capture_done
|
||||
);
|
||||
|
||||
localparam [7:0] VERSION = 8'h01;
|
||||
|
||||
localparam [6:0] REG_ID0 = 7'h00, // "STRX"
|
||||
REG_ID1 = 7'h01,
|
||||
REG_ID2 = 7'h02,
|
||||
REG_ID3 = 7'h03,
|
||||
REG_VERSION = 7'h04,
|
||||
REG_SOURCE = 7'h08, // 0 tap A, 1 enhanced A, 2 enhanced B, 3 pair
|
||||
REG_DECIM_HIGH = 7'h09,
|
||||
REG_DECIM_LOW = 7'h0A,
|
||||
REG_CONTROL = 7'h0B, // write: bit 0 start capture, bit 1 rewind DATA
|
||||
REG_STATUS = 7'h0C, // bit 0 busy, bit 1 done
|
||||
REG_DATA = 7'h10;
|
||||
|
||||
// Entropy and capture
|
||||
|
||||
wire [3:0] samples;
|
||||
|
||||
entropy_gen generator (.clk(clk), .enable(1'b1), .samples(samples));
|
||||
|
||||
reg [1:0] source;
|
||||
reg [15:0] decimation;
|
||||
reg capture_start;
|
||||
wire capture_busy;
|
||||
reg [CAPTURE_ADDR_WIDTH-1:0] prefetch_addr;
|
||||
wire [7:0] capture_byte;
|
||||
|
||||
raw_capture #(.ADDR_WIDTH(CAPTURE_ADDR_WIDTH)) capture (
|
||||
.clk(clk), .reset(reset), .samples(samples), .source(source),
|
||||
.decimation(decimation), .start(capture_start),
|
||||
.busy(capture_busy), .done(capture_done),
|
||||
.read_addr(prefetch_addr), .read_data(capture_byte)
|
||||
);
|
||||
|
||||
// SPI
|
||||
|
||||
wire selected, rx_valid, rx_is_first, tx_loaded;
|
||||
wire [7:0] rx_byte;
|
||||
reg [7:0] tx_byte;
|
||||
|
||||
spi_slave spi (
|
||||
.clk(clk), .reset(reset),
|
||||
.sck(spi_sck), .mosi(spi_mosi), .ss_n(spi_ss_n), .miso(spi_miso),
|
||||
.selected(selected), .rx_valid(rx_valid), .rx_byte(rx_byte),
|
||||
.rx_is_first(rx_is_first), .tx_byte(tx_byte), .tx_loaded(tx_loaded)
|
||||
);
|
||||
|
||||
reg is_read;
|
||||
reg [6:0] reg_addr;
|
||||
|
||||
// DATA bytes are prefetched one ahead: prefetch_addr moves when a byte is loaded for
|
||||
// shifting, bytes_read only when it has been fully clocked out. Between transactions
|
||||
// prefetch_addr rewinds to bytes_read so the trailing prefetch is not lost.
|
||||
reg [CAPTURE_ADDR_WIDTH-1:0] bytes_read;
|
||||
|
||||
wire reading_data = is_read && reg_addr == REG_DATA;
|
||||
|
||||
always @(*) begin
|
||||
case (reg_addr)
|
||||
REG_ID0: tx_byte = "S";
|
||||
REG_ID1: tx_byte = "T";
|
||||
REG_ID2: tx_byte = "R";
|
||||
REG_ID3: tx_byte = "X";
|
||||
REG_VERSION: tx_byte = VERSION;
|
||||
REG_SOURCE: tx_byte = {6'd0, source};
|
||||
REG_DECIM_HIGH: tx_byte = decimation[15:8];
|
||||
REG_DECIM_LOW: tx_byte = decimation[7:0];
|
||||
REG_STATUS: tx_byte = {6'd0, capture_done, capture_busy};
|
||||
REG_DATA: tx_byte = capture_byte;
|
||||
default: tx_byte = 8'h00;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
capture_start <= 1'b0;
|
||||
if (reset) begin
|
||||
source <= 2'd3;
|
||||
decimation <= 16'd1;
|
||||
is_read <= 1'b0;
|
||||
reg_addr <= 7'd0;
|
||||
bytes_read <= {CAPTURE_ADDR_WIDTH{1'b0}};
|
||||
prefetch_addr <= {CAPTURE_ADDR_WIDTH{1'b0}};
|
||||
end else begin
|
||||
if (!selected)
|
||||
prefetch_addr <= bytes_read;
|
||||
else if (tx_loaded && reading_data)
|
||||
prefetch_addr <= prefetch_addr + 1'b1;
|
||||
|
||||
if (rx_valid) begin
|
||||
if (rx_is_first) begin
|
||||
is_read <= rx_byte[7];
|
||||
reg_addr <= rx_byte[6:0];
|
||||
end else if (reading_data) begin
|
||||
bytes_read <= bytes_read + 1'b1;
|
||||
end else if (!is_read) begin
|
||||
case (reg_addr)
|
||||
REG_SOURCE: source <= rx_byte[1:0];
|
||||
REG_DECIM_HIGH: decimation[15:8] <= rx_byte;
|
||||
REG_DECIM_LOW: decimation[7:0] <= rx_byte;
|
||||
REG_CONTROL: begin
|
||||
if (rx_byte[0]) capture_start <= 1'b1;
|
||||
if (rx_byte[0] || rx_byte[1]) bytes_read <= {CAPTURE_ADDR_WIDTH{1'b0}};
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
100
fpga/rtl/sys_pll.v
Normal file
100
fpga/rtl/sys_pll.v
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// 48 MHz in, 120 MHz out (x5 / 2). Same altpll settings style as Arduino's Vidor
|
||||
// SYSTEM_PLL, reduced to one output.
|
||||
module sys_pll (
|
||||
input wire inclk0,
|
||||
output wire c0,
|
||||
output wire locked
|
||||
);
|
||||
|
||||
wire [4:0] clk;
|
||||
|
||||
altpll altpll_component (
|
||||
.inclk ({1'b0, inclk0}),
|
||||
.clk (clk),
|
||||
.locked (locked),
|
||||
.areset (1'b0),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ()
|
||||
);
|
||||
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "AUTO",
|
||||
altpll_component.clk0_divide_by = 2,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 5,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 20833,
|
||||
altpll_component.intended_device_family = "Cyclone 10 LP",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=sys_pll",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_UNUSED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
assign c0 = clk[0];
|
||||
|
||||
endmodule
|
||||
Loading…
Add table
Add a link
Reference in a new issue