initial commit, add dds_par module

This commit is contained in:
2024-01-15 09:36:08 +08:00
commit 315a673005
1374 changed files with 465956 additions and 0 deletions
@@ -0,0 +1,15 @@
####################################################################################
## Copyright (c) 2018 - 2023 Analog Devices, Inc.
### SPDX short identifier: BSD-1-Clause
## Auto-generated, do not modify!
####################################################################################
LIBRARY_NAME := jesd204_soft_pcs_rx
GENERIC_DEPS += jesd204_8b10b_decoder.v
GENERIC_DEPS += jesd204_pattern_align.v
GENERIC_DEPS += jesd204_soft_pcs_rx.v
INTEL_DEPS += jesd204_soft_pcs_rx_hw.tcl
include ../../scripts/library.mk
@@ -0,0 +1,379 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2017, 2018, 2020, 2022 Analog Devices, Inc. All rights reserved.
// SPDX short identifier: ADIJESD204
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module jesd204_8b10b_decoder (
input in_disparity,
input [9:0] in_char,
output [7:0] out_char,
output out_charisk,
output out_notintable,
output reg out_disperr,
output reg out_disparity
);
/*
* Only supports the subset of 8b10b that is used by JESD204.
* If non-supported control characters are supplied the output is undefined.
*/
reg [4:0] data5b;
reg notintable5b;
reg [1:0] disparity5b;
reg ignore5b;
reg [2:0] data3b;
reg notintable3b;
reg [1:0] disparity3b;
reg ignore3b;
reg [1:0] total_disparity;
reg notintable_disparity;
// Only detect K28.X
wire charisk = in_char[5:0] == 6'b000011 || in_char[5:0] == 6'b111100;
always @(*) begin
notintable5b = 1'b0;
disparity5b = 2'b00;
ignore5b = 1'b0;
case (in_char[5:0])
6'b000011: begin
data5b = 5'd28;
disparity5b = 2'b11;
end
6'b111100: begin
data5b = 5'd28;
disparity5b = 2'b01;
end
6'b000110: begin
data5b = 5'd00;
disparity5b = 2'b11;
end
6'b111001: begin
data5b = 5'd00;
disparity5b = 2'b01;
end
6'b010001: begin
data5b = 5'd01;
disparity5b = 2'b11;
end
6'b101110: begin
data5b = 5'd01;
disparity5b = 2'b01;
end
6'b010010: begin
data5b = 5'd02;
disparity5b = 2'b11;
end
6'b101101: begin
data5b = 5'd02;
disparity5b = 2'b01;
end
6'b100011: begin
data5b = 5'd03;
end
6'b010100: begin
data5b = 5'd04;
disparity5b = 2'b11;
end
6'b101011: begin
data5b = 5'd04;
disparity5b = 2'b01;
end
6'b100101: begin
data5b = 5'd05;
end
6'b100110: begin
data5b = 5'd06;
end
6'b000111: begin
data5b = 5'd7;
disparity5b = 2'b11;
ignore5b = 1'b1;
end
6'b111000: begin
data5b = 5'd7;
disparity5b = 2'b01;
ignore5b = 1'b1;
end
6'b011000: begin
data5b = 5'd8;
disparity5b = 2'b11;
end
6'b100111: begin
data5b = 5'd8;
disparity5b = 2'b01;
end
6'b101001: begin
data5b = 5'd9;
end
6'b101010: begin
data5b = 5'd10;
end
6'b001011: begin
data5b = 5'd11;
end
6'b101100: begin
data5b = 5'd12;
end
6'b001101: begin
data5b = 5'd13;
end
6'b001110: begin
data5b = 5'd14;
end
6'b000101: begin
data5b = 5'd15;
disparity5b = 2'b11;
end
6'b111010: begin
data5b = 5'd15;
disparity5b = 2'b01;
end
6'b001001: begin
data5b = 5'd16;
disparity5b = 2'b11;
end
6'b110110: begin
data5b = 5'd16;
disparity5b = 2'b01;
end
6'b110001: begin
data5b = 5'd17;
end
6'b110010: begin
data5b = 5'd18;
end
6'b010011: begin
data5b = 5'd19;
end
6'b110100: begin
data5b = 5'd20;
end
6'b010101: begin
data5b = 5'd21;
end
6'b010110: begin
data5b = 5'd22;
end
6'b101000: begin
data5b = 5'd23;
disparity5b = 2'b11;
end
6'b010111: begin
data5b = 5'd23;
disparity5b = 2'b01;
end
6'b001100: begin
data5b = 5'd24;
disparity5b = 2'b11;
end
6'b110011: begin
data5b = 5'd24;
disparity5b = 2'b01;
end
6'b011001: begin
data5b = 5'd25;
end
6'b011010: begin
data5b = 5'd26;
end
6'b100100: begin
data5b = 5'd27;
disparity5b = 2'b11;
end
6'b011011: begin
data5b = 5'd27;
disparity5b = 2'b01;
end
6'b011100: begin
data5b = 5'd28;
end
6'b100010: begin
data5b = 5'd29;
disparity5b = 2'b11;
end
6'b011101: begin
data5b = 5'd29;
disparity5b = 2'b01;
end
6'b100001: begin
data5b = 5'd30;
disparity5b = 2'b11;
end
6'b011110: begin
data5b = 5'd30;
disparity5b = 2'b01;
end
6'b001010: begin
data5b = 5'd31;
disparity5b = 2'b11;
end
6'b110101: begin
data5b = 5'd31;
disparity5b = 2'b01;
end
default: begin
data5b = 5'd00;
notintable5b = 1'b1;
end
endcase
end
always @(*) begin
ignore3b = 1'b0;
case (in_char[9:6])
4'b0010: begin
disparity3b = 2'b11;
end
4'b1101: begin
disparity3b = 2'b01;
end
4'b1100: begin
disparity3b = 2'b11;
ignore3b = 1'b1;
end
4'b0011: begin
disparity3b = 2'b01;
ignore3b = 1'b1;
end
4'b0100: begin
disparity3b = 2'b11;
end
4'b1011: begin
disparity3b = 2'b01;
end
4'b1000: begin
disparity3b = 2'b11;
end
4'b0111: begin
disparity3b = 2'b01;
end
4'b0001: begin
disparity3b = 2'b11;
end
4'b1110: begin
disparity3b = 2'b01;
end
default: begin
disparity3b = 2'b00;
end
endcase
end
always @(*) begin
notintable3b = 1'b0;
if (charisk == 1'b1) begin
case (in_char[9:6] ^ {4{in_char[5]}})
4'b1101: begin
data3b = 3'd0;
end
4'b0011: begin
data3b = 3'd3;
end
4'b1011: begin
data3b = 3'd4;
end
4'b1010: begin
data3b = 3'd5;
end
4'b1110: begin
data3b = 3'd7;
end
default: begin
data3b = 3'd0;
notintable3b = 1'b1;
end
endcase
end else begin
case (in_char[9:6])
4'b0010: begin
data3b = 3'd0;
end
4'b1101: begin
data3b = 3'd0;
end
4'b1001: begin
data3b = 3'd1;
end
4'b1010: begin
data3b = 3'd2;
end
4'b1100: begin
data3b = 3'd3;
end
4'b0011: begin
data3b = 3'd3;
end
4'b0100: begin
data3b = 3'd4;
end
4'b1011: begin
data3b = 3'd4;
end
4'b0101: begin
data3b = 3'd5;
end
4'b0110: begin
data3b = 3'd6;
end
4'b1000: begin
data3b = 3'd7;
notintable3b = in_char[5:4] == 2'b00;
end
4'b0111: begin
data3b = 3'd7;
notintable3b = in_char[5:4] == 2'b11;
end
4'b0001: begin
data3b = 3'd7;
notintable3b = in_char[5:4] != 2'b00;
end
4'b1110: begin
data3b = 3'd7;
notintable3b = in_char[5:4] != 2'b11;
end
default: begin
data3b = 3'd0;
notintable3b = 1'b1;
end
endcase
end
end
always @(*) begin
if (disparity3b == disparity5b && disparity3b != 2'b00) begin
notintable_disparity = 1'b1;
end else begin
notintable_disparity = 1'b0;
end
end
always @(*) begin
total_disparity = (ignore3b ? 2'b00 : disparity3b) ^ (ignore5b ? 2'b00 : disparity5b);
if (total_disparity[0] == 1'b0 || out_notintable == 1'b1) begin
out_disparity = in_disparity;
out_disperr = 1'b0;
end else if (total_disparity[1] == 1'b1) begin
out_disparity = 1'b0;
out_disperr = ~in_disparity;
end else begin
out_disparity = 1'b1;
out_disperr = in_disparity;
end
end
assign out_char = {data3b,data5b};
assign out_charisk = charisk;
assign out_notintable = notintable5b | notintable3b | notintable_disparity;
endmodule
@@ -0,0 +1,118 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2017, 2018, 2020, 2022 Analog Devices, Inc. All rights reserved.
// SPDX short identifier: ADIJESD204
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module jesd204_pattern_align #(
parameter DATA_PATH_WIDTH = 4
) (
input clk,
input reset,
input patternalign_en,
input [DATA_PATH_WIDTH*10-1:0] in_data,
output [DATA_PATH_WIDTH*10-1:0] out_data
);
localparam [9:0] PATTERN_P = 10'b1010000011;
localparam [9:0] PATTERN_N = 10'b0101111100;
reg [1:0] match_counter = 2'h0;
reg pattern_sync = 1'b0;
reg pattern_match = 1'b0;
reg [3:0] align = 4'h0;
reg [1:0] cooldown = 2'h3;
reg [8:0] data_d1 = 9'h00;
reg [DATA_PATH_WIDTH*10+2:0] aligned_data_stage1;
reg [DATA_PATH_WIDTH*10-1:0] aligned_data_stage2;
wire [(DATA_PATH_WIDTH+1)*10-2:0] full_data;
assign full_data = {in_data,data_d1};
assign out_data = aligned_data_stage2;
/* 2-stage cascade of 3:1 and 4:1 muxes */
integer i;
always @(*) begin
for (i = 0; i < DATA_PATH_WIDTH*10+3; i = i + 1) begin
if (i < DATA_PATH_WIDTH*10+1) begin
case (align[3:2])
2'b00: aligned_data_stage1[i] = full_data[i];
2'b01: aligned_data_stage1[i] = full_data[i+4];
2'b10: aligned_data_stage1[i] = full_data[i+8];
default: aligned_data_stage1[i] = 1'b0;
endcase
end else begin
case (align[2])
1'b0: aligned_data_stage1[i] = full_data[i];
default: aligned_data_stage1[i] = full_data[i+4];
endcase
end
end
aligned_data_stage2 = aligned_data_stage1[align[1:0]+:DATA_PATH_WIDTH*10];
end
always @(posedge clk) begin
data_d1 <= in_data[DATA_PATH_WIDTH*10-9+:9];
end
always @(posedge clk) begin
if (out_data[9:0] == PATTERN_P || out_data[9:0] == PATTERN_N) begin
pattern_match <= 1'b1;
end else begin
pattern_match <= 1'b0;
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
cooldown <= 2'h3;
align <= 4'h0;
end else begin
if (cooldown != 2'h0) begin
cooldown <= cooldown - 1'b1;
end else if (patternalign_en == 1'b1 && pattern_sync == 1'b0 &&
pattern_match == 1'b0) begin
cooldown <= 2'h3;
if (align == 'h9) begin
align <= 4'h0;
end else begin
align <= align + 1'b1;
end
end
end
end
always @(posedge clk) begin
if (reset == 1'b1) begin
pattern_sync <= 1'b0;
match_counter <= 2'h0;
end else begin
if (match_counter == 2'h0) begin
pattern_sync <= 1'b0;
end else if (match_counter == 2'h3) begin
pattern_sync <= 1'b1;
end
if (pattern_match == 1'b1) begin
if (match_counter != 2'h3) begin
match_counter <= match_counter + 1'b1;
end
end else begin
if (match_counter != 2'h0) begin
match_counter <= match_counter - 1'b1;
end
end
end
end
endmodule
@@ -0,0 +1,118 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2017, 2018, 2020, 2022 Analog Devices, Inc. All rights reserved.
// SPDX short identifier: ADIJESD204
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module jesd204_soft_pcs_rx #(
parameter NUM_LANES = 1,
parameter DATA_PATH_WIDTH = 4,
parameter REGISTER_INPUTS = 0,
parameter INVERT_INPUTS = 0
) (
input clk,
input reset,
input patternalign_en,
input [NUM_LANES*DATA_PATH_WIDTH*10-1:0] data,
output reg [NUM_LANES*DATA_PATH_WIDTH*8-1:0] char,
output reg [NUM_LANES*DATA_PATH_WIDTH-1:0] charisk,
output reg [NUM_LANES*DATA_PATH_WIDTH-1:0] notintable,
output reg [NUM_LANES*DATA_PATH_WIDTH-1:0] disperr
);
localparam LANE_DATA_WIDTH = DATA_PATH_WIDTH * 10;
wire [NUM_LANES*LANE_DATA_WIDTH-1:0] data_aligned;
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] char_s;
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] charisk_s;
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] notintable_s;
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] disperr_s;
reg [NUM_LANES-1:0] disparity = {NUM_LANES{1'b0}};
wire [DATA_PATH_WIDTH:0] disparity_chain[0:NUM_LANES-1];
wire [NUM_LANES*DATA_PATH_WIDTH*10-1:0] data_s;
wire patternalign_en_s;
always @(posedge clk) begin
char <= char_s;
charisk <= charisk_s;
notintable <= notintable_s;
disperr <= disperr_s;
end
generate
genvar lane;
genvar i;
if (REGISTER_INPUTS > 0) begin
reg patternalign_en_r;
reg [NUM_LANES*DATA_PATH_WIDTH*10-1:0] data_r;
always @(posedge clk) begin
patternalign_en_r <= patternalign_en;
data_r <= data;
end
assign patternalign_en_s = patternalign_en_r;
assign data_s = data_r;
end else begin
assign patternalign_en_s = patternalign_en;
assign data_s = data;
end
for (lane = 0; lane < NUM_LANES; lane = lane + 1) begin: gen_lane
jesd204_pattern_align #(
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
) i_pattern_align (
.clk(clk),
.reset(reset),
.patternalign_en(patternalign_en_s),
.in_data(data_s[LANE_DATA_WIDTH*lane+:LANE_DATA_WIDTH]),
.out_data(data_aligned[LANE_DATA_WIDTH*lane+:LANE_DATA_WIDTH]));
assign disparity_chain[lane][0] = disparity[lane];
always @(posedge clk) begin
if (reset == 1'b1) begin
disparity[lane] <= 1'b0;
end else begin
disparity[lane] <= disparity_chain[lane][DATA_PATH_WIDTH];
end
end
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: gen_dpw
localparam j = DATA_PATH_WIDTH * lane + i;
wire [9:0] in_char;
if (REGISTER_INPUTS > 1) begin
reg [9:0] in_char_r = 10'b0;
always @(posedge clk) begin
in_char_r <= INVERT_INPUTS ? ~data_aligned[j*10+:10] :
data_aligned[j*10+:10];
end
assign in_char = in_char_r;
end else begin
assign in_char = INVERT_INPUTS ? ~data_aligned[j*10+:10] :
data_aligned[j*10+:10];
end
jesd204_8b10b_decoder i_dec (
.in_char(in_char),
.out_char(char_s[j*8+:8]),
.out_charisk(charisk_s[j]),
.out_notintable(notintable_s[j]),
.out_disperr(disperr_s[j]),
.in_disparity(disparity_chain[lane][i]),
.out_disparity(disparity_chain[lane][i+1]));
end
end
endgenerate
endmodule
@@ -0,0 +1,53 @@
###############################################################################
## Copyright (C) 2017-2019, 2021, 2022 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIJESD204
###############################################################################
package require qsys 14.0
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
ad_ip_create jesd204_soft_pcs_rx "ADI JESD204 Transmit Soft PCS"
ad_ip_parameter REGISTER_INPUTS INTEGER 0
ad_ip_parameter INVERT_INPUTS INTEGER 0
set_module_property INTERNAL true
# files
ad_ip_files jesd204_soft_pcs_rx [list \
jesd204_soft_pcs_rx.v \
jesd204_pattern_align.v \
jesd204_8b10b_decoder.v \
]
# clock
add_interface clock clock end
add_interface_port clock clk clk Input 1
# reset
add_interface reset reset end
set_interface_property reset associatedClock clock
set_interface_property reset synchronousEdges DEASSERT
add_interface_port reset reset reset Input 1
# interfaces
add_interface rx_phy conduit start
#set_interface_property rx_phy associatedClock clock
#set_interface_property rx_phy associatedReset reset
add_interface_port rx_phy char char Output 32
add_interface_port rx_phy charisk charisk Output 4
add_interface_port rx_phy disperr disperr Output 4
add_interface_port rx_phy notintable notintable Output 4
add_interface_port rx_phy patternalign_en patternalign_en Input 1
add_interface rx_raw_data conduit end
#set_interface_property rx_raw_data associatedClock clock
#set_interface_property rx_raw_data associatedReset reset
add_interface_port rx_raw_data data raw_data Input 40