Verilog实验总结

一.组合电路设计

(1)数字加法器

a. 利用连续赋值语句实现

module add(a,b,sum,c_in,c_out);
	output sum,c_out;
	input a,b,c_in;
	assign sum=(a^b)^c_in;
	assign c_out=(a&b)|((a^b)&c_in);
endmodule

b.利用行为描述方式实现

module add(sum,a,b,c_in,c_out);
	output c_out,sum;
	input c_in,a,b;
	assign {c_out,sum}=a+b+c_in;
endmodule

 

c.2输入8 bit加法器(行为描述方式)

module add(sum,a,b,c_in,c_out);
	output c_out;
	output [7:0]sum;
	input [7:0]a,b;
	input c_in;
	assign {c_out,sum}=a+b+c_in;
endmodule

(2)数据比较器

例1:4位数据比较器

module comp(a,b,c,out);
input [3:0]a,b;
input c;
output [2:0]out;
reg [2:0]out;
always@ (a or b or c)
	if(a>b) 
		out=3'b100;
	else if(a<b)
		out=3'b001;
	     else
		out=c;
endmodule

(3).数据选择器

例1: 81数据选择器。

module select_8to1(sel,out,data_in);
	input[7:0]data_in;
	output out;
	input[2:0]sel;
	reg out;
always@(*)
case(sel)
	3'b000:out=data_in[0];
	3'b001:out=data_in[1];
	3'b010:out=data_in[2];
	3'b011:out=data_in[3];
	3'b100:out=data_in[4];
	3'b101:out=data_in[5];
	3'b110:out=data_in[6];
	3'b111:out=data_in[7];
	default:out=1'bx;
	endcase
endmodule

(4).  数字编码器

(有几个输入值,输入就为几位)

例1:二进制转化十进制8421BCD编码器,将十进制数012345678910个信号编成二进制代码的电路叫做二进制转化十进制编码器。 

module BCD8421(din,dout);
input [9:0]din;
output [3:0]dout;
reg [3:0] dout;
always@(din)
case(din)
	10'b0000000001:dout=4'b0000;
	10'b0000000010:dout=4'b0001;
	10'b0000000100:dout=4'b0010;
	10'b0000001000:dout=4'b0011;
	10'b0000010000:dout=4'b0100;
	10'b0000100000:dout=4'b0101;
	10'b0001000000:dout=4'b0110;
	10'b0010000000:dout=4'b0111;
	10'b0100000000:dout=4'b1000;
	10'b1000000000:dout=4'b1001;
	default:dout=4'bx;
endcase
endmodule

(5).数字译码器

译码是编码的逆过程;

输出有几种可能,输出就为几位;

例1:2线—4线译码器

module _2to4(e,din,dout);
input e;//使能,低电平有效
input [1:0] din;
output [3:0]dout;
reg [3:0]dout;
always@(din or e)
     case({din,e})
	3'b??1:dout=4'b1111;
	3'b000:dout=4'b1110;//0
	3'b010:dout=4'b1101;//1
	3'b100:dout=4'b1011;//2
	3'b110:dout=4'b0111;//3
	default:dout=4'bx;
     endcase
endmodule

(6)奇偶校验器

module checker(fod,fev,a);
	input[7:0]a;
	output fod,fev;        //fod为奇校验
	assign fod=^a;
	assign fev=~fod;
endmodule

 

二.时序电路设计

(1)触发器

例1:实现同步清0、置数和异步清0、置数共同在一个触发器上的复杂D触发器。

代码:

module dff(din,clk,clr,clr1,dout);
output dout;
input din,clk,clr,clr1;
reg dout;
//同步
always @(posedge clk)
    begin
        if(clr==0)
	        dout<=0;
        else dout<=din;
    end

always@(posedge clk or clr1)
    //begin
        if(!clr1)
	        dout<=0;
        else dout<=din;
    //end
endmodule

测试代码:

module dff_tb;
wire dout;
reg din,clk,clr,clr1;
dff uua(din,clk,clr,clr1,dout);
always #10 clk=~clk;
always #20 din=~din;

initial
	begin 
	clk=1;
	din=0;
	clr=0;
	clr1=0;
	#20 clr=1;
	#40 clr1=1;
end
endmodule

注意:

当clr,与clr1任何一个为零时,输出都为零

输出波形:

 

(2)计数器

例2:采用反馈清零法设计的十一进制计数器

