123doc Bao Cao Do An Chuyen Nganh Thiet Ke Bo Truyen Nhan Uartva Bit Nap Tren Kit Fpga

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 47

Đồ án chuyên ngành

ĐẠI HỌC BÁCH KHOA ĐÀ NẴNG


KHOA ĐIỆN TỬ-VIỄN THÔNG

BÁO CÁO ĐỒ ÁN CHUYÊN NGHÀNH

ĐỀ TÀI:

THIẾT KẾ BỘ TRUYỀN NHẬN UART 8 BIT NẠP TRÊN KIT FPGA

Sinh viên thực hiện : Đỗ Tiến Thành


Lớp : 09DT2
Giáo viên hướng dẫn: ThS. Võ Tuấn Minh

Đà Nẵng, 2014

LỜI CAM ĐOAN


Tôi xin cam đoan nội dung của đồ án này không phải là bản sao chép của bất cứ
đồ án nào đã có từ trước. Nếu vi phạm tôi xin chịu mọi hình thức kỷ luật của Khoa.
Sinh viên thực hiện
Đỗ Tiến Thành

NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN


.............................................................................................................................................
.............................................................................................................................................

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 1


Đồ án chuyên ngành

.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................

Đà Nẵng, ngày tháng 1 năm 2014


GIÁO VIÊN HƯỚNG DẪN
(Ký tên)

LỜI MỞ ĐẦU
Ngày nay, trong các hệ thống truyền dữ liệu có hai cách đưa tín hiệu lên đường
truyền: nối tiếp và song song. Cách truyền song song thường được truyền trên một
khoảng cách ngắn, ví dụ giữa các thiết bị trong cùng một phòng như từ máy tính sang
máy in. Cách truyền nối tiếp thường được thực hiện khi khoảng cách truyền khá xa.
Ngoài ra, trong cách truyền nối tiếp, dựa vào cách thực hiện sự đồng bộ giữa nơi
phát và thu ta có hai chế độ hoạt động: đồng bộvà bất đồng bộ. Trong chế độ bất đồng
bộ, xung đồng hồ được tạo ra một cách riêng rẻ ở máy phát và máy thu dựavào tần số
danh định tương ứng với vận tốc truyền (bit rate hoặc baud rate). Trong chế độ đồng
bộ, nơi phát có thể gửi xung đồng hồ tới nơi thu theo một kênh truyền song song với
kênh truyền dữ liệu hoặc nơi thu tự tạo ra xung đồng hồ bằng cách tách tín hiệu thời
gian từ dòng dữ liệu.
Trong đồ án này, tôi xin được trình bày về chuẩn truyền thông nối tiếp không
đồng bộ UART (Universal Asynchronous Receiver Transmitter). Vì truyền thông nối
tiếp có các ưu điểm sau:
- Khoảng cách truyền xa hơn truyền song song.
- Sốdây kết nối ít.
- Có thể truyền không dây dùng hồng ngoại.
- Có thể ghép nối với vi điều khiển hay PLC (Programmable Logic Device).
- Cho phép nối mạng.
- Có thể tháo lắp trong lúc máy tính đang làm việc.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 2


Đồ án chuyên ngành

MỤC LỤC

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 3


Đồ án chuyên ngành

Chương 1 MÔ TẢ TỔNG QUAN VỀ GIAO TIẾP UART

Truyền nối tiếp (serial transmission) các thông tin số hay bit thông qua một dây
đơn (single wire) hay một vật liệu trung gian nào đó thì tiết kiệm chi phí hơn nhiều so
với truyền song song dùng nhiều dây cùng một lúc. Truyền dữ liệu dùng UART có thể
thực hiện theo phương thức song công (full duplex) tức là việc gửi và nhận thực hiện
cùng một lúc, hay bán song công (half duplex), tức là các thiết bị thay phiên nhau phát
và nhận.
Bộ truyền UART phát từng bit trong byte dữ liệu một cách tuần tự. Bộ thu
UART chịu trách nhiệm lắp ghép các bit này lại thành các byte hoàn chỉnh. Mỗi UART
gồm có hai thanh ghi dịch, được dùng làm thành phần cơ bản trong việc chuyển giữa
nối tiếp sang song song và ngược lại.

1.1 Đặc trưng khung truyền

Hình 1.1 Định dạng khung truyền cơ bản


Mỗi ký tự được gửi sau một bit khởi tạo gọi là start bit ở mức logic thấp, số các
bit dữ liệu thường là 7 hay 8 đôi khi là 5, cũng có thể có thêm bit kiểm tra chẵn lẻ
(parity bit) và một hay nhiều stop bit ở mức logic cao. Start bit sẽ báo hiệu cho bộ thu
một ký tự mới đang được gửi đi (hay nói đúng hơn là đang đến). Tiếp theo sau start bit,
bộ thu sẽ nhận từ 5 đến 8 bit dữ liệu, phụ thuộc vào tùy vào cấu hình sử dụng. Theo sau
bit dữ liệu có thể là một bit kiểm tra chẵn lẻ và cuối cùng phải có ít nhất một stop bit ở
mức cao báo hiệu quá trình truyền một ký tự đã kết thúc. Bộ thu sẽ tiến hành xử lý các
bit đã nhận và chờ start bit để nhận byte dữ liệu tiếp theo. Bởi vì start bit luôn là mức
logic 0 trong khi stop bit ở mức logic 1 do đó không gây ra hiểu lầm giữa hai bit liên
tiếp được truyền.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 4


Đồ án chuyên ngành

1.1.1 Bộ nhận dữ liệu

Hình 1.2 Bộ nhận dữ liệu


Tất cả các hoạt động của phần cứng UART đều được đồng bộ hay điều khiển
bởi một tín hiệu xung đồng hồ (clock) chạy với tốc độ bằng một số nhân nguyên nào
đó của tốc độ dữ liệu, ví dụ việc truyền hay nhận một bit dữ liệu sẽ kéo dài trong vòng
16 xung clock chẳng hạn. Bộ thu sẽ kiểm tra trạng thái của tín hiệu được gửi đến tại
mỗi xung đồng hồ (theo cạnh lên hay cạnh xuống) để xem khi nào xảy ra start bit. Nếu
thời gian của một start bit kéo dài ít nhất là một nửa thời gian của một bit dữ liệu, thì
nó được xem là hợp lệ và báo hiệu việc truyền một ký tự mới đang xảy ra.
Nếu Start bit không đáp ứng yêu cầu, xung này xem như là xung sai (spurious
pulse) và bị bỏ qua. Thời gian truyền một bit được giám sát và trạng thái của đường
truyền được lấy mẫu tại điểm giữa mỗi bit. Đồng thời tạo ra xung clock (cạnh lên hay
xuống) cho phép dịch dữ liệu vào thanh ghi dịch (shift register). Sau khi kết thúc một
khung dữ liệu, nội dung của thanh ghi dịch đã được chuẩn bị sẵn sàng ở dạng song
song để gửi tới bộ xử lý dữ liệu trong hệ thống. UART lúc này sẽ đặt một cờ (flag) để
báo hiệu dữ liệu mới nhận đã sẵn sàng, hoặc nó cũng có thể tạo ra một ngắt (interrupt)
để yêu cầu bộ xử lý nhận dữ liệu vừa nhận được.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 5


