Determine whether a binary number is of power of two in verilog code  - Page 1
Forum section: electronics / general

author: promach
author_rank: Frequent Contributor
timestamp: September 30, 2019, 01:18:51 pm
content: I am trying to determine whether a binary number is of power of two (in other words, is it of one-hot encoding).I found amethodto do so, but it is for integer.Could anyone help to transform the method for usage with binary number in verilog ?

author: ucanel
author_rank: Regular Contributor
timestamp: September 30, 2019, 01:51:44 pm
content: 0000 0000 00000 0001 10000 0010 20000 0100 40000 1000 80001 0000 160010 0000 320100 0000 641000 0000 128... so on.Problem is simplyexcept Zero and Oneif there is only one "1" bit in the number.You may first check the number if it is Zero or One,and then right shift the number and check the LSBcount the "1" bitscheck the count if it is not One the number is not power of two.

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 30, 2019, 01:57:23 pm
content: Note that it's using the identity (usually well known for computer programmers):n AND (2^k - 1) = n MOD 2^kit follows that for n = 2^k, the result is 0, and, as they mention, also for n = 0 obviously, which is not a power of two, so that's a corner case, requiring an additional test.You can implement it exactly in the same way in Verilog (or VHDL)?You have the bitwise AND operator (&) and you can subtract 1 from a register?

author: promach
author_rank: Frequent Contributor
timestamp: September 30, 2019, 02:05:40 pm
content: Think about binary bits.What ifvis of 8 bits ? What do!and&do ?Shouldfbe only 1 bit in this case ?

author: tszaboo
author_rank: Super Contributor
timestamp: September 30, 2019, 02:18:04 pm
content: XOR all bits?

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 30, 2019, 02:22:04 pm
content: Quote from: promach on September 30, 2019, 02:05:40 pm& and | are bitwise operators, not logical. They do exactly what you'd expect. A bitwise operation (that is, bit by bit).The logical equivalent operators in Verilog are && and || (that's kind of similar to C.)So, for n and m registers:"n & m" is a bitwise AND of the two registers, requires n and m to be of the same width, and yields a value of the same width."c1 && c2 " is a logical AND of the two CONDITIONS c1 and c2, which are conditions ("booleans"), not registers.Quote from: promach on September 30, 2019, 02:05:40 pmI think you're confusing a couple notions here.'f' would just be the result of your test. You can test for conditions in Verilog.Here is an example in VHDL (I practically never use Verilog, so I don't want to write something incorrect, but it should be perfectly writable in Verilog):Code:subtype Word_t is unsigned(31 downto 0);signal MainClock, Reset : std_logic;signal nWord : Word_t;signal bIsPowerOfTwo : boolean;-- Is nWord a power of two?PowerOfTwo: process (Reset, MainClock)beginif Reset = '1' thenbIsPowerOfTwo <= false;elsif rising_edge(MainClock) thenbIsPowerOfTwo <= (nWord /= 0) and ((nWord and (nWord - 1)) = 0);end if;end process;

author: promach
author_rank: Frequent Contributor
timestamp: September 30, 2019, 02:31:01 pm
content: I understand those bitwise operatorsTry putting the expression in verilog code and pass the code into verilator for linting purpose .....

author: Kalvin
author_rank: Super Contributor
timestamp: September 30, 2019, 03:19:26 pm
content: Group the bits into four bit groups, and create a lookup table with the following output:0001 10010 10100 11000 1ELSE 0Now, you have a logic for a 4-bit number. For 16 bit number, you need five instances of these lookup-tables in two logic levels.Edit: Brainfart.

