利用D触发器实现任意倍数分频(并使用Verilog验证)

利用D触发器实现任意信号分频

我们都知道,利用D触发器可以实现分频,并且D触发器实现2的幂次方很容易,只要将它们简单的连起来就可以,那么如何利用D触发器实现任意倍数的分频呢?这里就需要对数电的知识有所了解了,这里就不阐述了,数电书翻一下就有的。
这里我举个利用D触发器实现占空比为50%的7分频,看会了这个应该可以自己实现任意的倍数分频了,好了,废话不多说,进入正题。

利用D触发器实现7分频原理

在这里插入图片描述
一般来说要想得到指定的分频信号,D触发器之间的连接架构是这样的,具体需要什么样的组合逻辑应该怎么得到呢,这里需要用到状态转移图。
例如,我们需要得到一个七分频的信号,那我们就可以先画出状态转移图。
在这里插入图片描述
上述的状态转移图刚好就是个七进制的计数器,只要把输出也适当加组合逻辑变化下,就可以得到7分频的信号。
下图为上述状态转移图的卡诺图。
在这里插入图片描述

Verilog仿真验证

根据上述给出的输入和输出的公式,将其用Verilog来验证。以下为Verilog代码。

module D_FF(
	input			clk,
	input			rst_n,
	
	output			out
);
reg			q1;
reg			q2;
reg			q3;
//reg			D1;
//reg			D2;
//reg			D3;
wire	in_t;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		q1 <= 1'b0;
	end
	else begin
		q1 <= in_t;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		q2 <= 1'b0;
	end
	else begin
		q2 <= q1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		q3 <= 1'b0;
	end
	else begin
		q3 <= q2;
	end
end
assign in_t = ((~q1)&(~q3))|((q1)&(~q2)&(q3));
assign out	= 	((~q3)&(~q1))|((~q3)&q1&(~q2))|(q1&(~q2)&q3&clk);

endmodule 

激励文件(testbench)

`timescale 1ns/1ps
module tb;
reg				clk;
reg				rst_n;

wire			out;

D_FF	D_FF_u(
						.clk(clk),
						.rst_n(rst_n),
						
						.out(out)
			 );			 
initial begin
	clk = 1'b0;
	rst_n = 1'b1;
	#100;
	rst_n = 1'b0;
	#100;
	rst_n = 1'b1;
	#10000;
	$stop;
end
always #10 clk = ~clk;
endmodule 

仿真结果分析

在这里插入图片描述
这里是行为仿真,可以看出out的高电平时间为3.5个时钟周期,低电平也是3.5个时钟周期,实现了占空比为50%的信号分配。但是我这里是行为仿真,不知道为什么会有一个毛刺,按道理说行为仿真只是验证功能的,不会出现毛刺的,如果有大神知道可以指教下。最后由于本人才疏学浅,上述内容如果有误的话,还请指正。

  • 9
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
首先,需要定义输入和输出端口: ``` module detector(input clk, input reset, input data, output reg output); ``` 然后,定义一个 D 触发器: ``` reg d; always @(posedge clk, posedge reset) begin if (reset) begin d <= 1'b0; end else begin d <= data; end end ``` 接着,定义一个状态机来检测序列: ``` reg [1:0] state; parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter S3 = 2'b11; always @(posedge clk, posedge reset) begin if (reset) begin state <= S0; output <= 1'b0; end else begin case (state) S0: begin if (d == 1'b0) begin state <= S1; end end S1: begin if (d == 1'b0) begin state <= S2; end else begin state <= S0; end end S2: begin if (d == 1'b1) begin state <= S3; end else begin state <= S0; end end S3: begin state <= S0; output <= 1'b1; end endcase end end ``` 最后,将输出端口连接到状态机中的输出: ``` assign output = (state == S3); ``` 完整的代码如下: ``` module detector(input clk, input reset, input data, output reg output); reg d; always @(posedge clk, posedge reset) begin if (reset) begin d <= 1'b0; end else begin d <= data; end end reg [1:0] state; parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter S3 = 2'b11; always @(posedge clk, posedge reset) begin if (reset) begin state <= S0; output <= 1'b0; end else begin case (state) S0: begin if (d == 1'b0) begin state <= S1; end end S1: begin if (d == 1'b0) begin state <= S2; end else begin state <= S0; end end S2: begin if (d == 1'b1) begin state <= S3; end else begin state <= S0; end end S3: begin state <= S0; output <= 1'b1; end endcase end end assign output = (state == S3); endmodule ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值