【原创】DE2 实验练习解答—lab 2:数字和显示(digital Logic)(DE2)

本节练习主要用组合逻辑电路实现2进制到10进制数字的转换以及BCD码的加法。

 

Part I 2进制数字的显示

 

在HEX3到HEX0上显示SW15-0的值。SW15-12,SW11-8,SW7-4,SW3-0分别对应于HEX3,HEX2,HEX1,HEX0.在数码管上显示0-9,忽略开关表示的数值1010-1111.

本练习的目的是手工推导数码管显示的逻辑,要求只用赋值语句和布尔表达式实现。

part1.v

 part1顶层文件

1 //part1 display 0-9 on the 7-segment displays
2  module part1(HEX3,HEX2,HEX1,HEX0,SW);
3 input [15:0]SW;
4 output [0:6]HEX3,HEX2,HEX1,HEX0;
5
6 btd H3(SW[15:12],HEX3);
7 btd H2(SW[11:8],HEX2);
8 btd H1(SW[7:4],HEX1);
9 btd H0(SW[3:0],HEX0);
10
11  endmodule

 

数码管译码电路:

1 //binary-to-decimal
2  module btd(s,seg);
3 input [3:0]s;
4 output [0:6]seg;
5
6 assign seg[6]=~s[3]&~s[2]&~s[1]|s[2]&s[1]&s[0];
7 assign seg[5]=~s[3]&~s[2]&s[0]|~s[2]&s[1]|s[1]&s[0];
8 assign seg[4]=s[0]|s[2]&~s[1];
9 assign seg[3]=~s[3]&~s[2]&~s[1]&s[0]|
10 s[2]&~s[1]&~s[0]|
11 s[2]&s[1]&s[0];
12 assign seg[2]=~s[2]&s[1]&~s[0];
13 assign seg[1]=s[2]&~s[1]&s[0]|s[2]&s[1]&~s[0];
14 assign seg[0]=s[2]&~s[1]&~s[0]|~s[3]&~s[2]&~s[1]&s[0];
15
16  endmodule

 

 

 

 

Part II 2进制值转换为10进制

 

将4位二进制输入V=v3v2v1v0转换成2位十进制数D=d1d0,在HEX1和HEX0上分别显示d1和d0.输出值与输入值的对应关系如表1.图1给出了电路的部分设计。比较器用来检测V>9.电路A用来将>9的输入转换成对应的个位的BCD码.电路B用来将1位二进制的输入转换为对应的BCD码显示.

 

001

002

 

 

part2.v

 

