本节练习主要用组合逻辑电路实现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顶层文件
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
数码管译码电路:
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码显示.
part2.v
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 行波进位加法器
part3.v
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
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
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
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
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