VHDL: การแปลงจากประเภท INTEGER เป็น STD_LOGIC_VECTOR


28

ฉันสร้างตัวนับ mod-16 และผลลัพธ์ผลลัพธ์คือ INTEGER (ตัวอย่างทั้งหมดที่ฉันเห็นเคยใช้ INTEGER)

ฉันสร้างตัวถอดรหัสการแสดงผลแบบ hex-to-7-Segment และอินพุตของมันคือ STD_LOGIC_VECTOR (เขียนอย่างนั้นเพราะมันง่ายที่จะแมปตารางความจริง)

ฉันต้องการเชื่อมต่อผลลัพธ์ของตัวนับกับอินพุตของตัวถอดรหัส แต่ฉันได้รับข้อผิดพลาด 'type mismatch' เมื่อพยายามคอมไพล์ใน QuartusII

มีวิธีการแปลงจากประเภท INTEGER เป็นประเภท STD_LOGIC_VECTOR ในรายการ VHDL หรือไม่

คำตอบ:


20

อย่างที่คนอื่นพูดใช้ieee.numeric_stdอย่าเลยieee.std_logic_unsignedซึ่งไม่ใช่แพ็คเกจ IEEE จริงๆ

อย่างไรก็ตามหากคุณใช้เครื่องมือที่มีการสนับสนุน VHDL 2008 คุณสามารถใช้แพ็คเกจใหม่ieee.numeric_std_unsignedซึ่งทำให้การstd_logic_vectorทำงานเป็นไปอย่างไม่ได้ลงนาม

นอกจากนี้เนื่องจากฉันไม่เห็นมันระบุไว้อย่างชัดเจนนี่เป็นตัวอย่างโค้ดจริงในการแปลงจากจำนวนเต็ม (ไม่มีลายเซ็น) เป็นstd_logic_vector:

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

16

ตามที่ LoneTech พูดว่าuse ieee.numeric_stdเป็นเพื่อนของคุณ คุณสามารถแปลง a std_logic_vectorเป็นintegerแต่คุณจะต้องแปลงมันเป็นsignedหรือunsignedก่อน (เนื่องจากคอมไพเลอร์ไม่มีความคิดที่คุณหมายถึง) VHDL เป็นภาษาที่พิมพ์อย่างยิ่ง ฉันเขียนเพิ่มเติมเกี่ยวกับเรื่องนี้ในบล็อกของฉัน

โดยพื้นฐานแล้วฉันจะเปลี่ยน 7seg converter ของคุณให้เป็นinteger(หรือที่จริง a naturalเนื่องจากว่ามันจะจัดการกับตัวเลขที่เป็นบวกเท่านั้น) - การแปลงนั้นเป็นการค้นหาอาร์เรย์ที่เรียบง่าย ตั้งค่าอาร์เรย์คงที่ด้วยการแปลงและเพียงแค่สร้างดัชนีด้วยจำนวนเต็มที่คุณใช้ในเอนทิตีเป็นอินพุต


ขอบคุณสำหรับสิ่งนี้. ฉันขอขอบคุณความคิดเห็นของคุณเป็นอย่างมาก ฉันอยู่ในตำแหน่งผู้ช่วยสอนการเรียนรู้ VHDL เพื่อช่วยให้เริ่มต้นศาสตราจารย์ผู้ซึ่งสั่นเทาเล็กน้อยเกี่ยวกับแนวคิดการเขียนโปรแกรม ฉันจะส่งต่อข้อมูลของคุณไปให้เขา - ตำราที่เราใช้ไม่ได้เจาะลึกคำถาม VHDL 'คุณธรรม'
เจ. พอลเฟอร์

