I am trying to create an Immediate Generator for RISC-V assembly, but I have encountered an error with if statement.
Here is my code in Verilog:
module signextend(in, out, sel);
parameter nin = 32;
parameter nout = 32;
input [nin-1:nin-25] in;
input [2:0] sel;
output [nout-1:0] out;
if (sel == 3'b000)
begin
assign out[19:0] = in[31:12];
assign out[31:20] = {12{in[31]}};
end
else if (sel == 3'b001)
begin
assign out[11:0] = in[31:20];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b010)
begin
assign out[4:0] = in[24:20];
assign out[31:5] = 0;
end
else if (sel == 3'b011)
begin
assign out[3:0] = in[11:8];
assign out[4:9] = in[30:25];
assign out[10] = in[7];
assign out[11] = in[31];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b100)
begin
assign out[4:0] = in[11:7];
assign out[11:5] = in[31:25];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b101)
begin
assign out[9:0] = in[21:30];
assign out[10] = in[20];
assign out[18:11] = in[19:12];
assign out[19] = in[31];
assign out[31:20] = {12{in[31]}};
end
else
assign out = 32'hxxxx;
endmodule
The problem exists in each if statement:
The generate if condition must be a constant expression.
You need to put all your code inside an always block and remove the assigns:
always #(*) begin
if (sel == 3'b000)
begin
out[19:0] = in[31:12];
out[31:20] = {12{in[31]}};
end
else if (sel == 3'b001)
// etc
An always block contains a little bit of software (your if statements) that models a little bit of hardware (the resulting combinational logic).
It is legal to have an if statement outside an always (or initial) block, but then it means something different. Then it means conditional including of hardware, ie if some condition is true, include this hardware. Such a condition has to be static, ie fixed at compile time. It cannot be an input, like your sel. If you think about it, that makes total sense: how could you create some hardware that magically appears and disappears depending on the value of some input? You can't. That is why you are getting your error.
You need to remove the assigns, because while it is legal to have an assign inside an always block, it means something weird. Never do it.
Related
I was wondering if I could get some help with this small script I tested.
For some reason, the if statement isn't executing, meaning the function won't run even if the value doesn't equal Rinzler. charData is a StringValue to be specific.
local charData = script.Parent.Data.CharacterData
local active = game.Workspace.Part
function change()
if not charData.Value == "Rinzler" then
charData.Value = "Rinzler"
print("Character has changed to Rinzler.")
end
end
active.Touched:Connect(change)
"Character has changed to Rinzler" isn't printing in the console no matter what I do.
The problem is here if not charData.Value == "Rinzler"
The not operator has higher priority than == in operator precedence list.
Update that code to:
function change()
if charData.Value ~= "Rinzler" then
charData.Value = "Rinzler"
print("Character has changed to Rinzler.")
end
end
I have a rather large if else block.
always #(posedge clk)
begin
r <= 3;
if( cond1 )
a <= 1;
else if( cond2 )
begin
a <= 2;
r <= 3;
end
else
a <= 3;
end
In this case I am trying to specify a default value for r in the blocks. Would the top r<= statement be executed for the first and last if blocks?
It is perfectly legal to specify default values.
In Verilog the last assignment 'wins'.
- For non blocking assignments that means only the last one is executed.
- For blocking assignments they are executed in the order they are encountered.
In fact in complex state machines it is a method I prefer.
You can use it in both combinatorial (blocking) and clocked/registered (non-blocking) code.
However it is good coding practice to flag this so the reader
knows you are setting defaults and that those values can be override further down in the code. Here a is a snippet from a UART transmitter:
// Defaults for TX FSM
nxt_tx_state = tx_state;
nxt_tx_bit_cnt = tx_bit_cnt;
nxt_tx_samp_cnt = tx_samp_cnt;
nxt_shift_out = shift_out;
The same holds when you have a bottom-all-overriding assignment:
....
....
// This overrides all the above
if (emergency_halt)
state <= IDLE_STATE;
How does the synhtesis tool process this default value? Or is not something I dont have to look at
You don't have to worry about it. Most important is that the simulation and the hardware behave in the same way.
But I'll answer anyway. Simplest is to give an example:
always #(*)
begin
// default
A = 1;
if (B==2)
A = 3;
if (B==4)
A = 5;
end
The synthesis tool translates this into:
if (B==4)
A = 5;
else if (B==2)
A = 3;
else
A = 1;
In this case the two 'if' statements are mutually exclusive but even if that is not the case the result will be that the hardware behaves as the blocking assignments: The last one wins.
I am debugging the following problem. Post detailed problem statement and the coding. My question is whether the last else if (else if (A[i-1]==C[i+j-1] && B[j-1]==C[i+j-1])) is necessary? I think it is not necessary since it is always covered either by else if(A[i-1]==C[i+j-1] && B[j-1]!=C[i+j-1]), or covered by else if (A[i-1]!=C[i+j-1] && B[j-1]==C[i+j-1]), i.e. previous two if-else check conditions. Thanks.
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
// The main function that returns true if C is
// an interleaving of A and B, otherwise false.
bool isInterleaved(char* A, char* B, char* C)
{
// Find lengths of the two strings
int M = strlen(A), N = strlen(B);
// Let us create a 2D table to store solutions of
// subproblems. C[i][j] will be true if C[0..i+j-1]
// is an interleaving of A[0..i-1] and B[0..j-1].
bool IL[M+1][N+1];
memset(IL, 0, sizeof(IL)); // Initialize all values as false.
// C can be an interleaving of A and B only of sum
// of lengths of A & B is equal to length of C.
if ((M+N) != strlen(C))
return false;
// Process all characters of A and B
for (int i=0; i<=M; ++i)
{
for (int j=0; j<=N; ++j)
{
// two empty strings have an empty string
// as interleaving
if (i==0 && j==0)
IL[i][j] = true;
// A is empty
else if (i==0 && B[j-1]==C[j-1])
IL[i][j] = IL[i][j-1];
// B is empty
else if (j==0 && A[i-1]==C[i-1])
IL[i][j] = IL[i-1][j];
// Current character of C matches with current character of A,
// but doesn't match with current character of B
else if(A[i-1]==C[i+j-1] && B[j-1]!=C[i+j-1])
IL[i][j] = IL[i-1][j];
// Current character of C matches with current character of B,
// but doesn't match with current character of A
else if (A[i-1]!=C[i+j-1] && B[j-1]==C[i+j-1])
IL[i][j] = IL[i][j-1];
// Current character of C matches with that of both A and B
else if (A[i-1]==C[i+j-1] && B[j-1]==C[i+j-1])
IL[i][j]=(IL[i-1][j] || IL[i][j-1]) ;
}
}
return IL[M][N];
}
thanks in advance,
Lin
You do need the final else if to catch the cases when the next character in C matches the next character in both A and B. For example, run your program with A="aaaa", B="aaaa", and C="aaaaaaaa" and see if you enter that last else if block.
Additionally, you also need a final else block to handle cases when none of the previous conditions match. In this case, you need to set IL[i][j] to false. Otherwise, the function will incorrectly return true.
Edit: Even though the code uses memset to initialize all elements of IL to 0, it may not work because ISO C++ does not support variable length arrays (VLAs). In fact, this is what happened when I tried the code at cpp.sh. It uses g++-4.9.2 with flags that causes it to report sizeof(IL) to be 1 even though g++ is supposed to support VLAs. Maybe this is a compiler bug or maybe it does not support multidimensional VLAs. In any case, it might be safer to not use them at all.
Here is an extremely simplified version of a section of code that I am having trouble with.
int i = 0;
int count = 0;
int time = 50;
int steps = 1000;
double Tol = 0.1;
bool crossRes = false;
bool doNext = true;
for (int i=0; i<steps; i++) {
//a lot of operations are done here, I will leave out the details, the only
//important things are that "dif" is calculated each time and doNext either
//stays true or is switched to false
if (doNext = true) {
if (dif <= Tol) count++;
if (count >= time) {
i = steps+1;
crossRes = true;
}
}
}
if (crossRes = true) {
printf("Nothing in this loop should happen if dif is always > Tol
because count should never increment in that case, right?");
}
My issue is that every time it gets done with the for loop, it executes the statements inside the "if (crossRes = true)" brackets even if count is never incremented.
You've made a common (and quite frustrating) mistake:
if (crossRes = true) {
This line assigns crossRes to true and returns true. You're looking to compare crossRes with true, which means you need another equals sign:
if (crossRes == true) {
Or more concisely:
if (crossRes) {
I stand corrected:
if (crossRes)
You wouldn't have this problem if your condition was
if (true = crossRes)
because it wouldn't compile.
`crossRes = true` always evaluates to `true` because it's an assignment, to `true`.
You want `crossRes == true`:
if (crossRes == true) {
printf("Nothing in this loop should happen if dif is always > Tol
because count should never increment in that case, right?");
}
= is assignment, == is equality comparison. You want:
if (crossRes == true) {
You make the same mistake here:
if (doNext = true) { // Bad code
The other answers here have told you the problem. Often your compiler will warn you but a way to ensure that you do not do this is to put the constant term on the left
true == crossRes
that way you get a compiler error instead of a warning and so it can't escape unnoticed since
true = crossRes
wont compile.
First, although a number of people have pointed to the problem with if (crossRes = true), for some reason they haven't (yet, anyway) pointed to the same problem with if (doNext = true).
I'll stick to pointing out that you really want if (crossRes) rather than if (crossRes == true) (or even if (true == crossRes)).
The first reason is that it avoids running into the same problem from a simple typo.
The second is that the result of the comparison is a bool -- so if if (crossRes==true) is necessary, you probably need if (((((crossRes == true) == true) == true) == true) just to be sure (maybe a few more -- you never know). This would, of course, be utterly silly -- you're starting with a bool, so you don't need a comparison to get a bool.
I'd also note for the record, that if you insist on doing a comparison at all, you should almost always use if (x != false) rather than if (x == true). Though it doesn't really apply in C++, in old C that doesn't have an actual Boolean type, any integer type can be used -- but in this case, a comparison to true can give incorrect results. At least normally, false will be 0 and true will be 1 -- but when tested, any non-zero value will count as equivalent to true. For example:
int x = 10;
if (x) // taken
if (x == true) // not taken, but should be.
If you're not starting with a Boolean value as you are here, then the if (<constant> <comparison> <variable>) makes sense and is (IMO) preferred. But when you're starting with a Boolean value anyway, just use it; don't do a comparison to produce another of the same.
Can I create an instance of an object within an if statement?
I've made 2 checkboxes in order to controll which constructor I use, but i get the error message " The name "mth" does not exist in the current context "
if (checkBox1.Checked && checkBox2.Checked)
{
Facto mth = new Facto(label3, wait_time, progressBar1);
}
else if(checkBox1.Checked==false && checkBox2.Checked)
{
Facto mth = new Facto(label3,wait_time);
}
else if (checkBox1.Checked && checkBox2.Checked == false)
{
checkBox1.Checked = false;
Facto mth = new Facto();
}
else
{
Facto mth = new Facto();
}
int result = mth.Factorial(number);
What am I doing wrong? I'm new to C# and I don't really have the hang of it yet.
Any help would be appreciated.
Thanks in advance.
This is a scoping problem. The variable mth only exists within the scope (brackets in your case) that it's defined in. As soon as you leave the scope the variabel is no longer available. Since you use the mth variable at the end of your code (and outside the scope) you get this error. In order to fix this you need to define the variable at a higher scope. Note that you don't have to assign it there.
This leads to something like (Note that I reformatted your brackets to make it easier to see the scope levels)
Facto mth; // Define it as the most outer scope level you are using it
if (checkBox1.Checked && checkBox2.Checked)
{
mth = new Facto(label3, wait_time, progressBar1);
}
else
if(checkBox1.Checked==false && checkBox2.Checked)
{
mth = new Facto(label3,wait_time);
}
else
if (checkBox1.Checked && checkBox2.Checked == false)
{
checkBox1.Checked = false;
mth = new Facto();
}
else
{
mth = new Facto();
}
int result = mth.Factorial(number);
EDIT: I would advice to always use {} brackets on every if and else even if they are not strictly required like in your case. As you can see in the layout it's not so easy to see where your first else ends and that the "int result line isn't part of it.
The problem here is not creating instance inside if block.
The mth reference is declared in the if/else blocks. This restricts the visibility/scope only to that block. so mth is not available when you try to refer it in line int result = mth.Factorial(number);
Just declare mth outside the if block and only instantiate inside if/else blocks.
For ex:
Facto mth;
if (checkBox1.Checked && checkBox2.Checked)
{
mth = new Facto(label3, wait_time, progressBar1);
}
...
Refer http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx for some basic information.