Tải bản đầy đủ (.doc) (43 trang)

Thiết kế bộ nhớ đệm cho bộ xử lí RISCV

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.7 MB, 43 trang )

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ - VIỄN THƠNG

BÁO CÁO MƠN HỌC
KĨ THUẬT MÁY TÍNH
Đề tài:

THIẾT KẾ BỘ NHỚ ĐỆM CHO
BỘ XỬ LÍ RISC-V

Giảng viên hướng dẫn:

TẠ THỊ KIM HUỆ

Hà nội,20/6/2021
1


LỜI NÓI ĐẦU
Cùng với sự phát triền của xã hội ,lĩnh vực Cơng nghệ máy tính đã vươn lên
chiếm vị thế ngày càng cao trong tất cả các lĩnh vực kinh tế,xa hội,cũng như trong đời
sống. Cơng nghệ máy tính bây giờ khơng chỉ được hiểu trong chiếc máy tính mà nó cịn
đi sâu vào trong các mặt đời sống xa hội,thông qua cá hệ nhúng …Một thành phần quan
trọng của máy tính là các bộ xử lí trung tâm (CPU).Có rất nhiều cơng sức được đầu tư
vào việc chế tạo các CPU nhằm tạo ra các máy tính đáp ứng yêu cầu ngày càng cao của
con người. Với sự phát triền nhanh chóng của cơng nghệ slicon và chi phí giảm của mạch
tích hợp,bộ xử lí RÍC đang gia tăng sử dụng rộng rãi trong mọi lĩnh vực. RISC là một
phần mở rộng của các nguyên tắc kiến trúc máy tính với tập lệnh đơn giản hóa.Thiết kế
đơn giản cung cấp hiệu năng vượt trội là lý tưởng để sử dụng.Một số ứng dung điển hình
bao gồm: xứ lí dữ liệu thương mại,các ứng dụng tính tốn chun sâu khoa học và kỹ
thuật,kiểm soát thời gian thực.


Để thiết kế một CPU với đầy đủ chức năng cần một công cụ đủ mạnh. Từ đó dẫn
đến sự ra đời của các ngôn ngữ mô tả phần cứng như VHDL,Verilog và systemverilog…
Ngôn ngữ mô tả phần cứng systemverirlog được sử dụng trong báo cáo này.Từ ngôn
ngữu systemverilog các nhà thiết kế phần cứng có tể thiết kế ra những thiết bị phần cứng
như PU ,bộ vi điều khiển…một cách nhanh chóng và cũng như thực hiện mô phỏng kiểm
tra khả năng hoạt động của thiết bị trước khi đưa vào sản xuất,nhờ vậy có thể giảm bớt
thời gian ,chi phí sản xuất

Danh sách các từ viết tắt
2


CPU…………….. Central Processing Unit
RISC-V…………. Reduced Instruction Set Computer - Five
SRAM.…………. Static Random Access Memory
FRAM.…………. Ferroelectric Random Access Memory
AMAT.…………. Average Memory Access Time
RTL….…………. Register Transfer Level
WRU….…………Way Replacement Unit
FSM….………….Finite State Machine
MCU….…………Microcontroller Unit
IoT...….…………Internet of Things
FPU...….…………Internet of Things
PULP...….……….Parallel Ultra Low Power
LSU.....….……….Load Store Unit
ALU...….………. Arithmetic Logic Unit
MAC...….………. Multiply–ACcumulate operation
SIMD...….……… Single Instruction Multiple Data
DMA...….….…… Direct Memory Access


Danh sách hình vẽ
Hình 1: Định dạng lệnh của RISC-V............................................................................................................................ 8
Hình 2: Sơ đồ khối của CPU RI5CY........................................................................................................................... 12

3


Hình 3: kiến trúc pipe-line của CPU RI5CY............................................................................................................... 14
Hình 4: Minh họa giao thức truy cập bộ nhớ (cơ bản)............................................................................................. 16
Hình 5: Minh họa giao thức truy cập bộ nhớ (Back-to-back)................................................................................... 16
Hình 6: Minh họa giao thức truy cập bộ nhớ (đáp ứng chậm).................................................................................16
Hình 7: Sơ đồ khối của vi điều khiển Pulpino.......................................................................................................... 17
Hình 8: Bản đồ truy cập bộ nhớ của vi điều khiển Pulpino...................................................................................... 18
Hình 9: Mơ hình bộ vi xử lý với 3 cấp bộ nhớ đệm.................................................................................................. 19
Hình 10: Vi kiến trúc mới được đề xuất cho Pulpino............................................................................................... 27
Hình 11: Kiến trúc thiết kế của bộ nhớ đệm lệnh.................................................................................................... 28
Hình 12: Sơ đồ khối tổng quát của khối cache controller........................................................................................ 29
Hình 13: Khối Hit/miss judgement.......................................................................................................................... 30
Hình 14: Khối WRU hiện thực bằng LFSR 8 bit......................................................................................................... 31
Hình 15: Khối CTRL FSM.......................................................................................................................................... 31
Hình 16: Khối Performance stat.............................................................................................................................. 33
Hình 17: Khối AXI Double Buffer............................................................................................................................. 33
Hình 18: Bộ nhớ SRAM single port.......................................................................................................................... 34
Hình 19: Cổng input/output của cache top module................................................................................................. 35
Hình 20: Cổng input/output của cache controller................................................................................................... 36
Hình 21: Verdi schematic của top cache module..................................................................................................... 37
Hình 22: Kiến trúc mơi trường mơ phỏng của Pulpino............................................................................................ 38
Hình 23: Các bước chạy của mơi trường mơ phỏng Pulpino.................................................................................... 40
Hình 24: Debug trực quan bằng Verdi..................................................................................................................... 41


4


