视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
verilog组合逻辑实验报告
2025-09-25 21:22:35 责编:小OO
文档
组合逻辑实验报告

无02 季涛2010012107

一多路选择器

实验目的

掌握组合逻辑基本设计方法;掌握多路选择器的基本原理。

设计方案

如图为二选一多路选择器的基本结构,根据真值表推出逻辑表达式为y=~s&a|s&b。

卡诺图如下图所示:

s/AB00011110
011
111
冒险分析:根据两级网络的冒险检测和消除理论我们得知,如果初始输入值和最终输入值能够被同一个本原蕴含想覆盖就不会出现毛刺,当输入变化跨越了多个本原蕴含项就会产生毛刺。

由卡诺图上可以看出,当AB=11,从s=0到s=1状态跳变时,这个过程没有包含在上面的逻辑表示式中,因此电路会产生冒险。

消除冒险的根本策略是添加冗余的本原蕴涵项。在这道题里,只要在逻辑表达式中加上a&b这一项即可。当然我们这里只考虑了单个输入发生变化的问题,因为在实际应用中,输入是按一定顺序变化的,即使有多个输入发生变化也是如此。

还有一种方案就是利用采样脉冲消除冒险。在这里就不多说了。

在此基础上可以设计出四选一的多路选择器,也就是实例化两个二选一多路选择器,然后再对这两个选择器的输出进行一次二选一。

代码

二选一多路选择器:

module mux_2_1(a,b,s,y,leda,ledb,leds);

    input a,b,s;

    output y,leda,ledb,leds;

    wire s1,a1,a2;

    buf b1(leda,a);

    buf b2(ledb,b);

    buf b3(leds,s);    

    not not1(s1,s);

    and and1(a1,s1,a);

    and and2(a2,s,b);

    or or1(y,a1,a2); 

endmodule

管脚约束:

NET "a" LOC = T10;

NET "b" LOC = T9;

NET "s" LOC = V9;

NET "y" LOC = T11;

NET "leda" LOC = U16;

NET "ledb" LOC = V16;

NET "leds" LOC = U15;

四选一多路选择器:

module mux_4_1(a,b,c,d,s1,s2,y,leda,ledb,ledc,ledd,leds1,leds2

    );

  input a,b,c,d,s1,s2;

  output y,leda,ledb,ledc,ledd,leds1,leds2;

  wire ledy1,ledy2;

  wire y1,y2;

  mux_2_1 m1(a,b,s1,y1,leda,ledb,leds1);

  mux_2_1 m2(c,d,s1,y2,ledc,ledd,leds1);  

  mux_2_1 m3(y1,y2,s2,y,ledy1,ledy2,leds2);

endmodule

管脚约束:

NET "a" LOC = T10;

NET "b" LOC = T9;

NET "c" LOC = V9;

NET "d" LOC = M8;

NET "s1" LOC = N8;

NET "s2" LOC = U8;

NET "y" LOC = T11;

NET "leda" LOC = U16;

NET "ledb" LOC = V16;

NET "ledc" LOC = U15;

NET "ledd" LOC = v15;

NET "leds1" LOC = M11;

NET "leds2" LOC = N11;

仿真结果

上图为四选一多路选择器的modelsim仿真结果。符合实验要求。

综合和硬件调试情况

调试结果符合预期,没有问题

二译码器

实验目的

掌握组合逻辑设计方法;掌握译码器设计原理。

设计方案

三八译码器如上图所示,真值表如下:

由真值表很容易得出逻辑表达式。分别用门级和行为级来实现。

上图为数码管七段译码基本结构,直接由真值表进行行为级的描述。

代码

三八译码器行为级描述:

module dec3to8men(a,d);

input [2:0]a;

output [7:0]d;

assign d[0]=~a[2]&~a[1]&~a[0];

assign d[1]=~a[2]&~a[1]&a[0];

assign d[2]=~a[2]&a[1]&~a[0];

assign d[3]=~a[2]&a[1]&a[0];

assign d[4]=a[2]&~a[1]&~a[0];

assign d[5]=a[2]&~a[1]&a[0];

assign d[6]=a[2]&a[1]&~a[0];

assign d[7]=a[2]&a[1]&a[0];

endmodule

三八译码器门级描述:

module dec3to8men(a,d);

input [2:0]a;

output [7:0]d;

wire[2:0]f;

wire

not not1(f[0],a[0]);

not not2(f[1],a[1]);

not not3(f[2],a[2]);

and and1(d[0],f[2],f[1],f[0]);

and and2(d[1],f[2],f[1],a[0]);

and and3(d[2],f[2],a[1],f[0]);

and and4(d[3],f[2],a[1],a[0]);

and and5(d[4],a[2],f[1],f[0]);

and and6(d[5],a[2],f[1],a[0]);

and and7(d[6],a[2],a[1],f[0]);

and and8(d[7],a[2],a[1],a[0]);

endmodule

三八译码器管脚约束:

