¿Cuál es la práctica de codificación estándar para una asignación sin bloqueo a una gran matriz de registros con selección de parte variable en Verilog?

No pude encontrar nada en el estándar Verilog-2001 sobre esto. Por ejemplo, el siguiente código funciona (Xilinx ISE):

reg r1;
always @(posedge clk or posedge rst) begin    
    if (rst) begin
        r1 <= 0;
    end else begin
        r1 <= r1;
        if (cond1) begin
            r1 <= 1'b1;
        end 
    end
end

En este caso, r1 se actualiza a 1'b1 cuando cond1es distinto de cero (@ posedge of clk); de lo contrario, conserva su valor (como se esperaba). Similarmente:

1 reg [1023:0] a_reg;
2 always @(posedge trigger or posedge rst) begin    
3     if (rst) begin
4         a_reg <= 0;
5     end else begin
6         a_reg <= a_reg; // required?
7         a_reg[i*2 +: 2] <= input; 
8     end
9 end

¿Se requiere la línea 6? ¿Qué se considera una práctica aceptable para el diseño de FPGA y ASIC? Me imagino que la línea 6 no es necesaria (según la definición de un registro, debe mantener su valor entre asignaciones). ¿O depende de la herramienta de síntesis/compilador (DC Compiler, Xilinx ISE/Vivado, Altera Quartus, etc.)? ¿Hay algo en la norma que arroje luz sobre esto?

Respuestas (1)

r1 <= r1no se requiere en ningún sintetizador, como lo es en la definición de RTL. Dado que la lógica está escrita bajo @posedge clk, está implícito que el valor anterior de un registro r1debe mantenerse en ese ciclo de reloj si r1no se impulsa ningún valor en ese borde de reloj, es decir, en este caso, si cond1se viola la condición.

Esto es cierto para el segundo ejemplo también. El a_regvector está formado por 1024 registros de 1 bit. Por lo tanto, la conclusión anterior que hicimos sobre el registro de 1 bit también r1es aplicable a cada registro en el vector.a_reg

¿Tendrías una fuente o material que cubra esto? ¿O esto solo está implícito en el estándar Verilog?
Esto está implícito para una lógica secuencial escrita en cualquier RTL.