数字EDA基础实验报告100227班XXX 10021189
数字EDA基础实验报告
实验四阻塞赋值与非阻塞赋值的区别
100227班XXX 10021189
一对实验的理解
通过本实验,要求我们掌握阻塞赋值与非阻塞赋值的概念和区别,以及了解阻塞赋值的使用情况。阻塞赋值与非阻塞赋值,在教材中我们已经了解了它们之间在语法上的区别以及综合后所得到的电路结构上的区别。在always块中,阻塞赋值(=)可以理解为赋值语句是顺序执行的,而非阻塞赋值(<=)可以理解为赋值语句是并发执行的。实际的时序逻辑设计中,一般的情况下非阻塞赋值语句被更多地使用,有时为了在同一周期实现相互关联的操作,也使用了阻塞赋值语句。
在搞清楚阻塞赋值与非阻塞赋值的区别之后,思考题要求我们完成以下两个模块来观察仿真波形,分析输出结果。
二实现思路
我们将课本中给定的模块进行略微修改,即可获得题目中所要求的模块。
三实验源代码
1 功能模块源代码
module ex4_1(clk,a,b,c);
always @(posedge clk)
endmodule
module ex4_2(clk,a,b,c);
output [3:0] b,c; input [3:0] a; input clk; reg [3:0] b,c; begin c = b; b = a; end
数字EDA基础实验报告100227班XXX 10021189
output [3:0] b,c; input [3:0] a; input clk; reg [3:0] b,c;
always @(posedge clk) b=a;
always @(posedge clk) c=b;
endmodule
2 测试模块源代码
`timescale 1ns/100ps
`include "ex4.v"
module testmodule;
wire [3:0] b1,c1,b2,c2;
reg [3:0] a;
reg clk;
initial
begin
clk = 0;
forever #50 clk = ~clk;
end
initial
begin
a = 4'h3;
$display("____________________________"); # 100 a = 4'h7;
$display("____________________________"); # 100 a = 4'hf;
$display("____________________________"); # 100 a = 4'ha;
$display("____________________________"); # 100 a = 4'h2;
$display("____________________________");
# 100 $display("____________________________"); $stop;
end
数字EDA基础实验报告100227班XXX 10021189
ex4_1 m1 (clk,a,b2,c2);
ex4_2 m2 (clk,a,b1,c1);
endmodule
四仿真波形
局部放大波形:
五波形说明
由波形可以看出:
每个时钟上升沿,两个模块输出端口b和c的值均发生变化,但是略有不同。第一个模块中b和c的值同时变为a;而第二个模块中b的值会理解变化为a,而c的值会变为b
前
数字EDA基础实验报告100227班XXX 10021189
一状态的值,即该模块拥有一个寄存器的效果。
六实验总结
我们先总结课本给出的两个模块的例子。课本给定了两个模块block与non_block,我们可以观察到如下波形:
可见,阻塞赋值(=)会使语句顺序执行。即先运行b=a,再运行c=b。故c和b的至均与a一致。
而非阻塞赋值(<=)会使语句并发执行。即b<=a和c<=b同时运行,所以此状态下c的值会先变为b,而b的值会立即变为a。
模块2使用了两个always语句,输出波形同非阻塞赋值。故可理解为两个always块同时运行,这就相当于两条语句同时运行的非阻塞赋值(<=)。
数字EDA基础实验报告100227班XXX 10021189
数字EDA基础实验报告
实验五用always块实现较复杂的组合逻辑电路
100227班XXX 10021189
一对实验的理解
本实验,我们需要使用always块来完成一个8路数据选择器,来掌握用always实现较大组合逻辑电路的方法,进一步了解assign与always两种组合电路实现方法的区别和注意点。另外,在测试文件中,我们需要练习使用随机数来产生数据。
使用assign结构来实现组合逻辑电路,如果逻辑关系比较复杂,不容易理解语句的功能。而适当地采用always来设计组合逻辑,使源代码语句的功能容易理解。课本例题是一个简单指令译码电路的设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,结果都要做出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assign语句,表达起来非常复杂。示例中使用了电平敏感的always块,所谓电平敏感的触发条件,是指在@后的括号内电平列表中的任何一个电平发生变化(与时序逻辑不同,它在@后的括号内没有沿敏感关键词,如posedge或negedge),就是触发always块的动作,并且运用了case结构来进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐,便于理解。 二实现思路
仿照课本always块的实例,我们可使用case语句来作为数据选择器的核心语句。通过case语句判定输入控制信号的值,将不同数据输出,已达到数据选择的目的。
三实验源代码
1 功能模块源代码
module ex5_1(a,b,c,d,e,f,g,h,n,out);
always @(n,a,b,c,d,e,f,g,h)
begin
output[3:0] out; reg[3:0] out; input[2:0] n; input[3:0] a,b,c,d,e,f,g,h;
数字EDA基础实验报告100227班XXX 10021189
case(n)
0: out = a;
1: out = b;
2: out = c;
3: out = d;
4: out = e;
5: out = f;
6: out = g;
7: out = h;
default: out=4'hx;//未收到指令时,输出任意态。
endcase
end
endmodule
2 测试模块源代码
`include "ex5.v"
module testmodule;
initial
#50 n =3'b000;
#50 n =3'b001;
#50 n =3'b010;
#50 n =3'b011;
wire [3:0] out; reg [2:0] n; reg [3:0] a,b,c,d,e,f,g,h; ex5_1 m (a,b,c,d,e,f,g,h,n,out); begin a={$random,$random,$random,$random}; b={$random,$random,$random,$random}; c={$random,$random,$random,$random}; d={$random,$random,$random,$random}; e={$random,$random,$random,$random}; f={$random,$random,$random,$random}; g={$random,$random,$random,$random}; h={$random,$random,$random,$random};
数字EDA基础实验报告100227班XXX 10021189
#50 n =3'b100;
#50 n =3'b101;
#50 n =3'b110;
#50 n =3'b111;
endmodule #50 $stop; end
四仿真波形
局部放大波形:
数字EDA基础实验报告100227班XXX 10021189
五波形说明
由波形可以看出:
每当控制信号变化时,输出的值也相应变化,其值为控制信号对应端口的输出。例如控制信号n=001时,out输出的是第1路(0~7)的信号,即out=b=1101,其余时间段类推。
最后一个时刻,选择信号不变,保持为n=111,而第7路数据变为000,则输出也变为000。可见该模块符合题目要求。
六实验总结
通过该实验,我们初步掌握了always实现较大组合逻辑电路的方法,进一步了解assign与always两种组合电路实现方法的区别。在测试文件中,我们开始学习使用随机数$random来产生数据。
数字EDA基础实验报告100227班XXX 10021189
数字EDA基础实验报告
实验六在Verilog中使用函数
100227班XXX 10021189
一对实验的理解
与一般的程序设计语言一样,Veirlog HDL也可使用函数以适应对不同变量采取同一运算的操作。Veirlog HDL函数在综合时被理解成具有独立运算功能的电路,每调用一次函数相当于改变这部分电路的输入以得到相应的计算结果。课本给出了一个函数调用的简单示范,采用同步时钟触发运算的执行,每个clk时钟周期都会执行一次运算。并且在测试模块中,通过调用系统任务$display在时钟的下降沿显示每次计算的结果。
本练习要求我们设计一个带控制端的逻辑运算电路,分别完成正整数的平方、立方和阶乘的运算。编写测试模块,并给出仿真波形。我们可以参照例子编写函数来完成任务。 二实现思路
本模块需要有两个功能:乘方和阶乘。于是我们可以加入控制端n(4bit),最前一位代表功能选择(0代表乘方运算,1代表阶乘运算),后3为代表乘方的阶数(例如010代表平方,011代表立方)。然后数据从data端输入数据。
在时钟上升沿到来时,判定n最高位是否为零。
① 当n[3]=0时,进入乘方模式,系统捕捉n的后三位{n[2],n[1],n[0]},然后进入循环。
循环内容就是将结果与data不断相乘,相乘次数为n后三位的值,也就实现了乘方运算。
② 当n[3]=1时,进入阶乘模式。阶乘函数课本已给出,我们可以仿照其完成。
完成以上运算后,系统会产生输出。
(注:为便于波形观察,将结果带宽由32bit调整为9bit,实际使用中根据输入范围可重新调整各变量带宽)
三实验源代码
1 功能模块源代码
module ex6_1(clk,data,n,result,reset);
output[8:0] result;
input[3:0] n; //操作数 4bit
数字EDA基础实验报告100227班XXX 10021189
input[3:0] data;
input reset,clk;
reg[8:0] result;
reg [3:0] temp;
//数据 3bit
always @(posedge clk) //clk的上沿触发同步运算。
begin
end
function [8:0] times; //相乘函数
end
endfunction
function [8:0] factorial; //阶乘运算
end
endfunction
if(!reset) //reset为低时复位。 result<=0; else if (n[3]==0) //乘方 begin result =1; for (temp={n[2],n[1],n[0]}; temp > 0; temp = temp - 1) result =times(result ,data); end else if (n[3]==1) //阶乘 result = factorial(data); input [8:0] data1; input [8:0] data2; times = data1 * data2; begin input [3:0] operand; reg [3:0] index; factorial = operand ? 1 : 0; factorial = index * factorial; begin for(index = 2; index <= operand; index = index + 1)
数字EDA基础实验报告100227班XXX 10021189
endmodule
2 测试模块源代码
`include "ex6.v"
`timescale 1ns/100ps
`define clk_cycle 50
module testmodule;
reg[3:0] data,i;
reg[3:0] n;
reg reset,clk;
wire[8:0] result;
initial
begin
data=0;
reset=1;
clk=0;
#100 reset=0;
#100 reset=1;
#200 data=5;
n=4'b0000;
#200 n=4'b0001;
#200 n=4'b0010;
#200 n=4'b0011;
#200 data=3;
#200 $stop;
end
always #`clk_cycle clk=~clk;
n=4'b1000; n=4'b1000; #200 data=5;
数字EDA基础实验报告100227班XXX 10021189
ex6_1 m (.clk(clk),.data(data),.n(n),.result(result),.reset(reset));
endmodule
四仿真波形
局部放大波形:
数字EDA基础实验报告100227班XXX 10021189
五波形说明
由波形可以看出:
n作为控制端,分别控制着运算模式,data根据n的不同而产生变化。具体过程参见上述截图。显然模块运行正常,可以完成预计功能。
六实验总结
通过本实验,我们了解了函数的定义和在模块设计中的使用,了解了函数的可综合性问题,同时了解了许多综合器不能总和复杂运算,熟悉了函数的编写、调用等工作。
报告名称:电子电路设计训练数字部分
学院:仪器科学与光电工程学院
目录
实验报告概述:... 3
一、 选做实验总结:... 3
(1) 补充练习2:楼梯灯设计... 3
(2) 练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序 5
(3) 练习题3:利用10MB的时钟,设计一个单周期形状的周期波形... 6
(4) 练习题4:运用always块设计一个8路数据选择器... 6
(5) 练习题5:设计一个带控制端的逻辑运算电路... 7
二、 必做实验总结:... 7
(1) 练习一:简单组合逻辑设计... 7
(2) 练习三:利用条件语句实现计数分频失序电路... 7
(3) 练习四:阻塞赋值与非阻塞赋值得区别... 8
(4) 练习五:用always块实现较复杂的组合逻辑电路... 8
(5) 练习六:在verilog HDL中使用函数... 9
(6) 练习七:在verilog HDL中使用任务... 9
(7) 练习八:利用有限状态机进行时许逻辑设计... 10
三、 实验总结及体会:... 10
四、 选作程序源代码... 11
(1) 练习题3:利用10MB的时钟,设计一个单周期形状的周期波形... 11
(2) 练习题4:运用always块设计一个8路数据选择器... 12
(3) 练习题5:设计一个带控制端的逻辑运算电路... 13
(4) 练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序 14
(5) 补充练习2:楼梯灯设计... 16
图表目录
Figure 1 楼梯灯任务4. 5
Figure 2 组合逻辑... 5
Figure 3 时序逻辑... 6
Figure 4 周期波形... 6
Figure 5 8路数据选择器... 6
Figure 6 逻辑运算电路... 7
Figure 7 组合逻辑设计... 7
Figure 8 计数分频时序电路... 8
Figure 9 阻塞赋值与非阻塞赋值得区别... 8
Figure 10 always块组合逻辑电路... 9
Figure 11 使用函数... 9
Figure 12 使用任务... 10
Figure 13 有限状态机... 10
电子电路设计训练(数字部分)实验报告
本实验报告为对四次电子电路设计训练(数字部分)实验的总结,主要包括以下四部分:
第一部分为选做实验总结,主要包括每个选择实验的设计思路、运行结果、注意事项、心得体会;
第二部分为必做实验总结,包括运行结果、总结、心得体会;
第三部分为课程总结和体会,是对全部实验及课程的总结;
第四部分为选做实验部分源代码;
一、 选做实验总结:
(1) 补充练习2:楼梯灯设计
设计思路:
本题给出楼梯的运行规则,并分别给与四个相应任务进行编程设计,考虑到程序的通用性及FPGA高速并行处理的优点,
主要思路如下:
根据运行规则(8s内和大于8s等),对每个灯的相应状态进行编程,设计时序逻辑及有限状态机;由于在总体上看,每个灯的状态变化相对独立(只有一个人上楼除外),故对每个灯编程所得到的程序代码可通用于其它灯(只需要改变相应寄存器定义即可),此即为灯控制模块,对4个不同的任务,只需设计其它部分判断逻辑,即可完成任务要求;如此设计,可大大提高程序设计效率、易用性,同时如果面对更多的灯控制需要,也可快速进行修改部署。
下面针对不同任务给出不同处理方法:
任务1/任务3:由于任务1和任务3在定义上有很大相同点,比如同样是一个人走楼梯,若不考虑一个人同时在两层使两个灯亮,则事实上就是一个人始终只能使一盏灯亮,亮起后盏时熄灭前一盏;在保持每个灯控制模块不改变的情况下,利用非阻塞赋值,判断该人目前所处状态及位置(上楼/下楼,楼层),同时规定输出,同时只能亮一盏灯;
任务2:由于输入信号已被赋值给寄存器变量,此时只需在系统时钟作用下对寄存器中输入变量进行判断,满足要求即为正确信号,再输入灯控制模块;
任务4:由于已有灯控制模块,此时只需结合任务2防抖电路,直接输出状态信号所对应的结果即可;
(单个)灯控制模块代码:
always @(posedge clk)
begin
signal_test[0]<=signal[0];
if(signal_test[0]==signal[0])
begin
i0=i0+1;
end
else
i0=0;
if(i0>=5)
begin
signal_reg[0]=signal[0];
end
if(state0==light_off)
begin
k0=0;
k0a=0;
k0b=0;
end
else
k0=k0+1;
case(signal_reg[0])
1: if(!reset)
begin
state0=light_off;
end
else
begin
k0a=k0a+1;
if((k0a >= 79)&&(k0<=119))
state0=light_on12;
else
state0=light_on8;
end
0:if(!reset)
begin
state0=light_off;
end
else if(k0a==0)
state0=light_off;
endcase
case(state0)
light_off:light_reg[0]=0;
light_on8:
begin
light_reg[0]=1;
if(k0b==79)
state0=light_off;
else
k0b=k0b+1;
end
light_on12:
begin
light_reg[0]=1;
if(k0b==119)
state0=light_off;
else
k0b=k0b+1;
end
endcase
end
*分栏显示,详细代码见报告第四部分;
运行结果:
Figure 1 楼梯灯任务4
Figure 2 楼梯灯信号防抖部分放大结果
(2) 练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序
设计思路:
纯组合排序中,设计sort排序任务对数列中的元素进行排序,通过调用任务实现对不同元素的排序功能,并将排序完成的结果直接输出;
冒泡排序即为每次将两个相邻数进行比较,大的数后“浮”,每一趟比较获得较大值并置于数列末位;
根据题目要求,每比较一次,即将调换位置的数字进行输出;同样设计sort任务,对两数字进行比较并排序;
通过排序控制和逻辑判断代码,控制sort任务的有效调用,进而实现冒泡排序功能;
根据设计要求,程序中只设计有一个输入端口,通过对输入信号不断移位,模拟串并行信号转换,从而完成穿行输入,并行比较的功能;
运行结果:
Figure 3 组合逻辑
Figure 4 时序逻辑
(3) 练习题3:利用10MB的时钟,设计一个单周期形状的周期波形
设计思路:
对输入时钟进行计数,通过if语句进行判断,若满足判断条件,则按要求改变输出信号;如此循环往复,即可产生所需单周期形状的周期波形;
运行结果:
Figure 5 周期波形
(4) 练习题4:运用always块设计一个8路数据选择器
设计思路:
利用define宏定义预先定义,利于后期程序功能的扩充和调整;同时利用case语句判断信号,并将相对应信号输出,进而完成系统目标功能;
运行结果:
Figure 6 8路数据选择器
(5) 练习题5:设计一个带控制端的逻辑运算电路
设计思路:
设计三个函数分别完成三个要求的计算,通过函数调用实现相应功能;设计的控制端为同步控制端,需要通过时钟信号从而进行检测复位;
运行结果:
Figure 7 逻辑运算电路
二、 必做实验总结:
(1) 练习一:简单组合逻辑设计
语法要点:
Assign语句构成的组合逻辑电路,若输入a,b改变,则输出equal;
利用assign equal=(a==b)?1:0语句,可同时完成判断赋值功能,大大减少代码量;
运行结果:
Figure 8 组合逻辑设计
(2) 练习三:利用条件语句实现计数分频时序电路
语法要点:
此程序主要练习了对输入时钟进行计数,判断,从而实现分频输出;
在实际应用中,可以通过该方式获得不同占空比或频率的信号供系统使用;
课本程序问题修改:
课本测试程序中未定义F10M_clk变量,故应将测试程序fdivision_TOP中出现的该变量改为已定义的F10M;
运行结果:
Figure 9 计数分频时序电路
(3) 练习四:阻塞赋值与非阻塞赋值的区别
语法要点:
阻塞赋值呈现的是一种立即赋值的状态,即同一个变量在前后语句中用到,语句间的顺序会影响到输出的结果;
非阻塞赋值对每一个块中语句间的相对位置没有要求,只在该块语句全部运行完成后同一进行赋值;
运行结果:
Figure 10 阻塞赋值与非阻塞赋值得区别
(4) 练习五:用always块实现较复杂的组合逻辑电路
语法要点:
Always@实现了对若干输入信号的敏感,即只要有一个信号改变,输出即改变;
通过case语句,实现了选择性输出,对不同功能进行综合;
运行结果:
Figure 11 always块组合逻辑电路
(5) 练习六:在verilog HDL中使用函数
语法要点:
函数最基本功能即实现计算,通过对不同函数定义,实现不同的计算功能;同时定义函数,可以利于在该模块外对某函数功能的调用,增强了程序的通用性和功能性,同时可以使程序结构更加清晰,易读易懂;
运行结果:
Figure 12 使用函数
(6) 练习七:在verilog HDL中使用任务
语法要点:
相比函数,任务的调用功能更强大,可以实现运算并输出多个结果的功能,同时任务并不返回计算值,只通过类似C语言中的形参和实参的数据交换,实现功能;任务的定义和调用可以只程序结构更明晰,功能更丰富;
程序中通过对比较顺序的设计,实现了对4个数字,进行5次比较即可成功完成排序功能的目的;
运行结果:
Figure 13 使用任务
(7) 练习八:利用有限状态机进行时许逻辑设计
语法要点:
设计有限状态机主要需要进行状态分配,状态编码,然后利用case语句进行判断,从而改变相应状态,实现状态转移和输出变换;
对涉及时钟的一般时序逻辑,主要运用非阻塞(〈=)赋值完成功能;
课本程序问题修改:
在modelsim 10中,测试文件时钟无法仿真,故只能保持与课本测试文件相同的思路,重新编写测试文件,仿真结果如下,与课本完全一致;
运行结果:
Figure 14 有限状态机
三、 实验总结及体会:
通过半个学期的学习和实验,我初步掌握了verilogHDL语言和modelsim软件,可以通过编程实现数字电路基础中几乎全部简单逻辑芯片的功能,同时可以用编程实现相对复杂一点的逻辑电路和功能.
总体而言,四次实验内容相对简单,几乎是在课后实验的基础上稍稍做了提高,以利于我们掌握并巩固课上学习的知识。有几个课后实验内容,按照程序输入后无法进行波形仿真,在改正一些错误定义,或者重写测试程序后,都能顺利完成实验任务。通过实验上机,巩固了我们的理论知识,加强了实际运用的能力,对整个课程的学习起到了很好的作用。
最后一个补充实验相对复杂,但实现的方法却可以有很多,在实际写代码前进行构思分析,在这个实验中显得尤为重要,例如,如何发挥FPGA并行处理的能力,如何提高程序的通用性,能够将所设计的模块结构同时完成四个任务,如何设计代码提高效率的同时节省硬件资源……都是在设计构思中不得不考虑的环节,因此,通过最后一个实验的设计,能够很好的锻炼我们解决实际生活中问题的能力,使我们对所学的知识能够真正有所使用。
运用verilog HDL语言进行硬件电路设计,已成为未来电路设计的主要趋势,学习这门语言及相应软件,能够帮助我们在以后的学习及科研中,大大提高我们的效率,使我们能够快速搭建实验平台,完成目标功能。
虽然8周的课,时间相对较短,但通过这8周的学习,我对verilog HDL语言有了全面的认识,对基本的语法都有了很好的掌握,虽然时间有限,不能对verilog HDL语言有更深入的认识,但通过这8周的学习,我为我将来进一步深化使用这个工具打下了坚实的基础。
四、 选作程序源代码
(1) 练习题3:利用10MB的时钟,设计一个单周期形状的周期波形
主程序:
module fd
ivison_2(RESET,F10M,clk_out,j);
input F10M,RESET;
output clk_out;
output[12:0] j;
reg clk_out;
reg[12:0] j;
always @(posedge F10M)
begin
if(!RESET)
begin
clk_out<=0;
j<=0;
end
else
begin
if(j==199)
begin
j<=j+1;
clk_out<=1;
end
else if(j==299)
begin
j<=j+1;
clk_out<=0;
end
else if(j==499)
j<=0;
else j<=j+1;
end
end
endmodule
测试程序:
`timescale 1ns/100ps
`define clk_cycle 50
module TOP_2;
reg F10M,RESET;
wire clk;
wire[12:0] j;
always #`clk_cycle F10M = ~F10M;
initial
begin
RESET=1;
F10M=0;
#100 RESET=0;
#100 RESET=1;
#10000 $stop;
end
fdivison_2 fdivison_2(.RESET(RESET),.F10M(F10M),.clk_out(clk),.j(j));
endmodule
(2) 练习题4:运用always块设计一个8路数据选择器
主程序:
`define s1 3'd0
`define s2 3'd1
`define s3 3'd2
`define s4 3'd3
`define s5 3'd4
`define s6 3'd5
`define s7 3'd6
`define s8 3'd7
module mux_8(a,b,c,d,e,f,g,h,selet,out);
input[3:0] a,b,c,d,e,f,g,h;
input[2:0] selet;
output[3:0] out;
reg[3:0] out;
always @(a or b or c or d or e or f or g or h or selet)
begin
case(selet)
`s1:out=a;
`s2:out=b;
`s3:out=c;
`s4:out=d;
`s5:out=e;
`s6:out=f;
`s7:out=g;
`s8:out=h;
default:out=4'hz;
endcase
end
endmodule
测试程序:
`timescale 1 ns/1 ns
module muxtest;
wire[3:0] out;
reg[3:0] a,b,c,d,e,f,g,h;
reg[2:0] selet;
parameter times1=8;
initial
begin
a=0;
b=1;
c=2;
d=3;
e=4;
f=5;
g=6;
h=7;
selet=3'h0;
repeat(5)
begin
#100
selet=selet+1;
end
selet=0;
repeat(times1)
begin
#100
selet=selet+1;
a={$random}%16;
b={$random}%16;
c={$random}%16;
d={$random}%16;
e={$random}%16;
f={$random}%16;
g={$random}%16;
h={$random}%16;
end
#100 $stop;
end
mux_8 m0(a,b,c,d,e,f,g,h,selet,out);
endmodule
(3) 练习题5:设计一个带控制端的逻辑运算电路
主程序:
`define sqrR 4'd0
`define triR 4'd0
`define factR 4'd0
module sqr(a,reset,clk,sqr_out,tri_out,fact_out);
input[3:0] a;
input reset,clk;
output[7:0] sqr_out,tri_out,fact_out;
reg[7:0] sqr_out,tri_out,fact_out;
always @(posedge clk)
begin
if(!reset)
{sqr_out,tri_out,fact_out}={`sqrR,`triR,`factR};
else
begin
sqr_out=sqr_cal(a);
tri_out=tri_cal(a);
fact_out=fact_cal(a);
end
end
function[7:0] sqr_cal;
input[3:0] a;
begin
sqr_cal=a*a;
end
endfunction
function[7:0] tri_cal;
input[3:0] a;
begin
tri_cal=a*a*a;
end
endfunction
function[7:0] fact_cal;
input[3:0] a;
begin
if(a>5)fact_cal=0;
else
begin
case(a)
0:fact_cal=1;
1:fact_cal=1;
2:fact_cal=2;
3:fact_cal=6;
4:fact_cal=24;
5:fact_cal=120;
endcase
end
end
endfunction
endmodule
测试程序:
`timescale 1 ns/100 ps
`define clk_cycle 50
module sqrTEST;
reg[3:0] a,i;
reg reset,clk;
wire[7:0] sqr_out,tri_out,fact_out;
initial
begin
clk=0;
a=0;
reset=1;
#100 reset=0;
#100 reset=1;
for(i=0;i<=6;i=i+1)
begin
#200 a=i;
end
#100 $stop;
end
always #`clk_cycle clk=~clk;
sqr m(a,reset,clk,sqr_out,tri_out,fact_out);
endmodule
(4) 练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序
组合逻辑实现程序:
module bub(ai,bi,ci,di,ao,bo,co,do);
input[7:0] ai,bi,ci,di;
output[7:0] ao,bo,co,do;
reg[7:0] ao,bo,co,do;
reg[7:0] ar,br,cr,dr;
reg[3:0] n;
parameter so=4; //
always @(ai or bi or ci or di)
begin
{ar,br,cr,dr}={ai,bi,ci,di};
for(n=so;n>1;n=n-1) //
bb(ar,br,cr,dr,n);
{ao,bo,co,do}={ar,br,cr,dr};
end
task bb; //
inout[7:0] x1,x2,x3,x4;
input[3:0] n; //
reg[7:0] temp;
reg[3:0] s;
if(n>0)
for(s=1;s<n;s=s+1)
begin
case(s)
1:sort2(x1,x2);
2:sort2(x2,x3);
3:sort2(x3,x4);
endcase
end
endtask
task sort2;
inout[7:0] x,y;
reg[7:0] temp;
if(x>y)
begin
temp=x;
x=y;
y=temp;
end
endtask
endmodule
组合逻辑测试程序:
`timescale 1 ns/100 ps
module bubTEST;
reg[7:0] ai,bi,ci,di;
wire[7:0] ao,bo,co,do;
initial
begin
ai=0;bi=0;ci=0;di=0;
repeat(4)
begin
#100 ai={$random}%256;
bi={$random}%256;
ci={$random}%256;
di={$random}%256;
end
#100 $stop;
end
bub m0(ai,bi,ci,di,ao,bo,co,do);
endmodule
时序逻辑实现程序:
module bub_1(in,clk,ar,br,cr,dr,ao,bo,co,do);
input[7:0] in;
input clk;
output[7:0] ao,bo,co,do;
output[7:0] ar,br,cr,dr;
reg[7:0] ao,bo,co,do;
reg[7:0] ar,br,cr,dr;
reg[3:0] n,s,q;
parameter so=4;
initial
begin
n=0;
s=0;
q=0;
end
always @(posedge clk)
begin
if(n<=so)
begin
n=n+1;
ar<=in;
br<=ar;
cr<=br;
dr<=cr;
end
if(n==so+1)
begin
n<=so+2;
s<=so;
q<=1;
end
if(s>1)
begin
{ao,bo,co,do}<={ar,br,cr,dr};
if(q<s)
begin
case(q)
1:sort2(ar,br);
2:sort2(br,cr);
3:sort2(cr,dr);
endcase
q<=q+1;
end
else
begin
s<=s-1;
q<=1;
end
end
end
task sort2;
inout[7:0] x,y;
reg[7:0] temp;
if(x>y)
begin
temp=x;
x=y;
y=temp;
end
endtask
endmodule
时序逻辑测试程序:
`timescale 1 ns/100 ps
module bubTEST_1;
reg[7:0] in;
reg clk;
wire[7:0] ao,bo,co,do,ar,br,cr,dr;
initial
begin
clk=0;
in=0;
begin
repeat(4)
#100 in={$random}%256;
end
#100 $stop;
end
always #50 clk=~clk;
bub_1 m0(in,clk,ar,br,cr,dr,ao,bo,co,do);
endmodule
(5) 补充练习2:楼梯灯设计
主程序:
module final2(signal,reset,clk,light);
input[2:0] signal;
input reset,clk;
output[2:0] light;
reg[2:0] signal_reg,light_reg,light_test,signal_test;
reg[11:0] k0,k1,k2,k0a,k1a,k2a,k0b,k1b,k2b;
reg[1:0] state0,state1,state2;
reg[3:0] i0,i1,i2;
parameter light_off=2'b00,
light_on8=2'b01,
light_on12=2'b10;
initial
begin
k0=0;k1=0;k2=0;
k0a=0;k1a=0;k2a=0;
k0b=0;k1b=0;k2b=0;
i0=0;i1=0;i2=0;
light_reg=3'b000;
state0=light_off;
state1=light_off;
state2=light_off;
signal_reg=0;
signal_test=signal;
end
// //
always @(posedge clk)
begin
signal_test[0]<=signal[0];
if(signal_test[0]==signal[0])
begin
i0=i0+1;
end
else
i0=0;
if(i0>=5)
begin
signal_reg[0]=signal[0];
end
if(state0==light_off)
begin
k0=0;
k0a=0;
k0b=0;
end
else
k0=k0+1;
case(signal_reg[0])
1: if(!reset)
begin
state0=light_off;
end
else
begin
k0a=k0a+1;
if((k0a >= 79)&&(k0<=119))
state0=light_on12;
else
state0=light_on8;
end
0:if(!reset)
begin
state0=light_off;
end
else if(k0a==0)
state0=light_off;
endcase
case(state0)
light_off:light_reg[0]=0;
light_on8:
begin
light_reg[0]=1;
if(k0b==79)
state0=light_off;
else
k0b=k0b+1;
end
light_on12:
begin
light_reg[0]=1;
if(k0b==119)
state0=light_off;
else
k0b=k0b+1;
end
endcase
end
always @(posedge clk)
begin
signal_test[1]<=signal[1];
if(signal_test[1]==signal[1])
begin
i1=i1+1;
end
else
i1=0;
if(i1>=5)
begin
signal_reg[1]=signal[1];
end
if(state1==light_off)
begin
k1=0;
k1a=0;
k1b=0;
end
else
k1=k1+1;
case(signal_reg[1])
1: if(!reset)
begin
state1=light_off;
end
else
begin
k1a=k1a+1;
if((k1a >= 79)&&(k1<=119))
state1=light_on12;
else
state1=light_on8;
end
0:if(!reset)
begin
state1=light_off;
end
else if(k1a==0)
state1=light_off;
endcase
case(state1)
light_off:light_reg[1]=0;
light_on8:
begin
light_reg[1]=1;
if(k1b==79)
state1=light_off;
else
k1b=k1b+1;
end
light_on12:
begin
light_reg[1]=1;
if(k1b==119)
state1=light_off;
else
k1b=k1b+1;
end
endcase
end
// //
always @(posedge clk)
begin
signal_test[2]<=signal[2];
if(signal_test[2]==signal[2])
begin
i2=i2+1;
end
else
i2=0;
if(i2>=5)
begin
signal_reg[2]=signal[2];
end
if(state2==light_off)
begin
k2=0;
k2a=0;
k2b=0;
end
else
k2=k2+1;
case(signal_reg[2])
1: if(!reset)
begin
state2=light_off;
end
else
begin
k2a=k2a+1;
if((k2a >= 79)&&(k2<=119))
state2=light_on12;
else
state2=light_on8;
end
0:if(!reset)
begin
state2=light_off;
end
else if(k2a==0)
state2=light_off;
endcase
case(state2)
light_off:light_reg[2]=0;
light_on8:
begin
light_reg[2]=1;
if(k2b==79)
state2=light_off;
else
k2b=k2b+1;
end
light_on12:
begin
light_reg[2]=1;
if(k2b==119)
state2=light_off;
else
k2b=k2b+1;
end
endcase
casex(light_reg)
3'b000:light_test=000;
3'b001:light_test=001;
3'b01x:light_test=010;
3'b1xx:light_test=100;
endcase
end
assign light=light_test;
endmodule
测试程序:
`timescale 10ms/10ms
module final_TOP2;
reg[2:0] signal;
reg clk,reset;
wire[2:0] light;
initial
begin
clk=0;
reset=1;
#2 reset=0;
#10 reset=1;
#10 signal=3'b111;
#10 signal=3'b000;
#900 signal=3'b111;
#100 signal=3'b000;
#900 signal=3'b011;
#100 signal=3'b000;
#900 signal=3'b001;
#900 signal=3'b000;
#100 $stop;
end
always #5 clk=~clk;
final2 m(signal,reset,clk,light);
endmodule
成绩北京航空航天大学自动控制原理实验报告班级120xx8学号120xx191学生姓名黄钟胤自动控制与测试教学实验中心自动控制原理实…
电子电路实验报告二XXXXXX班XXX10021189实验二射极跟随器分析与设计实验电路在Multisim11中搭建如下电器元件实…
实验三差动放大器的分析与设计实验电路在Multisim11中搭建如下电器元件实验内容1请对该电路进行直流工作点分析进而判断管子的工…
实验一共射放大器分析与设计一、实验目的1、进一步了解Multisim的各项功能,熟练掌握其使用方法,为后续课程打好基础。2、通过使…
20xx20xx学年第二学期计算机控制实验报告班级学院高等工程姓名李柏学号20xx年6月12日实验1模拟式小功率随动系统的实验调试…
物理光学实验报告班级班实验一组合干涉仪一实验目的通过本实验观察干涉现象了解干涉原理学会干涉光路的搭构与调整通过干涉环的变化与被测量…
成绩北京航空航天大学自动控制原理实验报告班级120xx8学号120xx191学生姓名黄钟胤自动控制与测试教学实验中心自动控制原理实…
实验一陀螺仪关键参数测试与分析实验加速度计关键参数测试与分析实验二零一三年五月十二日1实验一陀螺仪关键参数测试与分析实验一实验目的…