一个简单的PWM发生和捕获Verilog IP设计

这次IP的设计是有一个非常现实的应用需求的,在测试系统中,我们需要对芯片出来的PWM进行捕获或者对芯片出来的频率信号进行计算,另外还需要产生一定的PWM波形激励,用于测试芯片的PWM捕获功能,不过这里只是提供简单的PWM输出,诸如对称PWM,多通道同步等功能,这里暂时没有实现。

首先我们来看看PWM波形捕获的设计,具体的需求是要计算输入信号的频率和占空比信息。简单的想法就是用一个计数器对波形进行计数就可以了。对于频率的计算,一般通过计数也可以实现,不过这种方式只能捕获频率低于我们时钟输入频率的信号(一般只能到四分之一左右)。另外一种方法我称为双时钟计数法,也就是用两个时钟驱动两个计数器,计数到一定时间之后,对比两个计数器的计数结果就可以得到两个频率的关系,这种方式可以用一个比较低的时钟测量一个很高频率的时钟,不过对于FPGA来说,会有多驱动的问题,所以这里就不用这种方式了。

采用计数器对波形进行计数的方式,我们可以很容易的写出下面的Verilog代码:

module pwm_in(
    input clk,
    input rst_n,
    input pwm,
    output [31:0]pos_out,
    output [31:0]neg_out
);

reg [31:0] pos_out;
reg [31:0] neg_out;

reg [31:0] pos_cnt;
reg [31:0] neg_cnt;
reg pwm_r1, pwm_r2;

wire pwm_rising_edge;
wire pwm_falling_edge;

assign pwm_rising_edge = pwm_r1 & (~pwm_r2);
assign pwm_falling_edge = pwm_r2 & (~pwm_r1);

[email protected](posedge clk) begin
    pwm_r1 <= pwm;
    pwm_r2 <= pwm_r1;
end

[email protected](posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        pos_cnt <= 32'h0;
        pos_out <= 32'h0;
        neg_cnt <= 32'h0;
        neg_out <= 32'h0;
    end
    else begin
        // when reaches rising edge, load counter value to read buffer
        neg_out <= pwm_rising_edge ? neg_cnt : neg_out;
        pos_out <= pwm_falling_edge ? pos_cnt : pos_out;
        // neg_cnt increase when input keeps low
        neg_cnt <= pwm_rising_edge ? 32'h0 : (neg_cnt + !pwm);
        pos_cnt <= pwm_falling_edge ? 32'h0 : (pos_cnt + pwm);
    end
end

endmodule 

这里采用了打两拍的方式对波形的边沿进行采集,并将边沿的脉冲信号作为计数器清零和计数结果保存的触发信号。模块功能简单,够用就好,这里针对正负沿都用了一组计数器,这样做的好处是可以采集正负脉冲信号。

对于PWM波形的输出就更为简单了,直接上代码:

module pwm_out(
    input clk,
    input rst_n,
    input [31:0]mod_value,
    input [31:0]compare_value,
    output pwm_out
);
reg [31:0] counter;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        counter <= 32'h0;
    else
        counter <= (counter == mod_value) ? 32'h0 : (counter + 1'b1);
end

assign pwm_out = compare_value > counter;

endmodule

直接一个模计数器,计数结果和比较值进行比较就好了,简单粗暴,没有烦恼。并且计数器位宽足够,也就省去了分频的麻烦了。

相关文章

发表新评论