From 119d4e43a3db298ea8adbcc3ef4d19e21b56eee1 Mon Sep 17 00:00:00 2001 From: Alin-Tudor Sferle Date: Tue, 7 Nov 2023 10:45:14 +0200 Subject: [PATCH] axi_pwm_gen: Add support for 16 channels Signed-off-by: Alin-Tudor Sferle Signed-off-by: AndreiGrozav --- library/axi_pwm_gen/Makefile | 4 +- library/axi_pwm_gen/axi_pwm_gen.sv | 394 ++++++++++++++++++++++ library/axi_pwm_gen/axi_pwm_gen.v | 356 ------------------- library/axi_pwm_gen/axi_pwm_gen_1.v | 4 +- library/axi_pwm_gen/axi_pwm_gen_hw.tcl | 42 ++- library/axi_pwm_gen/axi_pwm_gen_ip.tcl | 10 +- library/axi_pwm_gen/axi_pwm_gen_regmap.sv | 202 +++++++++++ library/axi_pwm_gen/axi_pwm_gen_regmap.v | 274 --------------- 8 files changed, 644 insertions(+), 642 deletions(-) create mode 100644 library/axi_pwm_gen/axi_pwm_gen.sv delete mode 100644 library/axi_pwm_gen/axi_pwm_gen.v create mode 100644 library/axi_pwm_gen/axi_pwm_gen_regmap.sv delete mode 100644 library/axi_pwm_gen/axi_pwm_gen_regmap.v diff --git a/library/axi_pwm_gen/Makefile b/library/axi_pwm_gen/Makefile index 6c08f9c4f..e79670d4b 100644 --- a/library/axi_pwm_gen/Makefile +++ b/library/axi_pwm_gen/Makefile @@ -8,9 +8,9 @@ LIBRARY_NAME := axi_pwm_gen GENERIC_DEPS += ../common/ad_rst.v GENERIC_DEPS += ../common/up_axi.v -GENERIC_DEPS += axi_pwm_gen.v +GENERIC_DEPS += axi_pwm_gen.sv GENERIC_DEPS += axi_pwm_gen_1.v -GENERIC_DEPS += axi_pwm_gen_regmap.v +GENERIC_DEPS += axi_pwm_gen_regmap.sv XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc XILINX_DEPS += axi_pwm_gen_constr.ttcl diff --git a/library/axi_pwm_gen/axi_pwm_gen.sv b/library/axi_pwm_gen/axi_pwm_gen.sv new file mode 100644 index 000000000..73284096b --- /dev/null +++ b/library/axi_pwm_gen/axi_pwm_gen.sv @@ -0,0 +1,394 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2021-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/master/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/100ps + +module axi_pwm_gen #( + + parameter ID = 0, + parameter ASYNC_CLK_EN = 1, + parameter N_PWMS = 1, + parameter PWM_EXT_SYNC = 0, + parameter EXT_ASYNC_SYNC = 0, + parameter PULSE_0_WIDTH = 7, + parameter PULSE_1_WIDTH = 7, + parameter PULSE_2_WIDTH = 7, + parameter PULSE_3_WIDTH = 7, + parameter PULSE_4_WIDTH = 7, + parameter PULSE_5_WIDTH = 7, + parameter PULSE_6_WIDTH = 7, + parameter PULSE_7_WIDTH = 7, + parameter PULSE_8_WIDTH = 7, + parameter PULSE_9_WIDTH = 7, + parameter PULSE_10_WIDTH = 7, + parameter PULSE_11_WIDTH = 7, + parameter PULSE_12_WIDTH = 7, + parameter PULSE_13_WIDTH = 7, + parameter PULSE_14_WIDTH = 7, + parameter PULSE_15_WIDTH = 7, + parameter PULSE_0_PERIOD = 10, + parameter PULSE_1_PERIOD = 10, + parameter PULSE_2_PERIOD = 10, + parameter PULSE_3_PERIOD = 10, + parameter PULSE_4_PERIOD = 10, + parameter PULSE_5_PERIOD = 10, + parameter PULSE_6_PERIOD = 10, + parameter PULSE_7_PERIOD = 10, + parameter PULSE_8_PERIOD = 10, + parameter PULSE_9_PERIOD = 10, + parameter PULSE_10_PERIOD = 10, + parameter PULSE_11_PERIOD = 10, + parameter PULSE_12_PERIOD = 10, + parameter PULSE_13_PERIOD = 10, + parameter PULSE_14_PERIOD = 10, + parameter PULSE_15_PERIOD = 10, + parameter PULSE_0_OFFSET = 0, + parameter PULSE_1_OFFSET = 0, + parameter PULSE_2_OFFSET = 0, + parameter PULSE_3_OFFSET = 0, + parameter PULSE_4_OFFSET = 0, + parameter PULSE_5_OFFSET = 0, + parameter PULSE_6_OFFSET = 0, + parameter PULSE_7_OFFSET = 0, + parameter PULSE_8_OFFSET = 0, + parameter PULSE_9_OFFSET = 0, + parameter PULSE_10_OFFSET = 0, + parameter PULSE_11_OFFSET = 0, + parameter PULSE_12_OFFSET = 0, + parameter PULSE_13_OFFSET = 0, + parameter PULSE_14_OFFSET = 0, + parameter PULSE_15_OFFSET = 0 +) ( + + // axi interface + + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [15:0] s_axi_awaddr, + input [ 2:0] s_axi_awprot, + output s_axi_awready, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [15:0] s_axi_araddr, + input [ 2:0] s_axi_arprot, + output s_axi_arready, + output s_axi_rvalid, + output [ 1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + input s_axi_rready, + input ext_clk, + input ext_sync, + + output pwm_0, + output pwm_1, + output pwm_2, + output pwm_3, + output pwm_4, + output pwm_5, + output pwm_6, + output pwm_7, + output pwm_8, + output pwm_9, + output pwm_10, + output pwm_11, + output pwm_12, + output pwm_13, + output pwm_14, + output pwm_15 +); + + // local parameters + + localparam PWMS = N_PWMS-1; + localparam [31:0] CORE_VERSION = {16'h0002, /* MAJOR */ + 8'h00, /* MINOR */ + 8'h00}; /* PATCH */ + localparam [31:0] CORE_MAGIC = 32'h601a3471; // PLSG + localparam reg [31:0] PULSE_WIDTH_G[15:0] = '{PULSE_0_WIDTH, + PULSE_1_WIDTH, + PULSE_2_WIDTH, + PULSE_3_WIDTH, + PULSE_4_WIDTH, + PULSE_5_WIDTH, + PULSE_6_WIDTH, + PULSE_7_WIDTH, + PULSE_8_WIDTH, + PULSE_9_WIDTH, + PULSE_10_WIDTH, + PULSE_11_WIDTH, + PULSE_12_WIDTH, + PULSE_13_WIDTH, + PULSE_14_WIDTH, + PULSE_15_WIDTH}; + + localparam reg [31:0] PULSE_PERIOD_G[0:15] = '{PULSE_0_PERIOD, + PULSE_1_PERIOD, + PULSE_2_PERIOD, + PULSE_3_PERIOD, + PULSE_4_PERIOD, + PULSE_5_PERIOD, + PULSE_6_PERIOD, + PULSE_7_PERIOD, + PULSE_8_PERIOD, + PULSE_9_PERIOD, + PULSE_10_PERIOD, + PULSE_11_PERIOD, + PULSE_12_PERIOD, + PULSE_13_PERIOD, + PULSE_14_PERIOD, + PULSE_15_PERIOD}; + + localparam reg [31:0] PULSE_OFFSET_G[0:15] = '{PULSE_0_OFFSET, + PULSE_1_OFFSET, + PULSE_2_OFFSET, + PULSE_3_OFFSET, + PULSE_4_OFFSET, + PULSE_5_OFFSET, + PULSE_6_OFFSET, + PULSE_7_OFFSET, + PULSE_8_OFFSET, + PULSE_9_OFFSET, + PULSE_10_OFFSET, + PULSE_11_OFFSET, + PULSE_12_OFFSET, + PULSE_13_OFFSET, + PULSE_14_OFFSET, + PULSE_15_OFFSET}; + + // internal registers + + reg [PWMS:0] sync; + reg [31:0] offset_cnt = 32'd0; + reg offset_alignment = 1'b0; + reg pause_cnt_d = 1'b0; + + // internal signals + + wire clk; + wire up_clk; + wire up_rstn; + wire up_rreq_s; + wire up_wack_s; + wire up_rack_s; + wire [ 13:0] up_raddr_s; + wire [ 31:0] up_rdata_s; + wire up_wreq_s; + wire [ 13:0] up_waddr_s; + wire [ 31:0] up_wdata_s; + wire [ 15:0] pwm; + wire [ 31:0] pwm_width_s[0:PWMS]; + wire [ 31:0] pwm_period_s[0:PWMS]; + wire [ 31:0] pwm_offset_s[0:PWMS]; + wire [ 15:0] pwm_armed; + wire load_config_s; + wire pwm_gen_resetn; + wire ext_sync_s; + wire pause_cnt; + + assign up_clk = s_axi_aclk; + assign up_rstn = s_axi_aresetn; + + axi_pwm_gen_regmap #( + .ID (ID), + .ASYNC_CLK_EN (ASYNC_CLK_EN), + .CORE_MAGIC (CORE_MAGIC), + .CORE_VERSION (CORE_VERSION), + .N_PWMS (PWMS), + .PULSE_WIDTH_G (PULSE_WIDTH_G), + .PULSE_PERIOD_G (PULSE_PERIOD_G), + .PULSE_OFFSET_G (PULSE_OFFSET_G) + ) i_regmap ( + .ext_clk (ext_clk), + .clk_out (clk), + .pwm_gen_resetn (pwm_gen_resetn), + .pwm_width (pwm_width_s), + .pwm_period (pwm_period_s), + .pwm_offset (pwm_offset_s), + .load_config (load_config_s), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + + // external sync + + generate + + reg ext_sync_m0 = 1'b1; + reg ext_sync_m1 = 1'b1; + + if (EXT_ASYNC_SYNC) begin + always @(posedge clk) begin + if (pwm_gen_resetn == 1'b0) begin + ext_sync_m0 <= 1'b1; + ext_sync_m1 <= 1'b1; + end else begin + ext_sync_m0 <= (PWM_EXT_SYNC == 1) ? ext_sync : 0; + ext_sync_m1 <= ext_sync_m0; + end + end + assign ext_sync_s = ext_sync_m1; + end else begin + assign ext_sync_s = (PWM_EXT_SYNC == 1) ? ext_sync : 0; + end + + endgenerate + + // offset counter + + always @(posedge clk) begin + if (offset_alignment == 1'b1 || pwm_gen_resetn == 1'b0) begin + offset_cnt <= 32'd0; + end else begin + offset_cnt <= offset_cnt + 1'b1; + end + + if (pwm_gen_resetn == 1'b0) begin + offset_alignment <= 1'b0; + end else begin + // when using external sync an offset alignment can be done only + // after all pwm counters are paused(load_config)/reseated + offset_alignment <= (load_config_s == 1'b1) ? 1'b1 : + offset_alignment & + (ext_sync_s ? 1'b1 : !pause_cnt); + end + end + + assign pause_cnt = ((pwm_armed[1] | + pwm_armed[2] | + pwm_armed[3] | + pwm_armed[4] | + pwm_armed[5] | + pwm_armed[6] | + pwm_armed[7] | + pwm_armed[8] | + pwm_armed[9] | + pwm_armed[10] | + pwm_armed[11] | + pwm_armed[12] | + pwm_armed[13] | + pwm_armed[14] | + pwm_armed[15] ) ? 1'b1 : 1'b0); + genvar i; + generate + for (i = 0; i <= 15; i = i + 1) begin: pwm_cnt + if (i <= PWMS) begin + axi_pwm_gen_1 #( + .PULSE_WIDTH (PULSE_WIDTH_G[i]), + .PULSE_PERIOD (PULSE_PERIOD_G[i]) + ) i_axi_pwm_gen_1 ( + .clk (clk), + .rstn (pwm_gen_resetn), + .pulse_width (pwm_width_s[i]), + .pulse_period (pwm_period_s[i]), + .load_config (load_config_s), + .sync (sync[i]), + .pulse (pwm[i]), + .pulse_armed (pwm_armed[i])); + always @(posedge clk) begin + if (pwm_gen_resetn == 1'b0) begin + sync[i] <= 1'b1; + end else begin + sync[i] <= (offset_cnt == pwm_offset_s[i]) ? 1'b0 : 1'b1; + end + end + end else begin + assign pwm[i] = 1'b0; + assign pwm_armed[i] = 1'b0; + end + end + endgenerate + + assign pwm_0 = pwm[0]; + assign pwm_1 = pwm[1]; + assign pwm_2 = pwm[2]; + assign pwm_3 = pwm[3]; + assign pwm_4 = pwm[4]; + assign pwm_5 = pwm[5]; + assign pwm_6 = pwm[6]; + assign pwm_7 = pwm[7]; + assign pwm_8 = pwm[8]; + assign pwm_9 = pwm[9]; + assign pwm_10 = pwm[10]; + assign pwm_11 = pwm[11]; + assign pwm_12 = pwm[12]; + assign pwm_13 = pwm[13]; + assign pwm_14 = pwm[14]; + assign pwm_15 = pwm[15]; + + up_axi #( + .AXI_ADDRESS_WIDTH(16) + ) i_up_axi ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + +endmodule diff --git a/library/axi_pwm_gen/axi_pwm_gen.v b/library/axi_pwm_gen/axi_pwm_gen.v deleted file mode 100644 index 14fc60b14..000000000 --- a/library/axi_pwm_gen/axi_pwm_gen.v +++ /dev/null @@ -1,356 +0,0 @@ -// *************************************************************************** -// *************************************************************************** -// Copyright (C) 2021-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/master/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/100ps - -module axi_pwm_gen #( - - parameter ID = 0, - parameter ASYNC_CLK_EN = 1, - parameter N_PWMS = 1, - parameter PWM_EXT_SYNC = 0, - parameter EXT_ASYNC_SYNC = 0, - parameter PULSE_0_WIDTH = 7, - parameter PULSE_1_WIDTH = 7, - parameter PULSE_2_WIDTH = 7, - parameter PULSE_3_WIDTH = 7, - parameter PULSE_0_PERIOD = 10, - parameter PULSE_1_PERIOD = 10, - parameter PULSE_2_PERIOD = 10, - parameter PULSE_3_PERIOD = 10, - parameter PULSE_0_OFFSET = 0, - parameter PULSE_1_OFFSET = 0, - parameter PULSE_2_OFFSET = 0, - parameter PULSE_3_OFFSET = 0 -) ( - - // axi interface - - input s_axi_aclk, - input s_axi_aresetn, - input s_axi_awvalid, - input [15:0] s_axi_awaddr, - input [ 2:0] s_axi_awprot, - output s_axi_awready, - input s_axi_wvalid, - input [31:0] s_axi_wdata, - input [ 3:0] s_axi_wstrb, - output s_axi_wready, - output s_axi_bvalid, - output [ 1:0] s_axi_bresp, - input s_axi_bready, - input s_axi_arvalid, - input [15:0] s_axi_araddr, - input [ 2:0] s_axi_arprot, - output s_axi_arready, - output s_axi_rvalid, - output [ 1:0] s_axi_rresp, - output [31:0] s_axi_rdata, - input s_axi_rready, - input ext_clk, - input ext_sync, - - output pwm_0, - output pwm_1, - output pwm_2, - output pwm_3 -); - - // local parameters - - localparam [31:0] CORE_VERSION = {16'h0001, /* MAJOR */ - 8'h00, /* MINOR */ - 8'h00}; /* PATCH */ - localparam [31:0] CORE_MAGIC = 32'h601a3471; // PLSG - - // internal registers - - reg sync_0 = 1'b0; - reg sync_1 = 1'b0; - reg sync_2 = 1'b0; - reg sync_3 = 1'b0; - reg [31:0] offset_cnt = 32'd0; - reg offset_alignment = 1'b0; - reg pause_cnt_d = 1'b0; - - // internal signals - - wire clk; - wire up_clk; - wire up_rstn; - wire up_rreq_s; - wire up_wack_s; - wire up_rack_s; - wire [ 13:0] up_raddr_s; - wire [ 31:0] up_rdata_s; - wire up_wreq_s; - wire [ 13:0] up_waddr_s; - wire [ 31:0] up_wdata_s; - wire [127:0] pwm_width_s; - wire [127:0] pwm_period_s; - wire [127:0] pwm_offset_s; - wire [ 31:0] pwm_counter[0:3]; - wire load_config_s; - wire pwm_gen_resetn; - wire ext_sync_s; - wire pause_cnt; - wire offset_alignment_ready; - - assign up_clk = s_axi_aclk; - assign up_rstn = s_axi_aresetn; - - axi_pwm_gen_regmap #( - .ID (ID), - .ASYNC_CLK_EN (ASYNC_CLK_EN), - .CORE_MAGIC (CORE_MAGIC), - .CORE_VERSION (CORE_VERSION), - .N_PWMS (N_PWMS), - .PULSE_0_WIDTH (PULSE_0_WIDTH), - .PULSE_1_WIDTH (PULSE_1_WIDTH), - .PULSE_2_WIDTH (PULSE_2_WIDTH), - .PULSE_3_WIDTH (PULSE_3_WIDTH), - .PULSE_0_PERIOD (PULSE_0_PERIOD), - .PULSE_1_PERIOD (PULSE_1_PERIOD), - .PULSE_2_PERIOD (PULSE_2_PERIOD), - .PULSE_3_PERIOD (PULSE_3_PERIOD), - .PULSE_0_OFFSET (PULSE_0_OFFSET), - .PULSE_1_OFFSET (PULSE_1_OFFSET), - .PULSE_2_OFFSET (PULSE_2_OFFSET), - .PULSE_3_OFFSET (PULSE_3_OFFSET) - ) i_regmap ( - .ext_clk (ext_clk), - .clk_out (clk), - .pwm_gen_resetn (pwm_gen_resetn), - .pwm_width (pwm_width_s), - .pwm_period (pwm_period_s), - .pwm_offset (pwm_offset_s), - .load_config (load_config_s), - .up_rstn (up_rstn), - .up_clk (up_clk), - .up_wreq (up_wreq_s), - .up_waddr (up_waddr_s), - .up_wdata (up_wdata_s), - .up_wack (up_wack_s), - .up_rreq (up_rreq_s), - .up_raddr (up_raddr_s), - .up_rdata (up_rdata_s), - .up_rack (up_rack_s)); - - // external sync - - generate - - reg ext_sync_m0 = 1'b1; - reg ext_sync_m1 = 1'b1; - - if (EXT_ASYNC_SYNC) begin - always @(posedge clk) begin - if (pwm_gen_resetn == 1'b0) begin - ext_sync_m0 <= 1'b1; - ext_sync_m1 <= 1'b1; - end else begin - ext_sync_m0 <= (PWM_EXT_SYNC == 1) ? ext_sync : 0; - ext_sync_m1 <= ext_sync_m0; - end - end - assign ext_sync_s = ext_sync_m1; - end else begin - assign ext_sync_s = (PWM_EXT_SYNC == 1) ? ext_sync : 0; - end - - endgenerate - - // offset counter - - always @(posedge clk) begin - if (offset_alignment == 1'b1 || pwm_gen_resetn == 1'b0) begin - offset_cnt <= 32'd0; - end else begin - offset_cnt <= offset_cnt + 1'b1; - end - - if (pwm_gen_resetn == 1'b0) begin - pause_cnt_d <= 1'b0; - offset_alignment <= 1'b0; - end else begin - pause_cnt_d <= pause_cnt_d; - - // when using external sync an offset alignment can be done only - // after all pwm counters are paused(load_config)/reseated - offset_alignment <= (load_config_s == 1'b1) ? 1'b1 : - offset_alignment & - (ext_sync_s ? 1'b1 : !offset_alignment_ready); - end - end - - assign pause_cnt = ((pwm_counter[0] == 32'd1 || - pwm_counter[1] == 32'd1 || - pwm_counter[2] == 32'd1 || - pwm_counter[3] == 32'd1) ? 1'b1 : 1'b0); - assign offset_alignment_ready = !pause_cnt_d & pause_cnt; - - axi_pwm_gen_1 #( - .PULSE_WIDTH (PULSE_0_WIDTH), - .PULSE_PERIOD (PULSE_0_PERIOD) - ) i0_axi_pwm_gen_1( - .clk (clk), - .rstn (pwm_gen_resetn), - .pulse_width (pwm_width_s[31:0]), - .pulse_period (pwm_period_s[31:0]), - .load_config (load_config_s), - .sync (sync_0), - .pulse (pwm_0), - .pulse_counter (pwm_counter[0])); - - always @(posedge clk) begin - if (pwm_gen_resetn == 1'b0) begin - sync_0 <= 1'b1; - end else begin - sync_0 <= (offset_cnt == pwm_offset_s[31:0]) ? 1'b0 : 1'b1; - end - end - - generate - - if (N_PWMS >= 2) begin - axi_pwm_gen_1 #( - .PULSE_WIDTH (PULSE_1_WIDTH), - .PULSE_PERIOD (PULSE_1_PERIOD) - ) i1_axi_pwm_gen_1( - .clk (clk), - .rstn (pwm_gen_resetn), - .pulse_width (pwm_width_s[63:32]), - .pulse_period (pwm_period_s[63:32]), - .load_config (load_config_s), - .sync (sync_1), - .pulse (pwm_1), - .pulse_counter (pwm_counter[1])); - - always @(posedge clk) begin - if (pwm_gen_resetn == 1'b0) begin - sync_1 <= 1'b1; - end else begin - sync_1 <= (offset_cnt == pwm_offset_s[63:32]) ? 1'b0 : 1'b1; - end - end - end else begin - assign pwm_1 = 1'b0; - assign pwm_counter[1] = 32'd1; - end - - if (N_PWMS >= 3) begin - axi_pwm_gen_1 #( - .PULSE_WIDTH (PULSE_2_WIDTH), - .PULSE_PERIOD (PULSE_2_PERIOD) - ) i2_axi_pwm_gen_1( - .clk (clk), - .rstn (pwm_gen_resetn), - .pulse_width (pwm_width_s[95:64]), - .pulse_period (pwm_period_s[95:64]), - .load_config (load_config_s), - .sync (sync_2), - .pulse (pwm_2), - .pulse_counter (pwm_counter[2])); - - always @(posedge clk) begin - if (pwm_gen_resetn == 1'b0) begin - sync_2 <= 1'b1; - end else begin - sync_2 <= (offset_cnt == pwm_offset_s[95:64]) ? 1'b0 : 1'b1; - end - end - end else begin - assign pwm_2 = 1'b0; - assign pwm_counter[2] = 32'd1; - end - - if (N_PWMS >= 4) begin - axi_pwm_gen_1 #( - .PULSE_WIDTH (PULSE_3_WIDTH), - .PULSE_PERIOD (PULSE_3_PERIOD) - ) i3_axi_pwm_gen_1( - .clk (clk), - .rstn (pwm_gen_resetn), - .pulse_width (pwm_width_s[127:96]), - .pulse_period (pwm_period_s[127:96]), - .load_config (load_config_s), - .sync (sync_3), - .pulse (pwm_3), - .pulse_counter (pwm_counter[3])); - - always @(posedge clk) begin - if (pwm_gen_resetn == 1'b0) begin - sync_3 <= 1'b1; - end else begin - sync_3 <= (offset_cnt == pwm_offset_s[127:96]) ? 1'b0 : 1'b1; - end - end - end else begin - assign pwm_3 = 1'b0; - assign pwm_counter[3] = 32'd1; - end - endgenerate - - up_axi #( - .AXI_ADDRESS_WIDTH(16) - ) i_up_axi ( - .up_rstn (up_rstn), - .up_clk (up_clk), - .up_axi_awvalid (s_axi_awvalid), - .up_axi_awaddr (s_axi_awaddr), - .up_axi_awready (s_axi_awready), - .up_axi_wvalid (s_axi_wvalid), - .up_axi_wdata (s_axi_wdata), - .up_axi_wstrb (s_axi_wstrb), - .up_axi_wready (s_axi_wready), - .up_axi_bvalid (s_axi_bvalid), - .up_axi_bresp (s_axi_bresp), - .up_axi_bready (s_axi_bready), - .up_axi_arvalid (s_axi_arvalid), - .up_axi_araddr (s_axi_araddr), - .up_axi_arready (s_axi_arready), - .up_axi_rvalid (s_axi_rvalid), - .up_axi_rresp (s_axi_rresp), - .up_axi_rdata (s_axi_rdata), - .up_axi_rready (s_axi_rready), - .up_wreq (up_wreq_s), - .up_waddr (up_waddr_s), - .up_wdata (up_wdata_s), - .up_wack (up_wack_s), - .up_rreq (up_rreq_s), - .up_raddr (up_raddr_s), - .up_rdata (up_rdata_s), - .up_rack (up_rack_s)); - -endmodule diff --git a/library/axi_pwm_gen/axi_pwm_gen_1.v b/library/axi_pwm_gen/axi_pwm_gen_1.v index 0ba775de7..c74f2266d 100644 --- a/library/axi_pwm_gen/axi_pwm_gen_1.v +++ b/library/axi_pwm_gen/axi_pwm_gen_1.v @@ -48,7 +48,7 @@ module axi_pwm_gen_1 #( input sync, output reg pulse, - output [31:0] pulse_counter + output pulse_armed ); // internal registers @@ -134,6 +134,6 @@ module axi_pwm_gen_1 #( end end - assign pulse_counter = pulse_period_cnt; + assign pulse_armed = phase_align_armed; endmodule diff --git a/library/axi_pwm_gen/axi_pwm_gen_hw.tcl b/library/axi_pwm_gen/axi_pwm_gen_hw.tcl index 42f60146b..558e2325d 100644 --- a/library/axi_pwm_gen/axi_pwm_gen_hw.tcl +++ b/library/axi_pwm_gen/axi_pwm_gen_hw.tcl @@ -19,9 +19,9 @@ ad_ip_files axi_pwm_gen [list \ $ad_hdl_dir/library/intel/common/up_rst_constr.sdc \ $ad_hdl_dir/library/util_cdc/util_cdc_constr.tcl \ axi_pwm_gen_constr.sdc \ - axi_pwm_gen_regmap.v \ + axi_pwm_gen_regmap.sv \ axi_pwm_gen_1.v \ - axi_pwm_gen.v] + axi_pwm_gen.sv] # parameters @@ -34,14 +34,50 @@ ad_ip_parameter PULSE_0_WIDTH INTEGER 7 ad_ip_parameter PULSE_1_WIDTH INTEGER 7 ad_ip_parameter PULSE_2_WIDTH INTEGER 7 ad_ip_parameter PULSE_3_WIDTH INTEGER 7 +ad_ip_parameter PULSE_4_WIDTH INTEGER 7 +ad_ip_parameter PULSE_5_WIDTH INTEGER 7 +ad_ip_parameter PULSE_6_WIDTH INTEGER 7 +ad_ip_parameter PULSE_7_WIDTH INTEGER 7 +ad_ip_parameter PULSE_8_WIDTH INTEGER 7 +ad_ip_parameter PULSE_9_WIDTH INTEGER 7 +ad_ip_parameter PULSE_10_WIDTH INTEGER 7 +ad_ip_parameter PULSE_11_WIDTH INTEGER 7 +ad_ip_parameter PULSE_12_WIDTH INTEGER 7 +ad_ip_parameter PULSE_13_WIDTH INTEGER 7 +ad_ip_parameter PULSE_14_WIDTH INTEGER 7 +ad_ip_parameter PULSE_15_WIDTH INTEGER 7 ad_ip_parameter PULSE_0_PERIOD INTEGER 10 ad_ip_parameter PULSE_1_PERIOD INTEGER 10 ad_ip_parameter PULSE_2_PERIOD INTEGER 10 ad_ip_parameter PULSE_3_PERIOD INTEGER 10 +ad_ip_parameter PULSE_4_PERIOD INTEGER 10 +ad_ip_parameter PULSE_5_PERIOD INTEGER 10 +ad_ip_parameter PULSE_6_PERIOD INTEGER 10 +ad_ip_parameter PULSE_7_PERIOD INTEGER 10 +ad_ip_parameter PULSE_8_PERIOD INTEGER 10 +ad_ip_parameter PULSE_9_PERIOD INTEGER 10 +ad_ip_parameter PULSE_10_PERIOD INTEGER 10 +ad_ip_parameter PULSE_11_PERIOD INTEGER 10 +ad_ip_parameter PULSE_12_PERIOD INTEGER 10 +ad_ip_parameter PULSE_13_PERIOD INTEGER 10 +ad_ip_parameter PULSE_14_PERIOD INTEGER 10 +ad_ip_parameter PULSE_15_PERIOD INTEGER 10 ad_ip_parameter PULSE_0_OFFSET INTEGER 0 ad_ip_parameter PULSE_1_OFFSET INTEGER 0 ad_ip_parameter PULSE_2_OFFSET INTEGER 0 ad_ip_parameter PULSE_3_OFFSET INTEGER 0 +ad_ip_parameter PULSE_4_OFFSET INTEGER 0 +ad_ip_parameter PULSE_5_OFFSET INTEGER 0 +ad_ip_parameter PULSE_6_OFFSET INTEGER 0 +ad_ip_parameter PULSE_7_OFFSET INTEGER 0 +ad_ip_parameter PULSE_8_OFFSET INTEGER 0 +ad_ip_parameter PULSE_9_OFFSET INTEGER 0 +ad_ip_parameter PULSE_10_OFFSET INTEGER 0 +ad_ip_parameter PULSE_11_OFFSET INTEGER 0 +ad_ip_parameter PULSE_12_OFFSET INTEGER 0 +ad_ip_parameter PULSE_13_OFFSET INTEGER 0 +ad_ip_parameter PULSE_14_OFFSET INTEGER 0 +ad_ip_parameter PULSE_15_OFFSET INTEGER 0 # interfaces @@ -53,6 +89,6 @@ ad_interface clock ext_clk input 1 ad_interface signal ext_sync input 1 # output signals -for {set i 0} {$i < 4} {incr i} { +for {set i 0} {$i < 16} {incr i} { ad_interface signal pwm_$i output 1 if_pwm } diff --git a/library/axi_pwm_gen/axi_pwm_gen_ip.tcl b/library/axi_pwm_gen/axi_pwm_gen_ip.tcl index 3a69c1d69..7dd864359 100644 --- a/library/axi_pwm_gen/axi_pwm_gen_ip.tcl +++ b/library/axi_pwm_gen/axi_pwm_gen_ip.tcl @@ -15,9 +15,9 @@ adi_ip_files axi_pwm_gen [list \ "$ad_hdl_dir/library/common/up_axi.v" \ "$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \ "axi_pwm_gen_constr.ttcl" \ - "axi_pwm_gen_regmap.v" \ + "axi_pwm_gen_regmap.sv" \ "axi_pwm_gen_1.v" \ - "axi_pwm_gen.v"] + "axi_pwm_gen.sv"] adi_ip_properties axi_pwm_gen adi_ip_ttcl axi_pwm_gen "axi_pwm_gen_constr.ttcl" @@ -100,8 +100,8 @@ set_property -dict [list \ "widget" "checkBox" \ ] [ipgui::get_guiparamspec -name "EXT_ASYNC_SYNC" -component $cc] -# Maximum 4 pwms -for {set i 0} {$i < 4} {incr i} { +# Maximum 16 pwms +for {set i 0} {$i < 16} {incr i} { ipgui::add_param -name "PULSE_${i}_WIDTH" -component $cc -parent $page0 set_property -dict [list \ "display_name" "PULSE $i width" \ @@ -142,7 +142,7 @@ for {set i 0} {$i < 4} {incr i} { [ipx::get_user_parameters PULSE_${i}_OFFSET -of_objects $cc] } -for {set i 1} {$i < 4} {incr i} { +for {set i 0} {$i < 16} {incr i} { adi_set_ports_dependency "pwm_$i" \ "(spirit:decode(id('MODELPARAM_VALUE.N_PWMS')) > $i)" } diff --git a/library/axi_pwm_gen/axi_pwm_gen_regmap.sv b/library/axi_pwm_gen/axi_pwm_gen_regmap.sv new file mode 100644 index 000000000..91a70304c --- /dev/null +++ b/library/axi_pwm_gen/axi_pwm_gen_regmap.sv @@ -0,0 +1,202 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2021-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/master/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/100ps + +module axi_pwm_gen_regmap #( + + parameter ID = 0, + parameter CORE_MAGIC = 0, + parameter CORE_VERSION = 0, + parameter ASYNC_CLK_EN = 1, + parameter N_PWMS = 0, + parameter reg [31:0] PULSE_WIDTH_G[0:15] = '{16{32'd0}}, + parameter reg [31:0] PULSE_PERIOD_G[0:15] = '{16{32'd0}}, + parameter reg [31:0] PULSE_OFFSET_G[0:15] = '{16{32'd0}} +) ( + + // external clock + + input ext_clk, + + // control and status signals + + output clk_out, + output pwm_gen_resetn, + output [31:0] pwm_width[0:N_PWMS], + output [31:0] pwm_period[0:N_PWMS], + output [31:0] pwm_offset[0:N_PWMS], + output load_config, + + // processor interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack +); + + // internal registers + + reg [31:0] up_scratch = 'd0; + reg [31:0] up_pwm_width[0:N_PWMS] = PULSE_WIDTH_G[0:N_PWMS]; + reg [31:0] up_pwm_period[0:N_PWMS] = PULSE_PERIOD_G[0:N_PWMS]; + reg [31:0] up_pwm_offset[0:N_PWMS] = PULSE_OFFSET_G[0:N_PWMS]; + reg up_load_config = 1'b0; + reg up_reset = 1'b1; + + genvar n; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_wack <= 'd0; + up_scratch <= 'd0; + up_pwm_width = PULSE_WIDTH_G[0:N_PWMS]; + up_pwm_period = PULSE_PERIOD_G[0:N_PWMS]; + up_pwm_offset = PULSE_OFFSET_G[0:N_PWMS]; + up_load_config <= 1'b0; + up_reset <= 1'b1; + end else begin + up_wack <= up_wreq; + if ((up_wreq == 1'b1) && (up_waddr == 14'h2)) begin + up_scratch <= up_wdata; + end + if ((up_wreq == 1'b1) && (up_waddr == 14'h4)) begin + up_reset <= up_wdata[0]; + up_load_config <= up_wdata[1]; + end else begin + up_load_config <= 1'b0; + end + for (int i = 0; i <= N_PWMS; i++) begin + if ((up_wreq == 1'b1) && (up_waddr == 14'h10 + i)) begin + up_pwm_period[i] <= up_wdata; + end + if ((up_wreq == 1'b1) && (up_waddr == 14'h20 + i)) begin + up_pwm_width[i] <= up_wdata; + end + if ((up_wreq == 1'b1) && (up_waddr == 14'h30 + i)) begin + up_pwm_offset[i] <= up_wdata; + end + end + end + end + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq; + if (up_rreq == 1'b1) begin + if (up_raddr[13:4] == 10'd0) begin + case (up_raddr) + 14'h0: up_rdata <= CORE_VERSION; + 14'h1: up_rdata <= ID; + 14'h2: up_rdata <= up_scratch; + 14'h3: up_rdata <= CORE_MAGIC; + 14'h4: up_rdata <= up_reset; + 14'h5: up_rdata <= N_PWMS +1; + default: up_rdata <= 0; + endcase + end else if (up_raddr[3:0] > N_PWMS) begin + up_rdata <= 32'b0; + end else if (up_raddr[13:4] == 10'd1) begin + up_rdata <= up_pwm_period[up_raddr[3:0]]; + end else if (up_raddr[13:4] == 10'd2) begin + up_rdata <= up_pwm_width[up_raddr[3:0]]; + end else if (up_raddr[13:4] == 10'd3) begin + up_rdata <= up_pwm_offset[up_raddr[3:0]]; + end + end else begin + up_rdata <= 32'd0; + end + end + end + + generate + if (ASYNC_CLK_EN) begin : counter_external_clock + + assign clk_out = ext_clk; + + ad_rst i_d_rst_reg ( + .rst_async (up_reset), + .clk (clk_out), + .rstn (pwm_gen_resetn), + .rst ()); + + for (n = 0; n <= N_PWMS; n = n + 1) begin: up_to_adc_cdc + sync_data #( + .NUM_OF_BITS (96), + .ASYNC_CLK (1)) + i_pwm_props ( + .in_clk (up_clk), + .in_data ({up_pwm_period[n], + up_pwm_width[n], + up_pwm_offset[n]}), + .out_clk (clk_out), + .out_data ({pwm_period[n], + pwm_width[n], + pwm_offset[n]})); + end + + sync_event #( + .NUM_OF_EVENTS (1), + .ASYNC_CLK (1) + ) i_load_config_sync ( + .in_clk (up_clk), + .in_event (up_load_config), + .out_clk (clk_out), + .out_event (load_config)); + + end else begin : counter_sys_clock // counter is running on system clk + + assign clk_out = up_clk; + assign pwm_gen_resetn = ~up_reset; + for (n = 0; n <= N_PWMS; n = n + 1) begin: up_cd + assign pwm_period[n] = up_pwm_period[n]; + assign pwm_width[n] = up_pwm_width[n]; + assign pwm_offset[n] = up_pwm_offset[n]; + end + assign load_config = up_load_config; + + end + endgenerate + +endmodule diff --git a/library/axi_pwm_gen/axi_pwm_gen_regmap.v b/library/axi_pwm_gen/axi_pwm_gen_regmap.v deleted file mode 100644 index 0d81d0664..000000000 --- a/library/axi_pwm_gen/axi_pwm_gen_regmap.v +++ /dev/null @@ -1,274 +0,0 @@ -// *************************************************************************** -// *************************************************************************** -// Copyright (C) 2021-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/master/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/100ps - -module axi_pwm_gen_regmap #( - - parameter ID = 0, - parameter CORE_MAGIC = 0, - parameter CORE_VERSION = 0, - parameter ASYNC_CLK_EN = 1, - parameter N_PWMS = 3, - parameter PULSE_0_WIDTH = 7, - parameter PULSE_1_WIDTH = 7, - parameter PULSE_2_WIDTH = 7, - parameter PULSE_3_WIDTH = 7, - parameter PULSE_0_PERIOD = 10, - parameter PULSE_1_PERIOD = 10, - parameter PULSE_2_PERIOD = 10, - parameter PULSE_3_PERIOD = 10, - parameter PULSE_0_EXT_SYNC = 0, - parameter PULSE_0_OFFSET = 0, - parameter PULSE_1_OFFSET = 0, - parameter PULSE_2_OFFSET = 0, - parameter PULSE_3_OFFSET = 0 -) ( - - // external clock - - input ext_clk, - - // control and status signals - - output clk_out, - output pwm_gen_resetn, - output [127:0] pwm_width, - output [127:0] pwm_period, - output [127:0] pwm_offset, - output load_config, - - // processor interface - - input up_rstn, - input up_clk, - input up_wreq, - input [13:0] up_waddr, - input [31:0] up_wdata, - output reg up_wack, - input up_rreq, - input [13:0] up_raddr, - output reg [31:0] up_rdata, - output reg up_rack -); - - // internal registers - - reg [31:0] up_scratch = 'd0; - reg [31:0] up_pwm_width_0 = PULSE_0_WIDTH; - reg [31:0] up_pwm_width_1 = PULSE_1_WIDTH; - reg [31:0] up_pwm_width_2 = PULSE_2_WIDTH; - reg [31:0] up_pwm_width_3 = PULSE_3_WIDTH; - reg [31:0] up_pwm_period_0 = PULSE_0_PERIOD; - reg [31:0] up_pwm_period_1 = PULSE_1_PERIOD; - reg [31:0] up_pwm_period_2 = PULSE_2_PERIOD; - reg [31:0] up_pwm_period_3 = PULSE_3_PERIOD; - reg [31:0] up_pwm_offset_0 = PULSE_0_OFFSET; - reg [31:0] up_pwm_offset_1 = PULSE_1_OFFSET; - reg [31:0] up_pwm_offset_2 = PULSE_2_OFFSET; - reg [31:0] up_pwm_offset_3 = PULSE_3_OFFSET; - reg up_load_config = 1'b0; - reg up_reset = 1'b1; - - always @(posedge up_clk) begin - if (up_rstn == 0) begin - up_wack <= 'd0; - up_scratch <= 'd0; - up_pwm_width_0 <= PULSE_0_WIDTH; - up_pwm_width_1 <= PULSE_1_WIDTH; - up_pwm_width_2 <= PULSE_2_WIDTH; - up_pwm_width_3 <= PULSE_3_WIDTH; - up_pwm_period_0 <= PULSE_0_PERIOD; - up_pwm_period_1 <= PULSE_1_PERIOD; - up_pwm_period_2 <= PULSE_2_PERIOD; - up_pwm_period_3 <= PULSE_3_PERIOD; - up_pwm_offset_0 <= PULSE_0_OFFSET; - up_pwm_offset_1 <= PULSE_1_OFFSET; - up_pwm_offset_2 <= PULSE_2_OFFSET; - up_pwm_offset_3 <= PULSE_3_OFFSET; - up_load_config <= 1'b0; - up_reset <= 1'b1; - end else begin - up_wack <= up_wreq; - if ((up_wreq == 1'b1) && (up_waddr == 14'h2)) begin - up_scratch <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h4)) begin - up_reset <= up_wdata[0]; - up_load_config <= up_wdata[1]; - end else begin - up_load_config <= 1'b0; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h10)) begin - up_pwm_period_0 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h11)) begin - up_pwm_width_0 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h12)) begin - up_pwm_offset_0 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h13)) begin - up_pwm_period_1 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h14)) begin - up_pwm_width_1 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h15)) begin - up_pwm_offset_1 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h16)) begin - up_pwm_period_2 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h17)) begin - up_pwm_width_2 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h18)) begin - up_pwm_offset_2 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h19)) begin - up_pwm_period_3 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h1a)) begin - up_pwm_width_3 <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr == 14'h1b)) begin - up_pwm_offset_3 <= up_wdata; - end - end - end - - always @(posedge up_clk) begin - if (up_rstn == 0) begin - up_rack <= 'd0; - up_rdata <= 'd0; - end else begin - up_rack <= up_rreq; - if (up_rreq == 1'b1) begin - case (up_raddr) - 14'h0: up_rdata <= CORE_VERSION; - 14'h1: up_rdata <= ID; - 14'h2: up_rdata <= up_scratch; - 14'h3: up_rdata <= CORE_MAGIC; - 14'h4: up_rdata <= up_reset; - 14'h5: up_rdata <= N_PWMS; - 14'h10: up_rdata <= up_pwm_period_0; - 14'h11: up_rdata <= up_pwm_width_0; - 14'h12: up_rdata <= up_pwm_offset_0; - 14'h13: up_rdata <= up_pwm_period_1; - 14'h14: up_rdata <= up_pwm_width_1; - 14'h15: up_rdata <= up_pwm_offset_1; - 14'h16: up_rdata <= up_pwm_period_2; - 14'h17: up_rdata <= up_pwm_width_2; - 14'h18: up_rdata <= up_pwm_offset_2; - 14'h19: up_rdata <= up_pwm_period_3; - 14'h1a: up_rdata <= up_pwm_width_3; - 14'h1b: up_rdata <= up_pwm_offset_3; - default: up_rdata <= 0; - endcase - end else begin - up_rdata <= 32'd0; - end - end - end - - generate - if (ASYNC_CLK_EN) begin : counter_external_clock - - assign clk_out = ext_clk; - - ad_rst i_d_rst_reg ( - .rst_async (up_reset), - .clk (clk_out), - .rstn (pwm_gen_resetn), - .rst ()); - - sync_data #( - .NUM_OF_BITS (128), - .ASYNC_CLK (1) - ) i_pwm_period_sync ( - .in_clk (up_clk), - .in_data ({up_pwm_period_3, - up_pwm_period_2, - up_pwm_period_1, - up_pwm_period_0}), - .out_clk (clk_out), - .out_data (pwm_period)); - - sync_data #( - .NUM_OF_BITS (128), - .ASYNC_CLK (1) - ) i_pwm_width_sync ( - .in_clk (up_clk), - .in_data ({up_pwm_width_3, - up_pwm_width_2, - up_pwm_width_1, - up_pwm_width_0}), - .out_clk (clk_out), - .out_data (pwm_width)); - - sync_data #( - .NUM_OF_BITS (128), - .ASYNC_CLK (1) - ) i_pwm_offset_sync ( - .in_clk (up_clk), - .in_data ({up_pwm_offset_3, - up_pwm_offset_2, - up_pwm_offset_1, - up_pwm_offset_0}), - .out_clk (clk_out), - .out_data (pwm_offset)); - - sync_event #( - .NUM_OF_EVENTS (1), - .ASYNC_CLK (1) - ) i_load_config_sync ( - .in_clk (up_clk), - .in_event (up_load_config), - .out_clk (clk_out), - .out_event (load_config)); - - end else begin : counter_sys_clock // counter is running on system clk - - assign clk_out = up_clk; - assign pwm_gen_resetn = ~up_reset; - assign pwm_period = {up_pwm_period_3, up_pwm_period_2, up_pwm_period_1, up_pwm_period_0}; - assign pwm_width = {up_pwm_width_3, up_pwm_width_2, up_pwm_width_1, up_pwm_width_0}; - assign pwm_offset = {up_pwm_offset_3, up_pwm_offset_2, up_pwm_offset_1, up_pwm_offset_0}; - assign load_config = up_load_config; - - end - endgenerate - -endmodule