Antecedentes y aclaraciones:
Nunca he desarrollado / escrito una sola pieza de hardware antes, pero actualmente estoy usando Verilog para desarrollar un gran proyecto para un FPGA como mi proyecto final de graduación.
Tengo algunas preguntas sobre cómo escribir código verilog de manera eficiente. (Supongamos que, cuando digo "eficiente", me refiero a "la forma en que utiliza menos área y pines de la placa").
Dentro de los problemas, sugeriré posibles soluciones, pero si ninguna de ellas es correcta, no dude en anularlas y agregar su solución correcta.
De cierta manera, el problema 1 es el mismo que el problema 3, así que siéntete libre de responder solo a uno de ellos. He escrito ambos para proporcionar otro ejemplo del problema, en caso de que uno se sienta más cómodo respondiendo uno que el otro.
En caso de que no sepa cómo responder al problema 2, no se preocupe, ya que no es el problema principal aquí.
Gracias por su ayuda.
Problemas :
1 - Supongamos que tenemos un módulo X que controla si los módulos A, B, ... N están lógicamente encendidos / apagados, es decir, envía señales a ellos para señalar si deben ser habilitados o deshabilitados. Veo dos formas de hacer esto:
Opción 1: Envíe, a cada módulo de destino, un par de cables de habilitación / inhabilitación, desperdiciando espacio con cables. es decir:
module X(o_enable1, o_enable2, o_disable1, o_disable2);
assign i_enable1 = o_enable1;
assign i_disable1 = o_disable1;
module A(i_enable1, i_disable1);
assign i_enable2 = o_enable2;
assign i_disable2 = o_disable2;
module B(i_enable2, i_disable2);
Opción 2: Cree un bus, y cada módulo de destino será responsable de enmascararlo y verificar si se le envió la señal de habilitación / inhabilitación, lo que ahorra espacio en los cables, pero crea un demux para cada módulo. es decir:
// o_enableDisable -> 0 = 'ENABLE, 1 = 'DISABLE
module X(o_enableDisable, o_enableDisable_bus);
assign i_enDis1 = o_enableDisable;
assign i_enDis_bus1 = o_enableDisable;
module A(i_enDis1, i_enDis_bus1);
assign i_enDis2 = o_enableDisable2;
assign i_enDis_bus2 = o_enableDisable2;
module B(i_enDis2, i_enDis_bus2);
// ... Inside A
if ((if i_enDis1 == 'ENABLE)&&(i_enDis_bus1 == ENABLE_FOO1)) // Do something
if ((if i_enDis1 == 'DISABLE)&&(i_enDis_bus1 == DISABLE_FOO1)) // Do something
2 - En el problema anterior, asumimos que íbamos a habilitar / deshabilitar los módulos de manera lógica. En caso de que quisiéramos encenderlos / apagarlos físicamente para ahorrar energía, ¿hay alguna forma de hacerlo o simplemente tenemos una instrucción if dentro del módulo? es decir:
if (enabled) begin
// Contents of module while on
end else begin
// Contents of module while off
end
3 - Supongamos que tenemos un módulo decodificador X que envía comandos a los módulos A, B, ..., N. Veo 3 formas de hacer esto:
Opción 1: Comandos como cables simples, perdiendo pines, pero ahorrando el espacio de un demux. es decir:
module X(o_com1, ..., o_com_m, ..., o_com_n);
assign i_com1 = o_com1;
// ...
assign i_com_m = o_com_m;
module A(i_com1, ... , i_com_m);
module B(i_com_m_plus_1, ..., i_com_n);
Opción 2: La entrada logarítmica se descodificará dentro del módulo de destino, desperdiciando espacio con un demux. (Tenga en cuenta que X decodifica una instrucción, decide a qué módulo debe enviar un comando y luego le envía un comando)
module X(o_command_A, o_command_B, ...);
assign i_command_A = o_command_A;
module A(i_command_A);
assign i_command_B = o_command_B;
module B(i_command_B);
// Inside A
case (i_command_A)
'COMMAND_1: begin /* ... */ end
// ...
'COMMAND_n: begin /* ... */end
endcase
Opción 3: Una combinación de ambos.