Danh sách bảng
Table 1: Bảng các tập lệnh cơ sở và mở rộng của RISC-V........................................................................................... 7
Table 2: Phân loại các nhóm lệnh của tập lệnh RV32I................................................................................................ 8
Table 3: Những thanh ghi điều khiển HW Loop....................................................................................................... 11
Table 4: Bảng các input/output của bộ phát lệnh.................................................................................................... 15
Table 5: Bảng so sánh FRAM với các bộ nhớ khác................................................................................................... 24
Table 6: Bảng kết quả đo tỉ lệ cache miss của bộ nhớ đệm lệnh..............................................................................42

5


Mục lục
LỜI NÓI ĐẦU............................................................................................................................................................. 2
Danh sách các từ viết tắt........................................................................................................................................... 2
Danh sách hình vẽ..................................................................................................................................................... 3
Danh sách bảng......................................................................................................................................................... 5
Chương 1. Cơ sở lý thuyết......................................................................................................................................... 7
1.1 Sơ lược về kiến trúc tập lệnh RISC-V................................................................................................................ 7
1.1.1 Tổng quát................................................................................................................................................. 7
1.1.2 Kiến trúc tập lệnh cơ sở............................................................................................................................ 8
1.1.3 Kiến trúc tập lệnh mở rộng....................................................................................................................... 9
1.2 Vi xử lý RI5CY................................................................................................................................................ 10
1.2.1 Giới thiệu vi xử lý RI5CY.......................................................................................................................... 10
2.2.2 Kiến trúc tập lệnh mở rộng..................................................................................................................... 11
1.2.3 Vi kiến trúc............................................................................................................................................. 12
1.3 Sơ lược về vi điều khiển Pulpino.................................................................................................................... 17
1.3.1 Giới thiệu............................................................................................................................................... 17

1.3.3 Bản đồ truy cập bộ nhớ.......................................................................................................................... 18
1.4 Bộ nhớ đệm lệnh........................................................................................................................................... 18
1.4.1 Giới thiệu............................................................................................................................................... 18
1.4.2 Kiến trúc của bộ nhớ lệnh....................................................................................................................... 19
1.5 Sử dụng systemverilog để thiết kế phần cứng................................................................................................ 21
1.5.2 always_comb, always_latch, always_ff.................................................................................................... 22
1.5.4 Interface................................................................................................................................................. 22
1.5.5 Package.................................................................................................................................................. 23
1.6 Bộ nhớ FRAM................................................................................................................................................ 23
1.6.1 Giới thiệu về FRAM................................................................................................................................. 23
Chương 2. Thiết kế và hiện thực.............................................................................................................................. 26
2.1 Vi kiến trúc của MCU Pulpino........................................................................................................................ 26
2.2 Kiến trúc tổng quát của bộ nhớ đệm lệnh...................................................................................................... 27
2.3 Hiện thực bộ nhớ đệm lệnh........................................................................................................................... 29
2.3.1 Chi tiết hiện thực khối cache controller.................................................................................................. 29
2.1.2 Chi tiết hiện thực khối AXI double buffer................................................................................................ 33
2.1.3 Chi tiết hiện thực khối memory array..................................................................................................... 34
2.1.4 Kết quả hiện thực bằng SystemVerilog.................................................................................................... 34
Chương 3. Mô phỏng, tổng hợp và thực nghiệm..................................................................................................... 38
3.1 Môi trường mô phỏng................................................................................................................................... 38
3.1.1 Giới thiệu môi trường mô phỏng............................................................................................................ 38
3.1.2 Cách chạy mô phỏng............................................................................................................................... 40
3.1.3 Debug bằng giao diện Verdi.................................................................................................................... 41
3.2 Kết quả mô phỏng......................................................................................................................................... 42
Chương 4. Kết luận................................................................................................................................................. 43

6


Chương 1. Cơ sở lý thuyết

1.1 Sơ lược về kiến trúc tập lệnh RISC-V
1.1.1 Tổng quát
Kiến trúc tập lệnh RISC-V được thiết kế theo kiểu module nhằm cho
phép các nhà phát triển vi xử lý RISC-V có thể linh hoạt lựa chọn được kiến
trúc phù hợp nhất cho ứng dụng của họ. RISC-V định nghĩa kiến trúc tập lệnh
số nguyên 32-bit RV32I là kiến trúc tập lệnh cơ bản nhất. Với kiến trúc tập
lệnh cơ sở này, vi xử lý RISC-V đã có tất cả những lệnh cơ bản, những lệnh
điều khiển luồng, bộ thanh ghi, bộ nhớ, cách đánh địa chỉ bộ nhớ …vv…đủ
để hiện thực một vi xử lý đơn giản dạng tổng quát hỗ trợ đầy đủ cho phần
mềm và trình biên dịch.
Từ kiến trúc tập lệnh cơ sở này, nhà phát triển vi xử lý RISC-V có thể
linh hoạt chọn kết hợp với một hay nhiều tập lệnh mở rộng tùy chọn khác cho
các ứng dụng mục tiêu. Tập lệnh mở rộng có thể là tập lệnh mở rộng chuẩn
của nhà sáng lập RISC-V hoặc tập lệnh mở rộng phi tiêu chuẩn của nhà phát
triển vi xử lý RISC-V cho một sản phẩm mục tiêu nhất định.
Tên viết tắt
của tập lệnh
RV32I
RV32E
RV64I
RV128I
M
A
F
D
Q
C


Tên đầy đủ


Chú thích

Base Integer Instruction Set, 32-bit
4 tập lệnh cơ sở
Base Integer Instruction Set (embedded)
Base Integer Instruction Set, 64-bit
Base Integer Instruction Set, 128-bit
Integer Multiplication and Division
Atomic Instructions
Những tập mở
Single-Precision Floating-Point
rộng tiêu chuẩn
Double-Precision Floating-Point
Quad-Precision Floating-Point
Decimal Floating-Point


