Bài 7: Những điểm khác biệt trong lập trình phần cứng so với phần mềm
Bài viết quan trọng nhất cho một nhà thiết kế kỹ thuật số mới
Mọi nhà phát triển phần mềm biết một ngôn ngữ như C hay Java đều có cùng vấn đề khi cố bắt đầu lập trình trong VHDL hoặc Verilog. Ngôn ngữ phần cứng có những khác biệt mà các bạn cần lưu ý, nó hoạt động khác so với những gì chúng ta đã từng làm trong lập trình phần mềm. Nếu bạn mới phát triển phần cứng và đã biết một hoặc hai ngôn ngữ phần mềm nào đó, hãy đọc bài viết này để hiểu hơn về HDL. Bài viết này cung cấp các ví dụ về mã HDL và giải thích cách các mã hoạt động trong lập trình phần mềm và trong lập trình phần cứng để cho bạn thấy sự khác biệt.
Giả định # 1: Tuần tự và song song
Đây có lẽ là sự khác biệt cơ bản nhất giữa ngôn ngữ lập trình phần cứng và phần mềm. Các nhà thiết kế phần mềm lập ra các mã hoạt động tuần tự, nhưng có lẽ họ không nhận ra điều này. Điều này có nghĩa là mã tuần tự là mỗi dòng mã được thực hiện một tại một thời điểm. Ví dụ: Dòng # 2 chỉ có thể thực thi sau khi Dòng # 1 hoàn tất. VHDL và Verilog không cư xử theo cách này! Chúng được gọi là các ngôn ngữ logic song song và tất cả các dòng mã có thể và sẽ thực thi tất cả cùng một lúc. Đây là một ví dụ minh họa sự khác biệt giữa logic tuần tự và song song. Giả sử một nhà thiết kế muốn bật đèn LED một lần sau mỗi mười chu kỳ đồng hồ.
Mã phần mềm ví dụ:
while (1) { if (count == 9) { LED_on = 1; count = 0; } else { LED_on = 0; count = count + 1; } }
P_INCREMENT : process (clock) begin if rising_edge(clock) then if (count < 9) then count <= count + 1; else count <= 0; end if; end if; end process P_INCREMENT; LED_on <= ‘1’ when count = 9 else ‘0’;
Giả định # 2: Đối với vòng lặp
Đây là một vấn đề lớn mà các nhà phát triển phần cứng mới có. Ví dụ, trong ngôn ngữ C ta đã từng sử dụng các vòng lặp rất dễ dàng, và có thể chúng ta nghĩ rằng các vòng lặp trong Verilog và VHDL cũng hoạt động như vậy! Thật không may, các vòng lặp trong ngôn ngữ phần cứng KHÔNG hành xử theo cùng một cách như trong phần mềm. Khi chưa hiểu cách các vòng lặp làm việc, bạn không nên sử dụng chúng.
Mã phần mềm ví dụ:
For (int i=0; i<10; i++) data[i] = data[i] + 1;
P_INCREMENT : process (clock)
begin
if rising_edge(clock) then
if (index < 10) then
data[index] <= data[index] + 1;
index <= index + 1;
end if;
end if;
end process P_INCREMENT;
Chúng ta bắt đầu thấy sự khác biệt ở đây, mã C rất gắn, trong khi mã trong VHDL hoặc Verilog dài hơn, thực hiện nhiều công việc hơn. Một điều chắc chắn là: nếu bạn chưa thực hiện ít nhất 3 thiết kế FPGA bạn sẽ không bao giờ sử dụng được các vòng lặp. Vì vậy, suy nghĩ về cách mã bạn viết trong phần mềm có thể được viết lại để không bao giờ sử dụng vòng lặp for trong HDL. Thông thường tất cả những gì bạn cần là thêm một tín hiệu truy cập (như ở ví dụ trên) để làm điều tương tự với vòng lặp for.
Giả định # 3: Thực thi Mã ngay lập tức
Điều này liên quan đến logic song song. Các nhà phát triển phần mềm cần phải nhớ rằng một dòng mã không được thực hiện ngay lập tức, với giá trị của tín hiệu được cập nhật để sử dụng. Một ví dụ dưới đây mô tả chi tiết giả định này với trạng thái thiết bị. Ví dụ dưới đây cho thấy một thói quen khởi tạo cho một số thành phần ngoại vi thường thấy trong lập trình phần mềm, mà không áp dụng trong lập trình phần cứng.
Mã phần mềm ví dụ:
state = INITIALIZE; data = 5; state = LOAD_1; data = 6; state = LOAD_2; data = 1; state = DONE; data = 0;
KHÔNG Mã phần cứng tương đương: (Mã lỗi)
P_STATE_MACHINE : process (clock)
begin
if rising_edge(clock) then
state <= INITIALIZE;
data <= 5;
state <= LOAD_1;
data <= 6;
state <= LOAD_2;
data <= 1;
state <= DONE;
data <= 0;
end if;
end process P_STATE_MACHINE;
Biểu diễn phần cứng của mã này bị sai! Vì mỗi dòng trong một tiến trình thực thi đồng thời, data luôn bằng 0 và trạng thái state luôn bằng DONE. Mã này sẽ không bao giờ thực thi máy trạng thái theo cách nó sẽ làm trong mã phần mềm. Mã đúng trong VHDL:
Mã phần cứng tương đương:
P_STATE_MACHINE : process (clock) begin if rising_edge(clock) then if (state == INITIALIZE) then data <= 5; state <= LOAD_1; elsif (state == LOAD_1) then data <= 6; state <= LOAD_2; elsif (state == LOAD_2) then data <= 1; state <= DONE; elsif (state == DONE) then data = 0; else state <= INITIALIZE; end if; end if;
Ba ví dụ trên là ba vấn đề mà các nhà phát triển phần mềm thường gặp khó khăn khi bắt đầu thiết kế phần cứng với VHDL hoặc Verilog. Ba vấn đề trên luôn luôn trong tâm trí của một nhà thiết kế kỹ thuật số mới. Các câu hỏi về lệnh song sang, các vòng lặp và việc thực thi mã phải luôn được đưa ra xem xét. Cần phải nắm vững những sự khác biệt trong ngôn ngữ phần cứng mới giúp bạn tìm hiểu sau hơn về FPGA.
Bình luận gần đây