私は、組み合わせ論理と行動論理の組み合わせに頭を悩ませようとしています。4つのLEDと66MHzのクロック入力を備えた小さなFPGAがあります。アイデアは、それらのうちの2つを光らせ(1つは上昇、1つは下降)、もう2つは点滅させることでした。だから私は次のコードを思いついた:
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
ベンダー固有のDCMを使用したくなかったので、66MHzのクロックを備えた単純なビット加算器が魔法のように機能します。そもそも全体の設計が間違っているかもしれませんが(たとえば、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
私は上記の2つのアプローチのシンセサイザーレポートの違いを掘り下げてHDL回路図を調べようとしていましたが、私のような経験の浅い人には複雑すぎます。
合成ツールが組み合わせロジックを非常にうまく最適化することは間違いありませんが、右側の式が非常に複雑でワンライナーなどであると仮定すると、このようなことを言う方法はありますか?
if (some_reg_var) begin
assign net0 = 1;
assign net1 = 0;
end
else
begin
assign net0 = 0;
assign net1 = 1;
end
それともそうすることは理にかなっていますか?そうでない場合は、動作部分を単純化するために、そのような場合にレジスタを導入することは理にかなっていますか?少なくともいくつかのルールや親指があると確信しています。どんな助けでも大歓迎です。