1
มันเป็นปัญหาของ 'คุณธรรม' น้อยกว่ามันรับประกันความมั่นคง numeric_std lib เป็นมาตรฐานจริงที่ก่อตั้งขึ้นโดย IEEE ในขณะที่ std_logic_unsigned ไลบรารี่ถูกสร้างขึ้นโดยผู้ขายและนำไปใช้ในอุตสาหกรรมโดยไม่มีคำจำกัดความเป็นทางการ ไม่มีการรับประกันความเข้ากันได้ระหว่างผู้ขายกับ libs ที่ไม่ได้มาตรฐานแม้ว่าโดยทั่วไปแล้วจะทำงานได้ดี มันเป็นรูปแบบที่ดีในการก้าวไปสู่มาตรฐานในขณะนี้
MattG

1

สมมติว่าตัวนับ 4 บิตของคุณมีเอาต์พุต INTEGER SOME_INTEGER และคุณต้องการแปลงเป็น STD_LOGIC_VECTOR 4 บิต

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

คุณสามารถใช้ฟังก์ชันนี้เพื่อเริ่มต้นเวกเตอร์ด้วยตัวเลขที่มีความหมาย

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

ฉันคิดว่าคุณอาจต้องเพิ่ม "ใช้ IEEE.STD_LOGIC_ARITH.ALL;" และ / หรือ STD_LOGIC_UNSIGNED

การดำเนินการเสริมคือ conv_integer (vector) ฉันชอบที่จะใช้สิ่งนี้เมื่อฉันทำการเปรียบเทียบ ดังนั้นฉันอาจประกาศ

constant SOME_CONSTANT : integer := 999;

จากนั้นต่อมาฉันสามารถใช้สิ่งนี้ในคำสั่ง if

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

แก้ไข: คุณไม่จำเป็นต้องประกาศตัวแปรเป็นจำนวนเต็ม ลองเปลี่ยนการประกาศเป็น std_logic_vector แทน ตัวดำเนินการ + และ - ทำงานกับ std_logic_vectors


3
โปรดอย่าทำเช่นนี้! ใช้ numeric_std (ดู LoneTech และคำตอบของฉัน)
Martin Thompson

หากคุณมีวิธีที่ดีกว่าในการทำเช่นนั้นก็ดี แต่คำแนะนำของฉันใช้ได้ผลฉันคิดว่าการลงคะแนนเสียงของคุณนั้นไม่จำเป็น ฉันใช้ std_logic_arith มาหลายปีแล้วและฉันก็ไม่เคยมีปัญหากับมันเลย ฉันคิดว่าความกลัวเกี่ยวกับผู้ขายที่เปลี่ยนการใช้งานของพวกเขานั้นไม่มีมูลความจริง ผู้ขายที่ถูกต้องในใจของพวกเขาจะเสี่ยงที่จะทำลายการออกแบบของลูกค้า?
ajs410

1
คุณมีคำตอบว่าผู้ขายรายใดจะใส่ข้อมูลเฉพาะของผู้ขายไว้ในเนมสเปซของ IEEE มันยังคงดิบโดยเฉพาะอย่างยิ่งเมื่อจัดการกับค่าลงนามและไม่ได้ลงนาม
Yann Vernier

"เครื่องหมาย + และ - ทำงานกับ std_logic_vectors" AFAIK พวกเขาไม่ทำงานยกเว้นว่าฉันเข้าใจผิดความหมายของคุณ โดยทั่วไปจำเป็นต้องส่งไปยังประเภทที่เก็บข้อมูลที่ลงชื่อ / ไม่ได้ลงชื่อก่อน
stanri

1

คุณอาจจะสนใจในการใช้ชนิดunsignedและจากsigned ieee.numeric_stdพวกมันเข้ากันได้std_logic_vectorแต่มีการตีความตัวเลข (ไบนารีหรือ 2 ส่วนเติมเต็ม) นอกจากนี้ยังมีตัวเลือกที่จะนำการแปลความหมายในstd_logic_vectorแต่นี้จะไม่แนะนำให้ใช้


0

ดังที่คำตอบหลักบอกไว้วิธีที่แนะนำมีดังต่อไปนี้:

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

