题解 | #占空比50%的奇数分频#

占空比50%的奇数分频

https://www.nowcoder.com/practice/ccfba5e5785f4b3f9d7ac19ab13d6b31

之前一直是这样写的:
`timescale 1ns/1ns

module odo_div_or
   (
    input    wire  rst ,
    input    wire  clk_in,
    output   wire  clk_out7
    );

//*************code***********//

    reg [2:0] cnt_p, cnt_n;

    always@(posedge clk_in or negedge rst) begin
        if(!rst) begin
            cnt_p <= 'd0;
        end
        else begin
            cnt_p <= (cnt_p=='d6)?'d0:(cnt_p+'d1);
        end
    end

    always@(negedge clk_in or negedge rst) begin
        if(!rst) begin
            cnt_n <= 'd0;
        end
        else begin
            cnt_n <= (cnt_n=='d6)?'d0:(cnt_n+'d1);
        end
    end

    assign clk_out7 = (cnt_p>='d3) & (cnt_n>='d3);

//*************code***********//
endmodule
后来发现上面这种写法会有问题,因为cnt_p和cnt_n是不断在跳变的,如果直接通过组合逻辑
assign clk_out7 = (cnt_p>='d3) & (cnt_n>='d3);
赋值,输出的时钟可能会有毛刺,因此需要改成判断相等关系的写法:
`timescale 1ns/1ns

module odo_div_or
   (
    input    wire  rst ,
    input    wire  clk_in,
    output   wire  clk_out7
    );

//*************code***********//

    reg [2:0] cnt;

    always@(posedge clk_in or negedge rst) begin
        if(!rst) begin
            cnt <= 'd0;
        end
        else begin
            cnt <= (cnt=='d6)?'d0:(cnt + 'd1);
        end
    end

    reg clk_p, clk_n;
    always@(posedge clk_in or negedge rst) begin
        if(!rst) begin
            clk_p <= 1'b0;
        end
        else begin
            clk_p <= ((cnt=='d3)|(cnt=='d6))?(~clk_p):clk_p;
        end
    end
    always@(negedge clk_in or negedge rst) begin
        if(!rst) begin
            clk_n <= 1'b0;
        end
        else begin
            clk_n <= ((cnt=='d3)|(cnt=='d6))?(~clk_n):clk_n;
        end
    end

    assign clk_out7 = clk_p | clk_n;

//*************code***********//
endmodule
或者:
`timescale 1ns/1ns

module odo_div_or
   (
    input    wire  rst ,
    input    wire  clk_in,
    output   wire  clk_out7
    );

//*************code***********//

    reg [2:0] cnt;

    always@(posedge clk_in or negedge rst) begin
        if(!rst) begin
            cnt <= 'd0;
        end
        else begin
            cnt <= (cnt=='d6)?'d0:(cnt + 'd1);
        end
    end

    reg clk_p, clk_n;
    always@(posedge clk_in or negedge rst) begin
        if(!rst) begin
            clk_p <= 1'b0;
        end
        else begin
            clk_p <= ((cnt=='d2)|(cnt=='d6))?(~clk_p):clk_p;
        end
    end
    always@(negedge clk_in or negedge rst) begin
        if(!rst) begin
            clk_n <= 1'b0;
        end
        else begin
            clk_n <= ((cnt=='d2)|(cnt=='d6))?(~clk_n):clk_n;
        end
    end

    assign clk_out7 = clk_p & clk_n;

//*************code***********//
endmodule




全部评论
或者输出加一级寄存器也可以避免毛刺。
点赞 回复 分享
发布于 2022-09-18 17:57 上海

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务