module comp_11(clk,clr,dout);
output [3:0]dout;
input clk,clr;
reg [3:0]dout;
always @(posedge clk)
	if(clr)
		dout<=4'b0000;
	else if(dout==4'b1010)
		dout<=4'b0000;
	     else dout<=dout+1;
endmodule

 

(3)移位寄存器

例3:N位环型寄存器由N个移位寄存器组成,它可以实现环型移位。

module shift(clr,clk,dout);
parameter width=4,data=4'b0000;
output[width-1:0] dout;
input clr,clk;
reg [width-1:0] dout;
always@(posedge clk)
	if(!clr)
		dout<=data;
	else 
		dout<={dout[width-2:0],dout[width-1]};
endmodule

 

三.有限同步状态机

(1)基础概念

a.摩尔型:输出仅与当前状态有关(看C2模块)

b.米利型:与当前状态和输入共同决定

c.三段式

d.两段式

(2)Verilog HDL设计一个“111”序列检测器,当输入三个或三个以上的“1”时,电路输出为1,否则为0

a.摩尔型

第一步:先画出状态转移图(摩尔:四种状态)

 

三段式代码:

module moore(din,clk,clr,dout);
input din,clr,clk;
output dout;
reg dout;
parameter s0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;
reg [1:0]present_state,next_state;

//状态寄存器
always@(posedge clk or posedge clr)
	begin 
	   if(clr==1)
		present_state<=s0;//此处为当前状态输出
	   else 
		present_state<=next_state;
	end


//C1模块,为组合逻辑用=
always@(*)
	begin
	  case(present_state)
	s0:if(din==0) next_state=s0;
		else next_state=s1;
	s1:if(din==0) next_state=s0;
		else next_state=s2;
	s2:if(din==0) next_state=s0;
		else next_state=s3;
	s3:if(din==0) next_state=s0;
		else next_state=s3;
	default:next_state=s0;
	   endcase
end
//C2模块
always@(*)
	begin
	 if(present_state==s3)
		dout=1;
	 else dout=0;
	end
endmodule

测试代码:
 

module moore_tb;
 reg din,clr,clk;
 wire dout;
 moore uua(din,clk,clr,dout);
 always #10 clk=~clk;
 initial
   begin
	clr=0;
	clk=0;din=1;
	#20 din=0;
	#20 din=1;
	#40 din=1;
	#10 din=0;
	#20 din=1;
	#10 din=1;
	#20 din=1;
   end
endmodule

运行结果: 

 

b.米利型

状态转移图:

二段式代码:

module mealy_(din,dout,clk,clr);
input clk,clr,din;
output dout;
reg [1:0]present_state,next_state;
reg dout;
parameter s0=2'b00,s1=2'b01,s2=2'b11;
//状态寄存器
always@(posedge clk or posedge clr)
	begin
	 if(clr==1)
	    present_state<=s0;
	  else 
	    present_state<=next_state;
	end

always@(*)
	begin
	 case(present_state)
	s0:if(din==1) begin next_state=s1;dout=0;end
		else begin next_state=s0;dout=0;end
	s1:if(din==1)begin next_state=s2;dout=0;end
		else begin next_state=s0;dout=0;end
	s2:if(din==1)begin next_state=s2;dout=1;end
		else begin next_state=s0;dout=0;end
	default next_state=s0;
         endcase
	end
endmodule

测试代码:

module mealy__tb;
reg clk,clr,din;
wire dout;
mealy_ uut(din,dout,clk,clr);
always #10 clk=~clk;
initial
 begin
    clk=0;clr=0;din=0;
    #10 din=1;
    #20 din=1;
    #40 din=0;
    #20 din=1;
    #10 din=0;
    #60 din=1;
    #10 din=0;
    #20 din=1;

 end
endmodule

运行结果:


 

四.存储器

(1)设计位宽为8bit,深度为8的ROM

其端口有四个为:输出,时钟,片选,地址线

rom代码:

module rom(out,clk,cs,addr);
input clk,cs;
input [2:0]addr;
output [7:0]out;
reg [7:0]rom [7:0];      //注意不要忘记
reg [7:0]out;
initial
    begin
	rom[0]=8'b0000_0000;
	rom[1]=8'b0000_0001;
	rom[2]=8'b0000_0010;
	rom[3]=8'b0000_0011;
	rom[4]=8'b0000_0100;
	rom[5]=8'b0000_0101;
	rom[6]=8'b0000_0110;
	rom[7]=8'b0000_0111;
     end
always@(posedge clk)        //不要忘记写@
	begin
	    if(cs)
		out<=8'bzzzz_zzzz;
	    else 
		out<=rom[addr];
	end
endmodule
	

测试代码:

module rom_tb;
reg clk,cs;
reg [2:0]addr;
wire [7:0]out;            //注意输出为wire型,输入引脚为reg
rom uut(out,clk,cs,addr);
initial
   begin
	cs=1;
	addr=0;
	clk=0;
	#20 cs=0;
   end
always #10 clk=~clk;            

                                //repeat只能写在过程语句内
initial
repeat(7) 
	#20 addr=addr+1;

endmodule

实验结果:

 

 

(2)设计位宽为8bit,深度为8的RAM

其端口有:输入端口,输出端口,片选端口,读写选择端口,时钟,地址线

代码:

module ram(din,dout,we,cs,clk,addr);
 input clk,cs,we;
 input[2:0]addr;
 input [7:0]din;
 output [7:0]dout;
 reg[7:0]ram[7:0];            //前[7:0]代表8位,后[7:0]代表深度为8
 reg [7:0]dout;
always@(posedge clk)          //注意写always而不是initial
 begin
	if(cs)                    //低电平有效
  	  dout<=8'bzzzz_zzzz;
	else
	   if(we)                //低电平有效
		dout<=ram[addr];
	    else ram[addr]<=din;
 end
endmodule

测试代码:

注意

  • 前160单位时间写入数据,之后读出数据;
  • 重复7次,是因为刚开始的时候,din=0;addr=0;
  • 在重复第一次的时候,#20  addr=addr+1; din=din+1;则20单位的时候,addr为1,din为1;重复7次刚好到7;
module ram_tb;
 reg clk,cs,we;
 reg [2:0]addr;
 reg [7:0]din;
 wire [7:0]dout;
 ram uut(din,dout,we,cs,clk,addr);
 initial
	begin
	 clk=0;
	 addr=0;
	 cs=0;
	 we=0;
	din=0;
	 #160 we=1;
	end
always #10 clk=~clk;
 initial
	begin 
	   repeat(7)
	   begin
	       #20 addr=addr+1;
	           din=din+1;
	   end
	   #40 repeat(7)
         	#20 addr=addr-1;
	end
endmodule

写入的仿真图:

 输出的仿真图:

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值