BÁO CÁO BÀI TẬP LỚN Môn học: THIẾT KẾ VLSI Đề tài: CODE RTL CHO SYNCHRONOUS FIFO MỤC LỤC MỤC LỤC 1 DANH MỤC HÌNH VẼ 2 DANH MỤC BẢNG CHIẾU 3 CHƯƠNG I. TỔNG QUAN VỀ HỆ THỐNG 4 1.1. Giới thiệu về Synchronous FIFO 4 1.2. Sơ đồ khối của Synchronous FIFO 4 1.3. Yêu cầu hoạt động 6 CHƯƠNG II. THIẾT KẾ SƠ ĐỒ KHỐI 7 2.1. Thiết kế sơ đồ khối 7 2.2. Xây dựng thuật toán 7 2.2.1. Cơ sở lý thuyết 7 2.2.2. Xây dựng mô hình thuật toán 9 CHƯƠNG III. THỰC NGHIỆM 12 CHƯƠNG IV. KẾT QUẢ MÔ PHỎNG 16 4.1. Thiết lập trạng thái sau đó yêu cầu ghi 16 4.2. Thiết lập trạng thái sau đó yêu cầu đọc 16 4.3. Thiết lập trạng thái sau đó 2 yêu cầu ghi 17 4.4. Thiết lập trạng thái sau đó 1 yêu cầu ghi và 1 yêu cầu đọc 18
Trang 1ĐẠI HỌC BÁCH KHOA HÀ NỘI
TRƯỜNG ĐIỆN – ĐIỆN TỬ
-BÁO CÁO BÀI TẬP LỚN Môn học: THIẾT KẾ VLSI
Đề tài: CODE RTL CHO SYNCHRONOUS FIFO
Giảng viên hướng dẫn: Nguyễn Vũ Thắng
Mã lớp: 133390
Sinh viên thực hiện:
Họ và tên Mã số sinh viên Lớp
Hà Nội, 27/07/2022
Trang 2MỤC LỤC
MỤC LỤC 1
DANH MỤC HÌNH VẼ 2
DANH MỤC BẢNG CHIẾU 3
CHƯƠNG I TỔNG QUAN VỀ HỆ THỐNG 4
1.1 Giới thiệu về Synchronous FIFO 4
1.2 Sơ đồ khối của Synchronous FIFO 4
1.3 Yêu cầu hoạt động 6
CHƯƠNG II THIẾT KẾ SƠ ĐỒ KHỐI 7
2.1 Thiết kế sơ đồ khối 7
2.2 Xây dựng thuật toán 7
2.2.1 Cơ sở lý thuyết 7
2.2.2 Xây dựng mô hình thuật toán 9
CHƯƠNG III THỰC NGHIỆM 12
CHƯƠNG IV KẾT QUẢ MÔ PHỎNG 16
4.1 Thiết lập trạng thái sau đó yêu cầu ghi 16
4.2 Thiết lập trạng thái sau đó yêu cầu đọc 16
4.3 Thiết lập trạng thái sau đó 2 yêu cầu ghi 17
4.4 Thiết lập trạng thái sau đó 1 yêu cầu ghi và 1 yêu cầu đọc 18
Trang 3DANH MỤC HÌNH VẼ
Figure 1 Sơ đồ đầu vào và ra của SFIFO 4
Figure 2 Sơ đồ khối của SFIFO 7
Figure 3 Mô hình đọc ghi dữ liệu 8
Figure 4 Trạng thái đầu thu được sau các lần đọc ghi 8
Figure 5 Mô hình thuật toán 10
Figure 6 Mô phỏng 1 yêu cầu ghi 16
Figure 7 Mô phỏng 1 yêu cầu đọc 16
Figure 8 Mô phỏng 2 yêu cầu ghi 17
Figure 9 Mô phỏng 1 yêu cầu ghi và 1 yêu cầu đọc 18
Trang 4DANH MỤC BẢNG CHIẾU
Table 1 Các chân input 5 Table 2 Các chân output 5
Trang 5CHƯƠNG I TỔNG QUAN VỀ HỆ THỐNG
1.1 Giới thiệu về Synchronous FIFO
Thiết kế Synchronous FIFO (FIFO đồng bộ):
FIFO hoạt động như một kho lưu trữ giữa hai hệ thống con Một hệ thống con ghi dữ liệu vào bộ đệm; hệ thống con khác truy xuất (tức là đọc) dữ liệu từ bộ đệm và xóa khỏi bộ đệm Thứ tự truy xuất dữ liệu giống như thứ tự dữ liệu được lưu trữ và do đó bộ đệm được gọi là first-in-first-out
Nếu hai hệ thống con được điều khiển bởi cùng một xung clock) thì được gọi là Synchronous FIFO (FIFO đồng bộ)
1.2 Sơ đồ khối của Synchronous FIFO
Figure 1 Sơ đồ đầu vào và ra của SFIFO
Trang 6Trong đó:
Các chân input:
1 i_clk 1 bit Tạo xung clock để đồng bộ tín hiệu
2 i_rst_n 1 bit Thiết lập FIFO về trạng thái ban đầu
3 i_datain 32 bits Dữ liệu được ghi vào FIFO
4 i_almostempty_lvl 8 bits Số ô trống it nhất trong FIFO để
o_almostfull hoạt động (cờ báo gần trống)
5 i_almostfull_lvl 8 bits Số ô trống nhiều nhất trong FIFO để
o_almostfull hoạt động (cờ báo gần đầy)
6 i_valid_s 1 bit Yêu cầu ghi dữ liệu vào FIFO
7 i_ready_m 1 bit Yêu cầu đọc dữ liệu từ FIFO
Table 1 Các chân input
Các chân output:
1 o_empty 1 bit Cờ báo FIFO trống
3 o_almostfull 1 bit Cờ báo FIFO gần đầy ( dựa vào
chân i_almostfull_lvl)
4 o_almostempty 1 bit Cờ báo FIFO gần trống (dựa vào
chân i_almostempty_lvl)
5 o_valid_m 1 bit Cờ báo sẵn sàng đọc dữ liệu từ
FIFO
6 o_ready_s 1 bit Cờ báo sẵn sàng ghi dữ liệu vào
FIFO
7 o_dataout 32 bit Dữ liệu đọc từ FIFO
Trang 7Table 2 Các chân output
Ngoài ra SFIFO có kích thước FIFO_DEPTH = 256
1.3 Yêu cầu hoạt động
Khi có tín hiệu reset (i_reset_n hoạt động ở mức thấp):
o Cờ o_full) và o_almostfull hoạt động ở mức thấp
o Cờ o_empty và o_almostempty hoạt động ở mức cao
Khi có yêu cầu đọc/ghi, kiểm tra trạng thái của SFIFO:
o FIFO đầy: không cho phép ghi dữ liệu tới FIFO
- Cờ o_full, o_almostfull và o_valid_m hoạt động ở mức cao; cờ o_empty, o_almostempty và o_ready_s hoạt động ở mức thấp
o FIFO trống: không cho phép đọc dữ liệu từ FIFO
- Cờ o_empty, o_almostempty và o_ready_s hoạt động ở mức cao; cờ o_full, o_almostfull và o_valid_m hoạt động ở mức thấp
o FIFO gần đầy: Cảnh báo bộ đệm gần đầy, FIFO vẫn có thể đọc/ ghi dữ liệu
- Cờ o_almostfull, o_ready_s và o_valid_m hoạt động ở mức cao; cờ o_full, o_empty và o_almostempty hoạt động ở mức thấp
o FIFO gần trống: Cảnh báo bộ đệm gần trống, FIFO vẫn có thể đọc/ ghi dữ liệu
- Cờ o_almostempty, o_ready_s và o_valid_m hoạt động ở mức cao; cờ o_full, o_empty và o_almostfull hoạt động ở mức thấp
Sau khi đọc/ghi thành công dữ liệu con trỏ đọc/ ghi tăng lên 1
Trang 8CHƯƠNG II THIẾT KẾ SƠ ĐỒ KHỐI
2.1 Thiết kế sơ đồ khối
Từ những yêu cầu đặt ra xây dựng hệ thống gồm 3 bước chính:
o Bước 1: Kiểm tra trạng thái của chân reset
o Bước 2: Kiểm tra trạng thái của FIFO
o Bước 3: Đọc/ghi dữ liệu dựa vào yêu cầu đầu vào và trạng thái của FIFO
thu được ở bước 2
Figure 2 Sơ đồ khối của SFIFO
2.2 Xây dựng thuật toán
2.2.1 Cơ sở lý thuyết
Ví dụ mô tả về quá trình đọc ghi dữ liệu trong SFIFO và vị trí con trỏ đọc ghi SFIFO ở đây đang có kích thước là 8
Trang 9Figure 3 Mô hình đọc ghi dữ liệu
o Trạng thái của SFIFO thu được sau các lần đọc ghi
Figure 4 Trạng thái đầu thu được sau các lần đọc ghi
Nhận xét:
o SFIFO ở trạng thái trống khi con trỏ đọc và ghi trùng nhau
o SFIFO ở trạng thái đầy khi 3 bit cuối của con trỏ đọc và ghi trùng nhau
o Khi 3 bit cuối của con trỏ đọc lớn hơn 3 bit cuối của con trỏ ghi thì khoảng cách giữa 2 giá trị này là số ô nhớ còn trống trong bộ đệm
Trang 10o Khi 3 bit cuối của con trỏ ghi lớn hơn 3 bit cuối của con trỏ đọc thì khoảng cách giữa 2 giá trị này là số ô nhớ đã ghi trong bộ đệm
So sánh ô nhớ còn trống với i_almostfull_lvl và i_almostempty_lvl sẽ xác định được trạng thái của SFIFO
o Để ghi dữ liệu vào SFIFO:
- i_valid_s (yêu cầu ghi dữ liệu) và o_ready_s (sẵn sàng ghi dữ liệu) đều ở mức cao
- Khi đó ô nhớ có địa chỉ là 3 bit cuối của con trỏ ghi = i_datain, con trỏ ghi tăng lên 1
o Tương tự để đọc dữ liệu từ SFIFO:
- i_ready_m (yêu cầu đọc dữ liệu) và o_valid_m (sẵn sàng đọc dữ liệu) đều ở mức cao
- Khi đó o_dataout = ô nhớ có địa chỉ là 3 bit cuối của con trỏ đọc, con trỏ đọc tăng lên 1
2.2.2 Xây dựng mô hình thuật toán
Xây dựng mô hình thuật toán cho Synchronous FIFO kích thước là 256:
Ngoài các chân input và output, cần sử dụng 2 con trỏ đọc và ghi có kích thước là
9 bit và mảng rg_data với 256 phần tử, kích thước mỗi phần từ là 32bit để lưu dữ liệu
Trang 11 Mô hình thuật toán:
Figure 5 Mô hình thuật toán
Bước1(check_reset): Kiểm tra trạng thái của chân reset
o Khi reset hoạt động ở mức thấp:
w-ptr[8:0], r_ptr[8:0] gán bằng 0;
o Khi reset ở mức cao kiểm tra i_valid_s và o_ready_s nếu đều ở mức cao: w_ptr = w_ptr + 1
o Nếu sai kiểm tra tiếp i_ready_m và o_valid_m n u ế đều ở mức cao:
o r_ptr = r_ptr + 1
Bước 2 (check_state): Kiểm tra trạng thái của SFIFO
1/ Kiểm tra 2 con trỏ đọc và ghi nếu w_ptr[8:0] ≡ r_ptr[8:0]
o Đúng: SFIFO đang ở trạng thái trống
o Sai: Chuyển sang 2/
2/ Kiểm tra 2 con trỏ đọc và ghi nếu w_ptr[7:0] ≡ r_ptr[7:0]
o Đúng: SFIFO đang ở trạng thái đầy
o Sai: Chuyển sang 3/
Trang 123/ So sánh giá trị w_ptr[7:0] và r_ptr[7:0] để xác định SFIFO có ở trạng thái gần đầu/ gần trống không:
o Nếu w_ptr[7:0] < r_ptr[7:0]: số ô trống còn lại = r_ptr[7:0] – w_ptr[7:0];
o Nếu w_ptr[7:0] > r_ptr[7:0]:
số ô trống còn lại = FIFO_DEPTH – (w_ptr[7:0] - r_ptr[7:0])
Sau khi xác định được ô trống còn lại sẽ so sánh giá trị này với i_almostfull_lvl và i_almostempty_lvl
o Nếu số ô trống <= i_almostfull_lvl => SFIFO ở trạng thái gần đầy
o Nếu số ô trống >= i_almostempty => SFIFO ở trạng thái gần trống
Bước 3(write_data và read_data): Đọc/ghi dữ liệu dựa vào yêu cầu đầu vào và trạng
thái của FIFO thu được ở bước 2
1/ Ghi dữ liệu:
Nếu i_valid_s và o_ready_s đều ở mức cao:
rg_data[w_ptr] = i_datain
Sai: không thể ghi dữ liệu, w_ptr vẫn giữ nguyên trạng thái
2/ Đọc dữ liệu:
N u i_ready_m và o_valid_m ế đều ở mức cao:
o_dataout = rg_data[r_ptr]
Sai: không thể đọc dữ liệu, r_ptr vẫn giữ nguyên trạng thái
Trang 13CHƯƠNG III THỰC NGHIỆM
Từ sơ đồ thuật toán, lập trình bằng ngôn ngữ RTL, thiết kế Synchronous FIFO theo 3 bước
Bước1(check_reset): Kiểm tra trạng thái của chân reset
always @ (posedge i_clk or negedge i_rst_n)
begin
if(~i_rst_n)
begin
w_ptr[8:0] <= 9'd0;
r_ptr[8:0] <= 9'd0;
end
else if (i_valid_s && o_ready_s)
begin
w_ptr[8:0] <= w_ptr[8:0] +1'd1;
end
else if (i_ready_m && o_valid_m)
begin
r_ptr[8:0] <= r_ptr[8:0] +1'd1;
end
end
Xét xung clock i_clk ở sườn dương và reset i_rst_n ở sườn âm:
1/ Khi i_rst_n = 0 thiết lập con trỏ đọc/ghi SFIFO về trạng thái ban đầu
2/ Khi i_valid_s và o_ready_s đều ở mức 1: con trỏ ghi sẽ tăng lên 1
3/ Khi i_ready_m và o_valid_m đều ở mức 1: con trỏ đọc sẽ tăng lên 1
Bước 2 (check_state): Kiểm tra trạng thái của SFIFO
TH1: w_ptr[8:0] ≡ r_ptr[8:0] SFIFO ở trạng thái trống:
if (w_ptr == r_ptr)
begin
o_empty <= 1'd1;
o_full <= 1'd0;
o_ready_s <= 1'd1;
o_valid_m <= 1'd0;
o_almostfull <= 1'd0;
o_almostempty <= 1'd1;
end
Trang 14 TH2: w_ptr[7:0] ≡ r_ptr[7:0] và w_ptr[8] != r_ptr[8] SFIFO ở trạng thái đầy:
else if (r_ptr[7:0] && w_ptr[7:0] )
begin
o_empty <= 1'd0;
o_full <= 1'd1;
o_ready_s <= 1'd0;
o_valid_m <= 1'd1;
o_almostfull <= 1'd1;
o_almostempty <= 1'd0;
end
o TH3: Khi SFIFO không ở trạng thái đầy và trống, SFIFO sẵn sàng đọc ghi dữ liệu:
o_empty <= 1'd0;
o_full <= 1'd0;
o_ready_s <= 1'd1;
o_valid_m <= 1'd1;
Kiểm tra SFIFO ở trạng thái gần đầy/ gần trống:
TH1: Nếu w_ptr[7:0] < r_ptr[7:0]:
o So sánh số ô trống còn lại trong SFIFO ( = r_ptr[7:0] - w_ptr[7:0]) với i_almostfull_lvl và i_almostempty_lvl để đưa ra trạng thái của SFIFO:
- (r_ptr[7:0] - w_ptr[7:0]) <= i_almostfull_lvl => SFIFO gần đầy
- (r_ptr[7:0] - w_ptr[7:0]) >= i_almostempty_lvl => SFIFO gần trống
if(w_ptr[7:0]<r_ptr[7:0])
begin
/* SFIFO almost full */
if((r_ptr[7:0]-w_ptr[7:0])<= i_almostfull_lvl)
begin
o_almostfull <= 1'd1;
o_almostempty <= 1'd0;
end
/* SFIFO almost empty */
else if((r_ptr[7:0]-w_ptr[7:0]) >= i_almostempty_lvl)
begin
o_almostfull <= 1'd0;
Trang 15o_almostempty <= 1'd1;
end
else
begin
o_almostfull <= 1'd0;
o_almostempty <= 1'd0;
end
end
TH2/ Nếu w_ptr[7:0] > r_ptr[7:0]:
o So sánh số ô trống còn lại trong SFIFO ( = FIFO_DEPTH – ( r_ptr[7:0] + w_ptr[7:0])) với i_almostfull_lvl và i_almostempty_lvl để đưa ra trạng thái của SFIFO
- FIFO_DEPTH - (r_ptr[7:0] + w_ptr[7:0]) <= i_almostfull_lvl => SFIFO gần đầy
- FIFO_DEPTH - (r_ptr[7:0] + w_ptr[7:0]) >= i_almostempty_lvl => SFIFO gần trống
else
begin
/* SFIFO almost full */
if((FIFO_DEPTH-(w_ptr[7:0]-r_ptr[7:0])) <= i_almostfull_lvl) begin
o_almostfull <= 1'd1;
o_almostempty <= 1'd0;
end
/* SFIFO almost empty */
else if((FIFO_DEPTH -(w_ptr[7:0]-r_ptr[7:0])) >=
i_almostempty_lvl)
begin
o_almostfull <= 1'd0;
o_almostempty <= 1'd1;
end
else
begin
o_almostfull <= 1'd0;
o_almostempty <= 1'd0;
end
Trang 16end
Bước 3(write_data và read_data): Đọc/ghi dữ liệu dựa vào yêu cầu đầu vào và trạng
thái của FIFO thu được ở bước 2
1/ Ghi dữ liệu vào SFIFO khi i_valid_s và o_ready_s đều ở mức cao:
if (i_valid_s && o_ready_s)
begin
rg_data[w_ptr[7:0]] = i_datain;
end
2/ Đọc dữ liệu vào SFIFO khi i_ready_m và o_valid_m đều ở mức cao:
else if (i_ready_m && o_valid_m)
begin
o_dataout = rg_data[r_ptr[7:0]];
end
Trang 17CHƯƠNG IV KẾT QUẢ MÔ PHỎNG
4.1 Thiết lập trạng thái sau đó yêu cầu ghi
Figure 6 Mô phỏng 1 yêu cầu ghi
Khi có tín hiệu reset: 2 con trỏ đọc ghi set về 0
Tại xung clock 1: SFIFO ở trạng thái trống
Yêu cầu ghi tín hiệu vào thời điểm sườn âm của xung clock thứ 1 nên khi có tín hiệu xung clock t2: tăng con trỏ ghi lên 1
Vì trạng thái được xét dựa vào 2 con trỏ đọc ghi nên đến xung clock t3: SFIFO
ở trạng thái gần đầy
4.2 Thiết lập trạng thái sau đó yêu cầu đọc
Figure 7 Mô phỏng 1 yêu cầu đọc
Khi có tín hiệu reset: 2 con trỏ đọc ghi set về 0
Tại xung clock 1: SFIFO ở trạng thái trống
Trang 18 Yêu cầu đọc tín hiệu vào thời điểm sườn âm của xung clock thứ 1 nên khi có tín hiệu xung clock t2: vì SFIFO đang ở trạng thái trống các con trỏ giữ nguyên
vị trí, dữ liệu đọc ra không xác định và SFIFO vẫn ở trạng thái trống
4.3 Thiết lập trạng thái sau đó 2 yêu cầu ghi
Figure 8 Mô phỏng 2 yêu cầu ghi
Khi có tín hiệu reset: 2 con trỏ đọc ghi set về 0
Tại xung clock 1: SFIFO ở trạng thái trống
Yêu cầu ghi thứ 1 vào thời điểm tín hiệu sườn âm của xung clock thứ 1 nên khi
có tín hiệu xung clock t2: tăng con trỏ ghi lên 1 Tại sườn âm của chu kì thứ 2 tiếp tục yêu cầu đọc
Vì trạng thái được xét dựa vào 2 con trỏ đọc ghi nên đến xung clock t3: SFIFO
ở trạng thái gần đầy đồng thời tại sườn âm của chu kì thứ 3 yêu cầu ghi lần thứ
2
Bắt đầu xung clock t4 con trỏ ghi tiếp tục tăng lên 1, SFIFO vẫn ở trạng thái gần trống
Trang 194.4 Thiết lập trạng thái sau đó 1 yêu cầu ghi và 1 yêu cầu đọc
Figure 9 Mô phỏng 1 yêu cầu ghi và 1 yêu cầu đọc
Khi có tín hiệu reset: 2 con trỏ đọc ghi set về 0
Tại xung clock 1: SFIFO ở trạng thái trống
Yêu cầu ghi thứ 1 vào thời điểm tín hiệu sườn âm của xung clock thứ 1 nên khi
có tín hiệu xung clock t2: tăng con trỏ ghi lên 1
Vì trạng thái được xét dựa vào 2 con trỏ đọc ghi nên đến xung clock t3: SFIFO
ở trạng thái gần đầy
Bắt đầu xung clock t4 con trỏ đọc tăng lên 1, dữ liệu được đọc ra, SFIFO vẫn ở trạng thái gần trống
Bắt đầu chu kì t5 SFIFO quay về trạng thái trống