author: promach
author_rank: Frequent Contributor
timestamp: September 30, 2019, 03:28:07 pm
content: See the verilator linting output with is_power_of_two.vCode:verilator -Wall --lint-only is_power_of_two.v%Warning-WIDTH: is_power_of_two.v:6: Logical Operator LOGAND expects 1 bit on the LHS, but LHS's VARREF 'v' generates 8 bits.: ... In instance is_power_of_twoalways @(*) f = v && !(v & (v - 1));^~... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.%Warning-WIDTH: is_power_of_two.v:6: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS's AND generates 32 or 8 bits.: ... In instance is_power_of_twoalways @(*) f = v && !(v & (v - 1));^%Warning-UNUSED: is_power_of_two.v:4: Signal is not used: 'f': ... In instance is_power_of_tworeg f;^%Error: Exiting due to 3 warning(s)%Error: Command Failed /usr/bin/verilator_bin -Wall --lint-only is_power_of_two.vCode:module is_power_of_two();reg [7:0] v = 8'b11110000;reg f;always @(*) f = v && !(v & (v - 1));endmodule

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 30, 2019, 03:44:26 pm
content: Quote from: promach on September 30, 2019, 03:28:07 pmAnd the check is right. Sorry, you haven't completely listened.Have I copied the C version verbatim in VHDL? Nope. But it almost looks like you did in Verilog.You can't put a register (well, if it's wider than 1-bit anyway) on either side of a logical AND (&&). Put a CONDITION. That's what I did in VHDL. Verilog is forgiving, so you can also put a single-bit signal instead of a condition, but that's of no real use here."v && ..." is not correct"(v != 0) && ((v & (v -1)) == 0)" should be (again, modulo my knowledge in Verilog for exact syntax).Make conditions on both sides of the &&.

author: NorthGuy
author_rank: Super Contributor
timestamp: September 30, 2019, 06:07:52 pm
content: Quote from: Kalvin on September 30, 2019, 03:19:26 pmThis will not work. For successful integration, each 4-bit group must convey up three different states:- the group is all '0'- the group contains only one '1'- the group contains more than one '1'You cannot compress this into only one LUT output.

author: promach
author_rank: Frequent Contributor
timestamp: October 01, 2019, 04:19:13 am
content: Someone suggested me to use power_of_two = ^v which is so much simpler.Any comment ?

author: jhpadjustable
author_rank: Frequent Contributor
timestamp: October 01, 2019, 04:48:47 am
content: Quote from: promach on October 01, 2019, 04:19:13 amTry it with 'b111 or any odd number >=3 of 1s and report back. I think you'll find it's an even parity generator, not a one-hot tester.

author: Kalvin
author_rank: Super Contributor
timestamp: October 01, 2019, 06:07:10 am
content: Quote from: NorthGuy on September 30, 2019, 06:07:52 pmYes, you are absolutely right. I was thinking in a hurry (or wasn't thinking at all)

author: Someone
author_rank: Super Contributor
timestamp: October 01, 2019, 11:36:02 am
content: Quote from: SiliconWizard on September 30, 2019, 03:44:26 pmFor code golf you use the reduction operators:|v & ~|(v & (v - 1))The unsized literal 1 is really bad style too making it completely disgraceful code.As with all engineering and particularly FPGAs, the end goal is important and implementation can be radically different with other algorithms. Taking a target 6lut (dual output 5 lut) Xilinx Spartan 6 as an example with a 32 bit test word:Above method, 53 luts 212MHzAdder tree, 34 luts 225MHzAdder string, 34 luts 191MHzLut string, 10 luts 78MHzThe best code depends what your goals are, but taking a method optimised for CPUs and applying them direct to FPGAs is usually a sub-optimal approach on any metric other than mental effort.

author: promach
author_rank: Frequent Contributor
timestamp: October 01, 2019, 01:42:37 pm
content: QuoteYou did not post anything about adder tree for power-of-two detection at all ...

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 03:03:56 pm
content: Quote from: Someone on October 01, 2019, 11:36:02 amModifying the Kalvin's approach:1-st layer6 5x2 LUTs take 30 input signals. Each LUT produces two signals:- veto (more than one '1' in inputs)- mark (at least one '1' in inputs)2 input signals left intact - call them "orphaned"2-nd layerOne 6x1 LUT ors all the veto_signals, and produces veto_orOne 6x1 LUT takes all the mark signals and calculates veto2 signal (more than one mark is '1')One 6x1 LUT takes all the mark signals and calculates mark2 signal (at least one mark is '1')3-rd layerOne LUT takes veto_or, veto2, mark2 signals, also 2 original orphaned inputs (on the slowest A1 and A2 LUT pins) and calculates the final result (exactly one of mark2 and two orphaned signals is '1', and all vetoes are '0')This is 10 LUTs and 3 logic levels. Should run at least at 300 MHz on S6, faster on S7.

author: Kalvin
author_rank: Super Contributor
timestamp: October 01, 2019, 03:41:09 pm
content: My second attempt, hopefully correct this time.First layer LUT "one-hot-or-all-zeros" x 4 (for a 16 bit number):0000 01 # All zeros0001 10 # One hot0010 10 # One hot0100 10 # One hot1000 10 # One hotELSE 00 # OthersSecond layer LUT "one-hot-or-all-zeros" x 2:0101 01 # All zeros1001 10 # One hot0110 10 # One hotELSE 00 # OthersThird layer LUT "only-one-hot" x 1:0101 0 # All zeros1001 1 # Only one hot0110 1 # Only one hotELSE 0 # Others

author: free_electron
author_rank: Super Contributor
timestamp: October 01, 2019, 04:46:42 pm
content: Here's how i do that. This guarantees a known fixed propagation delay ( the actual gates are LUT's which have a constant propagation time irrespective of the type of gate created ). Note that the last step ( two inverters and an OR gate ) could have been done differently but it would have unbalanced the propagation delay creating very glitchy output. This was a deliberate decision.Since a LUT typically has 4 inputs and 2 outputs you can combine two OR gates into one lut.You can combine the three input or and the inverter also into one lut. you only need a NAND gate as output then.The idea is based on thinking 'in reverse'. the same principle used for half-adders.Look at a yellow block. two tests are done.ALO : there is at least one input high ( OR gate ), we will re-evaluate that in the next block.MTO : there is more than one high (and gate ) ,we feed those into an or-tree.All MTO signals propagate through the OR-tree. If one MTO is high the output will be low.Simply tell the synthesizer it needs to implement this as-is and not minimize the logic.Example : lets try a number where A0 if high and A5 is high.in the first column we get ALO from Lut1 high, andnd ALO from LUT3 high, nothing registers on the MTO's.in the second column we get both ALO's high and nothing registers on MTO's.in the last column both ALO and MTO goes high. since MTO is high the output will be low.signals passing a column all exet with the same propagation delay. There are not race conditions as all signals have passed the same amount of LUT's.Note that, if your FPGA has a different LUT construction ( like 8 input , 4 output or 4 input 3 output ) then other optimisations are possible.Don't leave such circuitry to the synthesizer.it would create a glitchy hairball...

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 01, 2019, 05:46:43 pm
content: Quote from: Someone on October 01, 2019, 11:36:02 amWell, I wrote several times that I'm no expert in Verilog. Should I add another one in capital and bold letters?That said, what is code golf exactly?And was the statement I gave plain wrong or unreadable? I think neither personally, but style is always a matter of taste. I don't know enough of Verilog to know the reduction operators, and it all looks kind of more cryptic than readable. As to the unsized literal, again I'm no Verilog guru whatsoever. It's perfectly fine in VHDL using 'numeric' types, and perfectly readable. A '1' has the additional nice property, like '0', to mean exactly the same thing in all bases. But again, I was clear I was certainly NOT going to write good Verilog; I think it was just plenty good enough to get the OP in the right direction, and answer his question.Quote from: Someone on October 01, 2019, 11:36:02 amYup. Absolutely. And good engineering is actually all about finding the simplest solution that meets ALL requirements of a given problem. The above "modulo" method is actually one of the fastest (at least for non-pipelined approaches) once synthesized (not the fastest, but pretty good), is simple to understand and simple to read from code, yields pretty compact code (which is always a plus for maintenance and validation), is provably correct, and takes up reasonable area (sure it's not the least area-hungry, but it's still reasonable. Unless you're going to instantiate myriads of such detectors, a few LUTs of difference won't make the slightest difference!)One concrete thing to note, is also that the end result in a given design will depend on a lot of factors. Synthesis tools do heavy optimizations. The "minus one" operation here is kinda "expensive". But if you use (v-1) elsewhere in your code, the tools will or may reuse it, thus making the overall thing actually take up less space than some other alternatives. Trying to think of small chunks of logics in isolation doesn't always give you the right idea of how the whole thing is going to be implemented.Again, if it fits all your requirements, AND is simple, then no need to find anything else. It would be overengineering. If the above doesn't fit the OP's requirements, then alright. Game over. If it does...Looks like the thread, now that solutions have been proposed, is going to turn into a pissing contest.For fun, I tried various alternatives, and still the above is hard to beat overall. Sure it's relatively easy to implement alternatives so that they take less area, but it's often a lot clunkier, and some have limitations (such as requiring a power of two number of bits, the above has no such restriction.) Can certainly be an interesting optimization problem per se, but I'm not sure it will further help the OP whatsoever.One last thing: as in many cases, the best answer to the OP's problem may not even be what they asked for. We discussed something similar in the Programming section about algorithms. Actually detecting that a given register holds a power of two value may not be required, and maybe some other approaches can yield the result they're looking for. Oh, and I don't really know the OP either - it could also be some kind of "homework" that we are gracefully doing for them...?

author: promach
author_rank: Frequent Contributor
timestamp: October 01, 2019, 06:53:23 pm
content: If this is homework, I will not spend time investigating the number of LUTs spent.How is adder tree approach different compared to|v & ~|(v & (v - 1))?And why adder tree approach uses less LUTs and resulted in higher fmax?

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 07:25:25 pm
content: Quote from: promach on October 01, 2019, 06:53:23 pmYou can just add all the bits and if see if the sum is equal to 1. You need a 2-bit saturating result.You can add everything consecutively. Or you can do it in a tree where each node represents a sum of a number of values coming from child nodes.My guess is Someone meant such tree.To use less LUTs, each LUT should use as many inputs as possible - otherwise resources get wasted. A bitwise operation uses only two inputs of a LUT (while 6 are available) - this is very inefficient.In theory, this should be optimized by tools to produce the optimal solution no matter how you write it. After all, the whole thing is just 32x1 LUT and the task you're giving to the tools is to model it with the available smaller LUTs, minimizing either the number of LUTs or the shortest path.In practice, tools are dumb and you cannot predict what they do, except that it is not likely to be optimal. You either agree to live with this, or you build everything from smaller pieces manually. If you run at 100 MHz, the former approach will work for you the best. If you want to run at 500 MHz, you've got to do many things manually.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 01, 2019, 07:39:11 pm
content: Quote from: NorthGuy on October 01, 2019, 07:25:25 pmYup. Well, tools are not that dumb, but nowhere near perfect. They'll usually do a good job at optimizing, and "packing" as many logic structures in each LUT as it can, but sometimes they don't get as good as you'd expect. They'll also often "waste" cells to favor speed, so it's also a matter of compromise (and tool settings).Quote from: NorthGuy on October 01, 2019, 07:25:25 pmAgreed. But then, as you said, MANY things. Just rewriting code won't be enough, and assuming the tools will implement your code in the way you think is often just wrong. So you'll need to set many things manually, including possibly placement!

author: GeorgeOfTheJungle
author_rank: Super Contributor
timestamp: October 01, 2019, 08:22:41 pm
content: What do the tools do if you just tell them to XOR these eight?(b0 AND /b1 AND /b2 AND /b3 AND /b4 AND /b5 AND /b6 AND /b7)(/b0 AND b1 AND /b2 AND /b3 AND /b4 AND /b5 AND /b6 AND /b7)(/b0 AND /b1 AND b2 AND /b3 AND /b4 AND /b5 AND /b6 AND /b7)(/b0 AND /b1 AND /b2 AND b3 AND /b4 AND /b5 AND /b6 AND /b7)(/b0 AND /b1 AND /b2 AND /b3 AND b4 AND /b5 AND /b6 AND /b7)(/b0 AND /b1 AND /b2 AND /b3 AND /b4 AND b5 AND /b6 AND /b7)(/b0 AND /b1 AND /b2 AND /b3 AND /b4 AND /b5 AND b6 AND /b7)(/b0 AND /b1 AND /b2 AND /b3 AND /b4 AND /b5 AND /b6 AND b7)https://circuitverse.org/simulator/edit/27677

author: Someone
author_rank: Super Contributor
timestamp: October 01, 2019, 10:16:51 pm
content: Quote from: NorthGuy on October 01, 2019, 03:03:56 pmIt won't hit 300MHz on a Spartan 6 without hand placement and design, synthesis for that type of design gets to:LUT Tree area optimised 9 luts 233MHz (or 8 luts with fabric logic)LUT Tree speed optimised 15 luts 277MHzall together:Bithack method, 53 luts 212MHzAdder tree, 34 luts 225MHzAdder string, 34 luts 191MHzBoolean, 21 luts 235MHzLUT Tree speed optimised, 15 luts 277MHzLUT string, 10 luts 78MHzLUT Tree area optimised, 9 luts 233MHz (or 8 luts with fabric logic)Quote from: promach on October 01, 2019, 01:42:37 pma) You're not employing me, so why expect a deliverable?b) You haven't mentioned any constraints or motivationsc) posting a picture of text of a static website as your example is really poor form...The original comes from here:https://graphics.stanford.edu/~seander/bithacks.htmlQuoteQuote from: SiliconWizard on October 01, 2019, 07:39:11 pmThe whole quote is important here, the tools are pretty crap at optimising between logic and adders, rarely use the fabric logic, and commit early to primitives which work against the requested design goals. Getting a fast and/or small result does need a good understanding of the specific tools and architecture. For example...Quote from: GeorgeOfTheJungle on October 01, 2019, 08:22:41 pmThats not verilog or VHDL code, but since this is one of those threads where everyone has their opinions but can't be bothered to actually test or check anything. If you do a pure logic equation the Xilinx tools spits out something between best and worst:Boolean, 21 luts 235MHzYou can get that sort of result with a very readable high level language style structure using a generate (loop), which is a typical real world solution balancing code readability, resources, speed, portability, etc.