NET"a[0]"LOC="T10";

NET"a[1]"LOC="T9";

NET"a[2]"LOC="V9";

NET"d[0]"LOC="U16";

NET"d[1]"LOC="V16";

NET"d[2]"LOC="U15";

NET"d[3]"LOC="v15";

NET"d[4]"LOC="M11";

NET"d[5]"LOC="N11";

NET"d[6]"LOC="R11";

NET"d[7]"LOC="T11";

七段译码器:

module decoder7(x,a,b,c,d,e,f,g);

  input [3:0]x;

  output reg a,b,c,d,e,f,g;

  always @(*)

    case(x)

      4'b0000 : begin a=0;b=0;c=0;d=0;e=0;f=0;g=1;end

      4'b0001 : begin a=1;b=0;c=0;d=1;e=1;f=1;g=1;end

      4'b0010 : begin a=0;b=0;c=1;d=0;e=0;f=1;g=0;end

      4'b0011 : begin a=0;b=0;c=0;d=0;e=1;f=1;g=0;end

      4'b0100 : begin a=1;b=0;c=0;d=1;e=1;f=0;g=0;end

      4'b0101 : begin a=0;b=1;c=0;d=0;e=1;f=0;g=0;end

      4'b0110 : begin a=0;b=1;c=0;d=0;e=0;f=0;g=0;end

      4'b0111 : begin a=0;b=0;c=0;d=1;e=1;f=1;g=1;end

      4'b1000 : begin a=0;b=0;c=0;d=0;e=0;f=0;g=0;end

      4'b1001 : begin a=0;b=0;c=0;d=0;e=1;f=0;g=0;end

      4'b1010 : begin a=0;b=0;c=0;d=1;e=0;f=0;g=0;end

      4'b1011 : begin a=1;b=1;c=0;d=0;e=0;f=0;g=0;end

      4'b1100 : begin a=0;b=1;c=1;d=0;e=0;f=0;g=1;end

      4'b1101 : begin a=1;b=0;c=0;d=0;e=0;f=1;g=0;end

      4'b1110 : begin a=0;b=1;c=1;d=0;e=0;f=0;g=0;end

      4'b1111 : begin a=0;b=1;c=1;d=1;e=0;f=0;g=0;end

      default : begin a=0;b=0;c=0;d=0;e=0;f=0;g=0;end

    endcase

  endmodule

管脚约束:

NET"x[0]"LOC="T10";

NET"x[1]"LOC="T9";

NET"x[2]"LOC="V9";

NET"x[3]"LOC="M8";

NET"a"LOC="T17";

NET"b"LOC="T18";

NET"c"LOC="U17";

NET"d"LOC="U18";

NET"e"LOC="M14";

NET"f"LOC="N14";

NET"g"LOC="L14";

仿真结果

三八译码器仿真结果如上图所示。

七段译码器的仿真结果如图所示。

综合和硬件调试情况

七段译码器没有设置使能信号,因此四位全都显示。其他没有问题。

三加法器

实验目的

掌握运算组合逻辑的设计方法;加法器的设计原理;逐次进位加法器和超前进位加法器。

设计方案

一位全加器的框图如图所示

由此可以设计出一位全加器的门级电路,在此基础上分别设计四位逐次进位和四位超前进位全加器。

逐次进位的框图如下图;

超前进位的框图如下图

我们定义gi=ai&bi,pi=ai^bi。于是有

通过迭代就可以提前计算出进位信号。

在此基础上,通过两个四位超前进位加法器可以设计出一个八位加法器;通过补码的运算把减法转化为加法,因此也设计出了四位减法器。

代码

一位全加器:

`timescale 1ns / 1ps

module fulad1bit(x,y,cin,sum,cout

    );

input x,y,cin;

output sum,cout;

wire xy,an1,an2;

xor xor1(sum,x,y,cin);

xor xor2(xy,x,y);

and and1(an1,xy,cin);

and and2(an2,x,y);

or or1(cout,an1,an2);

endmodule

四位逐次进位:

`timescale 1ns / 1ps

module ripple(a,b,cin,s,cout

    );

     input [3:0]a,b;

     output [3:0]s;

     input cin;

     output cout;

     wire cout0,cout1,cout2;

     fulad1bit f1(a[0],b[0],cin,s[0],cout0);

     fulad1bit f2(a[1],b[1],cout0,s[1],cout1);

     fulad1bit f3(a[2],b[2],cout1,s[2],cout2);

     fulad1bit f4(a[3],b[3],cout2,s[3],cout);

endmodule

四位超前进位:

