2010-05-05 74 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