2012-04-23 3 views
0

私は、組み合わせ論理と行動論理を組み合わせて私の頭を包み込んでいます。私は4つのLEDと66 MHzのクロック入力を持つ小型のFPGAを持っています。アイデアは、2つのものを輝かせ(1つは上がる、もう1つは下る)、もう1つは点滅させることでした。私は、ベンダー固有のDCMを使用したくなかった、と66MHzクロックを持つので、簡単なビット加算器は、魔法をうまくいく組み合わせ論理と行動論理を混合して連続的な割り当てを最適化するか?

module ledflash(input wire CLK, 
     input wire USER_RESET, 
     output wire LED[3:0]); 

    reg [26:0]   cnt; 
    reg [4:0]   pwm; 

    wire    led_enable = ~USER_RESET; 

    always @(posedge CLK) 
    begin 
    if (led_enable) 
     begin 
     cnt <= cnt + 1; 
     pwm <= pwm[3:0] + (cnt[26] ? cnt[25:22] : ~cnt[25:22]); 
     end 
    else 
     begin 
     cnt <= 0; 
     pwm <= 0; 
     end 
    end 

    assign LED[0] = led_enable ? (cnt[26] ? pwm[4] : ~pwm[4]) : 0; 
    assign LED[1] = led_enable ? (cnt[26] ? ~pwm[4] : pwm[4]) : 0; 

    assign LED[2] = led_enable ? cnt[25] : 0; 
    assign LED[3] = led_enable ? ~cnt[25] : 0; 

endmodule 

:だから私は、次のコードを思い付きました。おそらく、デザイン全体が間違っているかもしれません(たとえば、2つのクロックディバイダを使用して、同じことを達成するために2つのレジスタを少しだけ反転させることもできます)が、私はこの状況に遭遇し、 ..

通常のソフトウェア開発者の観点から見ると、重複していると思われる連続的な割り当ての一部があります。たとえば、余分なレジスタを使用することができますので、作業が少なくて済むように見えます。例えば:

module ledglow(input wire CLK, 
     input wire USER_RESET, 
     output wire LED[3:0]); 

    reg [26:0]   cnt; 
    reg [4:0]   pwm; 
    reg    led_pair1; 
    reg    led_pair2; 

    wire    led_enable = ~USER_RESET; 

    always @(posedge CLK) 
    begin 
    if (led_enable) 
     begin 
     cnt <= cnt + 1; 
     pwm <= pwm[3:0] + (cnt[26] ? cnt[25:22] : ~cnt[25:22]); 
     end 
    else 
     begin 
     cnt <= 0; 
     pwm <= 0; 
     end 
    led_pair1 <= cnt[26] ? pwm[4] : ~pwm[4]; 
    led_pair2 <= cnt[25]; 
    end 

    assign LED[0] = led_enable ? led_pair1 : 0; 
    assign LED[1] = led_enable ? ~led_pair1 : 0; 

    assign LED[2] = led_enable ? led_pair2 : 0; 
    assign LED[3] = led_enable ? ~led_pair2: 0; 

endmodule 

私は上記の二つのアプローチのためのシンセサイザーレポートの違いに掘るとHDLの回路図を見しようとしていたが、私のような経験の浅い人のために、それはあまりにも複雑。

間違いなく合成ツールは組み合わせ論理を非常にうまく最適化しますが、右辺の式が1ライナーなどと非常に複雑であると仮定すると、このようなことを言う方法はありますか?

if (some_reg_var) begin 
     assign net0 = 1; 
     assign net1 = 0; 
    end 
    else 
    begin 
     assign net0 = 0; 
     assign net1 = 1; 
    end 

それは意味がありますか?そうでない場合は、そのような場合にレジスタを導入して行動部分を簡素化することは理にかなっていますか?少なくともルールや親指があると確信しています。どんな助けもありがとうございます。

答えて

2

あなたの質問は少し冗長ですが、私はあなたが何を得ているのか理解していると思います。

alwaysブロック内のregsと同様に、if/elseロジックを使用するためにlong assignステートメントを分割する方法があるかどうかを知りたい場合は、

Verilogはいつも私にこのように面白いようでしたが、あなたが何か 'reg'データ型を宣言したという理由だけで、はレジスタに合成されるわけではありません。実際には、ストアする状態がある場合にのみレジスタを作成します。 2

wire a; 
wire b; 
assign a = b ? 0 : 1; 

ケース:

reg a; 
wire b; 

always @(b) 
    if(b) 
     a <= 0; 
    else 
     a <= 1; 

これらの両方がまったく同じロジックを作成する必要があります(

ケース1:次の2つのステートメントは、まったく同じことに合成する必要がある、と述べました単純にa =!bのインバータです。 regを宣言した2番目のケースでも、覚えておく必要はない(すべての入力が機密リストに入っている)ので、実際にはレジスタをインスタンス化するわけではありません。

これにより、複雑なif/elseロジックを記述してコードを簡素化することができます。これは余分なレジスタを合成するというペナルティを支払っているわけではありません。それで、あなたに最も快適な方法を書いてください。 (常時ブロックを使用する場合は、可能性のあるすべてのケースの割り当てがあることを確認するか、必要のないラッチを推測します)。

+0

こんにちはTimさん、お返事ありがとうございます。うん、質問は - どのように実際にレジスタを使用しないでそこに重複条件を避けるためです。私の場合、実際には、ザイリンクスシンセサイザは少し異なるコードを作成し、2つの余分な1ビットレジスタといくつかの異なるマルチプレクサを使用しました。しかしそれ以外の回路図は非常によく似ていました。一方、連続的な割り当てはクロックサイクルごとに実行されます。例えば、100MHzでストローブするシステムクロックによって駆動され、クロック分周器があり、LEDを変更できる「ロジック」がわずかに低いレートで実行されると仮定します。 –

+0

複雑なロジックをブロックに入れますか分周器出力によって駆動され、回路によって実行される全体的な実行ステップ/レート、およびおそらく消費者のエネルギーが減少するか?それは私のように感じる。論理自体はとにかくスペースを占有しません。ちょうどそこにシンセサイザーを圧倒する方法があるかもしれないと思った:) –

+0

これはあなたの最初のコメントへの返信です:これについて詳しく説明できますか?少し異なるコードを作成し、2つの余分な1ビットレジスタを使用しましたか?何よりも余分なレジスタ?どのようなコードですか?あなたのもう一つの質問では、継続的な割り当てはそれだけで、 "継続的"です。クロックサイクルとの関係はありません。連続式への入力が変更されると、出力は直後に(または数ピコ秒後に)変更されます。 – Tim