fpga: Add X440/FBX support

Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ni.com>
Co-authored-by: Ryan Marlow <ryan@lmarlow.com>


Original-commit: 596760a12e4834e47589c12f8a4fd083aa2f7c25
This commit is contained in:
Javier Valenzuela
2023-06-12 10:27:29 -05:00
committed by Aki Tomita
co-authored by Martin Braun Wade Fife Ryan Marlow
parent a405111ce7
commit 5cadf901c7
121 changed files with 20670 additions and 8739 deletions
+14 -1
View File
@@ -22,11 +22,14 @@
10M08_ID = "10M08SAU169I7G"
# Project directories
X440_DIR = $(abspath ./x440)
X410_DIR = $(abspath ./x410)
# Target specific variables
X410_CPLD_10M04: DEFS = VARIANT_`echo $(10M04_ID) | cut -c1-5`=1 PROJECT_DIR=$(X410_DIR) X410=1
X410_CPLD_10M08: DEFS = VARIANT_`echo $(10M08_ID) | cut -c1-5`=1 PROJECT_DIR=$(X410_DIR) X410=1
X440_CPLD_10M04: DEFS = VARIANT_`echo $(10M04_ID) | cut -c1-5`=1 PROJECT_DIR=$(X440_DIR) X440=1
X440_CPLD_10M08: DEFS = VARIANT_`echo $(10M08_ID) | cut -c1-5`=1 PROJECT_DIR=$(X440_DIR) X440=1
X410_CPLD_MFG_10M08: DEFS = VARIANT_`echo $(10M08_ID) | cut -c1-5`=1 MFG_SUPPORT=1 PROJECT_DIR=$(X410_DIR)
@@ -61,7 +64,7 @@ endif
##Supported Targets
##-----------------
all: X410_CPLD_10M04 X410_CPLD_10M08 ##(Default target)
all: X410_CPLD_10M04 X410_CPLD_10M08 X440_CPLD_10M04 X440_CPLD_10M08 ##(Default target)
##X410_CPLD_10M04: Motherboard CPLD targeted to 10M04SAU169I7G.
X410_CPLD_10M04:
@@ -73,6 +76,16 @@ X410_CPLD_10M08:
$(call quartus_build,$(10M08_ID),$(DEFS))
$(call post_build,"usrp_x410_cpld_`echo $(10M08_ID) | cut -c1-5 | tr A-Z a-z`")
##X440_CPLD_10M08: Motherboard CPLD targeted to 10M04SAU169I7G.
X440_CPLD_10M04:
$(call quartus_build,$(10M04_ID),$(DEFS))
$(call post_build,"usrp_x440_cpld_`echo $(10M04_ID) | cut -c1-5 | tr A-Z a-z`")
##X440_CPLD_10M08: Motherboard CPLD targeted to 10M08SAU169I7G.
X440_CPLD_10M08:
$(call quartus_build,$(10M08_ID),$(DEFS))
$(call post_build,"usrp_x440_cpld_`echo $(10M08_ID) | cut -c1-5 | tr A-Z a-z`")
X410_CPLD_IP: ##Build IPs only, needed for simulation.
@# Building only X410_CPLD_10M04 IP
$(call quartus_ip,$(10M04_ID),$(DEFS))
+2
View File
@@ -47,6 +47,8 @@ module pl_cpld_regs #(
`ifdef X410
`include "../regmap/x410/constants_regmap_utils.vh"
`else
`include "../regmap/x440/constants_regmap_utils.vh"
`endif
`include "../regmap/pl_cpld_base_regmap_utils.vh"
`include "../../../../lib/rfnoc/core/ctrlport.vh"
+2
View File
@@ -47,6 +47,8 @@ module ps_cpld_regs #(
);
`ifdef X410
`include "../regmap/x410/constants_regmap_utils.vh"
`else
`include "../regmap/x440/constants_regmap_utils.vh"
`endif
`include "../regmap/ps_cpld_base_regmap_utils.vh"
`include "../../../../lib/rfnoc/core/ctrlport.vh"
-275
View File
@@ -1,275 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: ctrlport_to_jtag
//
// Description:
//
// This module wraps a JTAG master and provides a ControlPort slave
// interface.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers
// DEFAULT_PRESCALAR : Default clock divider to use
//
`default_nettype none
module ctrlport_to_jtag #(
parameter BASE_ADDRESS = 0,
parameter DEFAULT_PRESCALAR = 0
) (
//---------------------------------------------------------------------------
// ControlPort Slave
//---------------------------------------------------------------------------
input wire ctrlport_clk,
input wire ctrlport_rst,
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status = 0,
output reg [31:0] s_ctrlport_resp_data = 0,
//---------------------------------------------------------------------------
// JTAG Signals
//---------------------------------------------------------------------------
output wire tck,
output wire tdi,
input wire tdo,
output wire tms
);
`include "../../../lib/rfnoc/core/ctrlport.vh"
`include "./regmap/jtag_regmap_utils.vh"
//---------------------------------------------------------------------------
// Local Registers
//---------------------------------------------------------------------------
reg [ TX_DATA_SIZE-1:0] tx_data_reg;
reg [ STB_DATA_SIZE-1:0] stb_data_reg;
reg [PRESCALAR_SIZE-1:0] prescalar_reg = DEFAULT_PRESCALAR;
reg [ LENGTH_SIZE-1:0] length_reg;
reg start_reg;
reg soft_rst_stb_reg;
//---------------------------------------------------------------------------
// Readback Signals from JTAG Master
//---------------------------------------------------------------------------
wire [31:0] rd_data;
wire ready;
//---------------------------------------------------------------------------
// Handling of CtrlPort
//---------------------------------------------------------------------------
localparam NUM_ADDRESSES = 32;
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
wire soft_rst_requested = (s_ctrlport_req_addr == BASE_ADDRESS + CONTROL) &&
(s_ctrlport_req_data[RESET] == 1'b1);
always @(posedge ctrlport_clk) begin
// Reset internal registers and responses
if (ctrlport_rst) begin
tx_data_reg <= {TX_DATA_SIZE {1'b0}};
stb_data_reg <= {STB_DATA_SIZE {1'b0}};
prescalar_reg <= DEFAULT_PRESCALAR;
length_reg <= {LENGTH_SIZE {1'b0}};
start_reg <= 1'b0;
soft_rst_stb_reg <= 1'b0;
s_ctrlport_resp_ack <= 1'b0;
end else begin
// Request independent default assignments
start_reg <= 1'b0;
soft_rst_stb_reg <= 1'b0; // self-clearing strobe
// Write requests
if (s_ctrlport_req_wr) begin
// Always issue an ack and no data
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= {CTRLPORT_DATA_W{1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
// Process write requests only in case ready is asserted because JTAG
// module requires these values to be stable when it is not ready.
//
// The one exception is when a soft-reset is requested to reset the
// bitq_fsm, in that case that is a valid write.
if (soft_rst_requested) begin
soft_rst_stb_reg <= 1'b1;
end else if (ready) begin
case (s_ctrlport_req_addr)
BASE_ADDRESS + TX_DATA: begin
tx_data_reg <= s_ctrlport_req_data;
end
BASE_ADDRESS + STB_DATA: begin
stb_data_reg <= s_ctrlport_req_data;
end
BASE_ADDRESS + CONTROL: begin
length_reg <= s_ctrlport_req_data[LENGTH_MSB:LENGTH];
prescalar_reg <= s_ctrlport_req_data[PRESCALAR_MSB:PRESCALAR];
// When the RESET bit is high, a soft-reset (i.e. no start strobe)
// must take place, which is handled by the default assignment.
// Otherwise, if the RESET bit is low, a start strobe should be
// issued, triggering a transaction.
start_reg <= (s_ctrlport_req_data[RESET] == 1'b0);
end
// Error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// Error in case ready is not asserted
end else begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
end
// Read requests
end else if (s_ctrlport_req_rd) begin
// Default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
case (s_ctrlport_req_addr)
BASE_ADDRESS + RX_DATA: begin
s_ctrlport_resp_data <= rd_data;
end
BASE_ADDRESS + CONTROL: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
s_ctrlport_resp_data[LENGTH_MSB:LENGTH] <= length_reg;
s_ctrlport_resp_data[PRESCALAR_MSB:PRESCALAR] <= prescalar_reg;
s_ctrlport_resp_data[READY] <= ready;
end
// Error on undefined address
default: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}};
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// No request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
end
//---------------------------------------------------------------------------
// JTAG Master
//---------------------------------------------------------------------------
// bitq_fsm reset is asserted by either the ctrlport_rst or the soft-reset
// strobe triggered through software.
wire bitq_resetn = ~(ctrlport_rst | soft_rst_stb_reg);
bitq_fsm #(
.IDLE_VALUE (1'b0)
) jtag_master (
.clk (ctrlport_clk),
.rstn (bitq_resetn),
.prescalar (prescalar_reg),
.bit_clk (tck),
.bit_in (tdo),
.bit_out (tdi),
.bit_stb (tms),
.start (start_reg),
.ready (ready),
.len (length_reg),
.wr_data (tx_data_reg),
.stb_data (stb_data_reg),
.rd_data (rd_data)
);
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="JTAG_REGMAP" readablestrobes="false" markdown="true" generatevhdl="true" ettusguidelines="true">
//
// <group name="JTAG_REGS">
// <info>
// This register map is present for each JTAG module.
//
// Basic operation would be:
//
// - poll @.ready until asserted
// - write / read data
// - write @.CONTROL register along with @.reset deasserted to start a transaction
//
// For resetting the BITQ FSM, simply assert @.reset.
//
// This operation seems a little strange, but it is what the axi_bitq driver
// expects. This behavior has been implemented in previous products.
//
// </info>
//
// <register name="TX_DATA" readable="false" offset="0x00" size="32">
// <info>Data to be transmitted (TDI)</info>
// </register>
//
// <register name="STB_DATA" readable="false" offset="0x04" size="32">
// <info>Data to be transmitted (TMS)</info>
// </register>
//
// <register name="CONTROL" offset="0x08" size="32">
// <info>JTAG module status and control</info>
// <bitfield name="prescalar" range="7..0" initialvalue="true">
// <info>Clock divider. Resulting JTAG frequency will be f_ctrlport / (2*(prescalar + 1)). See window description for details on the initial/minimum value.</info>
// </bitfield>
// <bitfield name="length" range="12..8">
// <info>(Number of bits - 1) to be transferred</info>
// </bitfield>
// <bitfield name="reset" readable="false" range="31">
// <info>When asserted ('1') a soft-reset for the bitq FSM is triggered,
// preventing any transactions to take place.
//
// Deassert this bit, along with values for @.prescalar and @.length
// to trigger a new transaction (start strobe).</info>
// </bitfield>
// <bitfield name="ready" writable="false" range="31">
// <info>Bitq FSM is ready for input (no data transmission in progress).</info>
// </bitfield>
// </register>
//
// <register name="RX_DATA" offset="0x0C" writable="false" size="32">
// <info>Received data (TDO)</info>
// </register>
//
// </group>
//</regmap>
//XmlParse xml_off
-276
View File
@@ -1,276 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: ctrlport_to_spi
//
// Description:
//
// This module wraps a SPI master and provides a ControlPort interface.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers.
//
`default_nettype none
module ctrlport_to_spi #(
parameter BASE_ADDRESS = 0
) (
//---------------------------------------------------------------
// ControlPort Slave
//---------------------------------------------------------------
input wire ctrlport_clk,
input wire ctrlport_rst,
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status = 0,
output reg [31:0] s_ctrlport_resp_data = 0,
//---------------------------------------------------------------
// SPI Signals
//---------------------------------------------------------------
output wire sclk,
output wire mosi,
output wire [15:0] ss,
input wire miso
);
`include "../../../lib/rfnoc/core/ctrlport.vh"
`include "./regmap/spi_regmap_utils.vh"
//---------------------------------------------------------------
// Translating CtrlPort <-> Wishbone
//---------------------------------------------------------------
reg wb_cyc_i; // Active bus cycle
reg wb_we_i = 1'b0; // Write access
reg [ 4:0] wb_adr_i = 5'b0;
reg [31:0] wb_dat_i = 32'b0;
wire wb_ack_o;
wire [31:0] wb_dat_o;
wire wb_err_o;
// Check for address to be in range [base_addr..base_addr+32)
localparam NUM_ADDRESSES = 32;
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
// Following chapter 3.2.3 (classic standard SINGLE WRITE cycle) of
// https://cdn.opencores.org/downloads/wbspec_b4.pdf
always @(posedge ctrlport_clk) begin
// Reset internal registers and responses
if (ctrlport_rst) begin
wb_cyc_i <= 1'b0;
s_ctrlport_resp_ack <= 1'b0;
end else begin
// Request independent default assignments
s_ctrlport_resp_ack <= 1'b0;
// Wait for ack on active bus transactions
if (wb_cyc_i) begin
if (wb_ack_o) begin
// End bus cycle and generate response
wb_cyc_i <= 1'b0;
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= wb_dat_o;
if (wb_err_o) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
end else begin
s_ctrlport_resp_status <= CTRL_STS_OKAY;
end
end
// Write requests
end else if (s_ctrlport_req_wr) begin
// Assume there is a valid address
wb_cyc_i <= 1'b1;
wb_we_i <= 1'b1;
wb_dat_i <= s_ctrlport_req_data;
case (s_ctrlport_req_addr)
BASE_ADDRESS + TX_DATA_LOW: begin
wb_adr_i <= 5'h00;
end
BASE_ADDRESS + TX_DATA_HIGH: begin
wb_adr_i <= 5'h04;
end
BASE_ADDRESS + CONTROL: begin
wb_adr_i <= 5'h10;
end
BASE_ADDRESS + CLOCK_DIVIDER: begin
wb_adr_i <= 5'h14;
end
BASE_ADDRESS + SLAVE_SELECT: begin
wb_adr_i <= 5'h18;
end
// Error on undefined address
default: begin
wb_cyc_i <= 1'b0;
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// Read requests
end else if (s_ctrlport_req_rd) begin
// Assume there is a valid address
wb_cyc_i <= 1'b1;
wb_we_i <= 1'b0;
case (s_ctrlport_req_addr)
BASE_ADDRESS + RX_DATA_LOW: begin
wb_adr_i <= 5'h00;
end
BASE_ADDRESS + RX_DATA_HIGH: begin
wb_adr_i <= 5'h04;
end
BASE_ADDRESS + CONTROL: begin
wb_adr_i <= 5'h10;
end
BASE_ADDRESS + CLOCK_DIVIDER: begin
wb_adr_i <= 5'h14;
end
BASE_ADDRESS + SLAVE_SELECT: begin
wb_adr_i <= 5'h18;
end
// Error on undefined address
default: begin
wb_cyc_i <= 1'b0;
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// No request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
end
//---------------------------------------------------------------
// SPI Master
//---------------------------------------------------------------
spi_top spi_master (
.wb_clk_i (ctrlport_clk),
.wb_rst_i (ctrlport_rst),
.wb_adr_i (wb_adr_i),
.wb_dat_i (wb_dat_i),
.wb_dat_o (wb_dat_o),
.wb_sel_i (4'hF),
.wb_we_i (wb_we_i),
.wb_stb_i (wb_cyc_i),
.wb_cyc_i (wb_cyc_i),
.wb_ack_o (wb_ack_o),
.wb_err_o (wb_err_o),
.wb_int_o (),
.ss_pad_o (ss),
.sclk_pad_o (sclk),
.mosi_pad_o (mosi),
.miso_pad_i (miso)
);
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="SPI_REGMAP" readablestrobes="false" markdown="true" generatevhdl="true" ettusguidelines="true">
//
// <group name="SPI_REGS">
// <info>
// This register map is present for each SPI master.
//
// For information about the register content and the way to interact with the core see the
// <a href="https://opencores.org/websvn/filedetails?repname=spi&path=%2Fspi%2Ftrunk%2Fdoc%2Fspi.pdf" target="_blank">documentation</a>
// of the SPI master from opencores used internally.
//
// The core is configured to operate with 16 slave signal signals, up to 128 bits per transmission and 8 bit clock divider.
// Only 64 bits of data are available via this register interface.
//
// For the different SPI modes use the following table to derive the bits in @.CONTROL register. Only option 0 (CPOL=0, CPHA=0) has been tested.
//
//| CPOL | CPHA | TX_NEG | RX_NEG |
//| ------- | -------- | -------- | ------- |
//| 0 | 0 | 1 | 0 |
//| 0 | 1 | 0 | 1 |
//| 1 | 0 | 0 | 1 |
//| 1 | 1 | 1 | 0 |
// </info>
//
// <register name="RX_DATA_LOW" offset="0x00" writable="false" size="32">
// <info>Lower 32 bits of the received word. (RxWord[31:0])</info>
// </register>
//
// <register name="RX_DATA_HIGH" offset="0x04" writable="false" size="32">
// <info>Higher 32 bits of the received word. (RxWord[63:32])</info>
// </register>
//
// <register name="TX_DATA_LOW" offset="0x08" readable="false" size="32">
// <info>Lower 32 bits of the received word. (TxWord[31:0])</info>
// </register>
//
// <register name="TX_DATA_HIGH" offset="0x0C" readable="false" size="32">
// <info>Higher 32 bits of the received word. (TxWord[63:32])</info>
// </register>
//
// <register name="CONTROL" offset="0x10" size="32">
// <info>Control register</info>
// </register>
// <register name="CLOCK_DIVIDER" offset="0x14" size="8">
// <bitfield name="Divider" range="7..0">
// <info>
// Clock Divider.
// </info>
// </bitfield>
// </register>
// <register name="SLAVE_SELECT" offset="0x18" size="16">
// <bitfield name="SS" range="15..0">
// <info>
// Slave select.
// </info>
// </bitfield>
// </register>
//
// </group>
//</regmap>
//XmlParse xml_off
-20
View File
@@ -1,20 +0,0 @@
#
# Copyright 2021 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description:
#
# Timing constants for the MB CPLD <-> DB CPLD SPI interface
#
# Delays are rounded to integer values which leave a slack of >1ns on each setup
# and hold path without requirement for adding hold delays (as reported
# by Quartus fitter report).
# The signal might change before the SCLK edge as the internal
# registers are driven by PLL reference clock rather than the SPI clock used
# for the port timing constaints.
set db_cpld_spi_max_out 14.000
set db_cpld_spi_min_out 2.000
set db_cpld_spi_max_in 2.000
set db_cpld_spi_min_in -2.000
-689
View File
@@ -1,689 +0,0 @@
#
# Copyright 2021 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description:
#
# Timing constraints for the X4xx's motherboard CPLD.
#
set_time_format -unit ns -decimal_places 3
#####################################################################
# General
#####################################################################
# For a couple of 3.3V interfaces the buffer SN74AVC4T774RSVR is used to
# increase the drive strength. For reuse we define the timings constants here.
# For direction A to B and B to A the maximum timing varies by 0.1 ns. Taking
# the maximum of both.
set buffer_prop_min 0.100
set buffer_prop_max 2.400
#####################################################################
# Main Clocks
#####################################################################
## Input clocks.
# Reliable clock: 100.0 MHz
set CLK_100_period 10.000
create_clock -name CLK_100 -period $CLK_100_period [get_ports CLK_100]
# internal PLL derived clock
derive_pll_clocks
# provide name for derived clocks
set CLK_250 [get_clocks {*clk[1]}]
# PLL output pins of the generated 50 MHz clock for internal processing
set clk50_period 20.000
set pll_clk_out_pin [get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[0]}]
set clk250_period 4.000
# PLL reference clock: 64 MHz (maximum)
set prc_clock_period 15.625
create_clock -name PLL_REF_CLK -period $prc_clock_period [get_ports PLL_REF_CLK]
#####################################################################
# Timing exceptions
#####################################################################
## SPI slaves
# Delay path for all synchronizers is based on the period of the
# faster clock domain (50 MHz derived by the PLL from 100 MHz reliable clock).
set clk50_period [expr {$CLK_100_period * 2}]
set_max_delay -to [get_registers *synchronizer_false_path\|value\[0\]\[*\]] \
$clk50_period
# sclk data to CLK_100
set_max_delay -from [get_registers *spi_slave_async\|received_word\[*\]] \
-to [get_registers *spi_slave_async\|data_out\[*\]] \
$clk50_period
# PLL driven data to sclk
set_max_delay -from [get_clocks {pll_inst*}] \
-to [get_registers *spi_slave_async\|transmit_bits\[*\]] \
$clk50_period
#####################################################################
# JTAG to daughterboards
#####################################################################
# Use the worst-case board propagation delays.
# Assuming 170.0 ps/in and usage of X410 DB.
# Longest trace | Trace length | Trace delay
# TDI to DB 0 | 7.625 in | 1.296 ns
# --------------------------------------------
# JTAG parameters
# see https://www.intel.com/content/www/us/en/programmable/documentation/mcn1397700832153.html#mcn1399899915639
set db_jtag_board_delay 1.296
set db_jtag_setup 3.000
set db_jtag_hold 10.000
set db_jtag_clk_to_out 20.000
set db0_jtag_outputs [get_ports {DB_JTAG_TDI[0] DB_JTAG_TMS[0]}]
set db0_jtag_inputs [get_ports {DB_JTAG_TDO[0]}]
set db1_jtag_outputs [get_ports {DB_JTAG_TDI[1] DB_JTAG_TMS[1]}]
set db1_jtag_inputs [get_ports {DB_JTAG_TDO[1]}]
##### DB 0 #####
# generated jtag clock is at least divided by 4
# max JTAG clock rate = 20 MHz
# source clock rate = 50 MHz
# only even dividers -> minimum value = 4
set db0_jtag_clk_register [get_registers {ctrlport_to_jtag:db0_jtag|bitq_fsm:jtag_master|bitq_state.HIGH}]
create_generated_clock -source $pll_clk_out_pin \
-name db0_jtag_clk $db0_jtag_clk_register \
-divide_by 4
# see White Rabbit DAC for futher explanation
set_false_path -from $db0_jtag_clk_register -to $db0_jtag_clk_register
create_generated_clock \
-source $db0_jtag_clk_register \
-name db0_jtag_out_clk [get_ports {DB_JTAG_TCK[0]}]
set_output_delay -clock db0_jtag_out_clk \
-max [expr {$db_jtag_setup + $db_jtag_board_delay + $buffer_prop_max}] \
$db0_jtag_outputs
set_output_delay -clock db0_jtag_out_clk \
-min [expr {-$db_jtag_hold - $db_jtag_board_delay - $buffer_prop_min}] \
$db0_jtag_outputs
# data is driven on CPLD on falling edge, which is 2 clock cycles ahead
# of the latch edge
set_multicycle_path -setup -start -to $db0_jtag_outputs 2
set_multicycle_path -hold -start -to $db0_jtag_outputs 3
# maximum delay accounts for slow clock and data propagation as
# well as clock to out time
set_input_delay -clock_fall -clock db0_jtag_out_clk \
-max [expr {$db_jtag_clk_to_out + 2*$db_jtag_board_delay + 2*$buffer_prop_max}] \
$db0_jtag_inputs
# worst-case everything changes immediatelly
set_input_delay -clock_fall -clock db0_jtag_out_clk \
-min [expr {2*$buffer_prop_min}] \
$db0_jtag_inputs
set_multicycle_path -setup -end -from $db0_jtag_inputs 2
set_multicycle_path -hold -end -from $db0_jtag_inputs 3
##### DB 1 #####
# generated jtag clock is at least divided by 4
set db1_jtag_clk_register [get_registers {ctrlport_to_jtag:db1_jtag|bitq_fsm:jtag_master|bitq_state.HIGH}]
create_generated_clock -source $pll_clk_out_pin \
-name db1_jtag_clk $db1_jtag_clk_register \
-divide_by 4
# see White Rabbit DAC for futher explanation
set_false_path -from $db1_jtag_clk_register -to $db1_jtag_clk_register
create_generated_clock \
-source $db1_jtag_clk_register \
-name db1_jtag_out_clk [get_ports {DB_JTAG_TCK[1]}]
set_output_delay -clock db1_jtag_out_clk \
-max [expr {$db_jtag_setup + $db_jtag_board_delay + $buffer_prop_max}] \
$db1_jtag_outputs
set_output_delay -clock db1_jtag_out_clk \
-min [expr {-$db_jtag_hold - $db_jtag_board_delay - $buffer_prop_min}] \
$db1_jtag_outputs
set_multicycle_path -setup -start -to $db1_jtag_outputs 2
set_multicycle_path -hold -start -to $db1_jtag_outputs 3
# maximum delay accounts for slow clock and data propagation as
# well as clock to out time
set_input_delay -clock_fall -clock db1_jtag_out_clk \
-max [expr {$db_jtag_clk_to_out + 2*$db_jtag_board_delay + 2*$buffer_prop_max}] \
$db1_jtag_inputs
# ideally everything changes immediatelly
set_input_delay -clock_fall -clock db1_jtag_out_clk \
-min [expr {2*$buffer_prop_min}] \
$db1_jtag_inputs
set_multicycle_path -setup -end -from $db1_jtag_inputs 2
set_multicycle_path -hold -end -from $db1_jtag_inputs 3
#####################################################################
# FPGA <-> MB CPLD PL SPI interface
#####################################################################
# Create clock for the PL's SPI interface.
# PRC at least divided by 2 by the SPI Master on FPGA
set pl_sclk_period [expr {2 * $prc_clock_period}]
create_clock -name pl_sclk -period $pl_sclk_period [get_registers mb_cpld_sclk]
# The SPI PL master (on the FPGA) is designed as a system synchronous
# interface using PLL_REF_CLK.
# The FPGA output constraints are required to calculate the windows
# at CPLD of valid data
# They are derived iteratively from the FPGA design ensuring a large
# valid data period.
set pl_spi_fpga_min_out 0.000
set pl_spi_fpga_max_out 11.000
# The longest trace on the PL SPI interface is (sssuming 170.0 ps/in)
# Longest trace | Trace length | Trace delay
# CS_0 | 7.143 in | 1.215 ns
set pl_spi_board_delay 1.215
# This path also contains a level translator which has a typical
# switching time of 2.7 ns. Let's add a margin of 1 ns as worst
# case estimation
set pl_level_trans_delay 3.700
# CPLD and FPGA both use PLL reference clock from a common clock chip.
# The traces from that clock chip to the ICs are not length matched
# Assume a worst case clock difference of 0.5 ns at the IC inputs.
# There is no direction defined. The clock can arrive faster or slower
# on one IC.
set pl_clock_diff 0.500
set pl_slave_inputs [get_ports {PL_CPLD_SCLK PL_CPLD_MOSI PL_CPLD_CS_N[*]}]
# calculate output delays back from capturing edge, add board delay, level translator and clock difference
set_input_delay -clock PLL_REF_CLK \
-max [expr {$prc_clock_period - $pl_spi_fpga_max_out + $pl_spi_board_delay + $pl_level_trans_delay + $pl_clock_diff}] \
$pl_slave_inputs
# Assuming data is going without any delay, clock is arriving early at CPLD.
# Negate minimum output delay as it is defined from the change to the start clock edge.
set_input_delay -clock PLL_REF_CLK \
-min [expr {- $pl_spi_fpga_min_out - $pl_clock_diff}] \
$pl_slave_inputs
# ensure large data valid window for the FPGA
# those values are used in the FPGA / DB CPLDs
# to calculate the input delay
# those values are maximum integer values to still meet timing
set pl_spi_cpld_min_out -1.000
set pl_spi_cpld_max_out 8.000
set pl_slave_outputs [get_ports {PL_CPLD_MISO}]
set_output_delay -clock PLL_REF_CLK -max $pl_spi_cpld_max_out $pl_slave_outputs
set_output_delay -clock PLL_REF_CLK -min $pl_spi_cpld_min_out $pl_slave_outputs
#####################################################################
# DB clock and reset
#####################################################################
# Output clocks for the daughterboards (SPI control)
create_generated_clock -source $pll_clk_out_pin \
-name db0_ref_clk [get_ports {DB_REF_CLK[0]}]
create_generated_clock -source $pll_clk_out_pin \
-name db1_ref_clk [get_ports {DB_REF_CLK[1]}]
# output reset within one clock period
set_max_delay -to [get_ports {DB_ARST[0] DB_ARST[1]}] $CLK_100_period
set_min_delay -to [get_ports {DB_ARST[0] DB_ARST[1]}] 0
#####################################################################
# DB SPI interfaces
#####################################################################
# --------- ----------------- -----------------
# FPGA | CS/SCLK/ | MB CPLD | | DB |
# |-- MOSI ->|--------> R1 ->|--------->| |
# SPI | | | | SPI |
# master |<- MISO --|<- R2 <--------|<---------| slave |
# --------- ----------------- -----------------
#
# The output clocks are derived from the PLL reference clock (PRC). The SCLK
# edges are aligned with the rising edge of PLL reference clock. There are two
# registers R1 and R2 in the SPI path between FPGA and DB.
# For the transmission of data from master to slave those registers are
# transparent. The overall reception is just delayed by 1 PLL reference clock
# cycle. In the other direction the MISO timing is different. The falling edge
# of SCLK is used for changing the data signals. The propagation of this signal
# to the DB is delayed by 1 PLL reference clock period because of register R1.
# The MISO signal is captured on the rising edge of SCLK on the FPGA. Register
# R2 in the MB CPLD changes the timing in a way that MISO has to be stable on
# the rising edge of PLL reference clock before the SCLK rising edge.
# Additionally a minimum of two PLL reference clock cycles are required for
# processing in the SPI slave. The number of processing cycles is denoted by n.
# Here is an example for n=2 and SPI bus with CPHA=0 and CPOL=0.
# Data is driven on the falling edge and captured on the rising edge of the
# clock signal. The falling edge of the SCLK@DB is delayed by a clock cycle
# because of R1. The FPGA as SPI master is capturing the data on the rising edge
# of SCLK. The register R2 on the MB CPLD is capturing the data one clock cycle
# earlier. Therefore MISO has to be stable one clock cycle earlier then the
# original SCLK at the MB CPLD input. The effective SCLK signal to use for the
# timing constraints of the DB therefore has a low period which is reduced by 2
# clock cycles (R1 + R2) of PLL reference clock. It still has the same period as
# SCLK. In this example the low period would be 2 PRC cycles and the high period
# would be 6 PRC cycles.
# The following waveform illustrates the timing for n=2. Based on the defined
# delays <XXXX> denotes the time when the signal is not stable.
#
# <--- R1 --->|<-------- n=2 -------->|<--- R2 --->
# PRC ___/-----\_____/-----\_____/-----\_____/-----\_____/----
# SCLK ---\_______________________________________________/----
# SCLK @ DB (ideal) ---------------\________________________________________
# SCLK @ DB (effective) ---------------\_______________________/----------------
# MOSI output @ MB CPLD --------------<XXXX>------------------------------------
# MISO input @ MB CPLD -------------------------<XXXX>-------------------------
# DB propagation and processing <--------->
# MOSI change @ FPGA ^
# MOSI change @ MB CPLD ^
# MISO capture @ MB CPLD ^
# MISO capture @ FPGA ^
#
# Although the delays are defined based on PLL reference clock the SPI bus clock
# must be divided by at least n+2, where n>1 to be functional. Increase n in
# case the DB propagation and processing time does not fit into n PLL reference
# clock cycles taking the delays from below into account (see waveform above).
# Make sure you defined the SPI bus clock frequency for the slave to n*PLL clock
# period (effective SPI clock). Set the required SPI DB clock divider on the
# FPGA before starting data transfer.
#
# The constants for this interface are defined in db_spi_shared_constants.sdc
#### DB 0 ####
create_generated_clock -source [get_ports {PLL_REF_CLK}] \
-name db0_ctrl_clk_int [get_registers {DB_CTRL_SCLK[0]~reg0}]
create_generated_clock -source [get_registers {DB_CTRL_SCLK[0]~reg0}] \
-name db0_ctrl_clk [get_ports {DB_CTRL_SCLK[0]}]
set db0_ctrl_outputs [get_ports {DB_CTRL_MOSI[0] DB_CTRL_CS_N[0]}]
set_output_delay -clock db0_ctrl_clk -max $db_cpld_spi_max_out $db0_ctrl_outputs
set_output_delay -clock db0_ctrl_clk -min $db_cpld_spi_min_out $db0_ctrl_outputs
set db0_ctrl_inputs [get_ports {DB_CTRL_MISO[0]}]
set_input_delay -clock db0_ctrl_clk -max $db_cpld_spi_max_in $db0_ctrl_inputs
set_input_delay -clock db0_ctrl_clk -min $db_cpld_spi_min_in $db0_ctrl_inputs
#### DB 1 ####
create_generated_clock -source [get_ports {PLL_REF_CLK}] \
-name db1_ctrl_clk_int [get_registers {DB_CTRL_SCLK[1]~reg0}]
create_generated_clock -source [get_registers {DB_CTRL_SCLK[1]~reg0}] \
-name db1_ctrl_clk [get_ports DB_CTRL_SCLK[1]]
set db1_ctrl_outputs [get_ports {DB_CTRL_MOSI[1] DB_CTRL_CS_N[1]}]
set_output_delay -clock db1_ctrl_clk -max $db_cpld_spi_max_out $db1_ctrl_outputs
set_output_delay -clock db1_ctrl_clk -min $db_cpld_spi_min_out $db1_ctrl_outputs
set db1_ctrl_inputs [get_ports {DB_CTRL_MISO[1]}]
set_input_delay -clock db1_ctrl_clk -max $db_cpld_spi_max_in $db1_ctrl_inputs
set_input_delay -clock db1_ctrl_clk -min $db_cpld_spi_min_in $db1_ctrl_inputs
#####################################################################
# Power supply clocks, LEDs, DIO direction
#####################################################################
# Change all output signals in this section within one clock period of the
# driving clocks.
# Power supply clocks
set power_supply_clocks_outputs [get_ports {PWR_SUPPLY_CLK_*}]
set_min_delay -to $power_supply_clocks_outputs 0
set_max_delay -to $power_supply_clocks_outputs $CLK_100_period
# LED signals
set led_outputs [get_ports {QSFP0_LED_ACTIVE[*] QSFP0_LED_LINK[*] \
QSFP1_LED_ACTIVE[*] QSFP1_LED_LINK[*]}]
set_min_delay -to $led_outputs 0
set_max_delay -to $led_outputs $prc_clock_period
# DIO direction
set dio_outputs [get_ports {DIO_DIRECTION_A[*] DIO_DIRECTION_B[*]}]
set_min_delay -to $dio_outputs 0
set_max_delay -to $dio_outputs $clk50_period
# Power control
set pwr_ctrl_outputs [get_ports {IPASS_POWER_DISABLE PWR_EN_5V_OSC_100 PWR_EN_5V_OSC_122_88}]
set_min_delay -to $pwr_ctrl_outputs 0
set_max_delay -to $pwr_ctrl_outputs $clk50_period
# Power fault inputs
# Virtual clocks for constraining inputs. Using an odd clock period to
# make sure any uncovered paths will result in timing errors due to short setup
# or hold path.
set power_fault_inputs [get_ports {IPASS_POWER_EN_FAULT[*]}]
create_clock -name virtual_async_in_clk -period 4.567
set_input_delay -clock virtual_async_in_clk 0 $power_fault_inputs
#####################################################################
# FPGA <-> MB CPLD PS SPI interface
#####################################################################
# Assume the PS SPI clock is maximum 5 MHz.
# It is driven from another source and provided with the data.
set ps_sclk_period 200.000
create_clock -name ps_sclk -period $ps_sclk_period [get_ports PS_CPLD_SCLK]
# The SPI PS master (on the FPGA) is wired through the MIO (Multiplexed I/O)
# pins, meaning that the timing characteristics of the interface come from
# the controller itself (i.e. no timed routing through PL).
# Based on the SPI master controller specification (DS925: Table 48),
# one may define the min/max input/output delay constraints.
set ps_spi_tco_min -2.000
set ps_spi_tco_max 5.000
set ps_spi_miso_setup -2.000
set ps_spi_miso_hold [expr {0.3 * $ps_sclk_period}]
# Use the worst-case board propagation delays.
# Assuming 170.0 ps/in.
# Longest trace | Trace length | Trace delay
# CS0_n | 4.735 in | 0.805 ns
# --------------------------------------------
set ps_spi_board_delay 0.805
set ps_slave_inputs [get_ports {PS_CPLD_MOSI PS_CPLD_CS_N[*]}]
# clock is immediately available, data is taking maximum time
# SPI data in CPOL=CPHA=1 is driven on the falling sclk edge
set ps_sclk_max_in_delay [expr {$ps_spi_tco_max + $ps_spi_board_delay}]
set_input_delay -clock ps_sclk -clock_fall \
-max $ps_sclk_max_in_delay \
$ps_slave_inputs
# fast data and clock delayed (reducing data delay)
set_input_delay -clock ps_sclk -clock_fall \
-min [expr {$ps_spi_tco_min - $ps_spi_board_delay}] \
$ps_slave_inputs
set ps_slave_outputs [get_ports {PS_CPLD_MISO}]
# use only half the frequency because falling edge is driving data
set_output_delay -clock ps_sclk \
-max [expr {$ps_spi_miso_setup + 2*$ps_spi_board_delay}] \
$ps_slave_outputs
# use hold requirement only as clock and data propagation further
# delay the signal
set_output_delay -clock ps_sclk \
-min [expr {-$ps_spi_miso_hold}] \
$ps_slave_outputs
# Chip select signals are captured for binary decoding in 250 MHz clock domain.
# To be able to specify a maximum delay for the data path only a second set of
# input delays is added to the root clock of the 250 MHz domain.
set_input_delay -add_delay -clock CLK_100 0 [get_ports {PS_CPLD_CS_N[*]}]
# Declare paths between the 2 clock domains as false paths
set_false_path -from [get_clocks {CLK_100}] -to [get_ports {PS_CPLD_MISO}]
set_false_path -from [get_clocks {ps_sclk}] -to [get_registers {synchronizer:ps_spi_input_sync_inst*}]
# Specify maximum data path delay
set_max_delay -from [get_ports {PS_CPLD_CS_N[*]}] -to $CLK_250 $clk250_period
#####################################################################
# MB CPLD PS SPI passthrough
#####################################################################
###### Binary CS decoding ######
# The CS outputs for the external SPI slaves are driven from a 250 MHz clock to
# ensure glitch free switching after binary encoding. Additionally those signals
# have to meet the setup and hold requirements of the SPI slaves operating at
# ps_sclk (5 MHz). CS lines typically are asserted half a clock period of sclk
# before any active edge of sclk. The constraints below are using multi-cycle
# paths to provide the placer with information about the clock multiplier from
# ps_sclk to 250 MHz. Furthermore they incorporate the time required for
# decoding by lowering the clock multiplier as shown in the waveform below
# (multiplier is not shown correctly).
#
# ps_sclk -\__________________________________________________/--------
# 250 MHz _/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\-
# CS @ CPLD input X>--------------- stable ------------------------------------
# CS @ CPLD output ---------<XXXXXXX>-------------- stable ---------------------
# |<----->| min decoding delay
# |<----->| change window
# --------------->| SPI slave hold requirement
# SPI slave setup requirement |<-------------------------------->|
#
# Get port to apply the multi-cycle constraint.
set binary_cs_ports [get_ports {LMK32_CS_N TPM_CS_N PHASE_DAC_CS_N DB_CALEEPROM_CS_N[*] CLK_DB_CS_N}]
# Determine number of full 250 MHz periods within half a period of ps_sclk.
set ps_spi_clock_divider [expr {int($ps_sclk_period/$clk250_period/2)}]
# Setup multi-cycle accounts for
# - one clock cycle data path delay from port to first register stage
# - one clock cycle to resolve meta-stability
# - up to 3 register stages internally (port to ps_cpld_cs_n_shift3)
# - one output register stage (registers on each $binary_cs_ports)
# Static timing analysis will take the data path from register to output port
# into account.
# The number of 250 MHz periods is reduced by a total of 7 clock cycles (listed
# above) to match the SPI slave setup requirement time shown in the waveform
# above. The slave's setup time in ps_sclk domain is specified below for each
# individual slave.
set ps_spi_setup_multicycle [expr {$ps_spi_clock_divider - 7}]
set_multicycle_path -setup -start -to $binary_cs_ports $ps_spi_setup_multicycle
# Hold multicycle accounts for
# - min 2 synchronization register stages internally (ps_cpld_cs_n_shift2)
# (= min one clock cycle delay as data could arrive just before setup
# requirement of first register stages assuming no data delay)
# - one output register stage
# Static timing analysis will take the data path from register to output port
# into account.
# As the clock edge for hold analysis is shifted with the setup edge the number
# of multi cycles has to be increased by this amount of cycles to get back to
# the falling edge of ps_sclk. Furthermore CS lines are released one half
# ps_sclk period after the last data transfer. So hold delay is increased by an
# additional half clock cycle.
set ps_spi_hold_multicycle [expr {$ps_spi_clock_divider + $ps_spi_setup_multicycle - 2}]
set_multicycle_path -hold -start -to $binary_cs_ports $ps_spi_hold_multicycle
###### local SPI slave ######
# The chip select path for the MB CPLD itself is driven in the 250 MHz clock
# domain and captured by registers operating at ps_sclk. Therefore setting the
# path as false path preventing the placer from adding additional routing delay
# to ensure hold timing. The setup path is limited to a maximum extend of one
# clock period. As this path crosses clock domains clock propagation is included
# in this path during static timing analysis. The TCL analysis in
# scripts/ps_cs_analysis.tcl ensures a maximum value for data excluding the
# clocking network.
set_false_path -from [get_registers {ps_spi_cs_n_decoded[0]}] -hold
set_max_delay -from [get_registers {ps_spi_cs_n_decoded[0]}] $clk250_period
###### LMK04832 ######
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name lmk_spi_sclk [get_ports LMK32_SCLK]
# Use the worst-case board propagation delays.
# Assuming 170.0 ps/in.
# Longest trace | Trace length | Trace delay
# LMK32_SCLK | 8.259 in | 1.404 ns
# --------------------------------------------
set lmk_board_delay 1.404
# setup and hold dominated by CS <-> SCK relationship
set lmk_setup 20.000
set lmk_hold 20.000
set lmk_tco_max 60.000
set lmk_outputs [get_ports {LMK32_MOSI LMK32_CS_N}]
set_output_delay -clock lmk_spi_sclk \
-max [expr {$lmk_setup + $lmk_board_delay + $buffer_prop_max}] \
$lmk_outputs
set_output_delay -clock lmk_spi_sclk \
-min [expr {-$lmk_hold - $lmk_board_delay - $buffer_prop_min}] \
$lmk_outputs
set lmk_inputs [get_ports {LMK32_MISO}]
set_input_delay -clock lmk_spi_sclk -clock_fall \
-max [expr {$lmk_tco_max + 2*$lmk_board_delay + 2*$buffer_prop_max}] \
$lmk_inputs
set_input_delay -clock lmk_spi_sclk -clock_fall \
-min [expr {2*$buffer_prop_min}] \
$lmk_inputs
###### Phase DAC ######
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name phase_dac_spi_sclk [get_ports PHASE_DAC_SCLK]
# Use the worst-case board propagation delays.
# Assuming 170.0 ps/in.
# Longest trace | Trace length | Trace delay
# SpiDCs3v3_n | 8.322 in | 1.415 ns
# --------------------------------------------
set phase_dac_board_delay 1.415
#setup dominated by SYNC signal
set phase_dac_setup 13.000
set phase_dac_hold 5.000
# device captures data on falling clock edge (CPOL = 1)
# constraining it as it would be like all the other SPI modules
# PS SPI master is responsible for changing SPI mode when talking
# to this device
set phase_dac_outputs [get_ports {PHASE_DAC_MOSI PHASE_DAC_CS_N}]
set_output_delay -clock phase_dac_spi_sclk -clock_fall \
-max [expr {$phase_dac_setup + $phase_dac_board_delay}] \
$phase_dac_outputs
set_output_delay -clock phase_dac_spi_sclk -clock_fall \
-min [expr {-$phase_dac_hold - $phase_dac_board_delay}] \
$phase_dac_outputs
###### TPM ######
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name tpm_spi_sclk [get_ports TPM_SCLK]
# Use the worst-case board propagation delays.
# Assuming 170.0 ps/in.
# Longest trace | Trace length | Trace delay
# TPM_CS_n | 1.128 in | 0.196 ns
# --------------------------------------------
set tpm_board_delay 0.196
#tco dominated by NSS signal
set tpm_setup 5.000
set tpm_hold 5.000
set tpm_tco_max 25.000
set tpm_outputs [get_ports {TPM_MOSI TPM_CS_N}]
set_output_delay -clock tpm_spi_sclk \
-max [expr {$tpm_setup + $tpm_board_delay}] \
$tpm_outputs
set_output_delay -clock tpm_spi_sclk \
-min [expr {-$tpm_hold - $tpm_board_delay}] \
$tpm_outputs
set tpm_inputs [get_ports {TPM_MISO}]
set_input_delay -clock tpm_spi_sclk -clock_fall \
-max [expr {$tpm_tco_max + 2*$tpm_board_delay}] \
$tpm_inputs
set_input_delay -clock tpm_spi_sclk -clock_fall \
-min 0 \
$tpm_inputs
###### DB Calibration EEPROM ######
# Use worst case board propagation delays to estimate input and output
# timing. The longest path assuming 170 ps/in is:
# db0_caleeprom_spi_cs_n | 4.387 in | 0.746 ns
set eeprom_board_prop_delay 0.746
# Within the path to the EEPROM on the DB there is a level-transistor.
# The maximum propagation delays are 0.1..3.3 ns to the DB and 3.7 ns from the DB.
set eeprom_lvl_trans_to_db_delay_min 0.1
set eeprom_lvl_trans_to_db_delay_max 3.3
set eeprom_lvl_trans_from_db_delay_max 3.7
# Data in setup and hold times of the EEPROM are 5ns (based on the
# CS_N setup and hold times).
set db_eeprom_setup 5
set db_eeprom_hold 5
# Ouput valid from SCK is min 0 ns and max 8 ns.
set db_eeprom_output_valid 8
# max out path assuming clock delay is 0 and data delay is maximum value
set eeprom_max_out [expr {$eeprom_board_prop_delay + $eeprom_lvl_trans_to_db_delay_max + $db_eeprom_setup}]
# min out path assuming clock delay is maximal and data delay is 0
set eeprom_min_out [expr {-($eeprom_board_prop_delay + $eeprom_lvl_trans_to_db_delay_min + $db_eeprom_hold)}]
# board propagation to eeprom and back + lvl_translator back and forth + clock to data on eeprom
set eeprom_max_in [expr {$eeprom_board_prop_delay*2 + $eeprom_lvl_trans_to_db_delay_max + $eeprom_lvl_trans_from_db_delay_max + $db_eeprom_output_valid}]
# assuming no delay for everything
set eeprom_min_in 0
### DB 0
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name db0_eeprom_clk [get_ports {DB_CALEEPROM_SCLK[0]}]
set db0_eeprom_outputs [get_ports {DB_CALEEPROM_MOSI[0] DB_CALEEPROM_CS_N[0]}]
set_output_delay -clock db0_eeprom_clk -max $eeprom_max_out $db0_eeprom_outputs
set_output_delay -clock db0_eeprom_clk -min $eeprom_min_out $db0_eeprom_outputs
set db0_eeprom_inputs [get_ports {DB_CALEEPROM_MISO[0]}]
# data is changed on the falling edge
set_input_delay -clock db0_eeprom_clk -clock_fall -max $eeprom_max_in $db0_eeprom_inputs
set_input_delay -clock db0_eeprom_clk -clock_fall -min $eeprom_min_in $db0_eeprom_inputs
### DB 1
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name db1_eeprom_clk [get_ports {DB_CALEEPROM_SCLK[1]}]
set db1_eeprom_outputs [get_ports {DB_CALEEPROM_MOSI[1] DB_CALEEPROM_CS_N[1]}]
set_output_delay -clock db1_eeprom_clk -max $eeprom_max_out $db1_eeprom_outputs
set_output_delay -clock db1_eeprom_clk -min $eeprom_min_out $db1_eeprom_outputs
set db1_eeprom_inputs [get_ports {DB_CALEEPROM_MISO[1]}]
# data is changed on the falling edge
set_input_delay -clock db1_eeprom_clk -clock_fall -max $eeprom_max_in $db1_eeprom_inputs
set_input_delay -clock db1_eeprom_clk -clock_fall -min $eeprom_min_in $db1_eeprom_inputs
#### Clocking AUX board SPI interface ####
# Rev B clocking aux board uses a LMK05318 connected to this interface
# Using its timing for this interface.
create_generated_clock -source [get_ports PS_CPLD_SCLK] \
-name clk_db_clk_out [get_ports CLK_DB_SCLK]
set clk_db_setup 10.000
set clk_db_hold 10.000
set clk_db_tco_max 20.000
# Just a worst case assumption based on 2 times the MB trace length CLK_DB_MOSI.
# The multiplier 2 accounts for any traces on the CLK AUX board.
set clk_db_board_delay 4.000
set clk_db_outputs [get_ports {CLK_DB_CS_N CLK_DB_MOSI}]
# Output signals have to stable for max setup and propagation time. Clock delay
# to device is expected to be 0 in this equation.
set_output_delay -clock clk_db_clk_out \
-max [expr {$clk_db_setup + $clk_db_board_delay + $buffer_prop_max}] $clk_db_outputs
# The min output delay is comprised of:
# - device required hold time ($clk_db_hold)
# - max clock propagation delay ($clk_db_board_delay)
# - min data propagation time (0)
# All terms have to be negated as min output delay is defined in opposite
# direction (positive into the past).
set_output_delay -clock clk_db_clk_out \
-min [expr {-$clk_db_hold - $clk_db_board_delay - $buffer_prop_min}] $clk_db_outputs
set clk_db_inputs [get_ports {CLK_DB_MISO}]
# Max delay calculated is based on
# - max clock delay ($clk_db_board_delay)
# - max clock to out LMK ($clk_db_tco_max)
# - max data path delay ($clk_db_board_delay)
set_input_delay -clock clk_db_clk_out -clock_fall \
-max [expr {$clk_db_tco_max + $clk_db_board_delay*2 + 2*$buffer_prop_max}] $clk_db_inputs
# Min delay assumes clock propagates to device and data propagates to CPLD
# without any delays.
set_input_delay -clock clk_db_clk_out -clock_fall \
-min [expr {2*$buffer_prop_min}] $clk_db_inputs
#####################################################################
# PCIe signals
#####################################################################
# I²C bus is operated at 100kHz. Constraints would not improve timing
# significantly (typically in the order of nanoseconds, which is negligible
# given the SCL period of 10 us).
# PCI-Express reset signal is not timing critical as it is received
# asynchronously by the FPGA.
set_false_path -to [get_ports {IPASS_SDA[0] IPASS_SCL[0] PCIE_RESET}]
# I²C inputs are only consumed by synchronizers.
# Add exceptions for all known consumers.
set_false_path -to [get_registers {PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix|UsfCablePort:UsfCablePortx|CablePort:CablePortx|I2cTop:CableI2cx|I2cMonitor:I2cMonitorx|I2cFilter:I2cFilterx|I2cSigFilter:SclFilterx|fSig_ms}]
set_false_path -to [get_registers {PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix|UsfCablePort:UsfCablePortx|CablePort:CablePortx|I2cTop:CableI2cx|I2cMonitor:I2cMonitorx|I2cFilter:I2cFilterx|I2cSigFilter:SdaFilterx|fSig_ms}]
set_false_path -to [get_registers {PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix|UsfCablePort:UsfCablePortx|CablePort:CablePortx|StuckBusFixer:StuckBusFixerx|DoubleSyncSlAsyncIn:DoubleSclkx|DoubleSyncAsyncInBase:DoubleSyncAsyncInBasex|DFlopAsync:oSig_msx|lpm_ff:LPM_FFx|dffs[0]}]
set_false_path -to [get_registers {PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix|UsfCablePort:UsfCablePortx|CablePort:CablePortx|StuckBusFixer:StuckBusFixerx|DoubleSyncSlAsyncIn:DoubleSdax|DoubleSyncAsyncInBase:DoubleSyncAsyncInBasex|DFlopAsync:oSig_msx|lpm_ff:LPM_FFx|dffs[0]}]
#####################################################################
# Known Issue of On-Chip Flash
#####################################################################
# see https://www.intel.com/content/www/us/en/programmable/support/support-resources/knowledge-base/tools/2016/warning--332060---node---alteraonchipflash-onchipflash-alteraonc.html
create_generated_clock -name flash_se_neg_reg \
-source [get_pins { on_chip_flash:flash_inst|altera_onchip_flash:onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|clk }] \
-divide_by 2 [get_pins { on_chip_flash:flash_inst|altera_onchip_flash:onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|q } ]
#####################################################################
# Clock uncertainty
#####################################################################
# Assign some uncertainty to all clocks
set clock_uncertainty 0.150
set_clock_uncertainty -to [get_clocks *] $clock_uncertainty
derive_clock_uncertainty
-297
View File
@@ -1,297 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: pl_cpld_regs
//
// Description:
//
// Basic Registers to inform software about version and capabilities.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers
//
`default_nettype none
module pl_cpld_regs #(
parameter BASE_ADDRESS = 0
) (
input wire ctrlport_clk,
input wire ctrlport_rst,
// Request
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
// Response
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status,
output reg [31:0] s_ctrlport_resp_data,
// QSFP LEDs
// Port 0
output wire [ 3:0] qsfp0_led_active,
output wire [ 3:0] qsfp0_led_link,
// Port 1
output wire [ 3:0] qsfp1_led_active,
output wire [ 3:0] qsfp1_led_link,
// iPass status
output wire [ 1:0] ipass_cable_present
);
`include "regmap/constants_regmap_utils.vh"
`include "regmap/pl_cpld_base_regmap_utils.vh"
`include "../../../lib/rfnoc/core/ctrlport.vh"
//---------------------------------------------------------------------------
// Address Calculation
//---------------------------------------------------------------------------
localparam NUM_ADDRESSES = 64;
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
//---------------------------------------------------------------------------
// Internal Registers
//---------------------------------------------------------------------------
reg [SCRATCH_REGISTER_SIZE-1:0] scratch_reg;
reg [LED_REGISTER_SIZE-1:0] led_reg;
reg [CABLE_PRESENT_REG_SIZE-1:0] ipass_reg;
//---------------------------------------------------------------------------
// Assign Outputs
//---------------------------------------------------------------------------
assign qsfp0_led_active = led_reg[QSFP0_LED_ACTIVE+:QSFP0_LED_ACTIVE_SIZE];
assign qsfp0_led_link = led_reg[QSFP0_LED_LINK+:QSFP0_LED_LINK_SIZE];
assign qsfp1_led_active = led_reg[QSFP1_LED_ACTIVE+:QSFP1_LED_ACTIVE_SIZE];
assign qsfp1_led_link = led_reg[QSFP1_LED_LINK+:QSFP1_LED_LINK_SIZE];
assign ipass_cable_present = ipass_reg;
//---------------------------------------------------------------------------
// Handling of ControlPort Requests
//---------------------------------------------------------------------------
always @(posedge ctrlport_clk) begin
// Reset internal registers and responses
if (ctrlport_rst) begin
scratch_reg <= 0;
led_reg <= 0;
ipass_reg <= 0;
s_ctrlport_resp_ack <= 1'b0;
// Write requests
end else if (s_ctrlport_req_wr) begin
// Always issue an ack and no data
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
case (s_ctrlport_req_addr)
BASE_ADDRESS + SCRATCH_REGISTER:
scratch_reg <= s_ctrlport_req_data;
BASE_ADDRESS + LED_REGISTER:
led_reg <= s_ctrlport_req_data[LED_REGISTER_SIZE-1:0];
BASE_ADDRESS + CABLE_PRESENT_REG: begin
ipass_reg[0] <= s_ctrlport_req_data[IPASS0_CABLE_PRESENT];
ipass_reg[1] <= s_ctrlport_req_data[IPASS1_CABLE_PRESENT];
end
// Error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// Read request
end else if (s_ctrlport_req_rd) begin
// Default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
case (s_ctrlport_req_addr)
BASE_ADDRESS + SIGNATURE_REGISTER:
s_ctrlport_resp_data <= PL_CPLD_SIGNATURE;
BASE_ADDRESS + REVISION_REGISTER:
s_ctrlport_resp_data <= CPLD_REVISION;
BASE_ADDRESS + OLDEST_COMPATIBLE_REVISION_REGISTER:
s_ctrlport_resp_data <= OLDEST_CPLD_REVISION;
BASE_ADDRESS + SCRATCH_REGISTER:
s_ctrlport_resp_data <= scratch_reg;
BASE_ADDRESS + GIT_HASH_REGISTER:
`ifdef GIT_HASH
s_ctrlport_resp_data <= `GIT_HASH;
`else
s_ctrlport_resp_data <= 32'hDEADBEEF;
`endif
BASE_ADDRESS + LED_REGISTER:
s_ctrlport_resp_data <= {{(CTRLPORT_DATA_W - LED_REGISTER_SIZE){1'b0}}, led_reg};
BASE_ADDRESS + CABLE_PRESENT_REG: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
s_ctrlport_resp_data[IPASS0_CABLE_PRESENT] <= ipass_reg[0];
s_ctrlport_resp_data[IPASS1_CABLE_PRESENT] <= ipass_reg[1];
end
// Error on undefined address
default: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}};
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// No request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="PL_CPLD_BASE_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="PL_CPLD_BASE_REGS">
// <info>
// Basic registers containing version and capabilities information.
// </info>
//
// <register name="SIGNATURE_REGISTER" offset="0x00" writable="false" size="32">
// <info>Contains the product's signature.</info>
// <bitfield name="PRODUCT_SIGNATURE" range="31..0">
// <info>Fixed value PL_CPLD_SIGNATURE of @.CONSTANTS_REGMAP</info>
// </bitfield>
// </register>
//
// <register name="REVISION_REGISTER" offset="0x04" writable="false" size="32">
// <info>Contains the CPLD revision (see CPLD_REVISION of @.CONSTANTS_REGMAP)</info>
// <bitfield name="REVISION_HH" range="7..0">
// <info>Contains revision hour code.</info>
// </bitfield>
// <bitfield name="REVISION_DD" range="15..8">
// <info>Contains revision day code.</info>
// </bitfield>
// <bitfield name="REVISION_MM" range="23..16">
// <info>Contains revision month code.</info>
// </bitfield>
// <bitfield name="REVISION_YY" range="31..24">
// <info>Contains revision year code.</info>
// </bitfield>
// </register>
//
// <register name="OLDEST_COMPATIBLE_REVISION_REGISTER" offset="0x08" writable="false" size="32">
// <info>
// This register returns (in YYMMDDHH format) the oldest revision
// that is still compatible with this one. Compatible means that
// registers or register bits may have been added, but not
// modified or deleted (see OLDEST_CPLD_REVISION of @.CONSTANTS_REGMAP).
// </info>
// <bitfield name="OLD_REVISION_HH" range="7..0">
// <info>Contains revision hour code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_DD" range="15..8">
// <info>Contains revision day code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_MM" range="23..16">
// <info>Contains revision month code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_YY" range="31..24">
// <info>Contains revision year code.</info>
// </bitfield>
// </register>
//
// <register name="SCRATCH_REGISTER" offset="0x0C" size="32">
// <info>Read/write register for general software use.</info>
// </register>
//
// <register name="GIT_HASH_REGISTER" offset="0x10" size="32" writable="false">
// <info>
// Git hash of commit used to build this image.{br}
// Value equals 0xDEADBEEF if the git hash was not used during synthesis.
// </info>
// <bitfield name="GIT_CLEAN" range="31..28">
// <info>
// 0x0 in case the git status was clean{br}
// 0xF in case there were uncommitted changes
// </info>
// </bitfield>
// <bitfield name="GIT_HASH" range="27..0">
// <info>7 hex digit hash code of the commit</info>
// </bitfield>
// </register>
// </group>
//
// <group name="MB_CPLD_LED_REGS">
// <info>
// Register Map to control QSFP LEDs.
// </info>
// <register name="LED_REGISTER" offset="0x20" size="16">
// <info>
// Provides to the LEDs of the QSFP ports.
// Write access will directly change the LED status.
// The LED lights up if the corresponding bit is set.
// </info>
// <bitfield name="QSFP0_LED_LINK" range="3..0">
// <info>Link LEDs of QSFP port 0</info>
// </bitfield>
// <bitfield name="QSFP0_LED_ACTIVE" range="7..4">
// <info>Active LEDs of QSFP port 0</info>
// </bitfield>
// <bitfield name="QSFP1_LED_LINK" range="11..8">
// <info>Link LEDs of QSFP port 1</info>
// </bitfield>
// <bitfield name="QSFP1_LED_ACTIVE" range="15..12">
// <info>Active LEDs of QSFP port 1</info>
// </bitfield>
// </register>
// </group>
//
// <group name="PL_CMI_REGS">
// <info>
// Cable present status register.
// </info>
// <register name="CABLE_PRESENT_REG" offset="0x30" size="2">
// <info>
// Information from FPGA about the cable present status.
// </info>
// <bitfield name="IPASS0_CABLE_PRESENT" range="0">
// <info>Set to 1 if cable present in iPass 0 connector.</info>
// </bitfield>
// <bitfield name="IPASS1_CABLE_PRESENT" range="1">
// <info>Set to 1 if cable present in iPass 1 connector.</info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off
-404
View File
@@ -1,404 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: ps_cpld_regs
//
// Description:
//
// Basic registers to inform software about version and capabilities.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers
//
`default_nettype none
module ps_cpld_regs #(
parameter BASE_ADDRESS = 0
) (
input wire ctrlport_clk,
input wire ctrlport_rst,
// Request
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
// Response
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status,
output reg [31:0] s_ctrlport_resp_data,
// Configuration outputs
output reg [ 1:0] db_clk_enable = 2'b00,
output reg [ 1:0] db_reset = 2'b11,
output reg pll_ref_clk_enable = 1'b0,
output reg [11:0] dio_direction_a = 12'b0,
output reg [11:0] dio_direction_b = 12'b0,
output reg [39:0] serial_num = 40'b0,
output reg cmi_ready = 1'b0,
input wire cmi_other_side_detected
);
`include "regmap/constants_regmap_utils.vh"
`include "regmap/ps_cpld_base_regmap_utils.vh"
`include "../../../lib/rfnoc/core/ctrlport.vh"
//-----------------------------------------------------------------------------
// Address Calculation
//-----------------------------------------------------------------------------
localparam NUM_ADDRESSES = 64;
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
//-----------------------------------------------------------------------------
// Internal Registers
//-----------------------------------------------------------------------------
reg [SCRATCH_REGISTER_SIZE-1:0] scratch_reg;
//-----------------------------------------------------------------------------
// Handling of ControlPort Requests
//-----------------------------------------------------------------------------
always @(posedge ctrlport_clk) begin
// Reset internal registers and responses
if (ctrlport_rst) begin
scratch_reg <= 0;
db_clk_enable <= 2'b00;
db_reset <= 2'b11;
pll_ref_clk_enable <= 1'b0;
dio_direction_a <= {DIO_DIRECTION_A_SIZE{1'b0}};
dio_direction_b <= {DIO_DIRECTION_B_SIZE{1'b0}};
s_ctrlport_resp_ack <= 1'b0;
s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
// Write requests
end else begin
if (s_ctrlport_req_wr) begin
// Always issue an ack and no data
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
case (s_ctrlport_req_addr)
BASE_ADDRESS + SCRATCH_REGISTER:
scratch_reg <= s_ctrlport_req_data;
BASE_ADDRESS + PL_DB_REGISTER: begin
if (s_ctrlport_req_data[DISABLE_CLOCK_DB0]) begin
db_clk_enable[0] <= 1'b0;
end else if (s_ctrlport_req_data[ENABLE_CLOCK_DB0]) begin
db_clk_enable[0] <= 1'b1;
end
if (s_ctrlport_req_data[DISABLE_CLOCK_DB1]) begin
db_clk_enable[1] <= 1'b0;
end else if (s_ctrlport_req_data[ENABLE_CLOCK_DB1]) begin
db_clk_enable[1] <= 1'b1;
end
if (s_ctrlport_req_data[DISABLE_PLL_REF_CLOCK]) begin
pll_ref_clk_enable <= 1'b0;
end else if (s_ctrlport_req_data[ENABLE_PLL_REF_CLOCK]) begin
pll_ref_clk_enable <= 1'b1;
end
if (s_ctrlport_req_data[ASSERT_RESET_DB0]) begin
db_reset[0] <= 1'b1;
end else if (s_ctrlport_req_data[RELEASE_RESET_DB0]) begin
db_reset[0] <= 1'b0;
end
if (s_ctrlport_req_data[ASSERT_RESET_DB1]) begin
db_reset[1] <= 1'b1;
end else if (s_ctrlport_req_data[RELEASE_RESET_DB1]) begin
db_reset[1] <= 1'b0;
end
end
BASE_ADDRESS + DIO_DIRECTION_REGISTER: begin
dio_direction_a <= s_ctrlport_req_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A];
dio_direction_b <= s_ctrlport_req_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B];
end
BASE_ADDRESS + SERIAL_NUM_LOW_REG: begin
serial_num[31:0] <= s_ctrlport_req_data;
end
BASE_ADDRESS + SERIAL_NUM_HIGH_REG: begin
serial_num[39:32] <= s_ctrlport_req_data[SERIAL_NUM_HIGH_REG_SIZE-1:0];
end
BASE_ADDRESS + CMI_CONTROL_STATUS: begin
cmi_ready <= s_ctrlport_req_data[CMI_READY];
end
// Error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// Read request
end else if (s_ctrlport_req_rd) begin
// Default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
case (s_ctrlport_req_addr)
BASE_ADDRESS + SIGNATURE_REGISTER:
s_ctrlport_resp_data <= PS_CPLD_SIGNATURE;
BASE_ADDRESS + REVISION_REGISTER:
s_ctrlport_resp_data <= CPLD_REVISION;
BASE_ADDRESS + OLDEST_COMPATIBLE_REVISION_REGISTER:
s_ctrlport_resp_data <= OLDEST_CPLD_REVISION;
BASE_ADDRESS + SCRATCH_REGISTER:
s_ctrlport_resp_data <= scratch_reg;
BASE_ADDRESS + GIT_HASH_REGISTER:
`ifdef GIT_HASH
s_ctrlport_resp_data <= `GIT_HASH;
`else
s_ctrlport_resp_data <= 32'hDEADBEEF;
`endif
BASE_ADDRESS + PL_DB_REGISTER: begin
s_ctrlport_resp_data[DB0_CLOCK_ENABLED] <= db_clk_enable[0];
s_ctrlport_resp_data[DB1_CLOCK_ENABLED] <= db_clk_enable[1];
s_ctrlport_resp_data[PLL_REF_CLOCK_ENABLED] <= pll_ref_clk_enable;
s_ctrlport_resp_data[DB0_RESET_ASSERTED] <= db_reset[0];
s_ctrlport_resp_data[DB1_RESET_ASSERTED] <= db_reset[1];
end
BASE_ADDRESS + DIO_DIRECTION_REGISTER: begin
s_ctrlport_resp_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A] <= dio_direction_a;
s_ctrlport_resp_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B] <= dio_direction_b;
end
BASE_ADDRESS + SERIAL_NUM_LOW_REG: begin
s_ctrlport_resp_data <= serial_num[31:0];
end
BASE_ADDRESS + SERIAL_NUM_HIGH_REG: begin
s_ctrlport_resp_data[SERIAL_NUM_HIGH_REG_SIZE-1:0] <= serial_num[39:32];
end
BASE_ADDRESS + CMI_CONTROL_STATUS: begin
s_ctrlport_resp_data[CMI_READY] <= cmi_ready;
s_ctrlport_resp_data[OTHER_SIDE_DETECTED] <= cmi_other_side_detected;
end
// Error on undefined address
default: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}};
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// No request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
end
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="PS_CPLD_BASE_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="PS_CPLD_BASE_REGS">
// <info>
// Basic registers containing version and capabilites information.
// </info>
//
// <register name="SIGNATURE_REGISTER" offset="0x00" writable="false" size="32">
// <info>Contains the product's signature.</info>
// <bitfield name="PRODUCT_SIGNATURE" range="31..0">
// <info>Fixed value PS_CPLD_SIGNATURE of @.CONSTANTS_REGMAP</info>
// </bitfield>
// </register>
//
// <register name="REVISION_REGISTER" offset="0x04" writable="false" size="32">
// <info>Contains the CPLD revision (see CPLD_REVISION of @.CONSTANTS_REGMAP).</info>
// <bitfield name="REVISION_HH" range="7..0">
// <info>Contains revision hour code.</info>
// </bitfield>
// <bitfield name="REVISION_DD" range="15..8">
// <info>Contains revision day code.</info>
// </bitfield>
// <bitfield name="REVISION_MM" range="23..16">
// <info>Contains revision month code.</info>
// </bitfield>
// <bitfield name="REVISION_YY" range="31..24">
// <info>Contains revision year code.</info>
// </bitfield>
// </register>
//
// <register name="OLDEST_COMPATIBLE_REVISION_REGISTER" offset="0x08" writable="false" size="32">
// <info>
// This register returns (in YYMMDDHH format) the oldest revision
// that is still compatible with this one. Compatible means that
// registers or register bits may have been added, but not
// modified or deleted (see OLDEST_CPLD_REVISION of @.CONSTANTS_REGMAP).
// </info>
// <bitfield name="OLD_REVISION_HH" range="7..0">
// <info>Contains revision hour code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_DD" range="15..8">
// <info>Contains revision day code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_MM" range="23..16">
// <info>Contains revision month code.</info>
// </bitfield>
// <bitfield name="OLD_REVISION_YY" range="31..24">
// <info>Contains revision year code.</info>
// </bitfield>
// </register>
//
// <register name="SCRATCH_REGISTER" offset="0x0C" size="32">
// <info>Read/write register for general software use.</info>
// </register>
//
// <register name="GIT_HASH_REGISTER" offset="0x10" size="32" writable="false">
// <info>
// Git hash of commit used to build this image.{br}
// Value equals 0xDEADBEEF if the git hash was not used during synthesis.
// </info>
// <bitfield name="GIT_CLEAN" range="31..28">
// <info>
// 0x0 in case the git status was clean{br}
// 0xF in case there were uncommitted changes
// </info>
// </bitfield>
// <bitfield name="GIT_HASH" range="27..0">
// <info>7 hex digit hash code of the commit</info>
// </bitfield>
// </register>
// </group>
//
// <group name="PS_CONTROL_REGS">
// <info>
// Register Map to control MB CPLD functions.
// </info>
// <register name="PL_DB_REGISTER" offset="0x20" size="32">
// <info>
// Register to control the PL part DB SPI connection and reset generation.
// The DB connection is clocked with PLL reference clock. Ensure this clock is stable
// and enabled before starting any SPI request.
// The PLL reference clock can be disabled if both DB connections are disabled or inactive.
// To enable the DB connection, enable clock with one write access and release
// reset with the next write access.
// To disable the DB connection, assert reset with one write access and
// disable clocks with the next write access.
// </info>
// <bitfield name="DB0_CLOCK_ENABLED" range="0" writable="false">
// <info>Indicates if a clock is forwarded to DB 0.</info>
// </bitfield>
// <bitfield name="DB1_CLOCK_ENABLED" range="1" writable="false">
// <info>Indicates if a clock is forwarded to DB 1.</info>
// </bitfield>
// <bitfield name="PLL_REF_CLOCK_ENABLED" range="2" writable="false">
// <info>Indicates if the PLL reference clock for the PL interface is enabled.</info>
// </bitfield>
// <bitfield name="DB0_RESET_ASSERTED" range="4" writable="false">
// <info>Indicates that reset is asserted for DB 0.</info>
// </bitfield>
// <bitfield name="DB1_RESET_ASSERTED" range="5" writable="false">
// <info>Indicates that reset is asserted for DB 1.</info>
// </bitfield>
// <bitfield name="ENABLE_CLOCK_DB0" range="8" readable="false">
// <info>Writing with this flag set enables DB 0 clock forwarding. (may be overwritten by @.DISABLE_CLOCK_DB0)</info>
// </bitfield>
// <bitfield name="ENABLE_CLOCK_DB1" range="9" readable="false">
// <info>Writing with this flag set enables DB 1 clock forwarding. (may be overwritten by @.DISABLE_CLOCK_DB1)</info>
// </bitfield>
// <bitfield name="ENABLE_PLL_REF_CLOCK" range="10" readable="false">
// <info>Writing with this flag set enables the PLL reference clock. Assert this flag after PLL reference clock is stable. (may be overwritten by @.DISABLE_PLL_REF_CLOCK)</info>
// </bitfield>
// <bitfield name="DISABLE_CLOCK_DB0" range="12" readable="false">
// <info>Writing with this flag set disables DB 0 clock forwarding (overrides @.ENABLE_CLOCK_DB0)</info>
// </bitfield>
// <bitfield name="DISABLE_CLOCK_DB1" range="13" readable="false">
// <info>Writing with this flag set disables DB 1 clock forwarding (overrides @.ENABLE_CLOCK_DB1)</info>
// </bitfield>
// <bitfield name="DISABLE_PLL_REF_CLOCK" range="14" readable="false">
// <info>Writing with this flag set disables the PLL reference clock (overrides @.ENABLE_PLL_REF_CLOCK). Assert this flag to reconfigure the clock.</info>
// </bitfield>
// <bitfield name="RELEASE_RESET_DB0" range="16" readable="false">
// <info>Writing with this flag set releases DB 0 reset. (may be overwritten by @.ASSERT_RESET_DB0)</info>
// </bitfield>
// <bitfield name="RELEASE_RESET_DB1" range="17" readable="false">
// <info>Writing with this flag set releases DB 1 reset. (may be overwritten by @.ASSERT_RESET_DB1)</info>
// </bitfield>
// <bitfield name="ASSERT_RESET_DB0" range="20" readable="false">
// <info>Writing with this flag set asserts reset for DB 0 (overrides @.RELEASE_RESET_DB0)</info>
// </bitfield>
// <bitfield name="ASSERT_RESET_DB1" range="21" readable="false">
// <info>Writing with this flag set asserts reset for DB 1 (overrides @.RELEASE_RESET_DB1)</info>
// </bitfield>
// </register>
// </group>
//
// <group name="DIO_REGS">
// <info>
// Registers to control the GPIO buffer direction on the DIO board connected to the FPGA.
// Make sure the GPIO lines between FPGA and GPIO board are not driven by two drivers.
// Set the direction in the FPGA's DIO register appropriately.
// </info>
// <register name="DIO_DIRECTION_REGISTER" offset="0x30" size="32">
// <info>
// Set the direction of FPGA buffer connected to DIO ports on the DIO board.{br/}
// Each bit represents one signal line. 0 = line is an input to the FPGA, 1 = line is an output driven by the FPGA.
// </info>
// <bitfield name="DIO_DIRECTION_A" range="11..0" initialvalue="0"/>
// <bitfield name="DIO_DIRECTION_B" range="27..16" initialvalue="0"/>
// </register>
// </group>
//
// <group name="PS_CMI_REGS">
// <info>
// Cable present status register.
// </info>
// <register name="SERIAL_NUM_LOW_REG" offset="0x34" size="32">
// <info>Least significant bytes of 5 byte serial number.</info>
// </register>
// <register name="SERIAL_NUM_HIGH_REG" offset="0x38" size="8">
// <info>Most significant byte of 5 byte serial number.</info>
// </register>
// <register name="CMI_CONTROL_STATUS" offset="0x3C" size="32">
// <info>Control CMI communication and delivers information on the CMI link status.</info>
// <bitfield name="CMI_READY" range="0">
// <info>Set if the device is ready to establish a PCI-Express link (affects CMI_CLP_READY bit).</info>
// </bitfield>
// <bitfield name="OTHER_SIDE_DETECTED" range="31" writable="false">
// <info>1 if an upstream CMI device has been detected.</info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off
-231
View File
@@ -1,231 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: ps_power_regs
//
// Description:
//
// Registers to control power supplies on the motherboard.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers.
// NUM_ADDRESSES : Number of bytes of address space to use.
//
`default_nettype none
module ps_power_regs #(
parameter BASE_ADDRESS = 0,
parameter NUM_ADDRESSES = 32
) (
input wire ctrlport_clk,
input wire ctrlport_rst,
// Request
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
// Response
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status,
output reg [31:0] s_ctrlport_resp_data,
// iPass
output reg ipass_power_disable = 1'b0,
input wire [ 1:0] ipass_power_fault_n,
// Oscillators
output reg osc_100_en,
output reg osc_122_88_en
);
`include "regmap/ps_power_regmap_utils.vh"
`include "../../../lib/rfnoc/core/ctrlport.vh"
//----------------------------------------------------------
// Address Calculation
//----------------------------------------------------------
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
//----------------------------------------------------------
// Internal Registers
//----------------------------------------------------------
reg [1:0] ipass_power_sticky = 2'b00;
reg [1:0] ipass_clear_sticky = 2'b00;
//----------------------------------------------------------
// Handling of ControlPort Requests
//----------------------------------------------------------
always @(posedge ctrlport_clk) begin
// Reset internal registers and responses
if (ctrlport_rst) begin
ipass_power_disable <= 1'b0;
s_ctrlport_resp_ack <= 1'b0;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}};
osc_100_en <= 1'b0;
osc_122_88_en <= 1'b0;
end else begin
// Default assignments
ipass_clear_sticky <= 2'b00;
// Write requests
if (s_ctrlport_req_wr) begin
// Always issue an ack and no data
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}};
case (s_ctrlport_req_addr)
BASE_ADDRESS + IPASS_POWER_REG: begin
ipass_power_disable <= s_ctrlport_req_data[IPASS_DISABLE_POWER_BIT];
ipass_clear_sticky[0] <= s_ctrlport_req_data[IPASS_CLEAR_POWER_FAULT0];
ipass_clear_sticky[1] <= s_ctrlport_req_data[IPASS_CLEAR_POWER_FAULT1];
end
BASE_ADDRESS + OSC_POWER_REG: begin
osc_100_en <= s_ctrlport_req_data[OSC_100];
osc_122_88_en <= s_ctrlport_req_data[OSC_122_88];
end
// Error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// Read request
end else if (s_ctrlport_req_rd) begin
// Default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
case (s_ctrlport_req_addr)
BASE_ADDRESS + IPASS_POWER_REG: begin
s_ctrlport_resp_data[IPASS_DISABLE_POWER_BIT] <= ipass_power_disable;
s_ctrlport_resp_data[IPASS_POWER_FAULT0] <= ipass_power_sticky[0];
s_ctrlport_resp_data[IPASS_POWER_FAULT1] <= ipass_power_sticky[1];
end
BASE_ADDRESS + OSC_POWER_REG: begin
s_ctrlport_resp_data[OSC_100] <= osc_100_en;
s_ctrlport_resp_data[OSC_122_88] <= osc_122_88_en;
end
// Error on undefined address
default: begin
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}};
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// No response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// No request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
end
//----------------------------------------------------------
// Sticky Logic of Power Registers
//----------------------------------------------------------
// Synchronize asynchronous inputs
wire [1:0] ipass_power_fault_lcl_n;
synchronizer #(
.WIDTH (2),
.STAGES (2),
.INITIAL_VAL (1'b0),
.FALSE_PATH_TO_IN (1)
) power_fault_sync (
.clk (ctrlport_clk),
.rst (ctrlport_rst),
.in (ipass_power_fault_n),
.out (ipass_power_fault_lcl_n)
);
always @(posedge ctrlport_clk) begin
if (ctrlport_rst) begin
ipass_power_sticky <= 2'b00;
end else begin
// Keep value if not cleared or set in case of fault
ipass_power_sticky <= (ipass_power_sticky & ~ipass_clear_sticky) | ~ipass_power_fault_lcl_n;
end
end
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="PS_POWER_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="PS_POWER_REGS">
// <info>
// Registers to control power supplies on the motherboard.
// </info>
//
// <register name="IPASS_POWER_REG" offset="0x00" size="32">
// <info>Controls the power supplies for the iPass connectors.</info>
// <bitfield name="IPASS_DISABLE_POWER_BIT" range="0">
// <info>Set to 1 to disable power for both iPass connectors.</info>
// </bitfield>
// <bitfield name="IPASS_CLEAR_POWER_FAULT0" range="30" readable="false">
// <info>Clear @.IPASS_POWER_FAULT0.</info>
// </bitfield>
// <bitfield name="IPASS_CLEAR_POWER_FAULT1" range="31" readable="false">
// <info>Clear @.IPASS_POWER_FAULT1.</info>
// </bitfield>
// <bitfield name="IPASS_POWER_FAULT0" range="30" writable="false">
// <info>
// Asserted signal indicates a power fault in power switch for iPass
// connector 0. Sticky bit. Asserted on occurrence. Reset using
// @.IPASS_CLEAR_POWER_FAULT0.
// </info>
// </bitfield>
// <bitfield name="IPASS_POWER_FAULT1" range="31" writable="false">
// <info>
// Asserted signal indicates a power fault in power switch for iPass
// connector 1. Sticky bit. Asserted on occurrence. Reset using
// @.IPASS_CLEAR_POWER_FAULT1.
// </info>
// </bitfield>
// </register>
//
// <register name="OSC_POWER_REG" offset="0x04" size="32">
// <info>Controls the power supplies for the oscillators.</info>
// <bitfield name="OSC_100" range="0">
// <info>Enables 5V power switch for the 100 MHz oscillator.</info>
// </bitfield>
// <bitfield name="OSC_122_88" range="1">
// <info>Enables 5V power switch for the 122.88 MHz oscillator.</info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off
-73
View File
@@ -1,73 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: pwr_supply_clk_gen
//
// Description:
//
// Generates a clock for one motherboard power supply.
//
// Parameters:
//
// BASE_ADDRESS : Base address for CtrlPort registers.
// NUM_ADDRESSES : Number of bytes of address space to use.
//
`default_nettype none
module pwr_supply_clk_gen#(
parameter SOURCE_CLK_FREQ = 100_000_000,
parameter TARGET_CLK_FREQ = 100_000
) (
// Base clock and reset
input wire clk,
input wire rst,
// Power supply clocks
output reg pwr_supply_clk
);
//-----------------------------------------------------------------------------
// Counter Calculation / Definition
//-----------------------------------------------------------------------------
// Counter to generate the power supply switching clock
// Assumption: the ratio between the generated clock and the source clock is
// even, therefore we can produce a 50% DC clock output.
localparam MAX_COUNT = SOURCE_CLK_FREQ / TARGET_CLK_FREQ / 2;
localparam COUNTER_W = $clog2(MAX_COUNT);
reg [COUNTER_W-1:0] counter = 0;
//-----------------------------------------------------------------------------
// Clock Generation
//-----------------------------------------------------------------------------
// This process implements a simple clock divider for the power supply
// switcher.
// SAFE COUNTER START! rst is a synchronous reset generated in the
// clk domain; therefore, inherently safe.
always @(posedge clk) begin
if (rst) begin
counter <= 0;
pwr_supply_clk <= 1'b0;
end
else begin
// Add one every cycle to the counter
counter <= counter + 1'b1;
// When the counter reaches its mid value, it is reset and the output clock
// output is toggled.
if (counter == MAX_COUNT-1) begin
counter <= 0;
pwr_supply_clk <= ~pwr_supply_clk;
end
end
end
endmodule
`default_nettype wire
-32
View File
@@ -1,32 +0,0 @@
#
# Copyright 2021 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Module: ps_cs_analysis
#
# Description:
#
# Analyze false path in PS SPI logic to ensure an upper delay boundary.
#
# get project to a working state
project_open -force "mb_cpld.qpf"
create_timing_netlist
update_timing_netlist
# Determine data path delay from MB CPLD chip select signal to MB CPLD internal
# SPI slave
set paths [report_path -from [get_registers {ps_spi_cs_n_decoded[0]}] -multi_corner]
set spiSlaveCsPathDelay [lindex $paths 1]
# clock period at 250 MHz (clock driving the decoding registers)
set maxDelay 4
# compare path from above with maximum delay
if ([expr {$maxDelay < $spiSlaveCsPathDelay}]) {
puts "MB CPLD SPI CS line longer than expected."
exit 1
}
exit 0
-39
View File
@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<cof>
<output_filename>output_files/mb_cpld_converted.pof</output_filename>
<n_pages>1</n_pages>
<width>1</width>
<mode>14</mode>
<sof_data>
<user_name>Page_0</user_name>
<page_flags>1</page_flags>
<bit0>
<sof_filename>output_files/mb_cpld.sof<compress_bitstream>1</compress_bitstream></sof_filename>
</bit0>
</sof_data>
<version>10</version>
<create_cvp_file>0</create_cvp_file>
<create_hps_iocsr>0</create_hps_iocsr>
<auto_create_rpd>1</auto_create_rpd>
<rpd_little_endian>1</rpd_little_endian>
<options>
<map_file>1</map_file>
</options>
<MAX10_device_options>
<por>0</por>
<io_pullup>1</io_pullup>
<config_from_cfm0_only>0</config_from_cfm0_only>
<isp_source>0</isp_source>
<verify_protect>0</verify_protect>
<epof>0</epof>
<ufm_source>0</ufm_source>
</MAX10_device_options>
<advanced_options>
<ignore_epcs_id_check>1</ignore_epcs_id_check>
<ignore_condone_check>2</ignore_condone_check>
<plc_adjustment>0</plc_adjustment>
<post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes>
<post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes>
<bitslice_pre_padding>1</bitslice_pre_padding>
</advanced_options>
</cof>
File diff suppressed because it is too large Load Diff
@@ -1,28 +0,0 @@
//
// Copyright 2022 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: constants_regmap_utils.vh
// Description:
// The constants in this file are autogenerated by XmlParse.
//===============================================================================
// A numerically ordered list of registers and their HDL source files
//===============================================================================
//===============================================================================
// RegTypes
//===============================================================================
//===============================================================================
// Register Group CONSTANTS_GROUP
//===============================================================================
// Enumerated type CONSTANTS_ENUM
localparam CONSTANTS_ENUM_SIZE = 4;
localparam PS_CPLD_SIGNATURE = 'hA522D27; // CONSTANTS_ENUM:PS_CPLD_SIGNATURE
localparam OLDEST_CPLD_REVISION = 'h20122114; // CONSTANTS_ENUM:OLDEST_CPLD_REVISION
localparam CPLD_REVISION = 'h21111615; // CONSTANTS_ENUM:CPLD_REVISION
localparam PL_CPLD_SIGNATURE = 'h3FDC5C47; // CONSTANTS_ENUM:PL_CPLD_SIGNATURE
@@ -1,36 +0,0 @@
//
// Copyright 2022 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: mb_cpld_pl_regmap_utils.vh
// Description:
// The constants in this file are autogenerated by XmlParse.
//===============================================================================
// A numerically ordered list of registers and their HDL source files
//===============================================================================
// PL_REGISTERS : 0x0 (mb_cpld.v)
// JTAG_DB0 : 0x60 (mb_cpld.v)
// JTAG_DB1 : 0x80 (mb_cpld.v)
//===============================================================================
// RegTypes
//===============================================================================
//===============================================================================
// Register Group MB_CPLD_PL_WINDOWS
//===============================================================================
// PL_REGISTERS Window (from mb_cpld.v)
localparam PL_REGISTERS = 'h0; // Window Offset
localparam PL_REGISTERS_SIZE = 'h40; // size in bytes
// JTAG_DB0 Window (from mb_cpld.v)
localparam JTAG_DB0 = 'h60; // Window Offset
localparam JTAG_DB0_SIZE = 'h20; // size in bytes
// JTAG_DB1 Window (from mb_cpld.v)
localparam JTAG_DB1 = 'h80; // Window Offset
localparam JTAG_DB1_SIZE = 'h20; // size in bytes
-93
View File
@@ -1,93 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: reset_generator
//
// Description:
//
// Generates a power-on reset signal that is asserted at startup and stays
// asserted for at least CYCLES_IN_RESET clock cycles.
//
// Internally, it generates a 1-bit synchronous signal (initialize) to safely
// initialize the power_on_reset_counter incremental counter to 0's.
//
// A delayed version of the initializing signal is also generated
// (counter_enable) to start counting.
//
// 1_ 2_ 3_ 4_ 5_ 6_ 7_ 8_ 9_
// clk _| |_| |_| |_| |_| |_| |_| |_| |_|
// _____________________
// initialize _____________|
// _________
// counter_enable _________________________|
//
`default_nettype none
module reset_generator (
input wire clk,
output reg power_on_reset = 1'b1
);
wire [0:0] counter_enable;
wire [0:0] initialize;
synchronizer #(
.WIDTH (1),
.STAGES (3),
.INITIAL_VAL (1'b0),
.FALSE_PATH_TO_IN (0)
) init_sync_inst (
.clk (clk),
.rst (1'b0),
.in (1'b1),
.out (initialize)
);
synchronizer #(
.WIDTH (1),
.STAGES (3),
.INITIAL_VAL (1'b0),
.FALSE_PATH_TO_IN (0)
) counter_en_sync_inst (
.clk (clk),
.rst (1'b0),
.in (initialize),
.out (counter_enable)
);
// Internal synchronous reset generator.
localparam CYCLES_IN_RESET = 20;
reg [7:0] power_on_reset_counter = 8'b0;
// This block generates a synchronous reset in the clk domain that can be
// used by downstream logic.
//
// power_on_reset_counter is first initialized to 0's upon assertion of
// initialize. Some cycles later (3), upon assertion if counter_enable,
// power_on_reset_counter starts to increment.
//
// power_on_reset will remain asserted until power_on_reset_counter reaches
// cycles_in_reset, resulting in the deassertion of power_on_reset.
always @(posedge clk) begin : power_on_reset_gen
if (counter_enable) begin
if (power_on_reset_counter == CYCLES_IN_RESET-1) begin
power_on_reset <= 1'b0;
end else begin
power_on_reset_counter <= power_on_reset_counter + 1'b1;
power_on_reset <= 1'b1;
end
end
else if (initialize) begin
power_on_reset_counter <= 8'b0;
power_on_reset <= 1'b1;
end
end
endmodule
`default_nettype wire
-288
View File
@@ -1,288 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: spi_slave
//
// Description:
//
// SPI slave for configuration CPOL = CPHA = 0.
// Transfers 8 bit = 1 byte MSB first. Parallel data has to be
// provided and consumed immediately when flags are asserted.
//
// Limitation: clk frequency <= 2*sclk frequency
//
// Data request from sclk domain is triggered towards the clk domain ahead of
// time. This is due to the clock domain crossing using the synchronizer and
// processing pipeline stages.
//
// The worst case propagation delay of the used synchronizer is:
//
// 4 'clk' clock cycles:
// 1 clock cycle of signal propagation to synchronizer
// (data_request_sclk assertion)
// 1 clock cycle to capture data with instability in first stage
// 1 clock cycle to stabilize first stage
// 1 clock cycle to capture data in second stage
// (data_request_clk available in 'clk' domain)
//
// Once synchronized in 'clk' domain, there is one additional clock cycle to
// derive data_out_valid and data_in_required. To ensure that transmit data
// is registered a 'clk' cycle ahead of the actual transmission we need 2
// more 'clk' clock cycles. This ensures that transmit_word has changed and
// is stable for at least one 'clk' cycle before 'sclk' asserts again. Any
// additional time required externally to respond to the control port
// requests should be considered in this crossing as well. This is a total of
// 7 clock cycles (+ctrlport response margin) @ clk domain. The minimum
// required time in sclk domain to issue the request is calculated based on
// the clock frequencies.
//
// Parameters:
//
// CLK_FREQUENCY : Frequency of "clk"
// SPI_FREQUENCY : Frequency of "sclk"
//
`default_nettype none
module spi_slave #(
parameter CLK_FREQUENCY = 50000000,
parameter SPI_FREQUENCY = 10000000
) (
//---------------------------------------------------------------
// SPI Interface
//---------------------------------------------------------------
input wire sclk,
input wire cs_n,
input wire mosi,
output wire miso,
//---------------------------------------------------------------
// Parallel Interface
//---------------------------------------------------------------
input wire clk,
input wire rst,
output reg data_in_required,
input wire data_in_valid,
input wire [7:0] data_in,
output reg data_out_valid,
output reg [7:0] data_out,
output wire active
);
wire [0:0] data_request_clk;
wire [0:0] reception_complete_clk;
//---------------------------------------------------------------
// SPI Receiver @ sclk
//---------------------------------------------------------------
reg [7:0] receiver_reg;
reg [2:0] current_bit_index;
reg reception_complete_sclk = 1'b0;
reg [7:0] received_word;
always @(posedge sclk or posedge cs_n) begin
// Reset logic on positive cs_n edge = slave idle
if (cs_n) begin
receiver_reg <= 8'b0;
end
// Rising edge of sclk
else begin
// Capture bits into shift register MSBs first
receiver_reg <= {receiver_reg[6:0], mosi};
end
end
// Reset with cs_n might occur too early during clk sync.
// Reset half way through the reception.
always @(posedge sclk) begin
// Complete word was received
if (current_bit_index == 7) begin
reception_complete_sclk <= 1'b1;
received_word <= {receiver_reg[6:0], mosi};
// Reset after half transaction
end else if (current_bit_index == 3) begin
reception_complete_sclk <= 1'b0;
end
end
//---------------------------------------------------------------
// Handover of data sclk -> clk
//---------------------------------------------------------------
synchronizer #(
.WIDTH (1),
.STAGES (2),
.INITIAL_VAL (1'b0),
.FALSE_PATH_TO_IN (1)
) data_sync_inst (
.clk (clk),
.rst (1'b0),
.in (reception_complete_sclk),
.out (reception_complete_clk)
);
//---------------------------------------------------------------
// Parallel interface data output @ clk
//---------------------------------------------------------------
reg reception_complete_clk_delayed = 1'b0;
// Propagate toggling signal without reset to ensure stability on reset
always @(posedge clk) begin
// Capture last state of reception
reception_complete_clk_delayed <= reception_complete_clk;
end
// Derive data and control signal
always @(posedge clk) begin
if (rst) begin
data_out_valid <= 1'b0;
data_out <= 8'b0;
end
else begin
// Default assignment
data_out_valid <= 1'b0;
// Provide data to output on rising_edge
if (reception_complete_clk & ~reception_complete_clk_delayed) begin
// Data can simply be captured as the reception complete signal
// indicates stable values in received_word.
data_out <= received_word;
data_out_valid <= 1'b1;
end
end
end
//---------------------------------------------------------------
// SPI Transmitter @ sclk
//---------------------------------------------------------------
// Data request calculation:
// SCLK_CYCLES_DURING_DATA_REQ = 8 clk period / sclk period
// Clock periods are expressed by reciprocal of frequencies.
// Term "+CLK_FREQUENCY-1" is used to round up the result in integer logic.
localparam SCLK_CYCLES_DURING_DATA_REQ = (8*SPI_FREQUENCY + CLK_FREQUENCY-1)/CLK_FREQUENCY;
// subtract from 8 bits per transfer to get target index
localparam DATA_REQ_BIT_INDEX = 8 - SCLK_CYCLES_DURING_DATA_REQ;
reg [7:0] transmit_bits;
reg [7:0] transmit_word;
reg data_request_sclk = 1'b0;
always @(negedge sclk or posedge cs_n) begin
// Reset logic on positive cs_n edge = slave idle
if (cs_n) begin
current_bit_index <= 3'b0;
data_request_sclk <= 1'b0;
transmit_bits <= 8'b0;
end
// Falling edge of sclk
else begin
// Fill or move shift register for byte transmissions
if (current_bit_index == 7) begin
transmit_bits <= transmit_word;
end else begin
transmit_bits <= {transmit_bits[6:0], 1'b0};
end
// Update bit index
current_bit_index <= current_bit_index + 1'b1;
// Trigger request for new word at start of calculated index
if (current_bit_index == DATA_REQ_BIT_INDEX-1) begin
data_request_sclk <= 1'b1;
// Reset after half the reception in case cs_n is not changed in between
// two transactions.
end else if (current_bit_index == (DATA_REQ_BIT_INDEX+4-1)%8) begin
data_request_sclk <= 1'b0;
end
end
end
// Drive miso output with data when cs_n low
assign miso = cs_n ? 1'bz : transmit_bits[7];
//---------------------------------------------------------------
// Handover of Data Request sclk -> clk
//---------------------------------------------------------------
synchronizer #(
.WIDTH (1),
.STAGES (2),
.INITIAL_VAL (1'b0),
.FALSE_PATH_TO_IN (1)
) request_sync_inst (
.clk (clk),
.rst (rst),
.in (data_request_sclk),
.out (data_request_clk)
);
//---------------------------------------------------------------
// Parallel Interface Data Input Control
//---------------------------------------------------------------
reg data_request_clk_delayed;
always @(posedge clk) begin
if (rst) begin
data_request_clk_delayed <= 1'b0;
data_in_required <= 1'b0;
transmit_word <= 8'b0;
end
else begin
// Default assignment
data_in_required <= 1'b0;
// Capture last state of data request
data_request_clk_delayed <= data_request_clk;
// Request data from input
if (~data_request_clk_delayed & data_request_clk) begin
data_in_required <= 1'b1;
end
// Capture new data if valid data available, 0 otherwise.
if (data_in_required) begin
if (data_in_valid) begin
transmit_word <= data_in;
end else begin
transmit_word <= 8'b0;
end
end
end
end
//---------------------------------------------------------------
// Chip Select
//---------------------------------------------------------------
// Driven as active signal in parallel clock domain
wire cs_n_clk;
assign active = ~cs_n_clk;
synchronizer #(
.WIDTH (1),
.STAGES (2),
.INITIAL_VAL (1'b1),
.FALSE_PATH_TO_IN (1)
) active_sync_inst (
.clk (clk),
.rst (rst),
.in (cs_n),
.out (cs_n_clk)
);
endmodule
`default_nettype wire
@@ -1,238 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: spi_slave_to_ctrlport_master
//
// Description:
//
// SPI slave to ContolPort master conversion in order to tunnel control port
// request through an SPI bus.
//
// The request format on SPI is defined as:
//
// Write request:
// 1'b1 = write, 15 bit address, 32 bit data (MOSI), 8 bit processing gap,
// 5 bit padding, 1 bit ack, 2 bit status
//
// Read request:
// 1'b0 = read, 15 bit address, 8 bit processing gap, 32 bit data (MISO),
// 5 bit padding, 1 bit ack, 2 bit status
//
// Parameters:
//
// CLK_FREQUENCY : Frequency of "clk"
// SPI_FREQUENCY : Frequency of "sclk"
//
`default_nettype none
module spi_slave_to_ctrlport_master #(
parameter CLK_FREQUENCY = 50000000,
parameter SPI_FREQUENCY = 10000000
) (
//---------------------------------------------------------------
// ControlPort Master
//---------------------------------------------------------------
input wire ctrlport_clk,
input wire ctrlport_rst,
output wire m_ctrlport_req_wr,
output wire m_ctrlport_req_rd,
output wire [19:0] m_ctrlport_req_addr,
output wire [31:0] m_ctrlport_req_data,
input wire m_ctrlport_resp_ack,
input wire [ 1:0] m_ctrlport_resp_status,
input wire [31:0] m_ctrlport_resp_data,
//---------------------------------------------------------------
// SPI Slave
//---------------------------------------------------------------
input wire sclk,
input wire cs_n,
input wire mosi,
output wire miso
);
`include "../../../lib/rfnoc/core/ctrlport.vh"
//---------------------------------------------------------------
// SPI Slave
//---------------------------------------------------------------
wire [7:0] data_in;
wire [7:0] data_out;
wire data_in_valid;
wire data_out_valid;
wire data_in_required;
wire spi_slave_active;
spi_slave #(
.CLK_FREQUENCY (CLK_FREQUENCY),
.SPI_FREQUENCY (SPI_FREQUENCY)
) spi_slave_async (
.sclk (sclk),
.cs_n (cs_n),
.mosi (mosi),
.miso (miso),
.clk (ctrlport_clk),
.rst (ctrlport_rst),
.data_in_required (data_in_required),
.data_in_valid (data_in_valid),
.data_in (data_in),
.data_out_valid (data_out_valid),
.data_out (data_out),
.active (spi_slave_active)
);
//---------------------------------------------------------------
// Reset Generation from SPI Slave
//---------------------------------------------------------------
reg spi_slave_active_delayed = 1'b0;
always @(posedge ctrlport_clk) begin
if (ctrlport_rst) begin
spi_slave_active_delayed <= 1'b0;
end
else begin
spi_slave_active_delayed <= spi_slave_active;
end
end
// Trigger reset on falling edge of active signal (rising edge of cs_n)
wire spi_slave_reset;
assign spi_slave_reset = spi_slave_active_delayed & (~spi_slave_active);
//---------------------------------------------------------------
// Transfer Constants
//---------------------------------------------------------------
localparam NUM_BYTES_TRANSACTION = 8;
localparam NUM_BYTES_WRITE_REQUEST_PAYLOAD = 6;
localparam NUM_BYTES_READ_REQUEST_PAYLOAD = 2;
localparam MAX_BYTES_RESPONSE_PAYLOAD = 5;
//---------------------------------------------------------------
// Data Receiver
//---------------------------------------------------------------
reg [3:0] num_bytes_received;
reg request_received;
reg write_request;
reg provide_response;
reg [NUM_BYTES_WRITE_REQUEST_PAYLOAD*8-1:0] request_reg = {NUM_BYTES_WRITE_REQUEST_PAYLOAD*8 {1'b0}};
always @(posedge ctrlport_clk) begin
if (ctrlport_rst || spi_slave_reset) begin
num_bytes_received <= 4'b0;
request_received <= 1'b0;
write_request <= 1'b0;
provide_response <= 1'b0;
end
else begin
// Counter number of received bytes
if (data_out_valid) begin
// Increment counter
num_bytes_received <= num_bytes_received + 1'b1;
if (num_bytes_received == NUM_BYTES_TRANSACTION-1) begin
num_bytes_received <= 4'b0;
end
end
// Check for read / write on first received byte's MSB
if (data_out_valid && (num_bytes_received == 0)) begin
write_request <= data_out[7];
end
// Detect complete request
request_received <= 1'b0;
if (data_out_valid) begin
if (write_request && (num_bytes_received == NUM_BYTES_WRITE_REQUEST_PAYLOAD-1)) begin
request_received <= 1'b1;
provide_response <= 1'b1;
end else if (~write_request && (num_bytes_received == NUM_BYTES_READ_REQUEST_PAYLOAD-1)) begin
request_received <= 1'b1;
provide_response <= 1'b1;
end
end
// Detect end of response on last received byte
if (num_bytes_received == NUM_BYTES_TRANSACTION-1) begin
provide_response <= 1'b0;
end
// Capture data into shift register
if (data_out_valid) begin
request_reg <= {request_reg[NUM_BYTES_WRITE_REQUEST_PAYLOAD*8-8-1:0], data_out};
end
end
end
// Drive ControlPort
localparam SPI_TRANSFER_ADDRESS_WIDTH = 15;
assign m_ctrlport_req_wr = request_received && write_request;
assign m_ctrlport_req_rd = request_received && ~write_request;
assign m_ctrlport_req_data = request_reg[CTRLPORT_DATA_W-1:0];
assign m_ctrlport_req_addr = (write_request) ?
{5'b0, request_reg[CTRLPORT_DATA_W+:SPI_TRANSFER_ADDRESS_WIDTH]} :
{5'b0, request_reg[0+:SPI_TRANSFER_ADDRESS_WIDTH]};
//---------------------------------------------------------------
// Response Handling
//---------------------------------------------------------------
reg [MAX_BYTES_RESPONSE_PAYLOAD*8-1:0] response_reg;
reg ready_for_response; // active during processing gap
wire write_response_byte;
always @(posedge ctrlport_clk) begin
if (ctrlport_rst || spi_slave_reset) begin
response_reg <= {8*MAX_BYTES_RESPONSE_PAYLOAD {1'b0}};
ready_for_response <= 1'b0;
end
else begin
// Reset response on new request
if (request_received) begin
ready_for_response <= 1'b1;
if (write_request) begin
// Just last byte -> padding, ack flag, CMDERR, padding (data length)
response_reg <= {5'b0, 1'b1, CTRL_STS_CMDERR, {CTRLPORT_DATA_W{1'b0}}};
end else begin
// Last 5 bytes -> data = 0, Padding, ack flag, CMDERR
response_reg <= {{CTRLPORT_DATA_W{1'b0}}, 5'b0, 1'b1, CTRL_STS_CMDERR};
end
// Capture response within processing gap, leave default response from above otherwise
end else if (m_ctrlport_resp_ack && ready_for_response) begin
if (write_request) begin
response_reg <= {5'b0, m_ctrlport_resp_ack, m_ctrlport_resp_status, {CTRLPORT_DATA_W{1'b0}}};
end else begin
response_reg <= {m_ctrlport_resp_data, 5'b0, m_ctrlport_resp_ack, m_ctrlport_resp_status};
end
end
// Shift data after writing to slave
if (write_response_byte) begin
response_reg <= {response_reg[0+:(MAX_BYTES_RESPONSE_PAYLOAD-1)*8], 8'b0};
ready_for_response <= 1'b0;
end
end
end
// Response is written after request part has been transferred
assign write_response_byte = data_in_required && provide_response;
// Assign SPI slave inputs
assign data_in = response_reg[(MAX_BYTES_RESPONSE_PAYLOAD-1)*8+:8];
assign data_in_valid = write_response_byte;
endmodule
`default_nettype wire
+222
View File
@@ -0,0 +1,222 @@
//
// Copyright 2022 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: led_control
//
// Description:
// Implements control over LED state via CtrlPort. The default state
// has the LEDs disabled.
//
`default_nettype none
module led_control #(
parameter BASE_ADDRESS = 0,
parameter REGMAP_SIZE = 8'h1
) (
// Clock and reset
input wire ctrlport_clk,
input wire ctrlport_rst,
// Request
input wire s_ctrlport_req_wr,
input wire s_ctrlport_req_rd,
input wire [19:0] s_ctrlport_req_addr,
input wire [31:0] s_ctrlport_req_data,
// Response
output reg s_ctrlport_resp_ack,
output reg [ 1:0] s_ctrlport_resp_status,
output reg [31:0] s_ctrlport_resp_data,
// LED Control (domain: ctrlport_clk)
output reg ch0_rx2_led,
output reg ch0_tx_led,
output reg ch0_rx_led,
output reg ch1_rx2_led,
output reg ch1_tx_led,
output reg ch1_rx_led,
output reg ch2_rx2_led,
output reg ch2_tx_led,
output reg ch2_rx_led,
output reg ch3_rx2_led,
output reg ch3_tx_led,
output reg ch3_rx_led
);
`include "../regmap/x440/led_setup_regmap_utils.vh"
`include "../../../../lib/rfnoc/core/ctrlport.vh"
//---------------------------------------------------------------
// ATR memory signals
//---------------------------------------------------------------
reg [31:0] led_ctrl_reg;
//---------------------------------------------------------------
// Handling of CtrlPort
//---------------------------------------------------------------
// Check of request address is targeted for this module.
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) && (s_ctrlport_req_addr < BASE_ADDRESS + REGMAP_SIZE);
always @(posedge ctrlport_clk) begin
// reset internal registers and responses
if (ctrlport_rst) begin
s_ctrlport_resp_ack <= 1'b0;
s_ctrlport_resp_status <= 2'b0;
s_ctrlport_resp_data <= 32'b0;
end else begin
// write requests
if (s_ctrlport_req_wr) begin
// always issue an ack and no data
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= {32{1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
case (s_ctrlport_req_addr)
BASE_ADDRESS + LED_CONTROL: begin
led_ctrl_reg <= s_ctrlport_req_data;
end
// error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// no response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
//req_rd not delayed
end else if (s_ctrlport_req_rd) begin
// default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {32{1'b0}};
case (s_ctrlport_req_addr)
BASE_ADDRESS : begin
s_ctrlport_resp_data <= led_ctrl_reg & LED_CONTROL_MASK;
end
// error on undefined address
default: begin
if (address_in_range) begin
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
// no response if out of range
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
endcase
// no request
end else begin
s_ctrlport_resp_ack <= 1'b0;
end
end
end
always @(posedge ctrlport_clk) begin
//outputs
ch0_rx2_led <= led_ctrl_reg[CH0_RX2_LED_EN];
ch0_tx_led <= led_ctrl_reg[CH0_TRX1_LED_RED_EN];
ch0_rx_led <= led_ctrl_reg[CH0_TRX1_LED_GR_EN];
ch1_rx2_led <= led_ctrl_reg[CH1_RX2_LED_EN];
ch1_tx_led <= led_ctrl_reg[CH1_TRX1_LED_RED_EN];
ch1_rx_led <= led_ctrl_reg[CH1_TRX1_LED_GR_EN];
ch2_rx2_led <= led_ctrl_reg[CH2_RX2_LED_EN];
ch2_tx_led <= led_ctrl_reg[CH2_TRX1_LED_RED_EN];
ch2_rx_led <= led_ctrl_reg[CH2_TRX1_LED_GR_EN];
ch3_rx2_led <= led_ctrl_reg[CH3_RX2_LED_EN];
ch3_tx_led <= led_ctrl_reg[CH3_TRX1_LED_RED_EN];
ch3_rx_led <= led_ctrl_reg[CH3_TRX1_LED_GR_EN];
end
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="LED_SETUP_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="LED_SETUP_REGISTERS">
// <info>
// Contains registers that control the LEDs.
// </info>
// <register name="LED_CONTROL" size="32" offset="0x0" attributes="Readable|Writable">
// <info>
// This register configures RF Frontend LEDs.
// </info>
// <bitfield name="CH0_RX2_LED_EN" range="0" initialvalue="0">
// <info>
// Enables the Ch0 Rx2 Green LED
// </info>
// </bitfield>
// <bitfield name="CH0_TRX1_LED_RED_EN" range="1" initialvalue="0">
// <info>
// Enables the Ch0 TRX (TX) Red LED
// </info>
// </bitfield>
// <bitfield name="CH0_TRX1_LED_GR_EN" range="2" initialvalue="0">
// <info>
// Enables the Ch0 TRX (RX) Green LED
// </info>
// </bitfield>
// <bitfield name="CH1_RX2_LED_EN" range="8" initialvalue="0">
// <info>
// Enables the Ch1 Rx2 Green LED
// </info>
// </bitfield>
// <bitfield name="CH1_TRX1_LED_RED_EN" range="9" initialvalue="0">
// <info>
// Enables the Ch1 TRX (TX) Red LED
// </info>
// </bitfield>
// <bitfield name="CH1_TRX1_LED_GR_EN" range="10" initialvalue="0">
// <info>
// Enables the Ch1 TRX (RX) Green LED
// </info>
// </bitfield>
// <bitfield name="CH2_RX2_LED_EN" range="16" initialvalue="0">
// <info>
// Enables the Ch2 Rx2 Green LED
// </info>
// </bitfield>
// <bitfield name="CH2_TRX1_LED_RED_EN" range="17" initialvalue="0">
// <info>
// Enables the Ch2 TRX (TX) Red LED
// </info>
// </bitfield>
// <bitfield name="CH2_TRX1_LED_GR_EN" range="18" initialvalue="0">
// <info>
// Enables the Ch2 TRX (RX) Green LED
// </info>
// </bitfield>
// <bitfield name="CH3_RX2_LED_EN" range="24" initialvalue="0">
// <info>
// Enables the Ch3 Rx2 Green LED
// </info>
// </bitfield>
// <bitfield name="CH3_TRX1_LED_RED_EN" range="25" initialvalue="0">
// <info>
// Enables the Ch3 TRX (TX) Red LED
// </info>
// </bitfield>
// <bitfield name="CH3_TRX1_LED_GR_EN" range="26" initialvalue="0">
// <info>
// Enables the Ch3 TRX (RX) Green LED
// </info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off
+21
View File
@@ -0,0 +1,21 @@
#
# Copyright 2022 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description:
#
# Timing constraints for the x440's motherboard CPLD.
#
#####################################################################
# DB specific LED constraints
#####################################################################
# LED signals
set led_outputs [get_ports {QSFP0_LED_ACTIVE[*] QSFP0_LED_LINK[*] \
QSFP1_LED_ACTIVE[*] QSFP1_LED_LINK[*] CH*_RX2_LED[*] CH*_TX_LED[*] CH*_RX_LED[*] } ]
set_min_delay -to $led_outputs 0
set_max_delay -to $led_outputs $prc_clock_period
@@ -1,5 +1,5 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
// Copyright 2022 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
@@ -7,7 +7,7 @@
//
// Description:
//
// Top level file for the X4xx motherboard CPLD.
// Top level file for the X440 motherboard CPLD.
//
// Parameters:
//
@@ -90,22 +90,20 @@ module mb_cpld #(
output wire [3:0] QSFP1_LED_ACTIVE,
output wire [3:0] QSFP1_LED_LINK,
// Daughterboard control interface
// Daughterboard LED GPIO
// 1 -> DB1 / 0 -> DB0
output reg [1:0] DB_CTRL_SCLK,
output reg [1:0] DB_CTRL_MOSI,
input wire [1:0] DB_CTRL_MISO,
output reg [1:0] DB_CTRL_CS_N,
output wire [1:0] DB_REF_CLK,
output wire [1:0] DB_ARST,
// Daughterboards' JTAG master interfaces.
// 1 -> DB1 / 0 -> DB0
output wire [1:0] DB_JTAG_TCK,
output wire [1:0] DB_JTAG_TDI, // from CPLD to DB
input wire [1:0] DB_JTAG_TDO, // from DB to CPLD
output wire [1:0] DB_JTAG_TMS,
output wire [1:0] CH0_RX2_LED,
output wire [1:0] CH0_TX_LED,
output wire [1:0] CH0_RX_LED,
output wire [1:0] CH1_RX2_LED,
output wire [1:0] CH1_TX_LED,
output wire [1:0] CH1_RX_LED,
output wire [1:0] CH2_RX2_LED,
output wire [1:0] CH2_TX_LED,
output wire [1:0] CH2_RX_LED,
output wire [1:0] CH3_RX2_LED,
output wire [1:0] CH3_TX_LED,
output wire [1:0] CH3_RX_LED,
//---------------------------------------------------------------------------
// PS Interfaces to/from Motherboard
//---------------------------------------------------------------------------
@@ -132,13 +130,6 @@ module mb_cpld #(
output wire [11:0] DIO_DIRECTION_A,
output wire [11:0] DIO_DIRECTION_B,
// Daughterboard calibration EEPROM SPI
// 1 -> DB1 / 0 -> DB0
output wire [1:0] DB_CALEEPROM_SCLK,
output wire [1:0] DB_CALEEPROM_MOSI,
input wire [1:0] DB_CALEEPROM_MISO,
output wire [1:0] DB_CALEEPROM_CS_N,
//---------------------------------------------------------------------------
// Miscellaneous
//---------------------------------------------------------------------------
@@ -161,9 +152,9 @@ module mb_cpld #(
// SPI masters (spi_top) are limited to 64 bit transmission length
`define SPI_MAX_CHAR_64
`include "../../../lib/rfnoc/core/ctrlport.vh"
`include "regmap/mb_cpld_ps_regmap_utils.vh"
`include "regmap/mb_cpld_pl_regmap_utils.vh"
`include "../../../../lib/rfnoc/core/ctrlport.vh"
`include "../regmap/mb_cpld_ps_regmap_utils.vh"
`include "../regmap/x440/mb_cpld_pl_regmap_utils.vh"
//---------------------------------------------------------------------------
// Clocks and Resets
@@ -346,24 +337,6 @@ module mb_cpld #(
wire [1:0] db_reset;
wire [1:0] ipass_cable_present;
// Clocks and reset
oddr db0_clk_out (
.outclock (clk50),
.din ({1'b0, db_clk_enable[0]}),
.pad_out (DB_REF_CLK[0]),
.aclr (reset_clk50)
);
oddr db1_clk_out (
.outclock (clk50),
.din ({1'b0, db_clk_enable[1]}),
.pad_out (DB_REF_CLK[1]),
.aclr (reset_clk50)
);
assign DB_ARST[0] = db_reset[0];
assign DB_ARST[1] = db_reset[1];
// PL SPI FPGA -> DB CPLD
reg mb_cpld_sclk, mb_cpld_mosi, mb_cpld_cs_n;
wire mb_cpld_miso;
@@ -378,24 +351,8 @@ module mb_cpld #(
// SW is expected to properly setup the DBs before issuing SPI transactions.
always @(posedge pll_ref_clk_int) begin : to_db
// Default chip selects
DB_CTRL_CS_N[0] <= 1'b1;
DB_CTRL_CS_N[1] <= 1'b1;
mb_cpld_cs_n <= 1'b1;
// DB 0
DB_CTRL_SCLK[0] <= PL_CPLD_SCLK;
DB_CTRL_MOSI[0] <= PL_CPLD_MOSI;
if (PL_CPLD_CS_N == PL_CS_DB0) begin
DB_CTRL_CS_N[0] <= 1'b0;
end
// DB 1
DB_CTRL_SCLK[1] <= PL_CPLD_SCLK;
DB_CTRL_MOSI[1] <= PL_CPLD_MOSI;
if (PL_CPLD_CS_N == PL_CS_DB1) begin
DB_CTRL_CS_N[1] <= 1'b0;
end
// MB CPLD
mb_cpld_sclk <= PL_CPLD_SCLK;
mb_cpld_mosi <= PL_CPLD_MOSI;
@@ -408,8 +365,6 @@ module mb_cpld #(
always @(posedge pll_ref_clk_int) begin : from_db
case (PL_CPLD_CS_N)
PL_CS_MB_CPLD : PL_CPLD_MISO <= mb_cpld_miso; // MB CPLD
PL_CS_DB1 : PL_CPLD_MISO <= DB_CTRL_MISO[1]; // DB 1
PL_CS_DB0 : PL_CPLD_MISO <= DB_CTRL_MISO[0]; // DB 0
PL_CS_IDLE : PL_CPLD_MISO <= 1'bz; // Inactive
endcase
end
@@ -450,6 +405,22 @@ module mb_cpld #(
wire [31:0] pl_regs_ctrlport_resp_data;
wire [ 1:0] pl_regs_ctrlport_resp_status;
wire [19:0] db0_led_ctrlport_req_addr;
wire [31:0] db0_led_ctrlport_req_data;
wire db0_led_ctrlport_req_rd;
wire db0_led_ctrlport_req_wr;
wire db0_led_ctrlport_resp_ack;
wire [31:0] db0_led_ctrlport_resp_data;
wire [ 1:0] db0_led_ctrlport_resp_status;
wire [19:0] db1_led_ctrlport_req_addr;
wire [31:0] db1_led_ctrlport_req_data;
wire db1_led_ctrlport_req_rd;
wire db1_led_ctrlport_req_wr;
wire db1_led_ctrlport_resp_ack;
wire [31:0] db1_led_ctrlport_resp_data;
wire [ 1:0] db1_led_ctrlport_resp_status;
wire [19:0] pl_term_ctrlport_req_addr;
wire [31:0] pl_term_ctrlport_req_data;
wire pl_term_ctrlport_req_rd;
@@ -458,22 +429,6 @@ module mb_cpld #(
wire [31:0] pl_term_ctrlport_resp_data;
wire [ 1:0] pl_term_ctrlport_resp_status;
wire pl_jtag0_ctrlport_req_rd;
wire pl_jtag0_ctrlport_req_wr;
wire pl_jtag0_ctrlport_resp_ack;
wire [31:0] pl_jtag0_ctrlport_resp_data;
wire [ 1:0] pl_jtag0_ctrlport_resp_status;
wire [19:0] pl_jtag0_ctrlport_req_addr;
wire [31:0] pl_jtag0_ctrlport_req_data;
wire [19:0] pl_jtag1_ctrlport_req_addr;
wire [31:0] pl_jtag1_ctrlport_req_data;
wire pl_jtag1_ctrlport_req_rd;
wire pl_jtag1_ctrlport_req_wr;
wire pl_jtag1_ctrlport_resp_ack;
wire [31:0] pl_jtag1_ctrlport_resp_data;
wire [1:0] pl_jtag1_ctrlport_resp_status;
ctrlport_splitter #(
.NUM_SLAVES (4)
) pl_ctrlport_splitter (
@@ -489,16 +444,16 @@ module mb_cpld #(
.s_ctrlport_resp_ack (pl_ctrlport_resp_ack),
.s_ctrlport_resp_status (pl_ctrlport_resp_status),
.s_ctrlport_resp_data (pl_ctrlport_resp_data),
.m_ctrlport_req_wr ({pl_regs_ctrlport_req_wr, pl_term_ctrlport_req_wr, pl_jtag0_ctrlport_req_wr, pl_jtag1_ctrlport_req_wr}),
.m_ctrlport_req_rd ({pl_regs_ctrlport_req_rd, pl_term_ctrlport_req_rd, pl_jtag0_ctrlport_req_rd, pl_jtag1_ctrlport_req_rd}),
.m_ctrlport_req_addr ({pl_regs_ctrlport_req_addr, pl_term_ctrlport_req_addr, pl_jtag0_ctrlport_req_addr, pl_jtag1_ctrlport_req_addr}),
.m_ctrlport_req_data ({pl_regs_ctrlport_req_data, pl_term_ctrlport_req_data, pl_jtag0_ctrlport_req_data, pl_jtag1_ctrlport_req_data}),
.m_ctrlport_req_wr ({pl_regs_ctrlport_req_wr, db0_led_ctrlport_req_wr, db1_led_ctrlport_req_wr, pl_term_ctrlport_req_wr}),
.m_ctrlport_req_rd ({pl_regs_ctrlport_req_rd, db0_led_ctrlport_req_rd, db1_led_ctrlport_req_rd, pl_term_ctrlport_req_rd}),
.m_ctrlport_req_addr ({pl_regs_ctrlport_req_addr, db0_led_ctrlport_req_addr, db1_led_ctrlport_req_addr, pl_term_ctrlport_req_addr}),
.m_ctrlport_req_data ({pl_regs_ctrlport_req_data, db0_led_ctrlport_req_data, db1_led_ctrlport_req_data, pl_term_ctrlport_req_data}),
.m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (),
.m_ctrlport_req_time (),
.m_ctrlport_resp_ack ({pl_regs_ctrlport_resp_ack, pl_term_ctrlport_resp_ack, pl_jtag0_ctrlport_resp_ack, pl_jtag1_ctrlport_resp_ack}),
.m_ctrlport_resp_status ({pl_regs_ctrlport_resp_status, pl_term_ctrlport_resp_status, pl_jtag0_ctrlport_resp_status, pl_jtag1_ctrlport_resp_status}),
.m_ctrlport_resp_data ({pl_regs_ctrlport_resp_data, pl_term_ctrlport_resp_data, pl_jtag0_ctrlport_resp_data, pl_jtag1_ctrlport_resp_data})
.m_ctrlport_resp_ack ({pl_regs_ctrlport_resp_ack, db0_led_ctrlport_resp_ack, db1_led_ctrlport_resp_ack, pl_term_ctrlport_resp_ack}),
.m_ctrlport_resp_status ({pl_regs_ctrlport_resp_status, db0_led_ctrlport_resp_status, db1_led_ctrlport_resp_status, pl_term_ctrlport_resp_status}),
.m_ctrlport_resp_data ({pl_regs_ctrlport_resp_data, db0_led_ctrlport_resp_data, db1_led_ctrlport_resp_data, pl_term_ctrlport_resp_data})
);
pl_cpld_regs #(
@@ -520,47 +475,63 @@ module mb_cpld #(
.ipass_cable_present (ipass_cable_present)
);
ctrlport_to_jtag #(
.BASE_ADDRESS (JTAG_DB0),
.DEFAULT_PRESCALAR (1)
) db0_jtag (
.ctrlport_clk (clk50),
.ctrlport_rst (reset_clk50),
.s_ctrlport_req_wr (pl_jtag0_ctrlport_req_wr),
.s_ctrlport_req_rd (pl_jtag0_ctrlport_req_rd),
.s_ctrlport_req_addr (pl_jtag0_ctrlport_req_addr),
.s_ctrlport_req_data (pl_jtag0_ctrlport_req_data),
.s_ctrlport_resp_ack (pl_jtag0_ctrlport_resp_ack),
.s_ctrlport_resp_status (pl_jtag0_ctrlport_resp_status),
.s_ctrlport_resp_data (pl_jtag0_ctrlport_resp_data),
.tck (DB_JTAG_TCK[0]),
.tdi (DB_JTAG_TDI[0]),
.tdo (DB_JTAG_TDO[0]),
.tms (DB_JTAG_TMS[0])
led_control #(
.BASE_ADDRESS (PL_DB0_LED_REGISTERS),
.REGMAP_SIZE (PL_DB0_LED_REGISTERS_SIZE)
) led_control_db0 (
.ctrlport_clk (clk50),
.ctrlport_rst (reset_clk50),
.s_ctrlport_req_wr (db0_led_ctrlport_req_wr),
.s_ctrlport_req_rd (db0_led_ctrlport_req_rd),
.s_ctrlport_req_addr (db0_led_ctrlport_req_addr),
.s_ctrlport_req_data (db0_led_ctrlport_req_data),
.s_ctrlport_resp_ack (db0_led_ctrlport_resp_ack),
.s_ctrlport_resp_status (db0_led_ctrlport_resp_status),
.s_ctrlport_resp_data (db0_led_ctrlport_resp_data),
.ch0_rx2_led (CH0_RX2_LED[0]),
.ch0_tx_led (CH0_TX_LED[0]),
.ch0_rx_led (CH0_RX_LED[0]),
.ch1_rx2_led (CH1_RX2_LED[0]),
.ch1_tx_led (CH1_TX_LED[0]),
.ch1_rx_led (CH1_RX_LED[0]),
.ch2_rx2_led (CH2_RX2_LED[0]),
.ch2_tx_led (CH2_TX_LED[0]),
.ch2_rx_led (CH2_RX_LED[0]),
.ch3_rx2_led (CH3_RX2_LED[0]),
.ch3_tx_led (CH3_TX_LED[0]),
.ch3_rx_led (CH3_RX_LED[0])
);
ctrlport_to_jtag #(
.BASE_ADDRESS (JTAG_DB1),
.DEFAULT_PRESCALAR (1)
) db1_jtag (
.ctrlport_clk (clk50),
.ctrlport_rst (reset_clk50),
.s_ctrlport_req_wr (pl_jtag1_ctrlport_req_wr),
.s_ctrlport_req_rd (pl_jtag1_ctrlport_req_rd),
.s_ctrlport_req_addr (pl_jtag1_ctrlport_req_addr),
.s_ctrlport_req_data (pl_jtag1_ctrlport_req_data),
.s_ctrlport_resp_ack (pl_jtag1_ctrlport_resp_ack),
.s_ctrlport_resp_status (pl_jtag1_ctrlport_resp_status),
.s_ctrlport_resp_data (pl_jtag1_ctrlport_resp_data),
.tck (DB_JTAG_TCK[1]),
.tdi (DB_JTAG_TDI[1]),
.tdo (DB_JTAG_TDO[1]),
.tms (DB_JTAG_TMS[1])
led_control #(
.BASE_ADDRESS (PL_DB1_LED_REGISTERS),
.REGMAP_SIZE (PL_DB1_LED_REGISTERS_SIZE)
) led_control_db1 (
.ctrlport_clk (clk50),
.ctrlport_rst (reset_clk50),
.s_ctrlport_req_wr (db1_led_ctrlport_req_wr),
.s_ctrlport_req_rd (db1_led_ctrlport_req_rd),
.s_ctrlport_req_addr (db1_led_ctrlport_req_addr),
.s_ctrlport_req_data (db1_led_ctrlport_req_data),
.s_ctrlport_resp_ack (db1_led_ctrlport_resp_ack),
.s_ctrlport_resp_status (db1_led_ctrlport_resp_status),
.s_ctrlport_resp_data (db1_led_ctrlport_resp_data),
.ch0_rx2_led (CH0_RX2_LED[1]),
.ch0_tx_led (CH0_TX_LED[1]),
.ch0_rx_led (CH0_RX_LED[1]),
.ch1_rx2_led (CH1_RX2_LED[1]),
.ch1_tx_led (CH1_TX_LED[1]),
.ch1_rx_led (CH1_RX_LED[1]),
.ch2_rx2_led (CH2_RX2_LED[1]),
.ch2_tx_led (CH2_TX_LED[1]),
.ch2_rx_led (CH2_RX_LED[1]),
.ch3_rx2_led (CH3_RX2_LED[1]),
.ch3_tx_led (CH3_TX_LED[1]),
.ch3_rx_led (CH3_RX_LED[1])
);
// Termination of ctrlport request
ctrlport_terminator #(
.START_ADDRESS (JTAG_DB1 + JTAG_DB1_SIZE),
.START_ADDRESS (PL_DB1_LED_REGISTERS + PL_DB1_LED_REGISTERS_SIZE),
.LAST_ADDRESS (2**CTRLPORT_ADDR_W-1)
) pl_terminator (
.ctrlport_clk (clk50),
@@ -682,16 +653,6 @@ module mb_cpld #(
assign PHASE_DAC_MOSI = PS_CPLD_MOSI;
assign PHASE_DAC_CS_N = ps_spi_cs_n_decoded[PS_CS_PHASE_DAC];
// DB EEPROM 0 SPI signals
assign DB_CALEEPROM_SCLK[0] = PS_CPLD_SCLK;
assign DB_CALEEPROM_MOSI[0] = PS_CPLD_MOSI;
assign DB_CALEEPROM_CS_N[0] = ps_spi_cs_n_decoded[PS_CS_DB0_CAL_EEPROM];
// DB EEPROM 1 SPI signals
assign DB_CALEEPROM_SCLK[1] = PS_CPLD_SCLK;
assign DB_CALEEPROM_MOSI[1] = PS_CPLD_MOSI;
assign DB_CALEEPROM_CS_N[1] = ps_spi_cs_n_decoded[PS_CS_DB1_CAL_EEPROM];
// CLK AUX DB SPI signals
assign CLK_DB_SCLK = PS_CPLD_SCLK;
assign CLK_DB_MOSI = PS_CPLD_MOSI;
@@ -702,8 +663,6 @@ module mb_cpld #(
assign PS_CPLD_MISO = (PS_CPLD_CS_N[2:0] == PS_CS_MB_CPLD) ? ps_spi_endpoint_miso :
(PS_CPLD_CS_N[2:0] == PS_CS_LMK32) ? LMK32_MISO :
(PS_CPLD_CS_N[2:0] == PS_CS_TPM) ? TPM_MISO :
(PS_CPLD_CS_N[2:0] == PS_CS_DB0_CAL_EEPROM) ? DB_CALEEPROM_MISO[0] :
(PS_CPLD_CS_N[2:0] == PS_CS_DB1_CAL_EEPROM) ? DB_CALEEPROM_MISO[1] :
(PS_CPLD_CS_N[2:0] == PS_CS_CLK_AUX_DB) ? CLK_DB_MISO :
1'bz; // Default case and PHASE_DAC
@@ -977,7 +936,7 @@ endmodule
//XmlParse xml_on
//<top name="X4XX_MB_CPLD">
//<top name="X440_MB_CPLD">
// <regmapcfg readablestrobes="false">
// <map name="MB_CPLD_PS_REGMAP"/>
// <map name="MB_CPLD_PL_REGMAP"/>
@@ -1011,21 +970,9 @@ endmodule
// All protocol masters controller by this register map are running with a clock frequency of 50 MHz.
// </info>
// <group name="MB_CPLD_PL_WINDOWS">
// <window name="PL_REGISTERS" offset="0x0" size="0x40" targetregmap="PL_CPLD_BASE_REGMAP"/>
// <window name="JTAG_DB0" offset="0x60" size="0x20" targetregmap="JTAG_REGMAP">
// <info>
// JTAG Master connected to first daugherboard's CPLD JTAG interface.
//
// **Use minimum value of 1 for @.JTAG_REGMAP.prescalar because the DB CPLD JTAG interface maximum clock frequency is 20 MHz.**
// </info>
// </window>
// <window name="JTAG_DB1" offset="0x80" size="0x20" targetregmap="JTAG_REGMAP">
// <info>
// JTAG Master connected to second daugherboard's CPLD JTAG interface.
//
// **Use minimum value of 1 for @.JTAG_REGMAP.prescalar because the DB CPLD JTAG interface maximum clock frequency is 20 MHz.**
// </info>
// </window>
// <window name="PL_REGISTERS" offset="0x0" size="0x40" targetregmap="PL_CPLD_BASE_REGMAP"/>
// <window name="PL_DB0_LED_REGISTERS" offset="0x50" size="0x10" targetregmap="LED_SETUP_REGMAP"/>
// <window name="PL_DB1_LED_REGISTERS" offset="0x60" size="0x10" targetregmap="LED_SETUP_REGMAP"/>
// </group>
//</regmap>
//<regmap name="CONSTANTS_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
@@ -1038,10 +985,10 @@ endmodule
// <info>
// This enumeration is used to create the constants held in the basic registers.
// </info>
// <value name="PS_CPLD_SIGNATURE" integer="0x0A522D27"/>
// <value name="PS_CPLD_SIGNATURE" integer="0x0A522D28"/>
// <value name="PL_CPLD_SIGNATURE" integer="0x3FDC5C47"/>
// <value name="CPLD_REVISION" integer="0x21111615"/>
// <value name="OLDEST_CPLD_REVISION" integer="0x20122114"/>
// <value name="CPLD_REVISION" integer="0x22080414"/>
// <value name="OLDEST_CPLD_REVISION" integer="0x22080414"/>
// </enumeratedtype>
// </group>
//</regmap>
@@ -293,74 +293,59 @@ set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to PHASE_DAC_SCLK
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to PHASE_DAC_MOSI
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to PHASE_DAC_CS_N
# Daughterboards' JTAG master interfaces.
set_location_assignment PIN_J12 -to DB_JTAG_TCK[0]
set_location_assignment PIN_G9 -to DB_JTAG_TCK[1]
set_location_assignment PIN_K12 -to DB_JTAG_TDI[0]
set_location_assignment PIN_E13 -to DB_JTAG_TDI[1]
set_location_assignment PIN_H10 -to DB_JTAG_TDO[0]
set_location_assignment PIN_F13 -to DB_JTAG_TDO[1]
set_location_assignment PIN_K11 -to DB_JTAG_TMS[0]
set_location_assignment PIN_G10 -to DB_JTAG_TMS[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TCK[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TCK[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TDI[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TDI[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TDO[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TDO[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TMS[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DB_JTAG_TMS[1]
# Daughterboards' Calibration EEPROM SPI interfaces.
set_location_assignment PIN_C9 -to DB_CALEEPROM_CS_N[0]
set_location_assignment PIN_B9 -to DB_CALEEPROM_MISO[0]
set_location_assignment PIN_B10 -to DB_CALEEPROM_MOSI[0]
set_location_assignment PIN_A10 -to DB_CALEEPROM_SCLK[0]
set_location_assignment PIN_B5 -to DB_CALEEPROM_MOSI[1]
set_location_assignment PIN_B6 -to DB_CALEEPROM_SCLK[1]
set_location_assignment PIN_B4 -to DB_CALEEPROM_MISO[1]
set_location_assignment PIN_B3 -to DB_CALEEPROM_CS_N[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_CS_N[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_MISO[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_MOSI[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_SCLK[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_MOSI[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_SCLK[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_MISO[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CALEEPROM_CS_N[1]
# Daughterboards' Control interfaces.
set_location_assignment PIN_C10 -to DB_CTRL_SCLK[0]
set_location_assignment PIN_A9 -to DB_CTRL_MISO[0]
set_location_assignment PIN_A8 -to DB_ARST[0]
set_location_assignment PIN_A11 -to DB_CTRL_CS_N[0]
set_location_assignment PIN_E8 -to DB_CTRL_MOSI[0]
set_location_assignment PIN_D8 -to DB_REF_CLK[0]
set_location_assignment PIN_A3 -to DB_REF_CLK[1]
set_location_assignment PIN_A4 -to DB_CTRL_MISO[1]
set_location_assignment PIN_D6 -to DB_CTRL_CS_N[1]
set_location_assignment PIN_E6 -to DB_CTRL_SCLK[1]
set_location_assignment PIN_A5 -to DB_CTRL_MOSI[1]
set_location_assignment PIN_B2 -to DB_ARST[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_SCLK[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_MISO[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_ARST[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_CS_N[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_MOSI[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_REF_CLK[0]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_REF_CLK[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_MISO[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_CS_N[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_SCLK[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_CTRL_MOSI[1]
set_instance_assignment -name IO_STANDARD "1.8 V" -to DB_ARST[1]
# DB0 TX/RX LEDS per chan
#-------------------------------------------
set_location_assignment PIN_A11 -to CH0_TX_LED[0]
set_location_assignment PIN_C10 -to CH0_RX_LED[0]
set_location_assignment PIN_A9 -to CH0_RX2_LED[0]
set_location_assignment PIN_E8 -to CH1_TX_LED[0]
set_location_assignment PIN_D8 -to CH1_RX_LED[0]
set_location_assignment PIN_A8 -to CH1_RX2_LED[0]
set_location_assignment PIN_C9 -to CH2_TX_LED[0]
set_location_assignment PIN_A10 -to CH2_RX_LED[0]
set_location_assignment PIN_B10 -to CH2_RX2_LED[0]
set_location_assignment PIN_K12 -to CH3_TX_LED[0]
set_location_assignment PIN_K11 -to CH3_RX_LED[0]
set_location_assignment PIN_J12 -to CH3_RX2_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_TX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_RX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_RX2_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_TX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_RX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_RX2_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_TX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_RX_LED[0]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_RX2_LED[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_TX_LED[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_RX_LED[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_RX2_LED[0]
# DB0 TX/RX LEDS per chan
#-------------------------------------------
set_location_assignment PIN_D6 -to CH0_TX_LED[1]
set_location_assignment PIN_E6 -to CH0_RX_LED[1]
set_location_assignment PIN_A4 -to CH0_RX2_LED[1]
set_location_assignment PIN_A5 -to CH1_TX_LED[1]
set_location_assignment PIN_A3 -to CH1_RX_LED[1]
set_location_assignment PIN_B2 -to CH1_RX2_LED[1]
set_location_assignment PIN_B3 -to CH2_TX_LED[1]
set_location_assignment PIN_B6 -to CH2_RX_LED[1]
set_location_assignment PIN_B5 -to CH2_RX2_LED[1]
set_location_assignment PIN_E13 -to CH3_TX_LED[1]
set_location_assignment PIN_G10 -to CH3_RX_LED[1]
set_location_assignment PIN_G9 -to CH3_RX2_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_TX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_RX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH0_RX2_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_TX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_RX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH1_RX2_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_TX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_RX_LED[1]
set_instance_assignment -name IO_STANDARD "1.8-V" -to CH2_RX2_LED[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_TX_LED[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_RX_LED[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CH3_RX2_LED[1]
# Miscellaneous.
#------------------------------------------
@@ -395,19 +380,19 @@ set_global_assignment -name VHDL_FILE ../ip/cmi/PcieCmiWrapper.vhd
set_global_assignment -name VHDL_FILE ../ip/cmi/PcieCmi.vhd
set_global_assignment -name QSYS_FILE ../ip/clkctrl/clkctrl.qsys
set_global_assignment -name QSYS_FILE ../ip/on_chip_flash/on_chip_flash.qsys
set_global_assignment -name SDC_FILE ../db_spi_shared_constants.sdc
set_global_assignment -name SDC_FILE ../mb_cpld.sdc
set_global_assignment -name VERILOG_FILE ../reconfig_engine.v
set_global_assignment -name VERILOG_FILE ../mb_cpld.v
set_global_assignment -name VERILOG_FILE ../ctrlport_to_spi.v
set_global_assignment -name VERILOG_FILE ../ctrlport_to_jtag.v
set_global_assignment -name VERILOG_FILE ../pl_cpld_regs.v
set_global_assignment -name VERILOG_FILE ../pwr_supply_clk_gen.v
set_global_assignment -name VERILOG_FILE ../ps_cpld_regs.v
set_global_assignment -name VERILOG_FILE ../ps_power_regs.v
set_global_assignment -name VERILOG_FILE ../reset_generator.v
set_global_assignment -name VERILOG_FILE ../spi_slave_to_ctrlport_master.v
set_global_assignment -name VERILOG_FILE ../spi_slave.v
set_global_assignment -name SDC_FILE ../common/common.sdc
set_global_assignment -name SDC_FILE ../x440/mb_cpld.sdc
set_global_assignment -name VERILOG_FILE ../x440/mb_cpld.v
set_global_assignment -name VERILOG_FILE ../x440/led_control.v
set_global_assignment -name VERILOG_FILE ../common/reconfig_engine.v
set_global_assignment -name VERILOG_FILE ../common/ctrlport_to_spi.v
set_global_assignment -name VERILOG_FILE ../common/pl_cpld_regs.v
set_global_assignment -name VERILOG_FILE ../common/pwr_supply_clk_gen.v
set_global_assignment -name VERILOG_FILE ../common/ps_cpld_regs.v
set_global_assignment -name VERILOG_FILE ../common/ps_power_regs.v
set_global_assignment -name VERILOG_FILE ../common/reset_generator.v
set_global_assignment -name VERILOG_FILE ../common/spi_slave_to_ctrlport_master.v
set_global_assignment -name VERILOG_FILE ../common/spi_slave.v
set_global_assignment -name QIP_FILE ../ip/pll/pll.qip
set_global_assignment -name VERILOG_FILE ../../../../lib/control/synchronizer_impl.v
set_global_assignment -name VERILOG_FILE ../../../../lib/control/synchronizer.v
@@ -421,12 +406,11 @@ set_global_assignment -name VERILOG_FILE ../../../../lib/control/pulse_synchroni
set_global_assignment -name VERILOG_FILE ../../../../lib/control/handshake.v
set_global_assignment -name VHDL_FILE ../../../../lib/vivado_ipi/axi_bitq/bitq_fsm.vhd
set_global_assignment -name VHDL_FILE ../../../../lib/vivado_ipi/axi_bitq/axi_bitq.vhd
set_global_assignment -name QIP_FILE ../ip/oddr/oddr.qip
set_global_assignment -name SOURCE_FILE db/mb_cpld.cmp.rdb
set_global_assignment -name PARTITION_NETLIST_TYPE POST_FIT -section_id "PcieCmi:PcieCmix"
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id "PcieCmi:PcieCmix"
set_global_assignment -name PARTITION_COLOR 52377 -section_id "PcieCmi:PcieCmix"
set_global_assignment -name PARTITION_IMPORT_FILE ../ip/cmi/PcieCmi.qxp -section_id "PcieCmi:PcieCmix"
set_global_assignment -name PARTITION_IMPORT_FILE ../../ip/cmi/PcieCmi.qxp -section_id "PcieCmi:PcieCmix"
set_global_assignment -name PARTITION_LAST_IMPORTED_FILE ip/cmi/PcieCmi.qxp -section_id "PcieCmi:PcieCmix"
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY pciec_5b6b1 -to "PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix" -section_id "PcieCmi:PcieCmix"
set_instance_assignment -name PARTITION_HIERARCHY pciec_5b6b1 -to "PcieCmiWrapper:pcie_cmi_inst|PcieCmi:PcieCmix" -section_id "PcieCmi:PcieCmix"