diff --git a/library/axi_hsci/Makefile b/library/axi_hsci/Makefile new file mode 100755 index 0000000000..e323666109 --- /dev/null +++ b/library/axi_hsci/Makefile @@ -0,0 +1,28 @@ +#################################################################################### +## Copyright (c) 2018 - 2025 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_hsci + +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += axi4_lite.sv +GENERIC_DEPS += axi_hsci.sv +GENERIC_DEPS += hsci_master_axi_slave.sv +GENERIC_DEPS += hsci_master_logic.sv +GENERIC_DEPS += hsci_master_regs_defs.vh +GENERIC_DEPS += hsci_master_regs_regs.sv +GENERIC_DEPS += hsci_master_top.sv +GENERIC_DEPS += hsci_mcore.v +GENERIC_DEPS += hsci_mdec.sv +GENERIC_DEPS += hsci_menc.sv +GENERIC_DEPS += hsci_mfrm_det.v +GENERIC_DEPS += hsci_mlink_ctrl.sv +GENERIC_DEPS += lfsr15_8.v +GENERIC_DEPS += pulse_sync.v + +XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc +XILINX_DEPS += axi_hsci_ip.tcl + +include ../scripts/library.mk diff --git a/library/axi_hsci/axi4_lite.sv b/library/axi_hsci/axi4_lite.sv new file mode 100644 index 0000000000..f481c4e5d4 --- /dev/null +++ b/library/axi_hsci/axi4_lite.sv @@ -0,0 +1,83 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ns +interface axi4_lite #( + DATA_WIDTH = 32, + ADDR_WIDTH = 32 +); + + localparam WSTRB_WIDTH = DATA_WIDTH/8; + + // Write address channel + logic awvalid; + logic awready; + logic [2:0] awprot; + logic [ADDR_WIDTH-1:0] awaddr; + + // Write data channel + logic wvalid; + logic wready; + logic [WSTRB_WIDTH-1:0] wstrb; + logic [DATA_WIDTH-1:0] wdata; + + // Write response channel + logic bvalid; + logic bready; + logic [1:0] bresp; + + // Read address channel + logic arvalid; + logic arready; + logic [2:0] arprot; + logic [ADDR_WIDTH-1:0] araddr; + + // Read response channel + logic rvalid; + logic rready; + logic [1:0] rresp; + logic [DATA_WIDTH-1:0] rdata; + + modport master ( + output awvalid, awprot, awaddr, wvalid, wstrb, wdata, bready, arvalid, arprot, araddr, rready, + input awready, wready, bvalid, bresp, arready, rvalid, rresp, rdata + ); + + modport slave ( + output awready, wready, bvalid, bresp, arready, rvalid, rresp, rdata, + input awvalid, awprot, awaddr, wvalid, wstrb, wdata, bready, arvalid, arprot, araddr, rready + ); + +endinterface diff --git a/library/axi_hsci/axi_hsci.sv b/library/axi_hsci/axi_hsci.sv new file mode 100644 index 0000000000..cda5b01bcb --- /dev/null +++ b/library/axi_hsci/axi_hsci.sv @@ -0,0 +1,128 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps +import hsci_master_regs_pkg::*; + +module axi_hsci #( + parameter AXI_ADDR_WIDTH = 15, + parameter AXI_DATA_WIDTH = 32, + parameter REGMAP_ADDR_WIDTH = 16, + parameter S_AXI_ADDR_WIDTH = 18 +) ( + input wire s_axi_aclk, + input wire s_axi_aresetn, + + input wire [S_AXI_ADDR_WIDTH-1:0] s_axi_awaddr, + input wire [2:0] s_axi_awprot, + input wire s_axi_awvalid, + input wire s_axi_bready, + input wire [AXI_DATA_WIDTH-1:0] s_axi_wdata, + input wire s_axi_wvalid, + input wire s_axi_rready, + input wire [(AXI_DATA_WIDTH/8)-1 : 0] s_axi_wstrb, + input wire [S_AXI_ADDR_WIDTH-1:0] s_axi_araddr, + input wire [2:0] s_axi_arprot, + input wire s_axi_arvalid, + + output wire s_axi_wready, + output wire s_axi_arready, + output wire [1:0] s_axi_rresp, + output wire [AXI_DATA_WIDTH-1:0] s_axi_rdata, + output wire s_axi_rvalid, + output wire s_axi_awready, + output wire [1:0] s_axi_bresp, + output wire s_axi_bvalid, + + input wire hsci_pclk, + output [7:0] hsci_menc_clk, + output [7:0] hsci_mosi_data, + input wire [7:0] hsci_miso_data, + + output wire hsci_pll_reset, + input wire hsci_rst_seq_done, + input wire hsci_pll_locked, + input wire hsci_vtc_rdy_bsc_tx, + input wire hsci_dly_rdy_bsc_tx, + input wire hsci_vtc_rdy_bsc_rx, + input wire hsci_dly_rdy_bsc_rx + +); + + axi4_lite #(32,18) axi(); + + assign axi.awaddr = s_axi_awaddr; + assign axi.awprot = s_axi_awprot; + assign axi.awvalid = s_axi_awvalid; + assign axi.bready = s_axi_bready; + assign axi.wdata = s_axi_wdata; + assign axi.wvalid = s_axi_wvalid; + assign axi.rready = s_axi_rready; + assign axi.wstrb = s_axi_wstrb; + assign axi.araddr = s_axi_araddr; + assign axi.arprot = s_axi_arprot; + assign axi.arvalid = s_axi_arvalid; + + assign s_axi_wready = axi.wready; + assign s_axi_arready = axi.arready; + assign s_axi_rresp = axi.rresp; + assign s_axi_rdata = axi.rdata; + assign s_axi_rvalid = axi.rvalid ; + assign s_axi_awready = axi.awready; + assign s_axi_bresp = axi.bresp; + assign s_axi_bvalid = axi.bvalid; + + hsci_master_top #( + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .REGMAP_ADDR_WIDTH (REGMAP_ADDR_WIDTH), + .S_AXI_ADDR_WIDTH (S_AXI_ADDR_WIDTH) + ) hsci_master_top ( + .axi_clk (s_axi_aclk), + .axi_resetn (s_axi_aresetn), + .axi (axi), + .hsci_pclk (hsci_pclk), + .hsci_menc_clk (hsci_menc_clk), + .hsci_mosi_data (hsci_mosi_data), + .hsci_miso_data (hsci_miso_data), + .hsci_pll_reset (hsci_pll_reset), + .hsci_rst_seq_done (hsci_rst_seq_done), + .hsci_pll_locked (hsci_pll_locked), + .hsci_vtc_rdy_bsc_tx (hsci_vtc_rdy_bsc_tx), + .hsci_dly_rdy_bsc_tx (hsci_dly_rdy_bsc_tx), + .hsci_vtc_rdy_bsc_rx (hsci_vtc_rdy_bsc_rx), + .hsci_dly_rdy_bsc_rx (hsci_dly_rdy_bsc_rx)); + +endmodule diff --git a/library/axi_hsci/axi_hsci_constr.ttcl b/library/axi_hsci/axi_hsci_constr.ttcl new file mode 100644 index 0000000000..6ce40261d1 --- /dev/null +++ b/library/axi_hsci/axi_hsci_constr.ttcl @@ -0,0 +1,20 @@ +############################################################################### +## Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +<: set ComponentName [getComponentNameString] :> +<: setOutputDirectory "./" :> +<: setFileName [ttcl_add $ComponentName "_constr"] :> +<: setFileExtension ".xdc" :> +<: setFileProcessingOrder late :> + +set_false_path \ + -from [get_cells -hierarchical * -filter {NAME=~*hsci_master_top/hsci_master_logic/hsci_master_regs_regs/O_reg[hsci_bram_start_address][data][*]/C}] \ + -to [get_cells -hierarchical * -filter {NAME=~*hsci_master_top/hsci_mcore/enc0/enc_addr_reg[*]/D}] + +set_false_path \ + -from [get_cells -hierarchical * -filter {NAME=~*hsci_master_top/hsci_master_logic/hsci_master_regs_regs/O_reg[hsci_xfer_num][data][*]/C}] \ + -to [get_cells -hierarchical * -filter {NAME=~*hsci_master_top/hsci_mcore/enc0/m_xfer_num_reg[*]/D}] + +set_false_path -from [get_cells -filter IS_SEQUENTIAL -hierarchical -regexp ".*O_reg.*"] -to [get_clocks -of_objects [get_ports {hsci_pclk}]] diff --git a/library/axi_hsci/axi_hsci_ip.tcl b/library/axi_hsci/axi_hsci_ip.tcl new file mode 100755 index 0000000000..b06dbad304 --- /dev/null +++ b/library/axi_hsci/axi_hsci_ip.tcl @@ -0,0 +1,57 @@ +############################################################################### +## Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +# ip + +source ../../scripts/adi_env.tcl +source ../scripts/adi_ip_xilinx.tcl + +adi_ip_create axi_hsci +adi_ip_files axi_hsci [list \ + "../common/ad_rst.v" \ + "../xilinx/common/ad_rst_constr.xdc" \ + "axi_hsci.sv" \ + "hsci_master_axi_slave.sv" \ + "hsci_master_logic.sv" \ + "hsci_master_regs_defs.vh" \ + "hsci_master_regs_regs.sv" \ + "hsci_master_top.sv" \ + "hsci_mcore.v" \ + "hsci_mdec.sv" \ + "hsci_menc.sv" \ + "hsci_mfrm_det.v" \ + "hsci_mlink_ctrl.sv" \ + "lfsr15_8.v" \ + "pulse_sync.v" \ + "axi4_lite.sv" ] + +adi_ip_properties axi_hsci +adi_ip_ttcl axi_hsci "axi_hsci_constr.ttcl" +set_property display_name "ADI AXI HSCI" [ipx::current_core] +set_property description "ADI AXI HSCI" [ipx::current_core] +# set_property company_url {https://wiki.analog.com/resources/fpga/docs/axi_hsci} [ipx::current_core] + +adi_init_bd_tcl + +proc add_reset {name polarity} { + set reset_intf [ipx::infer_bus_interface $name xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]] + set reset_polarity [ipx::add_bus_parameter "POLARITY" $reset_intf] + set_property value $polarity $reset_polarity +} + +ipx::infer_bus_interface hsci_pclk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +# ipx::infer_bus_interface hsci_data_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface s_axi_aclk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +# ipx::infer_bus_interface delay_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] + +add_reset s_axi_aresetn ACTIVE_LOW + +ipx::add_bus_parameter ASSOCIATED_BUSIF [ipx::get_bus_interfaces s_axi_aclk -of_objects [ipx::current_core]] +set_property value s_axi [ipx::get_bus_parameters ASSOCIATED_BUSIF -of_objects [ipx::get_bus_interfaces s_axi_aclk -of_objects [ipx::current_core]]] + +adi_add_auto_fpga_spec_params +ipx::create_xgui_files [ipx::current_core] + +ipx::save_core [ipx::current_core] diff --git a/library/axi_hsci/hsci_master_axi_slave.sv b/library/axi_hsci/hsci_master_axi_slave.sv new file mode 100755 index 0000000000..75966ad762 --- /dev/null +++ b/library/axi_hsci/hsci_master_axi_slave.sv @@ -0,0 +1,130 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps / 1ps + +module hsci_master_axi_slave #( + parameter integer REGMAP_ADDR_WIDTH = 10 +) ( + input wire axi_clk, + input wire axi_resetn, + + axi4_lite.slave axi, + + output wire [REGMAP_ADDR_WIDTH-1:0] regmap_raddr, + output wire regmap_rd_en, + output wire [REGMAP_ADDR_WIDTH-1:0] regmap_waddr, + output wire [31:0] regmap_wdata, + output wire regmap_wr_en, + input wire [31:0] regmap_rdata, + + output wire [REGMAP_ADDR_WIDTH-1:0] bram_addr, + output wire [31:0] bram_wdata, + input [31:0] bram_rdata, + output wire bram_we +); + + localparam AXI_STATE_WIDTH = 3; + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_IDLE = 0; + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_WRD = 1; + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_WRR = 2; + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_RDD = 3; // gives us 2 cyc latency to latch the data + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_DELAY_RDR = 4; // gives us another 1 cycle latency + localparam [AXI_STATE_WIDTH-1:0] AXI_STATE_RDR = 5; + localparam [17:0] BRAM_END = 'h8000; + + reg [AXI_STATE_WIDTH-1:0] axi_last, axi_curr, axi_next; + + reg [REGMAP_ADDR_WIDTH-1:0] regaddr; + reg [31:0] regdata; + reg en_bram; + reg en_regmap; + + wire axi_rdd = (axi_curr == AXI_STATE_RDD); + assign axi.awready = (axi_curr == AXI_STATE_IDLE); + assign axi.arready = (axi_curr == AXI_STATE_IDLE); + assign axi.wready = (axi_curr == AXI_STATE_WRD); + assign axi.bvalid = (axi_curr == AXI_STATE_WRR); + assign axi.rvalid = (axi_curr == AXI_STATE_RDR); + assign axi.bresp = 2'b00; + assign axi.rresp = 2'b00; + + assign axi.rdata = (en_bram) ? bram_rdata:regdata; + + assign regmap_waddr = regaddr; + assign regmap_wdata = regdata; + assign regmap_wr_en = en_regmap & (axi_last == AXI_STATE_WRD) & (axi_curr == AXI_STATE_WRR); + assign regmap_raddr = regaddr; + assign regmap_rd_en = en_regmap & (axi_last == AXI_STATE_IDLE) & (axi_curr == AXI_STATE_RDD); + + assign bram_addr = regaddr - 16'b1; // to map BRAM start at address 'h0000 + assign bram_wdata = regdata; + + assign bram_we = en_bram & (axi_last == AXI_STATE_WRD) & (axi_curr == AXI_STATE_WRR) ; + + always @(posedge axi_clk) axi_last <= axi_curr; + always @(posedge axi_clk) axi_curr <= ~axi_resetn ? AXI_STATE_IDLE : axi_next; + always @* begin + axi_next = AXI_STATE_IDLE; + case(axi_curr) + AXI_STATE_IDLE : axi_next = (axi.awvalid & axi.awready) + ? AXI_STATE_WRD + : (axi.arvalid & axi.arready) ? AXI_STATE_RDD : AXI_STATE_IDLE; + AXI_STATE_WRD : axi_next = axi.wvalid ? AXI_STATE_WRR : AXI_STATE_WRD; + AXI_STATE_WRR : axi_next = axi.bready ? AXI_STATE_IDLE : AXI_STATE_WRR; + AXI_STATE_RDD : axi_next = AXI_STATE_DELAY_RDR; + AXI_STATE_DELAY_RDR : axi_next = AXI_STATE_RDR; + AXI_STATE_RDR : axi_next = axi.rready ? AXI_STATE_IDLE : AXI_STATE_RDR; + endcase + end + + always @(posedge axi_clk) + regaddr <= ~axi_resetn ? {REGMAP_ADDR_WIDTH{1'b0}}: (axi.awvalid & axi.awready) ? axi.awaddr[2+:REGMAP_ADDR_WIDTH] + : (axi.arvalid & axi.arready) ? axi.araddr[2+:REGMAP_ADDR_WIDTH] : regaddr; + + always @(posedge axi_clk) regdata <= (axi.wvalid & axi.wready) ? axi.wdata : (axi_rdd ? regmap_rdata : regdata); + + // Decode Logic + always @(posedge axi_clk) begin + if((regaddr == 'h00000) | (regaddr > BRAM_END)) begin + en_bram <= 0; + en_regmap <= 1; + end else begin + en_bram <= 1; + en_regmap <= 0; + end + end + +endmodule diff --git a/library/axi_hsci/hsci_master_logic.sv b/library/axi_hsci/hsci_master_logic.sv new file mode 100644 index 0000000000..810d90a3bf --- /dev/null +++ b/library/axi_hsci/hsci_master_logic.sv @@ -0,0 +1,87 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps / 1ps + +module hsci_master_logic #( + parameter ADDR_WIDTH = 10, + parameter DATA_WIDTH = 32 +)( + input clk, + input srstn, + input [ADDR_WIDTH-1:0] I_rd_addr, + input I_wr_stb, + input [ADDR_WIDTH-1:0] I_wr_addr, + input [DATA_WIDTH-1:0] I_wr_data, + output reg [DATA_WIDTH-1:0] O_read_data, + input hsci_master_regs_pkg::hsci_master_regs_status_t I, + output hsci_master_regs_pkg::hsci_master_regs_regs_t O +); + + import hsci_master_regs_pkg::*; + + localparam NUM_GT_LANE = 16; + + hsci_master_regs_pkg::hsci_master_regs_status_t I_int; + hsci_master_regs_pkg::hsci_master_regs_regs_t O_int; + + + // By default I and O members are passed unmodified to the register map + // Overrides to the default behaviour are below. + always_comb begin + I_int = I; + + // Self-clearing spi_master_run + I_int.hsci_run.sclr = O.hsci_run.data; + end + + always_comb begin + O = O_int; + end + + // Yoda register map + hsci_master_regs_regs hsci_master_regs_regs( + .clk (clk), + .srstn (srstn), + .I_rd_addr (I_rd_addr), + .I_wr_stb (I_wr_stb), + .I_wr_addr (I_wr_addr), + .I_wr_data (I_wr_data), + .O_read_data (O_read_data), + .I (I_int), + .O (O_int) + ); + +endmodule diff --git a/library/axi_hsci/hsci_master_regs_defs.vh b/library/axi_hsci/hsci_master_regs_defs.vh new file mode 100644 index 0000000000..7320afaf31 --- /dev/null +++ b/library/axi_hsci/hsci_master_regs_defs.vh @@ -0,0 +1,1085 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +/// SPDX short identifier: ADIBSD +/////////////////////////////////////////////////////////////////////////////// + +`ifndef _DEFINE_SV_HSCI_MASTER_REGS +`define _DEFINE_SV_HSCI_MASTER_REGS + +// +// ---- Constant Definitions ---- +// +// Module RegisterMap Constants +// PROP_XXXX_AWIDTH Module RegisterMap AddressWidth +// +// Register Constants +// RG_XXXX_ADDR Address of the register +// RG_XXXX_RESET Reset value for the register +// +// BitField defines +// BF_XXXX_RESET Reset value for the bitfield +// BF_XXXX_WIDTH Width of the bitfield +// +// BitField register reference defines +// BF_XXXX_LSB LSB of the bitfield slice +// BF_XXXX_MSB MSB of the bitfield slice +// BF_XXXX_ROFFSET Offset of the slice in the register +// BF_XXXX_RMSB MSB of the slice in the register +// BF_XXXX_RMASK Mask of the slice in the register +// BF_XXXX_RWIDTH Width of the slice +// BF_XXXX_RESET Reset value of the slice +// + +package hsci_master_regs_pkg; + + + // ========== Module RegisterMap constants ========== + parameter PROP_HSCI_MASTER_REGS_AWIDTH = 'd16; // Module Address Width property decimal value. + + // ========== Register constants ========== + parameter RG_REVISION_ID_ADDR = 16'h0000; // Revision ID for SPI Master + parameter RG_REVISION_ID_RESET = 32'h00000001; + parameter RG_HSCI_MASTER_MODE_ADDR = 16'h8001; // HSCI Master Mode Selection + parameter RG_HSCI_MASTER_MODE_RESET = 32'h00000010; + parameter RG_HSCI_MASTER_XFER_NUM_ADDR = 16'h8002; // HSCI Master Number of Transactions + parameter RG_HSCI_MASTER_XFER_NUM_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_ADDR_SIZE_ADDR = 16'h8003; // HSCI Master Address Size + parameter RG_HSCI_MASTER_ADDR_SIZE_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_BYTE_NUM_ADDR = 16'h8004; // HSCI Master Data Size + parameter RG_HSCI_MASTER_BYTE_NUM_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_TARGET_ADDR = 16'h8005; // HSCI Master Target Chip Select + parameter RG_HSCI_MASTER_TARGET_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_CTRL_ADDR = 16'h8006; // HSCI Master CTRL + parameter RG_HSCI_MASTER_CTRL_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_BRAM_ADDRESS_ADDR = 16'h8007; // BRAM Sequence Start Addr + parameter RG_HSCI_MASTER_BRAM_ADDRESS_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_RUN_ADDR = 16'h8008; // HSCI Master RUN Trigger + parameter RG_HSCI_MASTER_RUN_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_STATUS_ADDR = 16'h8009; // HSCI Master Status + parameter RG_HSCI_MASTER_STATUS_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_LINKUP_CTRL_ADDR = 16'h800A; // HSCI Master Linkup CTRL + parameter RG_HSCI_MASTER_LINKUP_CTRL_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_TEST_CTRL_ADDR = 16'h800B; // HSCI Master Test CTRL + parameter RG_HSCI_MASTER_TEST_CTRL_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_LINKUP_STATUS_ADDR = 16'h800C; // HSCI Master Linkup Status + parameter RG_HSCI_MASTER_LINKUP_STATUS_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_LINKUP_STATUS2_ADDR = 16'h800D; // HSCI Master Linkup Status 2 + parameter RG_HSCI_MASTER_LINKUP_STATUS2_RESET = 32'h00000000; + parameter RG_HSCI_DEBUG_STATUS_ADDR = 16'h800E; // HSCI Master FSM Status + parameter RG_HSCI_DEBUG_STATUS_RESET = 32'h00000000; + parameter RG_MISO_TEST_BER_ADDR = 16'h800F; // MISO Test BER + parameter RG_MISO_TEST_BER_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_LINK_ERR_INFO_ADDR = 16'h8010; // HSCI Master Link Error Info + parameter RG_HSCI_MASTER_LINK_ERR_INFO_RESET = 32'h00000000; + parameter RG_HSCI_RATE_CTRL_ADDR = 16'h8011; // HSCI Rate Control + parameter RG_HSCI_RATE_CTRL_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_RST_ADDR = 16'h8012; // HSCI Master Reset Controls + parameter RG_HSCI_MASTER_RST_RESET = 32'h00000000; + parameter RG_HSCI_PHY_STATUS_ADDR = 16'h8013; // HSCI PHY STATUS + parameter RG_HSCI_PHY_STATUS_RESET = 32'h00000000; + parameter RG_HSCI_MASTER_SCRATCH_ADDR = 16'h801F; // Scratch Register + parameter RG_HSCI_MASTER_SCRATCH_RESET = 32'h00000000; + + // ========== BitFields ========== + + // BitField: hsci_revision_id (r) + // bitfield defines + parameter BF_HSCI_REVISION_ID_RESET = 16'h1; + parameter BF_HSCI_REVISION_ID_WIDTH = 32'd16; + // register reference defines + parameter BF_HSCI_REVISION_ID_LSB = 32'd0; + parameter BF_HSCI_REVISION_ID_MSB = 32'd15; + parameter BF_HSCI_REVISION_ID_ROFFSET = 32'd0; + parameter BF_HSCI_REVISION_ID_RMSB = 32'd15; + parameter BF_HSCI_REVISION_ID_RMASK = 16'hffff; + parameter BF_HSCI_REVISION_ID_RWIDTH = 32'd16; + typedef logic [15:0] hsci_revision_id_data_t; + // bitfield structures + typedef struct packed { + hsci_revision_id_data_t data; + } hsci_revision_id_reg_t; + + // BitField: hsci_xfer_mode (r/w) + // bitfield defines + parameter BF_HSCI_XFER_MODE_RESET = 2'h0; + parameter BF_HSCI_XFER_MODE_WIDTH = 32'd2; + // register reference defines + parameter BF_HSCI_XFER_MODE_LSB = 32'd0; + parameter BF_HSCI_XFER_MODE_MSB = 32'd1; + parameter BF_HSCI_XFER_MODE_ROFFSET = 32'd0; + parameter BF_HSCI_XFER_MODE_RMSB = 32'd1; + parameter BF_HSCI_XFER_MODE_RMASK = 2'h3; + parameter BF_HSCI_XFER_MODE_RWIDTH = 32'd2; + typedef logic [1:0] hsci_xfer_mode_data_t; + // bitfield structures + typedef struct packed { + hsci_xfer_mode_data_t data; + } hsci_xfer_mode_reg_t; + + // BitField: ver_b__na (r/w) + // bitfield defines + parameter BF_VER_B__NA_RESET = 1'h1; + parameter BF_VER_B__NA_WIDTH = 32'd1; + // register reference defines + parameter BF_VER_B__NA_LSB = 32'd0; + parameter BF_VER_B__NA_MSB = 32'd0; + parameter BF_VER_B__NA_ROFFSET = 32'd4; + parameter BF_VER_B__NA_RMSB = 32'd4; + parameter BF_VER_B__NA_RMASK = 5'h10; + parameter BF_VER_B__NA_RWIDTH = 32'd1; + typedef logic ver_b__na_data_t; + // bitfield structures + typedef struct packed { + ver_b__na_data_t data; + } ver_b__na_reg_t; + + // BitField: hsci_xfer_num (r/w) + // bitfield defines + parameter BF_HSCI_XFER_NUM_RESET = 16'h0; + parameter BF_HSCI_XFER_NUM_WIDTH = 32'd16; + // register reference defines + parameter BF_HSCI_XFER_NUM_LSB = 32'd0; + parameter BF_HSCI_XFER_NUM_MSB = 32'd15; + parameter BF_HSCI_XFER_NUM_ROFFSET = 32'd0; + parameter BF_HSCI_XFER_NUM_RMSB = 32'd15; + parameter BF_HSCI_XFER_NUM_RMASK = 16'hffff; + parameter BF_HSCI_XFER_NUM_RWIDTH = 32'd16; + typedef logic [15:0] hsci_xfer_num_data_t; + // bitfield structures + typedef struct packed { + hsci_xfer_num_data_t data; + } hsci_xfer_num_reg_t; + + // BitField: hsci_addr_size (r/w) + // bitfield defines + parameter BF_HSCI_ADDR_SIZE_RESET = 3'h0; + parameter BF_HSCI_ADDR_SIZE_WIDTH = 32'd3; + // register reference defines + parameter BF_HSCI_ADDR_SIZE_LSB = 32'd0; + parameter BF_HSCI_ADDR_SIZE_MSB = 32'd2; + parameter BF_HSCI_ADDR_SIZE_ROFFSET = 32'd0; + parameter BF_HSCI_ADDR_SIZE_RMSB = 32'd2; + parameter BF_HSCI_ADDR_SIZE_RMASK = 3'h7; + parameter BF_HSCI_ADDR_SIZE_RWIDTH = 32'd3; + typedef logic [2:0] hsci_addr_size_data_t; + // bitfield structures + typedef struct packed { + hsci_addr_size_data_t data; + } hsci_addr_size_reg_t; + + // BitField: hsci_byte_num (r/w) + // bitfield defines + parameter BF_HSCI_BYTE_NUM_RESET = 17'h0; + parameter BF_HSCI_BYTE_NUM_WIDTH = 32'd17; + // register reference defines + parameter BF_HSCI_BYTE_NUM_LSB = 32'd0; + parameter BF_HSCI_BYTE_NUM_MSB = 32'd16; + parameter BF_HSCI_BYTE_NUM_ROFFSET = 32'd0; + parameter BF_HSCI_BYTE_NUM_RMSB = 32'd16; + parameter BF_HSCI_BYTE_NUM_RMASK = 17'h1ffff; + parameter BF_HSCI_BYTE_NUM_RWIDTH = 32'd17; + typedef logic [16:0] hsci_byte_num_data_t; + // bitfield structures + typedef struct packed { + hsci_byte_num_data_t data; + } hsci_byte_num_reg_t; + + // BitField: spi_target (r/w) + // bitfield defines + parameter BF_SPI_TARGET_RESET = 32'h0; + parameter BF_SPI_TARGET_WIDTH = 32'd32; + // register reference defines + parameter BF_SPI_TARGET_LSB = 32'd0; + parameter BF_SPI_TARGET_MSB = 32'd31; + parameter BF_SPI_TARGET_ROFFSET = 32'd0; + parameter BF_SPI_TARGET_RMSB = 32'd31; + parameter BF_SPI_TARGET_RMASK = 32'hffffffff; + parameter BF_SPI_TARGET_RWIDTH = 32'd32; + typedef logic [31:0] spi_target_data_t; + // bitfield structures + typedef struct packed { + spi_target_data_t data; + } spi_target_reg_t; + + // BitField: hsci_cmd_sel (r/w) + // bitfield defines + parameter BF_HSCI_CMD_SEL_RESET = 2'h0; + parameter BF_HSCI_CMD_SEL_WIDTH = 32'd2; + // register reference defines + parameter BF_HSCI_CMD_SEL_LSB = 32'd0; + parameter BF_HSCI_CMD_SEL_MSB = 32'd1; + parameter BF_HSCI_CMD_SEL_ROFFSET = 32'd0; + parameter BF_HSCI_CMD_SEL_RMSB = 32'd1; + parameter BF_HSCI_CMD_SEL_RMASK = 2'h3; + parameter BF_HSCI_CMD_SEL_RWIDTH = 32'd2; + typedef logic [1:0] hsci_cmd_sel_data_t; + // bitfield structures + typedef struct packed { + hsci_cmd_sel_data_t data; + } hsci_cmd_sel_reg_t; + + // BitField: hsci_slave_ahb_tsize (r/w) + // bitfield defines + parameter BF_HSCI_SLAVE_AHB_TSIZE_RESET = 2'h0; + parameter BF_HSCI_SLAVE_AHB_TSIZE_WIDTH = 32'd2; + // register reference defines + parameter BF_HSCI_SLAVE_AHB_TSIZE_LSB = 32'd0; + parameter BF_HSCI_SLAVE_AHB_TSIZE_MSB = 32'd1; + parameter BF_HSCI_SLAVE_AHB_TSIZE_ROFFSET = 32'd4; + parameter BF_HSCI_SLAVE_AHB_TSIZE_RMSB = 32'd5; + parameter BF_HSCI_SLAVE_AHB_TSIZE_RMASK = 6'h30; + parameter BF_HSCI_SLAVE_AHB_TSIZE_RWIDTH = 32'd2; + typedef logic [1:0] hsci_slave_ahb_tsize_data_t; + // bitfield structures + typedef struct packed { + hsci_slave_ahb_tsize_data_t data; + } hsci_slave_ahb_tsize_reg_t; + + // BitField: hsci_bram_start_address (r/w) + // bitfield defines + parameter BF_HSCI_BRAM_START_ADDRESS_RESET = 16'h0; + parameter BF_HSCI_BRAM_START_ADDRESS_WIDTH = 32'd16; + // register reference defines + parameter BF_HSCI_BRAM_START_ADDRESS_LSB = 32'd0; + parameter BF_HSCI_BRAM_START_ADDRESS_MSB = 32'd15; + parameter BF_HSCI_BRAM_START_ADDRESS_ROFFSET = 32'd0; + parameter BF_HSCI_BRAM_START_ADDRESS_RMSB = 32'd15; + parameter BF_HSCI_BRAM_START_ADDRESS_RMASK = 16'hffff; + parameter BF_HSCI_BRAM_START_ADDRESS_RWIDTH = 32'd16; + typedef logic [15:0] hsci_bram_start_address_data_t; + // bitfield structures + typedef struct packed { + hsci_bram_start_address_data_t data; + } hsci_bram_start_address_reg_t; + + // BitField: hsci_run (r/w) + // bitfield defines + parameter BF_HSCI_RUN_RESET = 1'h0; + parameter BF_HSCI_RUN_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_RUN_LSB = 32'd0; + parameter BF_HSCI_RUN_MSB = 32'd0; + parameter BF_HSCI_RUN_ROFFSET = 32'd0; + parameter BF_HSCI_RUN_RMSB = 32'd0; + parameter BF_HSCI_RUN_RMASK = 1'h1; + parameter BF_HSCI_RUN_RWIDTH = 32'd1; + typedef logic hsci_run_data_t; + // bitfield structures + typedef struct packed { + hsci_run_data_t data; + } hsci_run_reg_t; + + typedef struct packed { + logic sclr; + } hsci_run_status_t; + + // BitField: master_done (r) Volatile + // bitfield defines + parameter BF_MASTER_DONE_RESET = 1'h0; + parameter BF_MASTER_DONE_WIDTH = 32'd1; + // register reference defines + parameter BF_MASTER_DONE_LSB = 32'd0; + parameter BF_MASTER_DONE_MSB = 32'd0; + parameter BF_MASTER_DONE_ROFFSET = 32'd0; + parameter BF_MASTER_DONE_RMSB = 32'd0; + parameter BF_MASTER_DONE_RMASK = 1'h1; + parameter BF_MASTER_DONE_RWIDTH = 32'd1; + typedef logic master_done_data_t; + + typedef struct packed { + master_done_data_t data; + } master_done_status_t; + + // BitField: master_running (r) Volatile + // bitfield defines + parameter BF_MASTER_RUNNING_RESET = 1'h0; + parameter BF_MASTER_RUNNING_WIDTH = 32'd1; + // register reference defines + parameter BF_MASTER_RUNNING_LSB = 32'd0; + parameter BF_MASTER_RUNNING_MSB = 32'd0; + parameter BF_MASTER_RUNNING_ROFFSET = 32'd1; + parameter BF_MASTER_RUNNING_RMSB = 32'd1; + parameter BF_MASTER_RUNNING_RMASK = 2'h2; + parameter BF_MASTER_RUNNING_RWIDTH = 32'd1; + typedef logic master_running_data_t; + + typedef struct packed { + master_running_data_t data; + } master_running_status_t; + + // BitField: master_wr_in_prog (r) Volatile + // bitfield defines + parameter BF_MASTER_WR_IN_PROG_RESET = 1'h0; + parameter BF_MASTER_WR_IN_PROG_WIDTH = 32'd1; + // register reference defines + parameter BF_MASTER_WR_IN_PROG_LSB = 32'd0; + parameter BF_MASTER_WR_IN_PROG_MSB = 32'd0; + parameter BF_MASTER_WR_IN_PROG_ROFFSET = 32'd2; + parameter BF_MASTER_WR_IN_PROG_RMSB = 32'd2; + parameter BF_MASTER_WR_IN_PROG_RMASK = 3'h4; + parameter BF_MASTER_WR_IN_PROG_RWIDTH = 32'd1; + typedef logic master_wr_in_prog_data_t; + + typedef struct packed { + master_wr_in_prog_data_t data; + } master_wr_in_prog_status_t; + + // BitField: master_rd_in_prog (r) Volatile + // bitfield defines + parameter BF_MASTER_RD_IN_PROG_RESET = 1'h0; + parameter BF_MASTER_RD_IN_PROG_WIDTH = 32'd1; + // register reference defines + parameter BF_MASTER_RD_IN_PROG_LSB = 32'd0; + parameter BF_MASTER_RD_IN_PROG_MSB = 32'd0; + parameter BF_MASTER_RD_IN_PROG_ROFFSET = 32'd3; + parameter BF_MASTER_RD_IN_PROG_RMSB = 32'd3; + parameter BF_MASTER_RD_IN_PROG_RMASK = 4'h8; + parameter BF_MASTER_RD_IN_PROG_RWIDTH = 32'd1; + typedef logic master_rd_in_prog_data_t; + + typedef struct packed { + master_rd_in_prog_data_t data; + } master_rd_in_prog_status_t; + + // BitField: miso_test_lfsr_acq (r) Volatile + // bitfield defines + parameter BF_MISO_TEST_LFSR_ACQ_RESET = 1'h0; + parameter BF_MISO_TEST_LFSR_ACQ_WIDTH = 32'd1; + // register reference defines + parameter BF_MISO_TEST_LFSR_ACQ_LSB = 32'd0; + parameter BF_MISO_TEST_LFSR_ACQ_MSB = 32'd0; + parameter BF_MISO_TEST_LFSR_ACQ_ROFFSET = 32'd4; + parameter BF_MISO_TEST_LFSR_ACQ_RMSB = 32'd4; + parameter BF_MISO_TEST_LFSR_ACQ_RMASK = 5'h10; + parameter BF_MISO_TEST_LFSR_ACQ_RWIDTH = 32'd1; + typedef logic miso_test_lfsr_acq_data_t; + + typedef struct packed { + miso_test_lfsr_acq_data_t data; + } miso_test_lfsr_acq_status_t; + + // BitField: hsci_man_linkup_word (r/w) + // bitfield defines + parameter BF_HSCI_MAN_LINKUP_WORD_RESET = 10'h0; + parameter BF_HSCI_MAN_LINKUP_WORD_WIDTH = 32'd10; + // register reference defines + parameter BF_HSCI_MAN_LINKUP_WORD_LSB = 32'd0; + parameter BF_HSCI_MAN_LINKUP_WORD_MSB = 32'd9; + parameter BF_HSCI_MAN_LINKUP_WORD_ROFFSET = 32'd0; + parameter BF_HSCI_MAN_LINKUP_WORD_RMSB = 32'd9; + parameter BF_HSCI_MAN_LINKUP_WORD_RMASK = 10'h3ff; + parameter BF_HSCI_MAN_LINKUP_WORD_RWIDTH = 32'd10; + typedef logic [9:0] hsci_man_linkup_word_data_t; + // bitfield structures + typedef struct packed { + hsci_man_linkup_word_data_t data; + } hsci_man_linkup_word_reg_t; + + // BitField: hsci_man_linkup (r/w) + // bitfield defines + parameter BF_HSCI_MAN_LINKUP_RESET = 1'h0; + parameter BF_HSCI_MAN_LINKUP_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MAN_LINKUP_LSB = 32'd0; + parameter BF_HSCI_MAN_LINKUP_MSB = 32'd0; + parameter BF_HSCI_MAN_LINKUP_ROFFSET = 32'd10; + parameter BF_HSCI_MAN_LINKUP_RMSB = 32'd10; + parameter BF_HSCI_MAN_LINKUP_RMASK = 11'h400; + parameter BF_HSCI_MAN_LINKUP_RWIDTH = 32'd1; + typedef logic hsci_man_linkup_data_t; + // bitfield structures + typedef struct packed { + hsci_man_linkup_data_t data; + } hsci_man_linkup_reg_t; + + // BitField: hsci_auto_linkup (r/w) + // bitfield defines + parameter BF_HSCI_AUTO_LINKUP_RESET = 1'h0; + parameter BF_HSCI_AUTO_LINKUP_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_AUTO_LINKUP_LSB = 32'd0; + parameter BF_HSCI_AUTO_LINKUP_MSB = 32'd0; + parameter BF_HSCI_AUTO_LINKUP_ROFFSET = 32'd11; + parameter BF_HSCI_AUTO_LINKUP_RMSB = 32'd11; + parameter BF_HSCI_AUTO_LINKUP_RMASK = 12'h800; + parameter BF_HSCI_AUTO_LINKUP_RWIDTH = 32'd1; + typedef logic hsci_auto_linkup_data_t; + // bitfield structures + typedef struct packed { + hsci_auto_linkup_data_t data; + } hsci_auto_linkup_reg_t; + + // BitField: mosi_clk_inv (r/w) + // bitfield defines + parameter BF_MOSI_CLK_INV_RESET = 1'h0; + parameter BF_MOSI_CLK_INV_WIDTH = 32'd1; + // register reference defines + parameter BF_MOSI_CLK_INV_LSB = 32'd0; + parameter BF_MOSI_CLK_INV_MSB = 32'd0; + parameter BF_MOSI_CLK_INV_ROFFSET = 32'd12; + parameter BF_MOSI_CLK_INV_RMSB = 32'd12; + parameter BF_MOSI_CLK_INV_RMASK = 13'h1000; + parameter BF_MOSI_CLK_INV_RWIDTH = 32'd1; + typedef logic mosi_clk_inv_data_t; + // bitfield structures + typedef struct packed { + mosi_clk_inv_data_t data; + } mosi_clk_inv_reg_t; + + // BitField: miso_clk_inv (r/w) + // bitfield defines + parameter BF_MISO_CLK_INV_RESET = 1'h0; + parameter BF_MISO_CLK_INV_WIDTH = 32'd1; + // register reference defines + parameter BF_MISO_CLK_INV_LSB = 32'd0; + parameter BF_MISO_CLK_INV_MSB = 32'd0; + parameter BF_MISO_CLK_INV_ROFFSET = 32'd13; + parameter BF_MISO_CLK_INV_RMSB = 32'd13; + parameter BF_MISO_CLK_INV_RMASK = 14'h2000; + parameter BF_MISO_CLK_INV_RWIDTH = 32'd1; + typedef logic miso_clk_inv_data_t; + // bitfield structures + typedef struct packed { + miso_clk_inv_data_t data; + } miso_clk_inv_reg_t; + + // BitField: hsci_mosi_test_mode (r/w) + // bitfield defines + parameter BF_HSCI_MOSI_TEST_MODE_RESET = 1'h0; + parameter BF_HSCI_MOSI_TEST_MODE_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MOSI_TEST_MODE_LSB = 32'd0; + parameter BF_HSCI_MOSI_TEST_MODE_MSB = 32'd0; + parameter BF_HSCI_MOSI_TEST_MODE_ROFFSET = 32'd0; + parameter BF_HSCI_MOSI_TEST_MODE_RMSB = 32'd0; + parameter BF_HSCI_MOSI_TEST_MODE_RMASK = 1'h1; + parameter BF_HSCI_MOSI_TEST_MODE_RWIDTH = 32'd1; + typedef logic hsci_mosi_test_mode_data_t; + // bitfield structures + typedef struct packed { + hsci_mosi_test_mode_data_t data; + } hsci_mosi_test_mode_reg_t; + + // BitField: hsci_miso_test_mode (r/w) + // bitfield defines + parameter BF_HSCI_MISO_TEST_MODE_RESET = 1'h0; + parameter BF_HSCI_MISO_TEST_MODE_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MISO_TEST_MODE_LSB = 32'd0; + parameter BF_HSCI_MISO_TEST_MODE_MSB = 32'd0; + parameter BF_HSCI_MISO_TEST_MODE_ROFFSET = 32'd1; + parameter BF_HSCI_MISO_TEST_MODE_RMSB = 32'd1; + parameter BF_HSCI_MISO_TEST_MODE_RMASK = 2'h2; + parameter BF_HSCI_MISO_TEST_MODE_RWIDTH = 32'd1; + typedef logic hsci_miso_test_mode_data_t; + // bitfield structures + typedef struct packed { + hsci_miso_test_mode_data_t data; + } hsci_miso_test_mode_reg_t; + + // BitField: hsci_capture_mode (r/w) + // bitfield defines + parameter BF_HSCI_CAPTURE_MODE_RESET = 1'h0; + parameter BF_HSCI_CAPTURE_MODE_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_CAPTURE_MODE_LSB = 32'd0; + parameter BF_HSCI_CAPTURE_MODE_MSB = 32'd0; + parameter BF_HSCI_CAPTURE_MODE_ROFFSET = 32'd2; + parameter BF_HSCI_CAPTURE_MODE_RMSB = 32'd2; + parameter BF_HSCI_CAPTURE_MODE_RMASK = 3'h4; + parameter BF_HSCI_CAPTURE_MODE_RWIDTH = 32'd1; + typedef logic hsci_capture_mode_data_t; + // bitfield structures + typedef struct packed { + hsci_capture_mode_data_t data; + } hsci_capture_mode_reg_t; + + // BitField: link_active (r) Volatile + // bitfield defines + parameter BF_LINK_ACTIVE_RESET = 1'h0; + parameter BF_LINK_ACTIVE_WIDTH = 32'd1; + // register reference defines + parameter BF_LINK_ACTIVE_LSB = 32'd0; + parameter BF_LINK_ACTIVE_MSB = 32'd0; + parameter BF_LINK_ACTIVE_ROFFSET = 32'd0; + parameter BF_LINK_ACTIVE_RMSB = 32'd0; + parameter BF_LINK_ACTIVE_RMASK = 1'h1; + parameter BF_LINK_ACTIVE_RWIDTH = 32'd1; + typedef logic link_active_data_t; + + typedef struct packed { + link_active_data_t data; + } link_active_status_t; + + // BitField: alink_txclk_adj (r) Volatile + // bitfield defines + parameter BF_ALINK_TXCLK_ADJ_RESET = 4'h0; + parameter BF_ALINK_TXCLK_ADJ_WIDTH = 32'd4; + // register reference defines + parameter BF_ALINK_TXCLK_ADJ_LSB = 32'd0; + parameter BF_ALINK_TXCLK_ADJ_MSB = 32'd3; + parameter BF_ALINK_TXCLK_ADJ_ROFFSET = 32'd4; + parameter BF_ALINK_TXCLK_ADJ_RMSB = 32'd7; + parameter BF_ALINK_TXCLK_ADJ_RMASK = 8'hf0; + parameter BF_ALINK_TXCLK_ADJ_RWIDTH = 32'd4; + typedef logic [3:0] alink_txclk_adj_data_t; + + typedef struct packed { + alink_txclk_adj_data_t data; + } alink_txclk_adj_status_t; + + // BitField: alink_txclk_inv (r) Volatile + // bitfield defines + parameter BF_ALINK_TXCLK_INV_RESET = 1'h0; + parameter BF_ALINK_TXCLK_INV_WIDTH = 32'd1; + // register reference defines + parameter BF_ALINK_TXCLK_INV_LSB = 32'd0; + parameter BF_ALINK_TXCLK_INV_MSB = 32'd0; + parameter BF_ALINK_TXCLK_INV_ROFFSET = 32'd8; + parameter BF_ALINK_TXCLK_INV_RMSB = 32'd8; + parameter BF_ALINK_TXCLK_INV_RMASK = 9'h100; + parameter BF_ALINK_TXCLK_INV_RWIDTH = 32'd1; + typedef logic alink_txclk_inv_data_t; + + typedef struct packed { + alink_txclk_inv_data_t data; + } alink_txclk_inv_status_t; + + // BitField: txclk_adj_mismatch (r) Volatile + // bitfield defines + parameter BF_TXCLK_ADJ_MISMATCH_RESET = 1'h0; + parameter BF_TXCLK_ADJ_MISMATCH_WIDTH = 32'd1; + // register reference defines + parameter BF_TXCLK_ADJ_MISMATCH_LSB = 32'd0; + parameter BF_TXCLK_ADJ_MISMATCH_MSB = 32'd0; + parameter BF_TXCLK_ADJ_MISMATCH_ROFFSET = 32'd10; + parameter BF_TXCLK_ADJ_MISMATCH_RMSB = 32'd10; + parameter BF_TXCLK_ADJ_MISMATCH_RMASK = 11'h400; + parameter BF_TXCLK_ADJ_MISMATCH_RWIDTH = 32'd1; + typedef logic txclk_adj_mismatch_data_t; + + typedef struct packed { + txclk_adj_mismatch_data_t data; + } txclk_adj_mismatch_status_t; + + // BitField: txclk_inv_mismatch (r) Volatile + // bitfield defines + parameter BF_TXCLK_INV_MISMATCH_RESET = 1'h0; + parameter BF_TXCLK_INV_MISMATCH_WIDTH = 32'd1; + // register reference defines + parameter BF_TXCLK_INV_MISMATCH_LSB = 32'd0; + parameter BF_TXCLK_INV_MISMATCH_MSB = 32'd0; + parameter BF_TXCLK_INV_MISMATCH_ROFFSET = 32'd11; + parameter BF_TXCLK_INV_MISMATCH_RMSB = 32'd11; + parameter BF_TXCLK_INV_MISMATCH_RMASK = 12'h800; + parameter BF_TXCLK_INV_MISMATCH_RWIDTH = 32'd1; + typedef logic txclk_inv_mismatch_data_t; + + typedef struct packed { + txclk_inv_mismatch_data_t data; + } txclk_inv_mismatch_status_t; + + // BitField: alink_table (r) Volatile + // bitfield defines + parameter BF_ALINK_TABLE_RESET = 16'h0; + parameter BF_ALINK_TABLE_WIDTH = 32'd16; + // register reference defines + parameter BF_ALINK_TABLE_LSB = 32'd0; + parameter BF_ALINK_TABLE_MSB = 32'd15; + parameter BF_ALINK_TABLE_ROFFSET = 32'd0; + parameter BF_ALINK_TABLE_RMSB = 32'd15; + parameter BF_ALINK_TABLE_RMASK = 16'hffff; + parameter BF_ALINK_TABLE_RWIDTH = 32'd16; + typedef logic [15:0] alink_table_data_t; + + typedef struct packed { + alink_table_data_t data; + } alink_table_status_t; + + // BitField: alink_fsm (r) Volatile + // bitfield defines + parameter BF_ALINK_FSM_RESET = 4'h0; + parameter BF_ALINK_FSM_WIDTH = 32'd4; + // register reference defines + parameter BF_ALINK_FSM_LSB = 32'd0; + parameter BF_ALINK_FSM_MSB = 32'd3; + parameter BF_ALINK_FSM_ROFFSET = 32'd16; + parameter BF_ALINK_FSM_RMSB = 32'd19; + parameter BF_ALINK_FSM_RMASK = 20'hf0000; + parameter BF_ALINK_FSM_RWIDTH = 32'd4; + typedef logic [3:0] alink_fsm_data_t; + + typedef struct packed { + alink_fsm_data_t data; + } alink_fsm_status_t; + + // BitField: enc_fsm (r) Volatile + // bitfield defines + parameter BF_ENC_FSM_RESET = 4'h0; + parameter BF_ENC_FSM_WIDTH = 32'd4; + // register reference defines + parameter BF_ENC_FSM_LSB = 32'd0; + parameter BF_ENC_FSM_MSB = 32'd3; + parameter BF_ENC_FSM_ROFFSET = 32'd0; + parameter BF_ENC_FSM_RMSB = 32'd3; + parameter BF_ENC_FSM_RMASK = 4'hf; + parameter BF_ENC_FSM_RWIDTH = 32'd4; + typedef logic [3:0] enc_fsm_data_t; + + typedef struct packed { + enc_fsm_data_t data; + } enc_fsm_status_t; + + // BitField: dec_fsm (r) Volatile + // bitfield defines + parameter BF_DEC_FSM_RESET = 3'h0; + parameter BF_DEC_FSM_WIDTH = 32'd3; + // register reference defines + parameter BF_DEC_FSM_LSB = 32'd0; + parameter BF_DEC_FSM_MSB = 32'd2; + parameter BF_DEC_FSM_ROFFSET = 32'd4; + parameter BF_DEC_FSM_RMSB = 32'd6; + parameter BF_DEC_FSM_RMASK = 7'h70; + parameter BF_DEC_FSM_RWIDTH = 32'd3; + typedef logic [2:0] dec_fsm_data_t; + + typedef struct packed { + dec_fsm_data_t data; + } dec_fsm_status_t; + + // BitField: capture_word (r) Volatile + // bitfield defines + parameter BF_CAPTURE_WORD_RESET = 10'h0; + parameter BF_CAPTURE_WORD_WIDTH = 32'd10; + // register reference defines + parameter BF_CAPTURE_WORD_LSB = 32'd0; + parameter BF_CAPTURE_WORD_MSB = 32'd9; + parameter BF_CAPTURE_WORD_ROFFSET = 32'd8; + parameter BF_CAPTURE_WORD_RMSB = 32'd17; + parameter BF_CAPTURE_WORD_RMASK = 18'h3ff00; + parameter BF_CAPTURE_WORD_RWIDTH = 32'd10; + typedef logic [9:0] capture_word_data_t; + + typedef struct packed { + capture_word_data_t data; + } capture_word_status_t; + + // BitField: parity_error (r) Volatile + // bitfield defines + parameter BF_PARITY_ERROR_RESET = 1'h0; + parameter BF_PARITY_ERROR_WIDTH = 32'd1; + // register reference defines + parameter BF_PARITY_ERROR_LSB = 32'd0; + parameter BF_PARITY_ERROR_MSB = 32'd0; + parameter BF_PARITY_ERROR_ROFFSET = 32'd18; + parameter BF_PARITY_ERROR_RMSB = 32'd18; + parameter BF_PARITY_ERROR_RMASK = 19'h40000; + parameter BF_PARITY_ERROR_RWIDTH = 32'd1; + typedef logic parity_error_data_t; + + typedef struct packed { + parity_error_data_t data; + } parity_error_status_t; + + // BitField: unkown_instruction_error (r) Volatile + // bitfield defines + parameter BF_UNKOWN_INSTRUCTION_ERROR_RESET = 1'h0; + parameter BF_UNKOWN_INSTRUCTION_ERROR_WIDTH = 32'd1; + // register reference defines + parameter BF_UNKOWN_INSTRUCTION_ERROR_LSB = 32'd0; + parameter BF_UNKOWN_INSTRUCTION_ERROR_MSB = 32'd0; + parameter BF_UNKOWN_INSTRUCTION_ERROR_ROFFSET = 32'd19; + parameter BF_UNKOWN_INSTRUCTION_ERROR_RMSB = 32'd19; + parameter BF_UNKOWN_INSTRUCTION_ERROR_RMASK = 20'h80000; + parameter BF_UNKOWN_INSTRUCTION_ERROR_RWIDTH = 32'd1; + typedef logic unkown_instruction_error_data_t; + + typedef struct packed { + unkown_instruction_error_data_t data; + } unkown_instruction_error_status_t; + + // BitField: slave_error_code (r) Volatile + // bitfield defines + parameter BF_SLAVE_ERROR_CODE_RESET = 8'h0; + parameter BF_SLAVE_ERROR_CODE_WIDTH = 32'd8; + // register reference defines + parameter BF_SLAVE_ERROR_CODE_LSB = 32'd0; + parameter BF_SLAVE_ERROR_CODE_MSB = 32'd7; + parameter BF_SLAVE_ERROR_CODE_ROFFSET = 32'd20; + parameter BF_SLAVE_ERROR_CODE_RMSB = 32'd27; + parameter BF_SLAVE_ERROR_CODE_RMASK = 28'hff00000; + parameter BF_SLAVE_ERROR_CODE_RWIDTH = 32'd8; + typedef logic [7:0] slave_error_code_data_t; + + typedef struct packed { + slave_error_code_data_t data; + } slave_error_code_status_t; + + // BitField: miso_test_ber (r) Volatile + // bitfield defines + parameter BF_MISO_TEST_BER_RESET = 32'h0; + parameter BF_MISO_TEST_BER_WIDTH = 32'd32; + // register reference defines + parameter BF_MISO_TEST_BER_LSB = 32'd0; + parameter BF_MISO_TEST_BER_MSB = 32'd31; + parameter BF_MISO_TEST_BER_ROFFSET = 32'd0; + parameter BF_MISO_TEST_BER_RMSB = 32'd31; + parameter BF_MISO_TEST_BER_RMASK = 32'hffffffff; + parameter BF_MISO_TEST_BER_RWIDTH = 32'd32; + typedef logic [31:0] miso_test_ber_data_t; + + typedef struct packed { + miso_test_ber_data_t data; + } miso_test_ber_status_t; + + // BitField: hsci_link_err_info (r) Volatile + // bitfield defines + parameter BF_HSCI_LINK_ERR_INFO_RESET = 31'h0; + parameter BF_HSCI_LINK_ERR_INFO_WIDTH = 32'd31; + // register reference defines + parameter BF_HSCI_LINK_ERR_INFO_LSB = 32'd0; + parameter BF_HSCI_LINK_ERR_INFO_MSB = 32'd30; + parameter BF_HSCI_LINK_ERR_INFO_ROFFSET = 32'd0; + parameter BF_HSCI_LINK_ERR_INFO_RMSB = 32'd30; + parameter BF_HSCI_LINK_ERR_INFO_RMASK = 31'h7fffffff; + parameter BF_HSCI_LINK_ERR_INFO_RWIDTH = 32'd31; + typedef logic [30:0] hsci_link_err_info_data_t; + + typedef struct packed { + hsci_link_err_info_data_t data; + } hsci_link_err_info_status_t; + + // BitField: scratch_reg (r/w) + // bitfield defines + parameter BF_SCRATCH_REG_RESET = 32'h0; + parameter BF_SCRATCH_REG_WIDTH = 32'd32; + // register reference defines + parameter BF_SCRATCH_REG_LSB = 32'd0; + parameter BF_SCRATCH_REG_MSB = 32'd31; + parameter BF_SCRATCH_REG_ROFFSET = 32'd0; + parameter BF_SCRATCH_REG_RMSB = 32'd31; + parameter BF_SCRATCH_REG_RMASK = 32'hffffffff; + parameter BF_SCRATCH_REG_RWIDTH = 32'd32; + typedef logic [31:0] scratch_reg_data_t; + // bitfield structures + typedef struct packed { + scratch_reg_data_t data; + } scratch_reg_reg_t; + + // BitField: hsci_mmcm_drp_trig (r/w) + // bitfield defines + parameter BF_HSCI_MMCM_DRP_TRIG_RESET = 1'h0; + parameter BF_HSCI_MMCM_DRP_TRIG_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MMCM_DRP_TRIG_LSB = 32'd0; + parameter BF_HSCI_MMCM_DRP_TRIG_MSB = 32'd0; + parameter BF_HSCI_MMCM_DRP_TRIG_ROFFSET = 32'd0; + parameter BF_HSCI_MMCM_DRP_TRIG_RMSB = 32'd0; + parameter BF_HSCI_MMCM_DRP_TRIG_RMASK = 1'h1; + parameter BF_HSCI_MMCM_DRP_TRIG_RWIDTH = 32'd1; + typedef logic hsci_mmcm_drp_trig_data_t; + // bitfield structures + typedef struct packed { + hsci_mmcm_drp_trig_data_t data; + } hsci_mmcm_drp_trig_reg_t; + + // BitField: hsci_rate_sel (r/w) + // bitfield defines + parameter BF_HSCI_RATE_SEL_RESET = 2'h0; + parameter BF_HSCI_RATE_SEL_WIDTH = 32'd2; + // register reference defines + parameter BF_HSCI_RATE_SEL_LSB = 32'd0; + parameter BF_HSCI_RATE_SEL_MSB = 32'd1; + parameter BF_HSCI_RATE_SEL_ROFFSET = 32'd1; + parameter BF_HSCI_RATE_SEL_RMSB = 32'd2; + parameter BF_HSCI_RATE_SEL_RMASK = 3'h6; + parameter BF_HSCI_RATE_SEL_RWIDTH = 32'd2; + typedef logic [1:0] hsci_rate_sel_data_t; + // bitfield structures + typedef struct packed { + hsci_rate_sel_data_t data; + } hsci_rate_sel_reg_t; + + // BitField: hsci_pll_reset (r/w) + // bitfield defines + parameter BF_HSCI_PLL_RESET_RESET = 1'h0; + parameter BF_HSCI_PLL_RESET_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_PLL_RESET_LSB = 32'd0; + parameter BF_HSCI_PLL_RESET_MSB = 32'd0; + parameter BF_HSCI_PLL_RESET_ROFFSET = 32'd8; + parameter BF_HSCI_PLL_RESET_RMSB = 32'd8; + parameter BF_HSCI_PLL_RESET_RMASK = 9'h100; + parameter BF_HSCI_PLL_RESET_RWIDTH = 32'd1; + typedef logic hsci_pll_reset_data_t; + // bitfield structures + typedef struct packed { + hsci_pll_reset_data_t data; + } hsci_pll_reset_reg_t; + + // BitField: hsci_master_clear_errors (r/w) + // bitfield defines + parameter BF_HSCI_MASTER_CLEAR_ERRORS_RESET = 1'h0; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MASTER_CLEAR_ERRORS_LSB = 32'd0; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_MSB = 32'd0; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_ROFFSET = 32'd4; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_RMSB = 32'd4; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_RMASK = 5'h10; + parameter BF_HSCI_MASTER_CLEAR_ERRORS_RWIDTH = 32'd1; + typedef logic hsci_master_clear_errors_data_t; + // bitfield structures + typedef struct packed { + hsci_master_clear_errors_data_t data; + } hsci_master_clear_errors_reg_t; + + // BitField: hsci_master_rstn (r/w) + // bitfield defines + parameter BF_HSCI_MASTER_RSTN_RESET = 1'h0; + parameter BF_HSCI_MASTER_RSTN_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_MASTER_RSTN_LSB = 32'd0; + parameter BF_HSCI_MASTER_RSTN_MSB = 32'd0; + parameter BF_HSCI_MASTER_RSTN_ROFFSET = 32'd8; + parameter BF_HSCI_MASTER_RSTN_RMSB = 32'd8; + parameter BF_HSCI_MASTER_RSTN_RMASK = 9'h100; + parameter BF_HSCI_MASTER_RSTN_RWIDTH = 32'd1; + typedef logic hsci_master_rstn_data_t; + // bitfield structures + typedef struct packed { + hsci_master_rstn_data_t data; + } hsci_master_rstn_reg_t; + + // BitField: hsci_reset_seq_done (r) Volatile + // bitfield defines + parameter BF_HSCI_RESET_SEQ_DONE_RESET = 1'h0; + parameter BF_HSCI_RESET_SEQ_DONE_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_RESET_SEQ_DONE_LSB = 32'd0; + parameter BF_HSCI_RESET_SEQ_DONE_MSB = 32'd0; + parameter BF_HSCI_RESET_SEQ_DONE_ROFFSET = 32'd0; + parameter BF_HSCI_RESET_SEQ_DONE_RMSB = 32'd0; + parameter BF_HSCI_RESET_SEQ_DONE_RMASK = 1'h1; + parameter BF_HSCI_RESET_SEQ_DONE_RWIDTH = 32'd1; + typedef logic hsci_reset_seq_done_data_t; + + typedef struct packed { + hsci_reset_seq_done_data_t data; + } hsci_reset_seq_done_status_t; + + // BitField: hsci_phy_pll_locked (r) Volatile + // bitfield defines + parameter BF_HSCI_PHY_PLL_LOCKED_RESET = 1'h0; + parameter BF_HSCI_PHY_PLL_LOCKED_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_PHY_PLL_LOCKED_LSB = 32'd0; + parameter BF_HSCI_PHY_PLL_LOCKED_MSB = 32'd0; + parameter BF_HSCI_PHY_PLL_LOCKED_ROFFSET = 32'd1; + parameter BF_HSCI_PHY_PLL_LOCKED_RMSB = 32'd1; + parameter BF_HSCI_PHY_PLL_LOCKED_RMASK = 2'h2; + parameter BF_HSCI_PHY_PLL_LOCKED_RWIDTH = 32'd1; + typedef logic hsci_phy_pll_locked_data_t; + + typedef struct packed { + hsci_phy_pll_locked_data_t data; + } hsci_phy_pll_locked_status_t; + + // BitField: hsci_vtc_rdy_tx (r) Volatile + // bitfield defines + parameter BF_HSCI_VTC_RDY_TX_RESET = 1'h0; + parameter BF_HSCI_VTC_RDY_TX_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_VTC_RDY_TX_LSB = 32'd0; + parameter BF_HSCI_VTC_RDY_TX_MSB = 32'd0; + parameter BF_HSCI_VTC_RDY_TX_ROFFSET = 32'd2; + parameter BF_HSCI_VTC_RDY_TX_RMSB = 32'd2; + parameter BF_HSCI_VTC_RDY_TX_RMASK = 3'h4; + parameter BF_HSCI_VTC_RDY_TX_RWIDTH = 32'd1; + typedef logic hsci_vtc_rdy_tx_data_t; + + typedef struct packed { + hsci_vtc_rdy_tx_data_t data; + } hsci_vtc_rdy_tx_status_t; + + // BitField: hsci_vtc_rdy_rx (r) Volatile + // bitfield defines + parameter BF_HSCI_VTC_RDY_RX_RESET = 1'h0; + parameter BF_HSCI_VTC_RDY_RX_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_VTC_RDY_RX_LSB = 32'd0; + parameter BF_HSCI_VTC_RDY_RX_MSB = 32'd0; + parameter BF_HSCI_VTC_RDY_RX_ROFFSET = 32'd3; + parameter BF_HSCI_VTC_RDY_RX_RMSB = 32'd3; + parameter BF_HSCI_VTC_RDY_RX_RMASK = 4'h8; + parameter BF_HSCI_VTC_RDY_RX_RWIDTH = 32'd1; + typedef logic hsci_vtc_rdy_rx_data_t; + + typedef struct packed { + hsci_vtc_rdy_rx_data_t data; + } hsci_vtc_rdy_rx_status_t; + + // BitField: hsci_dly_rdy_tx (r) Volatile + // bitfield defines + parameter BF_HSCI_DLY_RDY_TX_RESET = 1'h0; + parameter BF_HSCI_DLY_RDY_TX_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_DLY_RDY_TX_LSB = 32'd0; + parameter BF_HSCI_DLY_RDY_TX_MSB = 32'd0; + parameter BF_HSCI_DLY_RDY_TX_ROFFSET = 32'd4; + parameter BF_HSCI_DLY_RDY_TX_RMSB = 32'd4; + parameter BF_HSCI_DLY_RDY_TX_RMASK = 5'h10; + parameter BF_HSCI_DLY_RDY_TX_RWIDTH = 32'd1; + typedef logic hsci_dly_rdy_tx_data_t; + + typedef struct packed { + hsci_dly_rdy_tx_data_t data; + } hsci_dly_rdy_tx_status_t; + + // BitField: hsci_dly_rdy_rx (r) Volatile + // bitfield defines + parameter BF_HSCI_DLY_RDY_RX_RESET = 1'h0; + parameter BF_HSCI_DLY_RDY_RX_WIDTH = 32'd1; + // register reference defines + parameter BF_HSCI_DLY_RDY_RX_LSB = 32'd0; + parameter BF_HSCI_DLY_RDY_RX_MSB = 32'd0; + parameter BF_HSCI_DLY_RDY_RX_ROFFSET = 32'd5; + parameter BF_HSCI_DLY_RDY_RX_RMSB = 32'd5; + parameter BF_HSCI_DLY_RDY_RX_RMASK = 6'h20; + parameter BF_HSCI_DLY_RDY_RX_RWIDTH = 32'd1; + typedef logic hsci_dly_rdy_rx_data_t; + + typedef struct packed { + hsci_dly_rdy_rx_data_t data; + } hsci_dly_rdy_rx_status_t; + + // ========== Register Input and Output Structures ========== + typedef struct packed { + hsci_revision_id_reg_t hsci_revision_id; + hsci_xfer_mode_reg_t hsci_xfer_mode; + ver_b__na_reg_t ver_b__na; + hsci_xfer_num_reg_t hsci_xfer_num; + hsci_addr_size_reg_t hsci_addr_size; + hsci_byte_num_reg_t hsci_byte_num; + spi_target_reg_t spi_target; + hsci_cmd_sel_reg_t hsci_cmd_sel; + hsci_slave_ahb_tsize_reg_t hsci_slave_ahb_tsize; + hsci_bram_start_address_reg_t hsci_bram_start_address; + hsci_run_reg_t hsci_run; + hsci_man_linkup_word_reg_t hsci_man_linkup_word; + hsci_man_linkup_reg_t hsci_man_linkup; + hsci_auto_linkup_reg_t hsci_auto_linkup; + mosi_clk_inv_reg_t mosi_clk_inv; + miso_clk_inv_reg_t miso_clk_inv; + hsci_mosi_test_mode_reg_t hsci_mosi_test_mode; + hsci_miso_test_mode_reg_t hsci_miso_test_mode; + hsci_capture_mode_reg_t hsci_capture_mode; + scratch_reg_reg_t scratch_reg; + hsci_mmcm_drp_trig_reg_t hsci_mmcm_drp_trig; + hsci_rate_sel_reg_t hsci_rate_sel; + hsci_pll_reset_reg_t hsci_pll_reset; + hsci_master_clear_errors_reg_t hsci_master_clear_errors; + hsci_master_rstn_reg_t hsci_master_rstn; + } hsci_master_regs_regs_t; + + typedef struct packed { + hsci_run_status_t hsci_run; + master_done_status_t master_done; + master_running_status_t master_running; + master_wr_in_prog_status_t master_wr_in_prog; + master_rd_in_prog_status_t master_rd_in_prog; + miso_test_lfsr_acq_status_t miso_test_lfsr_acq; + link_active_status_t link_active; + alink_txclk_adj_status_t alink_txclk_adj; + alink_txclk_inv_status_t alink_txclk_inv; + txclk_adj_mismatch_status_t txclk_adj_mismatch; + txclk_inv_mismatch_status_t txclk_inv_mismatch; + alink_table_status_t alink_table; + alink_fsm_status_t alink_fsm; + enc_fsm_status_t enc_fsm; + dec_fsm_status_t dec_fsm; + capture_word_status_t capture_word; + parity_error_status_t parity_error; + unkown_instruction_error_status_t unkown_instruction_error; + slave_error_code_status_t slave_error_code; + miso_test_ber_status_t miso_test_ber; + hsci_link_err_info_status_t hsci_link_err_info; + hsci_reset_seq_done_status_t hsci_reset_seq_done; + hsci_phy_pll_locked_status_t hsci_phy_pll_locked; + hsci_vtc_rdy_tx_status_t hsci_vtc_rdy_tx; + hsci_vtc_rdy_rx_status_t hsci_vtc_rdy_rx; + hsci_dly_rdy_tx_status_t hsci_dly_rdy_tx; + hsci_dly_rdy_rx_status_t hsci_dly_rdy_rx; + } hsci_master_regs_status_t; + + + + + +/*----------------------------------------*/ +/* Function for MMR WR Access Validation */ +/*----------------------------------------*/ + +function automatic MMR_Rd_Valid_HSCI_MASTER_REGS( input [15:0] adr ); + logic valid; + begin + case( adr ) + 16'h0000 : valid = 1'b1; + 16'h8001 : valid = 1'b1; + 16'h8002 : valid = 1'b1; + 16'h8003 : valid = 1'b1; + 16'h8004 : valid = 1'b1; + 16'h8005 : valid = 1'b1; + 16'h8006 : valid = 1'b1; + 16'h8007 : valid = 1'b1; + 16'h8008 : valid = 1'b1; + 16'h8009 : valid = 1'b1; + 16'h800a : valid = 1'b1; + 16'h800b : valid = 1'b1; + 16'h800c : valid = 1'b1; + 16'h800d : valid = 1'b1; + 16'h800e : valid = 1'b1; + 16'h800f : valid = 1'b1; + 16'h8010 : valid = 1'b1; + 16'h8011 : valid = 1'b1; + 16'h8012 : valid = 1'b1; + 16'h8013 : valid = 1'b1; + 16'h801f : valid = 1'b1; + default : valid = 1'b0; + endcase + MMR_Rd_Valid_HSCI_MASTER_REGS = valid; + end +endfunction /* MMR_Rd_Valid_HSCI_MASTER_REGS */ + +/*----------------------------------------*/ +/* Function for MMR WR Access Validation */ +/*----------------------------------------*/ + +function automatic MMR_Wr_Valid_HSCI_MASTER_REGS( input [15:0] adr ); + logic valid; + begin + case( adr ) + 16'h8001 : valid = 1'b1; + 16'h8002 : valid = 1'b1; + 16'h8003 : valid = 1'b1; + 16'h8004 : valid = 1'b1; + 16'h8005 : valid = 1'b1; + 16'h8006 : valid = 1'b1; + 16'h8007 : valid = 1'b1; + 16'h8008 : valid = 1'b1; + 16'h800a : valid = 1'b1; + 16'h800b : valid = 1'b1; + 16'h8010 : valid = 1'b1; + 16'h8011 : valid = 1'b1; + 16'h8012 : valid = 1'b1; + 16'h8013 : valid = 1'b1; + 16'h801f : valid = 1'b1; + default : valid = 1'b0; + endcase + MMR_Wr_Valid_HSCI_MASTER_REGS = valid; + end +endfunction /* MMR_Wr_Valid_HSCI_MASTER_REGS */ + +endpackage + +`endif // end ifndef _DEFINE_SV_HSCI_MASTER_REGS diff --git a/library/axi_hsci/hsci_master_regs_regs.sv b/library/axi_hsci/hsci_master_regs_regs.sv new file mode 100644 index 0000000000..55e0b8f80e --- /dev/null +++ b/library/axi_hsci/hsci_master_regs_regs.sv @@ -0,0 +1,473 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +/// SPDX short identifier: ADIBSD +/////////////////////////////////////////////////////////////////////////////// + + +`include "hsci_master_regs_defs.vh" + +/* ++----------+----------------------------+---------+-----------------------------------------------------------------------+ +| ADDRESS | REG NAME | BITS | BITFIELD | ++----------+----------------------------+---------+-----------------------------------------------------------------------+ +| 00000000 | REVISION_ID | | | +| | | [15:0] | hsci_revision_id (r) | +| 00008001 | HSCI_MASTER_MODE | | | +| | | [1:0] | hsci_xfer_mode (r/w) | +| | | [4] | ver_b__na (r/w) | +| 00008002 | HSCI_MASTER_XFER_NUM | | | +| | | [15:0] | hsci_xfer_num (r/w) | +| 00008003 | HSCI_MASTER_ADDR_SIZE | | | +| | | [2:0] | hsci_addr_size (r/w) | +| 00008004 | HSCI_MASTER_BYTE_NUM | | | +| | | [16:0] | hsci_byte_num (r/w) | +| 00008005 | HSCI_MASTER_TARGET | | | +| | | [31:0] | spi_target (r/w) | +| 00008006 | HSCI_MASTER_CTRL | | | +| | | [1:0] | hsci_cmd_sel (r/w) | +| | | [5:4] | hsci_slave_ahb_tsize (r/w) | +| 00008007 | HSCI_MASTER_BRAM_ADDRESS | | | +| | | [15:0] | hsci_bram_start_address (r/w) | +| 00008008 | HSCI_MASTER_RUN | | | +| | | [0] | hsci_run (r/w) | +| 00008009 | HSCI_MASTER_STATUS | | | +| | | [0] | master_done (r) Volatile | +| | | [1] | master_running (r) Volatile | +| | | [2] | master_wr_in_prog (r) Volatile | +| | | [3] | master_rd_in_prog (r) Volatile | +| | | [4] | miso_test_lfsr_acq (r) Volatile | +| 0000800a | HSCI_MASTER_LINKUP_CTRL | | | +| | | [9:0] | hsci_man_linkup_word (r/w) | +| | | [10] | hsci_man_linkup (r/w) | +| | | [11] | hsci_auto_linkup (r/w) | +| | | [12] | mosi_clk_inv (r/w) | +| | | [13] | miso_clk_inv (r/w) | +| 0000800b | HSCI_MASTER_TEST_CTRL | | | +| | | [0] | hsci_mosi_test_mode (r/w) | +| | | [1] | hsci_miso_test_mode (r/w) | +| | | [2] | hsci_capture_mode (r/w) | +| 0000800c | HSCI_MASTER_LINKUP_STATUS | | | +| | | [0] | link_active (r) Volatile | +| | | [7:4] | alink_txclk_adj (r) Volatile | +| | | [8] | alink_txclk_inv (r) Volatile | +| | | [10] | txclk_adj_mismatch (r) Volatile | +| | | [11] | txclk_inv_mismatch (r) Volatile | +| 0000800d | HSCI_MASTER_LINKUP_STATUS2 | | | +| | | [15:0] | alink_table (r) Volatile | +| | | [19:16] | alink_fsm (r) Volatile | +| 0000800e | HSCI_DEBUG_STATUS | | | +| | | [3:0] | enc_fsm (r) Volatile | +| | | [6:4] | dec_fsm (r) Volatile | +| | | [17:8] | capture_word (r) Volatile | +| | | [18] | parity_error (r) Volatile | +| | | [19] | unkown_instruction_error (r) Volatile | +| | | [27:20] | slave_error_code (r) Volatile | +| 0000800f | MISO_TEST_BER | | | +| | | [31:0] | miso_test_ber (r) Volatile | +| 00008010 | HSCI_MASTER_LINK_ERR_INFO | | | +| | | [30:0] | hsci_link_err_info (r) Volatile | +| 00008011 | HSCI_RATE_CTRL | | | +| | | [0] | hsci_mmcm_drp_trig (r/w) | +| | | [2:1] | hsci_rate_sel (r/w) | +| | | [8] | hsci_pll_reset (r/w) | +| 00008012 | HSCI_MASTER_RST | | | +| | | [4] | hsci_master_clear_errors (r/w) | +| | | [8] | hsci_master_rstn (r/w) | +| 00008013 | HSCI_PHY_STATUS | | | +| | | [0] | hsci_reset_seq_done (r) Volatile | +| | | [1] | hsci_phy_pll_locked (r) Volatile | +| | | [2] | hsci_vtc_rdy_tx (r) Volatile | +| | | [3] | hsci_vtc_rdy_rx (r) Volatile | +| | | [4] | hsci_dly_rdy_tx (r) Volatile | +| | | [5] | hsci_dly_rdy_rx (r) Volatile | +| 0000801f | HSCI_MASTER_SCRATCH | | | +| | | [31:0] | scratch_reg (r/w) | ++----------+----------------------------+---------+-----------------------------------------------------------------------+ +*/ + +module hsci_master_regs_regs( + input clk, + input srstn, + input [15:0] I_rd_addr, + input I_wr_stb, + input [15:0] I_wr_addr, + input [31:0] I_wr_data, + output reg [31:0] O_read_data, + input hsci_master_regs_pkg::hsci_master_regs_status_t I, + output hsci_master_regs_pkg::hsci_master_regs_regs_t O +); + + import hsci_master_regs_pkg::*; + + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_MODE; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_TARGET; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_CTRL; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_RUN; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH; + wire wr_HSCI_MASTER_REGS_HSCI_RATE_CTRL; + wire wr_HSCI_MASTER_REGS_HSCI_MASTER_RST; + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_MODE = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8001)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8002)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8003)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8004)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_TARGET = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8005)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_CTRL = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8006)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8007)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_RUN = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8008)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL = ((I_wr_stb==1'b1) && (I_wr_addr==16'h800a)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL = ((I_wr_stb==1'b1) && (I_wr_addr==16'h800b)); + assign wr_HSCI_MASTER_REGS_HSCI_RATE_CTRL = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8011)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_RST = ((I_wr_stb==1'b1) && (I_wr_addr==16'h8012)); + assign wr_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH = ((I_wr_stb==1'b1) && (I_wr_addr==16'h801f)); + + // BitField: hsci_revision_id (r) + assign O.hsci_revision_id.data = 16'h1; + + // BitField: hsci_xfer_mode (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_xfer_mode.data <= 2'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_MODE) begin + O.hsci_xfer_mode.data <= I_wr_data[1:0]; + end + end + + // BitField: ver_b__na (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.ver_b__na.data <= 1'h1; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_MODE) begin + O.ver_b__na.data <= I_wr_data[4]; + end + end + + // BitField: hsci_xfer_num (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_xfer_num.data <= 16'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM) begin + O.hsci_xfer_num.data <= I_wr_data[15:0]; + end + end + + // BitField: hsci_addr_size (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_addr_size.data <= 3'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE) begin + O.hsci_addr_size.data <= I_wr_data[2:0]; + end + end + + // BitField: hsci_byte_num (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_byte_num.data <= 17'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM) begin + O.hsci_byte_num.data <= I_wr_data[16:0]; + end + end + + // BitField: spi_target (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.spi_target.data <= 32'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_TARGET) begin + O.spi_target.data <= I_wr_data[31:0]; + end + end + + // BitField: hsci_cmd_sel (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_cmd_sel.data <= 2'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_CTRL) begin + O.hsci_cmd_sel.data <= I_wr_data[1:0]; + end + end + + // BitField: hsci_slave_ahb_tsize (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_slave_ahb_tsize.data <= 2'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_CTRL) begin + O.hsci_slave_ahb_tsize.data <= I_wr_data[5:4]; + end + end + + // BitField: hsci_bram_start_address (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_bram_start_address.data <= 16'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS) begin + O.hsci_bram_start_address.data <= I_wr_data[15:0]; + end + end + + // BitField: hsci_run (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_run.data <= 1'h0; + end else if(I.hsci_run.sclr) begin + O.hsci_run.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_RUN) begin + O.hsci_run.data <= I_wr_data[0]; + end + end + + // BitField: master_done (r) Volatile + + // BitField: master_running (r) Volatile + + // BitField: master_wr_in_prog (r) Volatile + + // BitField: master_rd_in_prog (r) Volatile + + // BitField: miso_test_lfsr_acq (r) Volatile + + // BitField: hsci_man_linkup_word (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_man_linkup_word.data <= 10'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL) begin + O.hsci_man_linkup_word.data <= I_wr_data[9:0]; + end + end + + // BitField: hsci_man_linkup (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_man_linkup.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL) begin + O.hsci_man_linkup.data <= I_wr_data[10]; + end + end + + // BitField: hsci_auto_linkup (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_auto_linkup.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL) begin + O.hsci_auto_linkup.data <= I_wr_data[11]; + end + end + + // BitField: mosi_clk_inv (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.mosi_clk_inv.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL) begin + O.mosi_clk_inv.data <= I_wr_data[12]; + end + end + + // BitField: miso_clk_inv (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.miso_clk_inv.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL) begin + O.miso_clk_inv.data <= I_wr_data[13]; + end + end + + // BitField: hsci_mosi_test_mode (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_mosi_test_mode.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL) begin + O.hsci_mosi_test_mode.data <= I_wr_data[0]; + end + end + + // BitField: hsci_miso_test_mode (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_miso_test_mode.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL) begin + O.hsci_miso_test_mode.data <= I_wr_data[1]; + end + end + + // BitField: hsci_capture_mode (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_capture_mode.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL) begin + O.hsci_capture_mode.data <= I_wr_data[2]; + end + end + + // BitField: link_active (r) Volatile + + // BitField: alink_txclk_adj (r) Volatile + + // BitField: alink_txclk_inv (r) Volatile + + // BitField: txclk_adj_mismatch (r) Volatile + + // BitField: txclk_inv_mismatch (r) Volatile + + // BitField: alink_table (r) Volatile + + // BitField: alink_fsm (r) Volatile + + // BitField: enc_fsm (r) Volatile + + // BitField: dec_fsm (r) Volatile + + // BitField: capture_word (r) Volatile + + // BitField: parity_error (r) Volatile + + // BitField: unkown_instruction_error (r) Volatile + + // BitField: slave_error_code (r) Volatile + + // BitField: miso_test_ber (r) Volatile + + // BitField: hsci_link_err_info (r) Volatile + + // BitField: scratch_reg (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.scratch_reg.data <= 32'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH) begin + O.scratch_reg.data <= I_wr_data[31:0]; + end + end + + // BitField: hsci_mmcm_drp_trig (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_mmcm_drp_trig.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_RATE_CTRL) begin + O.hsci_mmcm_drp_trig.data <= I_wr_data[0]; + end + end + + // BitField: hsci_rate_sel (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_rate_sel.data <= 2'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_RATE_CTRL) begin + O.hsci_rate_sel.data <= I_wr_data[2:1]; + end + end + + // BitField: hsci_pll_reset (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_pll_reset.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_RATE_CTRL) begin + O.hsci_pll_reset.data <= I_wr_data[8]; + end + end + + // BitField: hsci_master_clear_errors (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_master_clear_errors.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_RST) begin + O.hsci_master_clear_errors.data <= I_wr_data[4]; + end + end + + // BitField: hsci_master_rstn (r/w) + always_ff @( posedge clk) begin + if(!srstn) begin + O.hsci_master_rstn.data <= 1'h0; + end else if(wr_HSCI_MASTER_REGS_HSCI_MASTER_RST) begin + O.hsci_master_rstn.data <= I_wr_data[8]; + end + end + + // BitField: hsci_reset_seq_done (r) Volatile + + // BitField: hsci_phy_pll_locked (r) Volatile + + // BitField: hsci_vtc_rdy_tx (r) Volatile + + // BitField: hsci_vtc_rdy_rx (r) Volatile + + // BitField: hsci_dly_rdy_tx (r) Volatile + + // BitField: hsci_dly_rdy_rx (r) Volatile + + wire [31:0] rdata_HSCI_MASTER_REGS_REVISION_ID; // Revision ID for SPI Master Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_MODE; // HSCI Master Mode Selection Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM; // HSCI Master Number of Transactions Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE; // HSCI Master Address Size Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM; // HSCI Master Data Size Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_TARGET; // HSCI Master Target Chip Select Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_CTRL; // HSCI Master CTRL Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS; // BRAM Sequence Start Addr Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_RUN; // HSCI Master RUN Trigger Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_STATUS; // HSCI Master Status Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL; // HSCI Master Linkup CTRL Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL; // HSCI Master Test CTRL Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS; // HSCI Master Linkup Status Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS2; // HSCI Master Linkup Status 2 Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_DEBUG_STATUS; // HSCI Master FSM Status Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_MISO_TEST_BER; // MISO Test BER Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINK_ERR_INFO; // HSCI Master Link Error Info Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH; // Scratch Register Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_RATE_CTRL; // HSCI Rate Control Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_MASTER_RST; // HSCI Master Reset Controls Read Data + wire [31:0] rdata_HSCI_MASTER_REGS_HSCI_PHY_STATUS; // HSCI PHY STATUS Read Data + assign rdata_HSCI_MASTER_REGS_REVISION_ID[31:0] = {16'h0, O.hsci_revision_id.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_MODE[31:0] = {27'h0, O.ver_b__na.data, 2'h0, O.hsci_xfer_mode.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM[31:0] = {16'h0, O.hsci_xfer_num.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE[31:0] = {29'h0, O.hsci_addr_size.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM[31:0] = {15'h0, O.hsci_byte_num.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_TARGET[31:0] = {O.spi_target.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_CTRL[31:0] = {26'h0, O.hsci_slave_ahb_tsize.data, 2'h0, O.hsci_cmd_sel.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS[31:0] = {16'h0, O.hsci_bram_start_address.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_RUN[31:0] = {31'h0, O.hsci_run.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_STATUS[31:0] = {27'h0, I.miso_test_lfsr_acq.data, I.master_rd_in_prog.data, I.master_wr_in_prog.data, I.master_running.data, I.master_done.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL[31:0] = {18'h0, O.miso_clk_inv.data, O.mosi_clk_inv.data, O.hsci_auto_linkup.data, O.hsci_man_linkup.data, O.hsci_man_linkup_word.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL[31:0] = {29'h0, O.hsci_capture_mode.data, O.hsci_miso_test_mode.data, O.hsci_mosi_test_mode.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS[31:0] = {20'h0, I.txclk_inv_mismatch.data, I.txclk_adj_mismatch.data, 1'h0, I.alink_txclk_inv.data, I.alink_txclk_adj.data, 3'h0, I.link_active.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS2[31:0] = {12'h0, I.alink_fsm.data, I.alink_table.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_DEBUG_STATUS[31:0] = {4'h0, I.slave_error_code.data, I.unkown_instruction_error.data, I.parity_error.data, I.capture_word.data, 1'h0, I.dec_fsm.data, I.enc_fsm.data}; + assign rdata_HSCI_MASTER_REGS_MISO_TEST_BER[31:0] = {I.miso_test_ber.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINK_ERR_INFO[31:0] = {1'h0, I.hsci_link_err_info.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH[31:0] = {O.scratch_reg.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_RATE_CTRL[31:0] = {23'h0, O.hsci_pll_reset.data, 5'h0, O.hsci_rate_sel.data, O.hsci_mmcm_drp_trig.data}; + assign rdata_HSCI_MASTER_REGS_HSCI_MASTER_RST[31:0] = {23'h0, O.hsci_master_rstn.data, 3'h0, O.hsci_master_clear_errors.data, 4'h0}; + assign rdata_HSCI_MASTER_REGS_HSCI_PHY_STATUS[31:0] = {26'h0, I.hsci_dly_rdy_rx.data, I.hsci_dly_rdy_tx.data, I.hsci_vtc_rdy_rx.data, I.hsci_vtc_rdy_tx.data, I.hsci_phy_pll_locked.data, I.hsci_reset_seq_done.data}; + + always_comb begin + case (I_rd_addr) + 16'h0000 : O_read_data = rdata_HSCI_MASTER_REGS_REVISION_ID; + 16'h8001 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_MODE; + 16'h8002 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_XFER_NUM; + 16'h8003 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_ADDR_SIZE; + 16'h8004 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_BYTE_NUM; + 16'h8005 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_TARGET; + 16'h8006 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_CTRL; + 16'h8007 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_BRAM_ADDRESS; + 16'h8008 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_RUN; + 16'h8009 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_STATUS; + 16'h800a : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_CTRL; + 16'h800b : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_TEST_CTRL; + 16'h800c : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS; + 16'h800d : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINKUP_STATUS2; + 16'h800e : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_DEBUG_STATUS; + 16'h800f : O_read_data = rdata_HSCI_MASTER_REGS_MISO_TEST_BER; + 16'h8010 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_LINK_ERR_INFO; + 16'h8011 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_RATE_CTRL; + 16'h8012 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_RST; + 16'h8013 : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_PHY_STATUS; + 16'h801f : O_read_data = rdata_HSCI_MASTER_REGS_HSCI_MASTER_SCRATCH; + default : + O_read_data = 32'h0; + endcase + end + +endmodule diff --git a/library/axi_hsci/hsci_master_top.sv b/library/axi_hsci/hsci_master_top.sv new file mode 100755 index 0000000000..97f73ec55c --- /dev/null +++ b/library/axi_hsci/hsci_master_top.sv @@ -0,0 +1,289 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps +import hsci_master_regs_pkg::*; + +module hsci_master_top #( + parameter AXI_ADDR_WIDTH = 16, + parameter AXI_DATA_WIDTH = 32, + parameter REGMAP_ADDR_WIDTH = 16, + parameter S_AXI_ADDR_WIDTH = 18 +)( + input wire axi_clk, + input wire axi_resetn, + + input wire hsci_pclk, + + axi4_lite.slave axi, + + output [7:0] hsci_menc_clk, + output [7:0] hsci_mosi_data, + input wire [7:0] hsci_miso_data, + + output hsci_pll_reset, + input wire hsci_rst_seq_done, + input wire hsci_pll_locked, + input wire hsci_vtc_rdy_bsc_tx, + input wire hsci_dly_rdy_bsc_tx, + input wire hsci_vtc_rdy_bsc_rx, + input wire hsci_dly_rdy_bsc_rx +); + + //-------------------------------------------------------------------------- + //----------- Local Parameters --------------------------------------------- + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + //----------- Signal Declarations ------------------------------------------ + //-------------------------------------------------------------------------- + + hsci_master_regs_pkg::hsci_master_regs_status_t I; + hsci_master_regs_pkg::hsci_master_regs_regs_t O; + + // BRAM Interface + logic bram_ce; + logic [14:0] bram_addr; + logic [3:0] bram_we; + logic [31:0] bram_dout; + logic [31:0] bram_din; + + logic sbiterra; + logic sbiterrb; + logic dbiterra; + logic dbiterrb; + + logic [14:0] bram_strt_addr; + + wire [REGMAP_ADDR_WIDTH-1:0] hsci_regmap_raddr; + wire hsci_regmap_rd_en; + wire [AXI_DATA_WIDTH-1:0] hsci_regmap_rdata; + wire [REGMAP_ADDR_WIDTH-1:0] hsci_regmap_waddr; + wire [AXI_DATA_WIDTH-1:0] hsci_regmap_wdata; + wire hsci_regmap_wr_en; + + wire [AXI_ADDR_WIDTH-1:0] axi_bram_addr; + wire [AXI_DATA_WIDTH-1:0] axi_bram_wdata; + wire [AXI_DATA_WIDTH-1:0] axi_bram_rdata; + wire axi_bram_wr_en; + + wire run_s; + wire hsci_clear_errors; + logic hsci_rstn_async; + logic hsci_rst_sync; + + + assign I.hsci_reset_seq_done = hsci_rst_seq_done; + assign I.hsci_phy_pll_locked = hsci_pll_locked; + assign I.hsci_vtc_rdy_tx = hsci_vtc_rdy_bsc_tx; + assign I.hsci_dly_rdy_tx = hsci_dly_rdy_bsc_tx; + assign I.hsci_vtc_rdy_rx = hsci_vtc_rdy_bsc_rx; + assign I.hsci_dly_rdy_rx = hsci_dly_rdy_bsc_rx; + + assign hsci_pll_reset = O.hsci_pll_reset.data; + assign hsci_rstn_async = O.hsci_master_rstn.data & hsci_pll_locked; + assign hsci_clear_errors = O.hsci_master_clear_errors.data; + assign bram_strt_addr = (O.hsci_bram_start_address.data)-1;//*'h4 - 16'h4; + + ad_rst i_hsci_rstn_reg ( + .rst_async(~hsci_rstn_async), + .clk(hsci_pclk), + .rstn(), + .rst(hsci_rst_sync)); + + pulse_sync sync_run ( + .dout (run_s), + .inclk (axi_clk), + .rst_inclk (~axi_resetn), + .outclk (hsci_pclk), + .rst_outclk (hsci_rst_sync), + .din (O.hsci_run.data)); + + // HSCI Core Instantiation + hsci_mcore hsci_mcore ( + //globals + .hsci_pclk (hsci_pclk), + .hsci_rstn (hsci_rstn_async), + // register inputs + .hsci_master_run (run_s), + .hsci_cmd_sel (O.hsci_cmd_sel.data), + .hsci_master_xfer_num (O.hsci_xfer_num.data), + .hsci_master_byte_num (O.hsci_byte_num.data), + .hsci_master_addr_size (O.hsci_addr_size.data), + .hsci_master_bram_addr (bram_strt_addr), + .tsize (O.hsci_slave_ahb_tsize.data), + .man_linkup (O.hsci_man_linkup.data), + .man_linkup_word (O.hsci_man_linkup_word.data), + .auto_linkup (O.hsci_auto_linkup.data), + .capture_mode (O.hsci_capture_mode.data), + .capture_word (I.capture_word.data), + .mosi_test_mode (O.hsci_mosi_test_mode.data), + .miso_test_mode (O.hsci_miso_test_mode.data), + .alink_fsm_stall (1'b0), + .alink_fsm_step (1'b0), + .clear_errors (hsci_clear_errors), + .ver_b_na (O.ver_b__na.data), + .mosi_clk_inv (O.mosi_clk_inv.data), + .miso_clk_inv (O.miso_clk_inv.data), + // status signals + .master_done (I.master_done.data), + .master_running (I.master_running.data), + .master_wr_in_prog (I.master_wr_in_prog.data), + .master_rd_in_prog (I.master_rd_in_prog.data), + .enc_fsm (I.enc_fsm.data), + .dec_fsm (I.dec_fsm.data), + .link_active (I.link_active.data), + .alink_fsm (I.alink_fsm.data), + .alink_table (I.alink_table.data), + .alink_txclk_adj (I.alink_txclk_adj.data), + .alink_txclk_inv (I.alink_txclk_inv.data), + .miso_ber_cnt (I.miso_test_ber.data), + .miso_test_lfsr_acq (I.miso_test_lfsr_acq.data), + .error_code (I.slave_error_code.data), + .parity_err (I.parity_error.data), + .unk_instr_err (I.unkown_instruction_error.data), + .link_err_info (I.hsci_link_err_info.data), + .alink_fsm_stalled (), // Output + .txclk_adj_mismatch (I.txclk_adj_mismatch.data), + .txclk_inv_mismatch (I.txclk_inv_mismatch.data), + // tdpram i/f + .mem_addr (bram_addr), + .mem_en (bram_ce), + .mem_din (bram_din), + .mem_we (bram_we), + .mem_dout (bram_dout), + // isedes/oserdes i/f + .menc_clk (hsci_menc_clk), + .menc_data (hsci_mosi_data), + .mdec_data (hsci_miso_data)); + + // Dual Port BRAM for the HSCI Master + xpm_memory_tdpram # ( + // Common module parameters + .MEMORY_SIZE (1048576), //positive integer (32KB * 32) in bits 128K = 1048576, Test= 2048, 64K (65468 bytes) = 523776 + .MEMORY_PRIMITIVE ("auto"), //string; "auto", "distributed", "block" or "ultra"; + .CLOCKING_MODE ("independent_clock"), //string; "common_clock", "independent_clock" + .MEMORY_INIT_FILE ("none"), //string; "none" or ".mem" + .MEMORY_INIT_PARAM ("" ), //string; + .USE_MEM_INIT (1), //integer; 0,1 + .WAKEUP_TIME ("disable_sleep"), //string; "disable_sleep" or "use_sleep_pin" + .MESSAGE_CONTROL (0), //integer; 0,1 + .ECC_MODE ("no_ecc"), //string; "no_ecc", "encode_only", "decode_only" or "both_encode_and_decode" + .AUTO_SLEEP_TIME (0), //Do not Change + .MEMORY_OPTIMIZATION ("true"), + + // Port A module parameters + .WRITE_DATA_WIDTH_A (32), //positive integer + .READ_DATA_WIDTH_A (32), //positive integer + .BYTE_WRITE_WIDTH_A (32), //integer; 8, 9, or WRITE_DATA_WIDTH_A value + .ADDR_WIDTH_A (15), //positive integer + .READ_RESET_VALUE_A ("0"), //string + .READ_LATENCY_A (2), //non-negative integer + .WRITE_MODE_A ("no_change"), //string; "write_first", "read_first", "no_change" + + // Port B module parameters + .WRITE_DATA_WIDTH_B (32), //positive integer + .READ_DATA_WIDTH_B (32), //positive integer + .BYTE_WRITE_WIDTH_B (8), //integer; 8, 9, or WRITE_DATA_WIDTH_B value + .ADDR_WIDTH_B (15), //positive integer + .READ_RESET_VALUE_B ("0"), //vector of READ_DATA_WIDTH_B bits + .READ_LATENCY_B (2), //non-negative integer + .WRITE_MODE_B ("no_change") //string; "write_first", "read_first", "no_change" + ) xpm_memory_tdpram_inst ( + // Common module ports + .sleep (1'b0), + // Port A module ports + .clka (axi_clk), + .rsta (~axi_resetn), + .ena (1'b1), + .regcea (1'b1), + .wea (axi_bram_wr_en), + .addra (axi_bram_addr), + .dina (axi_bram_wdata), + .injectsbiterra (1'b0), + .injectdbiterra (1'b0), + .douta (axi_bram_rdata), + .sbiterra (sbiterra), + .dbiterra (dbiterra), + // Port B module ports + .clkb (hsci_pclk), + .rstb (hsci_rst_sync), + .enb (bram_ce), + .regceb (1'b1), + .web (bram_we), + .addrb (bram_addr), + .dinb (bram_din), + .injectsbiterrb (1'b0), + .injectdbiterrb (1'b0), + .doutb (bram_dout), + .sbiterrb (sbiterrb), + .dbiterrb (dbiterrb)); + + // Convert AXI4 Lite to Yoda register interface + hsci_master_axi_slave #( + .REGMAP_ADDR_WIDTH (REGMAP_ADDR_WIDTH)) + hsci_master_axi_slave ( + .axi_clk (axi_clk), + .axi_resetn (axi_resetn), + .axi (axi), + + .regmap_raddr (hsci_regmap_raddr), + .regmap_rd_en (hsci_regmap_rd_en), + .regmap_waddr (hsci_regmap_waddr), + .regmap_wdata (hsci_regmap_wdata), + .regmap_wr_en (hsci_regmap_wr_en), + .regmap_rdata (hsci_regmap_rdata), + + .bram_addr (axi_bram_addr), + .bram_wdata (axi_bram_wdata), + .bram_rdata (axi_bram_rdata), + .bram_we (axi_bram_wr_en)); + + // Yoda register map + hsci_master_logic #( + .ADDR_WIDTH (REGMAP_ADDR_WIDTH), + .DATA_WIDTH (AXI_DATA_WIDTH) + ) hsci_master_logic ( + .clk (axi_clk), + .srstn (axi_resetn), + .I_rd_addr (hsci_regmap_raddr), + .I_wr_stb (hsci_regmap_wr_en), + .I_wr_addr (hsci_regmap_waddr), + .I_wr_data (hsci_regmap_wdata), + .O_read_data (hsci_regmap_rdata), + .I (I), + .O (O)); + +endmodule diff --git a/library/axi_hsci/hsci_mcore.v b/library/axi_hsci/hsci_mcore.v new file mode 100644 index 0000000000..bc539385da --- /dev/null +++ b/library/axi_hsci/hsci_mcore.v @@ -0,0 +1,299 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module hsci_mcore ( + // globals + input hsci_pclk, + input hsci_rstn, + // register inputs + input hsci_master_run, + input [1:0] hsci_cmd_sel, // 00=write, 01=read, 10=write + input [15:0] hsci_master_xfer_num, + input [16:0] hsci_master_byte_num, + input [2:0] hsci_master_addr_size, // 00=1 byte, 01=2 bytes, 10=3 bytes, 11=4 bytes + input [15:0] hsci_master_bram_addr, + input [1:0] tsize, // 00=byte, 01=halfword, 10=word + input man_linkup, + input [9:0] man_linkup_word, + input auto_linkup, + input capture_mode, + output [9:0] capture_word, + input mosi_test_mode, + input miso_test_mode, + input alink_fsm_stall, + input alink_fsm_step, + input clear_errors, + input ver_b_na, + input mosi_clk_inv, + input miso_clk_inv, + // status sigs + output master_done, + output master_running, + output master_wr_in_prog, + output master_rd_in_prog, + output [3:0] enc_fsm, + output [2:0] dec_fsm, + output link_active, + output [3:0] alink_fsm, + output [15:0] alink_table, + output [3:0] alink_txclk_adj, + output alink_txclk_inv, + output [31:0] miso_ber_cnt, + output miso_test_lfsr_acq, + output [7:0] error_code, + output parity_err, + output unk_instr_err, + output [31:0] link_err_info, + output alink_fsm_stalled, + output txclk_adj_mismatch, + output txclk_inv_mismatch, + // dpram i/f + output [14:0] mem_addr, + output mem_en, + output [31:0] mem_din, + output [3:0] mem_we, + input [31:0] mem_dout, + // iserdes/oserdes i/f + output [7:0] menc_clk, + output [7:0] menc_data, + input [7:0] mdec_data +); + + // hsci_mlink_ctrl internal outputs + wire [9:0] linkup_word; + wire [7:0] lfsr_word; + wire frm_acq; + // wire [31:0] link_err_info; + + // hsci_enc internal outputs + wire menc_pause; + wire [14:0] enc_addr; + wire enc_en; + wire [31:0] enc_data; + wire [3:0] menc_state; + wire xfer_mode; + wire read_op; + wire [16:0] read_byte_num; + + wire xfer_active; + wire menc_val; + wire [9:0] menc_word; + + // hsci_mfrm_det internal outputs + wire frm_det; + wire next_frm_start; + wire [9:0] mdec_sfrm; + // wire [31:0] mdec_ber_cnt; + + // hsci_mdec internal outputs + wire [14:0] dec_addr; + wire dec_en; + wire [31:0] dec_data; + wire [3:0] dec_we; + wire alink_dval; + wire [1:0] rd_tsize; + wire [7:0] alink_data; + wire signal_det; + wire signal_acquire; + wire idle_state; + wire [3:0] tx_clk_adj_rcvd; + wire tx_clk_inv_rcvd; + wire read_done; + wire [31:0] mdec_ber_cnt; + + // linkup control + hsci_mlink_ctrl ctrl0 ( + // global + .hsci_pclk(hsci_pclk), + .rstn(hsci_rstn), + // register sigs + .man_linkup(man_linkup), + .man_linkup_word(man_linkup_word), + .auto_linkup(auto_linkup), + .mosi_test_mode(mosi_test_mode), + .alink_fsm_stall(alink_fsm_stall), + .alink_fsm_step(alink_fsm_step), + .ver_b_na(ver_b_na), + // status sigs + .alink_fsm(alink_fsm), + .alink_table(alink_table), + .alink_txclk_adj(alink_txclk_adj), + .alink_txclk_inv(alink_txclk_inv), + .alink_fsm_stalled(alink_fsm_stalled), + .txclk_adj_mismatch(txclk_adj_mismatch), + .txclk_inv_mismatch(txclk_inv_mismatch), + // menc sigs + .menc_pause(menc_pause), + .lfsr_word(lfsr_word), + // mdec sigs + .signal_det(signal_det), + .signal_acquired(signal_acquired), + .alink_dval(alink_dval), + .alink_data(alink_data), + .idle_state(idle_state), + .frm_acq(frm_acq), + .tx_clk_adj_rcvd(tx_clk_adj_rcvd), + .tx_clk_inv_rcvd(tx_clk_inv_rcvd), + // output + .linkup_word(linkup_word), + .link_active(link_active), + .link_err_info(link_err_info)); + + // drive link_err_info out ber_cnt if auto link fsm = link_err + // assign miso_ber_cnt[31:0] = (alink_fsm == 4'hB) ? link_err_info[31:0]: mdec_ber_cnt[31:0]; + + // hsci_menc + hsci_menc enc0 ( + // globals + .hsci_pclk(hsci_pclk), + .rstn(hsci_rstn), + // register inputs + .hsci_master_run(hsci_master_run), + .hsci_cmd_sel(hsci_cmd_sel), + .hsci_master_xfer_num(hsci_master_xfer_num), + .hsci_master_byte_num(hsci_master_byte_num), + .hsci_master_addr_size(hsci_master_addr_size), + .hsci_master_bram_addr(hsci_master_bram_addr), + .tsize(tsize), + .mosi_test_mode(mosi_test_mode), + .mosi_clk_inv(mosi_clk_inv), + // status sigs + .master_done(master_done), + .master_running(master_running), + .master_wr_in_prog(master_wr_in_prog), + .master_rd_in_prog(master_rd_in_prog), + .enc_fsm(enc_fsm), + // link control sigs + .man_linkup(man_linkup), + .auto_linkup(auto_linkup), + .linkup_word(linkup_word), + .menc_pause(menc_pause), + .lfsr_word(lfsr_word), + // mem i/f + .enc_addr(enc_addr), + .enc_data(enc_data), + .enc_en(enc_en), + // oserdes i/f + .menc_clk(menc_clk), + .menc_data(menc_data), + // i/f to mdec + .menc_state(menc_state), + .xfer_mode(xfer_mode), + .read_op(read_op), + .read_byte_num(read_byte_num), + .read_done(read_done)); + // auto link i/f + // TBD + + // hsci_mfrm_det + hsci_mfrm_det frm_det0 ( + // globals + .hsci_pclk(hsci_pclk), + .rstn(hsci_rstn), + // iserdes i/f + .mdec_data(mdec_data), + // inputs from mdec + .dec_fsm(dec_fsm), + .rd_tsize(rd_tsize), + // register i/f + .capture_mode(capture_mode), + .capture_word(capture_word), + .miso_test_mode(miso_test_mode), + .miso_ber_cnt(miso_ber_cnt), + .miso_test_lfsr_acq(miso_test_lfsr_acq), + .miso_clk_inv(miso_clk_inv), + // link control sigs + .man_linkup(man_linkup), + .auto_linkup(auto_linkup), + .alink_fsm(alink_fsm), + .frm_acq(frm_acq), + // i/f to mdec + .frm_det(frm_det), + .next_frm_start(next_frm_start), + .mdec_sfrm(mdec_sfrm), + .mdec_val(mdec_val)); + + // hsci_mdec + hsci_mdec dec0 ( + // globals + .hsci_pclk(hsci_pclk), + .rstn(hsci_rstn), + // inputs from mfrm_det + .frm_det(frm_det), + .next_frm_start(next_frm_start), + .mdec_sfrm(mdec_sfrm), + .mdec_val(mdec_val), + .rd_tsize(rd_tsize), + // mem i/f + .dec_addr(dec_addr), + .dec_data(dec_data), + .dec_en(dec_en), + .dec_we(dec_we), + // register i/f + .miso_test_mode(miso_test_mode), + .dec_fsm(dec_fsm), + .error_code(error_code), + .clear_errors(clear_errors), + .parity_err(parity_err), + .unk_instr_err(unk_instr_err), + // link control sigs + .ver_b_na(ver_b_na), + .man_linkup(man_linkup), + .auto_linkup(auto_linkup), + .alink_fsm(alink_fsm), + .alink_dval(alink_dval), + .alink_data(alink_data), + .signal_det(signal_det), + .signal_acquired(signal_acquired), + .idle_state(idle_state), + .tx_clk_adj_rcvd(tx_clk_adj_rcvd), + .tx_clk_inv_rcvd(tx_clk_inv_rcvd), + // i/f to menc + .menc_state(menc_state), + .xfer_mode(xfer_mode), + .read_op(read_op), + .read_byte_num(read_byte_num), + .read_done(read_done)); + + // dpram mux, default reads to hsci_enc + assign mem_addr = (dec_en == 1'b1) ? dec_addr: enc_addr; + assign mem_en = enc_en | dec_en; + assign enc_data = mem_dout; + assign mem_din = dec_data; + assign mem_we = dec_we; + +endmodule diff --git a/library/axi_hsci/hsci_mdec.sv b/library/axi_hsci/hsci_mdec.sv new file mode 100644 index 0000000000..d302ae85e0 --- /dev/null +++ b/library/axi_hsci/hsci_mdec.sv @@ -0,0 +1,498 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module hsci_mdec ( + // globals + input hsci_pclk, + input rstn, + // mfrm_det i/o + input frm_det, + input next_frm_start, + input [9:0] mdec_sfrm, + input mdec_val, + output reg [1:0] rd_tsize, + // mem i/f + output reg [14:0] dec_addr, + output reg [31:0] dec_data, + output reg dec_en, + output reg [3:0] dec_we, + // reg sigs + input miso_test_mode, + output [2:0] dec_fsm, + output reg [7:0] error_code, + input clear_errors, + output reg parity_err, + output reg unk_instr_err, + // link control sigs + input ver_b_na, + input man_linkup, + input auto_linkup, + input [3:0] alink_fsm, + output reg alink_dval, + output reg [7:0] alink_data, + output reg signal_det, + output reg signal_acquired, + output idle_state, + output reg [3:0] tx_clk_adj_rcvd, + output reg tx_clk_inv_rcvd, + // i/f to menc + input [3:0] menc_state, + input xfer_mode, + input read_op, + input [16:0] read_byte_num, + output reg read_done +); + + typedef enum reg [2:0] { D_IDLE = 3'b000, + D_INSTR = 3'b001, + D_RINDEX = 3'b010, + D_RDATA = 3'b011, + D_ERROR = 3'b100, + D_LINKUP = 3'b101, + D_TMODE = 3'b110, + D_MERR = 3'b111 + } state; + + + localparam READ_ACK = 4'b1010; + localparam ERR_MSG = 4'b1100; + localparam ALINK = 4'b0101; + + // internal variables + state dec_state; + + wire [7:0] mdec_word; + wire mdec_par; + wire mdec_cont; + + reg p_calc; + + reg [16:0] read_byte_cnt; + reg read_pending; + reg read_done_d; + reg [31:0] rd_index; + reg [1:0] rd_index_cnt; + reg [31:0] rd_data; + reg [1:0] rd_data_cnt; + reg store_data; + reg [3:0] store_we; + reg new_dec_addr; + + reg [4:0] idle_cnt; + + assign mdec_word = mdec_sfrm[9:2]; + assign mdec_par = mdec_sfrm[1]; + assign mdec_cont = mdec_sfrm[0]; + + assign p_calc = mdec_word[7] + mdec_word[6] + mdec_word[5] + mdec_word[4] + mdec_word[3] + mdec_word[2] + mdec_word[1] + mdec_word[0] + mdec_cont; + // during active xfer, check parity + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + parity_err <= 1'b0; + else begin + if (mdec_par ^ p_calc) + parity_err <= 1'b1; + else if (clear_errors == 1'b1) + parity_err <= 1'b0; + else + parity_err <= parity_err; + end + end + + + // set signal_det if auto_linkup '1' and frm_det '1' + // once signal_det set, leave on until auto_linkup goes low + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + signal_det <= 1'b0; + else begin + if (auto_linkup == 1'b1) begin + if (frm_det == 1'b1) + signal_det <= 1'b1; + end + else + signal_det <= 1'b0; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign idle_state = ( (dec_state == D_IDLE) & (auto_linkup == 1'b1) ); + + // decode FSM + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + dec_state <= D_IDLE; + else begin + case(dec_state) + // + D_IDLE: begin + if (mdec_val == 1'b1) begin + // Don't try and decode INSTR if in man linkup mode, only ALINK + if (miso_test_mode == 1'b1) + dec_state <= D_TMODE; + else if (man_linkup == 1'b1) + dec_state <= D_IDLE; + else if (auto_linkup == 1'b1) begin + if ((mdec_word[7] == 1'b1) & (mdec_word[6:3] == ALINK)) // start bit and instr=ALINK + dec_state <= D_LINKUP; + else + dec_state <= D_IDLE; + end else begin + if (mdec_word[7] == 1'b1) begin // start bit + if (mdec_word[6:3] == READ_ACK) + dec_state <= D_RINDEX; + else if (mdec_word[6:3] == ERR_MSG) + dec_state <= D_ERROR; + else + dec_state <= D_MERR; + end + else + dec_state <= D_IDLE; + end // else: !if( (auto_linkup == 1'b1) | (man_linkup == 1'b1) ) + end else // if (mdec_val == 1'b1) + dec_state <= D_IDLE; + end // case: D_IDLE + + D_INSTR: begin + if (mdec_val == 1'b1) begin + // Don't try and decode INSTR if in linkup mode, only ALINK + if (mdec_word[7] == 1'b1) begin // start bit + if (mdec_word[6:3] == READ_ACK) + dec_state <= D_RINDEX; + else if (mdec_word[6:3] == ERR_MSG) + dec_state <= D_ERROR; + else + dec_state <= D_MERR; + end + end // if (mdec_val == 1'b1) + end // case: D_INSTR + + D_RINDEX: begin + if (mdec_val == 1'b1) begin + if (mdec_cont == 1'b0) + dec_state <= D_RDATA; + else + dec_state <= D_RINDEX; + end + end + + D_RDATA: begin + if (mdec_val == 1'b1) begin + if (mdec_cont == 1'b0) begin + if ((next_frm_start == 1'b0)) // no start bit on next incoming frame + dec_state <= D_IDLE; + else + dec_state <= D_IDLE; // handles back-to-back incoming frames + end // if (mdec_cont == 1'b0) + else + dec_state <= dec_state; + end + end + + D_LINKUP: begin + if (mdec_val == 1'b1) begin + if (mdec_cont == 1'b0) + dec_state <= D_IDLE; + else + dec_state <= D_LINKUP; + end + end + + D_ERROR: begin// go back to IDLE + if (mdec_val == 1'b1) + dec_state <= D_IDLE; + else + dec_state <= D_ERROR; + end + + D_TMODE: begin + if (miso_test_mode == 1'b1) + dec_state <= D_TMODE; + else + dec_state <= D_IDLE; + end + + D_MERR: begin // go back to IDLE + if (mdec_val == 1'b1) + dec_state <= D_IDLE; + else + dec_state <= D_MERR; + end + + default: begin + dec_state <= D_IDLE; + end + endcase // unique case (dec_state) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + rd_index <= 32'h0; + rd_data <= 32'h0; + + rd_index_cnt <= 2'b00; + rd_data_cnt <= 2'b00; + store_data <= 1'b0; + store_we <= 4'h0; + + alink_dval <= 1'b0; + alink_data <= 8'h00; + signal_acquired <= 1'b0; + + tx_clk_adj_rcvd <= 4'h0; + tx_clk_inv_rcvd <= 1'b0; + end else begin + case(dec_state) + D_IDLE: begin + rd_index <= 32'h0; + rd_data <= 32'h0; + + rd_index_cnt <= 2'b00; + rd_data_cnt <= (read_done == 1'b1) ? 2'b00: rd_data_cnt; + store_data <= 1'b0; + store_we <= 4'h0; + + if (auto_linkup == 1'b1) begin + if (ver_b_na == 1'b1) begin + if ((mdec_word[7] == 1'b1) & (mdec_word[6:3] == ALINK)) begin + tx_clk_adj_rcvd <= {mdec_word[1:0], mdec_par, mdec_cont}; + tx_clk_inv_rcvd <= mdec_word[2]; + end + end else begin + tx_clk_adj_rcvd <= 4'h0; + tx_clk_inv_rcvd <= 1'b0; + end // else: !if(ver_b_na == 1'b1) + end else begin // if (auto_linkup == 1'b1) + if (frm_det == 1'b1) + rd_tsize <= mdec_word[1:0]; + end // else: !if(auto_linkup == 1'b1) + + alink_dval <= 1'b0; + alink_data <= 8'h00; + end // case: D_IDLE + + D_INSTR: begin + rd_index_cnt <= 2'b00; + // rd_data_cnt <= 2'b00; + store_data <= 1'b0; + store_we <= 4'h0; + end + + D_RINDEX: begin + if (mdec_val == 1'b1) begin + case (rd_index_cnt) + 2'b00: rd_index <= {rd_index[31:8], mdec_word[7:0]}; + 2'b01: rd_index <= {rd_index[31:16], mdec_word[7:0], rd_index[7:0]}; + 2'b10: rd_index <= {rd_index[31:24], mdec_word[7:0], rd_index[15:0]}; + 2'b11: rd_index <= {mdec_word[7:0], rd_index[23:0]}; + endcase // case (rd_index_cnt) + rd_index_cnt <= (rd_index_cnt == 2'b11) ? rd_index_cnt: rd_index_cnt + 2'b01; + end + end // case: D_RINDEX + + D_RDATA: begin + if (mdec_val == 1'b1) begin + rd_index_cnt <= 2'b00; + + case(rd_data_cnt) + 2'b00: begin + rd_data <= {24'h0, mdec_word[7:0]}; + store_data <= 1'b1; + store_we <= 4'h1; + end + + 2'b01: begin + rd_data <= {16'h0, mdec_word[7:0], 8'h0}; + store_data <= 1'b1; + store_we <= 4'h2; + end + + 2'b10: begin + rd_data <= {8'h0, mdec_word[7:0], 16'h0}; + store_data <= 1'b1; + store_we <= 4'h4; + end + + 2'b11: begin + rd_data <= {mdec_word[7:0], 24'h0}; + store_data <= 1'b1; + store_we <= 4'h8; + end + endcase // case (rd_data_cnt) + rd_data_cnt <= rd_data_cnt + 2'b01; + end else begin // if (mdec_val == 1'b1) + store_data <= 1'b0; + rd_data_cnt <= rd_data_cnt; + rd_data <= rd_data; + end // else: !if(mdec_val == 1'b1) + end // case: D_RDATA + + D_LINKUP: begin + signal_acquired <= 1'b1; + if (mdec_val == 1'b1) begin + alink_dval <= 1'b1; + alink_data <= mdec_word[7:0]; + end else + alink_dval <= 1'b0; + end + + D_ERROR: begin + end + + D_MERR: begin + end + + default: begin + end + endcase // unique case (dec_state) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // tally read bytes + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + read_pending <= 1'b0; + read_byte_cnt <= 17'h00000; + read_done_d <= 1'b0; + read_done <= 1'b0; + end else begin + read_done_d <= read_done; + + if (read_op == 1'b1) begin + read_pending <= 1'b1; + read_byte_cnt <= 17'h00000; + read_done <= 1'b0; + end else if (store_data == 1'b1) begin + read_byte_cnt <= read_byte_cnt + 17'h00001; + end else if (read_byte_cnt > read_byte_num) begin + read_pending <= 1'b0; + read_byte_cnt <= 17'h00000; + read_done <= 1'b1; + end else if (read_done_d == 1'b1) begin // keep read_done high fr 2 cycles + read_done <= 1'b0; + end else begin + read_pending <= read_pending; + read_byte_cnt <= read_byte_cnt; + read_done <= read_done; + end // else: !if(store_data == 1'b1) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // set-up unkn_instr + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + unk_instr_err <= 1'b0; + else begin + if ((dec_state == D_MERR) & (mdec_val == 1'b1)) + unk_instr_err <= 1'b1; + else if (clear_errors == 1'b1) + unk_instr_err <= 1'b0; + else + unk_instr_err <= unk_instr_err; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + + // set-up error_code + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + error_code <= 1'b0; + else begin + if ((dec_state == D_ERROR) & (mdec_val == 1'b1)) + error_code <= mdec_word[7:0]; + else if (clear_errors == 1'b1) + error_code <= 8'h00; + else + error_code <= error_code; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + + // dpram i/f + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + dec_en <= 1'b0; + dec_we <= 4'h0; + dec_addr <= 15'h0000; + dec_data <= 32'h0; + new_dec_addr <= 1'b0; + end else begin + if (store_data == 1'b1) begin + dec_en <= 1'b1; + dec_we <= store_we; + dec_addr <= dec_addr; + dec_data <= rd_data; + if (dec_we[0] == 1'b1) + new_dec_addr <= 1'b0; + end else begin + if (menc_state == 4'b0000) begin // menc_state = IDLE + dec_en <= 1'b0; + dec_we <= 4'h0; + dec_addr <= 15'h0000; + dec_data <= 32'h0; + end else begin + dec_en <= 1'b0; + dec_we <= 4'h0; + dec_addr <= dec_addr; + dec_data <= 32'h0; + end // else: !if(dec_state == D_IDLE) + end // else: !if(store_data == 1'b1) + + if (dec_we[3] == 1'b1) begin + dec_addr <= dec_addr + 15'h0001; + new_dec_addr <= 1'b1; + end else if (xfer_mode == 1'b1) begin // dis-contiguous mode + if ((read_done == 1'b1) & (read_done_d == 1'b1)) begin + if (new_dec_addr == 1'b1) + new_dec_addr <= 1'b0; + else + dec_addr <= dec_addr + 15'h0001; + end + end else begin + if ((read_done == 1'b1) & (read_done_d == 1'b1)) begin + dec_addr <= 15'h0000; + new_dec_addr <= 1'b0; + end + end + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // set-up status sigs + assign dec_fsm = dec_state; + +endmodule diff --git a/library/axi_hsci/hsci_menc.sv b/library/axi_hsci/hsci_menc.sv new file mode 100644 index 0000000000..d3a8765903 --- /dev/null +++ b/library/axi_hsci/hsci_menc.sv @@ -0,0 +1,604 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module hsci_menc ( + // globals + input hsci_pclk, + input rstn, + // Reg inputs + input hsci_master_run, + input [1:0] hsci_cmd_sel, + input [15:0] hsci_master_xfer_num, + input [16:0] hsci_master_byte_num, + input [2:0] hsci_master_addr_size, + input [15:0] hsci_master_bram_addr, + input [1:0] tsize, + input mosi_test_mode, + input mosi_clk_inv, + // status sigs for regmap + output master_done, + output master_running, + output reg master_wr_in_prog, + output reg master_rd_in_prog, + output [3:0] enc_fsm, + // link control sigs + input man_linkup, + input auto_linkup, + input [9:0] linkup_word, + output menc_pause, + input [7:0] lfsr_word, + // mem interfac + output reg [14:0] enc_addr, + input [31:0] enc_data, // Note: this is data read from the memory and actually write data to the slave + output reg enc_en, + // oserdes interfac + output reg [7:0] menc_clk, + output reg [7:0] menc_data, + // i/f with mdec + output [3:0] menc_state, + output xfer_mode, + output reg read_op, + output reg [16:0] read_byte_num, + input read_done +); + + typedef enum reg [3:0] { S_IDLE = 4'b0000, + S_START1 = 4'b0001, + S_START2 = 4'b0010, + S_START3 = 4'b0011, + SEND_INSTR = 4'b0100, + SEND_ADDR = 4'b0101, + SEND_MASK = 4'b0110, + SEND_DATA = 4'b0111, + SEND_NUM = 4'b1000, + S_READOP = 4'b1001, + SEND_LINKUP = 4'b1010 + } state; + + state mstate; + state prev_state; + + localparam MWRITE_OP = 4'b0110; + localparam MREAD_OP = 4'b1000; + localparam MRMW_OP = 4'b1001; + localparam LINKUP_OP = 4'b1001; + + localparam LINKUP_SFRM = 5'b1_0101; + + reg [1:0] m_xfer_type; // hsci_cmd_sel: 0=write, 1=read, 2=rmw + reg [15:0] m_xfer_num; // hsci_master_xfer_num + reg [15:0] m_xfer_cnt; + reg [16:0] m_byte_num; // hsci_master_byte_num + reg [16:0] m_byte_cnt; + reg [2:0] m_addr_size; + + reg m_xfer_mode; // 0=continuous, 1=dis-contigous + reg [3:0] m_instr; + reg [1:0] m_tsize; + reg [1:0] maddr_cnt; + reg [1:0] mdata_cnt; + reg [1:0] mask_cnt; + reg [1:0] byte_num_size; + reg active_wr; + + reg [31:0] wr_addr; + reg [31:0] wr_mask; + reg [31:0] wr_data; + reg [9:0] menc_word; + reg [2:0] menc_word_cntr; + wire pbit; + reg [7:0] cur_buf, next_buf; + // wire menc_pause; + + // linkup variables + reg [2:0] linkup_cntr; + reg [7:0] lfsr_out; + reg lfsr_en; + reg [2:0] txclk_ctrl; + + // FIFO variables + reg [31:0] fmem [0:7]; + reg [2:0] wr_ptr, rd_ptr; + reg mem_fetch, mem_fetch_d1, mem_fetch_d2; + wire full; + wire empty; + + // status sigs for regmap + assign menc_state = mstate; + assign xfer_mode = m_xfer_mode; // 0=continuous, 1=dis-contiguous + + + // build 8 element FIFO to accomodate dpram interface + // this is a synchronize FIFO + // write side should ALWAYS write faster than read + // Once started write side will write until full + // NOTE: the write side will end up loadibg invalid values, but the FSM should retreat back to S_IDLE before those values are read + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + fmem[0] <= 32'h0; + fmem[1] <= 32'h0; + fmem[2] <= 32'h0; + fmem[3] <= 32'h0; + fmem[4] <= 32'h0; + fmem[5] <= 32'h0; + fmem[6] <= 32'h0; + fmem[7] <= 32'h0; + wr_ptr <= 3'b000; + enc_addr <= 15'h0000; + mem_fetch <= 1'b0; + mem_fetch_d1 <= 1'b0; + mem_fetch_d2 <= 1'b0; + end else begin + mem_fetch_d2 <= mem_fetch_d1; + mem_fetch_d1 <= mem_fetch; + + if (hsci_master_run == 1'b1) begin + enc_addr <= hsci_master_bram_addr; + mem_fetch <= 1'b1; + end else if (master_running == 1'b1) begin + if (empty == 1'b1) begin + enc_addr <= enc_addr + 15'h0001; + mem_fetch <= 1'b1; + end else begin + enc_addr <= enc_addr; + mem_fetch <= 1'b0; + end + + if (mem_fetch_d2 == 1'b1) begin + fmem[wr_ptr] <= enc_data; + wr_ptr <= wr_ptr + 3'b001; + end + end else begin// if (master_rinning == 1'b1) + wr_ptr <= 3'b000; + enc_addr <= 15'h0000; + mem_fetch <= 1'b0; + mem_fetch_d1 <= 1'b0; + mem_fetch_d2 <= 1'b0; + end // else: !if(master_rinning == 1'b1) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign full = ((( wr_ptr + 3'b001) == rd_ptr) | (( wr_ptr + 3'b010) == rd_ptr) | (( wr_ptr + 3'b011) == rd_ptr)); + assign empty = ((wr_ptr == rd_ptr) | (wr_ptr == (rd_ptr + 3'b001)) | (wr_ptr == (rd_ptr +3'b010)) | (wr_ptr == (rd_ptr +3'b011))); + + // FSM for access + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + mstate <= S_IDLE; + prev_state <= S_IDLE; + end else begin + unique case (mstate) + // remain in S_IDLE until hsci_master_run detected + S_IDLE: begin + if ((man_linkup == 1'b1) | (auto_linkup == 1'b1)) + mstate <= SEND_LINKUP; + else if (hsci_master_run == 1'b1) + mstate <= S_START1; + else + mstate <= S_IDLE; + end + + // wait for FIFO to catch up + S_START1: begin + mstate <= S_START2; + end + + // wait for FIFO to catch up + S_START2: begin + mstate <= S_START3; + end + + // wait for FIFO to catch up + S_START3: begin + mstate <= SEND_INSTR; + end + + // Access always begins with instruction word + // Gated by parser rdy + SEND_INSTR: begin + if (menc_pause != 1'b1) + mstate <= SEND_ADDR; + else + mstate <= SEND_INSTR; + end + + // For write, read or rmw operation, SEND_ADDR after SEND_INSTR + // Gated by menc_pause + // For Write_op proceed to SEND_DATA + // For RMW_op proceed to SEND_MASK + // For Read_req_op proced to SNED_NUM + SEND_ADDR: begin + if (menc_pause != 1'b1) begin + if (maddr_cnt == 2'b00) begin + if (m_instr == MWRITE_OP) + mstate <= SEND_DATA; + else if (m_instr == MRMW_OP) + mstate <= SEND_DATA; // write and rmw ops are treated the same + else + mstate <= SEND_NUM; + end else + mstate <= SEND_ADDR; + end else + mstate <= SEND_ADDR; + end // case: SEND_ADDR + + // RMW operation + // During Read-Modify-Write, the FSM will toggle between SEND_MASK and SEND_DATA + SEND_MASK: begin + if (menc_pause != 1'b1) begin + if (mask_cnt == 2'b00) + mstate <= SEND_DATA; + else + mstate <= SEND_MASK; + end else + mstate <= SEND_MASK; + end // case: SEND_MASK + + // Write or RMW Operation + // Gated by menc_pause + // Once all data sent, return to S_IDLE + SEND_DATA: begin + if (menc_pause != 1'b1) begin + if ((m_xfer_cnt == m_xfer_num) && (m_byte_cnt == m_byte_num)) + mstate <= S_IDLE; + else begin + if (m_byte_cnt == m_byte_num) + mstate <= SEND_INSTR; + else + mstate <= SEND_DATA; + end + end // if (menc_pause != 1'b1) + end // case: SEND_DATA + + // For Read_req_op, SEND_ADDR -> SEND_NUM + // Gated by menc_pause + // once complete, return to S_IDLE + SEND_NUM: begin + if (menc_pause != 1'b1) begin + if (byte_num_size == 2'b00) + mstate <= S_READOP; + else + mstate <= SEND_NUM; + end + end + + S_READOP: begin + if (menc_pause != 1'b1) begin + if (read_done == 1'b1) begin + if (m_xfer_mode == 1'b0) // continuous read + mstate <= S_IDLE; + else begin // discontiguous read, need to check xfer_cnt + if (m_xfer_cnt == m_xfer_num) + mstate <= S_IDLE; + else + mstate <= SEND_INSTR; + end + end // if (read_done == 1'b1) + else + mstate <= S_READOP; + end // if (menc_pause != 1'b1) + end // case: S_READOP + + SEND_LINKUP: begin + if ((man_linkup == 1'b1) | (auto_linkup == 1'b1)) + mstate <= SEND_LINKUP; + else + mstate <= S_IDLE; + end + + default: begin + mstate <= S_IDLE; + end + endcase // unique case (mstate) + prev_state <= mstate; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + + // Use FSM to determine action + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + // output to mparser + menc_word <= 10'h000; + + // internals + m_xfer_type <= 2'b00; + m_xfer_mode <= 1'b0; + m_xfer_num <= 16'h0000; + m_xfer_cnt <= 16'h0000; + m_byte_num <= 17'h0000; + m_byte_cnt <= 17'h0000; + m_addr_size <= 3'b000; + m_instr <= 4'h0; + m_tsize <= 3'b000; + maddr_cnt <= 2'b00; // needed for 16 bit & 32 bit addresses + mdata_cnt <= 2'b00; // needed for 16 bit and 32 bit data + mask_cnt <= 2'b00; + byte_num_size <= 2'b00; + + active_wr <= 1'b0; + wr_addr <= 32'h0; + wr_data <= 32'h0; + wr_mask <= 32'h0; + + read_op <= 1'b0; + read_byte_num <= 17'h0000; + + // memory access always on + enc_en <= 1'b1; + rd_ptr <= 3'b000; + end else begin + case (mstate) + S_IDLE: begin + menc_word <= 10'h000; + + if (hsci_master_run) begin // At beginning of operation, load info + m_xfer_type <= hsci_cmd_sel; + m_xfer_mode <= (hsci_master_xfer_num == 16'h0001) ? 1'b0: 1'b1; + m_xfer_num <= hsci_master_xfer_num - 1; + m_xfer_cnt <= 16'h0; + m_addr_size <= hsci_master_addr_size; + m_instr <= (hsci_cmd_sel[1:0] == 2'b00) ? MWRITE_OP: + (hsci_cmd_sel[1:0] == 2'b01) ? MREAD_OP: + (hsci_cmd_sel[1:0] == 2'b10) ? MRMW_OP: + LINKUP_OP; + m_byte_num <= hsci_master_byte_num - 1; + m_byte_cnt <= 17'h0000; + read_byte_num <= hsci_master_byte_num - 1; + maddr_cnt <= hsci_master_addr_size[1:0]; + byte_num_size <= (hsci_master_byte_num[16:8] == 8'h00) ? 2'b00: + (hsci_master_byte_num[16] == 1'b0) ? 2'b01: + 2'b10; + + m_tsize <= tsize; + + // start memory access + enc_en <= 1'b1; + end else begin// if (hsci_master_run) + m_xfer_type <= 2'b00; + m_xfer_mode <= 1'b0; + m_xfer_num <= 16'h0000; + m_xfer_cnt <= 16'h0000; + m_instr <= 3'b000; + m_addr_size <= 3'b000; + m_tsize <= 2'b00; + maddr_cnt <= 2'b00; + mdata_cnt <= 2'b00; + mask_cnt <= 2'b00; + byte_num_size <= 2'b00; + + active_wr <= 1'b0; + wr_addr <= 32'h0; + wr_data <= 32'h0; + wr_mask <= 32'h0; + + read_op <= 1'b0; + read_byte_num <= 17'h0000; + + // dpram i/f + enc_en <= 1'b1; + rd_ptr <= 3'b000; + end // else: !if(hsci_master_run) + end // case: S_IDLE + + SEND_INSTR: begin + m_byte_cnt <= 17'h0; + mdata_cnt <= 2'b00; + maddr_cnt <= m_addr_size; + + if (menc_pause != 1'b1) begin + // drive out instr + menc_word[9] <= 1'b1; // Start bit + menc_word[8:5] <= m_instr; // Instruction + menc_word[4:2] <= {1'b0, m_tsize}; // Tsize + menc_word[1] <= 1'b0; // Parity generation takes place in mparse + menc_word[0] <= 1'b0; + + // fifo i/f + // addr needs to be reformatted according to addr_size + case(hsci_master_addr_size) + 2'b00: wr_addr <= {24'h0, fmem[rd_ptr][7:0]}; + 2'b01: wr_addr <= {16'h0, fmem[rd_ptr][7:0], fmem[rd_ptr][15:8]}; + 2'b10: wr_addr <= {8'h0, fmem[rd_ptr][7:0], fmem[rd_ptr][15:8], fmem[rd_ptr][23:16]}; + 2'b11: wr_addr <= {fmem[rd_ptr][7:0], fmem[rd_ptr][15:8], fmem[rd_ptr][23:16], fmem[rd_ptr][31:24]}; + endcase // case (addr_size) + rd_ptr <= rd_ptr + 3'b001; + end else begin + menc_word <= menc_word; // hold menc_word + end // else: !if(menc_pause == 1'b1) + end // case: SEND_INSTR + + // Drive out a byte, 2 bytes or 4 bytes of address depending on addr_size + // need to wait for menc_pause + SEND_ADDR: begin + if (menc_pause != 1'b1) begin + // drive out addr + case (maddr_cnt) + 2'b11: begin menc_word <= {wr_addr[31:24], 1'b0, 1'b1}; end + 2'b10: begin menc_word <= {wr_addr[23:16], 1'b0, 1'b1}; end + 2'b01: begin menc_word <= {wr_addr[15:8], 1'b0, 1'b1}; end + 2'b00: begin menc_word <= {wr_addr[7:0], 1'b0, 1'b0}; end + endcase // case (maddr_cnt) + maddr_cnt <= (maddr_cnt == 2'b00) ? maddr_cnt: maddr_cnt - 1; + + // read next fifo location if maddr_cnt = 0 + if (maddr_cnt == 2'b00) begin + if ((m_instr == MWRITE_OP) | (m_instr == MRMW_OP)) begin + wr_data <= fmem[rd_ptr]; + rd_ptr <= rd_ptr + 3'b001; + end + end + end else begin // if ((menc_pause == 1'b1) && (menc_val == 1'b0)) + menc_word <= menc_word; + end // else: !if((menc_pause == 1'b1) && (menc_val == 1'b0)) + end // case: SEND_ADDR + + // send out data + // depending on tsize, send out byte, halfword or words with mdata_cnt keeping track + // m_daddr is incremented and compared to m_dmax, when m_daddr == m_dmax, dara xfer conplete + SEND_DATA: begin + if (menc_pause != 1'b1) begin + case (mdata_cnt) + 2'b00: menc_word[9:2] <= wr_data[7:0]; + 2'b01: menc_word[9:2] <= wr_data[15:8]; + 2'b10: menc_word[9:2] <= wr_data[23:16]; + 2'b11: menc_word[9:2] <= wr_data[31:24]; + endcase // case (mdata_cnt) + menc_word[1] <= 1'b0; + menc_word[0] <= (m_byte_num == m_byte_cnt) ? 1'b0: 1'b1; + m_byte_cnt <= m_byte_cnt + 16'h0001; + mdata_cnt <= mdata_cnt + 2'b01; + + // incr xfer_cnt if byte_num = byte_cnt + if (m_byte_cnt == m_byte_num) + m_xfer_cnt <= m_xfer_cnt + 1; + + // Dont fetch data if in dis-contiguous mode + if ((mdata_cnt == 2'b11) & (m_byte_cnt != m_byte_num)) begin + wr_data <= fmem[rd_ptr]; + rd_ptr <= rd_ptr + 3'b001; + end + end else begin // if (menc_pause == 1'b1) + menc_word <= menc_word; + end + end // case: SEND_DATA + + // For read op, send out number of bytes to read + SEND_NUM: begin + if (menc_pause != 1'b1) begin + case(byte_num_size) + 2'b10: begin + menc_word <= {m_byte_num[7:0], 1'b0, 1'b1}; + m_byte_num <= {8'h00, m_byte_num[16:8]}; + end + + 2'b01: begin + menc_word <= {m_byte_num[7:0], 1'b0, 1'b1}; + m_byte_num <= {8'h00, m_byte_num[16:8]}; + end + + 2'b00: begin + menc_word <= {m_byte_num[7:0], 1'b0, 1'b0}; + read_op <= 1'b1; + end + endcase // case (m_num_bytes_cnt) + byte_num_size <= (byte_num_size == 2'b00) ? 2'b00: byte_num_size - 2'b01; + end else begin // if (menc_pause == 1'b1) + menc_word <= menc_word; + end + end // case: SEND_NUM + + S_READOP: begin + read_op <= 1'b0; + menc_word <= 10'h0; + + if (menc_pause != 1'b1) begin + if ((m_xfer_mode == 1'b1) & (read_done == 1'b1)) + m_xfer_cnt <= m_xfer_cnt + 16'h0001; + end + end + + SEND_LINKUP: begin + if (menc_pause != 1'b1) + menc_word <= linkup_word; + end // case: SEND_LINKUP + endcase // case (mstate) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // set-up menc_word_cntr + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + menc_word_cntr <= 3'b000; + else begin + if (prev_state != S_IDLE) + menc_word_cntr <= (menc_word_cntr == 3'b100) ? 3'b000: menc_word_cntr + 3'b001; + else + menc_word_cntr <= 3'b000; + end + end + + // parser + assign pbit = (mstate != SEND_LINKUP) ? menc_word[9] + menc_word[8] + menc_word[7] + menc_word[6] + menc_word[5] + menc_word[4] + menc_word[3] + menc_word[2] + menc_word[0] + : menc_word[1]; + + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + cur_buf <= 8'h00; + next_buf <= 8'h00; + end else begin + case(menc_word_cntr) + 3'b000: begin cur_buf <= menc_word[9:2]; next_buf <= {6'h0, pbit, menc_word[0]}; end + 3'b001: begin cur_buf <= {next_buf[1:0], menc_word[9:4]}; next_buf <= {4'h0, menc_word[3:2], pbit, menc_word[0]}; end + 3'b010: begin cur_buf <= {next_buf[3:0], menc_word[9:6]}; next_buf <= {2'h0, menc_word[5:2], pbit, menc_word[0]}; end + 3'b011: begin cur_buf <= {next_buf[5:0], menc_word[9:8]}; next_buf <= { menc_word[7:2], pbit, menc_word[0]}; end + 3'b100: begin cur_buf <= next_buf[7:0]; next_buf <= 8'h00; end + endcase // case (menc_word_cntr) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign menc_pause = (menc_word_cntr == 3'b011); + assign menc_clk = (mosi_clk_inv == 1'b0) ? 8'h55: 8'hAA; + assign menc_data = (mosi_test_mode == 1'b1) ? lfsr_word: cur_buf; + + // set-up status sigs + assign master_done = (mstate == S_IDLE); + assign master_running = !(mstate == S_IDLE); + assign enc_fsm = mstate; + + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + master_wr_in_prog <= 1'b0; + master_wr_in_prog <= 1'b0; + end else begin + if ((mstate == S_START1) & ((m_instr == MWRITE_OP) | (m_instr == MRMW_OP))) + master_wr_in_prog <= 1'b1; + else if (mstate == S_IDLE) + master_wr_in_prog <= 1'b0; + else + master_wr_in_prog <= master_wr_in_prog; + + if ((mstate == S_START1) & (m_instr == MREAD_OP)) + master_rd_in_prog <= 1'b1; + else if (mstate == S_IDLE) + master_rd_in_prog <= 1'b0; + else + master_rd_in_prog <= master_wr_in_prog; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + +endmodule diff --git a/library/axi_hsci/hsci_mfrm_det.v b/library/axi_hsci/hsci_mfrm_det.v new file mode 100644 index 0000000000..bc115593d2 --- /dev/null +++ b/library/axi_hsci/hsci_mfrm_det.v @@ -0,0 +1,291 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module hsci_mfrm_det ( + // globals + input hsci_pclk, + input rstn, + // input from iserdes + input [7:0] mdec_data, + // inputs from mdec + input [2:0] dec_fsm, + input [1:0] rd_tsize, + // reg sigs + input capture_mode, + output reg [9:0] capture_word, + input miso_test_mode, + output miso_test_lfsr_acq, + output reg [31:0] miso_ber_cnt, + input miso_clk_inv, + // link control sigs + input man_linkup, + input auto_linkup, + input [3:0] alink_fsm, + input frm_acq, + // i/f to mdec + output reg frm_det, + output next_frm_start, + output reg [9:0] mdec_sfrm, + output mdec_val +); + + localparam READ_ACK = 4'b1010; + localparam ALINK = 4'b0101; + + localparam DEC_IDLE = 3'b000; + localparam DEC_RDATA = 3'b011; + localparam DEC_ERROR = 3'b100; + localparam DEC_MERR = 3'b111; + localparam DEC_LINKUP = 3'b111; + + reg [17:0] ibuf; + reg [3:0] frm_align; + wire [9:0] tmp_frm[0:7]; + + reg [14:0] lfsr_sreg; + reg [2:0] lfsr_cnt; + wire [7:0] lfsr_next; + reg [2:0] idle_cnt; + reg [1:0] frm_acq_cnt; + reg [6:0] mdec_data_d1; + + // count idle states + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + idle_cnt <= 3'b000; + else begin + if ((auto_linkup == 1'b1) & (dec_fsm == DEC_IDLE)) + idle_cnt <= (idle_cnt == 3'b100) ? 3'b000: idle_cnt + 3'b001; + else + idle_cnt <= 3'b000; + end + end // always @ (posedge hsci_pclk or negedge rstn) + + // when frm_acq pulse comes in hold frame detect for 4 clock cycles + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + frm_acq_cnt <= 2'b00; + else begin + if (frm_acq == 1'b1) + frm_acq_cnt <= 2'b11; + else + frm_acq_cnt <= (frm_acq_cnt == 2'b00) ? 2'b00: frm_acq_cnt - 2'b01; + end + end // always @ (posedge hsci_pclk or negedge rstn) + + // JPB + //capture and delay mdec_dats + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + mdec_data_d1 <= 7'h00; + else + mdec_data_d1 <= mdec_data[6:0]; + end + + // buffer input + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + ibuf <= 19'h00000; + else begin + if (miso_clk_inv == 1'b0) + ibuf <= {ibuf[10:0], mdec_data[7:0]}; + else + ibuf <= {ibuf[10:0], mdec_data_d1[6:0], mdec_data[7]}; + end + end + + assign tmp_frm[7] = ibuf[16:7]; + assign tmp_frm[6] = ibuf[15:6]; + assign tmp_frm[5] = ibuf[14:5]; + assign tmp_frm[4] = ibuf[13:4]; + assign tmp_frm[3] = ibuf[12:3]; + assign tmp_frm[2] = ibuf[11:2]; + assign tmp_frm[1] = ibuf[10:1]; + assign tmp_frm[0] = ibuf[9:0]; + + // search for frame aligment + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end else begin + if (frm_det == 1'b0) begin + if (ibuf[16] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h7; + mdec_sfrm <= tmp_frm[7]; + end else if(ibuf[14] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h5; + mdec_sfrm <= tmp_frm[5]; + end else if(ibuf[12] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h3; + mdec_sfrm <= tmp_frm[3]; + end else if(ibuf[10] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h1; + mdec_sfrm <= tmp_frm[1]; + end + end else begin// if (frm_det == 1'b0) + if (((auto_linkup == 1'b1) & (frm_acq_cnt != 2'b00)) | (idle_cnt == 3'b100)) begin + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end else if (((dec_fsm == DEC_LINKUP) | (dec_fsm == DEC_RDATA) | (dec_fsm == DEC_ERROR) | (dec_fsm == DEC_MERR)) & (mdec_sfrm[0] == 1'b0) & (mdec_val == 1'b1)) begin + // check for next frame coming in + case(frm_align) + 4'h7: begin + if (tmp_frm[5][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h5; + mdec_sfrm <= tmp_frm[5]; + end else if (tmp_frm[3][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h3; + mdec_sfrm <= tmp_frm[3]; + end else if (tmp_frm[1][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h1; + mdec_sfrm <= tmp_frm[1]; + end else begin // drop frm_det + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end // else: !if(tmp_frm[0][9] == 1'b1) + end // case: 3'h6 + + 4'h5: begin + if (tmp_frm[3][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h3; + mdec_sfrm <= tmp_frm[3]; + end else if (tmp_frm[1][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h1; + mdec_sfrm <= tmp_frm[1]; + end else begin // drop frm_det + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end // else: !if(tmp_frm[0][9] == 1'b1) + end // case: 3'h5 + + 4'h3: begin + if (tmp_frm[1][9] == 1'b1) begin + frm_det <= 1'b1; + frm_align <= 4'h1; + mdec_sfrm <= tmp_frm[1]; + end else begin // drop frm_det + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end // else: !if(tmp_frm[0][9] == 1'b1) + end // case: 3'h3 + + 4'h1: begin + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end // else: !if(tmp_frm[0][9] == 1'b1) + // end // case: 3'h1 + + default: begin // drop frm_det + frm_det <= 1'b0; + frm_align <= 4'h9; + mdec_sfrm <= 10'h000; + end + endcase // case (frm_align) + end else begin // if ( (dec_fsm == DEC_RDATA) & (mdec_cont == 1'b0) & (mdec_val == 1'b1) ) + frm_align <= (frm_align <= 4'h1) ? 4'h9:frm_align - 4'h2; + frm_det <= frm_det; + mdec_sfrm <= (frm_align == 4'h0) ? mdec_sfrm: + (frm_align == 4'h1) ? mdec_sfrm: tmp_frm[frm_align - 4'h2]; // if (dec_fsm == DEC_IDLE) + end // else: !if( ( (dec_fsm == DEC_LINKUP) | (dec_fsm == DEC_RDATA) | (dec_fsm == DEC_ERROR) | (dec_fsm == DEC_MERR) ) & (mdec_sfrm[0] == 1'b0) & (mdec_val == 1'b1) ) + end // else: !if(frm_det == 1'b0) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign mdec_val = ~( (frm_align == 4'h9) | (frm_align == 4'h8) ); + assign next_frm_start = (frm_align > 4'h1) ? tmp_frm[frm_align - 4'h2][9] : tmp_frm[7][9]; + + // in capture_mode, always spit out tmp_frm[0] + // for miso_test_mode, use capture_word + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + capture_word <= 10'h000; + else begin + if (capture_mode == 1'b1) + capture_word <= ( (frm_align == 4'h9) | (frm_align == 4'h8) ) ? capture_word: tmp_frm[frm_align]; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // DFx miso test mode + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + lfsr_sreg <= 15'h7fff; + lfsr_cnt <= 3'b000; + miso_ber_cnt <= 32'h0; + end else begin + if (miso_test_mode == 1'b1) begin + if (lfsr_cnt != 3'b111) begin + lfsr_sreg <= (|lfsr_sreg == 1'b0) ? 15'h0001: {lfsr_sreg[6:0], mdec_data[7:0]}; + if (lfsr_next == mdec_data[7:0]) + lfsr_cnt <= lfsr_cnt + 3'b001; + else + lfsr_cnt <= 3'b000; + end else begin + lfsr_sreg <= (|lfsr_sreg == 1'b0) ? 15'h0001: {lfsr_sreg[6:0], lfsr_next[7:0]}; + if (lfsr_next != mdec_data[7:0]) + miso_ber_cnt <= (miso_ber_cnt != 32'hffffffff) ? miso_ber_cnt + 32'h00000001: 32'hffffffff; + end // else: !if(lfsr_cnt != 3'b111) + end // if (miso_test_mode == 1'b1) + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign miso_test_lfsr_acq = (lfsr_cnt == 3'b111); + assign lfsr_next = {(lfsr_sreg[14] ^ lfsr_sreg[13]), + (lfsr_sreg[13] ^ lfsr_sreg[12]), + (lfsr_sreg[12] ^ lfsr_sreg[11]), + (lfsr_sreg[11] ^ lfsr_sreg[10]), + (lfsr_sreg[10] ^ lfsr_sreg[9]), + (lfsr_sreg[9] ^ lfsr_sreg[8]), + (lfsr_sreg[8] ^ lfsr_sreg[7]), + (lfsr_sreg[7] ^ lfsr_sreg[6])}; + +endmodule diff --git a/library/axi_hsci/hsci_mlink_ctrl.sv b/library/axi_hsci/hsci_mlink_ctrl.sv new file mode 100644 index 0000000000..8470cfe292 --- /dev/null +++ b/library/axi_hsci/hsci_mlink_ctrl.sv @@ -0,0 +1,737 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module hsci_mlink_ctrl ( + // globals + input hsci_pclk, + input rstn, + // register sigs + input man_linkup, + input [9:0] man_linkup_word, + input auto_linkup, + input mosi_test_mode, + input alink_fsm_stall, + input alink_fsm_step, + input ver_b_na, + // status sigs for regmap + output [3:0] alink_fsm, + output [15:0] alink_table, + output [3:0] alink_txclk_adj, + output alink_txclk_inv, + output alink_fsm_stalled, + output txclk_adj_mismatch, + output txclk_inv_mismatch, + // menc_sigs + input menc_pause, + output [7:0] lfsr_word, + // mdec sigs + input signal_det, + input signal_acquired, + input alink_dval, + input [7:0] alink_data, + input idle_state, + input [3:0] tx_clk_adj_rcvd, + input tx_clk_inv_rcvd, + output reg frm_acq, + // outputs + output reg [9:0] linkup_word, + output reg link_active, + output reg [31:0] link_err_info +); + + typedef enum reg [3:0] { M_IDLE = 4'h0, + M_RX_LINK = 4'h1, + M_TX_DETECT = 4'h2, + M_TX_CLK_ADJ = 4'h3, + M_TX_ACQ = 4'h5, + M_TX_ENDLP = 4'h6, + M_TX_STALL = 4'h7, + M_TX_DECIDE = 4'h8, + M_TX_CLK_INV = 4'h9, + M_SET_TXCLK = 4'hA, + M_TX_REACQ = 4'hB, + M_TX_LINKUP = 4'hC, + M_LINKUP = 4'hD, + M_LINK_ERR = 4'hE + } state; + state mlink_state; + state prev_state; + + localparam LINKUP_INSTR = 4'b0101; + localparam RX_LINK_CNT_DEF = 20'hfffff; + localparam ACQUIRE_CNT_DEF = 16'h0fff; + + reg [2:0] alink_cntr; + wire [7:0] lfsr_out; + wire lfsr_en; + + reg signal_lock; + reg [19:0] rx_link_cntr; + reg rx_link_to; + + reg [15:0] tx_acq_cntr; + reg tx_acq_to; + reg [3:0] tx_clk_adj, tx_clk_adj_d; + reg [3:0] tx_clk_adj_val; + reg tx_clk_inv; + reg [2:0] tx_ctrl; + reg tx_linkup_achieved; + reg [4:0] tx_ctrl_b0; + + reg [15:0] auto_link_table; + reg [7:0] lock_data_cntr; + wire[7:0] next_lock_data; + reg [2:0] lock_fail_cntr; + + reg [14:0] lock_sreg; + + reg [2:0] dec_cntr; + reg dec_made; + reg [5:0][2:0] sum7; + reg [7:0][2:0] sum5; + reg [9:0][1:0] sum3; + reg idle_det; + reg [5:0] idle_det_cntr; + reg [3:0] tx_del_cntr; + reg get_link_err_info; + reg fsm_step_d1, fsm_step_d2; + wire fsm_step; + + // Link-up FSM + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + mlink_state <= M_IDLE; + prev_state <= M_IDLE; + end else begin + case(mlink_state) + M_IDLE: begin + if (auto_linkup == 1'b1) + mlink_state <= M_RX_LINK; + else + mlink_state <= M_IDLE; + end + + M_RX_LINK: begin + if (rx_link_to == 1'b1) + mlink_state <= M_LINK_ERR; + else if (signal_det == 1'b1) + mlink_state <= M_TX_DETECT; + else + mlink_state <= M_RX_LINK; + end + + M_TX_DETECT: begin + if (signal_det == 1'b1) + mlink_state <= M_TX_CLK_ADJ; + else + mlink_state <= M_TX_DETECT; + end + + M_TX_CLK_ADJ: begin + mlink_state <= M_TX_ACQ; // A0 + end + + M_TX_ACQ: begin + if (tx_acq_to == 1'b1) + mlink_state <= M_TX_ENDLP; + else if (signal_lock == 1'b1) + mlink_state <= M_TX_ENDLP; + else + mlink_state <= M_TX_ACQ; + end + + M_TX_ENDLP: begin + if (tx_clk_adj == 4'h0) + mlink_state <= M_TX_DECIDE; + else + mlink_state <= M_TX_STALL; + end + + M_TX_STALL: begin + if (alink_fsm_stall == 1'b0) + mlink_state <= M_TX_CLK_ADJ; + else begin + if (fsm_step == 1'b1) + mlink_state <= M_TX_CLK_ADJ; + else + mlink_state <= M_TX_STALL; + end + end + + M_TX_DECIDE: begin + if (dec_made == 1'b1) begin + mlink_state <= M_SET_TXCLK; + end else begin + if (dec_cntr == 3'b000) begin + if (tx_clk_inv == 1'b0) + mlink_state <= M_TX_CLK_INV; + else + mlink_state <= M_LINK_ERR; + end else + mlink_state <= M_TX_DECIDE; + end // else: !if(dec_made == 1'b1) + end // case: M_TX_DECIDE + + M_TX_CLK_INV: begin + mlink_state <= M_TX_CLK_ADJ; + end + + M_SET_TXCLK: begin + if (ver_b_na == 1'b0) begin // A0 + if ( (tx_clk_adj == tx_clk_adj_val) & (tx_del_cntr == 4'h0) ) + mlink_state <= M_TX_LINKUP; + else + mlink_state <= M_SET_TXCLK; + end else begin // B0 + mlink_state <= M_TX_REACQ; + end // else: !if(ver_b_na == 1'b0) + end // case: M_SET_TXCLK + + M_TX_REACQ: begin + if (tx_acq_to == 1'b1) + mlink_state <= M_LINK_ERR; + else if (signal_lock == 1'b1) + mlink_state <= M_TX_LINKUP; + else + mlink_state <= M_TX_REACQ; + end + + M_TX_LINKUP: begin + if (idle_det == 1'b1) + mlink_state <= M_LINKUP; + else + mlink_state <= M_TX_LINKUP; + end + + M_LINKUP: begin + mlink_state <= M_LINKUP; + end + + M_LINK_ERR: begin + mlink_state <= M_LINK_ERR; + end + + default: begin + mlink_state <= M_LINK_ERR; + end + endcase // case (mlink_state) + + prev_state <= mlink_state; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + // tx delay cntr needed during set_txclk because there is a delay + // between changing tx_ctrl and when the chang occurs in the slave. + // So, tx delay cntr hold mlink_state in SET_TXCLK a little long before transitioning into TX_LINKUP + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) + tx_del_cntr <= 4'hf; + else begin + if (tx_clk_adj != tx_clk_adj_val) + tx_del_cntr <= 4'hf; + else + tx_del_cntr <= (tx_del_cntr == 4'h0) ? 4'h0: tx_del_cntr - 4'h1; + end + end // always @ (posedge hsci_pclk or negedge rstn) + + // MOSI portion of link control + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + linkup_word <= 10'h000; + alink_cntr <= 3'b000; + tx_clk_adj_d <= 4'hf; + tx_ctrl <= 3'b000; + tx_ctrl_b0 <= 5'h00; + end else begin + if ((auto_linkup== 1'b1) & (tx_linkup_achieved == 1'b0)) begin + if (ver_b_na == 1'b0) begin // A0 + if (mlink_state == M_TX_CLK_INV) + tx_ctrl <= 3'b011; // clock invert + else if ((mlink_state == M_TX_ACQ) | (mlink_state == M_SET_TXCLK)) begin + if ((mlink_state == M_TX_ACQ) & (alink_fsm_stall == 1'b1)) begin + if ((tx_acq_cntr == (ACQUIRE_CNT_DEF - 16'h002F) ) & (tx_clk_adj != 4'hF)) + tx_ctrl <= 3'b010; // decrement + else if ((alink_cntr == 3'b000) & (menc_pause == 1'b0)) + tx_ctrl <= 3'b000; + else + tx_ctrl <= tx_ctrl; + end else begin + if (tx_clk_adj < tx_clk_adj_d) + tx_ctrl <= 3'b010; // decrement + else if (tx_clk_adj > tx_clk_adj_d) + tx_ctrl <= 3'b001; // increment + else if ((alink_cntr == 3'b000) & (menc_pause == 1'b0)) + tx_ctrl <= 3'b000; + else + tx_ctrl <= tx_ctrl; + end // else: !if( (mlink_state == M_TX_ACQ) & (alink_fsm_stall == 1'b1) ) + end // if ( (mlink_state == M_TX_ACQ) | (mlink_state == M_SET_TXCLK) ) + end else begin // if (ver_b_na == 1'b0) + // B0 + tx_ctrl_b0 <= {tx_clk_inv, tx_clk_adj}; + end // else: !if(ver_b_na == 1'b0) + end else // if ((auto_linkup== 1'b1) & (tx_linkup_achieved == 1'b0)) + tx_ctrl <= 3'b000; + if (man_linkup == 1'b1) begin + linkup_word <= man_linkup_word; + end else if (auto_linkup == 1'b1) begin + if (mlink_state == M_TX_CLK_INV) + tx_clk_adj_d <= 4'hf; // clock invert resets txclk_adj back to 4'hf + else + tx_clk_adj_d <= tx_clk_adj; + + if (menc_pause == 1'b0) begin + if ((mlink_state == M_LINKUP) | (mlink_state == M_TX_LINKUP)) begin + linkup_word[9:0] <= 10'h000; + alink_cntr <= 3'b000; + end else begin + case (alink_cntr) + 3'b000: begin + linkup_word[9:2] <= (ver_b_na == 1'b0) ? {1'b1, LINKUP_INSTR, tx_ctrl}: {1'b1, LINKUP_INSTR, tx_ctrl_b0[4:2]}; + linkup_word[1] <= (ver_b_na == 1'b0) ? (linkup_word[9] + linkup_word[8] + linkup_word[7] + linkup_word[6] + linkup_word[5] + linkup_word[4] + linkup_word[3]): tx_ctrl_b0[1]; + linkup_word[0] <= (ver_b_na == 1'b0) ? 1'b0: tx_ctrl_b0[0]; + end + 3'b001, 3'b010, 3'b011, 3'b100, 3'b101: begin + linkup_word[9:2] <= lfsr_out[7:0]; + linkup_word[1] <= (linkup_word[9] + linkup_word[8] + linkup_word[7] + linkup_word[6] + linkup_word[5] + linkup_word[4] + linkup_word[3] + 1'b1); + linkup_word[0] <= 1'b1; + end + 3'b110: begin + linkup_word[9:2] <= lfsr_out[7:0]; + linkup_word[1] <= (linkup_word[9] + linkup_word[8] + linkup_word[7] + linkup_word[6] + linkup_word[5] + linkup_word[4] + linkup_word[3]); + linkup_word[0] <= 1'b0; + end + 3'b111: + linkup_word <= 10'h000; // IDLE + endcase // case (alink_cntr) + + alink_cntr <= alink_cntr + 3'b001; + end // else: !if( (mlink_state == M_LINKUP) | (mlink_state == M_TX_LINKUP) ) + end // if (menc_pause == 1'b0) + end else // if (auto_linkup == 1'b1) + linkup_word <= 10'h000; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign lfsr_en = ((mosi_test_mode == 1'b1) | ((alink_cntr != 3'b000) & (alink_cntr != 3'b111) & (menc_pause != 1'b1))); + + lfsr15_8 lfsr0 ( + .clk(hsci_pclk), + .rstn(rstn), + .en(lfsr_en), + .pn_out(lfsr_out)); + + assign lfsr_word = (mosi_test_mode == 1'b1) ? lfsr_out: 8'h00; + + // generate tx clock mismatch sigs + assign txclk_adj_mismatch = (ver_b_na == 1'b1) ? ~(tx_clk_adj == tx_clk_adj_rcvd): 1'b0; + assign txclk_inv_mismatch = (ver_b_na == 1'b1) ? ~(tx_clk_inv == tx_clk_inv_rcvd): 1'b0; + + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + signal_lock <= 1'b0; + + rx_link_cntr <= RX_LINK_CNT_DEF; + rx_link_to <= 1'b0; + + tx_acq_cntr <= ACQUIRE_CNT_DEF; + tx_acq_to <= 1'b0; + tx_clk_adj <= 4'hf; + tx_clk_adj_val <= 4'hf; + tx_clk_inv <= 1'b0; + tx_linkup_achieved <= 1'b0; + + auto_link_table <= 16'h0000; + + lock_data_cntr <= 8'h00; + lock_sreg <= 15'h7fff; + + dec_cntr <= 3'b111; + dec_made <= 1'b0; + sum7 <= 'h0; + sum5 <= 'h0; + sum3 <= 'h0; + + idle_det <= 1'b0; + idle_det_cntr <= 6'h3f; + + link_active <= 1'b0; + get_link_err_info <= 1'b0; + link_err_info <= 32'h0; + end else begin // if (~rstn) + case(mlink_state) + M_IDLE: begin + signal_lock <= 1'b0; + + rx_link_cntr <= RX_LINK_CNT_DEF; + rx_link_to <= 1'b0; + + tx_acq_cntr <= ACQUIRE_CNT_DEF; + tx_acq_to <= 1'b0; + tx_clk_adj <= 4'hf; + tx_clk_inv <= 1'b0; + tx_linkup_achieved <= 1'b0; + + auto_link_table <= 16'h0000; + + dec_cntr <= 3'b111; + dec_made <= 1'b0; + sum7 <= 'h0; + sum5 <= 'h0; + sum3 <= 'h0; + + idle_det <= 1'b0; + idle_det_cntr <= 6'h3f; + + link_active <= 1'b0; + get_link_err_info <= 1'b0; + link_err_info <= 32'h0; + end // case: M_IDLE + + M_RX_LINK: begin + rx_link_cntr <= (rx_link_cntr == 20'h0) ? rx_link_cntr: rx_link_cntr - 20'h1; + rx_link_to <= (rx_link_cntr == 20'h0); + end + + M_TX_DETECT: begin + end + + M_TX_CLK_ADJ: begin + if ((prev_state == M_TX_DETECT) | (prev_state == M_TX_CLK_INV)) begin + tx_clk_adj <= 4'hf; + auto_link_table <= 16'h0000; + end else begin + tx_clk_adj <= tx_clk_adj - 1; + end + dec_cntr <= 3'b111; + end // case: M_TX_CLK_ADJ + + M_TX_ACQ: begin // find a link frame, linkup cmd, 6 data sub frames + + tx_acq_cntr <= (tx_acq_cntr == 16'h0000) ? 16'h0000: tx_acq_cntr - 1; + tx_acq_to <= (tx_acq_cntr == 16'h0000); + + if ((txclk_adj_mismatch == 1'b0) & (txclk_inv_mismatch == 1'b0)) begin + if (alink_dval == 1'b1) begin + if (alink_data != next_lock_data) begin + if (lock_sreg == 15'h0000) + lock_sreg <= 15'h7fff; + else + lock_sreg <= {lock_sreg[6:0], alink_data}; + lock_data_cntr <= 8'h00; + end else begin + if (lock_sreg == 15'h0000) begin + lock_sreg <= 15'h7fff; + end else begin + lock_sreg[14:8] <= lock_sreg[6:0]; + lock_sreg[7] <= lock_sreg[14] ^ lock_sreg[13]; + lock_sreg[6] <= lock_sreg[13] ^ lock_sreg[12]; + lock_sreg[5] <= lock_sreg[12] ^ lock_sreg[11]; + lock_sreg[4] <= lock_sreg[11] ^ lock_sreg[10]; + lock_sreg[3] <= lock_sreg[10] ^ lock_sreg[9]; + lock_sreg[2] <= lock_sreg[9] ^ lock_sreg[8]; + lock_sreg[1] <= lock_sreg[8] ^ lock_sreg[7]; + lock_sreg[0] <= lock_sreg[7] ^ lock_sreg[6]; + lock_data_cntr <= (lock_data_cntr == 8'h7f) ? lock_data_cntr: lock_data_cntr + 8'h01; + signal_lock <= (lock_data_cntr == 8'h7f); + end // else: !if(lock_sreg == 15'h0000) + end + end // if (alink_dval == 1'b1) + end // if ((txclk_adj_mismatch == 1'b0) & (txclk_inv_mismatch == 1'b0)) + end // case: H_ACQ + + M_TX_ENDLP: begin + // tally aqc results + lock_data_cntr <= 8'h00; + signal_lock <= 1'b0; + auto_link_table[tx_clk_adj] <= signal_lock; + + // reset acq counter, etc + tx_acq_cntr <= ACQUIRE_CNT_DEF; + tx_acq_to <= 1'b0; + end + + M_TX_DECIDE: begin + dec_cntr <= (dec_cntr == 3'b000) ? 3'b000: dec_cntr - 3'b001; + + case (dec_cntr) + 3'b111: begin + sum7[0] <= auto_link_table[0] + auto_link_table[1] + auto_link_table[2] + auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6]; + sum7[1] <= auto_link_table[1] + auto_link_table[2] + auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7]; + sum7[2] <= auto_link_table[2] + auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8]; + sum7[3] <= auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8] + auto_link_table[9]; + sum7[4] <= auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8] + auto_link_table[9] + auto_link_table[10]; + sum7[5] <= auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8] + auto_link_table[9] + auto_link_table[10] + auto_link_table[11]; + + sum5[0] <= auto_link_table[0] + auto_link_table[1] + auto_link_table[2] + auto_link_table[3] + auto_link_table[4]; + sum5[1] <= auto_link_table[1] + auto_link_table[2] + auto_link_table[3] + auto_link_table[4] + auto_link_table[5]; + sum5[2] <= auto_link_table[2] + auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6]; + sum5[3] <= auto_link_table[3] + auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7]; + sum5[4] <= auto_link_table[4] + auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8]; + sum5[5] <= auto_link_table[5] + auto_link_table[6] + auto_link_table[7] + auto_link_table[8] + auto_link_table[9]; + sum5[6] <= auto_link_table[6] + auto_link_table[7] + auto_link_table[8] + auto_link_table[9] + auto_link_table[10]; + sum5[7] <= auto_link_table[7] + auto_link_table[8] + auto_link_table[9] + auto_link_table[10] + auto_link_table[11]; + + sum3[0] <= auto_link_table[0] + auto_link_table[1] + auto_link_table[2]; + sum3[1] <= auto_link_table[1] + auto_link_table[2] + auto_link_table[3]; + sum3[2] <= auto_link_table[2] + auto_link_table[3] + auto_link_table[4]; + sum3[3] <= auto_link_table[3] + auto_link_table[4] + auto_link_table[5]; + sum3[4] <= auto_link_table[4] + auto_link_table[5] + auto_link_table[6]; + sum3[5] <= auto_link_table[5] + auto_link_table[6] + auto_link_table[7]; + sum3[6] <= auto_link_table[6] + auto_link_table[7] + auto_link_table[8]; + sum3[7] <= auto_link_table[7] + auto_link_table[8] + auto_link_table[9]; + sum3[8] <= auto_link_table[8] + auto_link_table[9] + auto_link_table[10]; + sum3[9] <= auto_link_table[9] + auto_link_table[10] + auto_link_table[11]; + end // case: 3'b111 + + 3'b110: begin + if (sum7[0] == 3'b111) begin + tx_clk_adj_val <= 4'h3; + dec_made <= 1'b1; + end else if (sum7[1] == 3'b111) begin + tx_clk_adj_val <= 4'h4; + dec_made <= 1'b1; + end else if (sum7[2] == 3'b111) begin + tx_clk_adj_val <= 4'h5; + dec_made <= 1'b1; + end else if (sum7[3] == 3'b111) begin + tx_clk_adj_val <= 4'h6; + dec_made <= 1'b1; + end else if (sum7[4] == 3'b111) begin + tx_clk_adj_val <= 4'h7; + dec_made <= 1'b1; + end else if (sum7[5] == 3'b111) begin + tx_clk_adj_val <= 4'h8; + dec_made <= 1'b1; + end + end // case: 3'b110 + + 3'b101: begin + if (dec_made == 1'b0) begin // no decision yet + if (sum5[0] == 3'b101) begin + tx_clk_adj_val <= 4'h2; + dec_made <= 1'b1; + end else if (sum5[1] == 3'b101) begin + tx_clk_adj_val <= 4'h3; + dec_made <= 1'b1; + end else if (sum5[2] == 3'b101) begin + tx_clk_adj_val <= 4'h4; + dec_made <= 1'b1; + end else if (sum5[3] == 3'b101) begin + tx_clk_adj_val <= 4'h5; + dec_made <= 1'b1; + end else if (sum5[4] == 3'b101) begin + tx_clk_adj_val <= 4'h6; + dec_made <= 1'b1; + end else if (sum5[5] == 3'b101)begin + tx_clk_adj_val <= 4'h7; + dec_made <= 1'b1; + end else if (sum5[6] == 3'b101) begin + tx_clk_adj_val <= 4'h8; + dec_made <= 1'b1; + end else if (sum5[7] == 3'b101) begin + tx_clk_adj_val <= 4'h9; + dec_made <= 1'b1; + end + end // if (dec_made == 1'b0) + end // case: 3'b101 + + 3'b100: begin + if (dec_made == 1'b0) begin // no decision yet + if (sum3[0] == 2'b11) begin + tx_clk_adj_val <= 4'h1; + dec_made <= 1'b1; + end else if (sum3[1] == 2'b11) begin + tx_clk_adj_val <= 4'h2; + dec_made <= 1'b1; + end else if (sum3[2] == 2'b11) begin + tx_clk_adj_val <= 4'h3; + dec_made <= 1'b1; + end else if (sum3[3] == 2'b11) begin + tx_clk_adj_val <= 4'h4; + dec_made <= 1'b1; + end else if (sum3[4] == 2'b11) begin + tx_clk_adj_val <= 4'h5; + dec_made <= 1'b1; + end else if (sum3[5] == 2'b11) begin + tx_clk_adj_val <= 4'h6; + dec_made <= 1'b1; + end else if (sum3[6] == 2'b11) begin + tx_clk_adj_val <= 4'h7; + dec_made <= 1'b1; + end else if (sum3[7] == 2'b11) begin + tx_clk_adj_val <= 4'h8; + dec_made <= 1'b1; + end else if (sum3[8] == 2'b11) begin + tx_clk_adj_val <= 4'h9; + dec_made <= 1'b1; + end else if (sum3[9] == 2'b11) begin + tx_clk_adj_val <= 4'hA; + dec_made <= 1'b1; + end + end // if (dec_made == 1'b0) + end // case: 3'b100 + + default: begin + end + endcase // case (dec_cntr) + end // case: M_TX_DECIDE + + M_TX_CLK_INV: begin + tx_clk_inv <= 1'b1; + tx_clk_adj <= 4'hf; // tx_clk_inv also resets tx_clk_adj + auto_link_table <= 16'h0000; + end + + M_SET_TXCLK: begin // TX_ACK2 for B0 + if (ver_b_na == 1'b0) begin // A0 + if ((alink_cntr == 3'b111) & ((tx_clk_adj != tx_clk_adj_val))) + tx_clk_adj <= tx_clk_adj + 4'h1; + end else + tx_clk_adj <= tx_clk_adj_val; + end + + M_TX_REACQ: begin // re-acquire with desired txclk_adj + tx_acq_cntr <= (tx_acq_cntr == 16'h0000) ? 16'h0000: tx_acq_cntr - 1; + tx_acq_to <= (tx_acq_cntr == 16'h0000); + + if ((txclk_adj_mismatch == 1'b0) & (txclk_inv_mismatch == 1'b0)) begin + if (alink_dval == 1'b1) begin + if (alink_data != next_lock_data) begin + if (lock_sreg == 15'h0000) + lock_sreg <= 15'h7fff; + else + lock_sreg <= {lock_sreg[6:0], alink_data}; + lock_data_cntr <= 8'h00; + end else begin + if (lock_sreg == 15'h0000) begin + lock_sreg <= 15'h7fff; + end else begin + lock_sreg[14:8] <= lock_sreg[6:0]; + lock_sreg[7] <= lock_sreg[14] ^ lock_sreg[13]; + lock_sreg[6] <= lock_sreg[13] ^ lock_sreg[12]; + lock_sreg[5] <= lock_sreg[12] ^ lock_sreg[11]; + lock_sreg[4] <= lock_sreg[11] ^ lock_sreg[10]; + lock_sreg[3] <= lock_sreg[10] ^ lock_sreg[9]; + lock_sreg[2] <= lock_sreg[9] ^ lock_sreg[8]; + lock_sreg[1] <= lock_sreg[8] ^ lock_sreg[7]; + lock_sreg[0] <= lock_sreg[7] ^ lock_sreg[6]; + lock_data_cntr <= (lock_data_cntr == 8'h7f) ? lock_data_cntr: lock_data_cntr + 8'h01; + signal_lock <= (lock_data_cntr == 8'h7f); + end // else: !if(lock_sreg == 15'h0000) + end + end // if (alink_dval == 1'b1) + end // if ( (txclk_adj_mismatch == 1'b0) & (txclk_inv_mismatch == 1'b0) ) + end // case: H_ACQ + + M_TX_LINKUP: begin + tx_linkup_achieved <= 1'b1; + + if (idle_state == 1'b1) + idle_det_cntr <= (idle_det_cntr == 6'h00) ? 6'h00: idle_det_cntr - 6'h01; + else + idle_det_cntr <= 6'h3f; + idle_det <= (idle_det_cntr == 6'h00); + end + + M_LINKUP: begin + link_active <= 1'b1; + end + + M_LINK_ERR: begin + // Capture link error info + if (get_link_err_info == 1'b0) begin + link_err_info <= {15'h0, tx_linkup_achieved, tx_clk_adj, tx_clk_adj_val, dec_made, tx_acq_to, rx_link_to, signal_lock, prev_state}; + get_link_err_info <= 1'b1; + end + end + endcase // case (hsci_state) + end // else: !if(~rstn) + end // always @ (posedge rx_mclk or negedge rstn) + + // set-up fsm_step + // sample alink_fsm_step and generate a fsm_step pulse if rising edge detected + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + fsm_step_d2 <= 1'b0; + fsm_step_d1 <= 1'b0; + end else begin + fsm_step_d2 <= fsm_step_d1; + fsm_step_d1 <= alink_fsm_step; + end + end // always @ (posedge hsci_pclk or negedge rstn) + + assign fsm_step = (fsm_step_d1 & !fsm_step_d2); + + assign next_lock_data = {(lock_sreg[14] ^ lock_sreg[13]), + (lock_sreg[13] ^ lock_sreg[12]), + (lock_sreg[12] ^ lock_sreg[11]), + (lock_sreg[11] ^ lock_sreg[10]), + (lock_sreg[10] ^ lock_sreg[9]), + (lock_sreg[9] ^ lock_sreg[8]), + (lock_sreg[8] ^ lock_sreg[7]), + (lock_sreg[7] ^ lock_sreg[6])}; + + // set-up status sigs + assign alink_fsm = mlink_state; + assign alink_table = auto_link_table; + assign alink_txclk_adj = tx_clk_adj; + assign alink_txclk_inv = tx_clk_inv; + assign alink_fsm_stalled = ((mlink_state == M_TX_STALL) & (alink_fsm_stall == 1'b1)); + + // During auto link-up, if lock data not match, reset frame detect logic + always @ (posedge hsci_pclk or negedge rstn) begin + if (~rstn) begin + lock_fail_cntr <= 3'b000; + end else begin // fail counter increments when alink_data != next_lock_data + if ((mlink_state == M_TX_ACQ) & (alink_dval == 1'b1) & (alink_data != next_lock_data)) begin + if (lock_fail_cntr >= 3'b110) + lock_fail_cntr <= 3'b110; + else + lock_fail_cntr <= lock_fail_cntr + 1; + end else if (mlink_state != M_TX_ACQ) + lock_fail_cntr <= 3'b000; + else if (alink_data == next_lock_data) + lock_fail_cntr <= 3'b000; + else if (lock_fail_cntr >= 3'b110) + lock_fail_cntr <= 3'b000; + end // else: !if(~rstn) + end // always @ (posedge hsci_pclk or negedge rstn) + + assign frm_acq = (lock_fail_cntr >= 3'b110); + +endmodule diff --git a/library/axi_hsci/lfsr15_8.v b/library/axi_hsci/lfsr15_8.v new file mode 100644 index 0000000000..004f217da1 --- /dev/null +++ b/library/axi_hsci/lfsr15_8.v @@ -0,0 +1,73 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module lfsr15_8 ( + input clk, + input rstn, + input en, + output [7:0] pn_out +); + + wire stuck; + reg [14:0] lfsr; + + assign stuck = &lfsr; + + // LFSR that produces 8 bits per cycle + always @ (posedge clk or negedge rstn) begin + if (rstn == 0) + lfsr[14:0] <= 15'h7fff; + else begin + if (en) begin + lfsr[14:9] <= lfsr[6:1]; + lfsr[8] <= (stuck == 1'b1) ? 1: lfsr[0]; + lfsr[7] <= lfsr[14] ^ lfsr[13]; + lfsr[6] <= lfsr[13] ^ lfsr[12]; + lfsr[5] <= lfsr[12] ^ lfsr[11]; + lfsr[4] <= lfsr[11] ^ lfsr[10]; + lfsr[3] <= lfsr[10] ^ lfsr[9]; + lfsr[2] <= lfsr[9] ^ lfsr[8]; + lfsr[1] <= lfsr[8] ^ lfsr[7]; + lfsr[0] <= lfsr[7] ^ lfsr[6]; + end else + lfsr <= lfsr; + end + end + + assign pn_out = lfsr[7:0]; + +endmodule diff --git a/library/axi_hsci/pulse_sync.v b/library/axi_hsci/pulse_sync.v new file mode 100644 index 0000000000..58dbe04600 --- /dev/null +++ b/library/axi_hsci/pulse_sync.v @@ -0,0 +1,76 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module pulse_sync ( + output wire dout, + input wire inclk, + input wire rst_inclk, + input wire outclk, + input wire rst_outclk, + input wire din +); + + (* ASYNC_REG = "TRUE" *) reg din_d1; + (* ASYNC_REG = "TRUE" *) reg t; + reg [2:0] t_d; + reg dout_r; + + always @(posedge inclk) begin + if(rst_inclk) begin + din_d1 <= 1'b0; + t <= 1'b0; + end else begin + din_d1 <= din; + if(din && !din_d1) begin + t <= ~t; + end + end + end + + always @(posedge outclk) begin + if(rst_outclk) begin + t_d <= 'b0; + dout_r <= 1'b0; + end else begin + t_d <= {t_d[1:0], t}; + dout_r <= t_d[2] ^ t_d[1]; + end + end + + assign dout = dout_r; + +endmodule