I'm trying to compile following code in Modelsim:
module ctrl_mem
#(
parameter BYTE_SIZE = 256
)
(
input [ADDR_W - 1 : 0] i_addr,
...
...
);
localparam ADDR_W = $clog2(BYTE_SIZE);
Modelsim writes that ADDR_W is unknown.
Similar question was discussed here but Modelsim behavior is not covered there and unfortunately I cannot comment it to ask this question.
Is it possible to fix this issue without code modification?
I use Modelsim Altera Starter Edition 10.3c
Your code is not legal. The Verilog/SystemVerilog LRM requires that simple identifiers (those not followed by a '.' or '(') be declared prior to being referenced. The correct way to write this module is
module ctrl_mem
#(
parameter BYTE_SIZE = 256, localparam ADDR_W = $clog2(BYTE_SIZE)
)
(
input [ADDR_W - 1 : 0] i_addr,
...
...
);
As you discovered, the newer style parameter declaration ("module_parameter_port_list" in the LRM syntax definition) only supports parameters and not localparams, and as has been mentioned it needs to be declared before it's used, so this leaves you with the option of either using the old-style syntax, or using parameter.
Whenever I have an I/O width dependent on a constant derived from another parameter that I want to be able to override, I always used parameter for this reason. They way I think of it, a case like this is not necessarily a good candidate for 'localparam', as it's not truly/completely "local" -- you are using it to specify the width of an interface signal thus exposed outside the module. At least that's how I explain the situation to myself.
Related
Is their a possibility to access a node in the code using a define macro via string parameters
e.g.
module design
(
input logic signal_in_1_temp,
input logic signal_in_2_temp
);
endmodule
module tb_top;
parameter string signal_names[0:1] = {"in_1","in_2"};
i_design design(.signal_in_1_temp(0),.signal_in_2_temp(0));
`define IN_SIG(IN_NAME,VAL)\
force i_design.signal_\``IN_NAME\``_temp = VAL;
initial begin
\`IN_SIG(signal_name[0],1);
\`IN_SIG(signal_name[1],0);
end
endmodule
In the above the two inputs of the design would need to be accessed via a parameter list and then a macro ...
Compiling the above gives error .... I would want to know if we can access the nodes status or drive them based on the above means ..
The idea is to have a dynamic parameter list given and then to know the status of that list or drive them based on need....
Any suggestions ... please
No, you cannot use string names within the language to build identifier names. Verilog does have a C interface (called VPI) that allows you to access signals by signal name, but that comes at a performance cost which means the signal cannot have certain optimizations and must remain intact.
SystemVerilog has a bind construct that allows you to attach functionality to signals deep inside your design. I wrote a DVCon paper about it.
No, you cannot do it with strings, but you can do it with regular macro arguments.
here is a working example:
`define A(B) \
$display(sig_``B``_sig);
module top;
logic sig_x_sig, sig_hello_sig;
initial begin
`A(x)
`A(hello)
end
endmodule
do not use \ as in your code and do not use empty lines in macro definitions.
I would like to define a parameter MYTYPE using text macro, whose value is passed over by text macro, eg
`define MY_FEATURE(nam,def) parameter nam=def;
and then
`MY_FEATURE(MYTYPE, 1)
But the value is mixed by those who are defined by other text macros, eg
`MY_FEATURE(NEWTYPE, 2)
`MY_FEATURE(MYTYPE, NEWTYPE)
The latter case will not work unless the def in define MY_FEATURE is added with the directive dot.
I need to distinguish this two different cases and automatically expand the macro - only if it is defined, so I came up with this code but I got error.
`define yea 1
`define nop 0
`define MY_FEATURE(nam,def) `ifdef def parameter nam=`def; `else parameter nam=2; `endif
module test;
`MY_FEATURE(MYTYPE,yea)
initial begin
$display("%d",MYTYPE);
end
endmodule
The above code works and gives a 1 as output. However if I write
`MY_FEATURE(MYTYPE,10)
since for other cases I need to assign an actual number to the parameter, then I will get
`ifdef without a macro name - ignored.
My desired result is MYTYPE is assigned as 10.
Is there any way to achieve this? Thanks.
Code can be found here
http://www.edaplayground.com/x/6Jha
I think you are overthinking it. `define creates an directive expression. When when you pass a directive as parameter to another directive you can pass it as `yea.
Here is an example:
`define yea 1
`define nop 0
`define MY_FEATURE(nam,def) parameter nam=def;
module test;
`MY_FEATURE(MYTYPE,`yea)
`MY_FEATURE(MYTYPE2,10)
`MY_FEATURE(MYTYPE3,MYTYPE+MYTYPE2)
initial begin
$display("%d %d %d",MYTYPE, MYTYPE2, MYTYPE3); // displays: 1 10 11
end
endmodule
http://www.edaplayground.com/x/5Pgf
Verilog-AMS (superset of Verilog-A) is a language of its own, derived from Verilog (IEEE Std 1364); according the manual. This means your MY_FEATURE never creates new directives; it creates parameters. Directives and parameters are both treated as constants in simulation but act differently in compile. The `define/parameters relation in Verilog (and Verilog derived languages) is equivalent to C's #define/const relation. Unlike C, to access the value of a `define requires a ` prefix.
Neither directives or parameters cannot start with a numeric value. The first character must be an alpha or underscore (aka [a-zA-Z_]). There for 10 can never be a directives and even trying to use it is illegal syntax. There is noway for the compile to recover from an illegal syntax directive name. This is way I suggested passing `yea instead of yea.
If someone build you a nice model, then it should come with equally nice documentation or some way of getting support.
I have got a piece of verilog code, which i am trying to synthesize. There is a line in there,
MUX2B_XB gas34 ( notPropSig, OECin, generate, notCoutSig );
instantiating a module. Where, the module implements a simple Boolean logic. But, synthesizer was giving an error:
Syntax error near "generate".
I can not understand the use of 'generate' statement in this context here while instantiation and also how to go about resolving the error without affecting the intended functionality.
You seem to be trying to use generate as a variable name and connect that variable to the 3rd port of your module. However, generate is a Verilog keyword and cannot be used as a variable name (another example would be trying to use always as a variable like logic [1:0] always;, you cannot use such keywords as variable names). You simply need to change the name of that variable:
logic gen; // Or whatever the type and width of this line should be
...
MUX2B_XB gas34(notPropSig, OECin, gen, notCoutSig);
If you actually what to use the generate construct for something, you'll need to provide more context so we can help.
I am using Xilinx ISim (ISE)
I have the following assign statement:
assign dwToAlign = {first_aligned >> 3}[7:0] - {i_address >> 3}[7:0];
When I try to do a behavioral simulation, it throws an internal compiler error. If I comment this specific line, it compiles properly. I am certain that the exact same code compiled yesterday (I commited it to my git repo).
If I synthesize and then do a post-pnr simulation, the code synthesizes and simulates properly.
Is this valid verilog?
EDIT: Code on EDAPlayground http://www.edaplayground.com/x/3wW
No it is not valid. Your example uses {} concatenation operators I think you should just be using brackets ().
If you need to use part selects then declare the shifts first. It is all combinatorial logic and will result in the same hardware.
assign temp1 = (first_aligned >> 3);
assign temp2 = (i_address >> 3);
assign dwToAlign = temp1[7:0] - temp2[7:0];
It is worth noting that signed arithmetic will be ignored if part-selects are used, even if the full range is specified.
ie if temp1 and temp2 are declared as wire signed [7:0] temp1 when you access temp1[7:0] the signed property is ignored. If it is required you can force it using $signed( temp1[7:0] ). Signed shifts (>>>) be used as with signed data types if you need to preserve the sign info.
The OP has also left in the comments that for their case they could also just use:
assign dwToAlign = first_aligned[10:3] - i_address[10:3];
Verilog system function $value$plusargs invoked as task.Return value
will be ignored
I get the above error during a compile of my verilog test which is basically trying to read and write values over i2c. I wasn't getting this error earlier.I don't know what changed which is giving me this error.Also this error points to another file called tb.v which contains the testbench infrastructure. The line it points to in tb.v just says `ifdef TEST
That error message means you are calling a function which returns a value without doing anything with the return value. As Brian noted, $value$plusargs returns a value, so you need to either assign it to something, or in SystemVerilog you can ignore it with use of void'(..).
// For Verilog
reg result;
result = $value$plusargs(...);
-
// For SystemVerilog
void'($value$plusargs(...));
You may also care to know if the plusarg matched or not. In that case, it's best coded in this way:
if ($value$plusargs(...)) begin
// do something
end
One explanation as to why you started seeing this all of a sudden, would be if you changed something so the source is being compiled as SystemVerilog instead of Verilog. It's tool dependent, but a given compiler may complain about this in SystemVerilog but not in Verilog.
$value$pluargs is a function which returns a value. This value is whether or not the call succeeded or not. Not the value of the +arg you're attempting to get. I've seen some simulators get upset if you don't assign the result to something.
Basically this will fix it:
reg dummy;
dummy = $value$plusargs(...)