Verilog——分频器

在面试比试中经常出现的奇数时钟分频电路。

1. 不用时钟下降沿触发的3分频电路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module ClockDiv(  // 3 分频
input clk_i,
input rst_n,
output clk_o
);
reg [2:0] cnt;
always@(posedge clk_i or negedge rst_n) begin
if(rst_n == 1'b0) cnt<='b0;
else if(cnt == 2) cnt <= 'b0; // 计数到2
else begin
cnt <= cnt + 1'b1;
end
end

assign clk_o = (cnt<1 ) || (cnt==1 && clk_i); // 第一个时钟里clk_o为高,第二个时钟前半部分clk_o为高,后半部分为低。
endmodule

2. 不用时钟下降沿触发的任意奇数分频电路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module ClockDiv(
input clk_i,
input rst_n,
output clk_o
);
reg [2:0] cnt;
parameter DIV = 3;
localparam MID = (DIV-1)/2;
always@(posedge clk_i or negedge rst_n) begin
if(rst_n == 1'b0) cnt<='b0;
else if(cnt == (DIV-1)) cnt <= 'b0;
else begin
cnt <= cnt + 1'b1;
end
end

assign clk_o = (cnt<MID ) || (cnt==MID && clk_i);
endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module tb(

);
reg clk_i,rst_n;
wire clk_o;
wire clk5;
initial begin
clk_i <= 0;
forever #10 clk_i <= ~clk_i;
end
initial begin
rst_n = 1;
@(posedge clk_i) rst_n = 0;
@(posedge clk_i) rst_n = 1;
end
ClockDiv div3(
clk_i,
rst_n,
clk_o
);
ClockDiv #(.DIV(5)) div5(.clk_i(clk_i),.rst_n(rst_n),.clk_o(clk5));
endmodule

3. 下降沿触发的3分频

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module ClockDiv(input clk_i,input rst_n,output clk_o);
reg ck1;
reg[1:0] state;
always@(posedge clk_i or negedge rst_n) begin
if(rst_n == 1'b0) state <= 2'b00;
else begin
case(state)
2'b00: state<=2'b01;
2'b01: state<=2'b11;
2'b11: state<=2'b00;
default:state<=2'b00;
endcase
end
end
always@(negedge clk_i or negedge rst_n) begin
if(rst_n == 1'b0) ck1<=0;
else ck1 <= state[0]; //ck1相比state[0]延迟半个周期
end
assign clk_o = state[0] & ck1;
endmodule


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!