VHDL: Chuyển đổi từ loại INTEGER sang STD_LOGIC_VECTOR


28

Tôi đã xây dựng bộ đếm mod-16 và kết quả đầu ra là INTEGER (tất cả các ví dụ tôi thấy đã sử dụng INTEGER).

Tôi đã xây dựng bộ giải mã hiển thị hex-to-7 phân đoạn và đầu vào của nó là STD_LOGIC_VECTOR (đã viết theo cách đó vì nó dễ dàng vạch ra bảng chân lý).

Tôi muốn kết nối đầu ra của bộ đếm với đầu vào của bộ giải mã, nhưng tôi gặp lỗi 'gõ không khớp' khi cố gắng biên dịch trong QuartusII.

Có cách nào để chuyển đổi từ loại INTEGER sang loại STD_LOGIC_VECTOR trong danh sách VHDL không?

Câu trả lời:


20

Như những người khác đã nói, sử dụng ieee.numeric_std, không bao giờ ieee.std_logic_unsigned, đó không thực sự là một gói IEEE.

Tuy nhiên, nếu bạn đang sử dụng các công cụ hỗ trợ VHDL 2008, bạn có thể sử dụng gói mới ieee.numeric_std_unsigned, về cơ bản làm cho std_logic_vectorhành vi giống như không dấu.

Ngoài ra, vì tôi không thấy nó được nêu rõ ràng, đây là ví dụ mã thực tế để chuyển đổi từ một số nguyên (không dấu) sang std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

16

Như LoneTech nói, use ieee.numeric_stdlà bạn của bạn. Bạn có thể chuyển đổi std_logic_vectorthành một integer, nhưng bạn sẽ phải chuyển nó thành signedhoặc unsignedtrước tiên (vì trình biên dịch không biết ý bạn là gì). VHDL là một ngôn ngữ đánh máy mạnh mẽ. Tôi đã viết nhiều hơn về chủ đề này trên blog của tôi

Về cơ bản, tôi sẽ thay đổi trình chuyển đổi 7seg của bạn thành một integer(hoặc thực tế là natural, với điều kiện là nó sẽ chỉ xử lý các số dương) - chuyển đổi sau đó là một tra cứu mảng đơn giản. Thiết lập một mảng không đổi với các chuyển đổi trong và chỉ lập chỉ mục vào nó với số nguyên bạn sử dụng trên thực thể làm đầu vào.


Cảm ơn vì điều đó. Tôi đánh giá cao ý kiến ​​của bạn rất nhiều. Tôi đã ở vị trí TA của các loại, học VHDL để giúp một giáo sư bắt đầu, người hơi ngại về các khái niệm lập trình. Tôi sẽ chuyển thông tin của bạn cho anh ấy - cuốn sách giáo khoa mà chúng tôi đã sử dụng không đi sâu vào các câu hỏi về "đạo đức" của VHDL.
J. Polfer

1
Đó không phải là vấn đề "đạo đức" hơn là sự đảm bảo tính nhất quán. Lib_std lib là một tiêu chuẩn thực sự được thiết lập bởi IEEE, trong khi thư viện std_logic_un tiệc được tạo bởi một nhà cung cấp và được chấp nhận trong ngành mà không có bất kỳ định nghĩa chính thức thực sự nào. Không có gì đảm bảo khả năng tương thích giữa các nhà cung cấp với các lib không chuẩn, mặc dù nó thường hoạt động tốt. Đó là hình thức tốt để chuyển sang tiêu chuẩn bây giờ mặc dù.
MattG

1

Giả sử bộ đếm 4 bit của bạn có đầu ra INTEGER SOME_INTEGER và bạn muốn chuyển đổi nó thành STD_LOGIC_VECTOR 4 bit

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Bạn cũng có thể sử dụng điều này để khởi tạo vectơ với các số có ý nghĩa

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

Tôi nghĩ rằng bạn có thể cần thêm "sử dụng IEEE.STD_LOGIC_ARITH.ALL;" và / hoặc STD_LOGIC_UNSIGNED.

Các hoạt động bổ sung là conv_integer (vector). Tôi thích sử dụng điều này khi tôi so sánh. Vì vậy tôi có thể tuyên bố

constant SOME_CONSTANT : integer := 999;

Và sau đó, sau này, tôi có thể sử dụng điều này trong một câu lệnh if

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

EDIT: Bạn không cần phải khai báo biến là một số nguyên. Thay vào đó, hãy thử thay đổi khai báo thành std_logic_vector. Các toán tử + và - hoạt động trên std_logic_vector.


3
Xin đừng làm điều này! Sử dụng num_std (xem câu trả lời của LoneTech và của tôi)
Martin Thompson

