Estoy tratando de construir un divisor de frecuencia en un iCEstick de Lattice usando Verilog (con yosys, arachne-pnr, y icepack / iceprog):
module demo(input clk, output LED1, LED2, LED3, LED4, LED5);
assign LED1 = state;
// Generate impulse at lower frequency:
wire out_clk;
reg [31:0] cnt;
initial cnt <= 0;
always @(posedge clk) cnt <= cnt >= 6000000 ? 0 : cnt + 1;
assign out_clk = cnt == 0;
// On impulse, toggle state:
reg state;
initial state <= 0;
always @(posedge out_clk) state <= ~state;
endmodule
Esto funciona como se esperaba, es decir, el LED en la placa parpadea una vez por segundo (el reloj es de 12MHz).
Sin embargo, cuando 6000000 ('h5B8D80) se reemplaza por 5000000 (' h4C4B40), el LED simplemente permanece encendido permanentemente. ¿Por qué es eso?
Simulando con Icarus muestra los cambios de estado esperados, sin importar cuál sea el divisor.
Aquí hay una tabla de experimentos con más valores:
'h5B8D80 blinking
'h5B8D7f permanently on
'h5B8D7e blinking
'h5B8D7d blinking
'h5B8D7c blinking
'h5B8D78 blinking
'h5B8D70 blinking
'h5B8D60 blinking
'h5B8D40 blinking
'h5B8D00 blinking
'h5B8C80 blinking
'h4C4B40 permanently on
'h400000 blinking
También, para 'h4C4B40 agregando la línea "asignar LED2 = 1;" hace que LED1 (!) parpadee como se esperaba. Este no es el caso para 'h5B8D7f.
En conjunto, el comportamiento parece muy aleatorio.
EDITAR Para el registro, al sintetizar el mismo diseño con iCEcube2 de Lattice, el problema no se produce.