2016-11-30 94 views
0

這是一個微不足道的問題,但是經過我的大腦之後,我想到了在這裏發佈它。當我在Verilog中使用條件操作時出現錯誤

在我的代碼我使用條件操作寫入的線,如下所示:

assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00? (!DisI? {rs2, rs1} : 64'bz) : (RdEn==2'b01? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn}))) : 64'bz; 
  1. RS2 & RS1是32根的輸出導線。
  2. Rn & Rm是32位輸入。
  3. rs1 & rs2是32位寄存器。
  4. RdEn是2位寄存器。
  5. DisI和開關是一位寄存器。

enter image description here

模擬器(伊卡洛斯0.9.7或任何)是表示有在上述行語法錯誤。 請幫幫我。

在此先感謝。

這裏是我的代碼,它解決了同樣的問題:

module TEST(Rn, Rm, DisM, DisX, DisI, switch, RdEn, RS1, RS2); 
input [31:0]Rn, Rm; 
input DisM, DisX, DisI, switch; 
input [1:0]RdEn; 
output [31:0]RS1, RS2; 

reg [31:0]rs1, rs2; 

[email protected]* 
begin 
    rs1 = Rn + 32'd7; 
    rs2 = Rm - 32'd7; 
end 

assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00? (!DisI? {rs2, rs1} : {64{1'bz}}) : (RdEn==2'b01? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn}))) : {64{1'bz}}; 

endmodule 
+2

您的第338行與這麼多的條件是超級混淆。爲什麼不把它分開?這將爲理解和調試提供更清晰的代碼。 – noobuntu

回答

2

編譯器在RdEn==2'b00?解釋?爲第3位,而不是作爲三元運算符。只需在b00?之間加一個空格。相同的b01?

?是一個有效的z_digit。請參閱IEEE標準1800-2012,第5.7節數字。

而且,你有括號的數量不匹配(一個好的編輯器可以顯示出這一點):

assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00 ? (!DisI? {rs2, rs1} : {64{1'bz}}) : (RdEn==2'b01 ? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn})) : {64{1'bz}}; 

它也使用{64{1'bz}}來確保你得到的1'bz 64位的好習慣。

+0

沒有相同的錯誤消息。 – Arvind

+0

我已經使用edaplayground以及Xilinx的Isim – Arvind

+0

答案更新。 – toolic

1

雖然您已經有了一個可接受的答案,但我強烈建議您重新編碼分配。因爲它很難閱讀,因此難以調試。至少添加返回線和縮進,因此條件很容易在視覺上配對。例如,以下是工具解決方案的副本,其中添加了換行符和空格。請注意0​​問題如何在這種格式化風格下無法實現。像emacs和vim這樣的編輯器有語法插件,可以幫助縮進格式。

assign {RS2, RS1} = (!DisM || !DisX) 
    ? (RdEn==2'b00 
    ? (!DisI ? {rs2, rs1} : {64{1'bz}}) 
    : (RdEn==2'b01 
     ? (!switch ? {rs2, Rn} : {Rn, rs1}) 
     : {Rm, Rn})) 
    : {64{1'bz}}; 

在實踐中我發現條件運算?:(W/O高Z)通常使顯式2:合成時,1複用器其可以不是最佳的定時和麪積。我還發現保持三態分配簡單可以得到更清晰的結果。

我通常推薦的方法是確定輸出使能和輸出數據與三態分配獨立。通過這種方法,合成器通常比一個長分配語句更好地工作;至少從我的經驗來看。如果您擁有數量有限的三態驅動器,這種方法也很好,這對於FPGA來說很常見。

wire out_en = (!DisM || !DisX) && !(RdEn==2'b00 && !DisI); 
reg [63:0] out_data; 
always @* begin 
    case(RdEn) 
    2'b00 : out_data = {rs2, rs1}; 
    2'b01 : out_data = !switch ? {rs2, Rn} : {Rn, rs1}); 
    default : out_data = {Rm, Rn}; 
    endcase 
end 
assign {RS2, RS1} = out_en ? out_data : {64{1'bz}}; 

有時並聯的三態驅動器與非重疊啓用在滿足一些設計標準方面做得更好。這種方法可以根據技術節點和體系結構減少時間。通常會有一個區域受到影響,如果負載太多,它可能會對時間產生負面影響。

assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b00 && !DisI) ? {rs2, rs1} : {64{1'bz}}; 
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b01 && !switch) ? {rs2, Rn} : {64{1'bz}}; 
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b01 && switch) ? { Rn, rs1} : {64{1'bz}}; 
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn[1])    ? { Rm, Rn} : {64{1'bz}}; 

無論使用何種方法,請確保三態的啓用控制是無毛刺的。如果信號不乾淨,可能會導致總線爭用。理想情況下,啓用信號應該是直接觸發。在實踐中,觸發使能信號並不總是可行,所以您需要密切關注。您通常不會在RTL模擬中看到潛在的故障。如果出現問題,綜合報告可能會有所瞭解。

相關問題