Verilog入门设计(一)——基本组合电路设计

一、门电路
1、基本门电路
在这里插入图片描述

图1 门电路
基本门电路的几种描述方法: (1)门级结构描述
module gate1(a,b,c,d,f);
input a,b,c,d;
output f;
nand(s1,a,b);
and(s2,b,c,d);
or(f,s1,s2);
endmodule

(2)数据流描述

module gate2(f,a,b,c,d);
input a,b,c,d;
output f;
assign f=(~(a&b))|(b&c&d);
endmodule

(3)行为描述

module gate3(f,a,b,c,d);
input a,b,c,d;
output f;reg f;
always@(a or b or c or d)
	begin
	f=(~(a&b))|(b&c&d);
	end
endmodule

2、三态门

  三态:即高电平、低电平和高阻态。三态门是普通门的基础上加上控制端构成的,在需要信息传输的地方,三态门是必须的。下面以几种方式描述三态门。
请添加图片描述

图1 三态门

(1)行为描述的三态门

module tri_gate1(out,en,in);
input en,in;
output out; reg out;
always@(en,in)
	begin
	if(en) out<=in;
	else out<=1'bz;
	end
endmodule

  当en控制端为高电平时,out=in(即高、低电平态);当en为低电平时,out为高阻态。
(2)调用门元件bufif1描述的三态门

module tri_gate2(out,en,in);
input en,in;
output out; tri out; //out声明为tri表示out综合后的电路连接具有三态功能
bufif1(out,in,en);	//三态门端口顺序:输出、输入、控制端
endmodule

(3)数据流描述三态门

module tri_gate3(out,en,in);
input en,in;
output out; 
assign out=en?in:'bz;
endmodule

3、三态双向驱动器
  双向表示既可作输入、又可作输出。下面例举两个example说明三态驱动器的Verilog设计。
(1)数据流描述(使用assign 持续赋值语句)

//三态双向驱动器
module bidir(tri_out,out,in,en,b);
input in,en,b;
output out;
inout tri_out;
assign tri_out=en?in:'bz;
assign out=b^tri_out;
endmodule
  • 当en=1,tri_out=in,即此时tri_out为输出端口;tri_out的状态可为高电平和低电平状态。
  • 当en=0,tri_out为高阻态,out=b^tri_out。因为out的两个输入信号有一个为高阻态,所以out输出为不确定状态。

(2)行为+数据流描述(使用always过程语句和assign持续赋值语句)

module bidir2(bidir,en,clk);
input en,clk;
inout[7:0] bidir;reg[7:0] temp;
assign bidir=en?temp:8'bz;  //bidir作为输入
always@(posedge clk)
	begin if(en) temp=bidir;  //bidir作为输出
	else temp=temp+1;		//改变输入、输出值
	end
endmodule

二、编码器、译码器

1、3-8译码器
  3-8译码器具有3输入、8输出。译码器一般用于驱动数码管,根据数码管是共阴还是共阳的,可选择译码器是输出高电平还是低电平有效。下面的例子为输出高电平有效,若需要低电平有效只需将case语句中,8位二进制的取反(0变成1,1变成0)。

module tan_74138(cin,cout);
input[2:0] cin;
output[7:0] cout; reg[7:0] cout;
always@(cin)
begin
	case(cin)
	3'd0:cout=8'b00000001;	
	3'd1:cout=8'b00000010;
	3'd2:cout=8'b00000100;
	3'd3:cout=8'b00001000;
	3'd4:cout=8'b00010000;
	3'd5:cout=8'b00100000;
	3'd6:cout=8'b01000000;
	3'd7:cout=8'b10000000;
	default:cout[7:0]=7'bx;
	endcase
end
endmodule

2、8-3优先编码器

