2016-09-10 165 views
0

プライオリティエンコーダ用のVerilogコードを作成しましたが、このコードはシミュレーション目的では問題ありませんか?合成目的のコードは何ですか?あなたの意見や考えをあきらめてください。プライオリティエンコーダ用のVerilogコード

module pri_encoder(y,i,enable); 
output reg [3:0]y; 
input [15:0]i; 
input enable; 

[email protected](i or enable) 
if(enable) 
if(!i) 
y=4'bx; 
else if(i==1) 
y=4'b0; 
else if(i==2) 
    y=1; 
else if(i==3) 
    y=2; 
    else if(i>=4 && i<=7) 
    y=3; 
    else if(i>=8 && i<=16) 
    y=4; 
    else if(i>=16 && i<=32) 
    y=5; 
    else if(i>=32 && i<=64) 
    y=6; 
    else if(i>=64 && i<=128) 
    y=7; 
    else if(i>=128 && i<=256) 
    y=8; 
    else if(i>=256 && i<=512) 
    y=9; 
    else if(i>=512 && i<=1024) 
    y=10; 
    else if(i>=1024 && i<=2048) 
    y=11; 
endmodule 
+0

コンビナトリアルブロックの 'if(enable)'は、ラッチを意味します。 – Morgan

答えて

0

あなたが持っているデザインはおそらく合成可能ですが、上記のコメントごとにラッチが表示されます。 casex文は、ラッチを取り除くことを条件として、より読みやすくなります。

私が使用している小型のエンコーダです。私はそれを有効にするように修正しました。 "enable + select"入力の幅を{1'b1,6'bxxxxxx}のベクトルの幅と一致させることが重要です。この場合、1 + 6 = 7.必要に応じて拡大することができます。

function [2:0] prienc6; 
input  enable; 
input [5:0] select; 
reg [2:0] out; 
begin 
    casex({enable,select}) 
    {1'b1,6'b000001}: out = 3'b101; 
    {1'b1,6'b00001x}: out = 3'b100; 
    {1'b1,6'b0001xx}: out = 3'b011; 
    {1'b1,6'b001xxx}: out = 3'b010; 
    {1'b1,6'b01xxxx}: out = 3'b001; 
    {1'b1,6'b1xxxxx}: out = 3'b000; 
    {1'b0,6'bxxxxxx}: out = 3'b000; // if you assign out = out, then you get latches. 
    endcase 

    prienc6 = out ; 
end 
endfunction 

あなたは、このような

reg [2:0] encode_out; 

function [2:0] prienc6; 
input  enable; 
input [5:0] select; 
input [2:0] prev_out; 
reg [2:0] out; 
begin 
    casex({enable,select}) 
    {1'b1,6'b000001}: out = 3'b101; 
    {1'b1,6'b00001x}: out = 3'b100; 
    {1'b1,6'b0001xx}: out = 3'b011; 
    {1'b1,6'b001xxx}: out = 3'b010; 
    {1'b1,6'b01xxxx}: out = 3'b001; 
    {1'b1,6'b1xxxxx}: out = 3'b000; 
    {1'b0,6'bxxxxxx}: out = prev_out; 
    endcase 

    prienc6 = out ; 
end 
endfunction 

always @ (posedge clk or posedge reset) 
begin 
    if (reset) encode_out <= 3'b000; 
    else encode_out <= prienc6(some_enable,some_select,encode_out); //latch avoided. 

end 

として、これが適している場合、私は知りませんが、それは私の好ましい解決策である、ラッチを避けるためにprev_out、およびクロックが含まれるように、これを拡張することができます。私は機能の外部を有効にします。

reg [2:0] encode_out; 

function [2:0] prienc6; 
    input [5:0] select; 
    reg [2:0] out; 
    begin 
     casex(select) 
     6'b000001: out = 3'b101; 
     6'b00001x: out = 3'b100; 
     6'b0001xx: out = 3'b011; 
     6'b001xxx: out = 3'b010; 
     6'b01xxxx: out = 3'b001; 
     6'b1xxxxx: out = 3'b000; 
     default : out = 3'b000; 
     endcase 

     prienc6 = out ; 
    end 
    endfunction 

always @ (posedge clk or posedge reset) 
begin 
    if (reset) encode_out <= 3'b000; 
    else  encode_out <= enable ? prienc6(some_input) : encode_out; 
end 
+0

あなたの '(enable、select)'はcase文の構文が不正です。連結形式: '({enable、select})'に変更してください。法的には、 'casex'を使うのは避けてください。代わりに' casez'を使います( 'x'sを'? 'sに変更する)。 casexによるcasexの理由は、ここで説明されています(http://www.verilogpro.com/verilog-case-casezcase2/)とここにあります(http://www.sunburst-design。 com/papers/CummingsSNUG1999SJ_SynthMismatch.pdf)_verilog casexとcasez_の検索時にオンラインの他の情報源 – Greg

+0

ベクトルの連結を修正しました。 –

0

次のコードは3ビット優先エンコーダです。あなたの コードについても同じことが実現できます。私は可能な限りシンプルな方法でコードを書いています。

コードには、回路をラッチに合成させるelse条件は含まれていません。

module priority(input [7:0] a, 
input enable, 
output reg [2:0] b ); 

always @(*) 
begin 
if(enable) 
begin 
if (a[7:0]==1) 
b=0; 
else if(a[7:1]==1) 
b=1; 
else if(a[7:2]==1) 
b=2; 
else if(a[7:3]==1) 
b=3; 
else if(a[7:4]==1) 
b=4; 
else if(a[7:5]==1) 
b=5; 
else if(a[7:6]==1) 
b=6; 
else if(a[7]==1) 
b=7; 
end 
else 
b=4'bxxxx; 
end 
endmodule 
+0

plzどのケースでラッチが発生するのか教えてください。 –

+0

上記のプログラムでは、 'else'コマンドがないと仮定します。 enable = 1の場合、ifブロックが実行され、enable!= 1の場合、progarmはenableが1になるまで待たなければならず、以前の出力値を格納する必要があります。値の格納は、ラッチを使用して行うことができます。 @NavkantTagi –

関連する問題