我们在做FPGA设计时,有时会用到时钟频率奇数分频的频率,例如笔者FPGA的晶振为50M,当我们需要10M的时钟时,一种方式可以使用DCM或PLL获取,系统会内部分频到10M,但其实VERILOG内部也完全能实现,所以我们还是来了解一下。
有这样一个欢乐的时钟了,我们要得到以下的分频效果:
奇数分频的难点就在于,三分频要求1.5倍的时钟时间翻转一次,这样整体的周期时间是原来的3倍,即三分频。五分频亦类似。而恰恰verilog不允许你在两个always模块里对同一reg赋值。
那怎么得到三分频的时钟呢?请看下图
如果生成这样一个占空比2/3,周期三倍于时钟的信号(2行)。同时产生一个超前或落后于它半个Clock周期时间的信号(3行),对两信号做与运算
,得到的结果就恰好是三分频的时钟(4行);而Verilog中恰好不允许你在两个always模块里对同一reg赋值,但允许你在Clock的Posedge和Negedge分别对两个不相关的信号赋值。
- assign clkout=state1[1]&state2[1];
- always@(posedge clk)
- begin
- case(state1)
- begin
- 2'b01:state<=2'b10;
- 2'b10:state<=2'b11;
- 2'b11:state<=2'b01;
- endcase
- end
- always@(negedge clk)
- begin
- case(state2)
- 2'b01:state<=2'b10;
- 2'b10:state<=2'b11;
- 2'b11:state<=2'b01;
- endcase
- end
同样的,五分频
- assign clkout=state1[1]&state2[1];
- always@(posedge clk)
- begin
- case(state1)
- begin
- 3'b010:state<=3'b011;
- 3'b011:state<=3'b100;
- 3'b100:state<=3'b101;
- 3'b101:state<=3'b110;
- 3'b110:state<=3'b111;
- 3'b111:state<=3'b010;
- endcase
- end
- always@(negedge clk)
- begin
- case(state2)
- 3'b010:state<=3'b011;
- 3'b011:state<=3'b100;
- 3'b100:state<=3'b101;
- 3'b101:state<=3'b110;
- 3'b110:state<=3'b111;
- 3'b111:state<=3'b010;
- endcase
- end
什么原理呢?其实这样想挺好理解的:
三分频,每1.5个时钟周期就要翻转一次,因此我们通过时钟上升沿构造低电平占1个时钟周期,高电平占2个时钟周期的信号,再通过时钟的下降沿产生相同的信号,这相当与把原信号右移了半个时钟周期,相与后高电平被削掉了半个周期,低电平添了半个周期,就产生了1.5个时钟周期翻转一次的效果。
五分频类似。
由此猜测11分频可以由上升沿构造低电平占5个时钟周期,高电平占6个时钟周期的信号产生,我们来验证一下
验证是的啦
转载自:http://blog.csdn.net/lt66ds/article/details/10035187