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_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
|
||||
|
|
|
@ -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 #(
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -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 \
|
||||
]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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