อย่างไรก็ตามฉันต้องการอธิบายอย่างละเอียดเกี่ยวกับสาเหตุที่แนะนำนี้และทำไม VHDL จึงมีวิธีที่ซับซ้อนเช่นนี้ในการแปลงจำนวนเต็มเป็น std_logic_vectors

มันลงมาเพื่อดูว่าเครื่องมือประเภทนี้ดูได้อย่างไร

standard_logic_vector เป็นพวงของ 1s หรือ 0s ฉันมี 1,0001. หมายเลขนี้คืออะไร? มันขึ้นอยู่กับ มันเซ็นหรือไม่ได้ลงชื่อ? SLV ไม่ทราบหรือไม่สนใจ มีกี่บิต? SLV ของคุณยาวแค่ไหน?

จำนวนเต็มมีการลงนามและมักจะ 32 บิต (ถ้าฉันจำได้อย่างถูกต้อง)

ขั้นตอนที่ 1: ทำให้จำนวนเต็มของฉันสั้นลงและลงนาม นั่นคือส่วนนี้:

to_unsigned(my_int, my_slv'length));

"ฉันมีจำนวนเต็มนี้ฉันต้องการให้มันไม่ได้ลงนามและฉันต้องการให้พอดีกับความยาวของ SLV ของฉัน"

ขั้นตอนที่ 2: จากนั้นนำบิตเหล่านั้นมาใช้เพื่อขับ my_slv

my_slv <= std_logic_vector(...)

"ใช้บิตเหล่านี้และใช้เพื่อขับ slv ของฉัน"

(หมายเหตุเกี่ยวกับคำศัพท์A <= Bใน VHDL อ่านออกมาดัง ๆ ว่า "A ขับเคลื่อนด้วย B")

เมื่อรวมเข้าด้วยกันสิ่งนี้จะทำให้คุณได้รับ:

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

เมื่อมาจากพื้นหลังการเขียนโปรแกรมแบบดั้งเดิมมันง่ายมากที่จะติดอยู่ในวิธีการคิดโปรแกรม แต่ใน VHDL โค้ดที่คุณเขียนมีความหมายทางกายภาพในฮาร์ดแวร์ การรู้ว่าทำไมวิธีการนี้ถึงได้ผลและได้รับการแนะนำก็คือการคิดถึงสิ่งที่คุณเขียนในแง่ของฮาร์ดแวร์

เคล็ดลับโบนัส: ฟังก์ชั่นนำหน้าด้วย to_ เป็นฟังก์ชั่นที่ย่อ / เปลี่ยนแปลงตัวถูกดำเนินการ พวกเขาทำให้พวกเขาไม่ได้ลงนามหรือความยาวหรือทั้งสองอย่าง นี่คือเหตุผลที่ to_unsigned ต้องการให้คุณระบุความยาว ฟังก์ชั่นที่ไม่มี to_ (ตรง std_logic_vector (... ) ในตัวอย่างนี้) ถูกใช้เมื่อชนิดเข้ากันได้โดยตรงแล้ว msgstr "เอาบิตเหล่านี้มาใช้ในประเภทนี้โดยไม่จำเป็นต้องดัดแปลง" #:. สิ่งเหล่านี้ไม่มีอาร์กิวเมนต์ความยาวเนื่องจากทั้งสองด้านมีความเหมือนกันอยู่แล้ว ดังนั้นเมื่อสร้างสิ่งต่าง ๆ เช่นนี้ฉันไม่จำเป็นต้องค้นหามันฉันแค่คิดว่าฉันจะเปลี่ยนข้อมูลอย่างไร


0

ในการแปลงจำนวนเต็มเป็น std_logic_vector คุณมีหลายตัวเลือก ใช้ numeric_std:

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

หรือ

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

ใช้ std_logic_arith:

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

std_logic_arith ไม่ได้เป็นมาตรฐาน ieee แต่เครื่องมือส่วนใหญ่รวบรวมไว้ในห้องสมุด IEEE และมีการใช้กันอย่างแพร่หลาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.