author: Nusa
author_rank: Super Contributor
timestamp: October 01, 2019, 10:53:46 pm
content: Quote from: NorthGuy on October 01, 2019, 03:03:56 pmThis isn't my area, but am I missing something? Shouldn't the logic for a lookup approach be much simpler? Like so for up to 36 inputs:1st layer:Six 6x1 LUTs take 36 input signals and calculates mark signals (exactly one input is '1')2nd layer:One 6x1 LUT takes mark signals and calculates final output (exactly one input is '1') indicating that exactly one of the 36 inputs is 1.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 10:56:18 pm
content: Quote from: Someone on October 01, 2019, 10:16:51 pmI don't think you need manual P&R to get 300 MHz (although manual P&R can improve things further). But you do need to directly instantiate LUTs, rather than emulating them with Verilog/VHDL and then letting ISE find its own version of the design.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 10:59:07 pm
content: Quote from: Nusa on October 01, 2019, 10:53:46 pmThen '0' will mean - either all zeroes (which is perfectly valid for 'one hot') or more than one '1' (which means that this is not 'one hot').

author: Someone
author_rank: Super Contributor
timestamp: October 01, 2019, 11:08:03 pm
content: Quote from: NorthGuy on October 01, 2019, 10:56:18 pmTry it, tell us your results. Because I did exactly that and it wouldn't make 300MHz. Talk is cheap....

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 11:22:05 pm
content: Quote from: Someone on October 01, 2019, 11:08:03 pmSorry, no can do - don't have ISE installed anywhere.What speed did you get with 10 LUTs?