Table 1: Bảng các tập lệnh cơ sở và mở rộng của RISC-V
Để hỗ trợ tốt hơn cho việc phát triển hệ sinh thái phần mềm của vi xử lý
RISC-V, nhà sáng lập RISC-V đã cung cấp sẵn một tập các tập lệnh mở rộng
tiêu chuẩn, bao gồm phép nhân chia số nguyên (tập M), các toán tử nguyên tử
(tập A), phép tốn với số thực dấu phẩy động độ chính xác đơn (tập F), phép
toán với số thực dấu phẩy động độ chính xác kép (tập D). Một kiến trúc tập
lệnh hỗ trợ tập lệnh cơ bản I cùng với tất cả các tập lệnh vừa nêu (M, A, F, D)
gọi là kiến trúc tập lệnh đa mục đích, viết tắt là tập G, ví dụ như RV32G.
Ngồi ra, nhà sáng lập RISC-V còn cung cấp một tập lệnh mở rộng tiêu chuẩn
7



hữu ích nữa là tập lệnh nén để giảm kích thước của mã máy (tập C).
1.1.2 Kiến trúc tập lệnh cơ sở
Kiến trúc tập lệnh cơ sở đầu tiên và cơ bản nhất được RISC-V định
nghĩa là kiến trúc tập lệnh RV32I, bao gồm 47 lệnh có thể được phân chia dựa
trên chức năng và opcode thành 8 nhóm như sau:

Table 2: Phân loại các nhóm lệnh của tập lệnh RV32I
Nếu xét về định dạng của lệnh thì RV32I được chia thành sáu nhóm: Rtype, I-type, S-type, B-type, U-type, J-type. Trong đó R, I, S, U là bốn nhóm
chính, hai nhóm B và J giống hồn tồn nhóm S và U ngoại trừ khác nhau về
phần tốn tử “immediate”.

Hình 1: Định dạng lệnh của RISC-V

8


Về thanh ghi, RV32I có một thanh ghi PC và 32 thanh ghi trong đó có một
thanh ghi x0 ln mang giá trị 0, cộng với 31 thanh ghi đa mục đích x1-x31. Tất
cả đều có độ rộng 32-bit (với RV64I độ rộng của các thanh ghi này trở thành 64bit). Tương tự như kiến trúc tập lệnh RISC, RV32I cũng có kiến trúc LOADSTORE. Điều đó có nghĩa là chỉ có các lệnh Load và Store truy cập vào bộ nhớ,
cịn lại các phép tốn số học …vv… đều chỉ sử dụng các thanh ghi. Ngồi ra
RV32I có nghĩa là không gian địa chỉ là 32-bit và sử dụng little endian. Tương
ứng, RV64I có nghĩa là khơng gian địa chỉ là 64-bit và RV128I có khơng gian địa
chỉ là 128-bit. RV64I và RV128I cũng được xem là những kiến trúc tập lệnh cơ
sở. Bên cạnh đó, cịn một kiến trúc tập lệnh cơ sở nữa là RV32E định nghĩa cho
những hệ thống nhúng. RV32E chỉ có 16 thanh ghi 32-bit registers và những bộ
đếm của RV32I được tùy chọn có hay khơng.

1.1.3 Kiến trúc tập lệnh mở rộng
Như danh sách các kiến trúc tập lệnh cơ bản và mở rộng của RISC-V đề cập
ở trên, RISC-V định nghĩa rất nhiều tùy chọn tập lệnh mở rộng. Trong số đó,

một số đã hồn thiện về đặc tả kĩ thuật, cịn lại vẫn còn đang phát triển. Dưới
đây là những mở rộng đã đóng băng về đặc tả:








M: tập những lệnh nhân chia số nguyên.
A: tập những lệnh nguyên tử Atomic.
F: Single-precision floating point (tuân thủ IEEE 754-2008).
D: Double-precision floating point (tuân thủ IEEE 754-2008).
Q: Quad-precision floating point (tuân thủ IEEE 754-2008).
C: tập những lệnh nén (16-bit) để giảm kích thước của mã lệnh.

Những tập lệnh mở rộng đang được phát triển và sẽ đóng băng đặc tả trong
tương lai gần là tập L (decimal float), B (bit manipulation), J (dynamically
translated languages), T (transactional memory), P (packed SIMD), V (vector
operations), N (user-level interrupts).

9


1.2 Vi xử lý RI5CY
1.2.1 Giới thiệu vi xử lý RI5CY
RI5CY là vi xử lý có thiết kế tương đối hoàn thiện dựa trên kiến trúc
tập lệnh RISC-V nằm trong dự án PULP, là một dự án ngay từ ban đầu hướng
đến phát triển các thiết kế tối ưu về năng lượng tiêu thụ phục vụ cho các sản

phẩm IoT.
PULP là dự án hợp tác giữa phịng thí nghiệm các hệ thống tích hợp
(IIS) của viện cơng nghệ liên bang Thụy Sĩ (ETH Zurich) và phịng thí
nghiệm các hệ thống nhúng hiệu quả năng lượng của Đại học Bologna (Ý)
nhằm phát triển một nền tảng nghiên cứu phần cứng và phần mềm với tiêu chí
tối ưu năng lượng nhất.
Hiện tại PULP đang phát triển 3 dòng vi xử lý dùng cho 3 phân khúc khác
nhau bao gồm:
• Lõi giá thành thấp: gồm hai vi xử lý 2 tầng pipeline Zero-riscy (hỗ trợ
kiến trúc tập lệnh RV32IMC) và Micro-riscy (hỗ trợ kiến trúc tập lệnh
RV32EC) là những vi xử lý được tối ưu ở mức cao nhất hướng đến
những ứng dụng vi điều khiển đơn thuần hoặc có kết hợp với tính tốn
số học đơn giản. Hai vi xử lý này có kiến trúc khá tương đồng với hai
lõi CPU ARM Cortex M0/M0+.
• Vi xử lý RI5CY 4 tầng pipeline hỗ trợ kiến trúc tập lệnh RV32IMC[F]X
cùng với một số mở rộng thêm của riêng vi xử lý này như vòng lặp phần
cứng (HW loops), một số phép tính trên kiểu bit (bits manipulation),
những lệnh LOAD-STORE có địa chỉ tự động tăng…hướng đến những
ứng dụng cần tính tốn trên dữ liệu. Bộ vi xử lý này có kiến trúc khá
tương đồng với hai lõi CPU ARM Cortex M4/M4F.
• Vi xử lý 64-bit Ariane 6 tầng pipeline hỗ trợ kiến trúc tập lệnh
RV64IMC, có thể hỗ trợ hệ điều hành Linux. Bộ vi xử lý này được phát
triển để so sánh và cạnh tranh với CPU ARM Cortex M7.
Cụ thể, vi xử lý RI5CY có kiến trúc tập lệnh được mơ tả chi tiết như dưới
đây:
• Hỗ trợ đầy đủ cho tập lệnh cơ bản RV32I
• Hỗ trợ đầy đủ cho phần mở rộng tiêu chuẩn RV32C cho lệnh nén
(những lệnh có định dạng16-bit).
• Hỗ trợ đầy đủ cho phần mở rộng phép nhân và chia RV32M
• Tùy chọn hỗ trợ đầy đủ cho dấu chấm phẩy động độ chính xác đơn

