Suppose we have a 128 bit reg:
reg [127:0] line;
And we first select a 32-bit word out of it, and then select byte from this word, all using slicing:
word = line[(127-32*byte_addr[3:2])-:32];
byte = word[7:0];
That works fine. But if I wan't to combine both operators, in same line, it seems it is not permitted.
mybyte = line[(127-32*byte_addr[3:2])-:32][7:0]; //all the hell breaks loose
Unfortunately I couldn't find a clear rule in SV 3.1a spec that forbids this.
Please delete your SystemVerilog 3.1a spec and get a free copy of the 1800-2012 LRM
The concatenation operator described in section 11.4.12 does what you want.
mybyte = {line[(127-32*byte_addr[3:2])-:32]}[7:0];
The 1800-2012 LRM says (7.4.6)
An expression can select part of a packed array, or any integer type,
which is assumed to be numbered down to 0.
The term part-select refers
to a selection of one or more contiguous bits of a single-dimension
packed array.
No mention of a part-select of a part-select, which is what you are trying to do.
Can you make line multidimensional? Something like
reg [3:0][7:0] line [3:0];
This would make the indexing trivial.
Related
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.
module test #(parameter WIDTH = 4) (output wire [WIDTH-1:0] result, input wire input );
// synopsys template
assign result = {WIDTH{input}};
endmodule
In this code, {input} after WIDTH means what? In what way that affects the parameter?
The curly brackets, preceded by the parameter, are called the replication operator.
assign result = {WIDTH{input}};
makes WIDTH copies of the 1-bit input-signal and assigns it to the WIDTH-bit output signal result. This means that input does thus not affect the parameter like you suspected in your question. Rather, the parameter affects how many copies of input are made.
For future reference please also consult the SystemVerilog LRM. Simple syntax-related questions like yours can be easily looked up in that document. For example, take a look at Section 11.4.12.1 Replication operation in the document that I referenced.
I assume that when placing an unbased, unsized literal on the left-most side of a concatenation will simply fill in any missing bits with the given value. I didn't see anything explicitly stating this in the LRM.
logic [63:0] rd_data;
logic [31:0] mem_dout;
logic [15:0] op_data;
....
assign rd_data = {'0, op_data, mem_dout};
Obviously, the following would be illegal:
Edit: As #dave_59 pointed out, this is legal, just not intuitive.
assign rd_data = {op_data, mem_dout, '0};
Just wanted to check if anyone knows that (1) this simulates as expected, and (2) the major synthesis tools do the correct thing and tie the upper 16 bits to 0.
Actually, both statements are legal. In a self-determined context '0 is equivalent to 1'b0. All the operands of a concatenation evaluate in a self-determined context. The result of both concatenations is a 32+16+1=49-bit expression. In the context of the assignment to rd_data, those expressions get right-aligned, and then left padded with 15 zeros.
So you get the result you are expecting, but for an entirely different reason.
I need to perform basic operations on strings like concatenation,replacement and comparison in my Verilog simulation. How could it be possible? Is there any built-in support?
Thanks in advance.
There is no string datatype in Verilog however verilog does support string literals and using them as byte vectors. This is the example from the spec:
module string_test;
reg [8*14:1] stringvar;
initial begin
stringvar = "Hello world";
$display ("%s is stored as %h", stringvar,stringvar);
stringvar = {stringvar,"!!!"};
$display ("%s is stored as %h", stringvar,stringvar);
end
endmodule
Since strings use the reg datatype you can use the normal operators to manipulate them, keeping in mind each character uses 8 bits.
5.2.3.1 String operations
The common string operations copy, concatenate, and compare are supported by Verilog HDL operators. Copy
is provided by simple assignment. Concatenation is provided by the
concatenation operator. Comparison is provided by the equality
operators. When manipulating string values in vector regs, the regs
should be at least 8*n bits (where n is the number of ASCII
characters) in order to preserve the 8-bit ASCII code.
You'll have to write some tasks or functions if you need operations like searching.
If you have access to a modern simulator which supports SystemVerilog syntax, there is a string data type. Strings can be concatenated and compared. Refer to the IEEE Std (1800-2009).
sjtaheri,
Reviving a dead thread, but I see this question come up, and there is a newer solution for it.
svlib is a free, open-source library of utility functions for SystemVerilog. It includes file and string manipulation functions, full regular expression search/replace, easy reading and writing of configuration files, access to environment variables and wall-clock time, and much more. This project was presented at DVCon 2014.
http://www.verilab.com/resources/svlib/
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.