author: Nusa
author_rank: Super Contributor
timestamp: October 01, 2019, 11:33:20 pm
content: Quote from: NorthGuy on October 01, 2019, 10:59:07 pmAh, I see the distinction, although I'm having trouble finding a definition of one-hot that explains it that way. Feel free to point me toward one. Wiki doesn't mention zero-hot being included in it.But if one needs a zero-hot signal, it might be best to just calculate that in parallel since speed seems to be an important metric here. Another seven LUTs testing for all inputs being 0, still two-layer.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 01, 2019, 11:59:51 pm
content: Quote from: Nusa on October 01, 2019, 11:33:20 pm'one hot' is a nickname for the condition OP seeks to determine. I didn't understand what you mean by zero-hot.You propose:Quote from: Nusa on October 01, 2019, 10:53:46 pmConsider two inputs"111111000000000000000000000000000001""000000000000000000000000000000000001"The first one should produce '0' - it is not 'one hot'. The second one should produce '1' - it is 'one hot'.in both cases, your second layer LUT receives"000001"and returns '1'.Makes sense?

author: Nusa
author_rank: Super Contributor
timestamp: October 02, 2019, 12:08:49 am
content: You are correct, my logic is a failure. Thank you. On the bright side, I think I had the correct understanding of one-hot after all.

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: October 02, 2019, 12:17:46 am
content: I guess this approach could be translated to Verilog:https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallelNote that for the "best method for counting bits in a 32-bit integer" the result is in the lower 5 bits, so you need to AND the result with 31 (c = c & 31):v = v - ((v >> 1) & 0x55555555);v = (v & 0x33333333) + ((v >> 2) & 0x33333333);c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;c = c & 31;And if the count is 1, the number is a power of two.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 12:45:08 am
content: Note that max freq will depend a lot on routing (route often accounts for more than 50% of the total delay), so here giving raw numbers doesn't really help, they are merely indicative.For instance, I tried the first approach ("modulo") on a 32-bit register with ISE/Spartan 6. I get: 43% logic, 57% route for the total delay from input register to output (and 46 LUTs).Do you have a specific method for giving such numbers out of context? (Meaning, for an isolated entity like this?) I personally just write a minimal top-level with external ports, and connect them to the tested entity. Of course, that gives only an idea of the max freq you'll get in real conditions, in a complete design.

