From 5d044b9fd305c5ec74c95e10323a3a70782845a9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 3 Aug 2018 08:39:15 +0200 Subject: [PATCH] ad_ip_jesd204_tpl_dac: Share PN sequence generator between all channels All channels have a copy of the same logic to generate the PN sequences. Sharing the PN sequence generator among all channels slightly reduces the resource utilization of the core. Signed-off-by: Lars-Peter Clausen --- .../jesd204/ad_ip_jesd204_tpl_dac/Makefile | 1 + .../ad_ip_jesd204_tpl_dac_channel.v | 68 +++------------ .../ad_ip_jesd204_tpl_dac_core.v | 17 ++++ .../ad_ip_jesd204_tpl_dac_hw.tcl | 1 + .../ad_ip_jesd204_tpl_dac_ip.tcl | 1 + .../ad_ip_jesd204_tpl_dac_pn.v | 85 +++++++++++++++++++ 6 files changed, 115 insertions(+), 58 deletions(-) create mode 100644 library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_pn.v diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/Makefile b/library/jesd204/ad_ip_jesd204_tpl_dac/Makefile index 9cc4920b6..2b9d10adb 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/Makefile +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/Makefile @@ -22,6 +22,7 @@ GENERIC_DEPS += ad_ip_jesd204_tpl_dac.v GENERIC_DEPS += ad_ip_jesd204_tpl_dac_channel.v GENERIC_DEPS += ad_ip_jesd204_tpl_dac_core.v GENERIC_DEPS += ad_ip_jesd204_tpl_dac_framer.v +GENERIC_DEPS += ad_ip_jesd204_tpl_dac_pn.v GENERIC_DEPS += ad_ip_jesd204_tpl_dac_regmap.v XILINX_DEPS += ../../xilinx/common/ad_mul.v diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v index caebd0c72..af32fb5a0 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v @@ -37,6 +37,11 @@ module ad_ip_jesd204_tpl_dac_channel #( input [DATA_PATH_WIDTH*16-1:0] dma_data, output reg [DATA_PATH_WIDTH*16-1:0] dac_data = 'h00, + // PN data + + input [DATA_PATH_WIDTH*16-1:0] pn7_data, + input [DATA_PATH_WIDTH*16-1:0] pn15_data, + // Configuration input dac_data_sync, @@ -57,60 +62,19 @@ module ad_ip_jesd204_tpl_dac_channel #( output reg dac_enable = 1'b0 ); - localparam DW = DATA_PATH_WIDTH * 16 - 1; - - // internal registers - - reg [DW:0] dac_pn7_data = 'd0; - reg [DW:0] dac_pn15_data = 'd0; - // internal signals - wire [DW:0] dac_dds_data_s; - - wire [DW:0] pn15; - wire [DW+15:0] pn15_full_state; - wire [DW:0] dac_pn15_data_s; - wire [DW:0] pn15_reset; - wire [DW:0] pn7; - wire [DW+7:0] pn7_full_state; - wire [DW:0] dac_pn7_data_s; - wire [DW:0] pn7_reset; - - // PN15 x^15 + x^14 + 1 - assign pn15 = pn15_full_state[15+:DW+1] ^ pn15_full_state[14+:DW+1]; - assign pn15_full_state = {dac_pn15_data[14:0],pn15}; - - assign pn15_reset[DW-:15] = {15{1'b1}}; - assign pn15_reset[DW-15:0] = pn15_reset[DW:15] ^ pn15_reset[DW-1:14]; - - // PN7 x^7 + x^6 + 1 - assign pn7 = pn7_full_state[7+:DW+1] ^ pn7_full_state[6+:DW+1]; - assign pn7_full_state = {dac_pn7_data[6:0],pn7}; - - assign pn7_reset[DW-:7] = {7{1'b1}}; - assign pn7_reset[DW-7:0] = pn7_reset[DW:7] ^ pn7_reset[DW-1:6]; - - generate - genvar i; - for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_pn_swizzle - localparam src_lsb = i * 16; - localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * 16; - - assign dac_pn15_data_s[dst_lsb+:16] = dac_pn15_data[src_lsb+:16]; - assign dac_pn7_data_s[dst_lsb+:16] = dac_pn7_data[src_lsb+:16]; - end - endgenerate + wire [DATA_PATH_WIDTH*16-1:0] dac_dds_data_s; // dac data select always @(posedge clk) begin dac_enable <= (dac_data_sel == 4'h2) ? 1'b1 : 1'b0; case (dac_data_sel) - 4'h7: dac_data <= dac_pn15_data_s; - 4'h6: dac_data <= dac_pn7_data_s; - 4'h5: dac_data <= ~dac_pn15_data_s; - 4'h4: dac_data <= ~dac_pn7_data_s; + 4'h7: dac_data <= pn15_data; + 4'h6: dac_data <= pn7_data; + 4'h5: dac_data <= ~pn15_data; + 4'h4: dac_data <= ~pn7_data; 4'h3: dac_data <= 'h00; 4'h2: dac_data <= dma_data; 4'h1: dac_data <= {DATA_PATH_WIDTH/2{dac_pat_data_1, dac_pat_data_0}}; @@ -118,18 +82,6 @@ module ad_ip_jesd204_tpl_dac_channel #( endcase end - // pn registers - - always @(posedge clk) begin - if (dac_data_sync == 1'b1) begin - dac_pn15_data <= pn15_reset; - dac_pn7_data <= pn7_reset; - end else begin - dac_pn15_data <= pn15; - dac_pn7_data <= pn7; - end - end - // dds ad_dds #( diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v index 8270c8b0f..b343ed5ae 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v @@ -67,6 +67,9 @@ module ad_ip_jesd204_tpl_dac_core #( wire [NUM_LANES*32-1:0] dac_data_s; + wire [DATA_PATH_WIDTH*16-1:0] pn7_data; + wire [DATA_PATH_WIDTH*16-1:0] pn15_data; + // device interface ad_ip_jesd204_tpl_dac_framer #( @@ -78,6 +81,17 @@ module ad_ip_jesd204_tpl_dac_core #( .dac_data (dac_data_s) ); + // PN generator + ad_ip_jesd204_tpl_dac_pn #( + .DATA_PATH_WIDTH (DATA_PATH_WIDTH) + ) i_pn_gen ( + .clk (clk), + .reset (dac_sync), + + .pn7_data (pn7_data), + .pn15_data (pn15_data) + ); + // dac valid assign dac_valid = {NUM_CHANNELS{1'b1}}; @@ -99,6 +113,9 @@ module ad_ip_jesd204_tpl_dac_core #( .dac_data (dac_data_s[CDW*i+:CDW]), .dma_data (dac_ddata[CDW*i+:CDW]), + .pn7_data (pn7_data), + .pn15_data (pn15_data), + .dac_data_sync (dac_sync), .dac_dds_format (dac_dds_format), diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_hw.tcl b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_hw.tcl index e6974dc9f..5f6c70127 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_hw.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_hw.tcl @@ -51,6 +51,7 @@ ad_ip_files ad_ip_jesd204_tpl_dac [list \ ad_ip_jesd204_tpl_dac_channel.v \ ad_ip_jesd204_tpl_dac_core.v \ ad_ip_jesd204_tpl_dac_framer.v \ + ad_ip_jesd204_tpl_dac_pn.v \ ad_ip_jesd204_tpl_dac_regmap.v \ ] diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_ip.tcl b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_ip.tcl index a3489fc7b..e737e51ac 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_ip.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_ip.tcl @@ -48,6 +48,7 @@ adi_ip_files ad_ip_jesd204_tpl_dac [list \ "ad_ip_jesd204_tpl_dac_core.v" \ "ad_ip_jesd204_tpl_dac_framer.v" \ "ad_ip_jesd204_tpl_dac_regmap.v" \ + "ad_ip_jesd204_tpl_dac_pn.v" \ "ad_ip_jesd204_tpl_dac.v" ] adi_ip_properties ad_ip_jesd204_tpl_dac diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_pn.v b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_pn.v new file mode 100644 index 000000000..9ad5c32fd --- /dev/null +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_pn.v @@ -0,0 +1,85 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_ip_jesd204_tpl_dac_pn #( + parameter DATA_PATH_WIDTH = 4 +) ( + input clk, + input reset, + + output [DATA_PATH_WIDTH*16-1:0] pn7_data, + output [DATA_PATH_WIDTH*16-1:0] pn15_data +); + + localparam DW = DATA_PATH_WIDTH * 16 - 1; + + reg [DW:0] pn7_state = {DW+1{1'b1}}; + reg [DW:0] pn15_state = {DW+1{1'b1}}; + + wire [DW:0] pn7; + wire [DW+7:0] pn7_full_state; + wire [DW:0] pn7_reset; + wire [DW:0] pn15; + wire [DW+15:0] pn15_full_state; + wire [DW:0] pn15_reset; + + /* PN7 x^7 + x^6 + 1 */ + assign pn7 = pn7_full_state[7+:DW+1] ^ pn7_full_state[6+:DW+1]; + assign pn7_full_state = {pn7_state[6:0],pn7}; + + /* PN15 x^15 + x^14 + 1 */ + assign pn15 = pn15_full_state[15+:DW+1] ^ pn15_full_state[14+:DW+1]; + assign pn15_full_state = {pn15_state[14:0],pn15}; + + assign pn7_reset[DW-:7] = {7{1'b1}}; + assign pn7_reset[DW-7:0] = pn7_reset[DW:7] ^ pn7_reset[DW-1:6]; + + assign pn15_reset[DW-:15] = {15{1'b1}}; + assign pn15_reset[DW-15:0] = pn15_reset[DW:15] ^ pn15_reset[DW-1:14]; + + always @(posedge clk) begin + if (reset == 1'b1) begin + pn7_state <= pn7_reset; + pn15_state <= pn15_reset; + end else begin + pn7_state <= pn7; + pn15_state <= pn15; + end + end + + generate + /* + * The first sample contains the first MSB of the PN sequence, but the first + * sample is also in the LSB of the output data. So extract data at the MSB + * sample of the PN state and put it into the LSB sample of the output data. + */ + genvar i; + for (i = 0; i <= DW; i = i + 16) begin: g_pn_swizzle + assign pn7_data[i+:16] = pn7_state[DW-i-:16]; + assign pn15_data[i+:16] = pn15_state[DW-i-:16]; + end + endgenerate + +endmodule