Các mô hình và bài tập ứng dụng

Một phần của tài liệu Giáo trình vi mạch số lập trình (nghề điện tử công nghiệp) (Trang 110)

a. Lời giải thích:

Các chú thích được đưa vào với mục đích giải thích các câu lệnh, hay chỉ rõ mục đích, nhằm tăng tính dễ đọc, dễ sửa lỗi và phát triển chương trình. Có hai cách viết chú thích. v Cách 1: Chú thích được viết trên một hàng thì bắt đầu với ký hiệu “ // ” và lời chú thích v Cách 2: Chú thích trên nhiều hàng thì bắt đầu chú thích với ký hiệu “/*” và kết thúc với ký hiệu “ */ ” Ví dụ: // chú thích trên một hàng /* chú thích trên nhiều hàng */ b. Hằng số:

Hằng số kiểu sized: khai báo hằng số kiểu sized thì ta quan tâm đến tầm

giá trị của hằng số. Có thể coi hằng số có kiểu sized như hằng số có kiểu. Dạng biểu diễn:<size> ‘<base format> <number>

Trong đó:

v <size>: được biểu diễn dưới dạng số thập phân để chỉ số bit tối

đa của hằng số.

v <base format>: chỉ hệ cơ số

v <number>: Chứa giá trị hằng số và phải phù hợp với <base format>

Ví dụ:

4’b1111; //đây là số nhị phân 4 bit 12’habc; //đây là số thập lục phân 12 bit 16’d255; // đây là số thập phân 16 bit

Hằng số kiểu unsized: Khai náo hằng số kiểu unsized thì không quan tâm đến tầm giá trị của hằng số. Ta có thể coi hằng số kiểu unsized như hằng số không có kiểu.

Dạng biểu diễn:‘<base format> <number>

Nếu không có <base format> thì ngầm định là thập phân. Do không khai báo <size> nên số bit tối đa phụ thuộc vào trình mô phỏng, trình biên

dịch và có giá trị bit tối thiểu là 32 bit.

Ví dụ:

23456; // đây là số thập phân 32 bit ‘hc3; // đây là số hex 32 bit ‘o21; // đây là số octan 32 bit

c. Giá trị tùy định và tổng trở cao:

Verilog có hai ký hiệu biểu diễn giá trị tùy định và tổng trở cao, là những giá trị quan trọng trong thiết kế mạch số:

Giá trị tùy định ký hiệu là “ x ”, và giá trị tổng trở cao ký hiệu là “ z ”.

Ví dụ:

12’h13x; //đây là số hex 12 bit, 4 bit thấp có giá trị tùy định 2’bzz; //đây là số nhị phân 2 bit có giá trị tổng trở cao

d. Số âm:

Số âm có thể được biểu diễn bằng cách đặt một dấu trừ phía trước trị số chỉ kích thước. Các hằng số kích thước luôn luôn dương. Giá trị không hợp lệ khi ta đặt dấu trừ giữa <base format> và <number>.

Ví dụ:

-4’d-2; //cách biểu diễn không hợp lệ

e. Chuỗi ký tự:

Là một loạt các ký tự nằm trong dấu ngoặc kép “ ”. Chuỗi phải nằm trong một hàng và không chứa ký tự Enter. Các ký tự trong chuỗi có thể là mã thoát, chuỗi được xử lý như các giá trị liên tục trong bảng mã ASCII.

f. Kí tự gạch dưới và dấu hỏi:

Một kí tự gạch dưới “-” được chấp nhận bất kỳ đâu trong một số ngoại trừ ký tự đầu tiên. Ký tự gạch dưới được cho vào dùng để tăng tính dễ đọc của các con số và được bỏ đi trong trình biên dịch của Verilog.

Một dấu chấm hỏi “?” trong Verilog được sử dụng thay cho z trong biểu diễn số.

Ví dụ:

12’b1111_0000_1100; //dùng thêm các ký tự gạch dưới cho dễ đọc 4’b10?? ; //tương dươi với 4’b10zz

4.3.2. Điều khiển hệ thống cung cấp khí nén. a. Giá trị thiết lập:

Trong Verilog hỗ trợ bốn giá trị (bảng 6.1) và tám mức độ mạnh để mô tả các chức năng của phần cứng thực.

Bảng 6.1: Các giá trị thiết lập

0 Mức không, hoặc điều kiện không thỏa 1 Mức một, hoặc điều kiện đúng

X Giá trị tùy định

Z Trạng thái tổng trở cao, hoặc trạng thái động

Tám mức thường được sử dụng để giải quyết xung đột giữa các tín hiệu khác nhau trong mạch số. Giá trị 0 và 1 có thể có thêm mức độ ưu tiên theo bảng 6.2.

