Copyright©byNXT Trang1
HƯỚNG DẪN THIẾT KẾ BỘ NHỚ ĐƠN GIẢN
(Bài tập về nhà của thầy Thuận)
NỘI DUNG
DANH SÁCH HÌNH 2
1. Đề bài 3
2. Phân tích 3
2.1 Các bước thực hiện 3
2.1.1 Tạo project tên xxx trên Quartus 4
2.1.2 Tạo nhân phần cứng nios trên SOPC 5
2.1.3 Bổ sung vào project xxx trên Quartus 8
2.1.4 Tạo file xxxx code C trên Nios 8
2.1.5 Test hệ thống trên board DE2 10
2.1.6 Mô phỏng h
ệ thống trên Modelsim 11
2.2 Code 17
2.2.1 Code memoryDesign 17
2.2.2 Code C Nios 18
2.2.3 Code mô phỏng 18
Copyright©byNXT Trang2
DANH SÁCH HÌNH
Hình 1. 1 – Sơ đồ khối memory 3
Hình 2. 1 – Các thư mục và tập tin chính 4
Hình 2. 2 – Module memory 4
Hình 2. 3 – Set Top-Level Entity 5
Hình 2. 4 – Các components được chọn trong SOPC 5
Hình 2. 5 – Thiết lập Reset Vector và Exception Vector 5
Hình 2. 6 – Tự động hiệu chỉnh địa chỉ base 6
Hình 2. 7 – Cách add component tự tạo 6
Hình 2. 8 – Kiểm tra add thành công hay chưa 6
Hình 2. 9 – Đồng bộ các tín hi
ệu 7
Hình 2. 10 – Add thành công component tự tạo 7
Hình 2. 11 – Generate hệ thống 7
Hình 2. 12 – Tạo file Top-Level Entity 8
Hình 2. 13 – Mở Nios II IDE 8
Hình 2. 14 – Tạo project mới trong Nios II 9
Hình 2. 15 – Kiểm tra nội dung các thư viện 9
Hình 2. 16 – Kiểm tra địa chỉ 10
Hình 2. 17 – Tạo code C 10
Hình 2. 18 – Nạp phần cứng xuống DE2 11
Hình 2. 19 – Nạp phần mềm xuống DE2 11
Hình 2. 20 – Tạo project mới trong Modelsim 12
Hình 2. 21 – Add files vào project 12
Hình 2. 22 – Tạo file mô phỏng 13
Hình 2. 23 – Lệnh vsim 13
Hình 2. 24 – Mở cửa sổ dạng sóng 14
Hình 2. 25 – Add tín hiệu cần quan sát 14
Hình 2. 26 – Chuyển sang Hex 14
Hình 2. 27 – Lưu dạng sóng 15
Hình 2. 28 – Chạy mô phỏng 15
Hình 2. 29 – Quan sát dạng song mô phỏng 15
Hình 2. 30 – So sánh nội dung memory giữa Nios và Modelsim 16
Hình 2. 31 - So sánh nội dung onchip_mem giữa Nios và Modelsim 17
Hình 3. 1 – Code verilog thiết kế 17
Hình 3. 2 – Code C viết trong Nios II 18
Hình 3. 3 – Địa chỉ vật lí và địa chỉ logic 18
Hình 3. 4 – Code mô phỏng trên Modelsim 19
Copyright©byNXT Trang3
1. Đề bài
¾ Thiết kế memory 4x32 bits, có các tín hiệu
• clk (CLOCK_50)
• cs (chip_select)
• re (read_enable)
• we (write_enable)
• addr[1:0] (address)
• data_in[31:0]
• data_out[31:0]
Hình 1. 1 – Sơ đồ khối memory
¾ Lưu ý: Một trong các công cụ hiệu quả nhất để vẽ sơ đồ khối là Microsoft Visio 2007
2. Phân tích
2.1 Các bước thực hiện
¾ Một project hoàn chỉnh sẽ có các thư mục và tập tin chính sau (xem hình 2. 1)
9 Thư mục nios_sim chứa project mô phỏng – tool Modelsim
9 Thư mục software chứa project code C – tool Nios
9 File xxx.sof chứa RTL down xuống board DE2
9 File onchip_mem.hex chứa nội dung của code C sau khi biên dịch xong
9 File cpu.vo (file này rất quan trọng)
9 Các file verilog (.v)
¾ Lưu ý: đường dẫn cài đặt các tools của Altera và các bài tập phải không chứa khoảng
trắng, nếu có chứa khoảng trắng thì khi biên dịch trên Nios sẽ có báo lỗi
Ví dụ:
Sai Æ E:\XT Exercises\Verilog VHDL\SampleCode\memoryDesign\ (đường dẫn
chứa bài tập có khoảng trắng)
OK Æ E:\XT_Exercises\Verilog_VHDL\SampleCode\memoryDesign\
Tương tự, khi cài đặt các tools Altera, tốt nhất nên để đường dẫn mặc định của nó là
C:\altera\72 và C:\altera\Modeltech_6.2f
Copyright©byNXT Trang4
T
Hình 2. 1 – Các thư mục và tập tin chính
2.1.1 Tạo project tên xxx trên Quartus
9 Sau khi tạo xong, mình sẽ viết code Verilog để tạo module memory (chi tiết code
sẽ nói ở mục 3)
Hình 2. 2 – Module memory
9 Set file memoryDesign.v này là top-level entity để build thử xem còn lỗi hay
không. Vào Files Æ chuột phải vào memoryDesign.v Æ chọn Set as Top-Level
Entity
Copyright©byNXT Trang5
Hình 2. 3 – Set Top-Level Entity
9 Sau đó build thử. Nếu hết lỗi thì sang bước 2.1.2
2.1.2 Tạo nhân phần cứng nios trên SOPC
Mở SOPC, tạo project tên nios, sau đó tạo nhân phần cứng.
Hình 2. 4 – Các components được chọn trong SOPC
9 Nhớ nhấp chuột phải vào cpu, chọn Edit, sau đó chọn Reset Vector và Exception
Vector là onchip_mem
Hình 2. 5 – Thiết lập Reset Vector và Exception Vector
9 Tiếp tục chuột phải vào cpu, chọn Auto-Assign Base Addresses
Copyright©byNXT Trang6
Hình 2. 6 – Tự động hiệu chỉnh địa chỉ base
9 Kế tiếp, add file memoryDesign.v mình viết vào
Hình 2. 7 – Cách add component tự tạo
9 Chọn tiếp Signal
Hình 2. 8 – Kiểm tra add thành công hay chưa
Copyright©byNXT Trang7
9 Gán các tín hiệu tương ứng giữa module memoryDesign và Avalon bus (các bạn
có thể tìm hiểu lí do tại sao gán như vậy trong sách Avalon Bus Specification)
Hình 2. 9 – Đồng bộ các tín hiệu
của component tự tạo và Avalon Bus
9 Sau khi hết lỗi, nhấn Finish, ta được component mới trong SOPC
Hình 2. 10 – Add thành công component tự tạo
9 Chuột phải vào cpu, chọn Auto-Assign Base Addresses lần nữa. Sau đó, qua
System Generation thực hiện các bước sau. Cuối cùng Generate
Hình 2. 11 – Generate hệ thống
Copyright©byNXT Trang8
2.1.3 Bổ sung vào project xxx trên Quartus
9 Tạo file xxx.v
9 Vào file nios.v (tên file project trong SOPC), tìm module nios (…), copy vào
xxx.v
Hình 2. 12 – Tạo file Top-Level Entity
9 Set lại Top-Level Entity cho file xxx.v, sau đó build project
2.1.4 Tạo file xxxx code C trên Nios
9 Trong SOPC, nhấp vào Nios
Hình 2. 13 – Mở Nios II IDE
9 Tạo project xxxx theo các bước sau
Copyright©byNXT Trang9
Hình 2. 14 – Tạo project mới trong Nios II
9 Sau đó xóa nội dung file hello_world.c, chỉ để nội dung rỗng như hình dưới và
build (nhấn Ctrl+B).
Hình 2. 15 – Kiểm tra nội dung các thư viện
9 Sau khi build xong, vào file system.h để tìm địa chỉ các component. Khi cần dùng
component nào, ta chỉ quan tâm đến tên địa chỉ của component đó. Ví dụ khi cần
gọi địa chỉ base của memoryDesign (0x00011000), ta chỉ cần gọi tên
MEMORYDESIGN_INST_BASE
Copyright©byNXT Trang10
Hình 2. 16 – Kiểm tra địa chỉ
9 Kế tiếp, sửa nội dung file hello_world.c thành như sau và build lại lần nữa
Hình 2. 17 – Tạo code C
9 Sau khi biên dịch xong, Nios sẽ tạo ra 3 file
o onchip_mem.hex (đã đề cập ở đầu mục 2)
o onchip_mem.dat
o onchip_mem.sym
Î Trong đó, 2 file cuối chứa trong thư mục nios_sim phục vụ cho việc mô
phỏng
2.1.5 Test hệ thống trên board DE2
9 Đầu tiên, vào Quartus để nạp phần cứng
Copyright©byNXT Trang11
Hình 2. 18 – Nạp phần cứng xuống DE2
9 Sau đó vào Nios để nạp phần mềm
Hình 2. 19 – Nạp phần mềm xuống DE2
2.1.6 Mô phỏng hệ thống trên Modelsim
9 Mở công cụ Modelsim
9 Đặt tên project là xxxx và lưu trong /nios_sim
Copyright©byNXT Trang12
Hình 2. 20 – Tạo project mới trong Modelsim
9 Copy các file trong thư mục project Quartus vào project Modelsim, các bạn lưu ý
là không chọn file cpu.v
Hình 2. 21 – Add files vào project
9 Tạo file mô phỏng sim_xxx.v, sau đó compile project
Copyright©byNXT Trang13
Hình 2. 22 – Tạo file mô phỏng
9 Trong cửa sổ Transcript, gõ lệnh vsim – novopt sim_xxx (tên file mô phỏng)
Hình 2. 23 – Lệnh vsim
9 Sau đó gõ view wave
Copyright©byNXT Trang14
Hình 2. 24 – Mở cửa sổ dạng sóng
9 Add các tín hiệu vào cửa sổ wave
Hình 2. 25 – Add tín hiệu cần quan sát
9 Chọn kiểu hex cho dễ quan sát dạng sóng
Hình 2. 26 – Chuyển sang Hex
9 Lưu lại các tín hiệu add vào cửa sổ wave để sử dụng cho các lần sau
Copyright©byNXT Trang15
Hình 2. 27 – Lưu dạng sóng
9 Tiến hành mô phỏng: đặt thời gian mô phỏng là 500 ns, chọn Restart (bên trái),
sau đó chọn Run (bên phải)
Hình 2. 28 – Chạy mô phỏng
9 Quan sát dạng sóng mô phỏng
Hình 2. 29 – Quan sát dạng song mô phỏng
9 Quan sát giá trị memory thay đổi (sau khi mô phỏng xong), ta thấy kết quả giống
hệt đoạn code C trong nios
Copyright©byNXT Trang16
Hình 2. 30 –
So sánh nội dung memory giữa Nios và Modelsim
9 Ngoài ra, ta còn có thể quan sát được nội dung onchip_mem trong Modelsim
Nội dung onchip_mem trong Modelsim
Copyright©byNXT Trang17
Nội dung onchip_mem trong Nios
Hình 2. 31 -
So sánh nội dung onchip_mem giữa Nios và Modelsim
2.2 Code
2.2.1 Code memoryDesign
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
module memoryDesign (
// input
addr,
re,
data_in,
we,
clk,
cs,
// output
data_out
);
input we,
re,
clk,
cs;
input [1:0] addr;
input [31:0] data_in;
output [31:0] data_out;
reg [31:0] memory [0:3];
reg [31:0] data_out;
always @(posedge clk)
begin
memory[addr] <= (cs & we & ~re) ? data_in : memory[addr];
data_out <= (cs & ~we & re) ? memory[addr] : data_out;
end
endmodule
Hình 3. 1 – Code verilog thiết kế
9 Dòng 23 – Cấu trúc khai báo memory:
Copyright©byNXT Trang18
reg [DATA_WIDTH-1:0] <tên memory> [0:ADDR_WIDTH-1]
Trong đó:
DATA_WIDTH: số đường dữ liệu
ADDR_WIDTH: số đường địa chỉ
Ví dụ: cần memory tên xxx có 16 đường data, 18 đường địa chỉ (SRAM trên
board DE2), ta khai báo
reg [17:0] xxx [0:15]
9 Memory nhận giá trị ghi vào khi cs (chọn chip), we (cho phép ghi vào) và ~re
(không cho phép đọc ra)
9 Memory đọc giá trị ra khi cs (chọn chip), ~we (không cho phép ghi vào) và re
(cho phép đọc ra)
2.2.2 Code C Nios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <system.h>
int main()
{
// khai bao
volatile int * ptr = (int *) MEMORYDESIGN_INST_BASE;
*ptr = 0x99;
*(ptr + 0x1) = 0x10;
*(ptr + 0x2) = 0x23;
*(ptr + 0x3) = 0x567;
return 0;
}
Hình 3. 2 – Code C viết trong Nios II
9 Dòng 7 – ptr là biến con trỏ chỉ tới vùng nhớ base của memoryDesign
(0x00011000). MEMORYDESIGN_INST_BASE là tên gợi nhớ được tạo ra trong
system.h
9 Mỗi lần ptr tăng lên 1 tương ứng với việc tăng offset lên 4 đối với phần cứng
Phần cứng Bộ nhớ Phần mềm
offset = 0x0
0x0 0x1 0x2 0x3
ptr
offset = 0x4
0x4 0x5 0x6 0x7
ptr+1
offset = 0x8
0x8 0x9 0xa 0xb
ptr+2
offset = 0xc
0xc 0xd 0xe 0xf
ptr+3
Hình 3. 3 – Địa chỉ vật lí và địa chỉ logic
2.2.3 Code mô phỏng
1
2
3
4
5
6
module sim_xxx ();
reg clk;
reg reset_n;
xxx XXX(
Copyright©byNXT Trang19
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Inputs
clk,
reset_n
);
initial
clk = 1’b0;
always
#10 clk <= ~clk;
initial
begin
reset_n <= 0;
#200 reset_n <= 1;
end
Hình 3. 4 – Code mô phỏng trên Modelsim
9 Dòng 3, 4: khai báo reg cho clk và reset_n (bắt buộc)
9 Dòng 13 Æ 16: mô phỏng xung clock. Ban đầu, clk = 0, nhưng sau 10 đơn vị thời
gian, clk đảo giá trị (lên xuống)
9 Dòng 18 Æ 22: mô phỏng reset_n. Ban đầu reset_n = 0 (tác động mức thấp),
nhưng sau 200 đơn vị thời gian, reset_n bật lên = 1 (ngưng tác động)