Xử lý dấu phẩy động
4.4.1 Phép cộng và trừ
Các phép toán cộng và trừ trên các số phẩy động khó hơn nhiều so với các số nguyên. Giải thuật để cộng và trừ các số phẩy động được biểu diễn trong giản đồ sau:
Ví dụ sau đây sẽ miêu tả từng bước một sự hoạt động của khối cộng/ trừ hai số phẩy động.
Giả sử ta muốn cộng hai số phẩy động nhị phân 5 bit:
1001. . 1 24 × + 22 ×1.0010 ---
Bước 1: Lấy số mũ của số lớn hơn trừ đi số mũ của số nhỏ hơn. eL = 24, eS = 22 nên diff = 4 - 2 = 2
Bước 2: Dịch phần thập phân của số có số mũ nhỏ hơn sang bên phải diff bit. Lúc này, ta phải tách phần mũ ra mới có thể dịch được.
1.1001 000+ 0.0100 100 + 0.0100 100 ---
Bước 3: Sau khi dịch và đệm thêm bit, ta tiến hành cộng hai phần thập phân vào nhau.
1.1001 000+ 0.0100 100 + 0.0100 100 --- 1.1101 100 31 Toán hạng A = dấu A & e A & frac A
Toán hạngB = dấuB & eB & fracB
eA > eB ? eL = eA eS = eB fracL=fracA fracS=fracB eL = eB eS = eA fracL=fracB fracS=fracA diff = eL*eS
dịch phải fracS diff bit frac 0 = frac S +/- frac L e0 = eL Làm tròn frac0 Kiểm tra ngoại lệ
Báo hiệu ngoại lệ
Chuẩn hóa
Có
Không
Hình 4.3 Lưu đồ giải thuật phép cộng/trừ số phấy động
Bước 4: Sau khi cộng xong phần thập phân, ta tiến hành làm tròn đến số chẵn gần nhất. Ví dụ như số vừa được tính là 1.1101 100 sẽ được làm tròn thành 1.1110
Bước 5: Sau khi tính toán xong xuôi, ta ghép phần dấu và mũ vào phần thập phân vừa tính được rồi đẩy kết quả ra đầu ra. Như trong ví dụ này, kết quả sẽ là 24 ×1.1110
Bộ nhân trong khối xử lý phẩy động này sử dụng khả năng xử lý song song của FPGA để tiết kiệm xung nhịp đồng hồ. Nếu được sử dụng phương pháp xử lý nối tiếp để làm bộ nhân thì sẽ mất 32 xung nhịp trong khi thực hiện xử lý song song chỉ cần 5 nhịp. Tuy nhiên, bộ nhân xử lý song song sẽ tốn tài nguyên FPGA gấp 3 lần khối xử lý nối tiếp. Sau đây sẽ là lưu đồ giải thuật của bộ nhân dấu phấy động thực hiện trên FPGA.
Hình 4.4 Lưu đồ giải thuật phép nhân số phẩy động
Để có thể hiểu rõ hơn lưu đồ giải thuật trên, ta sẽ làm theo lưu đồ trên với một phép nhân hai số phẩy động nhị phân 5 bit:
1001. . 1 2100 × × 2110 ×1.0010 --- Toán hạngA = dấuA & eA & fracA Toán hạngB = dấuB & eB & fracB
Làm tròn frac 0 Kiểm tra ngoại lệ
Báo hiệu ngoại lệ
Chuẩn hóa Ra = dấu0 & e0 & frac0
Có
Không frac0 = fracA fracB
sign0 = signA xor signB
Bước1: Ở bước này, ta tiến hành tách riêng phần thập phân, số mũ, dấu của toán hạng đưa vào rồi nhân phần thập phân của hai số với nhau.
1.1001
× 1.0100
--- 1.11000010
Vậy ta có frac0 = 1.11000010. Cùng việc nhân phần thập phân vào nhau, ta cũng tiến hành tính số mũ: e0 = 2100+110-bias = 283
Bước 2: Sau khi đã tính được các kết quả trên, ta sẽ làm tròn phần thạp phân về số nguyên gần nhất: frac0 = 1.1100
Bước 3: Sau khi đã tính được đủ các thông số, ta ghép lại phần mũ và dấu sẽ được kết quả là: 283 × 1.1100
4.4.3 Phép chia
Phép chia trong khối xử lý phấy động này được thực hiện nối tiếp với giải thuật căn bản là phép trừ liên tục các số. Do phép chia không được dùng thường xuyên như phép nhân, nên nó được lập trình xử lý nối tiếp để tiết kiệm tài nguyên FPGA.
Để có thể hiểu rõ hơn các khối trong phép chia phẩy động ở lưu đồ trên, ta thử tiến hành phép chia từng bước một với hai số phẩy động nhị phân 5 bit:
0000. . 1 2110 ×
÷ 2100 ×0.0011
Bước 1: Đếm các số 0 ở phía trước phần thập phân của hai số cần tính. Ở trong ví dụ này ta dễ thấy zA = 0, zB = 3.
Bước 2: Sau khi đã tìm được zA và zB, ta tiến hành dịch trái phần thập phân của các số đó theo zA, zB sẽ được:
fracB = 00000 11000
Trong khi dịch các phần thập phân theo zA, zB ta cũng tiến hành tính số mũ của kết quả: e0 = 2110-100+bias-0+3 = 2140
Hình 4.5: Lưu đồ giải thuật phép chia số phẩy động
Bước 3: Sau khi đã có được các thông số fracA, fracB đã được dịch, ta tiến hành phép chia: 0000 , 100000 1000 , 000001 ÷ --- 1,0101
Toán hạngA = dấuA & eA & fracA Toán hạngB = dấuB & eB & fracB
Làm tròn frac 0 Kiểm tra ngoại lệ
Báo hiệu ngoại lệ Chuẩn hóa Ra = dấu 0 & e 0 & frac0 Có Không frac 0 = frac A / frac B
sign0 = signA xor signB
e0 = eA - eB + bias(127) – zA + zB Dịch trái frac
A z
A bit Dịch trái fracB zB bit Đếm các bit 0 ở đầu các
Bước 4: Sau khi các bước tính toán trên đã thực hiện xong xuôi, ta sẽ ghép các bit dấu, bit mũ và bit thập phân lại rồi đẩy kết quả ra đầu ra. Trong ví dụ này, kết quả sẽ là: 1,0101 × 2140