Đồ án chuyên ngành

Trong một vài kiểu UART, một bộ nhớ đệm nhỏ kiểu FIFO (First In First Out)
được đặt giữa thanh ghi dịch của bộ thu và bộ xử lý, việc làm này cho phép bộ xử lý có
nhiều thời gian hơn để thao tác trên dữ liệu nhằm hạn chế việc mất dữ liệu trong trường
hợp tốc độ xử lý của bộ xử lý chậm hơn quá trình nhận dữ liệu.

1.1.2 Bộ phát dữ liệu

Hình 1.3 Bộ phát dữ liệu


Một bộ nhớ đệm nhỏ kiểu FIFO (First In First Out) được đặt giữa thanh ghi dịch
của bộ phát và bộ xử lý giống như bên bộ nhận dữ liệu.
Ngay sau khi dữ liệu được gửi vào thanh ghi dịch thì phần cứng UART sẽ tạo ra
start bit, và dịch số bit dữ liệu yêu cầu ra ngoài đường truyền, tạo ra và ghép bit kiểm
tra chẵn lẻ vào cuối byte dữ liệu truyền nếu có, đồng thời chèn luôn cả stop bit.
Bởi việc truyền một khung dữ liệu có thể tương đối lâu so với tốc độ của bộ xử
lý, nên UART sẽ duy trì một cờ báo hiệu trạng thái bận để hệ thống không ghi byte dữ
liệu mới vào cho đến khi dữ liệu tại đã được truyền xong, việc báo hiệu này có thể thực
hiện thông qua một ngắt.

1.1.3 Tốc độ Baud


Baud rate là đại lượng xác định tốc độ phát bit dữ liệu trong truyền bất đồng bộ,
đơn vị là bps (bit per second).

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 6


Đồ án chuyên ngành

Bình thường, baud rate dùng để đo số bit thực sự được gửi trên kênh truyền chứ
không phải là lượng dữ liệu thực sự được gửi từ máy này sang máy khác.Việc tính
baud rate còn gồm cả những start bit, stop bit hay bit kiểm tra chẵn lẻ được tạo ra bởi
UART gửi nhưng bị loại bỏ bởi UART thu. Điều này có nghĩa rằng những từ dữ liệu có
độ dài 7 bit phải cần đến ít nhất 9 bit hoặc 10 bit (nếu có bit kiểm tra chẵn lẻ) để truyền
. Do đó, một modem có khả năng phát 300 bit trên giây từ nơi này sang nơi khác thì có
thể truyền 30 khung dữ liệu 7 bit nếu có dùng bit kiểm tra chẵn lẻ, 1 stop bit và 1 start
bit. Như vậy, số bit dữ liệu thực sự trong một giây của modem là 210 bit, số bit được
chèn thêm là 90 bit.

Chương 2 PHÂN TÍCH TỔNG QUAN VÀ THIẾT KẾ CÁC KHỐI


CHỨC NĂNG CỦA BỘ UART

Thiết kế một bộ truyền bất đồng bộ theo chuẩn UART thử nghiệm trên KIT FPGA. Cụ
thể, thiết kế bộ truyền nối tiếp theo chuẩn UART (Universal Asynchronous Receiver

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 7


Đồ án chuyên ngành

Transmitter) có các đặc điểm như sau: Cấu hình được tốc độ BAUD (tốc độ truyền dữ
liệu) theo công thức :

Trong đó: fbaud là tốc độ BAUD cần cấu hình, BRG là thanh ghi thiết lập tốc
độ baud có độ rộng 8 bit, fosc là tần số xung clock trong mạch.
Khung dữ liệu gồm: 1 start bit, 8 bit dữ liệu, 1 stop bit 8 bit dữ liệu cần truyền
có giá trị từ H00 đến HFF sẽ được chuyển đổi dạng mã ASCII trước khi truyền đi. Ví
dụ: Dữ liệu cần truyền là: H85 sẽ được đổi thành H38 (là mã ASCII của số 8) và
H35(là mã ASCII của số 5). Sau đó hai giá trị H38 và H35 sẽ được truyền đi qua
đường truyền nối tiếp.
2.1 Những yêu cầu của thiết kế :
- Tốc độ baud được chọn cố định trước khi tổng hợp thông qua biến BRG.
- Khung dữ liệu gồm 1 bit start, 8 bit dữ liệu, 1 bit stop.
- Truyền nhận song công (Dữ liệu được truyền đồng thời theo 2 hướng).

Hình 2.1 Truyền nhận song công

 Sơ đồ khối tổng quát: Thiết kế có 4 khối cơ bản như sau

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 8


Đồ án chuyên ngành

Lõi UART-FPGA gồm các khối chính như sau:


Khối truyền nối tiếp (TRANSMITTER): Nhận dữ liệu từ ngõ vào data_in và
phát đi dựa trên tốc độ baud đã được tính trong khối BAUD RATE.
Khối nhận dữ liệu nối tiếp (RECEIVER): Phát hiện, lấy mẫu và lưu trữ dữ liệu
nhận nối tiếp từ chân RX của UART ngoài thông qua tín hiệu uart_rx với tốc độ baud

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 9


Đồ án chuyên ngành

đã được tính ở khối BAUD RATE. Khối này có thêm bộ đệm FIFO 8 tầng để lưu tạm
dữ liệu và tránh mất mát dữ liệu.
Khối tạo tốc độ truyền (BAUD RATE): Dựa vào thông số tốc độ truyền được
cấu hình, khối này sẽ tính toán và tạo xung nhịp truyền dữ liệu khi phát và lấy mẫu dữ
liệu khi nhận.
Khối điều khiển và hiển thị (CONTROL DISPLAY): tiếp nhận tín hiệu điều
khiển tx_in để tạo ra tín hiệu cho phép khối truyền dữ liệu của UART hoạt động. Đồng
thời nhận các giá trị dữ liệu từ khối nhận dữ liệu của UART để giải mã LED 7 đoạn và
hiển thị kết quả.
Bốn khối trên sẽ được kết nối với nhau thành một thiết kế hoàn chỉnh ở file
core_uart.

2.2 Sơ đồ tín hiệu vào ra và sơ đồ chi tiết các khối thiết kế


2.2.1 Khối TRANSMITTER
*Sơ đồ tín hiệu giao tiếp

*Chức năng các tín hiệu:


