I’ve got a bit of Verilog code, and I’m wondering what it actually does, how it actually gets implemented. Is this a good forum to discuss that? If not, can someone point me to a forum that is more appropriate?
It’s been almost 24 hours since I made my initial post, so in case the answer to my first question is yes, I thought I’d write my Verilog code. It is:
module LessThan #( nmBits = 1)
( output rslt
, input [ nmBits-1:0] lftOp
, input [ nmBits-1:0] rhtOp);
assign rslt = lftOp < rhtOp;
endmodule
Now obviously output (rslt) is going to be a logical one if the integer represented by (lftOp) is mathematically less than the integer represented by (rhtOp), and (rslt) is going to be a logical zero otherwise. But the textbook for my VLSI Design class I took Fall 2024 at Utah Valley University says that the way this is usually calculated is to subtract (rhtOp) from (lftOp) and see if there’s a carry. If I just have this Verilog code and instantiate the (LessThan) module, will my circuit do that subtract, or will it calculate it some other way? I ask this because I think I have an algorithm that will calculate the right value without doing the subtract, and I’m curious whether or not my algorithm might be more efficient and less expensive.
Efficiency is a pretty nebulous metric at the best of times, and what is considered expensive is going to vary depending on the platform used and resources available. Given that this is the Yosys discussion forum, I can tell you that loading the code with yosys (and calling hierarchy; opt; alumacc;) does indeed use a subtraction and uses the carry out to determine the comparison result:
If you can map the $alu directly to a single cell (say a hardware DSP) then this is probably quite efficient. If you’re building out full adders then maybe less so:
(that’s after a call to techmap and opt for nmBits=1). If you’re just wanting to look at gate counts for simple cells you can just do that (and even prove that the outputs are equivalent with equiv). But I suspect if you’re mapping to actual hardware it gets more complicated when you start taking into account things like propagation delay and routing congestion.
KrystalDelusion: “If you can map the ($alu) directly to a single cell (say a hardware DSP) then this is probably quite efficient. If you’re building out full adders then maybe less so:” This sounds like you’re saying there already is an algorithm for calculating (LessThan) that doesn’t involve full adders. In fact, your first diagram appears to be an illustration of such a circuit. However, I’m at a loss as to what that diagram actually means. Can you elaborate on it? You’ve got a box on the left with ($7/$alu) in the middle, (A/B/Bl/Cl) on the left, and (CO/X/Y) on the right. What exactly do all of them mean? Keep in mind that my whole career amounts to five years of audited Computer Engineering classes at Utah Valley University.
The images above are generated with the show command in Yosys, which you can see documentation for. But in short, the boxes are cells (module instances), the top line ($7) is the name of the cell, the bottom line ($alu) is the name of the module being instantiated (also referred to as the “type”). Module names beginning with $ are built-in types, cell (or wire) names beginning with $ are auto generated (also referred to as “private”, in contrast with user-provided names which are “public”).
The $alu here is doing a subtraction, CI=1, BI=1 are the carry-in and invert-b signals (both of which are set for a subtraction), X is the result of A - B, CO is the carry-out, and Y is A xor B (which gets used for equality comparisons, such as if you’re doing >=). You can also take a look at the arithmetic logic unit documentation.
If you call show after hierarchy you’ll see that the circuit generated contains a $lt cell, alumacc then converts the $lt to a subtraction operation carried out by an $alu.
The answer can depend on the number of bits in the integer, which you do not specify.
see: https://www.electronics-tutorials.ws/combination/comb_8.html
x:"