RV32F (khối FPU được tùy chọn hỗ trợ hay khơng).
• Ngồi ra, RI5CY cịn có các phần mở rộng riêng của dự án PULP
không thuộc kiến trúc tập lệnh tiêu chuẩn (hay còn gọi là RV32X).
Phần kiến trúc tập lệnh mở rộng này sẽ được đề cập ở mục tiếp theo.

10


2.2.2 Kiến trúc tập lệnh mở rộng
Bên cạnh tập trung xây dựng vi kiến trúc của RI5CY dựa trên kiến trúc tập
lệnh chuẩn RV32IMFC của RISC-V nhằm đạt được hiệu suất và code density
tương đương với những vi xử lý cùng phân khúc sử dụng kiến trúc tập lệnh bản
quyền như dịng ARM Cortex-M, nhóm PULP đã cố gắng nghiên cứu mở rộng
tập lệnh và tối ưu vi kiến trúc của RI5CY để tăng cường hiệu xuất xử lý đồng
thời tối ưu về năng lượng tiêu thụ khi vi xử lý này hướng đến sản phẩm IoT.
• Lệnh Load và Store có địa chỉ bộ nhớ tự động tăng:
Trong lúc RI5CY đang thực hiện lệnh truy cập bộ nhớ với địa chỉ hiện
tại thì nó cũng tự động tính địa chỉ cho lệnh Load và Store tiếp theo dựa
vào địa chỉ hiện tại và tham số offset có sẵn. Mục đích của lệnh mở
rộng này là giảm thiểu số lượng lệnh cần cho việc thực thi đọc ghi vào
một vùng nhớ có địa chỉ tăng dần thường được tìm thấy trong các vịng
lặp. Lệnh mở rộng này có thể tăng tốc vi xử lý lên tới 20% nếu việc
truy cập vùng nhớ có địa chỉ tăng dần là thường xuyên, ví dụ như trong
phép nhân ma trận.
• Vịng lặp phần cứng:
Tương tự như mở rộng phía trên là lệnh Load và Store có địa chỉ bộ
nhớ tự động tăng, vịng lặp phần cứng được thêm vào nhằm giảm chi
phí phát lệnh của vi xử lý. Ngồi ra, nó cịn giúp cho khơng tốn bất kỳ
chu kì nào (zero stall cycles) cho việc thực hiện lệnh jump về đầu vòng
lặp mỗi khi kết thúc vòng lặp.

Một vòng lặp phần cứng được xác định bằng địa chỉ bắt đầu (trỏ vào lệnh
đầu tiên trong vòng lặp), địa chỉ kết thúc (trỏ vào lệnh cuối cùng trong
vòng lặp) và một bộ đếm giảm dần khi mỗi lần vòng lặp thực thi xong. Vi
xử lý có sẵn hai tập thanh ghi dành cho vịng lặp phần cứng nên nó hỗ trợ
được hai vịng lặp lồng nhau. Để sử dụng vịng lặp phần cứng thì phần
mềm cần thiết lập nội dung những thanh ghi trong bảng sau:
Địa chỉ

Tên thanh ghi

0x7C0

Hardware Loop 0 Start

0x7C1

Hardware Loop 0 End

0x7C2

Hardware Loop 0 Counter

0x7C4

Hardware Loop 1 Start

0x7C5

Hardware Loop 1 End


0x7C6

Hardware Loop 1 Counter

Table 3: Những thanh ghi điều khiển HW Loop
• Phép nhân tích lũy:
Để hỗ trợ tốt hơn cho các tính tốn xử lý tín hiệu số, RI5CY hiện thực
11


bốn mô đun: một bộ nhân 32bitx32bit, một bộ nhân phân số, và hai bộ
nhân tích vơ hướng. Kết hợp những mơ đun này giúp cho RI5CY có
khả năng hỗ trợ được phép nhân 2 véc tơ, phép nhân tích lũy (MAC) và
phép nhân dấu chấm tĩnh.
• Bộ số học và logic mở rộng:
RI5CY hỗ trợ thêm các phép toán logic và số học (ALU) nâng cao giúp
cho nó tăng thêm khả năng tính tốn như:
- Có thể thực hiện được nhiều lệnh trên nhiều dữ liệu song song chỉ
bằng một lệnh duy nhất và do đó làm tăng hiệu suất xử lý (kiểu SIMD).
- Hỗ trợ lệnh clip giúp cho các phép số học dấu chấm tĩnh hiệu quả hơn.
- Các phép tính tốn trên dữ liệu kiểu bit.
1.2.3 Vi kiến trúc
RI5CY là một vi xử lý 32-bit 4 tầng in-order pipe-line được hiện thực
bằng vi kiến trúc như sơ đồ khối dưới đây:

Hình 2: Sơ đồ khối của CPU RI5CY
❖ Kiến trúc pipeline

RI5CY sử dụng kiến trúc 4 tầng pipeline nhằm tránh trường hợp yêu
cầu write-back bị stall bởi một yêu cầu đọc bộ nhớ từ LSU. Trường hợp này