Tên tín hiệu Chiều Mô tả
clk input Clock đồng bộ.
reset_n input Reset đồng bộ,tích cực mức thấp.
uart_en input Cho phép hoạt động,tích cực mức cao.
tx_enable input Cho phép bắt đầu truyền dữ liệu.
data_in[7:0] input Bus dữ liệu truyền.
brg_tx_clken input Tín hiệu xác định vị trí dịch dữ liệu
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 10
Đồ án chuyên ngành

khi bộ truyền hoạt động.


uart_tx output Ngõ ra nối tiếp của dữ liệu truyền ,gán
ra cổng RS232.

*Máy trạng thái của bộ truyền dữ liệu:

*Mô tả các trạng thái :


Trạng thái hiện Mô tả Điều kiện Trạng thái kế
tại tiếp
Trạng thái rảnh
IDLE tx_enable LOAD_TXS
khi bộ truyền
không hoạt động.
Trạng thái nạp dữ
LOAD_TXS SHIFT_DATA
liệu vào thanh ghi
dịch.
Trạng thái truyền brg_tx_clken &

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 11


Đồ án chuyên ngành

SHIFT_DATA từng bit dữ liệu. tx_count = IDLE


“1001”
*Sơ đồ chi tiết khối TRANSMITTER:

Bộ cộng để tăng giá trị bộ đếm lên, bộ MUX để chọn các ngõ vào khác nhau
phụ thuộc vào giá trị của 2 tín hiệu set_tx_count và shift_en như hình vẽ, Flip Flop là
DFF để tạo thanh ghi lưu giá trị đếm. Bộ so sánh bằng để quyết định giá trị của tín hiệu
set_tx_count.
Bộ đếm để tạo tín hiệu tx_count[3:0], cứ khi nào dịch được 1 bit trong thanh ghi
tsr[9:0] thì giá trị bộ đếm tăng lên 1 .Khi tx_count = “1001” thì dữ liệu đã được truyền
xong.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 12


Đồ án chuyên ngành

Khối gồm các cổng logic: cổng AND4 để tạo tín hiệu shift_en cho phép dịch,
các bộ so sánh để tạo các tín hiệu tương ứng, bộ MUX để chọn các tín hiệu ngõ vào
dựa vào 2 tín hiệu shift_en và load_data, các DFF để tạo các thanh ghi tsr[9:0] vào tín
hiệu uart_tx.
Khối tạo thanh ghi dịch tsr 10 bit {gồm 1 bit start, 8 bit data_in, 1 bit stop) , khi
có xung brg_tx_clken và đủ các điều kiện như mô tả ở máy trạng thái thì dữ liệu trong
thanh ghi sẽ được dịch đến ngõ ra nối tiếp uart_tx của tín hiệu truyền cho tới khi truyền
hết 8 bit data_in.

2.2.2 Khối RECEIVER


*sơ đồ tín hiệu giao tiếp

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 13


Đồ án chuyên ngành

*Chức năng các tín hiệu:


Tên tín hiệu Chiều Mô tả
clk input Clock đồng bộ.
reset_n input Reset đồng bộ,tích cực mức thấp.
uart_en input Cho phép hoạt động,tích cực mức
cao.
brg_rx_clken input Xung cho phép xác định vị trí lấy
mẫu dữ liệu.
uart_rx input Đường nhận dữ liệu truyền nối
tiếp ,gán ra cổng RS232.
fifo_rd input Cho phép đọc dữ liệu từ FIFO ra.
rc_data[7:0] output Dữ liệu nhận được của khối
RECEIVER.
fifo_full output Cờ báo FIFO đầy,không ghi được
dữ liệu vào FIFO nữa.
fifo_empty output Cờ báo FIFO trống,có thể ghi được
dữ liệu vào FIFO.

*Máy trạng thái của bộ nhận dữ liệu:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 14


Đồ án chuyên ngành

*Mô tả các trạng thái :


Trạng thái hiện tại Mô tả Điều kiện Trạng thái kế tiếp
Trạng thái rảnh
IDLE tx_en CHECK_START_BIT
khi bộ nhận
không hoạt
động.
Trạng thái lấy samp_count =“0111” IDLE
CHECK_START_BIT
mẫu và kiểm tra & uart_rx_sync=”1”
samp_count =“0111” RECEIVE_DATA
bit start.
& uart_rx_sync=”0”
Trạng thái lấy
mẫu các bit trên
RECEIVE_DATA rx_count = “1010” IDLE
đường nhận dữ
liệu nối tiếp.
*Sơ đồ chi tiết khối RECEIVER:
Mạch đếm xung lấy mẫu:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 15


Đồ án chuyên ngành

Mạch gồm các bộ so sánh bằng để tạo các tín hiệu tương ứng trên hình vẽ, các
cổng OR2, AND2 để tạo tín hiệu inc_samp_count, bộ MUX để chọn các ngõ vào dựa
vào 2 tín hiệu inc_samp_count và clr_samp_count, thanh ghi DFF để tạo tín hiệu
samp_count[3:0].
Giá trị bộ đếm samp_count[3:0] sẽ tăng lên 1 khi các điều kiện của bộ MUX
được thỏa mãn.
Mạch đếm số bit nhận được:

Mạch gồm các bộ so sánh bằng để tạo các tín hiệu tương ứng trên hình vẽ, cỏng
AND3 để tạo tín hiệu inc_rx_count, bộ MUX để chọn các ngõ vào dựa vào 2 tín hiệu
inc_rx_count và set_comp, thanh ghi DFF để tạo tín hiệu rx_bitcount[3:0].

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 16


Đồ án chuyên ngành

Khi nhận được 1 bit thì rx_bitcount[3:0] sẽ tăng lên 1. Khi đã nhận đủ 10 bit của
thanh ghi dịch tsr[9:0] thì bộ đếm sẽ được reset nhờ tín hiệu clr_rx_count.

Mạch tạo thanh ghi dịch bên bộ nhận:

Mạch gồm bộ MUX để chọn các ngõ vào dựa vào tín hiệu inc_rx_count, thanh
ghi DFF để tạo tín hiệu rsr[7:0]
Tạo thanh ghi dịch 8 bit rsr[7:0] để nhận 8 bit data_in từ thanh ghi dịch tsr[9:0]
bên khối truyền.Khi có tín hiệu cho phép dịch inc_rx_count thì dữ liệu trong thanh ghi
sẽ được dịch qua phải 1 bit để đưa vào FIFO nhận.

Mạch bắt cạnh tín hiệu cho phép FIFO nhận:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 17


Đồ án chuyên ngành

Việc nhấn và giữ một nút (KEY) sẽ tạo ra mức logic 1 kéo dài trong nhiều xung
clock hê thống.
Nếu ta đưa trực tiếp tín hiệu fifo_rd vào để xét điều kiện đọc FIFO thì sẽ
không chính xác và không kiểm soát được số lần đọc. Để một lần nhấn nút
tương ứng với một byte dữ liệu được đọc đi thì ta phải tạo ra tín hiệu cho phép
chỉ tích cực trong đúng một chu kỳ của xung clock hệ thống. Mạch trên đây sẽ
thực hiện điều đó.
Dạng sóng mô phỏng :

