Chương 5. Thiết kế Block Design trên Vivado với giao thức AXI4
5.3.1. IP Microblaze giao tiếp với local memOry
Đối với IP Microbalze: phan mềm Vivado hỗ tro IP Microblaze dé khởi tạo giao diện có nhiệm vụ giao tiếp với IP Local Memory, IP Debug và IP Interrupt.
microblaze_0
microblaze_0_local_memory
|||+ INTERRUPT pune +I i (+)
-|||+ veBus h Le [PS
= MicroBlaze ue + ||_——IlF ss
M.AXILDP +}! LMB,
Reset ask si” ee
MicroBlaze
Hình 5-5. IP Microblaze giao tiếp với local memory
Khối IP Microblaze giao tiếp với Local memory như Hình 5.6 là một bộ nhớ BRAM được giao tiếp bởi bus LMB (Local Memory Bus) gồm 2 tín hiệu chính là:
¢ ILMB: Instruction interface, Local Memory Bus: giao tiếp lệnh theo chuẩn bus
LMB, chi dùng cho giao tiếp BRAM.
¢ DLMB: Data interface, Local Memory Bus: giao tiếp dữ liệu theo chuẩn bus
LMB, chi dùng cho giao tiếp BRAM.
5.3.2. IP AXI Uart Lite
axi_uartlite_O
“+ S_AXI
s_axi_aclk
UART +|||ˆ
| interrupt
s_axi_aresetn
AXI Uartlite
Hình 5-6. Khối IP Uart Lite
AXI Uart Lite — cho giao tiếp ánh xạ bộ nhớ thông lượng thấp. Và chỉ cho phép mỗi giá trị thực hiện trao đổi trong mỗi lần thực hiện. Dữ liệu có thé di chuyền đồng thời theo cả hai hướng giữa master và slave, và kích thước dữ liệu có thể khác nhau. Như hình trên giá trị nạp vào bus S_AXI, và xuất giá trị thong qua bus UART.
5.4. Kết qua thực thi trên FPGA
4Ð */
47 #include <stdio.h>
48 #include "platform.h”
49 #include "xil printf.h”
5ỉ #include "xi1 io.h"
51 #include "xparameters.h”
52° int main()
53 {
54 init_platform();
55 xil_printf("\nStart Testcasel\n");
56
57 //LOAD INST
58 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*0, @x00100093) ;
59 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*1, @x@0200113);
68 Xil_Out32(XPAR_RISCV_@ S89 _AXI BASEADDR + 4*2, @x@0308193) ;
61 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*3, @x@0408213) ;
62 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*4, @x@0510293) ;
63 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*5, @x@0520333);
64 Xil_Out32(XPAR_RISCV_@ _S@@_AXT_BASEADDR + 4*6, 0x40518383);
65 Xil_Out32(XPAR_RISCV_@ _S@@_AXI_BASEADDR + 4*7, @x0023F433) ;
66 Xil_Out32(XPAR_RISCV_@ S@@_AXI_BASEADDR + 4*8, @x@03264B3);
67 Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*9, @x@0918423);
68 Xil_Out32(XPAR_RISCV_@ _S@@_AXT_BASEADDR + 4*10, @x90408413);
69 Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*11, @x02440063);
79 Xil_Out32(XPAR_RISCV_@ _S@@_AXT_BASEADDR + 4*12, @x00030803);
71 Xil_Out32(XPAR_RISCV_@ SQ@_AXT_BASEADDR + 4*13, ỉx0901C883);
72 Xil_Out32(XPAR_RISCV_@ S@@_AXT_BASEADDR + 4*14, @x00019903);
73 Xil_Out32(XPAR_RISCV_@ S@@ AXI_BASEADDR + 4*15, @x90010983);
KLL_UUT32( APAK_KLSLV_@_300_AKL_BASEAUUK
Xil_Out32(XPAR_RISCV_@ S@@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR
Xil_Out32(XPAR_RISCV_@_SQ@_AXT_BASEADDR
Xi1 Out32(XPAR_RISCV 6 S88 AXT BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@ S@@_AXI_BASEADDR
Xil_Out32(XPAR_RISCV_@_SQ@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@0_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_SQ@_AXI_BASEADDR
Xil_Out32(XPAR_RISCV_@ S@@_AXI_BASEADDR
Xil_Out32(XPAR_RISCV_@ $@@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR
Xil_Out32(XPAR_RISCV_@_S@@_AXI_BASEADDR
4740, UXLA405/LF)ÿ
4°49, 0x2A968848);
4°50, Qx@@10A@A3); //x1 4*51, 0x0920A123); //x2 4*52, @x@@30A1A3); //x3 4*53, 0x0949A2A3); //x4 4*54, @x@@50A323); //x5 4*55, 0x0060A3A3); //x6 4*56, 0x0870A423); //x7 4*57, 0x0080A4A3); //x8 4*58, 0x0090A523); //x9 4*60, 0x09BÐA6A3); //x11 4*61, 0x99C0A723); //x12 4*63, 0x00E0A823); //x14 4*64, 0x00F0A8A3); //x15 4*65, 0x0140A923); //x20
Ta. an.
//DONE STNAL
Xi1_Out32(XPAR_RTSCV_6_S86_AXT_BASEADDR + 4*77, @x00000001) ;
//PRINT SINAL
Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*75, @x9@000001) ;
xil_printf(" ");
Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*76, @x90000013);
xil_printf("x2@ = %x\n", Xil_In32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*78)); Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*76, @x00000002) ;
xil_printf("x1 = %x\n", Xil_In32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*78)); Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*76, @x00000003);
xil_printf("x2 = %x\n", Xil_In32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*78)); Xil_Out32(XPAR_RISCV_@_S@@_AXT_BASEADDR + 4*76, @x00000004) ;
xil_printf("x3 = %x\n", Xi1 In32(XPAR RISCV_ỉ Sỉỉ_AXI BASEADDR + 4*78)); Xi1_Out32(XPAR_RTSCV_ỉ_S98_AXI_BASEADDR + 4*76, @x00000006);
xi1_printf("x4 = %x\n", Xil_In32(XPAR_RISCV_@_S@@_AXI_BASEADDR + 4*78));
Như hình trên, nhóm dùng ngôn ngữ C dé mô phỏng. Lệnh Xil_Out32 dùng dé nạp giá trị cho các thanh ghi slv_reg với địa chỉ tương ứng được đề cập ở thư viện
Xparameters.h.
Nhóm sử dụng tat cả 80 thanh ghi(slv_reg). Trong đó, 75 thanh ghi dùng để lưu giá trị của các Instruction, 5 thanh ghi còn lại dùng để điều khiển tín hiệu.
Như hình trên, nhóm sử dung 65 thanh ghi để ghi giá trị các Instruction dé nạp vào RISCV, thanh ghi 77 là tín hiệu bắt đầu để RISCV hoạt động.
Thanh ghi 75 dùng dé cho phép đọc các giá trị được lưu trong bộ nhớ đề xuất kết
quả.
Thanh ghi 75 là thanh ghi địa chỉ của bộ nhớ.
Thanh ghi 78 là thanh ghi chứa kết quả thực thi. Lệnh Xil_In32 dùng dé đọc giá trị
từ thanh ghi.
Nhóm kết nối kit với Baud Rate: 11520
wi Connect to serial port x
Basic Settings
Port: COM6 v
Baud Rate: 115200
> Advance Settings
Data Bits: 8 v
Stop Bits: — |1 _
Parity: None v
Flow Controk_|None = Timeout (sec):
Ce
Hình 5-8. Cấu hình kết nói với kit
xi0=4 x11=8 x19= 10 x20 = B x21 = CCCCC000. x24= 1
f10 = 42D4C000
f11 = 4125056E
f13 = 42B2C000 f11 = 41D1FFFF
#14 = 4388BC00 f12 = 42244666
f15 = C2B2C000 13 = 40DE0000
f16 = C388BC00 f14 = C13BFFFE
End Testcase1 End Testcase2
FFFFFFE
f10 = 40880000.
f11 = 41870000 if12 = 41ED8000 f13 = 42034000 f14 = C1E54000 End Testcase3
Hinh 5-9. Két qua nap kit
Kết quả thực thi khi thực hiện trên kit. Nhóm đã lấy các kết quả thực hiện như x1,
X2, x3,... tương ứng với các register trong REGE.
Tương tự fl, f2, f3 tương ứng với các registrer trong FPREGF.
Nhóm có dùng 1 script để kiểm tra độ chính xác của kết quả thực hiện được với kết quả thực tế nhóm đã chuẩn bị trước.
def compare files(filel_path, file2_path):
with open(filel_path, 'r') as filel:
linesl = filel.readlines()
with open(file2_path,“'n") as file2:
lines2 file2.readlines()
diff_lines = []
line_num = 1
for linel, line2 in zip(linesl, lines2):
if linel != line2:
diff_lines.append(f"Line {line_num}:")
diff_lines.append(f" File 1: {linel.strip()}")
diff_lines.append(f" File 2: {line2.strip()}")
diff_lines.append("")
line_num += 1
# Check for additional lines in file2 (if filel is shorter
if len(linesl) < len(lines2):
diff lines.append(f"Line {line num}:")
diff lines.append(f" File 1: <no line>")
diff lines.append (£" File 2: {line2.strip()}")
diff lines.append("")
line num += 1
# Check for additional lines in filel (if file2 is shorter)
if len(linesl) > len(lines2):
for linel in linesl[len(lines2):]:
diff lines.append(f"Line {line num}:")
diff lines.append(f" File 1: {linel.strip()}")
diff lines.append (£" File 2: <no line>")h
diff lines.append("")
line num += 1
return "\n".join(diff lines)
if name nT crete ——“E
filel_ path = "/content/outActual.txt"
file2 path = "/content/outKIT.txt"
result = compare files(filel path, file2 path)
print (result)
Chức năng của kịch bản kiểm thử trên là so sánh từng dòng của 2 đoạn text và xuất
ra các giá tri bi sai của 2 đoạn text trên. Nêu đúng hét sẽ không xuât gi cả.
Fa lai CS © if _ name == ” main ";
faa filel_path = “/content/outActual.txt"
Be sample_data file2 path = "/content/outKIT.txt”
R outActual.txt
R outkiT.txt result = compare_files(filel path, file2_path)
print(result)
Line 26:
File 1: f8 = 3E83C296 File 2: #8 = 3E83C297
Line 69:
File 1: f8 = BFECCCCD File 2: #8 = BFECCCCF
Line 61:
File 1: f9 = 488080980 File 2: f9 = 467FFFFF
Line 63:
File 1: f11 = 41D2eeee File 2: £11 = 41D1FFFF
Line 66:
File 1: f14 = C13C8888 File 2: #14 = C13BFFFE tis CAn trấnn 83 AIGR
Hình 5-10. Kết quả so sánh
Như hình ở trên kết quả thực thi trên KIT sé nam ở file2(outKIT.txt) và giá trị thực
tế sẽ năm ở file 1(outActual.txt).
Kết quả thực thi ở trên bị sai ở các đòng 26, 60, 61, 66 vi đó là các kết quả thuộc
nhóm lệnh floating point nên sẽ có các giá trị sai sd.
Ví dụ như ở Line 60:
Kết quả của File 1 là: BFECCCCD(-1.85000002384) Kết quả của File 2 là: BFECCCCF(-1.85000026226) Giá trị của các số thực sẽ không chênh lệch quá cao.
Các kịch bản mô phỏng sẽ được tải lên driver.
Link driver:
https://drive. google.com/drive/folders/laTZCoD-
z9u67gHel14ldqnyzEWrwrMK1?usp=sharing
Chương 6. Kết luận và hướng phát triển
6.1.
6.2.
6.3.
Kết luận Sau khi hoàn thành khoá luận, nhóm đã đạt được các kết quả như sau:
© Thiết kế đúng các chức năng của từng khối trong hệ thống RISCV.
© Mô phỏng được các lệnh RV64I và RV64F đã đề ra.
e_ Thiết kế được đường ống, giúp vi xử lý tăng tần số xử lý.
e Tích hợp thành công Cache và BPU vào hệ thống.
e Giải quyết xung đột trong đường ống.
e JP hoạt động ở tần số 115 MHz so với 100 MHz đã đề ra.
e Xây dựng được hệ thong SoC và thành công chạy trên Kit.
Ưu điểm và hạn chế của thiết kế
Ưu điểm của thiết kế:
e Tích hợp được bộ nhớ đệm (Cache) dé tăng tốc độ CPU trong van đề
truy xuất bộ nhớ e_ Tích hợp thành công khối BranchPrediction giúp CPU tốn ít chu kỳ hon
khi thực hiện các lệnh nhảy.
Nhược điểm của thiết kế:
e Chưa nạp thành công một vài lệnh trên kit
Hướng phát triển
Trong tương lai, dé cải tiến chất lượng, cũng như đối với sự phát triển thêm của khóa luận, nhóm xin đề xuất các ý kiến sau:
e Hoan thiện các lệnh còn lại của tập lệnh I. Mở rộng tập lệnh ngoài IF.
e Tăng tần số thiết kế. Nạp thành công tat cả các lệnh còn lại lên Kit.
e Tao thêm ngat cho hoạt động của các ngoại vi liên kết.
e Mô phỏng Imem và Dmem nằm ngoài vi xử lý dé thấy rõ tác dụng của
Cache khi nạp lên FPGA.
e Xây dựng hệ thống kiêm thử tự động cho thiết kế.