Bảng 6.2: Các mức ưu tiên

Mức ưu tiên Loại Cao nhất Supply Driving Strong Driving Pull Driving Large Storage Weak Driving Medium Storage Small Storage hightz High Impedance Thấp nhất

Hai tín hiệu có mức độ ưu tiên cùng điều khiển một đường dây, tín hiệu có độ ưu tiên cao sẽ được chọn. Ví dụ, nếu hai tín hiệu có độ ưu tiên là strong1 và weak0 xung đột, kết quả được giải quyết là strong1. Nếu hai tín hiệu có mức ưu tiên bằng nhau, thì kết quả là không xác định.

b. Kiểu net:

Dùng để mô tả sự kết nối trong các mạch phần cứng thực. Kiểu net thực sự là tên của các đường kết nối trong mạch.

Kiểu net thường được khai báo bằng từ khóa wire. Giá trị mặc định là z và có độ rộng là 1 bit.

Chú ý là net không phải là từ khóa, mà là một lớp dữ liệu như wire, wand, wor, tri, triand, trior, trireg,…trong đó, wire được sử dụng thường xuyên nhất

wire <tên biến>

Ví dụ:

wire a; //khai báo dây a trong mạch

c. Kiểu reg:

Biến kiểu reg dùng để lưu trữ giá trị như một thanh ghi. Giá trị được lưu trữ cho đến khi có giá trị khác ghi đè lên nó. Không được nhầm lẫn kiểu thanh ghi trong Verilog với các thanh ghi phần cứng trong mạch thực. Trong Verilog, thanh ghi có nghĩa là một biến lưu dữ liệu, không cần xung clock như thanh ghi phần cứng. Giá trị các thanh ghi có thể thay đổi bất kì lúc nào.

Các kiểu thanh ghi thông thường được khai báo bởi từ khóa reg. Giá trị mặc định là x, độ rộng mặc định là 1 bit.

Ví dụ:

reg a; //khai báo biến a để lưu dữ liệu initial

begin

a = 1’b1; //cho biến a lưu giá trị 1

#100 a = 1’b0; //sau 100 đơn vị thời gian cho a lưu giá trị 0 end

d. Kiểu Vector:

Net và reg có thể được khai báo như một vector (độ rộng nhiều bit). Biến kiểu vector khai báo dạng sau [MSB:LSB], bit có trọng số cao nhất luôn luôn nằm bên trái ngoặc vuông.

<kiểu dữ liệu> [MSB:LSB] <tên biến>;

Ví dụ:

wire [7:0] a; //khai báo biến a kiểu net với độ rộng 8 bit

reg [9:0] b; //khai báo biến b kiểu reg với độ rộng 10 bit

e. Kiểu mảng:

Mảng là một biến cấu trúc trong đó có nhiều phần tử cùng kiểu, mỗi phần tử là một biến của mảng. Mỗi biến thành phần này là một biến bình thường và chỉ để phân biệt giữa phần tử này với phần tử kia. Như vậy, để truy xuất tới một phần tử của mảng ta cần biết được chỉ số của nó. Verilog chỉ cho phép biến mảng có kiểu là reg, integer, time, real, realtime và vector. Verilog chỉ cho phép định nghĩa mảng một chiều, số phần tử trên một chiều gọi là kích thước của chiều đó.

<kiểu dữ liệu> [MSB:LSB] <tên mảng> <chiều dài mảng>;

Ví dụ:

reg [7:0] port_a [0:7]; /* khai báo kiểu mảng có 8 phần tử,

mỗi phần tử có độ rộng 8 bit */ integer counter [0:7]; /* khai báo kiểu mảng có 8 phần tử,

mỗi phần tử có độ rộng 1 bit */ counter [4]; //truy suất phần tử thứ 5 của mảng counter

f. Các kiểu dữ liệu Real, Integer và Time Register:

Integer là kiểu dữ liệu thường được dùng cho việc đếm. Các biến được khai báo bằng từ khóa integer. Mặc dù có thể sử dụng reg theo cách tương tự, nhưng sẽ thuận lợi hơn nếu sử dụng integer cho mục đích đếm, mặc định độ

rộng của integer phụ thuộc vào độ rộng đơn vị nhớ của hệ thống, ít nhất là 32 bit.

integer <tên biến>;

Ví dụ:

integer counter; //mục đích thông thường sử dụng trong bộ đếm

Real là các biến số thực được khai báo bằng từ khóa real, các biến số thực không có giới hạn, giá trị mặc định là 0. Khi giá trị biến được chuyển sang dạng số nguyên, số thực được làm tròn đến giá trị số nguyên nhỏ nhất.