Sau 2 chu kì của tín hiệu fifo_rd thì phát hiện được cạnh của fifo_rd_enable.
FIFO 8 tầng nhận dữ liệu:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 18


Đồ án chuyên ngành

Khi FIFO chưa Full,dữ liệu từ thanh ghi rsr[7:0] sẽ được ghi vào FIFO nhờ con
trỏ cho phép ghi wptr[3:0] và tín hiệu fifo_we.
Dữ liệu đọc ra thanh ghi rc_data[7:0] chính là dữ liệu nhận được để hiển thị trên
LED 7 đoạn. Con trỏ cho phép đọc rptr[3:0] sẽ cho phép đọc dữ liệu ra từ FIFO.
Mạch tạo ra con trỏ dữ liệu wptr[3:0] và rptr[3:0] :

Khi có tín hiệu fifo_we =1 thì bộ đếm sẽ hoạt động và con trỏ wptr[3:0] sẽ tăng
lên 1.Khi có tín hiệu fifo_re =1 thì bộ đếm sẽ hoạt động và con trỏ rptr[3:0] sẽ tăng lên
1.
Mạch tạo các cờ báo trạng thái của FIFO:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 19


Đồ án chuyên ngành

Mạch gồm các cổng XOR2, AND2, bộ so sánh bằng để tạo các tín hiệu tương
ứng như hình vẽ.
Khi con trỏ wptr[2:0] = rptr[2:0] và bit có trọng số cao nhất wptr[3] khác rptr[3]
thì tín hiệu fifo_full = 1 ,cờ này báo hiệu FIFO đầy, không thể ghi thêm dữ liệu vào
FIFO.
Khi con trỏ wptr[2:0] = rptr[2:0] và bit có trọng số cao nhất wptr[3] giống
rptr[3] thì tín hiệu fifo_empty = 1 ,cờ này báo hiệu FIFO chưa đầy, có thể ghi thêm dữ
liệu vào FIFO.

2.2.3 Khối BAUD RATE


*Sơ đồ tín hiệu giao tiếp

*Chức năng các tín hiệu:


Tên tín hiệu Chiều Mô tả
clk input Clock đồng bộ.
reset_n input Reset đồng bộ .Tích cực
mức thấp.
uart_en input Cho phép hoạt động.Tích

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 20


Đồ án chuyên ngành

cực mức cao.


brg_tx_clken output Xung cho phép dịch từng
bit dữ liệu khi bộ truyền
hoạt động.
brg_rx_clken output Xung cho phép xác định
vị trí lấy mẫu dữ liệu.

Mô tả xung truyền và xung nhận :

Tốc độ baud được chọn gán trước khi tổng hợp thông qua biến BRG theo công
thức sau:

fbaud tính theo đơn vị bps, fosc là tần số xung clock .


Xung Tx cho phép bắt đầu truyền 1 bit dữ liệu(Data) bên phát, ở bên thu khi
nhận được 1 bit dữ liệu thì cũng có 1 xung Rx được lấy mẫu ở giữa bit dữ liệu .
Khoảng thời gian lấy mẫu của Tx và Rx là 16x(n+1) xung CLOCK, với n là
tham số nạp vào để cấu hình cho tốc độ Baud.
*Sơ đồ chi tiết khối BAUD RATE:
Mạch tạo xung truyền :

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 21


Đồ án chuyên ngành

Mạch gồm bộ cộng để tăng giá trị đếm lên 1, cổng AND2, các bộ MUX để chọn
các giá trị ngõ vào khác nhau, bộ so sánh bằng, thanh ghi DFF để tạo tín hiệu
tx_count[15:0].
Khi có tín hiệu uart_en = 1, thì BRG sẽ được nạp vào ,bộ đếm sẽ bắt đầu đếm từ
0 cho tới khi tx_counter[15:0] = {16x(BRG + 1) -1} thì brg_tx_clken = 1.

Mạch tạo xung nhận :

Mạch gồm bộ cộng để tăng giá trị đếm lên 1, cổng AND2, các bộ MUX để chọn
các giá trị ngõ vào khác nhau, bộ so sánh bằng, thanh ghi DFF để tạo tín hiệu
rx_count[11:0].
Khi có tín hiệu uart_en = 1, thì BRG sẽ được nạp vào ,bộ đếm sẽ bắt đầu đếm từ
0 cho tới khi rx_counter[11:0] = BRG thì brg_rx_clken = 1.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 22


Đồ án chuyên ngành

2.2.4 Khối CONTROL DISPLAY


*Sơ đồ tín hiệu giao tiếp

*Chức năng các tín hiệu:


Tên tín hiệu Chiều Mô tả
clk input Clock đồng bộ .
reset_n input Reset đồng bộ .Tích cực mức thấp.
uart_en input Cho phép hoạt động.Tích cực mức cao.
tx_in input Cho phép ghi dữ liệu từ bus data_in vào
bộ truyền.
rc_data[7:0] input Giá trị dữ liệu nhận được từ khối
RECEIVER.
tx_enable output Tín hiệu cho phép bộ truyền bắt đầu
hoạt động.
hex0[6:0] output Giá trị giải mã LED 7 đoạn của 4 bit
thấp trong Byte dữ liệu nhận được.
hex1[6:0] output Giá trị giải mã LED 7 đoạn của 4 bit cao
trong Byte dữ liệu nhận được.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 23


Đồ án chuyên ngành

uart_tx output Đường truyền dữ liệu nối tiếp bất đồng


bộ gán ra cổng RS232.

*Sơ đồ chi tiết khối CONTROL DISPLAY


Mạch giải mã LED 7 đoạn cho dữ liệu nhận hiện tại:

Chức năng: giải mã 4 bit của rc_data thành 7 bit để hiện thị trên LED 7 đoạn

Mạch tạo tín hiệu cho phép truyền :

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 24


Đồ án chuyên ngành

Việc nhấn và giữ một nút (KEY) sẽ tạo ra mức logic 1 kéo dài trong
nhiều xung clock hê thống.
Nếu ta đưa trực tiếp tín hiệu tx_in vào để xét điều kiện truyền thì sẽ
không chính xác và không kiểm soát được số lần truyền. Để một lần nhấn nút
tương ứng với một khung dữ liệu được truyền đi thì ta phải tạo ra tín hiệu cho
phép chỉ tích cực trong đúng một chu kỳ của xung clock hệ thống. Mạch trên
đây sẽ thực hiện điều đó.
Dạng sóng mô phỏng :

Sau 2 chu kì của tín hiệu tx_in thì phát hiện được cạnh của tx_enable.