author: Someone
author_rank: Super Contributor
timestamp: October 02, 2019, 12:56:41 am
content: Quote from: 0xdeadbeef on October 02, 2019, 12:17:46 amThose sorts of "optimised" solutions assume you have a fixed width (usually 32bit) CPU, completely different thinking is required for implementation in other architectures such as an FPGA. You wouldn't & with a bit mask like that to get the low result, instead its "free" with c[4:0].Quote from: NorthGuy on October 01, 2019, 11:22:05 pmWithout anything more than your hunch, compared to an actual implementation, you still try and stick to your position and for the lols request more work from others. The 9 lut solution is the same number of logic layers as your estimated 10, still the same depth of 3 when optimised for speed with 15 luts. The difference is in the combinatorial delays to the different outputs of the luts, the slower paths are required to break out the denser packing so using all 6 luts rather than trying to use the dual 5 lut makes sense. Given that I doubt 10 luts is the optimal but you're welcome to play around all you like. Its getting very architecture specific at that point. To reliably hit your imagined goal it would need to be reduced to 2 layers of logic or use a bunch of black magic in the carry chains.Quote from: SiliconWizard on October 02, 2019, 12:45:08 amEasiest is to just take the synthesis results with their estimated routing costs, from register to register (with no i/o packing). Its a good first pass estimate, implementation can do further optimisations and change primitives so there are occasional cases where its needed, but the non-deterministic nature of the routing and the influence of the timing constraints lead to long run times to find the full speed possible. Real conditions are usually a design with 40-80% utilisation and fighting for resources with other constraints, it ends up very application specific to get the last 20% of gains in speed (or reverting to hand placement of the critical parts).

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 01:59:52 am
content: Quote from: Someone on October 02, 2019, 12:56:41 amYep pretty much what I do. But you must of course be careful how the tested entity/module is used in your "test" setup, to make sure it is actually fully utilized after implementation, and nothing gets pruned during synthesis/optimization.So, depending on what I want to see and how the module is going to be used in the end-design. If it's going to be directly connected to IOs, I'll connect its ports to ports of the top-level, and assign them to actual IOs. Now of course that introduces specific issues, even if you exclude the IOBs from your estimations. Both placement and routing may be less than optimal if you connect it to external ports, due to how it's going to place everything.In a case like this one, I did the following: I write a small top-level, I add an internal counter signal (32-bit register here), and I write a small process that increments it, so that it actually scans ALL possible values. This register is the input of the detector. The output still has to go out somewhere (typically an IO), otherwise the whole module may obviously get pruned. This last thing is kinda obvious, but the "input" part is sometimes less so. If you're not careful about feeding the modules all the possible input values, many logics can get pruned at synthesis time, and would give you a completely wrong idea. (OK this is probably obvious to the experienced crowd, but possibly a trap for others...)So, with this "counter" approach, the first version (suggested by the OP) gets me a max freq of 266MHz (device: Spartan-6 LX9, speed grade 3). I just chose the Timing strategy and selected 'performance with physical synthesis', which made a significant difference.I wrote an optimized version (basically a tree structure with a simplified adder - you don't need a full adder for this check), still written in pure HDL. It's just 19 LUTs, but it's actually very slightly slower (~262MHz). I could probably get it faster by making it 1 logic level less. Would need some serious thought to write it right. Again, still in pure HDL.Fast is good, but correct is better.Of course, you can then go on and directly instantiate LUTs as suggested to really further improve things, but I think the results I got were not so bad.And I agree that getting to more than 300MHz is certainly no picnic here.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 02:07:04 am
content: Quote from: 0xdeadbeef on October 02, 2019, 12:17:46 amJust a note. This thing is to actually count "set" bits. It's completely overkill for detecting that a number is a power of two (has just 1 set bit). The modulo "trick" given by the OP is much simpler, and much more efficient here (and additionally, as I already pointed out, much easier to prove correct. Go ahead and show us a proof that the piece of code you posted is correct... it'll take you a good while.)Besides, this one includes a multiply. You don't want multiplies in digital design unless you REALLY need them.

author: Someone
author_rank: Super Contributor
timestamp: October 02, 2019, 02:21:09 am
content: Quote from: SiliconWizard on October 02, 2019, 01:59:52 amThanks for all the details, 300MHz is within sight at 3 layers of logic in Spartan 6 but needs really ideal primitives and placement, monkeying with optimisation options, but isn't realisable in real designs. Your dummy harness is a good way to go, typically computational modules don't drive outputs so register to register is the metric. Some tools will pull/push register stages so they occasionally need attributes to stop that, equally the drivers and sinks may create placement constraints so a "clean" harness usually has several layers of registers on each side of the unit under test. Tests in context with the larger system are always important as there can be both beneficial and detrimental effects from adjacent sections.

author: BrianHG
author_rank: Super Contributor
timestamp: October 02, 2019, 02:43:24 am
content: Question: Why not parallel add all the individual bits together as 1 bit numbers and check to see if the sum total is equal to 1?

author: NorthGuy
author_rank: Super Contributor
timestamp: October 02, 2019, 03:05:19 am
content: Quote from: Someone on October 02, 2019, 12:56:41 amRequest work? You said you've already done it. Perhaps I misunderstood the meaning of word "exactly".Quote from: Someone on October 02, 2019, 12:56:41 amOf course, if you go with all 6x1 LUTs instead of 5x2, it'll be faster, mostly because O5 exiting out of the LUT is slow. Also the last LUT will only have 2 inputs which can use the fastest LUT pins. I guess that's what your 15-LUT solution is. It certainly will be faster than 10 LUTs.However, the overall speed you're getting for 3 logic levels on S6, seems slow to me. May be I just don't remember correctly.

author: promach
author_rank: Frequent Contributor
timestamp: October 02, 2019, 03:59:44 am
content: Quote@NorthGuy @SomeoneIf this is what you meant by adder tree approach , how does this actually work to determine whether a binary number is of power of two ?Note: I am not seeing that this adder tree approach could actually achieve such purpose. Please correct me if wrong.

