题解 | #占空比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
);
wire rst_n;
assign rst_n = rst;
//=========================================================================
// 这里,实现占空比 50%的奇数分频,可以在输入时钟的基础上,对其上升沿和下降沿分别计数,
// 从而得到两个时钟。
// 在本题中,奇数为7,且因为最开始时钟输出为低电平,因此在非50%占空比的7分频电路下,应当将输出时钟拉高的周期数目设置得短一些。
// 则设置翻转计数值为 [7/2]+1=4,效果也就是如:
// 周期0,1,2,3低电平;周期4,5,6为高电平。这样不是50%占空比。实现50%占空比,需要对时钟的
// 上升沿进行计数,按照如上翻转规律,得到时钟clk_p;再对时钟的下降沿进行计数,同样得到clk_n。
// 这样clk_p和clk_n的相位差为半个时钟周期。
// 根据clk_p,clk_n和clk_in的时序对比,对(clk_p|clk_n)进行逻辑判断即可得到占空比50%的7分频电路。
// 即其翻转位置在第三个周期的中间。(3.5个周期)
//=========================================================================
//*************code***********//
// ======================================================================================
// 方式(二):通过对clk_in上下沿分别进行计数,得到两个7分频3:4占比时钟
// ======================================================================================
reg [2:0] cnt_pos;
always @(posedge clk_in, negedge rst_n)
begin
if(~rst_n)
cnt_pos <= 3'd0;
else
cnt_pos <= (cnt_pos==3'd6)? 3'd0 : (cnt_pos+1'd1);
end
reg clk_p;
always @(posedge clk_in or negedge rst_n)
begin
if(~rst_n)
clk_p <= 1'b0;
else
clk_p <= (cnt_pos==3'd3 || cnt_pos==3'd6)? ~clk_p : clk_p;
end
reg [2:0] cnt_neg;
always @(negedge clk_in or negedge rst_n)
begin
if(~rst_n)
cnt_neg <= 3'd0;
else begin
cnt_neg <= (cnt_neg==3'd6)? 3'd0 : (cnt_neg+1'd1);
end
end
reg clk_n;
always @(negedge clk_in or negedge rst_n)
begin
if(~rst_n)
clk_n <= 1'b0;
else
clk_n <= (cnt_neg==3'd3 || cnt_neg==3'd6)? ~clk_n : clk_n;
end
assign clk_out7 = clk_p | clk_n;
// ======================================================================================
// 方式(一)- 未能通过:如下的判断方式,同时判断了上升沿和下降沿计数,得到的输出时钟总是在 clk_in 的上升沿同步拉高
// ======================================================================================
/*
reg [2:0] cnt_neg;
always @(negedge clk_in or negedge rst_n)
begin
if(~rst_n)
cnt_neg <= 3'd1;
else
cnt_neg <= (cnt_neg==3'd7)? 3'd1 : cnt_neg+1'd1;
end
reg [2:0] cnt_pos;
always @(posedge clk_in or negedge rst_n)
begin
if(~rst_n)
cnt_pos <= 3'd1;
else
cnt_pos <= (cnt_pos==3'd7)? 3'd1 : cnt_pos+1'd1;
end
assign clk_out7 =cnt_neg[2] && ~(cnt_neg==3'd3 && clk_in);
*/
//*************code***********//
endmodule

海康威视公司福利 1198人发布