数字IC秋招手撕代码(二)50%占空比的三分频

数字IC秋招手撕代码(二)50%占空比的三分频

🔈声明:
🔑未经作者允许,禁止转载
🚩推荐一个IC、FPGA新手入门的好网站:👉快 点 击 进 入 学 习 吧👈




# 题目 用verilog实现三分频电路,要求输出50%占空比

设计思路

如果不限制占空比50%的话,那么用counter做3进制计数,每次counter=1拉高,counter=2拉低即可,但是这样的占空比是1/3。
如果要做50占空比的三分频,则需要一个上升沿的六分频和一个下降沿的六分频组合来得到。
类似的奇分频都可以这样实现。
大致有三种组合方式都可以得到:

  1. 异或

后续将上升沿采样记为clk_pos,下降沿采样记为clk_neg


与逻辑分频

  • 用与逻辑来组合,需要clk_pos和clk_neg拉高2T,但是其本身有0.5T的时序差
  • 那么在cnt=0时,clk_pos拉高2拍
  • cnt=0时,clk_neg拉高2拍
  • 最后clk_pos & clk_neg 即为分频结果

下面是理论波形图方便理解。
在这里插入图片描述

代码

module div_and #(parameter n=5)
(
    input       clk,
    input       rstn,
    output      clk_div
    );
    
reg     [15:0]  cnt;
reg             clk_pos,clk_neg;

assign clk_div = clk_pos & clk_neg;

always @(posedge clk or negedge rstn)begin
  if(!rstn)
    cnt <= 0;
  else if(cnt==n-1)
    cnt <= 0;
  else 
    cnt <= cnt + 1;
end         
    
always @(posedge clk or negedge rstn)begin
    if(!rstn)
        clk_pos <= 1'b0;
    else if(cnt==n-1)
        clk_pos <= 1'b1;
    else if(cnt==(n>>1))
        clk_pos <= 1'b0;
end

always @(negedge clk or negedge rstn)begin
    if(!rstn)
        clk_neg <= 0;
    else if(cnt==n-1)
        clk_neg <= 1'b1;
    else if (cnt==(n>>1))
        clk_neg <= 1'b0;
end 
    
endmodule

或逻辑分频

  • 用或逻辑来组合,需要clk_pos和clk_neg只拉高1T,但是其本身有0.5T的时序差
  • 那么在cnt=2时,clk_pos拉高1拍
  • cnt=2时,clk_neg拉高1拍
  • 最后clk_pos | clk_neg 即为分频结果

下面是理论波形图方便理解。
在这里插入图片描述

代码

module div_or #(parameter n=3)
(
    input       clk,
    input       rstn,
    output      clk_div
    );
    
reg     [15:0]  cnt;
reg             clk_pos,clk_neg;

assign clk_div = clk_pos | clk_neg;

always @(posedge clk or negedge rstn)begin
  if(!rstn)
    cnt <= 0;
  else if(cnt==n-1)
    cnt <= 0;
  else 
    cnt <= cnt + 1;
end         
    
always @(posedge clk or negedge rstn)begin
    if(!rstn)
        clk_pos <= 1'b0;
    else if(cnt==n-1)
        clk_pos <= 1'b1;
    else
        clk_pos <= 1'b0;
end

always @(negedge clk or negedge rstn)begin
    if(!rstn)
        clk_neg <= 0;
    else if(cnt==n-1)
        clk_neg <= 1'b1;
    else 
        clk_neg <= 1'b0;
end 
    
endmodule

异或逻辑分频

  • 用异或逻辑来将两个六分频组合成三分频原理很简单,因为异或是相同为0,不同为1 所以需要将上升沿与下降沿差一半再翻转
  • 如果上升沿在cnt=2时翻转,那么下降沿应该在cnt=1翻转
  • 这样cnt带来了1T的时序差
  • 而上升沿和下降沿自带0.5T的时序差。

下面是理论波形图方便理解。
在这里插入图片描述


代码

module div #(parameter n=3)
(
    input       clk,
    input       rstn,
    output      clk_div
    );
    
reg     [15:0]  cnt;
reg             clk_pos,clk_neg;

assign clk_div = clk_pos ^ clk_neg;

always @(posedge clk or negedge rstn)begin
  if(!rstn)
    cnt <= 0;
  else if(cnt==n-1)
    cnt <= 0;
  else 
    cnt <= cnt + 1;
end         
    
always @(posedge clk or negedge rstn)begin
    if(!rstn)
        clk_pos <= 0;
    else if(cnt==n-1)
        clk_pos <= ~clk_pos;
end

always @(negedge clk or negedge rstn)begin
    if(!rstn)
        clk_neg <= 0;
    else if(cnt==(n>>1))
        clk_neg <= ~clk_neg;
end 
    
endmodule




  Verilog的学习还是要多以练习为主,想要练习Verilog的同学,推荐可以去nowcoder看看,他们现在的题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享一站式求职学习网站,最最最重要的里面的资源全部免费




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值