author: BrianHG
author_rank: Super Contributor
timestamp: October 02, 2019, 04:33:00 am
content: Quote from: promach on October 02, 2019, 03:59:44 amAhhh, just like I posted 3 posts above, I think they mean:Method 1:--------------------------------------------------------------------------------------------if ( (in + in + in + in + in + in + in + in) == 1 ) {eq_pow_of_2 <= 1;} else {eq_pow_of_2 <= 0;}--------------------------------------------------------------------------------------------Method 2:--------------------------------------------------------------------------------------------eq_pow_of_2 <= ( (in + in + in + in + in + in + in + in) = 1 );--------------------------------------------------------------------------------------------Note: On my side, when I used to develop in verilog, I would try both methods since for some reason, some verilog compilers like the one built in Quartus seems to better optimize the 'IF' method when simplifying the expression down to 1 bit and/or it aids in allowing for any other immediate compound actions located inside the braces based on the result before the next clock.All the ' in[ x ] ' individual bits seen as 1 bit numbers inside the 'IF's addition brackets are considered a single 1 bit number equal to 0 or 1.When adding all these together, when you get a sum of 1, the source number 'in[7..0]' is obviously a power of 2 since there is only '1' one in it. If you result is a Zero, or greater than 1, then either no bits are 1 or more than 1 bit is one in total.

author: promach
author_rank: Frequent Contributor
timestamp: October 02, 2019, 08:58:51 am
content: @BrianHGBut the code you posted just above will not work at all for odd number of 1's such as 8'b10110000