Chương 3 KIỂM TRA THIẾT KẾ

3.1 Giải thích cách viết testbench mô phỏng:


Bật tín hiệu uart_en(uart_en = 1) cho phép uart hoạt động:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 25


Đồ án chuyên ngành

• Test khối Control Dislay: quan sát dạng sóng các tín hiệu vào (rc_data_hex) /ra (hex)
của bộ giải mã Led 7 đoạn xem bộ giải mã đã hoạt động đúng chưa.
• Test khối Baud Rate: ta cấu hình 1 tốc độ baud cho uart truyền nhận bằng cách gán
cho BRG 1 giá trị.ví dụ BRG = 5,sau đó ta quan sát dạng sóng xem xung
truyền(brg_tx_clken) và nhận (brg_rx_clken) có đúng với tốc độ baud mình cấu hình
không.
• Test khối Transmitter: ta thử truyền dữ liệu với các trường hợp data_in khác nhau
,việc truyền dữ liệu sẽ được cho phép bởi tín hiệu tx_in.Ta sẽ bật(tắt) tín hiệu tx_in ở
các thời điểm khác nhau.Ta sẽ quan sát dạng sóng xem thanh ghi Shift_data(tsr) đã
dịch đúng với dữ liệu muốn truyền đi hay chưa.
• Test khối Receiver: việc ghi vào FIFO sẽ được thực hiện khi FIFO chưa full và có tín
hiệu cho phép ghi fifo_we. Kiểm tra xem thanh ghi nhận dữ liệu dịch(rsr) từ khối
Transmitter có dữ liệu hay chưa.Việc đọc ra từ FIFO sẽ được cho phép bởi tín hiệu
fifo_rd và khi FIFO không empty(có dữ liệu) .vì vậy ta sẽ bật (tắt) tín hiệu fifo_rd,rồi
quan sát dạng sóng xem rc_data có nhận được đúng dữ liệu truyền đi không.

3.2 Dạng sóng chạy mô phỏng:


Dùng phần mềm Modelsim của hãng Altera để chạy testbench mô phỏng dạng
sóng để kiểm tra thiết kế ta được dạng sóng như bên dưới:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 26


Đồ án chuyên ngành

Ta sẽ phân tích cụ thể từng khối:


3.2.1 Khối Control Display:

Dữ liệu trên hex1,hex0 để hiển thị lần lượt byte cao và byte thấp của dữ liệu
nhận được rc_data,tín hiệu rc_data_hex1 = 1111(byte cao của rc_data) giải mã thành
hex1=0001110 ,tín hiệu rc_data_hex0(byte thấp của rc_data) giải mã thành
hex0=100000 .kết quả nhận được đúng với mạch giải mã Led 7 đoạn.
Vậy mạch giải mã Led 7 đoạn hoạt động đúng theo thiết kế .

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 27


Đồ án chuyên ngành

3.2.2 Khối Baud rate:

Từ dạng sóng ta thấy:cứ 16 xung nhận( brg_rx_clken) lại có 1 xung


truyền(brg_tx_clken). Vậy kết quả mô phỏng đúng với mạch tạo xung truyền và mạch
tạo xung nhận trong khối Baud Rate thiết kế.

3.2.3 Khối Transmitter:

Ta thấy khi tx_in=1 thì thanh ghi dữ liệu bắt đầu dịch (data_in = 11110000)
Thanh ghi dịch tsr có 10 bit(1 bit start=0,8 bit data_in,1 bit stop=1), dữ liệu dịch như
sau: 1111100000->1111110000->1111111000->1111111100->1111111110-
>1111111111.
Vậy thanh ghi dịch hoạt động đúng với thiết kế.Bộ truyền dữ liệu thông hoạt
động của thanh ghi dịch như vậy là đúng với thiết kế của bộ Transmitter.

3.2.4 Khối Receiver:

Ta thấy dữ liệu đầu vào FIFO(rsr) và dữ liệu ra của FIFO(rc_data) bằng nhau
rsr=rc_data = 1111000 .dữ liệu này chính là dữ liệu data_in được thanh ghi dịch tsr
truyền đi.tín hiệu fifo_empty bật xuống 0 để báo hiệu FIFO đã nhận được dữ liệu.
Vậy FIFO ghi và đọc dữ liệu đúng với thiết kế.Khối Receiver nhận dữ liệu qua
FIFO đúng với thiết kế .
Kết luận:
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 28
Đồ án chuyên ngành

Dạng sóng mô phỏng đúng chức năng các khối của UART thiết kế.
Vậy thiết kế đúng với yêu cầu truyền- nhận bất đồng bộ dữ liệu 8 bit với tốc độ
baud cấu hình được.

Chương 4 DEMO THỰC TẾ TRÊN KIT DE1 CỦA HÃNG ALTERA

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 29


Đồ án chuyên ngành

4.1 Board mạch DE1 của hãng Altera

Kit DE1 của hãng Altera là kit FPGA có đầy đủ các phần: Chip FPGA Cyclone
II, bộ nhớ SDRAM 8 Mbyte,SRAM 512 kbyte, bộ cấu hình gồm các 10 switch và 4
key, các cổng giao tiếp I/O, các led báo hiệu. Kit này dùng để nạp các thiết kế viết bằng
ngôn ngữ verilog hoặc VHDL lên để Demo kết quả.

4.2 Demo thiết kế trên kit DE1


Dùng phần mềm Quartus II 9.0 của hãng Altera để cấu hình các chân I/O của
thiết kế trên kit ,sau đó ta nạp thiết kế lên kit DE1.Dùng các Switch và các Key (Key0
đến Key3) để cấu hình các tín hiệu cho phép truyền,nhận. Dùng 2 Led7-đoạn để quan
sát dữ liệu mà FIFO nhận được.
Dùng phần mềm Terminal để truyền dữ liệu từ máy tính xuống kit qua bộ
chuyển đổi RS232.
Bảng cấu hình các trên I/O của thiết kế trên kit DE1:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 30


Đồ án chuyên ngành

Mô hình kết nối:

Byte data hiển thị trên phần mềm Terminal khi truyền nhận :

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 31


Đồ án chuyên ngành

Uart_tx:
Trạng thái ban đầu FIFO trống ,led báo Empty sáng:

Khi PC gửi đủ 8 byte data thì FIFO đầy ,Led báo Full sáng:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 32


Đồ án chuyên ngành

Read từng byte của FIFO,hiển thị dữ liệu trên Led 7 đoạn(mã Hex 0X61 tương ứng mã
ASCII của kí tự a)
Khi read byte cuối cùng thì led empty sáng:

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 33


Đồ án chuyên ngành

ĐÁNH GIÁ ĐỀ TÀI THIẾT KẾ

