我正在尝试设计一个工作在250 PWM输入时钟的PWM+死区。(我需要250 PWM左右的PWM频率。用于自定义降压调节器)
这就是我到目前为止使用来自网格的IceCube2,使用iCE40LP1K设备实现的东西。最高频率得到(模拟)的是142 MHz最坏情况和260 Mhz最佳情况(-40°)。
我想知道这是否是包括互补输出死区的PWM发生器的正确方法,或者换句话说,这是否可以改进得更多。
module top(
input clk_16,
input [9:0] data_in,
output reg PWM_H,
output reg PWM_L
);
reg [9:0] compare;
reg [9:0] counter = 0;
always @(posedge PLLOUTCORE)
begin
compare <= data_in;
end
always@ (posedge PLLOUTCORE )
begin
if ( counter < compare )
PWM_H <= 1;
else // >= compare
PWM_H <= 0;
if ( counter == compare + 16 )
PWM_L <= 1;
if ( counter == (1024-16) )
PWM_L <= 0;
counter <= counter+1;
end发布于 2020-12-04 12:01:50
这是一个有点开放式的问题,有点基于观点,但是,因为你问的是带有死区的PWM,我会用一个例子来回答,并指出我在你的代码中看到的IMHO是糟糕的做法。
你对PWM_H的赋值就是一个很好的例子,你有一个IF和ELSE IF来设置PWM_H,你写PWM_L的方式不是很好,这种风格可能会导致合成错误。如果两个独立的if赋值相同的变量,如果这两个IF恰好同时为真,则可能会出现多驱动问题。你可能认为/知道事实并非如此,但不要去做。如果合成器检测到这一点,它很可能会抛出一个错误。取而代之的是重写IF和ELSE IF,就像对PWM_H所做的那样。
接下来,我得到了reg counter=0将为模拟重置计数器,但显然不是为了合成。这将在您的情况下工作,因为您使用的是完整的计数,并且它实际上将是一个非常快速的合成计数器。
我在下面写了一个例子,并使用了参数。这只是一个个人选择,但如果你以后想要调整的话,这确实会让事情变得很酷。我有一些额外的代码,因为当我模拟它时,我发现在偏移量设置的极端处发生了糟糕的事情。
与您的代码非常相似,我的PWM_L比PWM_H稍微复杂一些,但请注意,我将它放在一条语句中,而不是两条语句中,因此不可能实现多驱动程序。
module pwm_db
(input clk,
input reset,
input [9:0] offset,
output pwm_l,
output pwm_h
);
reg [9:0] counter = 0;
reg [9:0] proc_offset;
reg pwm_ld;
reg pwm_hd;
parameter COUNTER_MAX = 1024-1;
parameter DEADBAND_WIDTH = 16;
parameter DB_X2 = DEADBAND_WIDTH * 2;
parameter COUNTER_DB = COUNTER_MAX - DEADBAND_WIDTH;
// Limit the offset internally to keep the deadband from being over written
// Burning some registers for this to increase final synthesis speed.
always @ (posedge clk)
begin
proc_offset <= (offset >= DB_X2) && (offset <= COUNTER_MAX - DB_X2) ? offset :
offset < DB_X2 ? DB_X2 : COUNTER_MAX - DB_X2;
end
always @ (posedge clk)
begin
counter <= counter + 10'h001;
pwm_hd <= counter < proc_offset - DEADBAND_WIDTH; // on initially and turn off a DB width prior to offset
pwm_ld <= counter > proc_offset && counter < COUNTER_DB; // on at offset and off DW width prior to max count;
end
assign pwm_h = pwm_hd;
assign pwm_l = pwm_ld;
endmodulehttps://stackoverflow.com/questions/65133267
复制相似问题