2010-05-05 70 views
2

我使用三元語言翻譯了以下代碼。但是,我知道它有什麼問題。有人可以請我指出正確的方向嗎?將if else語句轉換爲三元

ForwardA = 0; 
ForwardB = 0; 

//EX Hazard 
if (EXMEMRegWrite == 1) begin 
if (EXMEMrd != 0) 
    if (EXMEMrd == IDEXrs) 
     ForwardA = 2'b10; 
    if (EXMEMrd == IDEXrt && IDEXTest == 0) 
     ForwardB = 2'b10; 
end 


//MEM Hazard 

if (MEMWBRegWrite == 1) begin 
if (MEMWBrd != 0) begin 
    if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs))) 
      if (MEMWBrd == IDEXrs) 
       ForwardA = 2'b01; 
    if (IDEXTest == 0) begin 
     if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt))) 
      if (MEMWBrd == IDEXrt) 
       ForwardB = 2'b01; 
    end 
end 
end 



ForwardA = (MEMWBRegWrite && MEMWBrd != 0 && (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs))) && (MEMWBrd == IDEXrs)) ? 
            2'b01 : ((EXMEMRegWrite && EXMEMrd != 0 && EXMEMrd == IDEXrs) ? 2'b10 : 0); 

ForwardB = (IDEXTest == 0 && MEMWBRegWrite && MEMWBrd != 0 && (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt))) && (MEMWBrd == IDEXrs)) ? 
            2'b01 : ((EXMEMRegWrite && EXMEMrd != 0 && EXMEMrd == IDEXrt && IDEXTest == 0) ? 2'b10 : 0); 
+9

將其分解成小塊。沒有合理的理由把這種複雜性的條件放在一條線上。 – 2010-05-05 16:23:16

+0

這是什麼語言? – 2010-05-05 16:24:22

+1

這既不是C,C++也不是Java – sth 2010-05-05 16:25:17

回答

10

令人驚訝的是,我要冒險downvotes,並告訴你,正確的方向是離開你的代碼在其相對可讀狀態。

我懷疑你能做到這一點會更糟糕的唯一的事情是做它作爲一個正則表達式或將其轉換爲內聯彙編:-)

,它是轉換容易要告訴你的事實關於你在嘗試什麼的智慧。


基於別處您的評論:

這是Verilog和因此,我需要做的是在三元和不能有別的如果,否則,我需要之前一直阻止我不想說......我想剩下的是0,如果沒有條件在其他如果是滿足上述

好吧,如果你必須做到這一點,對我的建議(我」我不是一個人在這裏提供這個advic e),這裏是你應該使用的方法(我不知道什麼是「永遠封鎖」,即使我沒有資格與你爭論點)。

由於您當前的代碼將ForwardAForwardB設置爲值,只有在某些條件下才更改它們,您可以通過顛倒順序將其轉換爲三元組。這是因爲,在您的if版本中,後面的代碼優先,但先前的代碼優先於三元。

找出在什麼情況下ForwardAForwardB設置爲相反的順序並重建這些條件。

這是您的原始代碼,壓縮了一下。我也將2'b10的東西改爲2'b10',所以我們仍然在SO渲染引擎中獲得了不錯的格式化 - 不要忘記將它們改回。

ForwardA = 0; 
ForwardB = 0; 
if (EXMEMRegWrite == 1) begin 
if (EXMEMrd != 0) 
    if (EXMEMrd == IDEXrs) 
     ForwardA = 2'b10'; 
    if (EXMEMrd == IDEXrt && IDEXTest == 0) 
     ForwardB = 2'b10'; 
end 
if (MEMWBRegWrite == 1) begin 
if (MEMWBrd != 0) begin 
    if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs))) 
      if (MEMWBrd == IDEXrs) 
       ForwardA = 2'b01'; 
    if (IDEXTest == 0) begin 
     if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt))) 
      if (MEMWBrd == IDEXrt) 
       ForwardB = 2'b01'; 
    end 
end 
end 

你可以看到B被設置在三個地方。它在底部的if,2'b10中設置爲2'b01,開頭爲0。轉換的條件:

ForwardB = ((MEMWBRegWrite == 1) && 
      (MEMWBrd != 0) && 
      (IDEXTest == 0) && 
      (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt))) && 
      (MEMWBrd == IDEXrt)) 
      ? 2'b01' 
      : ((EXMEMRegWrite == 1) && 
       (EXMEMrd != 0) && 
       (EXMEMrd == IDEXrt && IDEXTest == 0)) 
       ? 2'b10' 
       : 0; 

同樣,對於答:

ForwardA = ((MEMWBRegWrite == 1) && 
      (MEMWBrd != 0) && 
      (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs))) && 
      (MEMWBrd == IDEXrs)) 
      ? 2'b01' 
      : ((EXMEMRegWrite == 1) && 
       (EXMEMrd != 0) && 
       (EXMEMrd == IDEXrs)) 
       ? 2'b10' 
       : 0; 

現在背後的理論是好的,但如果我在轉錄犯了一個錯誤,我也不會半點驚訝,或者Verilog的只是把它的手在厭惡,拿起它的球,一溜小跑回家:-)