1. Thuận lợi
Áp dụng được những kiến thức đang học về thiết kế vi mạch số vào thực tiễn.
Thiết kế đã nạp chạy được trên kit DE1 thành công,từ đó đã gúp tôi nắm được quy
trình thiết kế mạch số trên FPGA. Kit đã có sẵn nên giảm bớt chi phí mua linh kiện lắp
rắp mạch.

2. Khó khăn
Trong quá trình làm đồ án, tôi đã gặp phải khó khăn về việc nạp chạy thử trên
kit vì bước đầu làm quen với việc thiết kế mạch trên FPGA.
Không có kit DE1 nên việc thử tại nhà rất bất tiện.

3. Hướng phát triển của đề tài


Tuy thiết kế đã đáp ứng được yêu cầu ban đầu đặt ra nhưng để tối ưu hơn ta có
thể thiết kế lõi UART có thêm 1 số tính năng:
o Cấu hình tốc độ Baud và Data truyền trên cùng 1 thanh ghi.
o Thiết kế thanh ghi dịch để có thể truyền thêm bit Parity kiểm tra chẵn lẻ.
o Thiết kế thêm 1 số tín hiệu báo việc truyền/nhận đang diễn ra.
o Thiết kế thêm một số chuẩn giao tiếp giữa UART với MCU và các thiết bị ngoại
vi khác.

Tài liệu tham khảo


[1] DE1 Development and Education Board User Manual – Altera
[2] Thiết kế Logic số -học viện kỹ thueetj quân sự
[3] Bảng mã ASCII-Bách khoa toàn thư Wikipedia
[4] Thiết kế Uart đơn giản dùng VHDL – Diễn đàn Icdesignvn.com

PHỤ LỤC
Code Verilog HDL mô tả thiết kế
Dùng phần mềm Modelsim của Altera để viết code Verilog mô tả chi tiết từng khối.

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 34


Đồ án chuyên ngành

1. Code khối Transmitter


module transmitter(clk,reset_n,uart_en,tx_enable,brg_tx_clken,data_in,uart_tx);
input clk,reset_n;
input uart_en,tx_enable,brg_tx_clken;
input [7:0] data_in;
output reg uart_tx;
wire shift;
wire shift_en;
wire load_data;
//wire fsm_en;
// wire load_msb;
// wire set_uart_tx;
wire set_tx_count;
wire tx_shift;
reg [3:0] tx_count;
reg [9:0] tsr;// Transmitter Shift Reg
parameter IDLE = 2'b00;
parameter LOAD_TXS = 2'b01;
parameter SHIFT_DATA = 2'b10;
reg [1:0] state;
reg [1:0] next_state;
//FSM may trang thai
// assign fsm_en = tx_enable & brg_tx_clken;
always @ (posedge clk or negedge reset_n) begin
if (~reset_n) state <= IDLE;
else state <= next_state;
end
// next state
always @ (*) begin
case (state)
IDLE: if(tx_enable) next_state = LOAD_TXS;
else next_state = IDLE;
LOAD_TXS: next_state = SHIFT_DATA;
SHIFT_DATA:if(brg_tx_clken & (tx_count == 4'b1001)) next_state = IDLE;
else next_state = SHIFT_DATA;
default: if((~reset_n) | (~uart_en)) next_state = IDLE;
endcase
end
assign tx_shift = (state == SHIFT_DATA)?1'b1:1'b0;
assign shift = (state == SHIFT_DATA)?1'b1:1'b0;
assign shift_en = shift & brg_tx_clken & tx_shift & uart_en;
assign load_data = (state == LOAD_TXS)?1'b1:1'b0;
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 35
Đồ án chuyên ngành

assign set_tx_count = (state == IDLE)?1'b1:1'b0;


//assign set_uart_tx = load_msb;
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) tx_count <= 4'd0;
else if(set_tx_count) tx_count <= 4'b0000;
else if(shift_en) tx_count <= tx_count + 4'b1;
end
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) tsr <=10'b1111111111;
//else if(load_msb) tsr <= 10'b1111111111;
else if(load_data) tsr <= {1'b1,data_in[7:0],1'b0}; //shift_reg
else if(shift_en) tsr <= {1'b1,tsr[9:1]}; //Shifting and transmitting
end
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) uart_tx <=1'b1;
else if (brg_tx_clken) uart_tx <=tsr[0];
end
endmodule

2. Code khối Receiver


module
receiver(clk,reset_n,uart_en,fifo_rd,brg_rx_clken,uart_rx,rc_data,fifo_full,fifo_empty);
input clk,reset_n;
input uart_en,brg_rx_clken,uart_rx,fifo_rd;
output wire [7:0] rc_data;
output wire fifo_full;
output wire fifo_empty;
wire set_comp;
wire fsm_receive;
wire sample_point;
wire inc_rx_count;
//wire rx_shift_en;
wire fsm_start_bit;
//wire receive_end;
wire clr_samp_count;
wire inc_samp_count;
wire fifo_we;
wire fifo_re;
wire fbit_comb;
wire fbit_equal;
reg uart_rx_sync;

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 36


Đồ án chuyên ngành

reg uart_rx_sync_2;
wire tx_en;
// detection edge
wire fifo_rd_enable;
reg fifo_rd_sync;
reg fifo_rd_sync_2;
reg [3:0] rx_bitcount;
reg [3:0] samp_count;
reg [7:0] rsr;
reg [3:0] wptr;
reg [3:0] rptr;
reg [7:0] fifo_stage [7:0];
parameter IDLE = 2'b00;
parameter CHECK_START_BIT =2'b01;
parameter RECEIVE_DATA =2'b10;
reg [1:0] state;
reg [1:0] next_state;
assign set_comp = (rx_bitcount[3:0] == 4'b1001)?1'b1:1'b0;
assign fsm_receive = (state == RECEIVE_DATA)?1'b1:1'b0;
assign fsm_start_bit = (state == CHECK_START_BIT)?1'b1:1'b0;
assign clr_rx_count = set_comp;//(state == IDLE)?1'b1:1'b0;
assign sample_point = (samp_count[3:0] == 4'b0111)?1'b1:1'b0;
assign inc_rx_count = fsm_receive & brg_rx_clken & sample_point;
//assign rx_shift_en = set_comp & brg_rx_clken;
assign inc_samp_count = brg_rx_clken & (fsm_start_bit | fsm_receive);
assign clr_samp_count = clr_rx_count;
//assign receive_end = (rx_bitcount[3:0] == 4'b1010)?1'b1:1'b0;
assign fifo_we = uart_en & set_comp & (~fifo_full);
assign fifo_re = uart_en & fifo_rd_enable & (~fifo_empty);
assign fbit_comb = wptr[3] ^ rptr[3];
assign fbit_equal = (wptr[2:0] == rptr[2:0])?1'b1:1'b0;
assign fifo_full = fbit_comb & fbit_equal;
assign fifo_empty =( ~fbit_comb) & fbit_equal;
// detection edge
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) begin
fifo_rd_sync <= 1'b1;
fifo_rd_sync_2 <= 1'b1;
end
else begin
fifo_rd_sync <= fifo_rd;
fifo_rd_sync_2 <= fifo_rd_sync;
end
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 37
Đồ án chuyên ngành

end
assign fifo_rd_enable = fifo_rd_sync_2 & (~fifo_rd_sync);

always @ (posedge clk or negedge reset_n) begin


if(~reset_n) begin
uart_rx_sync <= 1'b1;
uart_rx_sync_2 <= 1'b1;
end
else begin
uart_rx_sync <= uart_rx;
uart_rx_sync_2 <= uart_rx_sync;
end
end
assign tx_en = uart_rx_sync_2 & (~uart_rx_sync);
//FSM may trang thai
always @ (posedge clk or negedge reset_n) begin
if (~reset_n) state <= IDLE;
else if (~uart_en) state <= IDLE;
else state <= next_state;
end
// next state
always @ (*) begin
case (state)
IDLE: if(tx_en) next_state = CHECK_START_BIT;
else next_state = IDLE;
CHECK_START_BIT: begin
if((uart_rx_sync) & (samp_count == 4'b0111)) next_state = IDLE;
else if(~uart_rx_sync & (samp_count == 4'b0111)) next_state =
RECEIVE_DATA;
else next_state = CHECK_START_BIT;
end
RECEIVE_DATA: if(set_comp) next_state = IDLE;
else next_state = RECEIVE_DATA;
default: next_state = state;
endcase
end
// rx_counter
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) rx_bitcount <= 4'd0;
else if(clr_rx_count) rx_bitcount <= 4'b0000;
else if(inc_rx_count) rx_bitcount <= rx_bitcount + 4'b0001;
end

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 38


Đồ án chuyên ngành

//create register rsr[7:0]


always @ (posedge clk) begin
if(inc_rx_count) rsr <= {uart_rx_sync, rsr[7:1]};
end
// create samp_count[3:0]
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) samp_count <= 4'd0;
else if(clr_samp_count) samp_count <= 4'd0;
else if(inc_samp_count) samp_count <= samp_count + 4'd1;
end
// wptr
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) wptr <= 4'd0;
else if(fifo_we) wptr <= wptr + 4'd1;
end
// rptr
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) rptr <= 4'd0;
else if(fifo_re) rptr <= rptr + 4'd1;
end
// FIFO STAGE
always @ (posedge clk ) begin
if (fifo_we)
fifo_stage[wptr[2:0]] <= rsr;
end
assign rc_data = fifo_stage[rptr[2:0]];
endmodule

3. Code khối Baud rate


module baud_rate(clk,reset_n,uart_en,brg_tx_clken,brg_rx_clken);
`include "PARAMETER.h"
//input
input clk,reset_n;
input uart_en;
//output
output wire brg_tx_clken;
output wire brg_rx_clken;
//reg
reg [15:0] tx_counter;
reg [11:0] rx_counter;
//wire
wire set_tx_counter;
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 39
Đồ án chuyên ngành

wire set_rx_counter;
assign set_tx_counter = uart_en & brg_tx_clken;
assign set_rx_counter = uart_en & brg_rx_clken;
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) tx_counter <= 16'd0;
else if(set_tx_counter) tx_counter <= 16'd0;
else if(~set_tx_counter) tx_counter <= tx_counter + 16'd1;
end
assign brg_tx_clken = (tx_counter == ((BRG+1'b1)*5'd16)-1'b1)? 1'b1: 1'b0;
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) rx_counter <= 12'd0;
else if(set_rx_counter) rx_counter <= 12'd0;
else if(~set_rx_counter) rx_counter <= rx_counter + 12'd1;
end
assign brg_rx_clken = (rx_counter == BRG)?1'b1:1'b0;
endmodule

4. Code khối Control_dislay


module control_display(clk,reset_n,uart_en,tx_in,rc_data,tx_enable,hex0,hex1);
//input
input clk,reset_n;
input uart_en,tx_in;
input [7:0] rc_data;
//output
output wire tx_enable;
output reg[6:0] hex0,hex1;
reg tx_in_sync;
reg tx_in_sync_2;
//wire
wire [3:0] rc_data_hex0;
wire [3:0] rc_data_hex1;
// assign
assign rc_data_hex0 = rc_data[3:0];
assign rc_data_hex1 = rc_data[7:4];
//always
// detection edge
always @ (posedge clk or negedge reset_n) begin
if(~reset_n) begin
tx_in_sync <= 1'b1;
tx_in_sync_2 <= 1'b1;
end
else begin
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 40
Đồ án chuyên ngành

tx_in_sync <= tx_in;


tx_in_sync_2 <= tx_in_sync;
end
end
assign tx_enable = tx_in_sync_2 & (~tx_in_sync) & uart_en;

// giai ma Led 7 doan


//LED_0
always @ (*) begin
case (rc_data_hex0)
4'b0000: hex0 = 7'b1000000;
4'b0001: hex0 = 7'b1111001;
4'b0010: hex0 = 7'b0100100;
4'b0011: hex0 = 7'b0110000;
4'b0100: hex0 = 7'b0011001;
4'b0101: hex0 = 7'b0010010;
4'b0110: hex0 = 7'b0000010;
4'b0111: hex0 = 7'b1111000;
4'b1000: hex0 = 7'b0000000;
4'b1001: hex0 = 7'b0010010;
4'b1010: hex0 = 7'b0001000;
4'b1011: hex0 = 7'b0000011;
4'b1100: hex0 = 7'b1000110;
4'b1101: hex0 = 7'b0100001;
4'b1110: hex0 = 7'b0000110;
default: hex0 = 7'b0001110;
endcase
end
//LED_1
always @ (*) begin
case (rc_data_hex1)
4'b0000: hex1 = 7'b1000000;
4'b0001: hex1 = 7'b1111001;
4'b0010: hex1 = 7'b0100100;
4'b0011: hex1 = 7'b0110000;
4'b0100: hex1 = 7'b0011001;
4'b0101: hex1 = 7'b0010010;
4'b0110: hex1 = 7'b0000010;
4'b0111: hex1 = 7'b1111000;
4'b1000: hex1 = 7'b0000000;
4'b1001: hex1 = 7'b0010010;
4'b1010: hex1 = 7'b0001000;
4'b1011: hex1 = 7'b0000011;
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 41
Đồ án chuyên ngành

4'b1100: hex1 = 7'b1000110;


4'b1101: hex1 = 7'b0100001;
4'b1110: hex1 = 7'b0000110;
default: hex1 = 7'b0001110;
endcase
end
endmodule

5. Kết nối các khối thành 1 file Core Uart


module core_uart(/*AUTOARG*/
// Outputs
hex1, hex0, fifo_full, fifo_empty, uart_tx,
// Inputs
uart_en, tx_in, reset_n, fifo_rd, data_in, clk , uart_rx,
);
`include "PARAMETER.h"
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input clk; // To control_display of control_display.v, ...
input [7:0] data_in; // To transmitter of transmitter.v
input fifo_rd; // To receiver of receiver.v
input reset_n; // To control_display of control_display.v, ...
input tx_in; // To control_display of control_display.v
input uart_en; // To control_display of control_display.v, ...

// End of automatics
input uart_rx; // To receiver of receiver.v
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output fifo_empty; // From receiver of receiver.v
output fifo_full; // From receiver of receiver.v
output [6:0] hex0; // From control_display of control_display.v
output [6:0] hex1; // From control_display of control_display.v
output uart_tx; // From transmitter of transmitter.v
// End of automatics
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire brg_rx_clken; // From baud_rate of baud_rate.v
wire brg_tx_clken; // From baud_rate of baud_rate.v
wire [7:0] rc_data; // From receiver of receiver.v
wire tx_enable; // From control_display of control_display.v
// End of automatics
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 42
Đồ án chuyên ngành

control_display control_display(/*AUTOINST*/
// Outputs
.tx_enable(tx_enable),
.hex0 (hex0[6:0]),
.hex1 (hex1[6:0]),
// Inputs
.clk (clk),
.reset_n(reset_n),
.uart_en(uart_en),
.tx_in (tx_in),
.rc_data(rc_data[7:0]));
baud_rate baud_rate(/*AUTOINST*/
// Outputs
.brg_tx_clken (brg_tx_clken),
.brg_rx_clken (brg_rx_clken),
// Inputs
.clk (clk),
.reset_n (reset_n),
.uart_en (uart_en));
transmitter transmitter(/*AUTOINST*/
// Outputs
.uart_tx (uart_tx),
// Inputs
.clk (clk),
.reset_n (reset_n),
.uart_en (uart_en),
.tx_enable (tx_enable),
.brg_tx_clken (brg_tx_clken),
.data_in (data_in[7:0]));
receiver receiver(/*AUTOINST*/
// Outputs
.rc_data (rc_data[7:0]),
.fifo_full (fifo_full),
.fifo_empty (fifo_empty),
// Inputs
.clk (clk),
.reset_n (reset_n),
.uart_en (uart_en),
.brg_rx_clken (brg_rx_clken),
.uart_rx (uart_rx),
.fifo_rd (fifo_rd));
endmodule

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 43


Đồ án chuyên ngành

6. Code Testbecnh mô phỏng:


Ta cấu hình tốc độ baud cho Uart bằng cách tính tốc độ baud theo công thức :
fbaud = fosc/((BRG+1)*16)
trong đó :
fbaud : tốc độ baud ( ví dụ 9600bps,4800bps…)
fosc : tần số xung clock (chọn 50Mhz)
BRG: là thông số để cấu hình cho tôc độ baud.
Ví dụ muốn có tốc dộ baud = 9600bps,ta cấu hình cho BRG = 325 như sau:
parameter BRG = 12'd325;
// 9600 = fosc/((BRG+1)*16)
Code Verilog:
`timescale 10ps/1ps
`define DELAY 10
module tb_core_uart;
`include "PARAMETER.h"
// 4. Parameter definitions
parameter ENDTIME = 400000;
/*AUTOREGINPUT*/
// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
reg clk; // To tb of core_uart.v
reg [7:0] data_in; // To tb of core_uart.v
reg fifo_rd; // To tb of core_uart.v
reg reset_n; // To tb of core_uart.v
reg tx_in; // To tb of core_uart.v
reg uart_en; // To tb of core_uart.v
//reg uart_rx; // To tb of core_uart.v
// End of automatics
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire fifo_empty; // From tb of core_uart.v
wire fifo_full; // From tb of core_uart.v
wire [6:0] hex0; // From tb of core_uart.v
wire [6:0] hex1; // From tb of core_uart.v
wire uart_tx; // From tb of core_uart.v
// End of automatics
integer i;
core_uart tb(/*AUTOINST*/
// Outputs
.fifo_empty (fifo_empty),
.fifo_full (fifo_full),
.hex0 (hex0[6:0]),
.hex1 (hex1[6:0]),

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 44


Đồ án chuyên ngành

.uart_tx (uart_tx),
// Inputs
.clk (clk),
.data_in (data_in[7:0]),
.fifo_rd (fifo_rd),
.reset_n (reset_n),
.tx_in (tx_in),
.uart_en (uart_en),
.uart_rx (uart_tx));
//KHOI TAO GIA TRI BAN DAU
initial
begin
clk = 1'b0;
reset_n = 1'b0;
fifo_rd = 1'b1;
tx_in = 1'b0;
uart_en = 1'b1;
// uart_rx = 1'b1;
data_in = 8'd0;

end
// 9. Generating Test Vectors
initial
begin
main;
end
task main;
fork
clock_gen;
reset_gen;
tx_gen;
fifo_gen;
shift_gen;
debug_output;
endsimulation;
join
endtask

task clock_gen;
begin
forever #`DELAY clk = !clk;
end
endtask
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 45
Đồ án chuyên ngành

task reset_gen;
begin
#1 reset_n = 1'b1;
end
endtask
task tx_gen;
begin
#200 tx_in = 1'b1;
//#300 tx_in = 1'b1;
//#450 tx_in = 1'b0;
//#200 tx_in = 1'b1;
//#550 tx_in = 1'b0;
// #300 tx_in = 1'b1;
end
endtask

task fifo_gen;
begin
#100 fifo_rd = 1'b0;
#300 fifo_rd = 1'b1;
#450 fifo_rd = 1'b0;
#600 fifo_rd = 1'b1;
#300 fifo_rd = 1'b0;
#500 fifo_rd = 1'b1;
end
endtask
task shift_gen;
begin

data_in = 8'b01010101;
#(`DELAY*10) data_in = 8'b00001111;
#(`DELAY*10) data_in = 8'b11110000;
#(`DELAY*20) data_in = 8'b00111100;
#(`DELAY*30) data_in = 8'b10001111;
#(`DELAY*50) data_in = 8'b01110000;
end
endtask

// 10. Debug output


task debug_output;
begin
$display("----------------------------------------------");
SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 46
Đồ án chuyên ngành

$display("----------- SIMULATION RESULT ----------------");


$display("----------------------------------------------");
$monitor("TIME = %d, data_in = %b, fifo_rd = %b, tx_in = %b,hex0=
%h,hex1=%h",$time,data_in,fifo_rd,tx_in,hex0,hex1);
end
endtask
task endsimulation;
begin
#ENDTIME
$display("-------------- THE SIMUALTION END ------------");
$finish;
end
endtask
endmodul

SVTH: ĐỖ TIẾN THÀNH – LỚP 09DT2 Trang 47

You might also like