real <tên biến>;

Ví dụ:

real a; //khai báo biến số thực a initial

begin

a = 4e10; //a được gán giá trị theo số mũ

a = 2.13; //a được gán giá trị 2.13 end

Time là một kiểu dữ liệu đặc biệt dùng để khai báo biến kiểu thời gian. Một biến thời gian được khao báo bằng từ khóa time. Độ rộng của biến ít nhất là 64 bit. Hàm chức năng $time được dùng để lấy thời gian mô phỏng tức thời.

time <tên biến>;

Ví dụ:

time save_s; //khai báo một biến thời gian initial

save_s = $time; //lưu lại thời gian mô phỏng tức thời

g. Kiểu chuỗi:

Chuỗi được lưu trong reg. Mỗi biến phải đủ rộng để chứa chuỗi, mỗi kí tự trong chuỗi dài 1 byte. Nếu độ rộng thanh ghi chứa chuỗi rộng hơn chiều dài chuỗi thì verilog sẽ lấp đầy bằng giá trị 0. Nếu độ rộng thanh ghi nhỏ hơn, verilog sẽ bỏ bớt kí tự chuỗi. Vì vậy, phải luôn khai báo chuỗi có độ rộng lớn hơn hoặc bằng độ rộng cần thiết.

Ví dụ:

reg [8*8:1] bien_chuoi; //khai báo biến rộng 9 byte initial

chuỗi có thể chứa những mã thoát sau: Bảng 6.3: Bảng mã thoát Mã thoát Chức năng \n Xuống dòng \t Tab %% % \\ \ \” ” h. Khai báo hằng số

Verilog cho phép khai báo hằng số trong module bằng từ khóa parameter. Các giá trị hằng số có thể thay đổi trong quá trình thực hiện module bằng việc dùng phát biểu defparam. Trong verilog còn có hằng số cục bộ, là hằng số được định nghĩa bằng từ khóa localparam, giá trị của nó không bị thay đổi bằng phát biểu defparam, và được sử dụng để bảo vệ chống lại việc vô ý định lại giá trị hằng số.

parameter <tên hằng> = <giá trị hằng>;

Ví dụ:

parameter a = 5; //định nghĩa hằng port a localparam b = 4’h5, c =4’h8; //định nghĩa hằng số cục bộ

4.3.3 Đieu khi en hệ thongcungcap thuỷ lực

a. Chỉ thị hệ thống:

Verilog cung cấp các chỉ thị để hệ thống thực hiện các nhiệm vụ như hiển thị lên màng hình, theo dõi giá trị của các đường dây, dừng, và kết thúc chương trình. Các chỉ thị bắt đầu bằng$<từ khóa>. Ở đây, trình bày các chỉ thị hệ thống thường dùng nhất.

Để hiển thị thông tin ta dùng hàm $dislay, lúc này hệ thống sẽ hiển thị giá trị của biến, hoặc chuỗi hay biểu thức.

Cách dùng: $dislay (p1,p2,…,pn);

P1,p2,..,pn có thể là chuỗi hay biến, hoặc biểu thức. Dạng $dislay rất giống với printf trong ngôn ngữ C. Chuỗi hiển thị được định dạng theo các quy định cho trong bảng 6.4

Bảng 6.4: Bảng chỉ thị hệ thống

%d hay %D Hiển thị giá trị theo cơ số 10 %b hay %B Hiển thị giá trị theo kiểu nhị phân %s hay %S Hiển thị chuỗi

%h hay %H Hiển thị biến theo cơ số 16 %c hay %C Hiển thị kí tự ASCII

%m hay %M Hiển thị theo thứ bậc %v hay %V Hiển thị theo mức ưu tiên 5o hay %O Hiển thị theo hệ cơ số 8 %t hay %T Hiển thị thời gian hiện hành

%e hay %E Hiển thị theo kiểu khoa học (ví dụ 3e10) %f hay %F Hiển thị số thực theo kiểu thập phân

%g hay %G Hiển thị số thực theo kiểu khoa học hoặc thập phân, sao cho ngắn nhất

Để theo dõi thông tin, verilog cung cấp một cơ chế theo dõi sự thay đổi của tín hiệu, đó là chỉ thị $monitor.

Cách dùng: $monitor (p1,p2,..,pn);

Định dạng của $monitor cũng giống như $dislay, $monitor chỉ cần gọi một lần, sẽ hiển thị liên tục các giá trị của biến hay tín hiệu khi có bất kì sự thay đổi nào. Chỉ một danh sách theo dõi hoạt động tại một thời điểm, nếu có nhiều hơn một chỉ thị $monitor trong quá trình mô phỏng, thì chỉ thị $monitor cuối cùng sẽ hoạt động.

