Electronic – Efficient use of space in FPGA

fpgasystem-verilogverilog

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.

Best Answer

First, when designing FPGA's we mostly just think about "resources" rather than "space". Resources are things like routing resources, logic cells, RAM blocks, multiply-add blocks, etc. It looks like you're concerned about minimizing the use of routing resources, and willing to use more logic cells to do that.

Really, the best way to answer your questions (and first off, to find out if trading logic for routing is the right thing to do) is to synthesize your first-draft design and look at the resource usage. If routing resources are close to fully utilized, then start looking for ways to reduce them. If logic is close to fully utilized, then start looking for ways to make the opposite kind of optimization.

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.

The typical way to do this in an FPGA is to just let all N modules run continuously. If only one out of the N are used at any given time, then you can often just use a mux to select which of the outputs gets used by downstream logic. If the combinations of modules being "disabled" is more complex, then you often just tell downstream logic to ignore those inputs, rather than disabling the module generating them.

You normally don't have separate wires for enable and disable like you proposed in your 1st option. Just one wire that is (for exampel) high when the module should be enabled and low when it should be disabled.

Although of course having separate enable and disable lines that only pulse intermittently is also possible if you have a good reason to do it. They would typically drive the SET and RESET inputs of a flip-flop to generate the actual enable signal.

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?

FPGAs don't typically have provisions to selectively power down parts of the fabric.

It is possible to use enable pins to reduce power consumption (due to reduced switching), but if the amount of logic being disabled is not a very large fraction of your design, it's not likely to significantly improve your power budget.

Also, you need to show that at any given time at least some known fraction of the logic is disabled, since you'll have to design your power supplies and heat sinking to account for the worst-case operating conditions anyway.

Let's assume we have a decoder module X that sends commands to modules A, B, ..., N. I see 3 ways to do this:

Your option 1 (a seperate signal for each command) is a very common FPGA coding style. Similarly, one-hot encoding is typically recommended by synthesis tool vendors for encoding state machine states.