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 <lars@metafoo.de>main
parent
0be4a5c10e
commit
5d044b9fd3
|
@ -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_channel.v
|
||||||
GENERIC_DEPS += ad_ip_jesd204_tpl_dac_core.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_framer.v
|
||||||
|
GENERIC_DEPS += ad_ip_jesd204_tpl_dac_pn.v
|
||||||
GENERIC_DEPS += ad_ip_jesd204_tpl_dac_regmap.v
|
GENERIC_DEPS += ad_ip_jesd204_tpl_dac_regmap.v
|
||||||
|
|
||||||
XILINX_DEPS += ../../xilinx/common/ad_mul.v
|
XILINX_DEPS += ../../xilinx/common/ad_mul.v
|
||||||
|
|
|
@ -37,6 +37,11 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
input [DATA_PATH_WIDTH*16-1:0] dma_data,
|
input [DATA_PATH_WIDTH*16-1:0] dma_data,
|
||||||
output reg [DATA_PATH_WIDTH*16-1:0] dac_data = 'h00,
|
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
|
// Configuration
|
||||||
|
|
||||||
input dac_data_sync,
|
input dac_data_sync,
|
||||||
|
@ -57,60 +62,19 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
output reg dac_enable = 1'b0
|
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
|
// internal signals
|
||||||
|
|
||||||
wire [DW:0] dac_dds_data_s;
|
wire [DATA_PATH_WIDTH*16-1: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
|
|
||||||
|
|
||||||
// dac data select
|
// dac data select
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
dac_enable <= (dac_data_sel == 4'h2) ? 1'b1 : 1'b0;
|
dac_enable <= (dac_data_sel == 4'h2) ? 1'b1 : 1'b0;
|
||||||
case (dac_data_sel)
|
case (dac_data_sel)
|
||||||
4'h7: dac_data <= dac_pn15_data_s;
|
4'h7: dac_data <= pn15_data;
|
||||||
4'h6: dac_data <= dac_pn7_data_s;
|
4'h6: dac_data <= pn7_data;
|
||||||
4'h5: dac_data <= ~dac_pn15_data_s;
|
4'h5: dac_data <= ~pn15_data;
|
||||||
4'h4: dac_data <= ~dac_pn7_data_s;
|
4'h4: dac_data <= ~pn7_data;
|
||||||
4'h3: dac_data <= 'h00;
|
4'h3: dac_data <= 'h00;
|
||||||
4'h2: dac_data <= dma_data;
|
4'h2: dac_data <= dma_data;
|
||||||
4'h1: dac_data <= {DATA_PATH_WIDTH/2{dac_pat_data_1, dac_pat_data_0}};
|
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
|
endcase
|
||||||
end
|
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
|
// dds
|
||||||
|
|
||||||
ad_dds #(
|
ad_dds #(
|
||||||
|
|
|
@ -67,6 +67,9 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
|
|
||||||
wire [NUM_LANES*32-1:0] dac_data_s;
|
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
|
// device interface
|
||||||
|
|
||||||
ad_ip_jesd204_tpl_dac_framer #(
|
ad_ip_jesd204_tpl_dac_framer #(
|
||||||
|
@ -78,6 +81,17 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
.dac_data (dac_data_s)
|
.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
|
// dac valid
|
||||||
|
|
||||||
assign dac_valid = {NUM_CHANNELS{1'b1}};
|
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]),
|
.dac_data (dac_data_s[CDW*i+:CDW]),
|
||||||
.dma_data (dac_ddata[CDW*i+:CDW]),
|
.dma_data (dac_ddata[CDW*i+:CDW]),
|
||||||
|
|
||||||
|
.pn7_data (pn7_data),
|
||||||
|
.pn15_data (pn15_data),
|
||||||
|
|
||||||
.dac_data_sync (dac_sync),
|
.dac_data_sync (dac_sync),
|
||||||
.dac_dds_format (dac_dds_format),
|
.dac_dds_format (dac_dds_format),
|
||||||
|
|
||||||
|
|
|
@ -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_channel.v \
|
||||||
ad_ip_jesd204_tpl_dac_core.v \
|
ad_ip_jesd204_tpl_dac_core.v \
|
||||||
ad_ip_jesd204_tpl_dac_framer.v \
|
ad_ip_jesd204_tpl_dac_framer.v \
|
||||||
|
ad_ip_jesd204_tpl_dac_pn.v \
|
||||||
ad_ip_jesd204_tpl_dac_regmap.v \
|
ad_ip_jesd204_tpl_dac_regmap.v \
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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_core.v" \
|
||||||
"ad_ip_jesd204_tpl_dac_framer.v" \
|
"ad_ip_jesd204_tpl_dac_framer.v" \
|
||||||
"ad_ip_jesd204_tpl_dac_regmap.v" \
|
"ad_ip_jesd204_tpl_dac_regmap.v" \
|
||||||
|
"ad_ip_jesd204_tpl_dac_pn.v" \
|
||||||
"ad_ip_jesd204_tpl_dac.v" ]
|
"ad_ip_jesd204_tpl_dac.v" ]
|
||||||
|
|
||||||
adi_ip_properties ad_ip_jesd204_tpl_dac
|
adi_ip_properties ad_ip_jesd204_tpl_dac
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue