Monday, September 16, 2019

[Design][Thiết kế CPU 32 bit] [Bài 2] Tìm hiểu về tập lệnh assembly trong thiết kế CPU 32 bit

Tác giả: TrongTran
Ngày: 16/09/2019

Tài liệu tham khảo: www-inst.eecs.berkeley.edu/~cs61c/fa18/img/riscvcard.pdf và tài liệu học tập từ trường đại học Bách Khoa TP.HCM (Bộ môn Điện-Điện tử).

Đây là một bài nằm trong chuỗi bài hướng dẫn thiết kế 1 CPU RISC-V 32 bit.


Câu lệnh “ADD”

Cú pháp:                                   add rd, rs1, rs2

Với câu lệnh add bên trên CPU sẽ thực hiện 2 tác vụ đó là:


  • Reg[rd] = Reg[rs1] + Reg[rs2]
  • PC = PC + 4


Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 cộng với giá trị chứa trong thanh ghi rs2 và gán giá trị đó vào thanh ghi rd. Sau đó giá trị của PC = PC + 4.

Ví dụ:
Ta có thanh ghi R5 = 1 và R6 = 2.
Ta thực hiện câu lệnh

                           add r7, r5, r6

Sau khi thực hiện phép toán r7 sẽ chứa giá trị 1 + 2 = 3.

Vậy tại sao lại là PC = PC +4 mà không phải cộng 1 số nào khác. Đơn giản vì câu lệnh của ta sẽ có 32 bit (CPU 32 bit).
Mà trong memory thì mỗi đơn vị PC chứa 8 bit.

Chẳng hạn:
Ta có file IMEM như sau:

0001_0011 //PC
1000_1111 //PC+1
0101_1010 //PC+2
1111_0000 //PC+3
1010_1010 //PC+4

Vì câu lệnh của chúng ta có 32 bit nên ta cần ghép 4 dòng từ PC đến PC+3 để thành 1 câu lệnh 32 bit hoàn chỉnh. Sau khi thực hiện xong câu lệnh tại PC. Có phải câu lệnh tiếp theo chúng ta bắt đầu từ PC+4 không.

Câu lệnh “SUB”

Cú pháp:
                                   sub rd, rs1, rs2

Với câu lệnh sub bên trên CPU sẽ thực hiện 2 tác vụ đó là:

  • Reg[rd] = Reg[rs1] - Reg[rs2]
  • PC = PC + 4

Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 trừ cho giá trị chứa trong thanh ghi rs2 và gán kết quả vào thanh ghi rd. Sau đó tăng giá trị của PC = PC + 4 cho câu lệnh kế tiếp.

Ví dụ:
Ta có thanh ghi R5 = 6 và R6 = 2.
Ta thực hiện câu lệnh

                           sub r7, r5, r6


Sau khi thực hiện phép toán r7 sẽ chứa giá trị 6 - 2 = 4.

Ngoài ra ta còn có 1 số câu lệnh khác tương tự như:


  • and: and giá trị chứa trong hai thanh ghi rs1 và rs2 gán vào rd.
  • or: or giá trị chứa trong hai thanh ghi rs1 và rs2 gán vào rd.
  • xor: xor giá trị chứa trong hai thanh ghi rs1 và rs2 gán vào rd.
  • sll: câu lệnh shift left 
  • slt: Câu lệnh so sánh có dấu
  • sltu: Câu lệnh so sánh không dấu
  • srl: Câu lệnh shift right logical
  • sra: Câu lệnh shift right algorithm


Ở đây sẽ có nhiều bạn dễ nhầm lẫn giữa câu lệnh srl và sra , và giữa slt và sll. Để làm rõ sự khác biệt giữa srl và sra mình lấy ví dụ như sau: 

Mình có 1 số 8 bit A = 8’b11001010
Khi dùng lệnh srl shift right 2 đơn vị kết quả là 8’b00111010
Khi dùng lệnh sra shift right 2 đơn vị kết quả là 8’b11110010
Như vậy bit dấu được mở rộng trong câu lệnh sra. Còn câu lệnh srl thì mặc định mở rộng bit 0.
Nếu bit dấu là 0 thì khi shift right với 2 câu lệnh trên kết quả là như nhau.

Phân biệt 2 câu lệnh sll và slt.
Ý nghĩa của câu lệnh sll chỉ đơn giản là shift left giá trị chứa trong thanh ghi.
Mình lấy ví dụ:

rs1 = 8’b10001010 (Ở đây mình giả sử các thanh ghi chứa 8 bit data chứ không phải 32 bit cho bạn dễ nhìn thấy).
rs2 =8’b00000010 = 2.

                                   sll rd, rs1, rs2

Có nghĩa là shift left giá trị chứa trong thanh ghi rs1 đi 2 lần

Rd = 8’b10001010 << 2 = 8’b00101000

Nó đơn giản vậy thui.

Tương tự ta có câu lệnh slli

                                        sll rd, rs1, A

A là một số integer mình lấy ví dụ:

Rs1 = 8’b10001010 (Ở đây mình giả sử các thanh ghi chứa 8 bit data chứ không phải 32 bit cho bạn dễ nhìn thấy).
A  = 2.
Có nghĩa là shift giá trị chứa trong thanh ghi rs1 đi 2 lần
Rd = 8’b10001010 << 2 = 8’b00101000


Bây giờ chúng ta cùng tìm hiểu câu lệnh slt nhé:

Slt nghĩa là “set if less than” từ “s” đầu không phải là shift đâu nhé. 

                                       slt rd, rs1, rs2

Câu lệnh trên có nghĩa là nếu giá trị chứa trong thanh ghi rs1 nhỏ hơn giá trị chứa trong rs2 thì giá trị thanh ghi rd sẽ được set đến 1, Ngược lại là 0.
Mình lấy ví dụ:
Mình có x5 chứa giá trị 9, x6 chứa giá trị 10.

                                     slt x1, x5, x6

Sau khi thực hiện lệnh này vì 9 < 10, nên x1 sẽ được set = 1 (x1 chứa giá trị 1).
Câu lệnh slti: Câu lệnh này giống với câu lệnh slt nhưng thay rs2 bằng một số nguyên.
Mình lấy ví dụ:
Mình có x5 chứa giá trị 9

                                      slti x1, x5, 6


Vì 9 > 6 nên giá trị x1 sẽ bằng 0.


Câu lệnh “ADDI”

Cú pháp:
                                          addi  rd,rs1,A

Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 cộng với A (A là một số integer) và gán kết quả vào thanh ghi rd. Sau đó tăng giá trị của PC = PC + 4 cho câu lệnh kế tiếp.

Câu lệnh “SUBI”

Cú pháp:
                                     subi  rd,rs1,A 

Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 trừ cho A(A là một số integer)  và chứa giá trị kết quả trong thanh ghi rd. Sau đó tăng giá trị của PC = PC + 4 cho câu lệnh kế tiếp.
Vì trong câu lệnh giá trị A chỉ là 12 bit data. Vì vậy trước khi thực hiện cộng hoặc trừ số nhị phân ta phải mở rộng bit. Mở rộng bit có 2 dạng là mở rộng un-signed và signed.


Câu lệnh lw, lh, lb  (Load word, load halfword, load byte, load halfword unsigned và load byte un-signed)

Ngoài ra chúng ta còn có 1 số câu lệnh khác như slli, slti, sltui, srli, srai…v..v.

Cú pháp:
                                             lw rd, A(rs1)

Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 cộng với số A (Nếu là lệnh lw thì A nên là bội số của 4, nếu là lh thì A nên là bội số của 2 và lb thì A bất kì). Gọi kết quả là B = Reg{x2} + A. Ta tìm trong DMEM lấy giá trị tại địa chỉ B (Giá trị B chính là địa chỉ để ta truy vấn giá trị cần lấy) và gán vào thanh ghi rd.

Sự khác biệt giữa lw và lh và lb.

lw nghĩa là ta lấy 32 bit data (1 word) trong địa chỉ B và gán vào thanh ghi rd.
Trong khi lb là ta lấy 8 bit data (1 byte) trong địa chỉ B và mở rộng bit dấu thành 32 bit và gán vào thanh ghi rd.
Ở đây ta còn có lệnh lh nghĩa là load half word = 2 byte (Địa chỉ nên là bội số của 2).
Ngoài ra, ta còn có 1 số câu lệnh khác đó là:
lbu là “load unsigned byte” có nghĩa là ta mở rộng bit bằng cách thêm 0 vào 24 bit đầu MBS (không dấu) còn với LB thì ta mở rộng bit bằng bit dấu (Bit đầu tiên từ trái qua phải).
lhu là “load unsigned halfword” tương tự như trên.

Câu lệnh sw, sb, sh (Store word, store byte, Store halfword)

Cú pháp:
                                            sw rd, A(rs1)

Ý nghĩa của câu lệnh này là lấy giá trị chứa trong thanh ghi rs1 cộng với số A (Nếu là lệnh sw thì A nên là bội số của 4, sh thì A nên là bội số của 2, nếu là sb thì A bất kì). Gọi kết quả là B = Reg{x2} + A. Ta lấy giá trị chứa trong thanh ghi rd và lưu vào địa chỉ B (Giá trị B chính là địa chỉ để ta truy vấn giá trị cần lấy). Câu lệnh này ngược lại với câu lệnh lw.