có thể gặp ở kiến trúc của vi xử lý ARM Cortex-M4.
Là một kiến trúc pipeline in-order nên có nhược điểm là nếu một lệnh
chỉ cần tới tầng EX là hoàn thành vẫn phải đợi lệnh trước hoàn thành ở tầng
WB. Như thể hiện ở hình 2.3, tín hiệu điều khiển ex_ready bị chi phối bởi tín
hiệu rvalid từ bộ nhớ dữ liệu từ bên ngồi.
Hình 2.3 (phía dưới) thể hiện những tín hiệu điều khiển liên quan đến
hoạt động của pipeline. Tín hiệu điều khiển chính là *_ready thể hiện sự sẵn
sàng của từng tầng pipeline được truyền từ phải sang trái. Và mỗi tầng
pipeline có hai tín hiệu điều khiển đi vào: E(enable) và C (Clear). Tín hiệu E
12


tích cực cho tầng pipeline chuyển tới lệnh tiếp theo cịn tín hiệu C xóa bỏ lệnh
hiện tại ra khỏi tầng pipeline vì nó đã hồn thành.
Mỗi tầng pipeline phụ thuộc vào tầng kế tiếp nhưng độc lập với tầng
phía trước, có nghĩa là nó có thể hồn thành cơng việc của nó khơng phụ
thuộc vào việc tầng phía trước có đang bị stall hay khơng. Ở mặt khác, một
lệnh chỉ có thể được chuyển qua tầng kế tiếp khi tầng kế tiếp sẵn sàng nhận
lệnh tiếp theo (bằng cách đặt *_ready lên 1).

13


Hình 3: kiến trúc pipe-line của CPU RI5CY


Khối phát lệnh

Khối phát lệnh IF sử dụng một Prefetch buffer. Bộ đệm này được sử dụng
để tối ưu hiệu suất, đặc biệt là đối với phần mở rộng “vòng lặp phần cứng” sẽ

cần 4-8 lệnh có sẵn để thực thi vịng lặp, ngồi ra nó cịn mang ý nghĩa cân
bằng timing (timing closure). Prefetch buffer này có hai cấu hình để lựa chọn:
• Một FIFO gồm 3 entry, mỗi entry là 32 bit.
• Một cache line 128-bit. Cache line này có thể chứa tối thiểu 4 lệnh 32bit hoặc 8 lệnh 16-bit.
Bộ đệm tìm nạp trước này phát lệnh từ bộ nhớ bên ngồi hay bộ nhớ
đệm lệnh thơng qua interface và giao thức tương tự như khối Load-Store Unit
(LSU) của tầng WB, chỉ khác là phần phát lệnh là chỉ đọc nên ít tín hiệu giao
tiếp hơn. Bảng sau sẽ mơ tả những tín hiệu mà bộ Prefetch buffer sử dụng:

14


Tín hiệu
instr_req_o

Chiều
output

Đặc tả
Yêu cầu truy cập đọc lệnh tới bộ nhớ, phải
giữ giá trị một cho đến khi instr_gnt_i lên
1 được ít nhất một chu kỳ
instr_addr_o[31:0]
output
Địa chỉ truy cập bộ nhớ
instr_rdata_i[31:0]
input
Dữ liệu lệnh đọc từ bộ nhớ
instr_rvalid_i
input

Dữ liệu lệnh instr_rdata_i sẵn sàng tín hiệu
instr_rvalid_i này là 1. Tín hiệu này chỉ lên
1 chỉ trong đúng 1 chu kỳ đối với mỗi lần
đọc.
instr_gnt_i
input
Bộ nhớ trả lời chấp nhận yêu cầu đọc lệnh
Table 4: Bảng các input/output của bộ phát lệnh
Về giao thức mà bộ prefetch buffer sử dụng để giao tiếp với bộ nhớ
chứa lệnh bên ngoài (cũng cùng là giao thức mà khối LSU dùng để đọc ghi dữ
liệu xuống bộ nhớ dữ liệu) được đặc tả như dưới đây:
Khi LSU bắt đầu một lần truy cập bộ nhớ, nó sẽ cung cấp địa chỉ hợp lệ
thơng qua tín hiệu bus data_addr_o và đặt data_req_o lên 1. Bộ nhớ sau đó sẽ
chấp nhận yêu cầu bằng cách đặt data_gnt_i lên 1 ngay khi nó sẵn sàng. Việc
chấp nhận yêu cầu này có thể xảy ra ngay trong chu kỳ mà LSU đưa ra yêu
cầu hoặc có thể là một vài chu kỳ sau đó. Sau khi LSU nhận được trả lời chấp
nhận yêu cầu từ bộ nhớ, nó có thể tiếp tục bắt đầu một yêu cầu truy cập bộ
nhớ mới, tiếp theo. Khi đó, những tín hiệu như data_addr_o, data_wdata_o,
data_we_o, data_be_o có thể chuyển sang giá trị mới. Đồng thời, bộ nhớ có
thể trả kết quả truy cập về bằng cách đặt data_rvalid_i lên 1 và giá trị của tín
hiệu bus data_rdata_i khi đó có giá trị hợp lệ nếu là yêu cầu là đọc bộ nhớ
(nếu yêu cầu là ghi vào bộ nhớ thì data_rvalid_i vẫn lên 1 nhưng giá trị của
bus data_rdata_i không cần được quan tâm). Việc trả lời này xảy ra sau một
hoặc nhiều chu kỳ từ lúc LSU nhận được tín hiệu chấp nhận.

15


Ví dụ minh họa về biểu đồ thời gian của giao thức:


Hình 4: Minh họa giao thức truy cập bộ nhớ (cơ bản)

Hình 5: Minh họa giao thức truy cập bộ nhớ (Back-to-back)

Hình 6: Minh họa giao thức truy cập bộ nhớ (đáp ứng chậm)

16


