Skip to content

Commit

Permalink
axi_pwm_gen: Add support for 8 channels
Browse files Browse the repository at this point in the history
Signed-off-by: Alin-Tudor Sferle <[email protected]>
  • Loading branch information
alin724 committed Nov 7, 2023
1 parent a806a6f commit 7b972d1
Show file tree
Hide file tree
Showing 4 changed files with 232 additions and 143 deletions.
205 changes: 92 additions & 113 deletions library/axi_pwm_gen/axi_pwm_gen.v
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,26 @@ module axi_pwm_gen #(
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_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_0_OFFSET = 0,
parameter PULSE_1_OFFSET = 0,
parameter PULSE_2_OFFSET = 0,
parameter PULSE_3_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
) (

// axi interface
Expand Down Expand Up @@ -84,7 +96,11 @@ module axi_pwm_gen #(
output pwm_0,
output pwm_1,
output pwm_2,
output pwm_3
output pwm_3,
output pwm_4,
output pwm_5,
output pwm_6,
output pwm_7
);

// local parameters
Expand All @@ -93,13 +109,26 @@ module axi_pwm_gen #(
8'h00, /* MINOR */
8'h00}; /* PATCH */
localparam [31:0] CORE_MAGIC = 32'h601a3471; // PLSG
localparam [N_PWMS*32-1:0] PULSE_WIDTH = (N_PWMS == 1) ? PULSE_0_WIDTH :
(N_PWMS == 2 ? {PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 3 ? {PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 4 ? {PULSE_3_WIDTH,PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 5 ? {PULSE_4_WIDTH,PULSE_3_WIDTH,PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 6 ? {PULSE_5_WIDTH,PULSE_4_WIDTH,PULSE_3_WIDTH,PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 7 ? {PULSE_6_WIDTH,PULSE_5_WIDTH,PULSE_4_WIDTH,PULSE_3_WIDTH,PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} :
(N_PWMS == 8 ? {PULSE_7_WIDTH,PULSE_6_WIDTH,PULSE_5_WIDTH,PULSE_4_WIDTH,PULSE_3_WIDTH,PULSE_2_WIDTH,PULSE_1_WIDTH,PULSE_0_WIDTH} : 'b0)))))));
localparam [N_PWMS*32-1:0] PULSE_PERIOD = (N_PWMS == 1) ? PULSE_0_PERIOD :
(N_PWMS == 2 ? {PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 3 ? {PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 4 ? {PULSE_3_PERIOD,PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 5 ? {PULSE_4_PERIOD,PULSE_3_PERIOD,PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 6 ? {PULSE_5_PERIOD,PULSE_4_PERIOD,PULSE_3_PERIOD,PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 7 ? {PULSE_6_PERIOD,PULSE_5_PERIOD,PULSE_4_PERIOD,PULSE_3_PERIOD,PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} :
(N_PWMS == 8 ? {PULSE_7_PERIOD,PULSE_6_PERIOD,PULSE_5_PERIOD,PULSE_4_PERIOD,PULSE_3_PERIOD,PULSE_2_PERIOD,PULSE_1_PERIOD,PULSE_0_PERIOD} : 'b0)))))));

// internal registers

reg sync_0 = 1'b0;
reg sync_1 = 1'b0;
reg sync_2 = 1'b0;
reg sync_3 = 1'b0;
reg sync [N_PWMS-1:0];
reg [31:0] offset_cnt = 32'd0;
reg offset_alignment = 1'b0;
reg pause_cnt_d = 1'b0;
Expand All @@ -117,10 +146,11 @@ module axi_pwm_gen #(
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 [N_PWMS-1:0] pwm;
wire [N_PWMS*32-1:0] pwm_width_s;
wire [N_PWMS*32-1:0] pwm_period_s;
wire [N_PWMS*32-1:0] pwm_offset_s;
wire [N_PWMS*32-1:0] pwm_counter[0:N_PWMS-1];
wire load_config_s;
wire pwm_gen_resetn;
wire ext_sync_s;
Expand All @@ -140,14 +170,26 @@ module axi_pwm_gen #(
.PULSE_1_WIDTH (PULSE_1_WIDTH),
.PULSE_2_WIDTH (PULSE_2_WIDTH),
.PULSE_3_WIDTH (PULSE_3_WIDTH),
.PULSE_4_WIDTH (PULSE_4_WIDTH),
.PULSE_5_WIDTH (PULSE_5_WIDTH),
.PULSE_6_WIDTH (PULSE_6_WIDTH),
.PULSE_7_WIDTH (PULSE_7_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_4_PERIOD (PULSE_4_PERIOD),
.PULSE_5_PERIOD (PULSE_5_PERIOD),
.PULSE_6_PERIOD (PULSE_6_PERIOD),
.PULSE_7_PERIOD (PULSE_7_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)
.PULSE_3_OFFSET (PULSE_3_OFFSET),
.PULSE_4_OFFSET (PULSE_4_OFFSET),
.PULSE_5_OFFSET (PULSE_5_OFFSET),
.PULSE_6_OFFSET (PULSE_6_OFFSET),
.PULSE_7_OFFSET (PULSE_7_OFFSET)
) i_regmap (
.ext_clk (ext_clk),
.clk_out (clk),
Expand Down Expand Up @@ -214,114 +256,51 @@ module axi_pwm_gen #(
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 pause_cnt = (N_PWMS == 1) ? (pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 2 ? (pwm_counter[0] || pwm_counter[1] ? 1'b1 : 1'b0) :
(N_PWMS == 3 ? (pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 4 ? (pwm_counter[3] || pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 5 ? (pwm_counter[4] || pwm_counter[3] || pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 6 ? (pwm_counter[5] || pwm_counter[4] || pwm_counter[3] || pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 7 ? (pwm_counter[6] || pwm_counter[5] || pwm_counter[4] || pwm_counter[3] || pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) :
(N_PWMS == 8 ? (pwm_counter[7] || pwm_counter[6] || pwm_counter[5] || pwm_counter[4] || pwm_counter[3] || pwm_counter[2] || pwm_counter[1] || pwm_counter[0] ? 1'b1 : 1'b0) : 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;
genvar i;
for (i = 0; i < N_PWMS; i = i + 1) begin
axi_pwm_gen_1 #(
.PULSE_WIDTH (PULSE_WIDTH[i*32+31:i*32]),
.PULSE_PERIOD (PULSE_PERIOD[i*32+1:i*32])
) i_axi_pwm_gen_1(
.clk (clk),
.rstn (pwm_gen_resetn),
.pulse_width (pwm_width_s[i*32+31:i*32]),
.pulse_period (pwm_period_s[i*32+31:i*32]),
.load_config (load_config_s),
.sync (sync[i]),
.pulse (pwm[i]),
.pulse_counter (pwm_counter[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*32+31:i*32]) ? 1'b0 : 1'b1;
end
end
end
endgenerate

assign pwm_0 = (N_PWMS >= 1) ? pwm[0] : 1'b0;
assign pwm_1 = (N_PWMS >= 2) ? pwm[1] : 1'b0;
assign pwm_2 = (N_PWMS >= 3) ? pwm[2] : 1'b0;
assign pwm_3 = (N_PWMS >= 4) ? pwm[3] : 1'b0;
assign pwm_4 = (N_PWMS >= 5) ? pwm[4] : 1'b0;
assign pwm_5 = (N_PWMS >= 6) ? pwm[5] : 1'b0;
assign pwm_6 = (N_PWMS >= 7) ? pwm[6] : 1'b0;
assign pwm_7 = (N_PWMS >= 8) ? pwm[7] : 1'b0;

up_axi #(
.AXI_ADDRESS_WIDTH(16)
) i_up_axi (
Expand Down
14 changes: 13 additions & 1 deletion library/axi_pwm_gen/axi_pwm_gen_hw.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,26 @@ 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_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_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

# interfaces

Expand All @@ -53,6 +65,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 < 8} {incr i} {
ad_interface signal pwm_$i output 1 if_pwm
}
7 changes: 1 addition & 6 deletions library/axi_pwm_gen/axi_pwm_gen_ip.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ set_property -dict [list \
] [ipgui::get_guiparamspec -name "EXT_ASYNC_SYNC" -component $cc]

# Maximum 4 pwms
for {set i 0} {$i < 4} {incr i} {
for {set i 0} {$i < 8} {incr i} {
ipgui::add_param -name "PULSE_${i}_WIDTH" -component $cc -parent $page0
set_property -dict [list \
"display_name" "PULSE $i width" \
Expand Down Expand Up @@ -142,11 +142,6 @@ 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} {
adi_set_ports_dependency "pwm_$i" \
"(spirit:decode(id('MODELPARAM_VALUE.N_PWMS')) > $i)"
}

adi_set_ports_dependency "ext_sync" \
"(spirit:decode(id('MODELPARAM_VALUE.PWM_EXT_SYNC')) == 1)"

Expand Down
Loading

0 comments on commit 7b972d1

Please sign in to comment.