Предположим, есть конечный автомат, который в работе должен пробрасывать тактовую частоту через себя, а в состоянии IDLE установить выход тактовой частоты в единицу.
Тогда код может быть следующий:
Код
wire clk_in;
wire clk_out;
reg state;
assign clk_out = clk_in | ~(state^IDLE);
Т.е. если state и IDLE совпадают бит-в-бит, то их побитовый XOR будет равен нулю. Инвертированный ноль - это единица. Единица или clk_in - единица. В противном случае, ноль или clk_in - это clk_in.
Всё абсолютно прозрачно синтезируется.
Или код может быть такой:
Код
wire clk_in;
wire clk_out;
reg state;
assign clk_out = clk_in | (state == IDLE);//На месте синтезатора я заменил бы данную конструкцию на предыдущую
Или такой:
Код
wire clk_in;
wire clk_out;
reg state;
assign clk_out =(state == IDLE) ? 1 : clk_in;
Но почему не прокатывает следующий вариант?
Код
wire clk_in;
wire clk_out;
reg state;
always @(state)
begin
if(state == IDLE) begin
clk_out = 1;
end
else begin
clk_out = clk_in;
end
end
В таком варианте Квартус ругается на то, что "10137: Object on left-hand side of assignment must have a variable data type".
Не, ну нельзя, так - нельзя. Но эмм... в списке чувствительности отсутствуют posedge/negedge. В любом случае, синтезатор будет разворачивать эту конструкцию в комбинационную логику (причем, скорее всего в такую, как в первом примере). Так чего же он лезет на рожон (регистр ему подавай)? Какова логика языка? Почему так писать некорректно?