1.3 Sơ lược về vi điều khiển Pulpino
1.3.1 Giới thiệu
Tương tự như các sản phẩm khác của dự án PULP, Pulpino là vi điều
khiển 32-bit được xây dựng nhắm đến sản phẩm IoT. Pulpino sử dụng một vi
xử lý RI5CY và tái sử dụng các thành phần khác từ dự án PULP như hệ thống
bus, các thành phần ngoại vi (UART, SPI, GPIO, I 2C…), …vv. Vi điều khiển
này không sử dụng bộ nhớ đệm (cache) hay DMA. Nó chỉ dùng 2 bộ nhớ
riêng biệt hoàn toàn bằng SRAM, một cho bộ nhớ lệnh và một cho bộ nhớ
chứa dữ liệu. Ngồi ra, nó cịn chứa một vùng Boot rom 512B. Vùng Boot
Rom có chứa Boot Loader có thể tải chương trình từ thiết bị flash bên ngồi
thơng qua cổng SPI slave.
1.3.2 Kiến trúc hệ thống
Hình 2.7 dưới đây thể hiện sơ đồ khối của Pulpino.

Hình 7: Sơ đồ khối của vi điều khiển Pulpino
Vi xử lý RI5CY sử dụng 2 port riêng biệt cho đọc lệnh và đọc ghi dữ liệu.
Mã lệnh được tải vào Instr. RAM có kích thước 32KB, trong khi đó dữ liệu
được đọc ghi vào Data RAM cũng có kích thước 32KB.
Bus giao tiếp chính trong vi điều khiển này là AXI4 có độ rộng dữ liệu là 32
bit. Các thành phần ngoại vi kết nối vào bus AXI4 này thông qua bus APB và
một cầu AXI4-APB, tất cả đều có độ rộng dữ liệu là 32 bit.

Pulpino sử dụng khối Adv. Debug Unit cho mục đích Debug. Khối này có thể
truy cập được vào tất cả thanh ghi của vi xử lý và 2 bộ nhớ SRAM thông qua
cổng JTAG.
17


1.3.3 Bản đồ truy cập bộ nhớ
Bản đồ để truy cập bộ nhớ của Pulpino được phân bố như hình 2.8 dưới
đây. Về cơ bản được chia thành 4 vùng: vùng bộ nhớ lệnh, vùng bộ nhớ Boot
ROM, vùng bộ nhớ dữ liệu và vùng bộ nhớ truy cập các module ngoại vi và
Debug.

Hình 8: Bản đồ truy cập bộ nhớ của vi điều khiển Pulpino