Nếu bạn có cách tốt hơn để làm điều đó, thì tốt thôi, nhưng đề xuất của tôi có hiệu quả nên tôi nghĩ rằng việc bỏ phiếu của bạn là không cần thiết. Tôi đã sử dụng std_logic_arith trong nhiều năm và tôi chưa bao giờ có bất kỳ vấn đề nào với nó. Tôi nghĩ rằng những lo ngại về các nhà cung cấp thay đổi việc triển khai của họ là không có cơ sở; nhà cung cấp nào trong suy nghĩ đúng đắn của họ sẽ có nguy cơ phá vỡ thiết kế của khách hàng?
ajs410

1
Bạn đã có câu trả lời cho những gì nhà cung cấp cố tình đưa nội dung cụ thể của nhà cung cấp vào không gian tên của IEEE. Nó vẫn còn thô, đặc biệt khi xử lý các giá trị đã ký chưa ký.
Yann Vernier

"Các toán tử + và - hoạt động trên std_logic_vector." AFAIK, họ không làm việc, trừ khi tôi hiểu sai ý của bạn. thường là cần thiết để chuyển sang loại chứa dữ liệu đã ký / chưa ký trước.
stanri

1

Bạn có thể quan tâm đến việc sử dụng các loại unsignedsignedtừ ieee.numeric_std. Chúng tương thích với std_logic_vector, nhưng có một giải thích số (nhị phân hoặc bổ sung 2). Ngoài ra còn có tùy chọn để đưa ra một giải thích như vậy std_logic_vector, nhưng điều này không được khuyến khích .


0

Như câu trả lời chính nói, phương pháp được đề xuất như sau:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Tuy nhiên, tôi muốn giải thích lý do tại sao điều này được khuyến nghị và tại sao VHDL có cách chuyển đổi số nguyên dường như phức tạp như vậy thành std_logic_vector.

Các công cụ này được xem như thế nào.

Một Standard_logic_vector đúng nghĩa là một bó 1 hoặc 0. Tôi có 10001. Đây là số nào? Vâng, nó phụ thuộc. Được ký hay chưa ký? Ths SLV không biết hoặc quan tâm. Có bao nhiêu bit? Chà, SLV của bạn dài bao nhiêu?

Một số nguyên được ký và thường là 32 bit (nếu tôi nhớ chính xác).

Giai đoạn 1: Làm cho số nguyên của tôi ngắn hơn và không dấu. Đó là phần này:

to_unsigned(my_int, my_slv'length));

"Tôi có số nguyên này. Tôi muốn nó không được ký và tôi muốn nó phù hợp với chiều dài của SLV của tôi."

Giai đoạn 2: Sau đó, lấy các bit đó và sử dụng chúng để lái my_slv.

my_slv <= std_logic_vector(...)

"Lấy các bit này và sử dụng chúng để lái slv của tôi"

(Một lưu ý về thuật ngữ. A <= BTrong VHDL được đọc thành tiếng "A được điều khiển bởi B")

Kết hợp, điều này giúp bạn:

my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Khi đến từ một nền tảng lập trình truyền thống, rất dễ bị mắc kẹt trong lối suy nghĩ lập trình. Nhưng trong VHDL, mã bạn viết có ý nghĩa vật lý trong phần cứng. Biết lý do tại sao phương pháp này hoạt động và được khuyến nghị là một bước gần hơn để suy nghĩ về những gì bạn viết bằng thuật ngữ phần cứng.

Tiền thưởng: các hàm có tiền tố là to_ là các hàm rút ngắn / thay đổi toán hạng. Họ làm cho chúng không dấu hoặc một độ dài nhất định hoặc cả hai. Đây là lý do tại sao to_unign yêu cầu bạn chỉ định độ dài. Các hàm không có to_ (std_logic_vector thẳng (...) trong ví dụ này) được sử dụng khi các loại đã tương thích trực tiếp. "Lấy các bit này và nhét chúng vào loại này, không cần sửa đổi". Chúng không có đối số độ dài vì cả hai bên đều giống nhau. Vì vậy, khi xây dựng những thứ như thế này, tôi không cần phải tìm kiếm nó, tôi chỉ nghĩ về cách tôi thay đổi dữ liệu.


0

Để chuyển đổi một số nguyên thành std_logic_vector, bạn có một số tùy chọn. Sử dụng num_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

hoặc là

vect <= std_logic_vector( to_signed( your_int, vect'length));

Sử dụng std_logic_arith:

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith không phải là một tiêu chuẩn ieee, nhưng hầu hết các công cụ biên dịch nó vào thư viện IEEE và nó được sử dụng rộng rãi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.