author: BrianHG
author_rank: Super Contributor
timestamp: October 02, 2019, 11:35:14 am
content: Quote from: promach on October 02, 2019, 08:58:51 amJust so I understand, 8'b10110000 = 176, not a power of 2.In my code, inside the brackets, the functionality of the verilog compiler generates will see the input of 8'b10110000 having a sum total of '3', since there are 3 high bits. Since '3' is not equal to '1', then the result will be '0'I know that I didn't specify the possibility of a 4 bit result summing 8 possible ones, this is usually automatically taken care of by the compiler automatically.Oh, I think in my example #2, the '=' should be rather a '=='.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 12:59:41 pm
content: Quote from: BrianHG on October 02, 2019, 02:43:24 amThe "count the ones" is one of the methods I tested. But why would you think it could be synthesized more efficiently?Anyway, the end-result was worse than the first approach both in terms of number of LUTs and speed. It was one of the slowest of all approaches I tried.As I said above, you actually don't need a full adder to implement this check. The best version I designed so far (again in pure HDL, didn't bother to hand-craft LUTs and such) yielding 19 LUTs and the fastest speed, is sort of a full adder, but doesn't fully propagate the carry (it needs some thought to figure it out). Carry propagation can be handled in a very simple way here. To figure it out, take a given register (ideally with a power of two width), split it in half, assume you know the status of each half (power of two or not), and figure out how you can infer the status of the whole register. You'll get to see that just knowing the status of each part is not enough (it's not correct), and you'll find cases to show why, so you need to propagate a carry. But this can be done in a simpler way than with a full adder, because once a carry has been set, you know for sure that the number can't be a power of two.Another very simple approach I tried was a look-up, comparing "in parallel" the input register to the N (being the bit width) possible values.It actually didn't take as much area, and was stlightly faster than counting the ones. But still worse than the two above (modulo and the modified adder tree).

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 01:41:47 pm
content: Quote from: BrianHG on October 02, 2019, 11:35:14 amI don't know much about Verilog (and the more I see Verilog code, the more I tend to really NOT want to), but in VHDL, such sum would only be on 1-bit only, and thus be basically an xor.

author: promach
author_rank: Frequent Contributor
timestamp: October 02, 2019, 03:31:36 pm
content: Quote@BrianHGYour code is simple to understand and I am wondering how this adder tree approach compares to(v != 0) && ((v & (v -1)) == 0)

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 04:00:36 pm
content: Quote from: promach on October 02, 2019, 03:31:36 pmAfter all that's been said in this thread, and the tips given, I would suggest you try it for yourself - it's actually an interesting learning experience.If you don't already have some FPGA tools on your computer, pick one vendor and download the free version. Xilinx has ISE or Vivado, Lattice has Diamond, etc. Then you can set up your own virtual tests by creating projects and then looking at the reports (map, PAR, timing, etc...) You don't need an actual FPGA board; just use the tools to see the reports.

author: BrianHG
author_rank: Super Contributor
timestamp: October 02, 2019, 10:59:17 pm
content: Quote from: SiliconWizard on October 02, 2019, 12:59:41 pmThe efficiency of synthesis here was only the way Quartus' internal synth interprets the code and how it would place it in a macro cell. I'm looking at Quatrus of 5 or more years ago. It does some funny things at times and it is not thorough is complete synthesis like a true dedicated HDL compiler.1 thing I agree with you is that if you were to place inside an 'IF' within Quartus, doing a simple compare would most likely offer a greater F-Max when working with source integers up to 18 bits when using the 'Cyclone' series FPGA, and up to 36 bits when using the larger faster ones.Example:if ( (in[7..0] == 8'b10000000) ||(in[7..0] == 8'b01000000) ||(in[7..0] == 8'b00100000) ||(in[7..0] == 8'b00010000) ||(in[7..0] == 8'b00001000) ||(in[7..0] == 8'b00000100) ||(in[7..0] == 8'b00000010) ||(in[7..0] == 8'b00000001) ) {eq_pow2 <= 1;} else {eq_pow2 <= 0;}Because of the nature of Altera's Quartus synthesizer and their macrocell structure, this code will offer you the greatest FMax you can get in a single pipe clock cycle.I am not sure if you wrote my code like:if (in[7..0] == 8'b10000000) eq_pow2 <= 1;else if (in[7..0] == 8'b01000000) eq_pow2 <= 1;else if (in[7..0] == 8'b00100000) eq_pow2 <= 1;else if (in[7..0] == 8'b00010000) eq_pow2 <= 1;.........else eq_pow2 <= 0;would offer any advantage, though it makes things messy if you want to do more than just setting a single register during the compare before the clock cycle ends.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 02, 2019, 11:17:31 pm
content: Regarding if's (even though I use VHDL, but I'm sure this yields the same results), there are interesting things to realize.Talking about how "dumb" synthesis tools can be...Even with Synplify (which is not half bad), you'll run into this. You'll find out that in MOST cases where you use a "if", synthesis will yield a priority encoder, even when it's obvious by design that the if sequence could be perfectly replaced with a simple logic equation instead (without any priority needed). Which is sometimes pretty inefficient.Long story short: avoid "if" when you can. Sure it may look elegant. But tools are dumb. Yeah definitely.One simple example: implementing look-up for the above test.Here are two examples I tested. They are, from a logic POV, strictly identical. One will yield a structure with a priority encoder though, for no useful reason, and take almost twice as many LUTs.Code:if rising_edge(Clk) thenbIsPowerOfTwo <= false;for i in 0 to (DataWidth - 1) loopif nWordIn = to_unsigned(2**i, nWordIn'length) thenbIsPowerOfTwo <= true;exit;end if;end loop;end if;and:Code:if rising_edge(FPGA_Clk) thenbIsPowerOfTwo <= false;for i in 0 to (DataWidth - 1) loopbIsPowerOfTwo <= bIsPowerOfTwo or (nWordIn = to_unsigned(2**i, nWordIn'length));end loop;end if;The last one, you figured it, is the one that yields the better implementation, although again, I don't think it formally should make a difference.And this last one, actually, as simple as it is (one of the simplest approaches!), yields a rather compact structure, almost as fast as the adder tree one.

author: BrianHG
author_rank: Super Contributor
timestamp: October 03, 2019, 12:37:08 am
content: Yes, using those loops would yield the same results and are far superior for large numbers of bits. Note that I write things out the way I do so I may insert exceptions or alternate conditions as I work since a routine like this I may use in first to arrive style interrupt controller where I may have specific priority conditions to add.As for using the IF, within there I may also clear or increment a timer/position counter or add additional flags.I tend to operate best at a low level, near the silicon and how my compiler tool likes to partition logic & unfortunately I started with a very early 2000s Quartus 1 which I had to learn to tease every little FMax out of it as working with things like video image processing and ram controller on an APEX FPGA, or Cyclone 1 at 150MHz speeds took quite a little miracle touch. (Yes, I started out with AHDL which couldn't synth loops, yet had some quick tricks when comparing addresses like using 'x's inside the compared bit-fields as 'don't care' bits.) (Talk about system crashes when your code became too elegant as well.)Today, this is obsolete as higher level programming will synthesize just fine and my techniques now only may serve as beginner teaching aids or for special circumstances like forcing a FPGA suite to implement a node literally with a degree of certainty.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 03, 2019, 04:24:10 pm
content: Quote from: BrianHG on October 03, 2019, 12:37:08 amYup, and it makes the overall code much more readable and easier to maintain.But, as I just showed above, there can be some pitfalls that are not necessarily obvious (those cases that make you think "why is the tool soo dumb?").That said, and as I mentioned earlier, as long as the end-result meets your requirements, there's no need to really bother. Over-optimizing is a waste of time, and can be risky.

author: MorgothCreator
author_rank: Contributor
timestamp: October 06, 2019, 10:33:16 am
content: Use LUT's like asynchronous memory, for 5 input LUT you be able to feed 5 bits from the word, on two LUT you feed 10 bit, from 2 LUT up you use a second stage LUT so you can feed up to 25 bit, 5 LUT first stage, 1 second stage, and so on, from 26 bit up you need 3 stage LUT cascaded and you can go up to 125 bit with 3 stage LUT cascaded.Is the fastest way, because you are limited on LUT inputs number, if you want to work on very high frequency you can pipeline these stages that is very simple, because is a simple logic you can compose it at low level.If you use high level formulas you will end up with some monster schematic

author: promach
author_rank: Frequent Contributor
timestamp: October 07, 2019, 04:38:48 am
content: Quote@SiliconWizardI understandDataWidth, but what arenWordInandlength?Could you post the code for signals declaration ?

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 07, 2019, 12:35:15 pm
content: Quote from: promach on October 07, 2019, 04:38:48 amDataWidth was a generic (constant) to define the register width in bits (probably obvious).nWordIn is of type unsigned here (typically: 'unsigned(DataWidth -1 downto 0);' )If the input "Word" is a std_logic_vector and you want to directly use that, you could also write the following instead:"Word = std_logic_vector(to_unsigned(2**i, nWordIn'length))"(I just prefer to use the "numeric" types in VHDL if there's going to be any kind of operation on them, and cast from/to std_logic only when required.)'length is a VHDL attribute that gives the "length" of the corresponding object (unsigned are arrays, so that's the number of bits here). It's handy to write reusable code. Here, it would be equivalent to DataWidth."to_unsigned(2**i, nWordIn'length)" is a handy way of expressing a power of two constant (2^i) of the width of nWordIn in a generic way. It's entirely processed at compile time. Dunno how to write this in Verilog. It may be possible; or you may have to write hard-coded constants instead? (Don't know...)Likewise, the "for" loop here is entirely processed at compile time. It's the equivalent of hand-writing "xxx or yyy or zzz or..." but in a more compact, and generic way. No need to rewrite anything if you just change the bit width.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 07, 2019, 01:25:25 pm
content: Quote from: promach on October 07, 2019, 04:38:48 amI see you're switching to VHDLThis code will not work. When you assign multiple times within the same block, only the last assignment survives.You need to create a variable and then use ":=" instead of "<=" to do the accumulation. Once you've done this, you assign the variable to the signal.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 07, 2019, 02:01:44 pm
content: Quote from: NorthGuy on October 07, 2019, 01:25:25 pmSorry about that. The "if" version worked though - due to the if structure in the for loop.I just copied it to write this "or" version, a bit too fast. Sorry about the fuckup. (For my tests, I actually wrote functions instead of putting the code directly in the process, so that was indeed correct. Moral: avoid posting illustrative code you haven't tested, or be prepared to apologize.)Due to the assignment using the previous value of bIsPowerOfTwo in the OR operation, it could actually lead to a pretty nasty behavior.SORRY again.The right version would be:Code:PowerOfTwo: process (Reset, Clk)variable b : boolean;beginif rising_edge(Clk) thenif Reset = '1' thenbIsPowerOfTwo <= false;elseb := false;for i in 0 to (DataWidth - 1) loopb := b or (nWordIn = to_unsigned(2**i, nWordIn'length));end loop;bIsPowerOfTwo <= b;end if;end if;end process;

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 07, 2019, 02:28:25 pm
content: As a bonus, I'll post the function I used to implement my "dedicated adder" structure. So far, it's the fastest approach I tested while being the smallest in LUTs (for a 100% generic HDL approach - of course you can do better with more hand-tweaking). It reaches ~262MHz.Note that it's a recursive function, which will naturally yield a tree structure.Code:type PowerOfTwo_t isrecordbPowerOfTwo, bCarry : boolean;end record;(...)function IsPowerOfTwo(w : unsigned) return PowerOfTwo_t isvariable iMid : integer;variable sPowerOfTwo, sPowerOfTwo1, sPowerOfTwo2 : PowerOfTwo_t;variable bCarry : boolean;beginif w'length > 2 theniMid := w'low + w'length / 2;sPowerOfTwo1 := IsPowerOfTwo(w(w'high downto iMid));sPowerOfTwo2 := IsPowerOfTwo(w((iMid - 1) downto w'low));bCarry := sPowerOfTwo1.bCarry or sPowerOfTwo2.bCarry;sPowerOfTwo.bPowerOfTwo := (not bCarry) and (sPowerOfTwo1.bPowerOfTwo xor sPowerOfTwo2.bPowerOfTwo);sPowerOfTwo.bCarry := bCarry or (sPowerOfTwo1.bPowerOfTwo and sPowerOfTwo2.bPowerOfTwo);elsesPowerOfTwo.bPowerOfTwo := ((w(w'low) xor w(w'high)) = '1');sPowerOfTwo.bCarry := ((w(w'low) and w(w'high)) = '1');end if;return sPowerOfTwo;end IsPowerOfTwo;-- Can be used like so: bIsPowerOfTwo <= IsPowerOfTwo(nWordIn).bPowerOfTwo;It shows: how you can use functions (even recursive here), and how you can use records to, for instance, return compound values from functions.Disclaimer: from my tests and design, it should be correct. Don't hesitate to state if you can find bad corner cases.

author: promach
author_rank: Frequent Contributor
timestamp: October 07, 2019, 02:57:00 pm
content: QuoteJust a moment, variablebis 1-bit , butnWordInis not 1-bit.How can you perform anORoperation between two of them ?

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 07, 2019, 06:20:59 pm
content: Quote from: promach on October 07, 2019, 02:57:00 pmIt's actually a boolean OR between two booleans here (and not between 'b' and 'nWordIn'!): 'b', and the equality test 'xx = yy', the result of which is a boolean. ('xx' and 'yy' do have the same type.)

author: hamster_nz
author_rank: Super Contributor
timestamp: October 07, 2019, 08:52:30 pm
content: I would have thought that the optimal way would be to look at the underlying FPGA architecture, find the biggest width LUT that it supports in a single slice (8 bits on Xilinx 7-series logic), then just compress 8 bits down to two (00 = no bits, 01 = one bit, 11 = more than one bit, apologies for the VHDL):case testvalue_8_bits iswhen "00000000" => result <= "00";when "00000001" => result <= "01";when "00000010" => result <= "01";when "00000100" => result <= "01";when "00001000" => result <= "01";when "00010000" => result <= "01";when "00100000" => result <= "01";when "01000000" => result <= "01";when "10000000" => result <= "01";when others => result <= "11";end case;Have as many of these as you need for the width of your input, concatenate the "result" outputs together and repeat, until you get down to two bits. A bit like numerology to find your birth numberThat would be one slice and level of logic for values up to 8 bits, two levels of logic and 18 slices for 32-bit values, and three levels of logic for values up to 256 bits.I would have guessed it to be about the same resource usage but much faster as the original (x &(x-1)==0), and without the corner-cases for 0 and 1.

author: NorthGuy
author_rank: Super Contributor
timestamp: October 08, 2019, 03:04:32 pm
content: Quote from: hamster_nz on October 07, 2019, 08:52:30 pmThe muxes which make the 8-input LUT out of the slice are slow. Using them may be slower than using LUTs from other slices.

author: TomS_
author_rank: Frequent Contributor
timestamp: October 09, 2019, 12:46:30 pm
content: Quote from: ucanel on September 30, 2019, 01:51:44 pmThere are more elegant ways to count 1's that dont involve testing every single bit. Thats how I used to do it, but then I thought there has to be a better way and did some searching around...For example, you can use a lookup table if you have the storage to hold that table, or something like Brian Kernighan’s Algorithm which will only loop n times, where n is the number of set bits - its quite ingenious really, if its worthwhile to implement in an FPGA.

author: Someone
author_rank: Super Contributor
timestamp: October 09, 2019, 08:44:54 pm
content: Quote from: TomS_ on October 09, 2019, 12:46:30 pmYou do have to test every single bit, there is no way around that. It only comes down to a speed vs size vs code readability/reusability trade off as is common in most FPGA algorithms. Higher end tools can help make those more automatic/directed but it is still testing all bits.