Hai chỉ thị thường được sử dụng để mở hoặc tắt các chức năng theo dõi là$monitoron và $monitoroff.

Quá trình theo dõi mặc định được bắt đầu cùng với việc mô phỏng, nhưng có thể được mở và tắt trong quá trình mổ phỏng bằng hai chỉ thị trên.

Để dừng và kết thúc mô phỏng, verilog cung cấp chỉ thị $stop. Cách dùng: $stop;

Chỉ thị $stop được sử dụng để dừng quá trình để sửa lỗi, thay đổi tín hiệu trong thiết kế,..đưa quá trình mô phỏng vào chế độ treo.

Chỉ thị $finish dùng để kết thúc mô phỏng. Cách dùng: $finish;

b. Chỉ thị biên dịch:

Verilog cung cấp một số chỉ thị biên dịch. Tất cả các chỉ thị được định nghĩa bởi cấu trúc ‘<từ khóa>. Hai chỉ thị biên dịch hữu ích nhất là‘define và ‘inclucde.

‘define dùng để định nghĩa macro trong verilog, nó giống như #define trong ngôn ngữ C.

‘include dùng để cho phép đưa vào một file mã nguồn verilog trong chương trình khác trong quá trình biên dịch. Cách làm việc giống như #include trong C. Chỉ thị này thường dùng để thêm vào nội dung toàn cục hoặc các định nghĩa thông dụng.

4.3.4. Điều khiển hệ thống thông gióa.Các thành phần trong một module: a.Các thành phần trong một module:

Module là một cấu trúc cơ bản của ngôn ngữ verilog. Mọi thành phần trong verilog đều chứa trong module. Một module có khả năng giao tiếp với các module khác thông qua các port. Cấu trúc bên trong của module này không thể truy suất từ các module khác, đây là một tính chất rất linh hoạt của verilog giúp người thiết kế có thể thay đổi cấu trúc bên trong của module mà không làm ảnh hưởng đến các thiết kế khác.

Cấu trúc của một module trong verilog như hình 6.3.

Hình 6.3 – Cấu trúc module trong verilog

Định nghĩa một module bắt đầu bằng từ khóa module và phải kết thúc bằng từ khóaendmodule. Mỗi module phải có tên riêng đại diện cho module

đó, khai báo các port (nếu có), tùy chọn khai báo các thông số (parameter) phải đặt ở đầu module. Port list và port chỉ có khi module có bất kì cổng giao tiếp với môi trường bên ngoài. Có năm thành phần bên trong module là: khai

báo biến, các câu lệnh mức dataflow, tạo các module thấp hơn, khối lệnh hành vi, và nhiệm vụ - chức năng của module. Các thành phần có thể đặt bất kỳ đâu, bất kỳ vị trì nào bên trong module. Verilog cho phép ghép nhiều module được định nghĩa trong cùng một file. Các module có thể được định nghĩa tại bất kì vị trí nào của file.

b.Port :

Port cung cấp giao diện, qua đó module có thể truyền thông với môi trường bên ngoài. Các thành phần bên trong module không nhìn thấy được từ môi trường bên ngoài. Sự thay đổi các thành phần bên trong không ảnh hưởng đến môi trường bên ngoài, miễn là giao diện không bị thay đổi. Điều này cung cấp tính linh hoạt mạnh cho người thiết kế.

Danh sách các port là tùy chọn, và được khai báo khi định nghĩa module. Nếu module không trao đổi bất kỳ tín hiệu nào với bên ngoài, thì ta không cần danh sách các port.

Tất cả các port trong danh sách port đều phải được khai báo trong module, mỗi port trong khai báo có thể thuộc một trong ba dạng sau:

Từ khóa Loại port

input Port ngõ vào output Port ngõ ra

inout Port hai chiều (vào/ra)

Lưu ý là các port input và inout thường được khai báo dưới dạng wire, nếu portoutput lưu trữ giá trị của port thì phải được khai báo dưới dạng reg.

Có nhiều quy luật chi phối các kết nối port khi các module được thể hiện bên trong module khác, Trình mô phỏng sẽ báo lỗi nếu ta vi phạm các quy luật kết nối port. Các quy luật được tóm tắt như sau:

v Input: ở bên trong thì port input luôn luôn có kiểu net, còn bên ngoài port input có thể được kết nối đến một biến kiểu reg hoặc kiểu net.

v Ouput: ở bên trong port output có kiểu reg hoặc kiểu net, còn bên noài

Một phần của tài liệu Giáo trình vi mạch số lập trình (nghề điện tử công nghiệp) (Trang 110)

Tải bản đầy đủ (PDF)

(125 trang)