2017-08-08 95 views
1

我希望有更多VHDL經驗的人可以啓發我!總而言之,我有一個LCD實體和一個主實體來實例化它。液晶顯示屏採用一個84字符的字符串(「msg」),這個字符串在我使用變量或信號索引時似乎會造成很大的問題。我不知道這是什麼原因,但是,由於字符串顯示HEX值,並且每個時鐘週期,我讀取一個16位值...我需要更新每個nybble的字符串的4個字符16位值。這不需要在一個時鐘週期內完成,因爲在大量循環之後讀取新值......但是,嘗試增加一個「t」變量,並且只將字符串值更改爲「t」無論出於何種原因,時間都沒有區別。VHDL - 字符串索引 - RAM使用率和總邏輯元素每增加100%以上

的錯誤是:「錯誤(170048):被選擇設備有型M4K的26 RAM位置(S)」不過,目前的設計需要26個以上的成功適應

以下是編譯報告與問題:

Flow Status Flow Failed - Tue Aug 08 18:49:21 2017 
Quartus II 64-Bit Version 13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition 
Revision Name Revision1 
Top-level Entity Name Main 
Family Cyclone II 
Device EP2C5T144C6 
Timing Models Final 
Total logic elements 6,626/4,608 (144 %) 
Total combinational functions 6,190/4,608 (134 %) 
Dedicated logic registers 1,632/4,608 (35 %) 
Total registers 1632 
Total pins 50/89 (56 %) 
Total virtual pins 0 
Total memory bits 124,032/119,808 (104 %) 
Embedded Multiplier 9-bit elements 0/26 (0 %) 
Total PLLs 1/2 (50 %) 

的RAM彙總表包含57行的 「LCD:顯示屏| altsyncram:複用器#### _ rtl_0 | altsyncram _ ####:AUTO_GENERATED | aLTSYNCRAM」

這裏是LCD實體:

entity LCD is 
    generic(
     delay_time : integer := 50000; 
     half_period : integer := 7 
); 
    port(
     clk  : in std_logic; 
     SCE : out std_logic := '1'; 
     DC : out std_logic := '1'; 
     RES : out std_logic := '0'; 
     SCLK : out std_logic := '1'; 
     SDIN : out std_logic := '0'; 
     op : in std_logic_vector(2 downto 0); 
     msg : in string(1 to 84); 
     jx : in integer range 0 to 255 := 0; 
     jy : in integer range 0 to 255 := 0; 
     cx : in integer range 0 to 255 := 0; 
     cy : in integer range 0 to 255 := 0 
); 
end entity; 

以下代碼是什麼原因造成的問題,其中a,b,c和d是其由4各自後遞增變量讀:

msg(a) <= getHex(data(3 downto 0)); 
msg(b) <= getHex(data(7 downto 4)); 
msg(c) <= getHex(data(11 downto 8)); 
msg(d) <= getHex(data(15 downto 12)); 

卸下一些這些線的使存儲器和邏輯元素使用量都下降了,但它們看起來仍然很荒謬,我不明白原因。 用整數代替a,b,c和d,如1,2,3和4,會導致問題完全消失,邏輯元素爲22%,RAM使用率爲0%!

如果有人有任何想法,我會非常感激!如果有人需要,我會發佈下面的完整代碼......但要警告,這有點麻煩,我覺得問題可能很簡單。提前謝謝了!

Main.vhd LCD.vhd

+0

您正在閱讀多次(嵌套for循環2)從同一ROM中同一時鐘週期(從了getByte函數推斷出),從而合成必須複製ROM來產生足夠的讀端口,因此它產生了很多M4K的塊。您需要序列化,也就是說在多個時鐘週期內進行翻譯操作,因此只需要一個或2個(雙端口ROM)接口。 – Paebbels

+1

@Paebbels聽起來像一個答案。 – plugwash

+2

您的pastebin鏈接將在29天內過期,您的問題不提供[最小,完整和可驗證示例](https://stackoverflow.com/help/mcve),也不提供pastebin代碼。生成一個最小示例的過程可以引導對正在發生的事情以及可以證明其他問題的模擬進行洞察。什麼是LCD顯示,波特率?沒有MCVe或信息,治癒不能進行,例如,雙緩衝區msg,一個緩衝區連接到UART,另一個緩衝區使用多個時鐘中的單個ROM進行組合。 – user1155120

回答

2

這裏有幾個問題。

第一個是HDL綜合工具做了很多優化。這基本上意味着,如果您沒有將輸入和輸出部分正確連接到某個可能(但不確定)被優化程序清除的事物。

第二是你必須非常小心循環和功能。基本上循環將被展開並且函數將被內聯,所以一小段代碼可能會產生大量的邏輯。

第三個是,在某些cicumstances數組將被轉換爲內存元素。

正如在註釋中指出的,這個循環是大量內存使用的根本原因。

for j in 0 to 83 loop 
    for i in 0 to 5 loop 
     pixels((j*6) + i) <= getByte(msg(j+1), i); 
    end loop; 
end loop; 

這有可能會使用大量內存資源。每次調用「getByte」需要在「ram」的(部分)上有一個讀端口,但blockrams只有兩個讀端口。所以「ram」被複制以滿足更多讀端口的需要。內部循環讀取同一位置的不同部分,因此外部循環的每次迭代都需要在RAM上有一個獨立的讀取端口。這就是大約40份的公羊。閱讀旋風2數據表每個副本都需要2 M4K塊

那麼,爲什麼當你使用數字而不是變量a,b,c和d不會出現這種情況?

如果編譯器能弄清楚的東西是一個常數可以在編譯時計算它。這將限制對「像素」的調用次數,這些像素必須被實際轉換爲內存塊,而不是隻將結果硬編碼。儘管如此,我很驚訝它下降到零。

我注意到你的代碼實際上除了時鐘和實際上並沒有被用於任何東西的「rx」輸入之外沒有任何輸入,所以合成器很可能會被搞清楚在構建時有很多東西。通常消除一個代碼可以允許消除另一個位,直到你什麼也沒有剩下。