I'm using systemVerilog and I have a package that holds some of my modules parameter values (for example parameter SPI_RATE = 2_000_000;). Is there any way I can set one value for simulation and a different one for synthesis? (I'm using ModelSim).
For example I would like something like:
if(IN_SIM) begin
parameter SPI_RATE = 2_000_000;
end
else begin
parameter SPI_RATE = 1_000_000;
end
Thanks!
Yes, that's possible. SystemVerilog supports conditional compiler directives such as `ifdef, `ifndef, `else, `elsif, and `endif. Note that those directives are using a grave accent (ASCII 0x60) and not a normal apostrophe (ASCII 0x27).
Furthermore, most synthesis tools support the macro identifier SYNTHESIS. So, you could do the following:
`ifdef SYNTHESIS
parameter SPI_RATE = 1_000_000;
`else
parameter SPI_RATE = 2_000_000;
`endif
Yes. You can set a macro from the command line in any simulation using the +define plusarg, eg:
+define+SPI_RATE=2_000_000
Then somewhere in your code, you can say
parameter SPI_RATE = `SPI_RATE;
And in your synthesiser there will be a mechanism for setting the value of a macro: read the instructions for your synthesiser.
IMHO -
Using the first answer
`ifdef SYNTHESIS
is much preferred over the 3rd answer
/* synthesis translate_off */
The last form is a variation of /* synopsys translate_off */, which was unique to one synthesis tool.
The macro SYNTHESIS has been in common use for more than a decade, and should be defined by any synthesis tool, without any extra command line options.
If you want to run equivalence checking (rtl vs gate level netlist), you will probably need to define the SYNTHESIS macro by the method recommended for that equivalence tool.
With Synplify Pro, you can use the /*synthesis translate_off */ /*synthesis translate_off */ to accomplish this, a similar construct is usable in VHDL with appropriate syntax/comment changes. Xilinx Vivado uses // synthesis translate_off and // synthesis translate_on
const logic IN_SIM = 1'b0
/*synthesis translate_off */
|| 1'b1
/*synthesis translate_on */
;
The advantage of this construct is that it doesn't require any external scripting changes.
Related
Are pure (only accessing input regs) functions synthesizable when they are accessed as a cross module reference?
Example:
// a module with functions inside
module functions;
function fn1;
input reg i;
fn1 = i;
endfunction
endmodule
// must be synthesizable vvv
module consumer(input i, output o);
functions fns();
assign o = fns.fn1(i);
endmodule
It's perfectly synthesizable because a pure function gets in-lined into the combinatorial logic inside the the calling module. There are no cross-module reference to any signals after that. But many synthesis tools haven chosen not to handle any kind of cross-module reference, even if the hierarchy gets flattened.
In SystemVerilog you would define a function inside a package and then import the package into your module. Any synthesis tools that supports the most basic SystemVerilog constructs also supports this.
It's not possible in Verilog. (yes, that's the complete answer ffs)
I'm using a simple UART in Verilog that has as part of some definitions of ASCII values. For example:
parameter ASCII_a = 8'h61;
parameter ASCII_b = 8'h62;
parameter ASCII_c = 8'h63;
parameter ASCII_d = 8'h64;
parameter ASCII_e = 8'h65;
parameter ASCII_f = 8'h66;
etc. I'm trying to find the best way to create these parameters just once and then get access to them in multiple files. I'm used to VHDL when you can create a package and include that package where you like. I know that Verilog can use the include directive, but then I believe I need to surround it with ifdefs.
I would like to just create a SystemVerilog package, but I don't want to deal with Synthesis compatibility issues between vendor tools. (I know that Microsemi has this weird thing where you can include SV files, but they need to end in .v for example).
For you long-time Verilog coders, what's the preferred approach for this?
I wish I could say SystemVerilog packages would be the ideal choice, but like you, I have found compatibility issues with synthesis and formal verification tools that claim to be SystemVerilog compliant.
In lieu of that, I have seen two approaches commonly used:
1) Global `define statements, sourced once (or gratuitously sourced by every file that uses them):
`define ASCII_a 8'h61
I do not recommend this approach because of the risk of name collision, i.e. different IP modules using the same parameter name to represent different values. In this case, the effective value of the parameter is dependent on compile order, which is not what you want in most cases.
2) Parameter include files, commonly with a different extension (e.g. .vh, .vinc) to prevent them from being accidentally compiled outside a `include statement. For example:
my_params.vh:
localparam ASCII_a = 8'h61;
...
my_module.v:
`include "my_params.vh"
Some designers wrap their params file with ifdef, which is a good practice to use in cases where the IP includes multiple files and those files in turn include the parameter file.
`ifndef _my_params_h
`define _my_params_h
localparam ASCII_a = 8'h61;
...
`endif
I have this SV code :
module m1 (input int a);
always begin #1; force a=a+1; end
endmodule
module m ();
int a;
m1 m1(a);
endmodule
Is this statement in above code valid force a=a+1;?
It might work in your simulator, however it is not recommended.
In the IEEE std 1800-2009 section 10.6 defines a force statement as a "procedural continuous assignment." There is an example in the LRM stating that if a value on the right hand side of the equation is changes, then it will force the new value to the right hand variable. In this case a=a+1 should technically cause an infinite loop but likely does not because of a scheduling rule.
In general force should be used sparingly and be used in a test bench and behavioral modeling. Functional expressions are allowed with force however circular dependance needs to be avoided. Best to assign a constant expression with force is possible.
Yes, I believe the behavior is well defined in this case. Module m1 will see the forced value but the enclosing module will not.
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.
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.