module encoder8_3(none_on,outcode,a,b,c,d,e,f,g,h);
input a,b,c,d,e,f,g,h;
output none_on;output[2:0] outcode;reg[3:0] outtemp;
assign {none_on,outcode}=outtemp;  //none_on=1,无输入,否则有输入
always@(a or b or c or d or e or f or g or h)
	begin
	if(h) outtemp=4'b0111;
	else if(g) outtemp=4'b0110;
	else if(f) outtemp=4'b0101;
	else if(e) outtemp=4'b0100;
	else if(d) outtemp=4'b0011;
	else if(c) outtemp=4'b0010;
	else if(b) outtemp=4'b0001;
	else if(a) outtemp=4'b0000;
	else 		  outtemp=4'b1000;
	end
endmodule

作为条件语句,if-else语句具有优先顺序,利用这个特点,实现优先编码器的设计。在该例子中,输入为a~h,输出为outcode。输入高电平有效,根据if-else语句顺序,h的优先级最高,a的优先级最低。

3、七段数码管译码器

module decode7(decodeout,dec_in);
input[3:0] dec_in;
output[6:0] decodeout;reg[6:0] decodeout;
always@(dec_in)
	begin
	case(dec_in)		//case语句进行译码
	4'd0:decodeout=7'b1111110;		//decodeout[6]~[0]分别对应数码管的a~g
	4'd1:decodeout=7'b0110000;
	4'd2:decodeout=7'b1101101;
	4'd3:decodeout=7'b1111001;
	4'd4:decodeout=7'b0110011;
	4'd5:decodeout=7'b1011011;
	4'd6:decodeout=7'b1011111;
	4'd7:decodeout=7'b1110000;
	4'd8:decodeout=7'b1111111;
	4'd9:decodeout=7'b1111011;
	default:decodeout=7'bx;
	endcase
	end
endmodule
	
	

4、奇偶校验位产生器

module parity(even_bit,odd_bit,input_bus);
input[7:0] input_bus; 
output even_bit,odd_bit;
assign odd_bit=^input_bus;		//产生奇检验位
assign even_bit=~odd_bit;     //产生偶检验位
endmodule
	

计检验位产生原理:
odd_bit等于input_bus各位异或的结果。
例如:input_bus=00000001,则:

odd_bit=((((((0^0)^0)^0)^0)^0)^0)^1=1

如果input_bus的各位1的个数为奇数,则odd_bit=1,否则odd_bit=0,因为1的数量不是奇数就是偶数。所以偶校验位:even_bit=~odd_bit;

三、数据选择器
以4选1数据选择器为例,有4个输入端口,一个2位选择控制端,一个输出端。
(1)用if~else语句描述的4选1数据选择器

module mux4_1
(
	input in1,in2,in3,in4,
	input[1:0] sel,
	output reg out
);
always@(in1,in2,in3,in4,sel)
	begin
	if(sel==2'b00)
		out=in1;
	else if(sel==2'b01)
		out=in2;
	else if(sel==2'b10)
		out=in3;
	else
		out=in4;
	end
endmodule

(2)用case语句描述的4选1数据选择器

module mux4_1
(
	input in1,in2,in3,in4,
	input[1:0] sel,
	output reg out
);
always@(in1,in2,in3,in4,sel)
	begin case(sel)
			2'b00: out=in1;
			2'b01: out=in2;
			2'b10: out=in3;
			default: out=in4;
			endcase
	end
endmodule

四、其他组合电路
下面的例子是用组合电路实现的ROM,该存储器用16个存储单元存储了16个结果,分别是0~15共16个数的平方,根据地址输出相应的结果。

module rom
(
	input[3:0] addr,
	output[7:0] data
);
function[7:0] romout;
input[3:0] addr;
case(addr)
	0:romout=0;
	1:romout=1;
	2:romout=4;
	3:romout=9;
	4:romout=16;
	5:romout=25;
	6:romout=36;
	7:romout=49;
	8:romout=64;
	9:romout=81;
	10:romout=100;
	11:romout=121;
	12:romout=144;
	13:romout=169;
	14:romout=196;
	15:romout=215;
	16:romout=256;
	default:romout=8'hxx;
	endcase
endfunction
assign data=romout(addr);
endmodule