无02 季涛2010012107
一多路选择器
实验目的
掌握组合逻辑基本设计方法;掌握多路选择器的基本原理。
设计方案
如图为二选一多路选择器的基本结构,根据真值表推出逻辑表达式为y=~s&a|s&b。
卡诺图如下图所示:
s/AB | 00 | 01 | 11 | 10 |
0 | 1 | 1 | ||
1 | 1 | 1 |
由卡诺图上可以看出,当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语句的使用。下载本文