数字IC设计verilog编写——2如何优雅的写出分频器RTL设计(续)

上一篇文章介绍了有关分频器的RTL设计,有细心的读者可以发现RTL代码并不完善,如何对RTL改进,优雅的写出RTL,让面试官对你的coding style有深刻的印象,并认为你的基础扎实;

下面先看这个例子:

使用Verilog语言编写7分频的RTL设计:

module div_old_7(    //define div = N
    input    clk,
    input    rstn,
    output   o_clk
);
	 parameter N = 7;

    reg    [2:0]  clk_cnt_pos, clk_cnt_neg;
    reg          pos_clk, neg_clk;

	 //pos_edge clk cnt
    always @(posedge clk ) begin
        if (!rstn)
            clk_cnt_pos <= 3'b0;
        else if (clk_cnt_pos == N-1)
            clk_cnt_pos <= 3'b0;
        else
            clk_cnt_pos <= clk_cnt_pos + 1'b1;
    end

    //pos clk flag
    always @(posedge clk ) begin
    	if (!rstn)
          pos_clk <= 1'b0;
      else if (clk_cnt_pos == N-1 )
          pos_clk <= ~pos_clk;
		else if (clk_cnt_pos == (N-1)/2 - 1)
          pos_clk <= ~pos_clk;
    end

	 //neg_edge clk
    always @(negedge clk ) begin
      if (!rstn)
         clk_cnt_neg <= 3'b0;
      else if (clk_cnt_neg == N-1)
         clk_cnt_neg <= 3'b0;
      else
         clk_cnt_neg <= clk_cnt_neg + 1'b1;
    end

    //neg clk flag
    always @(negedge clk ) begin
    	if (!rstn)
          neg_clk <= 1'b0;
      else if (clk_cnt_neg == N-1 )
          neg_clk <= ~pos_clk;
		else if (clk_cnt_neg == (N-1)/2 - 1)
          neg_clk <= ~neg_clk;
    end

    assign o_clk = neg_clk | pos_clk;

endmodule

上述RTL设计有如下问题:

采用同步复位带来的问题,虽然采用同步设计的思路,可以有效避免亚稳态,但是在FPGA或ASIC设计中,标准单元库中的寄存器一般均带有异步复位端的寄存器,如果大量采用这种设计,会带来额外的逻辑来确保功能正确;

采用两个上升沿always语句块与采用两个下降沿always语句块,其实在综合过程中也会在面积上有一定的增加;可以考虑将相同的功能块尽量放在一个always语句块中;

采用(N-1)/2的设计方法,也会带来面积上的增加的问题;

最后采用将时钟直接或逻辑的操作,虽然在功能上并不会带来问题,但是对于敏感时钟来说,毛刺可能会发生,因此,在实际设计应用中,需要确保产生的高质量的时钟;

优雅的写出7分频RTL设计:

module div_old_7(    //define div = N
    input    clk,
    input    rstn,
    output  reg  o_clk
);
	 parameter N = 7;

	 reg 			rstn_sync0,rstn_sync1;

	 always @(posedge clk or negedge rstn) begin
		if (!rstn)
        {rstn_sync1,rstn_sync0} <= 2'b00;
      else
      	 {rstn_sync1,rstn_sync0} <={rstn_sync0,1'b1,};
	 end

    reg    [2:0]  clk_cnt_pos, clk_cnt_neg;
    reg          pos_clk, neg_clk;


    always @(posedge clk or negedge rstn_sync1) begin
        if (!rstn_sync1)  begin
            clk_cnt_pos <= 0;
            pos_clk     <= 1'b0;
        end
        else  if (clk_cnt_pos == N-1) begin
            clk_cnt_pos <= 0;‘’
            pos_clk     <= ~pos_clk;
        end
        else if (clk_cnt_pos == (N-1) >> 1 - 1 ) begin
            clk_cnt_pos <= clk_cnt_pos + 1'b1;
            pos_clk     <= ~pos_clk;
        end
        else
            clk_cnt_pos <= clk_cnt_pos + 1'b1;
    end

    always @(negedge clk or negedge rstn_sync1) begin
        if (!rstn_sync1) begin
            clk_cnt_neg <= 0;
            neg_clk     <= 1'b0;
        end
        else  if (clk_cnt_neg == N-1) beign
            clk_cnt_neg <= 0
            neg_clk     <= ~neg_clk;
        end
        else if (clk_cnt_neg == (N-1)>>1 - 1 ) begin
            clk_cnt_neg <= clk_cnt_neg + 1'b1;
            neg_clk     <= ~neg_clk;
        end
        else
            clk_cnt_neg <= clk_cnt_neg +1'b1;
    end

	 always @(negedge clk or negedge rstn_sync1) begin
        if (!rstn_sync1)
          o_clk <= 1'b0;
        else
          o_clk <= neg_clk | pos_clk;
	 end

endmodule

喜欢作者的朋友们欢迎关注B站: 摆渡沧桑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆渡沧桑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值