// *************************************************************************** // *************************************************************************** // Copyright (C) 2022-2023 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 axi_tdd_regmap #( parameter ID = 0, parameter CHANNEL_COUNT = 8, parameter DEFAULT_POLARITY = 8'h00, parameter REGISTER_WIDTH = 32, parameter BURST_COUNT_WIDTH = 32, parameter SYNC_INTERNAL = 1, parameter SYNC_EXTERNAL = 0, parameter SYNC_EXTERNAL_CDC = 0, parameter SYNC_COUNT_WIDTH = 64 ) ( // tdd clock input logic tdd_clk, input logic tdd_resetn, // tdd interface control input axi_tdd_pkg::state_t tdd_cstate, output logic tdd_enable, output logic [CHANNEL_COUNT-1:0] tdd_channel_en, output logic [CHANNEL_COUNT-1:0] asy_tdd_channel_pol, output logic [BURST_COUNT_WIDTH-1:0] asy_tdd_burst_count, output logic [REGISTER_WIDTH-1:0] asy_tdd_startup_delay, output logic [REGISTER_WIDTH-1:0] asy_tdd_frame_length, output logic [REGISTER_WIDTH-1:0] asy_tdd_channel_on [0:CHANNEL_COUNT-1], output logic [REGISTER_WIDTH-1:0] asy_tdd_channel_off [0:CHANNEL_COUNT-1], output logic [SYNC_COUNT_WIDTH-1:0] asy_tdd_sync_period, output logic tdd_sync_rst, output logic tdd_sync_int, output logic tdd_sync_ext, output logic tdd_sync_soft, // bus interface input logic up_rstn, input logic up_clk, input logic up_wreq, input logic [ 7:0] up_waddr, input logic [31:0] up_wdata, output logic up_wack, input logic up_rreq, input logic [ 7:0] up_raddr, output logic [31:0] up_rdata, output logic up_rack ); // package import import axi_tdd_pkg::*; // local params localparam CHANNEL_COUNT_EXTRA = CHANNEL_COUNT - 1; // internal registers logic [31:0] up_scratch; logic [ 1:0] up_tdd_cstate; logic up_tdd_enable; logic up_tdd_sync_rst; logic up_tdd_sync_int; logic up_tdd_sync_ext; logic up_tdd_sync_soft; logic [CHANNEL_COUNT-1:0] up_tdd_channel_en; logic [CHANNEL_COUNT-1:0] up_tdd_channel_pol; logic [BURST_COUNT_WIDTH-1:0] up_tdd_burst_count; logic [REGISTER_WIDTH-1:0] up_tdd_startup_delay; logic [REGISTER_WIDTH-1:0] up_tdd_frame_length; logic [REGISTER_WIDTH-1:0] up_tdd_channel_on [0:CHANNEL_COUNT-1]; logic [REGISTER_WIDTH-1:0] up_tdd_channel_off [0:CHANNEL_COUNT-1]; //internal wires logic [31:0] status_synth_params_s; logic [31:0] status_def_polarity_s; logic [31:0] up_tdd_channel_en_s; logic [31:0] up_tdd_channel_pol_s; logic [31:0] up_tdd_burst_count_s; logic [31:0] up_tdd_startup_delay_s; logic [31:0] up_tdd_frame_length_s; logic [63:0] up_tdd_sync_period_s; logic [31:0] up_tdd_channel_on_s [0:31]; logic [31:0] up_tdd_channel_off_s [0:31]; //initial values initial begin up_rdata = 32'b0; up_wack = 1'b0; up_rack = 1'b0; up_scratch = 32'b0; up_tdd_enable = 1'b0; up_tdd_sync_rst = 1'b0; up_tdd_sync_int = 1'b0; up_tdd_sync_ext = 1'b0; up_tdd_sync_soft = 1'b0; up_tdd_channel_en = '0; up_tdd_channel_pol = '0; up_tdd_burst_count = '0; up_tdd_startup_delay = '0; up_tdd_frame_length = '0; up_tdd_channel_on = '{default:0}; up_tdd_channel_off = '{default:0}; end //read-only synthesis parameters assign status_synth_params_s = { /*31:24 */ 1'b0, 7'(SYNC_COUNT_WIDTH), /*23:16 */ 2'b0, 6'(BURST_COUNT_WIDTH), /*15: 8 */ 2'b0, 6'(REGISTER_WIDTH), /* 7: 0 */ 1'(SYNC_EXTERNAL_CDC), 1'(SYNC_EXTERNAL), 1'(SYNC_INTERNAL), 5'(CHANNEL_COUNT_EXTRA)}; assign status_def_polarity_s = {{(32-CHANNEL_COUNT){1'b0}}, DEFAULT_POLARITY}; // processor write interface always @(posedge up_clk) begin if (up_rstn == 0) begin up_wack <= 1'b0; up_scratch <= 32'b0; up_tdd_enable <= 1'b0; up_tdd_sync_rst <= 1'b0; up_tdd_sync_int <= 1'b0; up_tdd_sync_ext <= 1'b0; up_tdd_sync_soft <= 1'b0; up_tdd_channel_en <= '0; up_tdd_channel_pol <= '0; up_tdd_startup_delay <= '0; up_tdd_frame_length <= '0; up_tdd_burst_count <= '0; end else begin up_wack <= up_wreq; if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_SCRATCH)) begin up_scratch <= up_wdata; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_CONTROL)) begin up_tdd_sync_soft <= up_wdata[4]; up_tdd_sync_ext <= up_wdata[3] & SYNC_EXTERNAL; up_tdd_sync_int <= up_wdata[2] & SYNC_INTERNAL; up_tdd_sync_rst <= up_wdata[1]; up_tdd_enable <= up_wdata[0]; end else begin up_tdd_sync_soft <= 1'b0; up_tdd_sync_ext <= up_tdd_sync_ext; up_tdd_sync_int <= up_tdd_sync_int; up_tdd_sync_rst <= up_tdd_sync_rst; up_tdd_enable <= up_tdd_enable; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_CH_ENABLE)) begin up_tdd_channel_en <= up_wdata[CHANNEL_COUNT-1:0]; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_CH_POLARITY) && !up_tdd_enable) begin up_tdd_channel_pol <= up_wdata[CHANNEL_COUNT-1:0]; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_BURST_COUNT) && !up_tdd_enable) begin up_tdd_burst_count <= up_wdata[BURST_COUNT_WIDTH-1:0]; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_STARTUP_DELAY) && !up_tdd_enable) begin up_tdd_startup_delay <= up_wdata[REGISTER_WIDTH-1:0]; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_FRAME_LENGTH) && !up_tdd_enable) begin up_tdd_frame_length <= up_wdata[REGISTER_WIDTH-1:0]; end end end assign up_tdd_channel_en_s = {{(32-CHANNEL_COUNT){1'b0}}, up_tdd_channel_en}; assign up_tdd_channel_pol_s = {{(32-CHANNEL_COUNT){1'b0}}, up_tdd_channel_pol}; assign up_tdd_burst_count_s = {{(32-BURST_COUNT_WIDTH){1'b0}}, up_tdd_burst_count}; assign up_tdd_startup_delay_s = {{(32-REGISTER_WIDTH){1'b0}}, up_tdd_startup_delay}; assign up_tdd_frame_length_s = {{(32-REGISTER_WIDTH){1'b0}}, up_tdd_frame_length}; // internal sync counter generation (low and high) generate if (SYNC_COUNT_WIDTH>32) begin logic [31:0] up_tdd_sync_period_low; logic [(SYNC_COUNT_WIDTH-32-1):0] up_tdd_sync_period_high; always @(posedge up_clk) begin if (up_rstn == 0) begin up_tdd_sync_period_low <= 32'b0; up_tdd_sync_period_high <= '0; end else begin if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_SYNC_CNT_LOW) && !up_tdd_enable) begin up_tdd_sync_period_low <= up_wdata[31:0]; end if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_SYNC_CNT_HIGH) && !up_tdd_enable) begin up_tdd_sync_period_high <= up_wdata[(SYNC_COUNT_WIDTH-32-1):0]; end end end assign up_tdd_sync_period_s[31:0] = up_tdd_sync_period_low; assign up_tdd_sync_period_s[63:32] = {{(64-SYNC_COUNT_WIDTH){1'b0}}, up_tdd_sync_period_high}; assign asy_tdd_sync_period = {up_tdd_sync_period_high, up_tdd_sync_period_low}; //skipping CDC end else begin if (SYNC_COUNT_WIDTH>0) begin logic [SYNC_COUNT_WIDTH-1:0] up_tdd_sync_period_low; always @(posedge up_clk) begin if (up_rstn == 0) begin up_tdd_sync_period_low <= '0; end else begin if ((up_wreq == 1'b1) && (up_waddr == ADDR_TDD_SYNC_CNT_LOW) && !up_tdd_enable) begin up_tdd_sync_period_low <= up_wdata[(SYNC_COUNT_WIDTH-1):0]; end end end assign up_tdd_sync_period_s[31:0] = {{(32-SYNC_COUNT_WIDTH){1'b0}}, up_tdd_sync_period_low}; assign up_tdd_sync_period_s[63:32] = 32'b0; assign asy_tdd_sync_period = up_tdd_sync_period_low; //skipping CDC end else begin assign up_tdd_sync_period_s[31:0] = 32'b0; assign up_tdd_sync_period_s[63:32] = 32'b0; assign asy_tdd_sync_period = '0; end end endgenerate // channel register generation genvar i; generate for (i=0; i