二分频:
// 用D触发器做个二分频的电路
// 在时钟每触发2个周期时,电路输出1个周期信号。
module div2(clk,rst,clk_out);
input clk,rst;
output reg clk_out;
always@(posedge clk)begin
if(!rst)begin
clk_out <= 0;
end
else begin
clk_out <= ~clk_out; // 时钟每触发1个周期时,电路输出半个周期信号。
end
end
endmodule
实现奇数倍分频且占空比为50%的情况:
5 分频
// 实现奇数倍分频且占空比为50%的情况
// 在时钟每触发 n个周期时,电路输出1个周期信号。
// 以下实现 5分频 (原来2个半周期,现在半个周期)
module div5(
input clk,
input rst,
output fclk,
output reg[2:0] cnt
);
// 计数器 5
always@(posedge clk or negedge rst)begin
if(~rst)begin
cnt <= 3'd0;
end
else if(cnt == 3'd4)begin
cnt <= 0;
end
else begin
cnt <= cnt + 3'd1;
end
end
reg f1clk, f2clk;
always@(posedge clk or negedge rst)begin
if(~rst)begin
f1clk <= 1'b1;
end
else if(cnt == 3'd1)begin
f1clk <= ~f1clk;
end
else if(cnt == 3'd4)begin
f1clk <= ~f1clk;
end
else begin
f1clk <= f1clk;
end
end
always@(negedge clk or negedge rst)begin
if(~rst)begin
f2clk <= 1'b1;
end
else begin
f2clk <= f1clk;
end
end
assign fclk = f1clk | f2clk;
endmodule
`timescale 1ns/1ns
module div5_tb;
// Inputs
reg clk;
reg rst;
// Outputs
wire fclk;
wire [2:0] cnt;
// Instantiate the Unit Under Test (UUT)
div5 uut (
.clk(clk),
.rst(rst),
.fclk(fclk),
.cnt(cnt)
);
initial begin
clk = 0; rst = 0;
#20 rst = 1;
#200 $stop;
end
always #10 clk = ~clk;
endmodule
3分频
3分频设置一个3clk计数器。3//2=1,clk1占一个clk,clk2延后半个clk(下降沿触发)。最后 assign clk_out = f1clk | f2clk 即可
// https://wavedrom.com/editor.html 在线画波形图
{signal: [
{name: 'clk', wave: 'p..........'},
{name: 'f1clk', wave: '0.10.10....'},
{name: 'f2clk', wave: '0.10.10....', phase: -0.5} // phase:-0.5右移半clk
]}
// 3分频, 占空比为50%
// 在时钟每触发3个周期时,电路输出1个周期信号
module div3 (
input clk, // Clock
input rst_n, // Asynchronous reset active low
output clk_out
);
// 3周期计数器
reg [1:0] cnt;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
cnt <= 2'd0;
end
else if(cnt == 2'd2)begin
cnt <= 2'd0;
end
else begin
cnt <= cnt + 2'd1;
end
end
reg f1clk, f2clk;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
f1clk <= 0;
end
else if(cnt==2'd0 || cnt==2'd1) begin
f1clk <= ~f1clk;
end
else begin
f1clk <= f1clk;
end
end
always @(negedge clk or negedge rst_n) begin
if(~rst_n) begin
f2clk <= 0;
end
else begin
f2clk <= f1clk;
end
end
assign clk_out = f1clk | f2clk;
endmodule
`timescale 1ns/1ns
module div3_tb;
// Inputs
reg clk;
reg rst_n;
// Outputs
wire clk_out;
// Instantiate the Unit Under Test (UUT)
div3 uut (
.clk(clk),
.rst_n(rst_n),
.clk_out(clk_out)
);
initial begin
clk = 0; rst_n = 0;
#20 rst_n = 1;
#200 $stop;
end
always #10 clk = ~clk;
endmodule