FPGA系統設計實務 L2
FPGA系統設計實務 L2
Shortcut method:
Addition & Subtraction: Cumbersome simply compute bit wise complement
Must compare magnitudes to determine sign of result 0111 1000
Twos Complement Numbers Addition and Subtraction of Numbers
Sign and Magnitude
-1 +0
-2 1111 0000 +1 4 0100 -4 1100
-3
1110 0001 Result sign bit is the
+2 + same as the operands'
like 1's comp 1101 0010 +3 0011 + (-3) 1011
-4 sign.
except shifted 1100 0011 +3 0 100 = + 4
one position 7 0111 -7 1111
clockwise -5 1011 0100 +4 1 100 = - 4
1010 0101
-6 +5 -
1001 0110
-7 1000 0111 +6
When signs differ, 4 0100 -4 1100
-8 +7 operation is subtract,
sign of result depends -3 1011 +3 0011
Only one representation for 0 on sign of number with
the larger magnitude 1 0001 -1 1001
One more negative number than positive number
Twos complement = bitwise complement + 1 = ones complement + 1
module ADD8(a,b,carryin,sum,carryout);
A
input [7:0] a, b; /* add these bits */ A
B
B
input carryin; /* carry in*/ S
CI CO
CI
output [7:0] sum; /* result */ A
B
output carryout;
wire [7:0] carry; /* transfers the carry between bits */
… arriving @N CI CO
signal @N+2
fulladd a7(a[7],b[7],carry[6],sum[7],carry[7]); @0 A
assign carryout= carry[7]; @0 B @1 two gate delays
endmodule to compute CO
Carry Lookahead Circuits Carry Lookahead Circuits
Carry Lookahead Logic
module CADD4(A, B, cin, S, cout,ov); assign S[0]=P[0]^cin; module ADD8(A,B,cin,S,cout,ov);
Carry Generate Gi = Ai Bi must generate carry when A = B = 1 input[7:0] A,B;
assign S[1]=P[1]^C[0];
Carry Propagate Pi = Ai + Bi Ai Bi carry in will equal carry out here input [3:0] A, B; input cin;
assign S[2]=P[2]^C[1]; output[7:0] S;
input cin; assign S[3]=P[3]^C[2];
Reexpress the carry logic as follows: output cout;
output [3:0] S;
Sum and Carry can be reexpressed wire c,ov0;
output cout,ov; assign C[0]=G[0]|(P[0]& cin);
in terms of generate/propagate: C0 = G0 + P0 Cin
wire [3:0] G, P; assign C[1]=G[1]|…………… CADD4 u0(A[3:0],B[3:0],cin,S[3:0],c,ov0);
Si = Ai Bi Ci-1 = Pi Ci-1 C1 = G1 + P1 C0 = G1 + P1 G0 + P1 P0 Cin wire [3:0] C; assign C[2]=G[2]|………..; CADD4 u1(A[7:4],B[7:4],c,S[7:4],cout,ov);
Ci = Ai Bi + Ai Ci-1 + Bi Ci-1 C2 = G2 + P2 C1 = G2 + P2 G1 + P2 P1 G0 + P2 P1 P0 Cin assign C[3]=G[3]|…………..;
= Ai Bi + Ci-1 (Ai + Bi) C3 = G3 + P3 C2 = G3 + P3 G2 + P3 P2 G1 + P3 P2 P1 G0 + P3 P2 P1 P0 Cin assign G=A&B; endmodule
= Ai Bi + Ci-1 (Ai Bi) //assign P=A|B; assign cout=C[3];
assign P=A^B; assign ov=C[3]^C[2];
= Gi + Ci-1 Pi
Each of the carry equations can be implemented in a two-level logic endmodule
network.
module MUX_4to1(Dout,D0,D1,D2,D3,sel);
Multiplexer module MUX_4to1 (Dout,D0,D1,D2,D3,sel,e);
input [1:0] D0,D1,D2,D3;
input [1:0] D0,D1,D2,D3; input [1:0] sel;
input [1:0] sel; output [1:0] Dout;
• Also called data selectors. Input e;
output [1:0] Dout; reg [1:0] Dout;
• Basic function: select one of its 2 data wire [1:0] D;
input lines and place the corresponding always@(*)
assign D=(sel[1])?((sel[0])?D3:D2): begin
information onto a single output line. ((sel[0])?D1:D0);
//assign Dout= D & {e,e}; case(sel)
• 𝑛 input bits needed to specify which assign Dout=(e)?D:2’d0; 2'b00: Dout <= D0;
input line is to be selected. endmodule 2'b01: Dout <= D1;
2'b10: Dout <= D2;
• Place binary code for a desired 2'b11: Dout <= D3;
endcase
data input line onto its 𝑛 select input
lines. end
endmodule
Carry Select Adder
Redundant hardware to make carry calculation go faster ADDERs
B
C8 B[7:4] A[7:4] B[3:0] A[3:0] 8
4-Bit Adder 0 Adder 8 A
4 4 4 4
[7:4] Low
cout c0 cin ~
CADD4 CADD4 8
C4 ov 8
C8 1 4 ADD8 op 1 0
4-Bit Adder Adder 4
[7:4] High 8
S[7:4] S[3:0]
1 0 1 0 1 0 1 0
ADD8
4? C4 4-Bit Adder C0
9d 7d c1 5d c0
2:1 Mux [3:0] c0 8
0 cin cout ov
ADD8 ADD8 ADD8 ADD8
C8 S7 S6 S5 S4 S3 S2 S1 S0 cout
11d Subtractor/Adder
ADD8 1
ADD8 ADD8
Compute the high order sums in parallel
one addition assumes carry in = 0 Carry Select Adder
the other assumes carry in = 1
4 4 ADD8 4 4 4 BCDADD2 4
cout S0[3:0] S[7:4] S[3:0] cout S0[3:0] S[7:4] S[3:0]
4 4
4 4
+6 +6
4 A = a3a2a1a0 c0 = a0 4 A = a3a2a1a0 c0 = a0
1 0 c1= ~ a1 1 0 c1= ~ a1
4
6 = 0110 + c2= ~ (a1 ^ a2) 8
6 = 0110 + c2= ~ (a1 ^ a2)
c3= (a1 | a2) ^ a3 c3= (a1 | a2) ^ a3
S[3:0] cout c3c2c1c0 S[3:0] cout c3c2c1c0
cout= (a1 | a2) & a3 cout= (a1 | a2) & a3
Combinational Multiplier
BtoBCD架構圖 BCD_ADD2 是8bit BCD加法器
Basic Concept
由兩個4bit BCD加法器串接
Adjust BB0(A[3:0],S,c1); multiplicand 1101 (13)
assign S1={3'b000,c1,S}; product of 2 4-bit numbers
multiplier * 1011 (11) is an 8-bit number
BCDADD2 BB1(S1,8'h16,1'b0,_S2,c2);
assign S2=(A[4])? _S2:S1; 1101
1101
BCDADD2 BB2(S2,8'h32,1'b0,_S3,c3);
assign S3=(A[5])? _S3:S2; Partial products 0000
1101
BCDADD2 BB3(S3,8'h64,1'b0,_S4,c4);
assign S4_10=(A[6])? _S4:S3;
10001111 (143)
assign S4_2 = (A[6])?{3'd0,c4}:4'd0;
BCDADD2 BB4(S4_10,8'h28,1'b0,_S5,c5);
BCDADD1 BB5(S4_2,4'h1,c5,_S51,c51);
assign S5=(A[7])?_S5:S4_10;
assign S51=(A[7])?_S51:S4_2;
Combinational Multiplier
module CCMul4(A,B,M);
module CCMul8(A,B,M);
input[7:0] A,B;
Decoder & Encoder (Binary)
input[3:0] A,B; output[15:0] M;
output[7:0] M; module DEC2to4(A, en, Y);
wire[7:0] m0,m1,m2,m3;
wire[3:0] m0,m1,m2,m3; input[1:0] A;
wire[15:0] sa, sb;
wire[7:0] sa,sb; Input en;
wire c0,c1,c2;
wire c0,c1,c2; output[3:0] Y;
reg [3:0] _Y;
CCMul4 u0(A[3:0],B[3:0],m0);
assign m0=(B[0])?A:4'd0; always @(A)
CCMul4 u1(A[7:4],B[3:0],m1);
assign m1=(B[1])?A:4'd0; 2 to 4 line binary decoder case(A)
CCMul4 u2(A[3:0],B[7:4],m2);
assign m2=(B[2])?A:4'd0; 2’b00: _Y <= 4’b0001;
CCMul4 u3(A[7:4],B[7:4],m3);
assign m3=(B[3])?A:4'd0; 2’b01: _Y <= 4’b0010;
Binary Encoder 2’b10: _Y <= 4’b0100;
//CSADD16 u4({8’d0,m0},{m3,8’d0},1’b0,sa,c0);
ADD8 u0({4'd0,m0},{3'd0,m1,1'b0},1'b0,sa,c0); default: _Y <= 4’b1000;
assign sa = {m3,m0};
ADD8 u1({2'd0,m2,2'd0},{1'b0,m3,3'd0},1'b0,sb,c0); endcase
CSADD16 u5({4'd0,m1,4'd0},{4'd0,m2,4'd0},1'b0,sb,c1);
ADD8 u2(sa,sb,1'b0,M,c2); assign Y= {en,en,en,en} & _Y;
CSADD16 u6(sa,sb,1'b0,M,c2);
endmodule
endmodule endmodule
4 to 16 line Decoder
module _7segEnc(A,_7seg);
Priority Encoder 7-Segment LED Encoder input[3:0] A;
output[6:0] _7seg;
reg [6:0] _7seg;
always@(A)
4 to 2 Priority Encoder
case(A)
4'h0:_7seg<=7'b1000000;
4'h1:_7seg<=7'b1111001;
8 to 3 Priority Encoder 4'h2:_7seg<=7'b0100100;
4'h3:_7seg<=7'b0110000;
4'h4:_7seg<=7'b0011001;
4'h5:_7seg<=7'b0010010;
4'h6:_7seg<=7'b0000010;
4'h7:_7seg<=7'b1011000;
4'h8:_7seg<=7'b0000000;
4'h9:_7seg<=7'b0010000;
4'hA:_7seg<=7'b0001000;
4'hB:_7seg<=7'b0000011;
A = D3 + D1D2′ 4'hC:_7seg<=7'b1000110;
B= D2 + D3 4'hD:_7seg<=7'b0100001;
V = D0 + D1 + D2 + D3 4'hE:_7seg<=7'b0000110;
4'hF:_7seg<=7'b0001110;
Z= ~V
endcase
endmodule
Glitching example Glitching example behavior
• Gate network: • NOR gate produces 0 output at beginning and end:
• beginning: bottom input is 1;
• end: NAND output is 1;
• Difference in delay between application of primary inputs and
generation of new NAND output causes glitch.
F l o a t i n g Po i n t – I E E E 7 5 4
union Float{
float v;
struct {
unsigned F:23;
unsigned E:8;
F unsigned S:1;
};
unsigned long d;
};