本節練習主要用組合邏輯電路實作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碼顯示.
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SMxkTO1YTZ4MGOkBTOwMmYyYzXzUDMxYTM5IzLcZDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
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 行波進位加法器
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
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