tag 标签: fpga,奇数分频

相关博文
  • 热度 4
    2016-3-23 21:57
    1134 次阅读|
    2 个评论
    前几天在一家做逻辑设计的公司里做了一道笔试题,有些心塞。用 Verilog HDL 描述三分频的实现。说实话,一开始我是拒绝的。我之前做过分频实验,几百毫秒的 LED 闪烁,控制蜂鸣器发出不同音频段的声音,都是分频实验的例子。现在想想,基本都是偶数分频。 一开始我是 6 分频的基础上做了 2 倍频,结果描述内容过于繁琐,以致写着写着就放弃挣揣,没经历过得东西是编不出来的。回来在网上找到了许多解决奇、偶数的分频实现。说实话,理论知识还是比较多的,就是代码实现有些欲盖迷彰,我抄写下来验证几乎都是错的。好在理论知识分析透彻,而后我自己尝试编写了一下,写下作为分享。         偶数分频,例如二分频,简单讲就是一个时钟周期的高电平和一个时钟周期的低电平。设 reg  cnt ,默认一位,每一个时钟上升沿自加 1 ,则 cnt 的电平变化就可以作为二分频输出。由此,设 reg cnt ,则 cnt ,cnt ,cnt 对应 4/8/16 分频。这些操作,我们常常在 led 延时处理上用到。 语言描述如下: module test2_1(clk,rst_n,clk_out2,clk_out4,clk_out8); input clk; input rst_n; output clk_out2; output clk_out4; output clk_out8; reg cnt; always@(posedge clk or negedge rst_n) if(!rst_n) cnt = 3 'd0; else cnt = cnt +1'b1; assign clk_out2 = cnt ; assign clk_out4 = cnt ; assign clk_out8 = cnt ; e ndmodule        另类偶数分频如 6/10/12 分频,可在前 3/5/6 个整数周期处理输出高 / 低电平,后 3/5/6 个整数周期取反,操作相对简单,可实现输出为占空比为 1:1 的分频信号。占空比不等的情况就更简单。 关键语言描述如下: ( N=6 ) if(cnt N/2-1)begin cnt = cnt + 1'b1; end else begin cnt = 3'd0; clk_out = ~clk_out; End 在设计中,我处理为 cnt N/2, 或 cnt 小于等于 N/2-1 ,结果实现均为 8 分频。我开始分析 cnt 3, 那 cnt 就只有取 0,1 , 2 为一种状态的电位,记满到 3 时,电位取反, cnt 清零,重复执行得到效果。而事实上 cnt N/2-1 才正确。我寻思着这样不是取了 0 、 1 两次数吗。后来在奇数分频遇到类似问题。 奇数分频占空比为 1:1 的实现比较复杂,以 5 分频为例,我采用两个计数器,一个计数器在时钟上升沿触发计数,另一个计数器在时钟下降沿触发计数(或 clk_n = ~clk )。各自控制产生一个 5 分频信号,调节占空比为 3 : 2 (容易)。第一个 5 分频比第二个 5 分频快半个周期,两个信号取或,完美将占空比分配为 1:1 ,通俗点说,就是 3-0.5 = 2+0.5 。 此时,我也遇到了 cnt N-1 和 cnt2 == (N-1)/2 的问题,尤其是 cnt2 == (N-1)/2 ,表面上让我误以为是占空比为 2:3 ,但 事实上是 信号 占空比为 3:2 。后来在仿真中我多添加了 cnt 的检测,效果就明显看出来了。而究其根源是 always 中 clk 上升沿采样与 赋值 改变之间的先后关系 ,而这在后仿真中逻辑延时能体现出来。语言描述较长,在附录中呈现。 因为上升沿和赋值几乎一条线,我没有混淆是先采集还是先赋值,而是会纠结于多算一个周期或少算一个周期。我还发现自己的逻辑设计不熟练导致与理想 效果还是有差距的。调试时,花在逻辑优化的时间较长,另外在后仿真中 cnt 始终为 Z 态,不便于我观察,这是我的疑惑,也是接下来要解决的吧。 备注:我会在智慧科技(优先)、 EDN 、电子产品世界更新内容,信息不涉及商业用途。