【问题标题】:How can write code in verilog shorter using case sentence如何使用案例句在verilog中编写更短的代码
【发布时间】:2017-03-28 13:04:09
【问题描述】:

我是 Verilog 的新手,但在基础知识方面仍有一些问题。下面的代码是模块之一,按照我想要的方式工作,但我想知道它是否可以写得更高效、更短,以及如何完成。 感谢您的帮助!

`timescale 1ns / 1ps


module COUNTER
  (
    input A_i,
    input B_i,
    input ENABLE_i,
    input CLK,
    input RESET,
    input R_i,
    input UP_DOWN_i, // za realno stanje se UP_DOWN_o prepisuje v UP_DOWN_i
    output reg signed [7:0] VALUE_o,
    output reg UP_DOWN_o  
  );



  reg A;
  reg B;
  reg signed [7:0] VALUE_cmp;
  wire [1:0] A_B={A,B};

  initial VALUE_o = 8'b00000000;
  initial VALUE_cmp = 8'b00000000;
  initial A = 1'b0;
  initial B = 1'b0;
  initial UP_DOWN_o = 1'b1;


  always@ (posedge CLK or posedge RESET)
  begin
    A <= A_i;
    B <= B_i;
    VALUE_cmp <= VALUE_o; 

    if (RESET || R_i)
    begin
      VALUE_o<= 8'b0;
      VALUE_cmp <=8'b0;  
    end

    else if (ENABLE_i)
    begin

//up or down
      if (UP_DOWN_i)
      begin 
//up
        if ((A == 1'b0) && (A_i == 1'b0) && (B == 1'b0) && (B_i == 1'b1))
          VALUE_o <= VALUE_o+1;  
        else if ((A == 1'b0) && (A_i == 1'b1) && (B == 1'b1) && (B_i == 1'b1))
          VALUE_o <= VALUE_o+1;  
        else if ((A == 1'b1) && (A_i == 1'b1) && (B == 1'b1) && (B_i == 1'b0))
          VALUE_o <= VALUE_o+1;  
        else if ((A == 1'b1) && (A_i == 1'b0) && (B == 1'b0) && (B_i == 1'b0))
          VALUE_o <= VALUE_o+1;
// change
        if ((A == 1'b0) && (A_i == 1'b1) && (B == 1'b0) && (B_i == 1'b0))
            VALUE_o <= VALUE_o+1;
        else if ((A == 1'b1) && (A_i == 1'b1) && (B == 1'b0) && (B_i == 1'b1))
            VALUE_o <= VALUE_o+1;  
        else if ((A == 1'b1) && (A_i == 1'b0) && (B == 1'b1) && (B_i == 1'b1))
            VALUE_o <= VALUE_o+1;
        else if ((A == 1'b0) && (A_i == 1'b0) && (B == 1'b1) && (B_i == 1'b0))
            VALUE_o <= VALUE_o+1;
// after  
        else if (A == A_i ==B == B_i )
            VALUE_o <= VALUE_o+1;              
      end

      else
      begin
 //down  
        if ((A == 1'b0) && (A_i == 1'b1) && (B == 1'b0) && (B_i == 1'b0))
            VALUE_o <= VALUE_o-1;
        else if ((A == 1'b1) && (A_i == 1'b1) && (B == 1'b0) && (B_i == 1'b1))
            VALUE_o <= VALUE_o-1;  
        else if ((A == 1'b1) && (A_i == 1'b0) && (B == 1'b1) && (B_i == 1'b1))
            VALUE_o <= VALUE_o-1;
        else if ((A == 1'b0) && (A_i == 1'b0) && (B == 1'b1) && (B_i == 1'b0))
            VALUE_o <= VALUE_o-1;         
//change     
        else if ((A == 1'b1) && (A_i == 1'b1) && (B == 1'b1) && (B_i == 1'b0))
                VALUE_o <= VALUE_o-1;
        else if ((A == 1'b0) && (A_i == 1'b1) && (B == 1'b1) && (B_i == 1'b1))
                VALUE_o <= VALUE_o-1;
        else if ((A == 1'b0) && (A_i == 1'b0) && (B == 1'b0) && (B_i == 1'b1))
                        VALUE_o <= VALUE_o-1;
        else if ((A == 1'b1) && (A_i == 1'b0) && (B == 1'b0) && (B_i == 1'b0))
                                VALUE_o <= VALUE_o-1;
// after  
        else if (A == A_i ==B == B_i )
            VALUE_o <= VALUE_o-1;     
       end
      end
  end

  always@ (posedge CLK) // kasneje potrebo vezat za UP_DOWN_o
  begin      
       //steje dol
      if (VALUE_cmp > VALUE_o)
        UP_DOWN_o <= 0;

      //steje gor
      else if (VALUE_cmp < VALUE_o)
          UP_DOWN_o <= 1;        
  end        
endmodule

【问题讨论】:

  • 您绝对可以通过直接使用信号的值来缩短它,而不是每次都进行比较。例如:(A == 1'b1) &amp;&amp; (A_i == 1'b0) &amp;&amp; (B == 1'b1) &amp;&amp; (B_i == 1'b1)A &amp; !A_i &amp; B &amp; B_i 相同
  • 使用案例可能会很有趣。如果你连接你的 4 个信号(比如说wire [3:0] val = {A,A_i,B,B_i}),你可以根据val 使用 case 执行各种操作
  • else if (A == A_i ==B == B_i ) 看起来很奇怪,因为评估 == 的顺序不明确。也许你打算else if ((A == A_i) == (B == B_i)),但如果你这样做了,if-statements(case-statement) 的所有条件都会执行相同的操作。

标签: verilog fpga system-verilog hdl


【解决方案1】:

按照您的建议,可以通过将 if-else 链替换为 case 来缩短它。这是密集的实现。同样在这类问题中,您可以使用查找表 (LUT)。

  always@ (posedge CLK or posedge RESET)
  begin
    A <= A_i;
    B <= B_i;
    VALUE_cmp <= VALUE_o; 

    if (RESET || R_i)
    begin
      VALUE_o<= 8'b0;
      VALUE_cmp <=8'b0;  
    end

    else if (ENABLE_i)
    begin

//up or down
      if (UP_DOWN_i)
      begin 

        case({A,A_i,B,B_i})
            //up
            4'b0001, 4'b0111,
            4'b1110, 4'b1000,
            // change
            4'b0100, 4'b1101,
            4'b1011, 4'b0010:
                VALUE_o <= VALUE_o+1;
        endcase
        if (A == A_i ==B == B_i )
            VALUE_o <= VALUE_o+1; 
        end

      else
      begin

        case({A,A_i,B,B_i})
        //down 
        4'b0100, 4'b1101,
        4'b1011, 4'b0010,
        //change  
        4'b1110, 4'b0111,
        4'b0001, 4'b1000:
            VALUE_o <= VALUE_o-1;
        endcase
// after  
        else if (A == A_i ==B == B_i )
            VALUE_o <= VALUE_o-1;     
       end
      end
  end

以下是 LUT 实现的参考: https://www.csee.umbc.edu/~tinoosh/cmpe415/slides/Rom-LUT-verilog.pdf

【讨论】:

    猜你喜欢
    • 2023-01-26
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多