Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce the size of the repository. However, over the last half-decade, the split between the repositories has proven more burdensome than it has been helpful. By merging the FPGA code back, it will be possible to create atomic commits that touch both FPGA and UHD codebases. Continuous integration testing is also simplified by merging the repositories, because it was previously difficult to automatically derive the correct UHD branch when testing a feature branch on the FPGA repository. This commit also updates the license files and paths therein. We are therefore merging the repositories again. Future development for FPGA code will happen in the same repository as the UHD host code and MPM code. == Original Codebase and Rebasing == The original FPGA repository will be hosted for the foreseeable future at its original local location: https://github.com/EttusResearch/fpga/ It can be used for bisecting, reference, and a more detailed history. The final commit from said repository to be merged here is 05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as v4.0.0.0-pre-uhd-merge. If you have changes in the FPGA repository that you want to rebase onto the UHD repository, simply run the following commands: - Create a directory to store patches (this should be an empty directory): mkdir ~/patches - Now make sure that your FPGA codebase is based on the same state as the code that was merged: cd src/fpga # Or wherever your FPGA code is stored git rebase v4.0.0.0-pre-uhd-merge Note: The rebase command may look slightly different depending on what exactly you're trying to rebase. - Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge: git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches Note: Make sure that only patches are stored in your output directory. It should otherwise be empty. Make sure that you picked the correct range of commits, and only commits you wanted to rebase were exported as patch files. - Go to the UHD repository and apply the patches: cd src/uhd # Or wherever your UHD repository is stored git am --directory fpga ~/patches/* rm -rf ~/patches # This is for cleanup == Contributors == The following people have contributed mainly to these files (this list is not complete): Co-authored-by: Alex Williams <alex.williams@ni.com> Co-authored-by: Andrej Rode <andrej.rode@ettus.com> Co-authored-by: Ashish Chaudhari <ashish@ettus.com> Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com> Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Derek Kozel <derek.kozel@ettus.com> Co-authored-by: EJ Kreinar <ej@he360.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Ian Buckley <ian.buckley@gmail.com> Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Jon Kiser <jon.kiser@ni.com> Co-authored-by: Josh Blum <josh@joshknows.com> Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Matt Ettus <matt@ettus.com> Co-authored-by: Michael West <michael.west@ettus.com> Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com> Co-authored-by: Nick Foster <nick@ettus.com> Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Paul David <paul.david@ettus.com> Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com> Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com> Co-authored-by: Sylvain Munaut <tnt@246tNt.com> Co-authored-by: Trung Tran <trung.tran@ettus.com> Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com> Co-authored-by: Wade Fife <wade.fife@ettus.com> Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
This commit is contained in:
co-authored by
Alex Williams
Andrej Rode
Ashish Chaudhari
Ben Hilburn
Ciro Nishiguchi
Daniel Jepson
Derek Kozel
EJ Kreinar
Humberto Jimenez
Ian Buckley
Jörg Hofrichter
Jon Kiser
Josh Blum
Jonathon Pendlum
Matt Ettus
Michael West
Moritz Fischer
Nick Foster
Nicolas Cuervo
Paul Butler
Paul David
Ryan Marlow
Sugandha Gupta
Sylvain Munaut
Trung Tran
Vidush Vishwanath
Wade Fife
parent
74893643ca
commit
6b67702ad7
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2016 Ettus Research
|
||||
#
|
||||
|
||||
include $(TOOLS_DIR)/make/viv_ip_builder.mak
|
||||
|
||||
AURORA_PHY_SRCS = \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_x1.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_mmcm.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_clk_gen.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_axis_mac.v \
|
||||
$(IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS)
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS = $(addprefix $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma_ex/, \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_clock_module.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_gt_common_wrapper.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_support_reset_logic.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_support.v \
|
||||
imports/aurora_64b66b_pcs_pma_cdc_sync_exdes.v \
|
||||
imports/aurora_64b66b_pcs_pma_example_axi_to_ll.v \
|
||||
imports/aurora_64b66b_pcs_pma_example_ll_to_axi.v \
|
||||
)
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_SRCS = $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma/aurora_64b66b_pcs_pma.xci
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_OUTS = $(addprefix $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma/, \
|
||||
aurora_64b66b_pcs_pma.xci.out \
|
||||
)
|
||||
|
||||
$(IP_AURORA_64B66B_PCS_PMA_SRCS) $(IP_AURORA_64B66B_PCS_PMA_OUTS) $(IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS): $(IP_DIR)/aurora_64b66b_pcs_pma/aurora_64b66b_pcs_pma.xci
|
||||
$(call BUILD_VIVADO_IP,aurora_64b66b_pcs_pma,$(ARCH),$(PART_ID),$(IP_DIR),$(IP_BUILD_DIR),1)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,329 @@
|
||||
//
|
||||
// Copyright 2016 Ettus Research LLC
|
||||
//
|
||||
|
||||
module aurora_axis_mac #(
|
||||
parameter PHY_ENDIANNESS = "LITTLE", //{"LITTLE, "BIG"}
|
||||
parameter PACKET_MODE = 0,
|
||||
parameter MAX_PACKET_SIZE = 512,
|
||||
parameter BIST_ENABLED = 1
|
||||
) (
|
||||
// Clocks and resets
|
||||
input phy_clk,
|
||||
input phy_rst,
|
||||
input sys_clk,
|
||||
input sys_rst,
|
||||
input clear,
|
||||
// PHY TX Interface (Synchronous to phy_clk)
|
||||
output [63:0] phy_m_axis_tdata,
|
||||
output phy_m_axis_tvalid,
|
||||
input phy_m_axis_tready,
|
||||
// PHY RX Interface (Synchronous to phy_clk)
|
||||
input [63:0] phy_s_axis_tdata,
|
||||
input phy_s_axis_tvalid,
|
||||
// User TX Interface (Synchronous to sys_clk)
|
||||
input [63:0] s_axis_tdata,
|
||||
input s_axis_tlast,
|
||||
input s_axis_tvalid,
|
||||
output s_axis_tready,
|
||||
// User RX Interface (Synchronous to sys_clk)
|
||||
output [63:0] m_axis_tdata,
|
||||
output m_axis_tlast,
|
||||
output m_axis_tvalid,
|
||||
input m_axis_tready,
|
||||
// PHY Status Inputs (Synchronous to phy_clk)
|
||||
input channel_up,
|
||||
input hard_err,
|
||||
input soft_err,
|
||||
// Status and Error Outputs (Synchronous to sys_clk)
|
||||
output [31:0] overruns,
|
||||
output [31:0] soft_errors,
|
||||
output reg [31:0] checksum_errors,
|
||||
output critical_err,
|
||||
// BIST Interface (Synchronous to sys_clk)
|
||||
input bist_gen_en,
|
||||
input [5:0] bist_gen_rate,
|
||||
input bist_checker_en,
|
||||
input bist_loopback_en,
|
||||
output reg bist_checker_locked,
|
||||
output reg [47:0] bist_checker_samps,
|
||||
output reg [47:0] bist_checker_errors
|
||||
);
|
||||
|
||||
// ----------------------------------------------
|
||||
// Resets, Clears, Clock crossings
|
||||
// ----------------------------------------------
|
||||
|
||||
wire phy_s_axis_tready; // Internal only. The PHY has no backpressure signal.
|
||||
|
||||
// Stay idle if the PHY is not up or if it experiences a fatal error
|
||||
wire clear_sysclk, clear_phyclk;
|
||||
synchronizer #(.INITIAL_VAL(1'b1)) clear_sync_phyclk_i (
|
||||
.clk(phy_clk), .rst(1'b0 /* no reset */), .in((~channel_up) | hard_err | clear), .out(clear_phyclk));
|
||||
synchronizer #(.INITIAL_VAL(1'b1)) clear_sync_sysclk_i (
|
||||
.clk(sys_clk), .rst(1'b0 /* no reset */), .in(clear_phyclk), .out(clear_sysclk));
|
||||
|
||||
// ----------------------------------------------
|
||||
// Counters
|
||||
// ----------------------------------------------
|
||||
|
||||
reg [31:0] overruns_reg;
|
||||
reg [31:0] soft_errors_reg;
|
||||
|
||||
// Counter for recoverable errors. For reporting only.
|
||||
always @(posedge phy_clk)
|
||||
if (phy_rst | clear_phyclk)
|
||||
soft_errors_reg <= 32'd0;
|
||||
else if (soft_err)
|
||||
soft_errors_reg <= soft_errors_reg + 32'd1;
|
||||
|
||||
// Tag an overrun if the FIFO is full. Samples will get dropped
|
||||
always @(posedge phy_clk)
|
||||
if (phy_rst | clear_phyclk)
|
||||
overruns_reg <= 32'd0;
|
||||
else if (phy_s_axis_tvalid & ~phy_s_axis_tready)
|
||||
overruns_reg <= overruns_reg + 32'd1;
|
||||
|
||||
wire [7:0] dummy0;
|
||||
fifo_short_2clk status_counters_2clk_i (
|
||||
.rst(phy_rst),
|
||||
.wr_clk(phy_clk), .din({8'h00, soft_errors_reg, overruns_reg}), .wr_en(1'b1), .full(), .wr_data_count(),
|
||||
.rd_clk(sys_clk), .dout({dummy0, soft_errors, overruns}), .rd_en(1'b1), .empty(), .rd_data_count()
|
||||
);
|
||||
|
||||
// ----------------------------------------------
|
||||
// BIST Wires
|
||||
// ----------------------------------------------
|
||||
|
||||
wire [63:0] bist_o_tdata;
|
||||
wire bist_o_tvalid, bist_o_tready;
|
||||
wire [63:0] bist_i_tdata;
|
||||
wire bist_i_tvalid, bist_i_tready;
|
||||
wire [63:0] loopback_tdata;
|
||||
wire loopback_tvalid, loopback_tready;
|
||||
reg bist_gen_en_reg = 1'b0, bist_checker_en_reg = 1'b0, bist_loopback_en_reg = 1'b0;
|
||||
reg [5:0] bist_gen_rate_reg = 'd0;
|
||||
|
||||
generate if (BIST_ENABLED == 1) begin
|
||||
// Pipeline control signals
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst | clear_sysclk) begin
|
||||
bist_gen_en_reg <= 1'b0;
|
||||
bist_checker_en_reg <= 1'b0;
|
||||
bist_loopback_en_reg <= 1'b0;
|
||||
bist_gen_rate_reg <= 'd0;
|
||||
end else begin
|
||||
bist_gen_en_reg <= bist_gen_en;
|
||||
bist_checker_en_reg <= bist_checker_en;
|
||||
bist_loopback_en_reg <= bist_loopback_en;
|
||||
bist_gen_rate_reg <= bist_gen_rate;
|
||||
end
|
||||
end
|
||||
end endgenerate
|
||||
// ----------------------------------------------
|
||||
// RX Data Path
|
||||
// ----------------------------------------------
|
||||
|
||||
wire [63:0] i_raw_tdata;
|
||||
wire i_raw_tvalid, i_raw_tready;
|
||||
|
||||
wire [63:0] i_pip_tdata;
|
||||
wire i_pip_tvalid, i_pip_tready;
|
||||
|
||||
wire [63:0] i_pkt_tdata;
|
||||
wire i_pkt_tlast, i_pkt_tvalid, i_pkt_tready;
|
||||
|
||||
wire [63:0] i_gt_tdata;
|
||||
wire i_gt_tlast, i_gt_tvalid, i_gt_tready;
|
||||
|
||||
wire checksum_err;
|
||||
|
||||
wire [63:0] phy_s_axis_tdata_endian, phy_m_axis_tdata_endian;
|
||||
|
||||
generate if (PHY_ENDIANNESS == "BIG") begin
|
||||
assign phy_s_axis_tdata_endian = {
|
||||
phy_s_axis_tdata[7:0], phy_s_axis_tdata[15:8], phy_s_axis_tdata[23:16], phy_s_axis_tdata[31:24],
|
||||
phy_s_axis_tdata[39:32], phy_s_axis_tdata[47:40], phy_s_axis_tdata[55:48], phy_s_axis_tdata[63:56]
|
||||
};
|
||||
assign phy_m_axis_tdata = {
|
||||
phy_m_axis_tdata_endian[7:0], phy_m_axis_tdata_endian[15:8], phy_m_axis_tdata_endian[23:16], phy_m_axis_tdata_endian[31:24],
|
||||
phy_m_axis_tdata_endian[39:32], phy_m_axis_tdata_endian[47:40], phy_m_axis_tdata_endian[55:48], phy_m_axis_tdata_endian[63:56]
|
||||
};
|
||||
end else begin
|
||||
assign phy_s_axis_tdata_endian = phy_s_axis_tdata;
|
||||
assign phy_m_axis_tdata = phy_m_axis_tdata_endian;
|
||||
end endgenerate
|
||||
|
||||
// Large FIFO must be able to run input side at 64b@156MHz to sustain 10Gb Rx.
|
||||
axi64_4k_2clk_fifo ingress_fifo_i (
|
||||
.s_aresetn(~phy_rst), .s_aclk(phy_clk),
|
||||
.s_axis_tdata(phy_s_axis_tdata_endian), .s_axis_tlast(phy_s_axis_tvalid), .s_axis_tuser(4'h0),
|
||||
.s_axis_tvalid(phy_s_axis_tvalid), .s_axis_tready(phy_s_axis_tready), .axis_wr_data_count(),
|
||||
.m_aclk(sys_clk),
|
||||
.m_axis_tdata(i_raw_tdata), .m_axis_tlast(), .m_axis_tuser(),
|
||||
.m_axis_tvalid(i_raw_tvalid), .m_axis_tready(i_raw_tready), .axis_rd_data_count()
|
||||
);
|
||||
|
||||
// AXI-Flop to ease timing
|
||||
axi_fifo_flop #(.WIDTH(64)) input_pipe_i0 (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata(i_raw_tdata), .i_tvalid(i_raw_tvalid), .i_tready(i_raw_tready),
|
||||
.o_tdata(i_pip_tdata), .o_tvalid(i_pip_tvalid),
|
||||
.o_tready(bist_checker_en_reg ? bist_i_tready : (bist_loopback_en_reg ? loopback_tready : i_pip_tready)),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
assign bist_i_tdata = i_pip_tdata;
|
||||
assign bist_i_tvalid = i_pip_tvalid & bist_checker_en_reg;
|
||||
|
||||
assign loopback_tdata = i_pip_tdata;
|
||||
assign loopback_tvalid = i_pip_tvalid & bist_loopback_en_reg;
|
||||
|
||||
axi_strip_preamble #(.WIDTH(64), .MAX_PKT_SIZE(MAX_PACKET_SIZE)) axi_strip_preamble_i (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata(i_pip_tdata), .i_tvalid(i_pip_tvalid & ~bist_checker_en_reg & ~bist_loopback_en_reg), .i_tready(i_pip_tready),
|
||||
.o_tdata(i_gt_tdata), .o_tlast(i_gt_tlast), .o_tvalid(i_gt_tvalid), .o_tready(i_gt_tready),
|
||||
.crc_err(checksum_err), .pkt_dropped(), .crit_error(critical_err)
|
||||
);
|
||||
|
||||
axi_fifo_flop #(.WIDTH(65)) input_pipe_i1 (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata({i_gt_tlast, i_gt_tdata}), .i_tvalid(i_gt_tvalid), .i_tready(i_gt_tready),
|
||||
.o_tdata({m_axis_tlast, m_axis_tdata}), .o_tvalid(m_axis_tvalid), .o_tready(m_axis_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
always @(posedge sys_clk)
|
||||
if (sys_rst | clear_sysclk)
|
||||
checksum_errors <= 32'd0;
|
||||
else if (checksum_err)
|
||||
checksum_errors <= checksum_errors + 32'd1;
|
||||
|
||||
// ----------------------------------------------
|
||||
// TX Data Path
|
||||
// ----------------------------------------------
|
||||
|
||||
wire [63:0] o_pkt_tdata;
|
||||
wire o_pkt_tlast, o_pkt_tvalid, o_pkt_tready;
|
||||
|
||||
wire [63:0] o_pip_tdata;
|
||||
wire o_pip_tvalid, o_pip_tready;
|
||||
|
||||
wire [63:0] o_raw_tdata;
|
||||
wire o_raw_tvalid, o_raw_tready;
|
||||
|
||||
// AXI-Flop to ease timing
|
||||
axi_fifo_flop #(.WIDTH(65)) output_pipe_i0 (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata({s_axis_tlast, s_axis_tdata}), .i_tvalid(s_axis_tvalid), .i_tready(s_axis_tready),
|
||||
.o_tdata({o_pkt_tlast, o_pkt_tdata}), .o_tvalid(o_pkt_tvalid), .o_tready(o_pkt_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
// Insert preamble and EOP
|
||||
axi_add_preamble #(.WIDTH(64)) axi_add_preamble_i (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata(o_pkt_tdata), .i_tlast(o_pkt_tlast), .i_tvalid(o_pkt_tvalid), .i_tready(o_pkt_tready),
|
||||
.o_tdata(o_pip_tdata), .o_tvalid(o_pip_tvalid), .o_tready(o_pip_tready & ~bist_gen_en_reg & ~bist_loopback_en_reg)
|
||||
);
|
||||
|
||||
// AXI-Flop to ease timing
|
||||
axi_fifo_flop #(.WIDTH(64)) output_pipe_i1 (
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(clear_sysclk),
|
||||
.i_tdata(bist_gen_en_reg ? bist_o_tdata : (bist_loopback_en_reg ? loopback_tdata : o_pip_tdata)),
|
||||
.i_tvalid(bist_gen_en_reg ? bist_o_tvalid : (bist_loopback_en_reg ? loopback_tvalid : o_pip_tvalid)),
|
||||
.i_tready(o_pip_tready),
|
||||
.o_tdata(o_raw_tdata), .o_tvalid(o_raw_tvalid), .o_tready(o_raw_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
assign bist_o_tready = o_pip_tready;
|
||||
assign loopback_tready = o_pip_tready;
|
||||
|
||||
// Egress FIFO
|
||||
axi64_4k_2clk_fifo egress_fifo_i (
|
||||
.s_aresetn(~phy_rst), .s_aclk(sys_clk),
|
||||
.s_axis_tdata(o_raw_tdata), .s_axis_tlast(o_raw_tvalid), .s_axis_tuser(4'h0),
|
||||
.s_axis_tvalid(o_raw_tvalid), .s_axis_tready(o_raw_tready), .axis_wr_data_count(),
|
||||
.m_aclk(phy_clk),
|
||||
.m_axis_tdata(phy_m_axis_tdata_endian), .m_axis_tlast(), .m_axis_tuser(),
|
||||
.m_axis_tvalid(phy_m_axis_tvalid), .m_axis_tready(phy_m_axis_tready), .axis_rd_data_count()
|
||||
);
|
||||
|
||||
// -------------------------------------------------
|
||||
// BIST: Generator and checker for a LFSR polynomial
|
||||
// -------------------------------------------------
|
||||
localparam LFSR_LEN = 32;
|
||||
localparam LFSR_SEED = {LFSR_LEN{1'b1}};
|
||||
|
||||
function [LFSR_LEN-1:0] compute_lfsr_next;
|
||||
input [LFSR_LEN-1:0] current;
|
||||
// Maximal length polynomial: x^32 + x^22 + x^2 + x^1 + 1
|
||||
compute_lfsr_next = {current[30:0], current[31]^current[21]^current[1]^current[0]};
|
||||
endfunction
|
||||
|
||||
function [63:0] lfsr_to_axis;
|
||||
input [LFSR_LEN-1:0] lfsr;
|
||||
lfsr_to_axis = {~lfsr, lfsr};
|
||||
endfunction
|
||||
|
||||
function [LFSR_LEN-1:0] axis_to_lfsr;
|
||||
input [63:0] axis;
|
||||
axis_to_lfsr = axis[LFSR_LEN-1:0];
|
||||
endfunction
|
||||
|
||||
generate if (BIST_ENABLED == 1) begin
|
||||
// Throttle outgoing LFSR to based on the specified rate
|
||||
// BIST Throughput = sys_clk BW * (bist_gen_rate+1)/64
|
||||
reg [5:0] throttle_cnt;
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst | clear_sysclk)
|
||||
throttle_cnt <= 6'd0;
|
||||
else if (bist_gen_en_reg)
|
||||
throttle_cnt <= throttle_cnt + 6'd1;
|
||||
end
|
||||
// NOTE: This techinically violates AXIS spec (valid revocation)
|
||||
assign bist_o_tvalid = bist_gen_en_reg && (throttle_cnt <= bist_gen_rate_reg);
|
||||
|
||||
// Unsynchronized LFSR generator (for BIST output)
|
||||
reg [LFSR_LEN-1:0] lfsr_gen = LFSR_SEED, lfsr_check = LFSR_SEED;
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst | clear_sysclk | ~bist_gen_en_reg)
|
||||
lfsr_gen <= LFSR_SEED;
|
||||
else if (bist_o_tready & bist_o_tvalid)
|
||||
lfsr_gen <= compute_lfsr_next(lfsr_gen);
|
||||
end
|
||||
assign bist_o_tdata = lfsr_to_axis(lfsr_gen);
|
||||
|
||||
// Synchronized LFSR checker (for BIST input)
|
||||
wire [LFSR_LEN-1:0] lfsr_next = compute_lfsr_next(lfsr_check);;
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst | clear_sysclk | ~bist_checker_en_reg) begin
|
||||
bist_checker_locked <= 1'b0;
|
||||
lfsr_check <= LFSR_SEED;
|
||||
end else if (bist_i_tvalid && bist_i_tready) begin
|
||||
lfsr_check <= axis_to_lfsr(bist_i_tdata);
|
||||
if (bist_i_tdata == lfsr_to_axis(LFSR_SEED))
|
||||
bist_checker_locked <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// LFSR checker
|
||||
always @(posedge sys_clk) begin
|
||||
if (bist_checker_locked) begin
|
||||
if (bist_i_tvalid & bist_i_tready) begin
|
||||
bist_checker_samps <= bist_checker_samps + 48'd1;
|
||||
if (bist_i_tdata != lfsr_to_axis(lfsr_next)) begin
|
||||
bist_checker_errors <= bist_checker_errors + 48'd1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
bist_checker_samps <= 48'd0;
|
||||
bist_checker_errors <= 48'd0;
|
||||
end
|
||||
end
|
||||
assign bist_i_tready = 1'b1;
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright 2016 Ettus Research LLC
|
||||
//
|
||||
|
||||
module aurora_phy_clk_gen
|
||||
(
|
||||
input refclk_ibuf,
|
||||
output clk156,
|
||||
output init_clk
|
||||
);
|
||||
|
||||
wire init_clk_buf;
|
||||
|
||||
BUFG clk156_bufg_inst (
|
||||
.I (refclk_ibuf),
|
||||
.O (clk156)
|
||||
);
|
||||
|
||||
// Divding independent clock by 2 as source for DRP clock
|
||||
BUFR # (
|
||||
.BUFR_DIVIDE ("2")
|
||||
) dclk_divide_by_2_buf (
|
||||
.I (clk156),
|
||||
.O (init_clk_buf),
|
||||
.CE (1'b1),
|
||||
.CLR (1'b0)
|
||||
);
|
||||
|
||||
BUFG dclk_bufg_i (
|
||||
.I (init_clk_buf),
|
||||
.O (init_clk)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// Copyright 2017 Ettus Research LLC
|
||||
//
|
||||
|
||||
module aurora_phy_mmcm
|
||||
(
|
||||
input aurora_tx_clk_unbuf,
|
||||
input mmcm_reset,
|
||||
output user_clk,
|
||||
output sync_clk,
|
||||
output mmcm_locked
|
||||
);
|
||||
|
||||
wire mmcm_fb_clk;
|
||||
wire user_clk_i;
|
||||
wire sync_clk_i;
|
||||
wire aurora_tx_clk;
|
||||
|
||||
BUFG txout_clock_net_i (
|
||||
.I(aurora_tx_clk_unbuf),
|
||||
.O(aurora_tx_clk)
|
||||
);
|
||||
|
||||
localparam MULT = 10;
|
||||
localparam DIVIDE = 5;
|
||||
localparam CLK_PERIOD = 3.103;
|
||||
localparam OUT0_DIVIDE = 4;
|
||||
localparam OUT1_DIVIDE = 2;
|
||||
localparam OUT2_DIVIDE = 6;
|
||||
localparam OUT3_DIVIDE = 8;
|
||||
|
||||
MMCME2_ADV #(
|
||||
.BANDWIDTH ("OPTIMIZED"),
|
||||
.CLKOUT4_CASCADE ("FALSE"),
|
||||
.COMPENSATION ("ZHOLD"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (DIVIDE),
|
||||
.CLKFBOUT_MULT_F (MULT),
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKFBOUT_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT0_DIVIDE_F (OUT0_DIVIDE),
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT0_USE_FINE_PS ("FALSE"),
|
||||
.CLKIN1_PERIOD (CLK_PERIOD),
|
||||
.CLKOUT1_DIVIDE (OUT1_DIVIDE),
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT2_DIVIDE (OUT2_DIVIDE),
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT3_DIVIDE (OUT3_DIVIDE),
|
||||
.CLKOUT3_PHASE (0.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_USE_FINE_PS ("FALSE"),
|
||||
.REF_JITTER1 (0.010)
|
||||
) mmcm_adv_inst (
|
||||
.CLKFBOUT (mmcm_fb_clk),
|
||||
.CLKFBOUTB (),
|
||||
.CLKOUT0 (user_clk_i),
|
||||
.CLKOUT0B (),
|
||||
.CLKOUT1 (sync_clk_i),
|
||||
.CLKOUT1B (),
|
||||
.CLKOUT2 (),
|
||||
.CLKOUT2B (),
|
||||
.CLKOUT3 (),
|
||||
.CLKOUT3B (),
|
||||
.CLKOUT4 (),
|
||||
.CLKOUT5 (),
|
||||
.CLKOUT6 (),
|
||||
// Input clock control
|
||||
.CLKFBIN (mmcm_fb_clk),
|
||||
.CLKIN1 (aurora_tx_clk),
|
||||
.CLKIN2 (1'b0),
|
||||
// Tied to always select the primary input clock
|
||||
.CLKINSEL (1'b1),
|
||||
// Ports for dynamic reconfiguration
|
||||
.DADDR (7'h0),
|
||||
.DCLK (1'b0),
|
||||
.DEN (1'b0),
|
||||
.DI (16'h0),
|
||||
.DO (),
|
||||
.DRDY (),
|
||||
.DWE (1'b0),
|
||||
// Ports for dynamic phase shift
|
||||
.PSCLK (1'b0),
|
||||
.PSEN (1'b0),
|
||||
.PSINCDEC (1'b0),
|
||||
.PSDONE (),
|
||||
// Other control and status signals
|
||||
.LOCKED (mmcm_locked),
|
||||
.CLKINSTOPPED (),
|
||||
.CLKFBSTOPPED (),
|
||||
.PWRDWN (1'b0),
|
||||
.RST (mmcm_reset)
|
||||
);
|
||||
|
||||
BUFG user_clk_net_i (
|
||||
.I(user_clk_i),
|
||||
.O(user_clk)
|
||||
);
|
||||
BUFG sync_clock_net_i (
|
||||
.I(sync_clk_i),
|
||||
.O(sync_clk)
|
||||
);
|
||||
endmodule
|
||||
@@ -0,0 +1,258 @@
|
||||
//
|
||||
// Copyright 2016 Ettus Research LLC
|
||||
//
|
||||
|
||||
module aurora_phy_x1 #(
|
||||
parameter SIMULATION = 0
|
||||
)(
|
||||
// Clocks and Resets
|
||||
input areset,
|
||||
input refclk,
|
||||
input user_clk,
|
||||
input sync_clk,
|
||||
input init_clk,
|
||||
input qpllclk,
|
||||
input qpllrefclk,
|
||||
output user_rst,
|
||||
// GTX Serial I/O
|
||||
input rx_p,
|
||||
input rx_n,
|
||||
output tx_p,
|
||||
output tx_n,
|
||||
// AXI4-Stream TX Interface
|
||||
input [63:0] s_axis_tdata,
|
||||
input s_axis_tvalid,
|
||||
output s_axis_tready,
|
||||
// AXI4-Stream RX Interface
|
||||
output [63:0] m_axis_tdata,
|
||||
output m_axis_tvalid,
|
||||
// AXI4-Lite Config Interface
|
||||
input [31:0] s_axi_awaddr,
|
||||
input [31:0] s_axi_araddr,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [3:0] s_axi_wstrb,
|
||||
input s_axi_awvalid,
|
||||
input s_axi_rready,
|
||||
output [31:0] s_axi_rdata,
|
||||
output s_axi_awready,
|
||||
output s_axi_wready,
|
||||
output s_axi_bvalid,
|
||||
output [1:0] s_axi_bresp,
|
||||
output [1:0] s_axi_rresp,
|
||||
input s_axi_bready,
|
||||
output s_axi_arready,
|
||||
output s_axi_rvalid,
|
||||
input s_axi_arvalid,
|
||||
input s_axi_wvalid,
|
||||
// Status and Error Reporting Interface
|
||||
output reg channel_up,
|
||||
output reg hard_err,
|
||||
output reg soft_err,
|
||||
input qplllock,
|
||||
input qpllrefclklost,
|
||||
output qpllreset,
|
||||
output tx_out_clk,
|
||||
input mmcm_locked,
|
||||
output gt_pll_lock
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Status and Error Signals
|
||||
//--------------------------------------------------------------
|
||||
wire hard_err_i, soft_err_i, channel_up_i, lane_up_i;
|
||||
always @(posedge user_clk) begin
|
||||
hard_err <= hard_err_i;
|
||||
soft_err <= soft_err_i;
|
||||
channel_up <= channel_up_i && lane_up_i;
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Reset and PMA Init Sequence
|
||||
//--------------------------------------------------------------
|
||||
// Requirements from PG074:
|
||||
// - It is expected that user_clock is stable when the reset_pb signal is applied.
|
||||
// - During the board power-on sequence, both the pma_init and reset_pb signals are
|
||||
// expected to be High. INIT_CLK and GT_REFCLK are expected to be stable during
|
||||
// power-on for the proper functioning of the Aurora 64B/66B core. When both clocks are
|
||||
// stable, pma_init is deasserted followed by the deassertion of reset_pb.
|
||||
// - Normal Operation Reset Sequence:
|
||||
// 1. Assert reset. Wait for a minimum time equal to 128*user_clk's time-period.
|
||||
// 2. Assert pma_init. Keep pma_init and reset asserted for at least one second to prevent
|
||||
// the transmission of CC characters and ensure that the remote agent detects a hot plug event.
|
||||
// 3. Deassert pma_init.
|
||||
// 4. Deassert reset_pb.
|
||||
|
||||
localparam PWRON_PMA_INIT_CYC = 32'd1024;
|
||||
localparam SYSRST_ASSERT_CYC = 32'd128;
|
||||
localparam PMA_INIT_ASSERT_CYC_LOG2 = (SIMULATION == 1) ? 4 : 26;
|
||||
localparam SYSRST_DEASSERT_CYC = 32'd20;
|
||||
|
||||
wire reset_iclk, pma_init, reset_pb;
|
||||
wire gt_pll_lock_iclk, mmcm_locked_iclk;
|
||||
|
||||
synchronizer #( .STAGES(3), .INITIAL_VAL(1'b1) ) input_rst_sync_i (
|
||||
.clk(init_clk), .rst(1'b0), .in(areset), .out(reset_iclk)
|
||||
);
|
||||
|
||||
synchronizer #( .STAGES(3), .INITIAL_VAL(1'b0) ) gt_pll_lock_sync_i (
|
||||
.clk(init_clk), .rst(1'b0), .in(gt_pll_lock), .out(gt_pll_lock_iclk)
|
||||
);
|
||||
|
||||
synchronizer #( .STAGES(3), .INITIAL_VAL(1'b0) ) mmcm_locked_sync_i (
|
||||
.clk(init_clk), .rst(1'b0), .in(mmcm_locked), .out(mmcm_locked_iclk)
|
||||
);
|
||||
|
||||
localparam [2:0] RST_ST_PWRON_PMA_INIT = 3'd0;
|
||||
localparam [2:0] RST_ST_PWRON_PMA_SYSRST = 3'd1;
|
||||
localparam [2:0] RST_ST_IDLE = 3'd2;
|
||||
localparam [2:0] RST_ST_SYSRST_PRE = 3'd3;
|
||||
localparam [2:0] RST_ST_PMA_INIT = 3'd4;
|
||||
localparam [2:0] RST_ST_SYSRST_POST = 3'd5;
|
||||
|
||||
reg [2:0] rst_state = RST_ST_PWRON_PMA_INIT;
|
||||
reg [31:0] rst_counter = PWRON_PMA_INIT_CYC;
|
||||
|
||||
always @(posedge init_clk) begin
|
||||
case (rst_state)
|
||||
RST_ST_PWRON_PMA_INIT: begin
|
||||
if (rst_counter == 32'd0) begin
|
||||
rst_state <= RST_ST_PWRON_PMA_SYSRST;
|
||||
rst_counter <= SYSRST_DEASSERT_CYC;
|
||||
end else begin
|
||||
rst_counter <= rst_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
RST_ST_PWRON_PMA_SYSRST: begin
|
||||
if (rst_counter == 32'd0) begin
|
||||
rst_state <= RST_ST_IDLE;
|
||||
end else begin
|
||||
rst_counter <= rst_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
RST_ST_IDLE: begin
|
||||
if (reset_iclk) begin
|
||||
rst_state <= RST_ST_SYSRST_PRE;
|
||||
rst_counter <= SYSRST_ASSERT_CYC;
|
||||
end
|
||||
end
|
||||
RST_ST_SYSRST_PRE: begin
|
||||
if (rst_counter == 32'd0) begin
|
||||
rst_state <= RST_ST_PMA_INIT;
|
||||
rst_counter <= {{(32-PMA_INIT_ASSERT_CYC_LOG2){1'b0}}, {PMA_INIT_ASSERT_CYC_LOG2{1'b1}}};
|
||||
end else if (mmcm_locked_iclk) begin
|
||||
rst_counter <= rst_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
RST_ST_PMA_INIT: begin
|
||||
if (rst_counter == 32'd0) begin
|
||||
rst_state <= RST_ST_SYSRST_POST;
|
||||
rst_counter <= SYSRST_DEASSERT_CYC;
|
||||
end else begin
|
||||
rst_counter <= rst_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
RST_ST_SYSRST_POST: begin
|
||||
if (rst_counter == 32'd0) begin
|
||||
rst_state <= RST_ST_IDLE;
|
||||
end else begin
|
||||
rst_counter <= rst_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign reset_pb = (rst_state != RST_ST_IDLE);
|
||||
assign pma_init = (rst_state == RST_ST_PMA_INIT || rst_state == RST_ST_PWRON_PMA_INIT);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// GT Common
|
||||
//--------------------------------------------------------------
|
||||
wire gt_qpllclk_quad1_i;
|
||||
wire gt_qpllrefclk_quad1_i;
|
||||
wire gt_qpllclk_quad2_i;
|
||||
wire gt_qpllrefclk_quad2_i;
|
||||
wire gt_to_common_qpllreset_i;
|
||||
wire gt_qpllrefclklost_i;
|
||||
wire gt_qplllock_i;
|
||||
|
||||
assign gt_qpllclk_quad1_i = qpllclk;
|
||||
assign gt_qpllrefclk_quad1_i = qpllrefclk;
|
||||
assign gt_qpllclk_quad2_i = qpllclk;
|
||||
assign gt_qpllrefclk_quad2_i = qpllrefclk;
|
||||
assign gt_qplllock_i = qplllock;
|
||||
assign gt_qpllrefclklost_i = qpllrefclklost;
|
||||
assign qpllreset = gt_to_common_qpllreset_i;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// IP Instantiation
|
||||
//--------------------------------------------------------------
|
||||
|
||||
wire gt_rxcdrovrden_i = 1'b0;
|
||||
wire [2:0] loopback_i = 3'b000;
|
||||
wire power_down_i = 1'b0;
|
||||
aurora_64b66b_pcs_pma aurora_64b66b_pcs_pma_i (
|
||||
.refclk1_in (refclk),
|
||||
// TX AXI4-S Interface
|
||||
.s_axi_tx_tdata (s_axis_tdata),
|
||||
.s_axi_tx_tvalid (s_axis_tvalid),
|
||||
.s_axi_tx_tready (s_axis_tready),
|
||||
// RX AXI4-S Interface
|
||||
.m_axi_rx_tdata (m_axis_tdata),
|
||||
.m_axi_rx_tvalid (m_axis_tvalid),
|
||||
// GTX Serial I/O
|
||||
.rxp (rx_p),
|
||||
.rxn (rx_n),
|
||||
.txp (tx_p),
|
||||
.txn (tx_n),
|
||||
// Status and Error
|
||||
.hard_err (hard_err_i),
|
||||
.soft_err (soft_err_i),
|
||||
.channel_up (channel_up_i),
|
||||
.lane_up (lane_up_i),
|
||||
// System Interface
|
||||
.mmcm_not_locked (!mmcm_locked),
|
||||
.user_clk (user_clk),
|
||||
.sync_clk (sync_clk),
|
||||
.reset_pb (reset_pb),
|
||||
.gt_rxcdrovrden_in (gt_rxcdrovrden_i),
|
||||
.power_down (power_down_i),
|
||||
.loopback (loopback_i),
|
||||
.pma_init (pma_init),
|
||||
.gt_pll_lock (gt_pll_lock),
|
||||
.drp_clk_in (init_clk),
|
||||
.gt_qpllclk_quad1_in (gt_qpllclk_quad1_i),
|
||||
.gt_qpllrefclk_quad1_in (gt_qpllrefclk_quad1_i),
|
||||
.gt_to_common_qpllreset_out(gt_to_common_qpllreset_i),
|
||||
.gt_qplllock_in (gt_qplllock_i),
|
||||
.gt_qpllrefclklost_in (gt_qpllrefclklost_i),
|
||||
// AXI4-Lite config
|
||||
.s_axi_awaddr (s_axi_awaddr),
|
||||
.s_axi_awvalid (s_axi_awvalid),
|
||||
.s_axi_awready (s_axi_awready),
|
||||
.s_axi_wdata (s_axi_wdata),
|
||||
.s_axi_wstrb (s_axi_wstrb),
|
||||
.s_axi_wvalid (s_axi_wvalid),
|
||||
.s_axi_wready (s_axi_wready),
|
||||
.s_axi_bvalid (s_axi_bvalid),
|
||||
.s_axi_bresp (s_axi_bresp),
|
||||
.s_axi_bready (s_axi_bready),
|
||||
.s_axi_araddr (s_axi_araddr),
|
||||
.s_axi_arvalid (s_axi_arvalid),
|
||||
.s_axi_arready (s_axi_arready),
|
||||
.s_axi_rdata (s_axi_rdata),
|
||||
.s_axi_rvalid (s_axi_rvalid),
|
||||
.s_axi_rresp (s_axi_rresp),
|
||||
.s_axi_rready (s_axi_rready),
|
||||
// GTXE2 COMMON DRP Ports
|
||||
.qpll_drpaddr_in (qpll_drpaddr_in_i),
|
||||
.qpll_drpdi_in (qpll_drpdi_in_i),
|
||||
.qpll_drpdo_out (),
|
||||
.qpll_drprdy_out (),
|
||||
.qpll_drpen_in (qpll_drpen_in_i),
|
||||
.qpll_drpwe_in (qpll_drpwe_in_i),
|
||||
.init_clk (init_clk),
|
||||
.link_reset_out (),
|
||||
.sys_reset_out (user_rst),
|
||||
.tx_out_clk (tx_out_clk)
|
||||
);
|
||||
endmodule
|
||||
Reference in New Issue
Block a user