I am just getting started with verilog. I was looking at some example code for a floating multiply someone wrote and I came across this...
if ($signed(b_e == -1023) && (b_m == 0)) begin
z[63] <= 1;
z[62:52] <= 2047;
z[51] <= 1;
z[50:0] <= 0;
state <= put_z;
end
I am just wondering what the $signed is. I tried googling it but I just got a bunch of results about signed math (not about this function). I thought functions that begin with a $ were only for test-bench code. What does this function do? Also is there a place where I can get a list of the verilog functions?
There are a number of Verilog system functions can be used for synthesis as well as testbenches. Most of the synthesizable function perform some kind of arithmetic or logical conversion. SystemVerilog has replaced most of the $functions with casts or built-in methods.
In this example, the use of $signed makes no sense to me as the result of a comparison is always a 1-but unsigned value, and this result will be and'ed with another 1-bit expression. So the $signed is not doing anything. Casting a value to signed only makes sense if the value need to be extended to a larger width, or in a relational operation.
You can find the list of functions in the IEEE Std 1800-2017 Language Reference Manual (LRM).
Related
I have a conditional 2-bit variable coming in. Based off its value, the current value is either incremented or decremented. By that, I mean:
module verilog_block(clk, cond, incr, curr_val)
input clk;
input [1:0] cond;
input [5:0] incr;
output reg [5:0] curr_val;
always # posedge(clk)
begin
curr_val <= curr_val + (!cond[1] - cond[1]) * incr * cond[0];
end
endmodule
Sorry if I made any mistakes, I haven't checked this specific code, as I am just trying to illustrate my question. If cond[0]==0, I don't want curr_val to change (irrespective of cond[1]). If cond[1]==1, I want curr_val to reduce by incr, and if cond[1]==0, I want curr_val to increment by incr.
I think this works, theoretically, but my goal is to expand this into a much larger code. Therefore, it needs to be optimized. I know that the * operator can be slow and require a lot of resources, but I am not sure if that applies to the case of multiplication with only one bit.
If you can spot a way to make this code optimized for area, please let me know. Thanks a lot.
Any good synthesis tool will optimize multiplication where it can, especially when it involves multiplication by zero or any power of 2. But you've created a very hard to read operation. Why not write it the way you said it:
always # posedge(clk)
begin
if (cond[0]==1)
curr_val <= curr_val + (cond[1]==1) ? -incr : incr;
end
I recently came across this answer on stackoverflow.
With Verilog, once you take a part-select, the result is unsigned. Use the $signed system task on the part select to make it signed.
Is this method synthesizable (ie the system task $signed)
If it is not synthesizable, is there a different way to perform arithmetic shift on variables like a <= a>>>2 (this should give the quotient when a is divided by 4).
It certainly is synthesizable. Whether your particular tool supports it is another question.
You can also use a cast in SystemVerilog.
res = signed'(registers[0][0]) >>> 2;
I initialize a register
reg[1:0] yreg;
and manipulate it a bit, i.e., value from prev. iteration of program is shifted to 1 spot when I add in the new value in the 0 spot
yreg = SIGNAL; //here SIGNAL is an input to the program
And then I want to access the values at the 0 and 1 spots in the register later for a calculation. How can I do this? My initial reaction was yreg[0] and yreg[1] (I normally program in python =) but this is producing an error (line 35 is the line of code that has yreg[0] and yreg[1] in it):
ERROR:HDLCompiler:806 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 35: Syntax error near "[".
My assumption when I saw this was that it's not the right syntax to use the brackets to access a certain index of the register. How do you properly access the information in an index of a register? I'm having trouble finding information on this.
Sorry for the probably ridiculous question, this is my first time ever using verilog or FPGAs in general.
Full Code
module trapverilog(
input CLK,
input SIGNAL,
input x,
output OUT
);
reg[1:0] yreg;
float sum = 0;
always #(posedge CLK)
begin
yreg = SIGNAL; //should shift automatically...?
sum = ((reg[0] + reg[1])*x/2) + sum; //this is effectively trapezoidal integration
OUT = sum;
end
endmodule
You have a fundamental misunderstanding of how Verilog signals work.
By default, all Verilog signals are single bits. For example, in your code, SIGNAL, x, and out are all one bit wide. They cannot store a number (other than 0 or 1).
Specifying a width when you define a signal (like reg [1:0] yreg) controls how many bits are used to represent that signal. For instance, yreg is a two-bit signal. This does not mean that it "shifts automatically"; it just means that the signal is two bits wide, allowing it to be used to represent numbers from 0 to 3 (among other things).
I would strongly advise that you work through a course in digital electronics design. Verilog programming is very different from procedural programming languages (such as Python), and you will have a hard time making sense of it without a solid understanding of what you are actually building here.
Apparently as per this answer using brackets to get a certain index of a register is correct. I just forgot to call the variable properly - I was calling reg[0] instead of yreg[0]. Changing this fixed the error.
I'm trying to understand following scenario:
typedef enum logic [2:0] {
ONE, TWO, THREE, FOUR, FIVE
} enum_t;
A case statement with enum_t type in case expression:
enum_t case_expression;
logic [2:0] result;
case (case_expression)
ONE: result = 3'b000;
TWO: result = 3'b001;
THREE: result = 3'b010;
FOUR: result = 3'b011;
FIVE: result = 3'b100;
endcase
I'm not sure or clear about following :
Is it okay not to have a default case statement for result? The case_expression is an enum with only 5 valid values. However it's 3 bits. So how the synthesis tool will evaluate this logic? Is it going to infer latch ?
All case items are mutually exclusive. So can I use unique keyword here to aid synthesis tool to optimize the design?
I don't have much expereince in synthesis. So I would appreciate any feedback. Thanks!
This depends on how strongly typed your synthesis tool is. Unfortunately, there are a number of ways that your case_expression could have the value 3'b111 (through casting and poor error checking in some simulation tools). So its best to put the default in for safety's sake.
If "case_expression" takes the value "x", the case statement will not be able to resolve which case to enter. If default case were to be mentioned, it would gracefully enter the default case. You will see runtime error if case_expression takes value of "x" if default is not mentioned.
I believe "unique case" is a directive to synthesis tool mentioning all cases are enumerated. This would prevent a latch. If in simulation if none of the ENUM values are on the case expression, then during simulation a runtime error will be reported.
I'm reading some third party Verilog, and found this:
function [31:0] factorial;
input [3:0] operand;
reg [3:0] index;
begin
factorial = operand ? 1 : 0;
for(index = 2; index <= operand; index = index + 1)
factorial = index * factorial;
end
endfunction
It seems that the begin and end keywords are redundant here. Are they? What is their use?
I don't know about the general case, but in this specific case:
If a function contains more than one statement, the statements must be
enclosed in a begin-end or fork-join block.
Source: Verilog Golden Reference Guide
Both answers are correct. If the Verilog task or function had multiple statements, they were also required to have begin-end statements. Starting in SystemVerilog-2005, we removed the requirement to put begin-end inside of something that already had a begin-end. Most of us on the committee thought it was silly to require a begin-end inside of something that was already going to have endfunction/endtask. I mean, come-on! Don't you think a compiler could figure out that when it got the endtask/endfunction statement that it was at the end of the task or function?? Removing the begin-end from tasks and functions cuts out a surprising amount of useless code. Score another point for SystemVerilog!
According to the SystemVerilog extension (IEEE Standard 1800-2009), begin/end are optional inside a function. However, your toolset (simulator, etc.) must be capable of understanding this syntax, which was introduced in 2005.