Logical replication is often used in FPGA design.
1. The signal-driven series is very large, fan-out is very large, and the driving force needs to be increased
Adjust the fan-out of the signal when logical replication is most commonly used. If a signal needs to drive many units in the back-level, the fan output of the signal is very large, one way to increase the drive capability of the signal is to insert a multi-level buffer, however, although this can increase the driving capability, it also increases the path Delay of this signal.
In order to avoid this situation, we can copy the logic for generating this signal, and use multiple signals of the same frequency and phase to drive the subsequent circuit, so that the average fan-out to each channel is reduced, in this way, the buffer does not need to be inserted to meet the requirement of increasing driving capacity, thus saving the path Delay of the signal. See the transition from Figure 1.1 to Figure 1.2. Figure 1.1 before logical Replication
Figure 1.2 after logical Replication
Because the synthesizer is already very intelligent, most of the logical replication work in this scenario is completed by the synthesizer, and manual adjustment is not required. All major FPGA manufacturers and third-party integrators have this function.
2. A lot of repetitive work is required in FPGA.
In some FPGA designs, logic replication is useful when many repeated designs are required.
For example, in a special application, you need to design a three-state Io pin with a 240-Bit Width that can be arbitrarily changed. Let's first look at how to design a common three-state pin with a bit width.
module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input dat_in;
input io_dir;
output dat_out;
inout io_out;
assign io_out = io_dir ? dat_in : 1'bz;
assign dat_out = io_out;
endmodule
As shown in the preceding program, the typical design code of a single bidirectional IO port is used. switching between the data and high impedance is controlled by the IO input direction in the middle, how to design a 240-bit bidirectional IO port? Is it shown in the following program:
module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input [239 : 0] dat_in;
input [239 : 0] io_dir;
output [239 : 0] dat_out;
inout [239 : 0] io_out;
assign io_out = io_dir ? dat_in : 240'bz;
assign dat_out = io_out;
endmodule
Obviously, this is not acceptable, because when io_dir is 240 bits, this formula is false only when all values are 0, and is true in other cases, obviously, every Io that you don't want is a two-way interface design.
The modification code is as follows:
Module inout_interface (
Dat_in,
Io_out,
Io_dir,
Dat_out
);
Input [239: 0] dat_in;
Input [239: 0] io_dir;
Output [239: 0] dat_out;
Inout [239: 0] io_out;
Assign io_out [0] = io_dir [0]? Dat_in [0]: 1' BZ;
Assign dat_out [0] = io_out [0];
Assign io_out [1] = io_dir [1]? Dat_in [1]: 1' BZ;
Assign dat_out [1] = io_out [1];
Assign io_out [2] = io_dir [2]? Dat_in [2]: 1' BZ;
Assign dat_out [2] = io_out [2];
.
. // 10 thousand rows are omitted here
.
Assign io_out [239] = io_dir [239]? Dat_in [239]: 1 'bz;
Assign dat_out [1, 239] = io_out [2, 239];
Endmodule
Obviously, this method can achieve 240-bit-width independent direction Io control, but it is estimated that writing code will be exhausting. Is there any better way?
Of course, there is a logic replication syntax in verilog2001-generate, which can be used to perform unlimited replication on the OpenGL module. With this module, we can easily achieve our requirements through logical replication.
// A single bidirectional Io implementation module
Module pin_inout (
Indat,
Indir,
Outdat,
Outdatin
);
Input indat;
Input indir;
Inout outdat;
Output outdatin;
Assign outdat = indir? Indat: 1' BZ;
Assign outdatin = outdat;
Endmodule
Module inout_interface (
Dat_in,
Io_out,
Io_dir,
Dat_out
);
Input [239: 0] dat_in;
Input [239: 0] io_dir;
Output [239: 0] dat_out;
Inout [239: 0] io_out;
// Logical replication 240 times
Genvar I;
Generate
For (I = 0; I <240; I = I + 1)
Begin: pin_loop
Pin_inout pin_inout_inst (
. Indat (dat_in [I]),
. Indir (io_dir [I]),
. Outdat (io_out [I]),
. Outdatin (dat_out [I])
);
End
Endgenerate
Endmodule
From the code above, we can see that the clever use of the OpenGL syntax can reduce your workload.
3. Summary
In FPGA design, we do not need to perform logical replication in some cases, but in some cases, logical replication has to be completed manually. Therefore, mastering the OpenGL syntax is a prerequisite for designing a good model and reducing the workload.