I'm trying to translate a Verilog program into VHDL and have stumbled across a statement where a question mark (?) operator is used in the Verilog program.
The following is the Verilog code;
1 module music(clk, speaker);
2 input clk;
3 output speaker;
4 parameter clkdivider = 25000000/440/2;
5 reg [23:0] tone;
6 always #(posedge clk) tone <= tone+1;
7 reg [14:0] counter;
8 always #(posedge clk) if(counter==0) counter <= (tone[23] ? clkdivider-1 : clkdivider/2-1); else counter <= counter-1;
9 reg speaker;
10 always #(posedge clk) if(counter==0) speaker <= ~speaker;
11 endmodule
I don't understand the 8th line, could anyone please shed some light on this?
I've read on the asic-world website that the question mark is the Verilog alternate for the Z character. But I don't understand why it's being used in this context.
Kind regards
That's a ternary operator. It's shorthand for an if statement
Format:
condition ? if true : if false
Example:
tone[23] ? clkdivider-1 : clkdivider/2-1
Translates to something like (not correct syntax but I think you'll get it):
if tone[23] is 1, counter = clkdivider-1
else counter = clkdivider/2-1
Here are two examples of a 2 to 1 MUX using if statement and ternary operator.
On the asic-world website, it is covered under Conditional Operators
Another way of writing, e.g. the following Verilog:
q <= tone[23] ? clkdivider-1 : clkdivider/2-1;
in VHDL would be:
q <= clkdivider-1 when tone[23] else clkdivider/2-1;
Think of it as a MUX, before the ? is the selection bit and on two sides of : are the inputs
Related
I am trying to learn Verilog and I have this simple code
module division (
output reg [14:0] A,
input [14:0] D);
reg[4:0] i;
always #(*) begin
for (i = 14; i >= 0; i = i-1) begin
A[0] = D[i];
end
end
endmodule
This returns the error : Index out of range for D.. I have no idea why, since D is declared on that interval. Can you please help me?
I know the code might not make any sense, but I only included the relevant part to the issue.
You have declared i as unsigned, so the expression i >= 0 will always be true.
When i reaches 0, the next iteration is 5'b11111, which is out of range. You should declare i as an integer or add the signed keyword.
Bit to know new syntax := (the walrus operator) that assigns values. Anyone explain with brief example.
Lets take the first example from the What's new in 3.8 documentation:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
"Normal" assignment is a statement, it can't be used as part of expressions. Without the expression-assignment ("walrus") operator the above example would have to be something like
n = len(a)
if n > 10:
print(f"List is too long ({n} elements, expected <= 10)")
With the expression-assignment you can combine the assignment to n with the condition.
I am working with a legacy code base written in VB and have run into a conditional operator that I don't understand and cannot figure out what to search for to resolve it.
What I am dealing with is the following code and the variables that result as true. The specific parts that I do not understand are (1) the relationship between the first X and the first parens (-2 and (2) the role of X < 2
If X is a value below -2 it evaluates as false.
If X is a value above 2 it evaluates as true.
If Y is below 5 it evaluates to true as expected.
X = 3
Y = 10
If X > (-2 And X < 2) Or Y < 5 Then
'True
Else
'False
End If
I'm gonna leave off the Or Y < 5 part of the expression for this post as uninteresting, and limit myself to the X > (-2 And X < 2) side of the expression.
I haven't done much VB over the last several years, so I started out with some digging into Operator Precedence rules in VB, to be sure I have things right. I found definitive info on VBA and VB.Net, and some MSDN stuff that might have been VB6 but could also have been the 2013 version of VB.Net. All of them, though, gave the < and > comparison operators higher precedence over the And operator, regardless of whether you see And as logical or bitwise.
With that info, and also knowing that we must look inside parentheses first, I'm now confident the very first part of the expression to be evaluated is X < 2 (rather than -2 And X). Further, we know this will produce a Boolean result, and this Boolean result must be then converted to an Integer to do a bitwise (not logical) And with -2. That result (I'll call it n), which is still an Integer, can at last be compared to see if X > n, which will yield the final result of the expression as a Boolean.
I did some more digging and found this Stack Overflow answer about converting VB Booleans to Integers. While not definitive documentation, I was once privileged to meet the author (Hi #JaredPar) and know he worked on the VB compiler team at Microsoft, so he should know what he's talking about. It indicates that VB Boolean True has the surprising value of -1 as an integer! False becomes the more-normal 0.
At this point we need to talk about the binary representation of negative numbers. Using this reference as a guide (I do vaguely remember learning about this in college, but it's not the kind of thing I need every day), I'm going to provide a conversion table for integers from -3 to +3 in an imaginary integer size of only 4 bits (short version: invert the bit pattern and add one to get the negative representation):
-3 1101
-2 1110
-1 1111 --this helps explain **why** -1 was used for True
0 0000
1 0001
2 0010
3 0010
Stepping back, let's now consider the original -2 And X < 2 parenthetical and look at the results from the True (-1) and False (0) possible outcomes for X < 2 after a bitwise And with -2:
-2 (1110) And True (1111) = 1110 = -2
-2 (1110) And False (0000) = 0000 = 0
Really the whole point here from using the -1 bit pattern is anything And True produces that same thing you started with, whereas anything And False produces all zeros.
So if X < 2 you get True, which results in -2; otherwise you end up with 0. It's interesting to note here that if our language used positive one for True, you'd end up with the same 0000 value doing a bitwise And with -2 that you get from False (1110 And 0001).
Now we know enough to look at some values for X and determine the result of the entire original expression. Any positive integer is greater than both -2 and 0, so the expression should result in True. Zero and -1 are similar: they are less than two, and so will be compared again only as greater than -2 and thus always result in True. Negative two, though, and anything below, should be False.
Unfortunately, this means you could simplify the entire expression down to X > -2. Either I'm wrong about operator precedence, my reference for negative integer bit patterns is wrong, you're using a version of VB that converts True to something other than -1, or this code is just way over-complicated from the get-go.
I believe the sequence is as follows:
r = -2 and X 'outputs X with the least significant bit set to 0 (meaning the first lesser even number)
r = (r < 2) 'outputs -1 or 0
r = (X > r) 'outputs -1 or 0
r = r Or (Y < 5)
Use AndAlso and OrElse.
I'm still trying to get used to some of the quirks of VHDL and I'm having a bit of an issue. First off, I understand that shift operators like rol, ror, ssl, srl, etc. are not synthesizeable. The purpose of this lab is to use a golden model to check against a synthesizeable version of the same thing in a testbench.
Now, the purpose of this program is to convert thermometer code into a 3-bit binary number. So, in other words, thermometer code "00000001" = "001", "00000011" = "010", "00000111" = "011", etc. I'm basically trying to count the number of 1's in the string from right to left. There will be no case where a '0' is placed between the string of 1's, so the vector "00011101" is invalid and will never occur.
I've devised a non-synthesizeable (and so far, non-compile-able) algorithm that I can't figure out how to get working. Basically, the idea is to read the thermometer code, shift it right and increment a counter until the thermometer code equals zero, and then assign the counter value to the 3-bit std_logic_vector. Below is the code I've done so-far.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity therm2bin_g is
port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
bin : out std_logic_vector(2 downto 0); -- binary code
i : integer range 0 to 7);
end therm2bin_g;
architecture behavioral_g of therm2bin_g is
begin
golden : process(therm)
begin
while(therm /= "00000000") loop
therm <= therm srl 1;
i = i + 1;
end loop;
bin <= std_logic'(to_unsigned(i,3));
end process golden;
behavioral_g;
here's a version that is synthesisable. the while loop is replaced by a for loop. srl is implemented explicitly:
entity therm2bin_g is
port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
bin : out std_logic_vector(2 downto 0); -- binary code
i : out integer range 0 to 7);
end therm2bin_g;
architecture behavioral_g of therm2bin_g is
begin
golden : process(therm)
variable i_internal: integer range 0 to 7;
begin
i_internal:=0;
for idx in 0 to therm'length loop
if therm/="0000000" then
therm<='0' & therm(therm'left downto 1);
i_internal := i_internal + 1;
end if;
end loop;
bin<=std_logic_vector(to_unsigned(i_internal,bin'length));
i<=i_internal;
end process golden;
end behavioral_g;
"... operators like rol, ror, ssl, srl, etc. are not synthesizeable..."
Who says that on who's authority? Have you checked? On which synthesis tool? Was it a recent version, or a version from the early 1990s?
Note that the argument that some tools might not support it is just silly. The fact that some kitchens might not have an oven does not stop people from writing recipes for cake.
I'm new at using the glpk tool, and after writing a model for certain integer problem and running the solver (glpsol) i get negative values in some constraint that shouldn't be negative at all:
No.Row name Activity Lower bound Upper bound
8 act[1] 0 -0
9 act[2] -3 -0
10 act[2] -2 -0
That constraint is defined like this:
act{j in J}: sum{i in I} d[i,j] <= y[j]*m;
where the sets and variables used are like this:
param m, integer, > 0;
param n, integer, > 0;
set I := 1..m;
set J := 1..n;
var y{j in J}, binary;
As the upper bound is negative, i think the problem may be in the y[j]*m parte, of the right side of the inequality.. perhaps something with the multiplication of binarys? or that the j in that side of the constrait is undefined? i dont know...
i would be greatly grateful if someone can help me with this! :)
and excuse for my bad english
thanks in advance!
Sounds like you have an overflow problem. Which values of m and n produced the output shown?