Оптимизация непрерывного назначения путем смешивания комбинационной и поведенческой логики?
Я пытаюсь обернуть голову вокруг сочетания комбинационной и поведенческой логики. У меня есть небольшая FPGA с 4 светодиодами и тактовым входом 66 МГц. Идея состояла в том, чтобы заставить двух из них светиться (один поднимается, один падает), а другой - мигать. Итак, я придумал следующий код:
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 для конкретного производителя, поэтому простые битовые сумматоры с тактовой частотой 66 МГц дают волю волшебству. Возможно, весь дизайн изначально неправильный (например, я мог бы использовать два делителя тактовых импульсов и просто перевернуть немного из двух регистров, чтобы достичь (почти) одного и того же), но я столкнулся с этой ситуацией, которая заставила меня задуматься...
С точки зрения обычного разработчика программного обеспечения, в непрерывных назначениях есть несколько частей, которые кажутся излишними. Например, можно использовать дополнительный регистр, и, таким образом, кажется, что выполняется меньше работы. Например:
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, но это слишком сложно для такого неопытного парня, как я.
Без сомнения, инструмент синтеза очень хорошо оптимизирует комбинационную логику, но при условии, что выражения правой части очень сложны, чтобы быть однострочными и т. Д., Есть ли способ сказать что-то подобное?
if (some_reg_var) begin
assign net0 = 1;
assign net1 = 0;
end
else
begin
assign net0 = 0;
assign net1 = 1;
end
Или это вообще имеет смысл сделать? Если нет, имеет ли смысл вводить регистры в таких случаях, чтобы упростить поведенческую часть? Я уверен, что есть некоторые правила или по крайней мере. Любая помощь приветствуется.
1 ответ
Ваш вопрос немного многословен, но я думаю, что понимаю, к чему вы клоните (поправьте меня, если я ошибаюсь).
Вы хотите знать, есть ли способ разбить длинные операторы присваивания, чтобы использовать логику if/else, похожую на reg в блоке Always?
Verilog всегда казался мне немного смешным в этом смысле, но только потому, что вы объявляете что-то тип данных 'reg' , не означает, что он синтезируется в регистр. Фактически он создает регистр только в том случае, если есть какое-то состояние для хранения. Сказав это, следующие два утверждения должны объединить в одно и то же:
Случай 1:
wire a;
wire b;
assign a = b ? 0 : 1;
Случай 2:
reg a;
wire b;
always @(b)
if(b)
a <= 0;
else
a <= 1;
Оба из них должны создать точно такую же логику (просто инвертор с a =! B). Даже во втором случае, когда вы объявили reg, он на самом деле не создает регистр, потому что нечего запоминать (все входные данные находятся в списке чувствительности).
Из-за этого вы можете свободно писать сложную логику if/else для упрощения вашего кода, и это не означает, что вы платите штраф за синтез дополнительных регистров. Так что не стесняйтесь писать это, какой путь для вас наиболее удобен. (Если вы используете блок всегда, убедитесь, что у вас есть назначение для всех возможных случаев, или вы обнаружите защелку, которую вы, вероятно, не хотите).