1 //part 2
2  module part2(V,D1,D0);
3 input [3:0]V;
4 output [0:6]D1,D0;
5 wire z; //comparator output
6  wire [2:0]a; //circuit A output
7  wire [3:0]m; //multiplexer output
8  
9 comparator C(V,z);
10 circuita A(V[2:0],a);
11 mux_4b_2to1 M(V,{1'b0,a},z,m);
12   circuitb B(z,D1);
13 btd D(m,D0);
14
15  endmodule
16
17  //circuit B
18  module circuitb(z,seg);
19 input z;
20 output [0:6]seg;
21
22 assign seg[6]=1;
23 assign seg[5]=z;
24 assign seg[4]=z;
25 assign seg[3]=z;
26 assign seg[2]=0;
27 assign seg[1]=0;
28 assign seg[0]=z;
29
30  endmodule
31
32
33  //4-bit 2-to-1 multiplexer
34  module mux_4b_2to1(x,y,s,m);
35 input [3:0]x;
36 input [3:0]y;
37 input s;
38 output [3:0]m;
39
40 mux_2to1 u3(x[3],y[3],s,m[3]);
41 mux_2to1 u2(x[2],y[2],s,m[2]);
42 mux_2to1 u1(x[1],y[1],s,m[1]);
43 mux_2to1 u0(x[0],y[0],s,m[0]);
44
45  endmodule
46  //2to1 multiplexer
47  module mux_2to1(a,b,s,m);
48 input a,b,s;
49 output m;
50
51 assign m=s?b:a;
52
53  endmodule
54
55
56  //circuit A
57  module circuita(v,a);
58 input [2:0]v;
59 output [2:0]a;
60
61 assign a[2]=v[2]&v[1];
62 assign a[1]=v[2]&~v[1];
63 assign a[0]=(v[1]&v[0])|(v[2]&v[0]);
64
65  endmodule

 

 

Part III 行波进位加法器

 

003

 

part3.v

 

1 //4-bit ripple-carry adder circuit
2  module part3(SW,LEDR,LEDG);
3 input [8:0]SW;
4 output [8:0]LEDR;
5 output [4:0]LEDG;
6 wire [3:0]a,b;
7 wire cin;
8 wire [3:0]s;
9 wire cout;
10 wire [3:1]c;
11
12 assign LEDR=SW;
13 assign cin=SW[8];
14 assign a=SW[7:4];
15 assign b=SW[3:0];
16 assign LEDG[4]=cout;
17 assign LEDG[3:0]=s;
18
19 fadder(cin,a[0],b[0],s[0],c[1]);
20 fadder(c[1],a[1],b[1],s[1],c[2]);
21 fadder(c[2],a[2],b[2],s[2],c[3]);
22 fadder(c[3],a[3],b[3],s[3],cout);
23
24  endmodule
25
26  //full adder
27  module fadder(ci,a,b,s,co);
28 input ci,a,b;
29 output s,co;
30
31 assign s=ci^a^b,
32 co=(a^b)?ci:b;
33
34  endmodule

 

 

Part IV 1位BCD加法器

 

注意处理和的最大值S1S0=9+9+1=19。

part4.v

 

1 //part IV:BCD adder
2
3  //circuit A
4  module circuit_A(s,ao);
5 input [3:0]s;
6 output [3:0]ao;
7
8 assign ao[3]=~s[3]&~s[2]&s[1],
9 ao[2]=(~s[3]&~s[2]&~s[1])|(s[3]&s[2]&s[1]),
10 ao[1]=(~s[3]&~s[2]&~s[1])|(s[3]&s[2]&~s[1]),
11 ao[0]=(~s[3]&~s[2]&s[0])|(s[3]&s[2]&s[0])|
12 (~s[2]&s[1]&s[0]);
13
14  endmodule
15
16  //4-bit 2-to-1 multiplexer
17  module mux2to1_4b(x,y,s,m);
18 input [3:0]x,y;
19 input s;
20 output [3:0]m;
21
22 mux_2to1 u3(x[3],y[3],s,m[3]);
23 mux_2to1 u2(x[2],y[2],s,m[2]);
24 mux_2to1 u1(x[1],y[1],s,m[1]);
25 mux_2to1 u0(x[0],y[0],s,m[0]);
26
27  endmodule
28  //2to1 multiplexer
29  module mux_2to1(a,b,s,m);
30 input a,b,s;
31 output m;
32
33 assign m=s?b:a;
34
35  endmodule
36
37  //circuit B
38  module circuit_B(z,seg);
39 input z;
40 output [0:6]seg;
41
42 assign seg[6]=1;
43 assign seg[5]=z;
44 assign seg[4]=z;
45 assign seg[3]=z;
46 assign seg[2]=0;
47 assign seg[1]=0;
48 assign seg[0]=z;
49
50  endmodule
51
52  //7-segment decoder
53  module btd(s,seg);
54 input [3:0]s;
55 output [0:6]seg;
56
57 assign seg[6]=~s[3]&~s[2]&~s[1]|s[2]&s[1]&s[0];
58 assign seg[5]=~s[3]&~s[2]&s[0]|~s[2]&s[1]|s[1]&s[0];
59 assign seg[4]=s[0]|s[2]&~s[1];
60 assign seg[3]=~s[3]&~s[2]&~s[1]&s[0]|
61 s[2]&~s[1]&~s[0]|
62 s[2]&s[1]&s[0];
63 assign seg[2]=~s[2]&s[1]&~s[0];
64 assign seg[1]=s[2]&~s[1]&s[0]|s[2]&s[1]&~s[0];
65 assign seg[0]=s[2]&~s[1]&~s[0]|~s[3]&~s[2]&~s[1]&s[0];
66
67  endmodule
68
69  //4-bit full adder
70  module fa_4b(a,b,s,cin,cout);
71 input [3:0]a,b;
72 input cin;
73 output [3:0]s;
74 output cout;
75
76 wire [3:1]c;
77
78 fadder fao(cin,a[0],b[0],s[0],c[1]);
79 fadder fa1(c[1],a[1],b[1],s[1],c[2]);
80 fadder fa2(c[2],a[2],b[2],s[2],c[3]);
81 fadder fa3(c[3],a[3],b[3],s[3],cout);
82
83  endmodule
84
85  //full adder
86  module fadder(ci,a,b,s,co);
87 input ci,a,b;
88 output s,co;
89
90 assign s=ci^a^b,
91 co=(a^b)?ci:b;
92
93  endmodule
94
95  //circuit comparator
96  module comparator(v,z);
97 input [3:0]v;
98 output z;
99
100 assign z=(v[3]&v[2])|(v[3]&v[1]);
101
102  endmodule
103
104  //part 4 top file
105  module part4(SW,LEDR,LEDG,LEDG8,HEX6,HEX4,HEX1,HEX0);
106 input [8:0]SW; //Cin,A,B
107  output [8:0]LEDR;
108 output [4:0]LEDG;
109 output [0:6]HEX6,HEX4,HEX1,HEX0;
110 output LEDG8;
111
112 wire [3:0]sum; //sum
113  wire co; //cout
114  wire [3:0]ao; //circuit_A output
115  wire [3:0]m; //mux2to1_4b output
116  wire z; //comparator output
117 wire bi; //circuit_B input
118 wire va,vb; //A,B comparator output
119 assign LEDR=SW,
120 LEDG[4]=co,
121 LEDG[3:0]=sum,
122 LEDG8=va|vb;
123 assign bi=co|z;
124
125 fa_4b u0(SW[7:4],SW[3:0],sum,SW[8],co);
126 circuit_A u1(sum,ao);
127 comparator u7(sum,z);
128 mux2to1_4b u2(sum,ao,bi,m);
129 btd u3(m,HEX0);
130 circuit_B u4(bi,HEX1);
131 btd u5(SW[7:4],HEX6);
132 btd u6(SW[3:0],HEX4);
133 comparator u8(SW[7:4],va),
134 u9(SW[3:0],vb);
135
136
137
138 endmodule
139

 

 

Part V 2位BCD加法器

 

part5.v

 

1 /*...The ADDER CIRUIT....*/
2 //A Full Adder Circuit
3 module fulladder(C,A,B,S,O);
4 input C,A,B;
5 output S,O;
6
7 //C = CarryIn, A & B = Inputs, S = Sum, O = Carryout
8 assign S = C^(A^B);
9 assign O = (~(A^B)&B)|((A^B)&C);
10 endmodule
11
12 //4 Bit, Full Adder Circuit
13 module fulladder_4bit(C,A,B,S,O);
14 input C;
15 input [3:0]A,B;
16 output O;
17 output [3:0]S;
18 wire [3:0]cwire;
19
20 //C=CarryIn, A&B = Inputs, S = Sumb, O = CarryOut, CWIRE= Carry wire between adders
21 fulladder N0(C,A[0],B[0],S[0],cwire[0]);
22 fulladder N1(cwire[0],A[1],B[1],S[1],cwire[1]);
23 fulladder N2(cwire[1],A[2],B[2],S[2],cwire[2]);
24 fulladder N3(cwire[2],A[3],B[3],S[3],cwire[3]);
25
26 //BCD Carry
27 assign O = cwire[3]|(S[3]&S[2])|(S[3]&S[1]);
28 endmodule
29
30 //BCD Adder: Sum Finder
31 module bcdAdder(C,A,B,S,O);
32 input C;
33 input [3:0]A,B;
34 output [3:0]S;
35 output O;
36 wire [3:0]cwire;
37 wire [3:0]preSum;
38
39 fulladder_4bit MidAd1(C,A,B,preSum,O);
40
41 assign cwire[0] =0;
42 assign cwire[1] = O;
43 assign cwire[2] = O;
44 assign cwire[3] =0;
45
46
47 fulladder_4bit MidAd2(0,cwire,preSum,S);
48
49 endmodule
50
51 //top_level file
52 module part5(SW,HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,
53 HEX0);
54 input [16:0]SW;
55 output [0:6]HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,
56 HEX0;
57
58 wire [3:0]s0,s1;
59 wire co0,co1;
60
61 btd ua1(SW[15:12],HEX7);
62 btd ua0(SW[11:8],HEX6);
63 btd ub1(SW[7:4],HEX5);
64 btd ub0(SW[3:0],HEX4);
65
66 bcdAdder u0(SW[16],SW[11:8],SW[3:0],s0,co0);
67 bcdAdder u1(co0,SW[15:12],SW[7:4],s1,co1);
68 circuit_B us2(co1,HEX2);
69 btd us1(s1,HEX1);
70 btd us0(s0,HEX0);
71
72 endmodule

 设计思想

  参考 University of Sulaimani College of Engineering Electrical Engineering Department --Advanced Electronic Lab-fourth Year 2010-2011, prepared by:Mr. Arazs.Ameen.

 

 

代码

 1 module part5(SW,HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,HEX0);
 2     input [15:0] SW;
 3     output [0:6] HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,HEX0;
 4     
 5     wire [3:0] a1,a0,b1,b0;
 6     wire k0,s2;
 7     wire [3:0] s1,s0;
 8     
 9     assign a1=SW[15:12];
10     assign a0=SW[11:8];
11     assign b1=SW[7:4];
12     assign b0=SW[3:0];
13     
14     bcd_adder u0(a0,b0,1'b0,k0,s0);
15     bcd_adder u1(a1,b1,k0,s2,s1);
16     
17     circuit_B u3(s2,HEX2);
18     btd u4(s1,HEX1);
19     btd u5(s0,HEX0);
20     btd u6(a1,HEX7);
21     btd u7(a0,HEX6);
22     btd u8(b1,HEX5);
23     btd u9(b0,HEX4);
24     
25 endmodule     
module bcd_adder(a,b,cin,k,s);
    input [3:0] a,b;
    input cin;
    output [3:0] s;    //bcd_adder sum
    output k;        //bcd_adder cout
    
    wire [3:0] sum;
    wire co;
    wire [3:0] ao;
    wire [3:0] m;
    wire z;
    wire bi;
    
    assign bi=co|z;
    
    fa_4b u0(a,b,sum,cin,co);
    circuit_A u1(sum,ao);
    comparator u7(sum,z);
    mux2to1_4b u2(sum,ao,bi,m);
    
    assign k=bi;
    assign s=m;
    
endmodule 

ok,至此,解法更完善。

Part VI 另种实现2位BCD加法器的方法

 

用if-else结构实现,抽象描述,让编译器去实现具体电路。

part6.v

 

1 //1-digit bcd_adder
2 module bcdadder(Ci,A,B,S,Co);
3 input Ci;
4 input [3:0]A,B;
5 outputreg [3:0]S;
6 outputreg Co;
7
8 reg [3:0]z;
9 reg [4:0]t;
10
11 always @(Ci,A,B)
12 begin
13 t=A+B+Ci;
14 if(t>9)
15 begin
16 z=4'd10;
17 Co=1'b1;
18 end
19 else
20 begin
21 z=0;
22 Co=0;
23 end
24 S=t-z;
25 end
26 endmodule
27
28 //top_level file
29 module bcdadder_2(SW,HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,
30 HEX0);
31 input [16:0]SW;
32 output [0:6]HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,
33 HEX0;
34
35 wire [3:0]s0,s1;
36 wire co0,co1;
37
38 btd ua1(SW[15:12],HEX7);
39 btd ua0(SW[11:8],HEX6);
40 btd ub1(SW[7:4],HEX5);
41 btd ub0(SW[3:0],HEX4);
42
43 bcdadder u0(SW[16],SW[11:8],SW[3:0],s0,co0);
44 bcdadder u1(co0,SW[15:12],SW[7:4],s1,co1);
45 circuit_B us2(co1,HEX2);
46 btd us1(s1,HEX1);
47 btd us0(s0,HEX0);
48
49 endmodule

 

 解法2:完全照搬伪码

 1 //2-digit bcd_adder
 2 module part6(SW,HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,HEX0);
 3     input [15:0] SW;
 4     output [0:6] HEX7,HEX6,HEX5,HEX4,HEX2,HEX1,HEX0;
 5     
 6     wire [3:0] A1,A0,B1,B0;
 7     wire [4:0] T1,T0;
 8     wire [3:0] S1,S0;
 9     wire S2;
10     reg [3:0] Z1,Z0;
11     reg c1,c2;
12     
13     assign T0=A0+B0;
14     assign T1=A1+B1+c1;
15     assign S0=T0-Z0;
16     assign S1=T1-Z1;
17     assign S2=c2;
18     
19     always @(T1,T0)
20     begin
21         if(T0>9)
22             begin
23                 Z0=4'd10;
24                 c1=1'b1;
25             end
26         else
27             begin
28                 Z0=4'd0;
29                 c1=1'b0;
30             end
31         if(T1>9)
32             begin
33                 Z1=4'd10;
34                 c2=1'b1;
35             end
36         else
37             begin
38                 Z1=4'd0;
39                 c2=1'b0;
40             end
41     end
42 
43     assign A1=SW[15:12];
44     assign A0=SW[11:8];
45     assign B1=SW[7:4];
46     assign B0=SW[3:0];
47     
48     circuit_B u3(S2,HEX2);
49     btd u4(S1,HEX1);
50     btd u5(S0,HEX0);
51     btd u6(A1,HEX7);
52     btd u7(A0,HEX6);
53     btd u8(B1,HEX5);
54     btd u9(B0,HEX4);
55     
56 endmodule     

 

 

Part VII 6位二进制数转换为2位十进制数的电路

 

方法:

用两个寄存器,一个6bit,一个8bit,分别存bin码和有待实现的bcd码。接下来,逐位将BIN的最高位移入BCD的最低位。同时,将BCD的16位寄存器按每四位划成一块,我们称之为个十百千好了。但记住,个,十,百,千都有4个bit位。

1.将bin[5](bin是bin[5:0])移入bcd[0]。这样,bin[5]就变成了原来的bin[4],bin[0]=0。

2.分别检查个十百千里存的数是不是大于等于5(按二进制换十进制那样换算),如果是,加3。

3.重做1,2。直到全部移进去。

原理:bin和bcd的表示方法的差别,就在于10用bin表示为1010,用bcd表示成10000。但左移一位就是乘2,这个是没问题的。因此,如果不做2的操作,就等于不停的把个位数乘2加上新的个位数,这样还是原来的数。做了2之后,就等于把原来的1010变成10000,因为1010在bcd码里是不可能出现的,因此要把10变成bin下面的16。而5=10/2,3=(16-10)/2,也等于(18-12)/2……等等等等。

参考:

BCD and Add3 Converter by Dr. John S. Loomis:
            http://www.johnloomis.org/ece314/notes/devices/binary_to_BCD/bin_to_bcd.html

part7.v

 

1 //6-bit binary to 2-digit BCD
2 module b2b(a,ones,tens);
3 input [5:0]a;
4 output [3:0]ones,tens;
5
6 wire [3:0]c1,c2,c3;
7 wire [3:0]d1,d2,d3;
8
9 assign d1={1'b0,a[5:3]};
10 assign d2={c1[2:0],a[2]};
11 assign d3={c2[2:0],a[1]};
12 add3 m1(d1,c1);
13 add3 m2(d2,c2);
14 add3 m3(d3,c3);
15 assign ones={c3[2:0],a[0]};
16 assign tens={1'b0,c1[3],c2[3],c3[3]};
17
18 endmodule
19
20 //add3.v
21 module add3(in,out);
22 input [3:0] in;
23 output [3:0] out;
24 reg [3:0] out;
25
26 always @ (in)
27 case (in)
28 4'b0000: out <= 4'b0000;
29 4'b0001: out <= 4'b0001;
30 4'b0010: out <= 4'b0010;
31 4'b0011: out <= 4'b0011;
32 4'b0100: out <= 4'b0100;
33 4'b0101: out <= 4'b1000;
34 4'b0110: out <= 4'b1001;
35 4'b0111: out <= 4'b1010;
36 4'b1000: out <= 4'b1011;
37 4'b1001: out <= 4'b1100;
38 default: out <=4'b0000;
39 endcase
40 endmodule
41
42 //top_level file
43 module binary2bcd(SW,HEX1,HEX0);
44 input [5:0]SW;
45 output [0:6]HEX1,HEX0;
46
47 wire [3:0]ones,tens;
48
49 b2b u3(SW,ones,tens);
50 btd u1(ones,HEX0);
51 btd u2(tens,HEX1);
52
53 endmodule
 

解法2:

 1 //bcd conversion
 2 module bcd(
 3     input [5:0] binary,
 4     output reg [3:0] tens,
 5     output reg [3:0] ones
 6     );
 7     
 8     integer i;
 9     always @(binary)
10     begin
11         //set 10's,and 1's to 0
12         tens=4'd0;
13         ones=4'd0;
14         
15         for(i=5;i>=0;i=i-1)
16         begin
17             //add 3 to clumns >=5
18             if(tens>=5)
19                 tens=tens+3;
20             if(ones>=5)
21                 ones=ones+3;
22             
23             //shift left one
24             tens=tens<<1;
25             tens[0]=ones[3];
26             ones=ones<<1;
27             ones[0]=binary[i];
28         end
29     end
30 
31 endmodule     

 

posted on 2010-04-23 17:22  yf.x  阅读(6379)  评论(31编辑  收藏  举报

导航