我是靠谱客的博主 愉快哑铃,最近开发中收集的这篇文章主要介绍verilog之时序逻辑电路(附代码)前言1.触发器2.锁存器和寄存器3.移位寄存器4.分频器5.计数器6.其他时序逻辑电路,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

刚学前端设计的时候,听到的就是组合逻辑、时序逻辑,很重要!但是究竟有什么用?到底怎么体现,没有多少老师可以明确指出来,当自己看的东西多了,就可以理解了,甚至可以得出自己的范式。

到目前为止,要想掌握组合逻辑,就请先掌握本文列出的计数器、触发器、锁存器、寄存器分频器等简单的组合逻辑电路。

1.触发器

包括RS触发器、JK触发器、D触发器、T触发器。

2.锁存器和寄存器

锁存器的功能同触发器类似,但也有本质区别:触发器是在有效时钟沿到来时才发生作用,而锁存器是电平敏感的,只要时钟信号有效,锁存器就会起作用

2.1锁存器

2.1.1电平敏感的1位数据锁存器

module latch1(
	clk,
	d,
	q
);
	input clk,d;
	output q;
	
	assign q = clk?d:q;

endmodule

综合的电路图如下:

在这里插入图片描述

2.1.2带有置位功能和复位功能的电平敏感的1位数据锁存器

module latch2(
	clk,load,reset,d,q
);
input clk,load,reset,d;
output q;

assign q = reset?1'b0:(load?1'b1:(clk?d:q));

endmodule

综合得到的电路图如下:

在这里插入图片描述

2.2 寄存器

推荐阅读FPGA应该掌握的小笔记中涉及到的寄存器知识点。

带有清零功能的8位数据寄存器reg_8.v

推荐阅读:异步复位清零的一些常识

module reg_8(
	out,
	in,
	clk,
	clr
);
	output 	[7:0] out;
	input		[7:0]	in;
	input				clk;
	input				clr;
	reg		[7:0]	out;
	
	always@(posedge clk or posedge clr)
	if(clr)		out <= 0;
	else			out <= in;
endmodule

综合得到的电路图如下:

在这里插入图片描述

3.移位寄存器

3.1 8位左移移位寄存器shiftleft_reg.v

module shiftleft_reg(clk,rst,l_in,s,q);
	input clk,rst,l_in,s;
	output 	[7:0]	q;
	reg		[7:0]	q;
	always@(posedge clk)
	begin
		if(rst)
			q <= 8'b0;
		else if(s)
			q <= {q[6:0],l_in};
		else 
			q <= q;
	end

endmodule

3.2 8位右移移位寄存器

module shiftright_reg(clk,rst,r_in,s,q);
	input clk,rst,r_in,s;
	output 	[7:0]	q;
	reg		[7:0]	q;
	always@(posedge clk)
	begin
		if(rst)
			q <= 8'b0;
		else if(s)
			q <= {r_in,q[7:1]};
		else 
			q <= q;
	end

endmodule

4.分频器

5.计数器

6.其他时序逻辑电路

6.1同步器

当一个时序电路的输入由另一个时钟驱动的电路产生或来自一个外部异步电路时,需要用同步器将输入数据与需要的时钟同步。即常用在跨时钟处理!

简单同步器设计代码Synchronizer.v

module Synchronizer(
	clk,
	data,
	syn
);

input 	clk;
input 	data;
output	syn;
reg 		syn;

always@(posedge clk)
	if(data == 0)
		syn <= 0;
	else 
		syn <=1;

endmodule

仿真文件Synchronizer_tb.v

`timescale 1ns/1ns
`define clk_period 20

module Synchronizer_tb;

	reg 	clk;
	reg 	data;
	wire	syn;

	Synchronizer Synchronizer_inst(
		clk,
		data,
		syn
	);

	initial clk = 1;
	always #(`clk_period/2) clk = ~clk;

	initial begin
		data = 1'b0;
		#(`clk_period*2+5);
		data = 1'b1;
		#(`clk_period*2);
		data = 1'b0;
		#(`clk_period*2+6);
		data = 1'b1;
		#8;
		data = 1'b0;
		#16;
		data = 1'b1;
		#(`clk_period);
		data = 1'b0;
		#(`clk_period*2);
		$stop;
	end

endmodule

功能仿真

在这里插入图片描述

6.2边沿检测电路

在这里插入图片描述

设计代码edge_detect.v

module edge_detect(
	clk				,
	rst_n			,
	data			,
	raising_edge	,
	faling_edge		,
	double_edge		
);
	input		clk				;
	input		rst_n			;
	input		data			;
	output		raising_edge	;
	output		faling_edge		;
	output		double_edge		;
	
	reg data_reg0,data_reg1;

	always@(posedge clk or negedge rst_n)
	if(!rst_n)begin
		data_reg0 <= 1'b0;
		data_reg1 <= 1'b0;
	end
	else begin
		data_reg0 <= data;
		data_reg1 <= data_reg0;
	end
	
	assign raising_edge  = ~data_reg1 &&  data_reg0;
	assign faling_edge   =  data_reg1 && ~data_reg0;
	assign double_edge   =  data_reg1  ^  data_reg0;

endmodule

仿真文件edge_detect_tb.v

`timescale 1ns/1ns
`define clk_period 20

module edge_detect_tb;

	reg		clk				;
	reg		rst_n				;
	reg		data				;
	wire		raising_edge	;
	wire		faling_edge		;
	wire		double_edge		;

	edge_detect edge_detect_inst(
		.clk				(clk				),
		.rst_n			(rst_n			),
		.data				(data				),
		.raising_edge	(raising_edge	),
		.faling_edge	(faling_edge	),
		.double_edge	(double_edge	)	
	);

	initial clk = 1;
	always #(`clk_period/2) clk = ~clk;
	
	initial begin
		rst_n = 1'b0;
		#(`clk_period);
		rst_n = 1'b1;
	end
	
	initial begin
		data = 1'b0;
		#(`clk_period+10);
		data = 1'b1;
		#(`clk_period*3);
		data = 1'b0;
		#(`clk_period-5);
		data = 1'b1;
		#(`clk_period*2);
		data = 1'b0;
		#(`clk_period*3);
		$stop;
	end
endmodule

功能仿真

在这里插入图片描述

最后

以上就是愉快哑铃为你收集整理的verilog之时序逻辑电路(附代码)前言1.触发器2.锁存器和寄存器3.移位寄存器4.分频器5.计数器6.其他时序逻辑电路的全部内容,希望文章能够帮你解决verilog之时序逻辑电路(附代码)前言1.触发器2.锁存器和寄存器3.移位寄存器4.分频器5.计数器6.其他时序逻辑电路所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部