北航电子电路设计verilog实验报告文档格式.docx
《北航电子电路设计verilog实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《北航电子电路设计verilog实验报告文档格式.docx(49页珍藏版)》请在冰豆网上搜索。
![北航电子电路设计verilog实验报告文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/8/a8c36679-23e7-4d7c-aca2-d6a804dd8386/a8c36679-23e7-4d7c-aca2-d6a804dd83861.gif)
#100$stop;
end
comparem(.equal(equal),.a(a),.b(b));
五、仿真结果
六、实验总结
verilog组合逻辑设计一般常用的语句有两种:
持续赋值语句(assign语句)和过程赋值语句(always@(*)语句)。
两者之间的差别有:
持续赋值语句(assign语句)主要用于对wire型变量的赋值,因为wire(线型)的值不能存住,需要一直给值,所以需要用持续赋值。
例如:
assignc=a+b;
只要a和b有任意变化,都可以立即反映到c上,也就是说c的值是根据a,b的值随时变化的。
过程赋值语句(always语句)主要用于reg型变量的赋值
,因为always语句被执行是需要满足触发条件的,所以always过程块里面的内容不是每时每刻都被执行,因此需要将被赋值的对象定义成寄存器类型,以便这个值能被保持住。
本实验测试模块中,为了生成变化的数据信号a和b,采用了#100a=0;
b=1;
赋值语句。
若需要比较的数据较多,所需赋值语句会增加,采用always#100clock=~clock产生周期时钟信号然后随机生成数据更简便。
选作一:
设计一个字节的比较器
比较两个字节的大小,如a[7:
0]大于b[7:
0],则输出高电平,否则输出低电平;
并改写测试模型,使其能进行比较全面的测试。
三、实验代码
①模块源代码:
modulecompare_8bit(result,a,b);
input[7:
0]a,b;
outputresult;
assignresult=(a>
b)?
`timescale1ns/1ns
compare_8bit.v"
moduletest;
reg[7:
wireresult;
initial
begin
a=8'
d0;
b=8'
#100a=8'
d6;
b=8'
d5;
d9;
d12;
d15;
#100$stop;
end
compare_8bitm(.result(result),.a(a),.b(b));
经过改写:
./eight.v"
regclock;
clock=0;
always#50clock=~clock;
always@(posedgeclock)
a={$random}%256;
b={$random}%256;
begin#100000$stop;
eightm(.result(result),.a(a),.b(b));
四、仿真结果
五、实验总结
最初测试模块使用了#100a=8'
的赋值语句,a,b的每个值都要手动赋予。
由于一个字节(8位)有256个可能值,为了进行比较全面的测试,改写为
always#50clock=~clock;
让a,b随机生成数据,可通过设置运行时间进行任意次比较。
练习二简单分频时序逻辑电路的设计
1、掌握最基本组合逻辑电路的实现方法。
2、学习时序电路测试模块的编写。
3、学习综合和不同层次的仿真。
用always块和@(posedgeclk)或@(negedgeclk)的结构表述一个1/2分频器的可综合模型,观察时序仿真结果。
modulehalf_clk(reset,clk_in,clk_out);
inputclk_in,reset;
outputclk_out;
regclk_out;
always@(posedgeclk_in)
if(!
reset)clk_out=0;
elseclk_out=~clk_out;
end
`timescale1ns/100ps
`defineclk_cycle50
moduletop;
regclk,reset;
wireclk_out;
always#`clk_cycleclk=~clk;
clk=0;
reset=1;
#10reset=0;
#110reset=1;
#100000$stop;
half_clkm0(.reset(reset),.clk_in(clk),.clk_out(clk_out));
在可综合的VerilogHDL模型,通常使用always块和@(posedgeclk)或@(negedgeclk)的结构来表述时序逻辑。
为了能正确地观察到仿真结果,并确定时序电路的起始相位,在可综合风格的模块中,通常定义一个复位信号reset,当reset为低电平时,对电路中的寄存器进行复位。
clk_out起始段为红色,是因为它是reg型,且尚未被赋值,仿真工具认为其为不定态。
选作二七段数码管译码电路
设计一个七段数码管译码电路。
modulesegdisplay(data,seg);
input[3:
0]data;
output[6:
0]seg;
reg[6:
0]paraseg;
always@(data)
case(data)
4'
b0000:
paraseg=7'
b1111110;
b0001:
b0110000;
b0010:
b1101101;
b0011:
b1111001;
b0100:
b0110011;
b0101:
b1011011;
b0110:
b0011111;
b0111:
b1110000;
b1000:
b1111111;
b1001:
b1110011;
b1010:
b0001101;
b1011:
b0011001;
b1100:
b0100011;
b1101:
b1001011;
b1110:
b0001111;
b1111:
b0000000;
endcase
assignseg=paraseg;
moduleexperiment4;
wire[6:
0]out;
reg[3:
data=0;
clock=0;
always#50clock=~clock;
data<
=data+1;
#10000$stop;
segdisplaysegdisplay11(.data(data),.seg(out));
在每个上升沿data自加,依次从0000加到1111,在把其对应代表七段数码管abcdefg亮暗的7位二进制数赋值给paraseg,即输出out。
练习三:
利用条件语句实现计数分频时序电路
1、掌握条件语句在简单时序模块设计中的使用。
2、学习在Verilog模块中应用计数器。
3、学习测试模块的编写、综合和不同层次的仿真。
仿真一个可综合风格的分频器,将10MB的时钟分频为500KB的时钟,定义一个计数器,原理同1/2分频器一样,只不过分频变为1/20。
modulefdivision(RESET,F10M,F500K);
inputF10M,RESET;
outputF500K;
regF500K;
0]j;
always@(posedgeF10M)
if(!
RESET)
F500K<
=0;
j<
else
if(j==9)
=~F500K;
=j+1;
end
endmodule
moduletest_fdivision;
regF10M,RESET;
wireF500K_clk;
always#`clk_cycleF10M=~F10M;
RESET=1;
F10M=0;
#100RESET=0;
#100RESET=1;
fdivisionm(.RESET(RESET),.F10M(F10M),.F500K(F500K_clk));
我们按照课本上的程序进行了仿真,从仿真结果中可以看到,结果所得的信号的周期是原信号的20倍,即实现了1/20分频。
选作三:
设计一个单周期形状的周期波形
利用10MHZ的时钟,设计一个单周期形状的周期波形。
moduleexp3(RESET,F10M,F_OUT);
outputF_OUT;
regF_OUT;
reg[15:
RESET)//?
?
F_OUT<
//?
case(j)
199:
F_OUT<
=1;
299:
499:
j<
endcase
`defineclk_cycle50
moduletest_exp3;
wireF;
always
#`clk_cycleF10M=~F10M;
#50000$stop;
exp3m2(.RESET(RESET),.F10M(F10M),.F_OUT(F));
这个实验只需要把练习三中的程序稍加修改即可得到结果。
在实验的过程,一开始我们预设的stop的持续时间太短,导致输出不到一个周期,让我们误以为编写的程序有逻辑问题,从而耽误了很多时间。
后来我们根据波形的高低电平持续时间重新计算了步长,根据步长进行时钟翻转的设置,最终得到了正确的结果。
练习五:
用always块实现较复杂的组合逻辑
1、掌握用always实现较大组合逻辑电路的方法。
2、进一步了解assign与always两种组合电路实现方法的区别和注意点。
3、学习测试模块中随机数的产生和应用。
4、学习综合不同层次的仿真,并比较结果。
设计一个简单的指令译码电路,该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,都有要作出及时的反应。
`defineplus3'
d0
`defineminus3'
d1
`defineband3'
d2
`definebor3'
d3
`defineunegate3'
d4
modulealu(out,opcode,a,b);
output[7:
input[2:
0]opcode;
input[7:
0]a,b;
always@(opcodeoraorb)
case(opcode)
`plus:
out=a+b;
`minus:
out=a-b;
`band:
out=a&
b;
`bor:
out=a|b;
`unegate:
out=~a;
default:
out=8'
hx;
endcase
./lx5m.v"
modulealutest;
wire[7:
reg[2:
parametertimes=5;
opcode=3'
h0;
repeat(times)
begin
#100a={$random}%256;
opcode=opcode+1;
从仿真结果来看,opcode=000时,程序实现a+b的功能;
opcode=001时,程序实现a-b的功能;
opcode=010时,程序实现a&
b的功能;
opcode=011时,程序实现a|b的功能;
opcode=100时,程序实现-a的功能;
opcode=101时,系统进入高阻态,输出未知。
选作五:
运用always块设计一个8路数据选择器
一、实验设备
二、实验内容
每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应地变化。
moduleexp5(slt,in0,in1,in2,in3,in4,in5,in6,in7,out);
0]slt;
input[3:
0]in0,in1,in2,in3,in4,in5,in6,in7;
output[3:
0]out;
reg[3:
always@(in0orin1orin2orin3orin4orin5orin6orin7orslt)
case(slt)
3'
d0:
out<
=in0;
d1:
=in1;
d2:
=in2;
d3:
=in3;
d4:
=in4;
d5:
=in5;
d6:
=in6;
d7:
=in7;
`timescale1ns/1ns
moduletest_exp5_2;
0]slt=0;
regclk;
wire[3:
always#10clk=~clk;
always@(posedgeclk)
slt=slt+1;
initial
clk=0;
in0=1;
in1=3;
in2=5;
in3=7;
in4=9;
in5=11;
in6=13;
in7=15;
#160
in0=0;
in1=2;
in2=4;
in3=6;
in4=8;
in5=10;
in6=12;
in7=14;
exp5
m(.slt(slt),.in0(in0),.in1(in1),.in2(in2),.in3(in3),.in4(in4),.in5(in5),.in6(in6),.in7(in7),.out(out));
五、实验结果
从仿真波形中可以看出,在输入一定时,输出随着stl的变化而变化;
当输入改变时,和之前相同stl的情况下,输出也发生了变化,满足了题目的要求。
在设计程序的时候,我们将16个数按单数双数分为两组,是为了便于查看实验结果,实际上可以任意将这16个数均分为两组,都可以满足输出随输入变化的要求。
本次实验是一个较为复杂的组合逻辑电路,在实现这样的电路的时候,一般考虑条件分支语句(如if…else或者case等)来实现相应的功能。
练习六:
在VerilogHDL中使用函数
1、了解函数的定义和在模块设计中的使用。
2、了解函数的可综合性问题。
3、了解许多综合器不能综合复杂的算术运算。
做一个函数调用的示例,采用同步时钟触发运算的执行,每个clk时钟周期执行一次运算,在测试模块中,调用系统任务$display及在时钟的下降沿显示每次运算的结果。
modulelx6(clk,n,result,reset);
output[31:
0]result;
0]n;
inputreset,clk;
reg[31:
reset)
result<
=n*factorial(n)/((n*2)+1);
function[31:
0]factorial;
0]operand;
0]index;
factorial=operand?
for(index=2;
index<
=operand;
index=index+1)
factorial=index*factorial;
endfunction
`include"
lx6m.v"
moduletest_lx6;
0]n,i;
regreset,clk;
wire[31:
n=0;
reset=1;
#100reset=0;
#100reset=1;
for(i=0;
i<
=15;
i=i+1)
#200n=i;
always#`clk_cycleclk=~clk;
lx6m(.clk(clk),.n(n),.result(result),.reset(reset));
六、实验结果
按照课本上的程序进行仿真,实验结果显示,程序完成了对数据的阶乘运算。
我们也借此初步了解了函数的使用方法。
选作六:
设计一个带控制端的逻辑运算电路
分别完成正整数的平方、立方和最大数为5的阶乘的运算,要求可综合。
编写测试模块,并给出各种层次的仿真波形,比较它们的不同。
modulext6(clk,n,result,reset,select);
input[1:
0]select;