Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
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_two
always @(*) 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_two
always @(*) f = v && !(v & (v - 1));
^
%Warning-UNUSED: is_power_of_two.v:4: Signal is not used: 'f'
: ... In instance is_power_of_two
reg f;
^
%Error: Exiting due to 3 warning(s)
%Error: Command Failed /usr/bin/verilator_bin -Wall --lint-only is_power_of_two.v
Code Verilog - [expand] 1 2 3 4 5 6 7 8 module is_power_of_two(); reg [7:0] v = 8'b11110000; reg f; always @(*) f = v && !(v & (v - 1)); endmodule
@barry - I was going to say that , but it doesnt work.
1011:
1 XOR 0 = 1 XOR 1 = 0 XOR 1 = 1
So you dont get a power of 2.
Code Verilog - [expand] 1 2 logic [3:0] v; assign f = v && !(v & (v -1));
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 module not_test; logic [3:0] v; logic [3:0] vm1; initial begin for (int i=0; i<16; i++) begin v = i; $display ("v=%4b, v-1=%4b, v&(v-1)=%4b, !(v&(v-1))=%4b, v&&!(v&(v-1))=%4b, v&&~|(v&(v-1))=%4b", v, v-4'b1, v&(v-4'b1), !(v&(v-4'b1)), v&&!(v&(v-4'b1)), v&&~|(v&(v-4'b1))); end $stop; end endmodule
v=0000, v-1=1111, v&(v-1)=0000, !(v&(v-1))=0001, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=0001, v-1=0000, v&(v-1)=0000, !(v&(v-1))=0001, v&&!(v&(v-1))=0001, v&&~|(v&(v-1))=0001
v=0010, v-1=0001, v&(v-1)=0000, !(v&(v-1))=0001, v&&!(v&(v-1))=0001, v&&~|(v&(v-1))=0001
v=0011, v-1=0010, v&(v-1)=0010, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=0100, v-1=0011, v&(v-1)=0000, !(v&(v-1))=0001, v&&!(v&(v-1))=0001, v&&~|(v&(v-1))=0001
v=0101, v-1=0100, v&(v-1)=0100, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=0110, v-1=0101, v&(v-1)=0100, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=0111, v-1=0110, v&(v-1)=0110, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1000, v-1=0111, v&(v-1)=0000, !(v&(v-1))=0001, v&&!(v&(v-1))=0001, v&&~|(v&(v-1))=0001
v=1001, v-1=1000, v&(v-1)=1000, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1010, v-1=1001, v&(v-1)=1000, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1011, v-1=1010, v&(v-1)=1010, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1100, v-1=1011, v&(v-1)=1000, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1101, v-1=1100, v&(v-1)=1100, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1110, v-1=1101, v&(v-1)=1100, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
v=1111, v-1=1110, v&(v-1)=1110, !(v&(v-1))=0000, v&&!(v&(v-1))=0000, v&&~|(v&(v-1))=0000
always @(*) f = (v != 0) && ((v & (v - 1)) == 0);
No necessarily the only possible way to describe it, but clear and unequivocal Verilog, in so far preferred.The solution is to use
Code:always @(*) f = (v != 0) && ((v & (v - 1)) == 0);
How exactly? I don't think it's possible, but why don't you try?Someone suggested me to use power_of_two = ^v which is so much simpler.
No it's not the preferred solution, it is a verbose solution. Maybe you should switch to VHDL.The solution is to use
Code:always @(*) f = (v != 0) && ((v & (v - 1)) == 0);
Yeah my comment is, don't listen to them they don't know much. ^v is reduction XOR which is how you compute PARITY it does not compute powers of 2. I already mentioned that in my previous post #6.Someone suggested me to use power_of_two = ^v which is so much simpler.
Any comment ?
Code Verilog - [expand] 1 always @(*) is_power_of_two = ((in[7] + in[6] + in[5] + in[4] + in[3] + in[2] + in[1] + in[0]) == 1);
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity test is generic ( DATA_WIDTH : natural := 8 ); port ( inp : in std_logic_vector(DATA_WIDTH-1 downto 0); result : out std_logic ); end entity; architecture rtl of test is begin process (inp) variable n: integer; begin n := 0; for i in 0 to data_width-1 loop n := n + to_integer(unsigned(inp(i downto i))); end loop; result <= '0'; if n=1 then result <= '1'; end if; end process; end rtl;
Interesting that you are pointing this out to me as if I don't already know this solution. I have been discussing the question posted in #1 and the desire to translate it to Verilog. I was also commenting about how you cannot use a reduction XOR operation to check for power of two.@ads-ee
The following will also work, with less LUTs and higher fmax compared to the solution above.
Code Verilog - [expand] 1 always @(*) is_power_of_two = ((in[7] + in[6] + in[5] + in[4] + in[3] + in[2] + in[1] + in[0]) == 1);
Please correct me if wrong.
Code Verilog - [expand] 1 assign is_power_of_two = ((in[7] + in[6] + in[5] + in[4] + in[3] + in[2] + in[1]) == 1) & ~in[0];
20 = 1
So, in[0] could have the value of 1
Note: I am trying to detect one-hot as mentioned in post #1