¿Cómo funcionan los bucles for en verilog? ¿Por qué no puedo lograr lo que quiero?

Este es mi código para un multiplexor simple de 2-1 8 bits, donde SW[17]está mi selector.

Si está encendido, muestra Y = SW[15:8], si está apagado, muestra X = SW[7:0].

module part2 (SW, LEDR, LEDG);

    input [17:0] SW; //inputs
    output [17:0] LEDR; //light every switch
    output [7:0] LEDG;  //byte desired

    //All switches to red leds.
    assign LEDR = SW;       

    //Green leds get the desired byte.
    assign LEDG[0] = (~SW[17] & SW[0]) | (SW[17] & SW[8]);
    assign LEDG[1] = (~SW[17] & SW[1]) | (SW[17] & SW[9]);
    assign LEDG[2] = (~SW[17] & SW[2]) | (SW[17] & SW[10]);
    assign LEDG[3] = (~SW[17] & SW[3]) | (SW[17] & SW[11]);
    assign LEDG[4] = (~SW[17] & SW[4]) | (SW[17] & SW[12]);
    assign LEDG[5] = (~SW[17] & SW[5]) | (SW[17] & SW[13]);
    assign LEDG[6] = (~SW[17] & SW[6]) | (SW[17] & SW[14]);
    assign LEDG[7] = (~SW[17] & SW[7]) | (SW[17] & SW[15]);

endmodule

Este código es simple, pero estoy tratando de optimizarlo y reemplazar las 8 líneas.

Quería usar algún tipo de bucle, pero fallé:

integer index;
initial
   begin
   for(index = 0; index < 8; index  = index+1)
       begin
       assign LEDG[index] = (~SW[17] & SW[index]) | (SW[17] & SW[index+8]);
       end
   end

También probé esto, y fallé:

//Green leds get the desired byte.
always @(SW) begin
    if (~SW[17])
        assign LEDG = SW[7:0]; 
    else
        assign LEDG = SW[15:5];
end

Recibo un error que dice que la parte izquierda de la tarea debe tener un tipo de datos variable.

Respuestas (1)

Dentro de un bloque 'siempre', elimine la asignación, simplemente use LEDG[índice] = ... Además, cambie la declaración de salida a 'registro de salida [7:0] LEDG'. El tipo de datos reg es el tipo de datos variable al que hace referencia el mensaje de error.

Me puedes explicar esto ? ¿Por qué funciona cuando hago eso? Y dado que esto no es realmente programación de software (donde menos líneas es mejor), ¿cuál de los tres códigos será más eficiente?
Un bloque siempre indica un conjunto de instrucciones de procedimiento que suceden en el orden en que están escritas. El tipo de datos reg puede mantener su valor mientras se completa el resto del bloque siempre, mientras que el tipo de datos 'cable' (el predeterminado) no lo hace. Reg es lo que debe usarse en cada bloque siempre, aunque ese bloque en particular sea corto y finalice de inmediato. La asignación se usa para tipos de cables y se puede considerar como la conexión de cables físicos entre piezas de hardware o una ruta para que viaje una señal.
Gracias, ¿y por qué no funciona el bucle for? Se compila pero el resultado no es lo que quiero.
Podría estar fuera de aquí, pero creo que los bloques 'iniciales' solo se ejecutan una vez, por lo que determinará la salida una vez y nunca se actualizará después de eso.
initial se "ejecuta" solo una vez, como usted dice.