Consider this
reg [5:0]assign_me;
reg [11:0]source_of_data;
assign_me <= source_of_data[5:0];
where assign_me always gets the least significant bits of source_of_data. Here the 5 is hardcoded in the last line in the sense that if for some reason the definition of assign_me changes to reg [6:0]assign_me I will have to change the last line. Is there any way to avoid this? Like for example in a pythonic notation something like assign_me <= source_of_data[:0]?
You could use:
assign_me <= source_of_data;
Verilog will assign the LSB's. But, you might get warnings about width mismatch.
A cleaner way is to use a parameter:
parameter WIDTH = 6;
reg [WIDTH-1:0]assign_me;
reg [11:0]source_of_data;
assign_me <= source_of_data[WIDTH-1:0];
When it comes to integral (packed) arrays, Verilog is loosely typed. Verilog will right justify to align LSBs, then make the assignment padding or truncating the MSB. You do not need to select a specific set of bits unless you need to mask bits on either end. Some tools will generate size mismatch warnings, especially around port connections, but the language does not require it.
One thing to be careful of is that selecting bits of a single is always unsigned regardless of the sightedness of the signal as a whole.
Related
What is the goal of declaring an array with an offset? [8:1] instead of [7:0]
I'm used to declare my signals with reg [7:0] sig; for an 8b signal.
Declaring reg [8:1] sig; or even reg [1008:1000] sig; gives the same value with sig = 1; $display("sig=%d", sig);
What's the purpose of defining them like that? Is there any disadvantage on calculation(mismatch)? Especially when used with other signals starting from 0.
It depends on the logic you want to create that addresses each individual bit (you might want to read this article on Big-Endian versus Little-Endian. If you don't need to select individual bits, then the ordering and start bit is completely arbitrary.
If you are designing a positioning system, then it might even make sense to have negative indexes.
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 always thought that bus notations is annotated like this:
input bus[MSB:LSB]
where MSB >= LSB.
But recently, I was told that even this is possible:
wire LSB >= MSB.
Is it even true?
If so, then how come synthesizer tools get the bus size and all? Do they consider that whichever index is big is MSB?
Yes, both directions of bit numbering could be used in declarations. However, the same ordering must be used when you do bit selection. For example
wire [0:15] bus;
reg [15:0] data;
assign bus [3:6] = data[3:0];
In most cases through industry the second notation is used (msb > lsb) and it is encouraged for consistency reasons. However in some situations it is convenient to do the opposite.
The bit numbering does not matter until you select a single bit or part select of the bus. As long as you know how the signal is declared any tool can figure out the bit width and msb ordering
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 new to Verilog, and am having a lot of trouble with it. For example, I want to have an array with eight cells, each of which is 8 bits wide. The following doesn't work:
reg [7:0] transitionTable [0:7];
assign transitionTable[0] = 10;
neither does just doing transitionTable[0] = 10; or transitionTable[0] = 8'h10; Any ideas?
(In case it is not obvious and relevant: I want to make a finite state machine, and specify the state transitions in an array, since that seems easier than a massive case switch.)
When using assign you should declare the array as a wire instead of areg.
Since your goal is to design an FSM, there is no need to store the state values in an array. This is typically done using Verilog parameter's, a state register and a next_state with a case/endcase statement.
The following paper shows a complete example: FSM Fundamentals
If this is targeted towards synthesis:
A little beyond what was answered above, there are standard FSM coding styles that you should adhere to so the tools can perform better optimization. As described in the Cummings paper, one-hot is usually best for FPGA devices and in fact ISE(with default settings) will ignore your encoding and implement whatever it thinks will best utilize the resources on the device. This almost invariably results in a one-hot encoded FSM regardless of the state encoding you chose, provided it recognizes your FSM.
OK, so to answer your question, let's dig a little deeper into Verilog syntax.
First of all, to specify a range of bits, either do [MSB:LSB] or [LSB:MSB]. The standard is MSB:LSB but it is really up to you here, but try to be consistent.
Next, in array instantiation we have:
reg WIDTH reg_name NUMBER;
where WIDTH is the "size" of each element and NUMBER is the number of elements in the array.
So, you first want to do:
reg [7:0] transitionTable [7:0];
Then, to assign particular bytes (8 bits = 1 byte), do:
initial begin
transitionTable[0] = 8'h10;
end
A good book to learn Verilog from is FPGA Prototyping By Verilog Examples by Pong P. Chu.