Я новичок в Verilog и пытаюсь реализовать очень простую логику для генерации импульса точной ширины. Я использую плату разработки ICE40 FPGA и IceStudio. У меня есть сигнал CLK с периодом ~ 83 нс (12 МГц), и я хочу генерировать импульсы с периодом ~ 1245 нс, но разной длины (например, большое время ~ 415 нс и низкое время ~ 830 нс) .
Я подумал, что мог бы сделать это, сделав вращающийся сдвиговый регистр длиной 15 бит, а затем переключить мой выход ВЫСОКИЙ на передний фронт первого бита, а затем переключить его на НИЗКИЙ на заднем фронте пятого бита. Вот код, который я придумал:
reg [14:0] shifter;
reg OUT;
initial begin
shifter <= 15'b01;
end
always @(posedge CLK) begin
shifter <= shifter << 1;
shifter[0] <= shifter[14];
end
always @(posedge shifter[0]) begin
OUT <= 1;
end
always @(negedge shifter[4]) begin
OUT <= 0;
end
Если я назначу отдельные биты «сдвига» для выхода, я смогу проверить в области видимости, что этот регистр сдвига работает должным образом; но, несмотря на это, OUT остается НИЗКИМ, как будто блоки «всегда» никогда не срабатывают.
Каждый учебник, который я нашел в Интернете, где обсуждаются блоки «всегда @ (posegde)» или «всегда @ (negegde)», делает это на каком-то внешнем сигнале, таком как CLK или RESET. Мне интересно, что я совершаю какую-то ошибку новичка, предполагая, что она также может работать с внутренней переменной регистра, такой как "shiftter".
Может кто-нибудь объяснить мне, так ли это на самом деле?
ОБНОВЛЕНИЕ: Следующий код делает то, что я хочу, но все же любопытно, почему моя оригинальная реализация не работает:
reg [14:0] shifter;
reg OUT;
initial begin
shifter <= 15'b01;
end
always @(posedge CLK) begin
shifter <= shifter << 1;
shifter[0] <= shifter[14];
OUT <= shifter[0] | shifter[1] | shifter[2] | shifter[3] | shifter[4] | shifter[5];
end