Lệnh nhảy có điều kiện beq, bne, blt, bge, bltu, bgeu

Cú pháp:
                                          beq rs1, rs2, A

Câu lệnh này nhằm thay đổi câu lệnh được thực hiện tiếp theo bằng cách thay đổi giá trị của PC. Thông thường sau khi thực hiện 1 câu lệnh giá trị PC = PC + 4. Tuy nhiên, trong câu lệnh trên nếu giá trị trong thanh ghi rs1 bằng giá trị trong thanh ghi rs2 thì PC = PC + A (Không phải + 4 và giá trị của A nên là bội của 4 chẳng hạn 8, 16, 20 …v..v).
Tương tự ta có câu lệnh: bne nghĩa là nhảy khi rs1 # rs2 (Không bằng).

blt: nhảy khi rs1 < rs2 (nhỏ hơn).
bge: Nhảy khi rs1 >= rs2.
bltu: Tương tự như lệnh blt nhưng so sánh các số không dấu.
bgeu: Tương tự như lệnh bge nhưng so sánh các số không dấu.


Câu lệnh jal (Jump and load), jalr (Jump and load register)

Cú pháp:
                                           jal rd, A

Câu lệnh này thực hiện 2 chức năng đó là 
Gán giá trị PC+4 vào thanh ghi rd (Load)
Gán giá trị PC = PC + A (Jump).
Đây là câu lệnh nhảy không điều kiện.
Như vậy câu lệnh tiếp theo ta thực hiện sẽ là PC = PC + A. Tuy nhiên, ta vẫn có thể biết được vị trí mà PC sẽ chạy tiếp theo nếu không jump nhờ vào giá trị PC + 4 được gán vào thanh ghi rd.

                                  jalr rd, rs1, A

Câu lệnh này thực hiện 2 chức năng đó là 
Gán giá trị PC+4 vào thanh ghi rd.
Gán giá trị PC = Reg{rs} + A.
Câu lệnh này khác câu lệnh jal ở trên chỗ giá trị của PC được gán bằng Reg{rs} + A thay vì bằng PC + A.

Câu lệnh "LUI"

Cú pháp:
                                      lui rd, K

K: Là 1 số.

Ý nghĩa của câu lệnh này là nhằm gán một số rất lớn vào một thanh ghi.
Thông thường để gán 1 số vào 1 thanh ghi ta sẽ dùng lệnh add.
Chẳng hạn:

                                         addi r4, r4, 0
                                         addi r5, r4, A

Trong đó A (tối đa 12 bit và được mở rộng bit dấu) là số muốn add vào thanh ghi r5.
Tuy nhiên trong câu lệnh add, giá trị của A bị giới hạn bởi 12 bit data. Nghĩa là tối đa chúng ta gán vào thanh ghi r5 là 000007FE (Các số 0 đầu là do mở rộng bit).
Với câu lệnh lui ta có thể gán số lớn nhất là FFFFF000 vào thanh ghi r5.
Cú pháp:

                                            lui x10, K

K là số có tối đa 20 bit data. Với câu lệnh lui, K được mở rộng về bên phải 12 bit data nữa là 32 bit.
Mình lấy ví dụ:

                                         lui x10, 0xFE06F

Nghĩa là mình sẽ gán được 1 số có giá trị 0xFE06F000 vào thanh ghi x10, Trong đó 12 bit cuối (0x000) bên phải được tự động mở rộng.

Ngoài ra ta còn có câu lệnh li (gán có dấu)

                                  li x10, 0xFF04FEEF

Câu lệnh AUIPC

Cú pháp:
                                    auipc rd, A

Câu lệnh này có nghĩa là gán giá trị PC=PC+A (A được mở rộng 12 bit bên phải giống câu lệnh lui bên trên) và lưu giá trị đó vào thanh ghi rd.

Câu lệnh này dùng giống như các câu lệnh nhảy tuy nhiên ta dùng với một đoạn code dài mà các câu lệnh nhảy khác như jal, beq,..v… không đáp ứng được.


1 comment:

  1. Where to Bet on Sports To Bet On Sports In Illinois
    The best sports bet types and bonuses 바카라 사이트 available wooricasinos.info in Illinois. The most common 토토사이트 sports betting options available. Bet $20, Win 바카라 사이트 $150, Win $100 or

    ReplyDelete

Cách tính BW và latency trong 1 hệ thống SoC sử dụng chuẩn giao tiếp AXI protocol

Tác giả:  TrongTran Ngày:  31/12/2019 Nếu bạn nào đang làm về verification cho system performance (ST) thì bài này sẽ bổ ích cho bạn. Ngày ...