描述
编写一个模块,对输入的时钟信号clk_in,实现任意奇数分频,要求分频之后的时钟信号占空比为50%。模块应包含一个参数,用于指定分频的倍数。
模块的接口信号图如下:
要求:使用Verilog HDL语言实现,并编写testbench验证模块的功能。
输入描述:
clk_in:输入时钟信号
rst_n:复位信号,低电平有效
输出描述:
clk_out:分频之后的时钟信号
`timescale 1ns/1ns
module clk_divider
#(parameter dividor = 5)
( input clk_in,
input rst_n,
output clk_out
);
localparam dividor_sub1 = dividor - 1;
localparam dividor_sub1_div2 = dividor_sub1 / 2;
localparam cnt_r_phase = 1;
localparam cnt_r_init = (4'd0 + dividor_sub1_div2 + cnt_r_phase) % dividor;
localparam cnt_sub1_r_init = (dividor_sub1 + dividor_sub1_div2 + cnt_r_phase) % dividor;
reg [3:0] cnt_r = 4'd0, cnt_sub1_r = dividor_sub1;
reg clkout_posedge_r = 1'b0;
reg clkout_negedge_r = 1'b0;
always @(posedge clk_in) begin
if (~rst_n) begin
cnt_r <= cnt_r_init;
end else begin
if (cnt_r == dividor_sub1) begin
cnt_r <= 4'd0;
end else begin
cnt_r <= cnt_r + 4'd1;
end
end
end
always @(posedge clk_in) begin
if (~rst_n) begin
cnt_sub1_r <= cnt_sub1_r_init;
end else begin
if (cnt_sub1_r == dividor_sub1) begin
cnt_sub1_r <= 4'd0;
end else begin
cnt_sub1_r <= cnt_sub1_r + 4'd1;
end
end
end
always @(posedge clk_in) begin
if (~rst_n) begin
clkout_posedge_r <= 1'b0;
end else begin
if (cnt_r == 4'd0) begin
clkout_posedge_r <= 1'b1;
end else if (cnt_r == dividor_sub1_div2) begin
clkout_posedge_r <= 1'b0;
end
end
end
always @(negedge clk_in) begin
if (~rst_n) begin
clkout_negedge_r <= 1'b0;
end else begin
if (cnt_r == 4'd0) begin
clkout_negedge_r <= 1'b1;
end else if (cnt_r == dividor_sub1_div2) begin
clkout_negedge_r <= 1'b0;
end
end
end
assign clk_out = clkout_posedge_r | clkout_negedge_r;
endmodule