北航数字EDA基础实验报告(4~6)

数字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基础实验报告46

北航数字EDA基础实验报告46

数字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基础实验报告46

数字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基础实验报告46

北航数字EDA基础实验报告46

数字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基础实验报告46

北航数字EDA基础实验报告46

数字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

相关推荐