Verilog入门设计(二)——基本逻辑电路设计

导读:本篇文章讲解 Verilog入门设计(二)——基本逻辑电路设计,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、触发器

1、D触发器

  D触发器特征:

– 功能表

D CLK Q QN
0 时钟上升沿 0 1
1 时钟上升沿 1 0
x 0 last Q last QN
x 1 last Q last QN

– 方程

Q

n

+

1

=

D

Q_{n+1}=D

Qn+1=D
– 时序图
在这里插入图片描述

(1)基本D触发器

//基本D触发器
module DFF(Q,D,clk);
input D,clk;
output Q;reg Q;
always@(posedge clk)
	begin
	Q<=D;
	end
endmodule

时序图:
在这里插入图片描述

(2)带异步清零、异步置1的D触发器

//带异步清零、异步置1的D触发器
module DFF1(Q,QN,D,clk,reset,set);
input D,clk,reset,set;
output Q,QN;reg Q,QN;
parameter DELAY=5;
always@(posedge clk or negedge reset or negedge set)
	begin
	if(!reset) begin  Q<=0;QN<=1;end
	else if(!set) begin  Q<=1;QN<=0;end
	else begin  Q<=D;QN<=~D;end
	end
endmodule

时序图:
在这里插入图片描述

(3)带同步清零、同步置1的D触发器

//带同步清零、同步置1的D触发器
module DFF2(Q,QN,D,clk,reset,set);
input D,clk,reset,set;
output Q,QN;reg Q,QN;
always@(posedge clk)
	begin 
	if(!reset) begin Q<=0;QN<=1;end
	else if(!set) begin Q<=1;QN<=0;end
	else begin Q<=D;QN<=~D;end
	end
endmodule

时序图:在这里插入图片描述

2、JK触发器

(1)带异步清零、异步置1的JK触发器

//带异步清零,异步置一的JK触发器
module JK_FF(Q,J,K,reset,set,clk);
input J,K,reset,set,clk;
output Q; reg Q;
always@(posedge clk or negedge reset or negedge set)
	begin if(!reset) Q<=1'b0;
	else if(!set) Q<=1'b1;
	else case({J,K})
	2'b00:Q<=Q;
	2'b01:Q<=1'b0;
	2'b10:Q<=1'b1;
	2'b11:Q<=~Q;
	default:Q<=1'bx;
	endcase
	end
endmodule

时序图:
在这里插入图片描述

二、寄存器与锁存器

1、锁存器

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

//电平敏感的1位数据锁存器
module latch1
(
	output q,
	input d,clk
);
assign q=clk?d:q;	//时钟信号为高电平时,将输入端数据锁存
endmodule

时序图:
在这里插入图片描述

(2)带置位端和复位端的1位数据锁存器

//带置位端和复位端的1位数据锁存器
module latch2
(
	output q,
	input d,clk,reset,set
);
assign q=reset?0:(set?1:(clk?d:q));
endmodule

时序图:
在这里插入图片描述

(3)8位数据锁存器

//8位数据锁存器
module latch3
(
	output reg[7:0] q,
	input clk,
	input[7:0] data
);
always@(clk,data)
	begin
	if(clk)
		q=data;
	else
		q=q;
	end
endmodule

时序图:
在这里插入图片描述

2、寄存器

(1)8位数据寄存器

//8位数据寄存器
module reg8
(
	output reg[7:0] out_data,
	input[7:0] in_data,
	input clk,clr
);
always@(posedge clk, negedge clr)
	begin
	if(!clr)
		out_data<=0;
	else
		out_data<=in_data;
	end
endmodule

时序图:
在这里插入图片描述

(2)8位移位寄存器

//8位移位寄存器
module shifter
(
	output reg[7:0] dout,
	input clk,clr,din
);
always@(posedge clk)
	begin
	if(clr)
		dout<=8'b0;
	else
		begin
		dout<=dout<<1;
		dout[0]=din;
		end
	end
endmodule

时序图:
在这里插入图片描述

三、计数器与串并转换器

1、计数器

(1)可变模加法/减法计数器

//同步清0、同步置数可变模加法/减法计数器
module updown_count
(
	output[7:0] qd,
	input clk,clr,load,up_down,
	input[7:0] d
);
reg[7:0] cnt;
assign qd=cnt;
always@(posedge clk)
	begin
	if(!clr)	cnt<=8'h00;		//同步清0
	else if(load)	cnt<=d;		//同步置数
	else if(up_down)	cnt<=cnt+1;		//加法计数器
	else	cnt<=cnt-1;						//减法计数器
	end
endmodule

时序图:在这里插入图片描述

(2)4位Johnson计数器

//4位Johnson计数器
module Johnson
(
	output reg[3:0] out,
	input clk,clr
);
always@(posedge clk,posedge clr)
	begin
	if(clr)	out<=4'h0;
	else
		begin
		out<=out<<1;
		out[0]<=~out[3];
		end
	end
endmodule

时序图:
在这里插入图片描述

2、串/并转换器

(1)串并转换器

//4位串并转换程序
module SIPO
(
	output reg[3:0] pout,
	input sin,clk
); 
always@(posedge clk)
	begin
	pout={pout,sin};//采用位拼接
	end
endmodule

时序图:
在这里插入图片描述

(2)并串转换器

//4位并串转换程序(带异步清零端)
module PISO
(
	output s_out,
	output reg[3:0] databuf,
	input clk,reset,
	input[3:0] p_in
);

always@(posedge clk, negedge reset)
	begin
	if(!reset) databuf<=4'b0000;
	else 	databuf<=p_in<<1;
	end
assign s_out=databuf[3];
endmodule


时序图:
在这里插入图片描述

四、简易微处理器

  该微处理器根据输入的指令,能实现四种操作,分别为两数相加、两数相减、操作数+1,操作数-1.操作数与操作码均从输入指令中提取。

//用函数实现的处理器
module mpc
(
	output reg[8:0] out,			//输出结果
	input[17:0] instr				//instr为输入指令
);
reg func;
reg[7:0] op1,op2;					//从指令中提取的两个操作数
function[16:0] code_add;		//函数定义
input[17:0] instr;
reg add_func;
reg[7:0] code,opr1,opr2;
	begin
	code=instr[17:16];			//输入指令instr的高2位是操作码
	opr1=instr[7:0];				//输入指令instr的低8位是操作数opr1
	case(code)
		2'b00: begin
				 add_func=1;	
				 opr2=instr[15:8];	//从输入指令instr提取第二个操作数
				 end
		2'b01: begin
				 add_func=0;
				 opr2=instr[15:8];	//从输入指令instr提取第二个操作数
				 end
		2'b10: begin
				 add_func=1;
				 opr2=8'd1;				//实现+1操作
				 end
		default: begin
				 add_func=0;
				 opr2=8'd1;				//实现-1操作
				 end
	 endcase
	 code_add={add_func,opr2,opr1};
	 end
endfunction
always@(instr)
	begin
	{func,op2,op1}=code_add(instr);	//调用函数
	if(func==1)	out=op1+op2;			//实现两数相加,操作数1加1操作
	else	out=op1-op2;					//实现两数相减,操作数1减1操作
	end
endmodule

时序图:
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/73697.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!