Background and clarifications:
I've never developed/written a single piece of hardware before, but I'm currently using Verilog to develop a huge project for a FPGA as my final graduation project.
I've got some questions on how to write verilog code efficiently. (Assume that, when I say "efficient", I mean "the way that uses less area and pins of the board").
Within the problems I'll suggest possible solutions, but, if none of them is right, feel free to negate them and add your correct solution.
In a certain way, problem 1 is the same as problem 3, so feel free to answer only one of them. I've written both to provide another example of the problem, just in case one feels more comfortable in answering one than the other.
In case you don't know how to answer problem 2, don't worry, as it's not the main problem here.
Thank you for your help.
Problems:
1 - Let's assume we have a module X that controls if modules A, B, ... N are logically on/off, that is, it sends signals to them to signal if they should be enabled or disabled. I see two ways of doing this:
Option 1: Send, to each destination module, a pair of enable/disable wires, wasting space with wires. i.e.:
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);
Option 2: Create a bus, and each destination module would be responsible to mask it and verify if the enable/disable signal was sent to it, saving wire space, but creating a demux for every module. i.e.:
// 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 - In the previous problem, we assumed that we were going to enable/disable modules logically. In case we wanted to turn them on/off physically to save power, is there a way to do that, or do we just have an if statement inside the module? i.e:
if (enabled) begin
// Contents of module while on
end else begin
// Contents of module while off
end
3 - Let's assume we have a decoder module X that sends commands to modules A, B, ..., N. I see 3 ways to do this:
Option 1: Commands as single wires, loosing pins, but saving the space of a demux. i.e.:
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);
Option 2: Logarithmic input to be decoded inside destination module, wasting space with a demux. (Note that X decodes an instruction, decides which module it should send a command to and then sends a command to it)
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
Option 3: A mix of both.