我至少可以表明,如果你一定要沿着這條路走下去,你倆:

  • 試着讓三元表情至少有一個可讀,帶有所有漂亮的空白和多行;和
  • 將原始代碼保留在註釋中,至少如果您有問題或想要更改邏輯,至少可以返回到原始代碼?

真的,你會感謝我在半年的時間,當你正在尋找在這個一遍,試圖找出地球上你想什麼:-)

+2

爲什麼有人會低聲說你應該說什麼? – Paul 2010-05-05 16:29:37

+0

總是存在風險 - 畢竟我沒有提供所要求的答案。然而,自從我從80年代初就開始從事這個行業以來,我已經很熟練地告訴人們他們錯了什麼時候,但現在比我以前更爲巧妙:-) – paxdiablo 2010-05-05 16:32:03

+0

你是絕對正確的。用三元數轉換它沒有意義。它不會提供更好的代碼,並且可讀性也較差。 OP轉錄錯誤並且無法糾正的事實是一個很好的指標,他不應該這樣做。 – 2010-05-05 16:54:51

1

好吧,假設你堅持無論出於何種原因保持它的三元形式,如果你只是正確地格式化它,你的可讀性會大大提高。現在

const bool cond1 = MEMWBRegWrite && MEMWBrd != 0 && 
        !(EXMEMRegWrite == 1 && EXMEMrd != 0 && EXMEMrd == IDEXrs) && 
        MEMWBrd == IDEXrs; 
ForwardA = cond1 
      ? 2'b01 
      : ((EXMEMRegWrite && EXMEMrd != 0 && EXMEMrd == IDEXrs) ? 2'b10 : 0); 

const bool cond2 = IDEXTest == 0 && 
        MEMWBRegWrite && MEMWBrd != 0 && 
        !(EXMEMRegWrite == 1 && EXMEMrd != 0 && EXMEMrd == IDEXrt) && 
        MEMWBrd == IDEXrs; 
ForwardB = cond2 
      ? 2'b01 
      : ((EXMEMRegWrite && EXMEMrd != 0 && EXMEMrd == IDEXrt && IDEXTest == 0) ? 2'b10 : 0); 

,該代碼被格式化,就好像它,而不是無論你實際使用的是C++,但它變得更容易弄清楚發生了什麼事情。

但是,我會指出你的if語句不可能匹配你的三元表達式。你的if語句沒有else語句,而且三元表達式總是還有其他從句。但是,由於你的問題甚至沒有完全清楚你是否試圖將if語句轉換成三元表達式,或者將三元表達式轉換爲if語句,所以要準確地給你想要的東西有點困難。

編輯:三元表達式總是同時具有if和else子句。你不能直接把一個沒有else子句的if語句變成一個三元語,因爲你不會有三元語的其他部分。現在,如果需要,可以在某些情況下使用一些技巧,例如爲自己設置變量。例如,

ForwardA = cond1 ? newValue : FordwardA; 

你基本上說不要改變else子句中的值 - 但這是假設你將結果賦值給一個變量。表達越複雜,拉動這種技巧就越困難,代碼變得越複雜。更何況,根據編譯器做了什麼或不做什麼優化,它可能會將變量分配給自己,這不是非常有效。

一般來說,將沒有else子句的if語句翻譯成三元表達式是一個壞主意。它只能通過拉扯技巧來完成,而不是直接說出你的意思,這隻會讓事情變得複雜。而且這段代碼很複雜。

我建議不要在這裏使用三元組,除非你真的需要它。如果你這樣做,至少要打破這個表達。即使你的三元表達是正確的,它的很多難以閱讀比if語句。

編輯2:如果你確實需要這是三元的表達,那麼我建議你坐下來,找出其下ForwardA應該是什麼樣的設定值的確切條件,並創建一個三元表達式基於此,而不是試圖直接轉換您擁有的if語句(以及ForwardB的相同語句)。您的if-statments不僅決定分配給每個變量的值,而且決定將該值賦予哪個變量,這會使事情變得複雜。

在其他語言(我不知道verilog)中,除了表達式右側的任何操作外,還可以使用三元表達式來選擇要賦值的變量,但這是變得非常複雜。最好創建一個臨時值來保存要分配的值,並創建一個單獨的三元來確定將其分配給哪個變量。

不知道verilog,我真的不知道你可以做什麼,不能做if語句和三元表達式,但我會認爲有一個更好的方法來處理這個比使用三元。也許不是,但你想要做的是非常困難和容易出錯。

+0

我其實是從三元組轉換成三元組...所以你是說在這種情況下不可能把三元組分解成三元組? – aherlambang 2010-05-05 16:42:19

+0

我設法弄清楚MEMWBrd == IDEXrs的問題;應該是MEMWBrd == IDEXrt;爲前鋒乙 – aherlambang 2010-05-05 21:31:15

1

第一個不這樣做!沒有意義,這樣做。它不會編譯爲更好的代碼,並且可讀性更差,正如您在嘗試更正它時注意到的那樣。如果你需要它作爲表達式,最好將它編碼爲內聯函數。

3

你不需要這樣做。將代碼粘貼在「always @ *」塊中,並將您分配的任何內容聲明爲「reg」。

reg [1:0] ForwardA; 
reg [1:0] ForwardB; 

always @(*) begin 
    // Your combo logic here.. 
end