1.4 Bộ nhớ đệm lệnh
1.4.1 Giới thiệu
Trong những kiến trúc máy tính ngày nay, CPU thường có nhiều tầng bộ
nhớ đệm (cache* level). Gần CPU nhất là bộ nhớ đệm cấp 1 (L1 cache) rồi đến
bộ nhớ đệm cấp 2, 3 (L2 cache, L3 cache) và có thể có cả bộ đếm nhớ cấp cuối
cùng (FLC-Final Level Cache). Trong đó, bộ nhớ đệm cấp 1 là bộ nhớ đệm
(

thuật ngữ bộ nhớ đệm và thuật ngữ cache sử dụng tương đương trong tài liệu này

18


nhanh nhất, có chi phí đắt nhất nên thường có kích thước hạn chế. Bộ nhớ
đệm L1 này thường được sử dụng để lưu trữ những dữ liệu mà CPU truy cập
gần nhất hay dữ liệu tiếp theo mà CPU cần xử lý ngay lập tức. Bộ nhớ đệm

này thường được chia thành hai bộ nhớ đệm riêng có chức năng khác nhau,
một dành cho mã lệnh (instruction cache) và một là dành cho dữ liệu mà
chương trình cần xử lý (data cache). Hai bộ nhớ đệm này có thể truy cập vào
cùng bộ nhớ đệm cấp lớn hơn là L2 cache. Kiến trúc điển hình này được mơ
tả như mơ hình dưới đây:

Hình 9: Mơ hình bộ vi xử lý với 3 cấp bộ nhớ đệm
Do tính chất đặc trưng của dữ liệu là mã lệnh đã được trình biên dịch
xử lý nên so với bộ nhớ đệm dữ liệu, bộ nhớ đệm lệnh ít phức tạp hơn. Luồng
của mã nguồn có thể dễ dự đốn hơn để prefetch và mã nguồn có thể lặp đi
lặp lại (ví dụ như vòng lặp) hay đơn giản là địa chỉ chứa những lệnh tiếp theo
tăng tuyến tính. Tóm lại, bộ nhớ đệm lệnh rất tốt về tính cục bộ khơng gian
lẫn thời gian (temporal locality & spatial locality).
1.4.2 Kiến trúc của bộ nhớ lệnh
Một bộ nhớ đệm lệnh cũng có kiến trúc tương tự như một đệm nhớ bất
kỳ nào khác với những thành phần chính như dưới đây:
❖ Memory array
Là bộ nhớ SRAM nơi thực sự chứa dữ liệu (là lệnh cho CPU) được nạp
lên từ bộ nhớ cấp cao hơn. Tùy vào tính chất kết hợp (associative) của cache,
memory array này có thể chia thành 1,2,4,8…bộ nhớ nhỏ hơn bằng nhau
(tương ứng với 1-way,2-way,4-way,8-way…).

19


Mỗi bộ nhớ nhỏ lại được chia nhiều khối dữ liệu có kích cỡ nhỏ hơn,
gọi là cache block. Lệnh được chuyển từ bộ nhớ chính lên bộ nhớ đệm cache
này theo từng khối có kích thước bằng cache block. Khi CPU cần đọc lệnh ở
một vị trí trong bộ nhớ chính, nó sẽ tìm trong cache đầu tiên. cache sẽ kiểm
tra vị trí dữ liệu yêu cầu đã được lưu sẵn trong bất cứ cache block nào hay

không. Nếu có, là cache hit. Cịn ngược lại, nếu khơng tìm thấy được vị trí dữ
liệu trong cache, thì là cache miss. Trong trường hợp cache hit, CPU đọc lệnh
từ cache block lên ngay lập tức. Còn nếu là cache miss, cache sẽ tạo một entry
mới và sao chép dữ liệu từ bộ nhớ chính lên cache block tương ứng, sau đó
đáp ứng yêu cầu đọc lệnh của CPU.
❖ Tag array
Để kiểm tra có cache block nào chứa sẵn lệnh cần đọc hay không
(cache hit hay cache miss), một phần của địa chỉ truy cập bộ nhớ gửi từ CPU
(gọi là tag field) sẽ được so sánh với những dữ liệu tag đã lưu trước trong Tag
array khi nạp dữ liệu lên cache ở những lần truy cập trước.
Ví dụ:
CPU truy cập bộ nhớ để đọc lệnh bằng địa chỉ có độ rộng 24 bit.
Cache có kích thước 8KB tổ chức thanh 8-ways. Mỗi way có kích thước 1kB
chia thành 256 cache block, mỗi cache block có kích thước 4 byte.
Khi đó, cache dùng 2 bit thấp nhất làm địa chỉ offset cho 4 byte trong mỗi
cache block, 8 bit thấp tiếp theo làm tag index để truy cập vào memory array
và dùng 24-10=14 bit cao còn lại cho tag field.
❖ Bit valid array
Mỗi cache block sử dụng 1-bit đại diện cho trạng thái của nó. Khi valid
bit này bằng 1 có nghĩa là cache block này đã được sử dụng và đang lưu trữ
dữ liệu. Nếu valid bit này bằng 0, có nghĩa là cache block chưa có dữ liệu.
Khi cache block chưa có dữ liệu, khi cache miss, cache đọc dữ liệu từ bộ nhớ
chính lên lưu vào cache block và đặt valid bit của cache block này lên 1.
❖ Cache controller

Khi CPU khởi tạo yêu cầu đọc lệnh, cache controller sẽ so sánh tag
field từ địa chỉ đọc lệnh của CPU với tất cả dữ liệu tag tương ứng từ các cache
way để xác định cache hit hay cache miss. Đối với cache hit, cache controller
đọc lệnh từ memory array và trả về cho CPU ngay để thực thi. Đối với Cache
miss, cache controller sẽ đi đọc lệnh từ bộ nhớ cấp trên và tìm cache block để

lưu dữ liệu mới vào đồng thời trả lệnh được yêu cầu về cho CPU thực thi.
❖ Way Replacement Unit (WRU)

20


Nếu cache có nhiều way, nhưng khi so sánh tag field từ địa chỉ đọc lệnh
của CPU với tất cả dữ liệu tag tương ứng từ các cache way đều khơng trùng
khớp, có nghĩa là dữ liệu lệnh cần đọc khơng có trong bất kì cache block nào
của bất kì way nào, gọi là way miss, một dạng khác của cache miss. Trong
trường hợp này, WRU sẽ tìm ra một way sẽ bị flush và thay thế bằng dữ liệu
mới. WRU thường được hiện thực bằng một thuật toán như LRU (Least
Recently Used) hoặc LFSR (Linear Feedback Shift Register).

1.5 Sử dụng systemverilog để thiết kế phần cứng
Với sự phát triển gần đây của các công cụ tổng hợp, SystemVerilog (gọi
tắt là SV) từ chỗ là một ngơn ngữ lập trình được sử dụng chủ yếu để tạo ra
môi trường mô phỏng để kiểm định thiết kế phần cứng đã dần trở thành ngôn
ngữ thiết kế phần cứng. Việc sử dụng SV trong thiết kế phần cứng đã mang
đến nhiều mặt tích cực cho thiết kế. Ví dụ như mã RTL được trình bày ngắn
gọn, dễ đọc hơn (sử dụng interface thay vì dùng module ports) hay giải quyết
được những lỗi của Verilog mà chỉ được tìm thấy ở giai đoạn sau tổng hợp (sử
dụng always_comb, always_ff, always_latch thay vì dung always như Verilog
trước đây) …
Sau đây, một số thành phần hay phương pháp thiết kế mới mà SV mà mang
lại sẽ được trình bày:
1.5.1 Kiểu dữ liệu logic
Verilog sử dụng 2 kiểu dữ liệu là wire và reg để khai báo các tín hiệu. Và
việc dùng 2 kiểu dữ liệu này cần phù hợp với ngữ cảnh nơi mà tín hiệu được
khai báo sử dụng. Ví dụ như biến được khai báo với kiểu reg khơng thể sử dụng

bên ngồi khối always hay biến được khai báo với kiểu wire không thể sử dụng
bên trong khối always…vv… SV giải quyết rắc rối thông qua việc thống nhất

21


2 kiểu dữ liệu đó thành kiểu logic. Với SV, người viết RTL khơng cịn lúng
túng với việc chọn lựa khai báo cho từng port của module là reg hay wire Ví
dụ:
module sv_example
( input logic[1:0] a, b,
output logic c
);
always @(a,b) begin
if (a[0]==b[0] && a[1]==b[1]) c = 1;
else c = 0;
end
endmodule
1.5.2 always_comb, always_latch, always_ff
Verilog cung cấp một định nghĩa always duy nhất để người lập trình tạo
ra các thành phần combination logic, flipflop hay latch. Dựa vào cách viết
RTL, công cụ tổng hợp tự suy luận ra logic mà người viết RTL mong muốn.
Do đó, khơng có cách nào để kiểm tra khối always đó viết đúng hay sai cho
đến khi qua giai đoạn tổng hợp.
SV đã giải quyêt vấn đề thông qua việc đưa ra những định nghĩa mới
always_comb, always_latch hay always_ff để viết ra các thành phần
combination logic, flipflop hay latch một cách tường minh. Và các thành phần
được kiểm tra đúng sai ngay lúc chạy mô phỏng.
Khối always ở ví dụ trên có thể viết lại như sau:
always_comb begin

if (a[0]==b[0] && a[1]==b[1]) c = 1;
else c = 0;
end
1.5.3 Kiểu dữ liệu người dùng tự định nghĩa
Kiểu dữ liệu tự định nghĩa thông qua typedef hay enum giúp cho mã
viết ra được gọn gàng và trực quan nhưng verilog không hỗ trợ điều này. Tuy
vậy, điều may mắn là SV đã hỗ trợ chúng trong thiết kế RTL. Ví dụ:
typedef logic [31:0] arm_bus;
arm_bus axi4_bus, apb_bus, ahb_bus;
enum logic [1:0] {IDLE, ACTIVE, CHECK, ANSWER} en_state;
1.5.4 Interface
Một trong những nhược điểm lớn của Verilog trước đây chính là việc
khai báo cổng (input, output, inout) của module và kết nối những module thông
qua việc kết nối từng tín hiệu ra vào này. Việc khai báo và kết nối này tạo ra
những đoạn mã RTL trùng lắp ở nhiều nơi và tạo ra nguy cơ sai sót. SV đã khắc
22


phục điều này bằng việc cung cấp interface giúp cho mã RTL gọn gàng và các
module được kết nối đơn giản hơn.
Ví dụ
interface intf_1;
wire sig1, sig2, sig3, sig4;
endinterface: intf_1
module top;
wire clock, reset;
intf_1 i1();
mod_a u1 (.a1(i1), .clk(clock), .rstN(reset) );
mod_b u2 (.b1(i1), .clk(clock), .rstN(reset) );
endmodule: top

module mod_a (interface a1, input clk, rstN); ... endmodule module mod_b
(intf_1 b1, input clk, rstN); ... endmodule
1.5.5 Package
Một hạn chế khác nữa của Verilog là khơng có một phương thức chia
sẻ những khai báo chung giữa các module. Mỗi module chứa toàn bộ khai báo
dùng cho bên trong module đó. SV bổ sung cho verilog bằng khái niệm
package do người dùng tự định nghĩa. Package là không gian khai báo có thể
được tham khảo từ bất kì module nào cũng như từ những đoạn mã mô phỏng.
Những mục thuộc pakage mà có thể tổng hợp được:
• parameter and localparam constant definitions
• const variable definitions
• typedef user-defined types
• Fully automatic task and function definitions
• import statements from other packages
• export statements for package chaining
Ngồi ra, SV có rất nhiều cải tiến khác so với Verilog như thêm Void
function, thêm Ending name, `begin_keywords, ‘end_keywords, timeunit,
timeprecision, nâng cấp hàm for, thêm hàm foreach …

1.6 Bộ nhớ FRAM
1.6.1 Giới thiệu về FRAM
FRAM (hay FeRAM) là chữ viết tắt của Ferroelectric RAM, là một loại
bộ nhớ mới nổi thuộc loại Non-Volatile Memory (NVM) rất phù hợp cho các
ứng dụng yêu cầu tiết kiệm năng lượng như IoT. Vì là bộ nhớ loại NVM cho
nên FRAM không mất dữ liệu khi mất nguồn điện. Ngoài ra, như cách gọi,
RAM là một phần trong tên của bộ nhớ này, cho nên cách thức FRAM hoạt
động tương tự như DRAM. Nó cho phép truy cập đọc ghi ngẫu nhiên đến
từng bit. Và không giống như các loại bộ nhớ EEPROM hay Flash, FRAM
23



khơng cần một trình tự đặc biệt nào để ghi dữ liệu và cũng không cần điện thế
cao để lập trình dữ liệu vào bộ nhớ này [11].
Cụ thể, những đặc tính nổi bật của FRAM được liệt kê như sau:
- Là loại bộ nhớ non-volatile nên không mất dữ liệu khi mất nguồn
điện
- Là loại bộ nhớ có khả năng truy cập ngẫu nhiên theo địa chỉ đến
từng byte hay word giống như SRAM.
- Quá trình đọc hay ghi vào FRAM khơng cần q trình cài đặt
hay chuẩn bị nào.
- Tốc độ ghi nhanh, với độ trễ nhỏ hơn 50ns, nhanh hơn công nghệ
Flash hay EEPROM hơn 100 lần [17].
- FRAM cho phép ghi xóa đến 10^15 lần.
- FRAM yêu cầu về năng lượng tiêu thụ rất thấp vì điện thế hoạt
động chỉ cần 2V so với yêu cầu 10-14V của Flash hay EEPROM
[17].
1.6.2 So sánh FRAM với các loại bộ nhớ khác
Bảng so sánh sau đây được trích từ báo cáo [18] của Texas Instrument:

Table 5: Bảng so sánh FRAM với các bộ nhớ khác
Từ bảng so sánh trên cho thấy rằng, tốc độ truy cập của FRAM là chậm
hơn so với SRAM nhưng so với SRAM thì FRAM có ưu thế về khả năng giữ
lại dữ liệu khi khơng có nguồn điện. Ngồi ra, năng lượng khi khi hoạt động
của FRAM cũng thấp khi so với SRAM, chỉ khoảng 2X so với SRAM. Nhưng
ở mặt khác, SRAM lại tốn năng lượng nhiều ở phần năng lượng rò cịn FRAM
lại khơng tốn năng lượng rị vì là bộ nhớ NVM.
Cịn so với Flash và EEPROM thì FRAM có năng lượng khi hoạt động
nhỏ hơn 2.5X và >500X lần tương ứng. Trong khi đó, tốc độ đọc ghi của
FRAM lại nhanh hơn 100X lần so với hai loại bộ nhớ này.
Cịn so với DRAM thì FRAM tốn ít năng lượng hơn DRAM rất nhiều. Đối

với DRAM, điện tích bị rò rỉ và mất dần, cho nên để DRAM lưu trữ dữ liệu cho
bất kỳ thứ gì ngồi một thời gian rất ngắn, mọi ơ nhớ của nó cần được đọc định
kỳ và viết lại, quá trình này gọi là làm mới (refresh). Mỗi ô nhớ phải được làm
24


mới nhiều lần mỗi giây (thường là 16 lần/giây) [9] và điều này làm tiêu tốn

25


×