Estoy tratando de escribir un módulo Verilog que genere una señal de reinicio de encendido durante algunos ciclos de reloj. Estoy sintetizando usando Lattice iCEcube2 + Synplify Pro apuntando a un iCE40 HX1K en el Nandland Go Board .
Si escribo el módulo de esta manera, se está optimizando:
`default_nettype none
module reset_generator #(
parameter COUNT_WIDTH = 2
) (
input wire i_clk,
output wire o_rst
);
reg [COUNT_WIDTH:0] rst_count;
assign o_rst = !rst_count[COUNT_WIDTH];
always @(posedge i_clk) begin
if (o_rst == 1) begin
rst_count <= rst_count + 1;
end
end
endmodule
iCEcube2 emite esta advertencia:
...
@N:CL189 : reset_generator.v(13) | Register bit rst_count[4] is always 1.
@N:CL159 : reset_generator.v(6) | Input i_clk is unused.
...
@N:BN115 : ball_absolute_mv_vga_top.v(19) | Removing instance reset_gen (in view: work.ball_absolute_mv_vga_top(verilog)) of type view:work.reset_generator_4s(verilog) because it does not drive other instances.
...
Y puedo verificar que la o_rst
señal nunca se establece en 1
. Pensé que todos los registros se inicializaron en 0
, por lo que no estoy seguro de por qué piensa rst_count[4] is always 1
.
Sin embargo, si configuro explícitamente rst_count
a 0
, así:
reg [COUNT_WIDTH:0] rst_count = 0;
Ahora ya no se optimiza y funciona como se esperaba, pero iCEcube2 muestra esta advertencia:
@W:FX1039 : reset_generator.v(13) | User-specified initial value defined for instance reset_gen.rst_count[4:0] is being ignored.
Esta advertencia también implica que los valores iniciales son 0. Entonces, ¿por qué se optimiza la primera versión? ¿Y por qué agregar un valor inicial que se ignora cambia el comportamiento? ¿Es esto solo una peculiaridad de iCEcube2 y/o Synplify Pro?
EDIT 1 : estoy usando un reinicio de encendido porque Lattice solo puede inicializar registros a cero, y me gustaría que algunos comiencen con valores distintos de cero.
El o_rst
de este reset_generator
componente está conectado a otro componente en un nivel superior como este:
wire w_reset;
reset_generator #(
.COUNT_WIDTH(4)
) reset_gen (
.i_clk(i_clk),
.o_rst(w_reset)
);
ball_absolute ball_absolute (
.clk(i_clk),
.reset(w_reset),
.vsync(o_vga_vsync),
// ...
);
La razón por la que hace esto es porque ball_absolute
tiene un par de registros X/Y para la posición de la pelota en la pantalla. Me gustaría que la pelota comenzara en el medio de la pantalla, no en (0, 0)
. Y debido a que Lattice solo puede inicializar registros en 0
, quiero usar una señal de reinicio de encendido para establecer X/Y en valores distintos de cero.
El proyecto completo está en GitHub .
EDICIÓN 2 : También entiendo que una señal de bloqueo de PLL podría usarse como un reinicio de encendido, pero desafortunadamente el HX1K no tiene ningún PLL. El Go Board utiliza un cristal externo para el reloj.
Esta es probablemente una peculiaridad en synplify. Synplify está diseñado para sintetizar diseños para ASIC, no para FPGA y, como resultado, es bastante obstinado. Para los ASIC, es común no inicializar nada nunca y, en su lugar, utilizar reinicios explícitos. Y como resultado, synplify maneja los bloques iniciales y los inicializadores en línea de manera diferente a las herramientas FPGA; específicamente, en su mayoría los ignora, incluso si causa un comportamiento extraño e inesperado. De todos modos, todas las señales que no se inicializan explícitamente no comienzan en 0, comienzan en X (nivel lógico indeterminado). Y luego las herramientas pueden elegir el valor que quieran durante la síntesis si puede simplificar la lógica. Entonces, parece que eso es lo que synplify está haciendo aquí... Se da cuenta de que puede convertir esa X en particular en un 1 y, como resultado, eliminar un montón de lógica. Si inicializa ese registro a 0, entonces synplify no puede hacer esta optimización, pero le advierte que el inicializador se ignora porque synplify no entiende cómo inicializar los registros, ya que no puede hacerlo en un ASIC. Lo que debe hacer es mantener el init en línea a cero, pero también agregar una entrada de reinicio externa que también puede reiniciar ese registro.
rst_count = 0
e ignorar la advertencia.
mitu raj
usuario253751
cristiano b
Dave Dribin
0
en el encendido y cuenta hacia adelante. Una vezo_rst
que baja,rst_count
permanece en el mismo valor distinto de cero para siempre.Dave Dribin
el fotón
Dave Dribin
el fotón
el fotón
rst_count[4]
)Dave Dribin