2017-03-28 11 views
1

Verilogの新機能ですが、まだ基本的な問題があります。次のコードはモジュールの一つであり、私が望むように動作しますが、それがより効率的で短く書かれているのか、どうすればいいのでしょうか。 ありがとうございます!ケース・センテンスを使用して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; 


    [email protected] (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 

    [email protected] (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 
+0

あなたは間違いなくそれが短い代わりに、直接の信号の値を使用して比較するたびに作ることができます。例えば、 ''(A == 1'b1)&&(A_i == 1'b0)&&(B == 1'b1)&&(B_i == 1'b1) ''は '' A ' !A_i&B&B_i'' – Krouitch

+0

ケースを使用すると面白いかもしれません。あなたが4つのシグナルを連結した場合( '' wire [3:0] val = {A、A_i、B、B_i} ''としましょう)、 '' val''に応じてケース – Krouitch

+0

'else if(A == A_i == B == B_i) 'は、' == 'を評価する順序があいまいであるので不思議に見えます。もしあなたが 'else if((A == A_i)==(B == B_i))'を意図していたのであれば、if文(case文)のすべての条件は同じ操作をします。 – Greg

答えて

0

お勧めとしてそれはcaseif-elseチェーンを交換することによって短縮することができます。ここに高密度実装があります。また、この種の問題では、ルックアップテーブル(LUT)を使用することができます。ここで

[email protected] (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

+0

ありがとうございました、それは私がやろうとしていたものです。 – surfer113

関連する問題