`timescale 1ns / 1ps

module look_carry(a,b,cin,s,cout

    );

input [3:0]a,b;

output [3:0]s;

input cin;

output cout;

wire [3:0]g,p;

wire [4:0]ci;

wire pc0,pc1,pc2,pc3;

//assign g[0]=a[0]&b[0];

and and1(g[0],a[0],b[0]);

//assign p[0]=a[0]^b[0];

xor xor1(p[0],a[0],b[0]);

//assign g[1]=a[1]&b[1];

and and2(g[1],a[1],b[1]);

//assign p[1]=a[1]^b[1];

xor xor2(p[1],a[1],b[1]);

//assign g[2]=a[2]&b[2];

and and3(g[2],a[2],b[2]);

//assign p[2]=a[2]^b[2];

xor xor3(p[2],a[2],b[2]);

//assign g[3]=a[3]&b[3];

and and4(g[3],a[3],b[3]);

//assign p[3]=a[3]^b[3];

xor xor4(p[3],a[3],b[3]);

//assign ci[0]=cin;

buf buf1(ci[0],cin);

//assign ci[1]=g[0]+p[0]*ci[0];

and and5(pc0,p[0],ci[0]);

or or1(ci[1],g[0],pc0);

//assign ci[2]=g[1]+p[1]*ci[1];

and and6(pc1,p[1],ci[1]);

or or2(ci[2],g[1],pc1);

//assign ci[3]=g[2]+p[2]*ci[2];

and and7(pc2,p[2],ci[2]);

or or3(ci[3],g[2],pc2);

//assign ci[4]=g[3]+p[3]*ci[3];

and and8(pc3,p[3],ci[3]);

or or4(ci[4],g[3],pc3);

fulad1bit f1(a[0],b[0],ci[0],s[0],cout0);

fulad1bit f2(a[1],b[1],ci[1],s[1],cout1);

fulad1bit f3(a[2],b[2],ci[2],s[2],cout2);

fulad1bit f4(a[3],b[3],ci[3],s[3],cout);

endmodule

八位加法器:

module carry8_bit(a,b,cin,s,cout);

  

input [7:0]a,b;

output [7:0]s;

input cin;

output cout;

wire cout1;

look_carry l1(a[3:0],b[3:0],cin,s[3:0],cout1);

look_carry l2(a[7:4],b[7:4],cout1,s[7:4],cout);

endmodule

四位减法器:

`timescale 1ns / 1ps

module sub4_bit(a,b,cin,s,cout);

     input [3:0]a,b;

     output [3:0]s;

     wire [3:0]m;

     input cin;

     output cout;

     wire [3:0]s1;

     wire cout1;

     

     not not1(m[0],b[0]);

     not not2(m[1],b[1]);

     not not3(m[2],b[2]);

     not not4(m[3],b[3]);

  

  look_carry l1(a,m,cin,s1,cout1);

  buf buf1(s[0],s1[0]);

  buf buf2(s[1],s1[1]);

  buf buf3(s[2],s1[2]);

  buf buf4(s[3],s1[3]);

  buf buf5(cout,cout1);

endmodule

管脚约束:

NET"a[0]"LOC="T5";

NET"a[1]"LOC="V8";

NET"a[2]"LOC="U8";

NET"a[3]"LOC="N8";

NET"b[0]"LOC="M8";

NET"b[1]"LOC="V9";

NET"b[2]"LOC="T9";

NET"b[3]"LOC="T10";

NET"s[0]"LOC="V15";

NET"s[1]"LOC="U15";

NET"s[2]"LOC="V16";

NET"s[3]"LOC="U16";

NET"cout"LOC="T11";

NET"cin"LOC="C9";

仿真结果

逐次进位的仿真结果如下图所示:

超前进位:

八位加法器:

减法器:

综合和硬件调试情况

符合预期,没有什么问题。

思考题:

1我在实验中采用了(1)式,虽然这两个都可以具体综合实现,但仔细考虑发现,使用迭代浪费的资源较多,综合后的面积可能比后者要大,所以最好还是采用后者。

2十六位加法器,最直观的想法就是由之前设计的两个八位加法器级联,还有一种可以通过十六个一位全加器通过超前进位的方法组成。综合速率和逻辑资源来看,还是用八位的级联比较好。

3减法的基本设计思想就是化减法为加法,因为wire型量在综合中是无符号的,所以我们之前设计的加法器都是无符号型的。根据数字电路课上的知识我们知道减法可以通过补码运算进行,也就是说两个数a,b相减,可以通过先求b的补码,然后与a相加即可。补码是通过原码取反后加1得到。在我设计的加法器中,进位信号cin就是起到了加1的作用,而进位输出起到了是一个正负标志的作用,不亮表示正数,亮灯表示负数,此时显示的是补码。

实验总结

第一次实验主要熟悉了组合逻辑的实现方法和掌握了ISE软件综合以及实验平台的运用。在实验的过程中对verilog语言也有了更多的认识。

比如一些最基本的概念:

1什么是门级实现,什么是行为级实现;

2for语句只能在always块里运用;

3alwanys块需要被赋值的变量必须是reg型的,其他为wire型的;

4默认的数据是十进制的;

5模块之间的调用只能通过实例化,中间变量设为wire型的

6assign语句的使用。下载本文

显示全文
专题