How can I use the force with array in verilog? - verilog

I'd like to force some bunch of signals by derived multiple instances in verilog as below.
integer ii;
initial begin
for (ii=0; ii<19; ii=ii+1) begin
force sydnney.top.vx1.mpg.jpg[ii].trig.be[3] = 1'b1;
end
end
But, I've got the below error :
Illegal operand for constant expression [4(IEEE)].
Is that impossible way to using like that?
update
I've got some error when I use as below,
generate
wire val;
genvar xidx;
for(val=0; val<3; val=val+1) begin : force_be3y_loop
#10
for(xidx=0; xidx<3; xidx=xidx+1) begin : force_be3x_loop
initial force top.comp.img.tc[xidx].t1c.b2tc = val;
initial force top.comp.img.tc[xidx].t1c.b2tc[23] = val;
initial force top.comp.img.tc[xidx].t1c.b2tc[22] = val;
initial force top.comp.img.tc[xidx].t1c.b2tc[21] = val;
initial force top.comp.img.tc[xidx].t1c.b2tc[20] = val;
end
end
endgenerate
error message :
Expecting the keyword 'end' [12.1.3(IEEE 2001)].
An 'endgenerate' is expected [12.1.3(IEEE 2001)].
expecting the keyword 'endmodule' [12.1(IEEE)].
An 'endgenerate' is expected [12.1.3(IEEE 2001)].
Do I make something wrong?
update2
the original concept of mine is the below,
integer ii;
initial begin
for (bb=0; bb<3; bb=bb+1) begin
#10
for (ii=0; ii<19; ii=ii+1) begin
force sydnney.top.vx1.mpg.jpg[ii].trig.be[3] = bb;
...
end
end
but that is not work with
Illegal operand for constant expression [4(IEEE)] error message.
So I'm looking for solution.

The module portion of a hierarchical references must be constant. You cannot loop through the indexes of arrayed module instances or generate-for-loops at simulation time. You can loop through them durring the elaboration phase of compilation with a generate-for-loops.
generate
genvar gidx;
for(gidx=0; gidx<19; gidx=gidx+1) begin : force_be3_loop
initial force sydnney.top.vx1.mpg.jpg[gidx].trig.be[3] = 1'b1;
end
endgenerate

Related

Getting an error calling a task in verilog testbench

I've following tasks with different input vectors (that part is not written for simplicity) in my Verilog testbench
task input_set_1;
begin
end
endtask
task input_set_2;
begin
end
endtask
task input_set_3;
begin
end
endtask
task input_set_4;
begin
end
endtask
I'm trying to call only one of them during the testbench simulation using the below task
task input_calling;
integer i;
begin
i = $urandom_range(1, 4);
input_set_i;
end
endtask
initial begin
#3;
input_calling;
end
I'm expecting with each test run, any of the input_set_1, or input_set_2 or input_set_3 or input_set_4 will be called based on the random number i=1 to 4, however, I'm getting an error saying input_set_i is not defined. I suspect some string to int mismatch is preventing I to take randomized value in the input _set_i task.
You are trying to do something which is impossible in verilog (as well as in any non-scripting language). Name of the task is a compile-time element which must be known to the compiler at compilation time. i is a run-time, dynamic element. You cannot use run-time objects to modify compile-time objects.
So, your best bet is to use dynamic language features to make your program work, e.g. if statements. Here is an example:
module top;
task a;
$display("a");
endtask
task b;
$display("b");
endtask
initial begin
for (int k = 0; k < 4; k++) begin
automatic int i = $urandom_range(2,1);
if (i == 1)
a;
else if (i == 2)
b;
end
end
endmodule

Create a int parameter from a loop variable

I am trying to get a code similar to this to work:
module testModule #( parameter LEN = 4,
parameter logic [0:0] OPTION = 1'b0 )
(
input Clk,
input [LEN-1:0] DataIn,
input [LEN-1:0] Condition,
output [LEN-1:0] DataOut_1,
output [LEN-1:0] DataOut_2
);
// CODE 1
always_ff #(posedge Clk) begin
for (int i = 0; i < LEN; i++) begin
if (OPTION == 1'b0) begin
if (Condition[0]) begin
DataOut_1[i] <= DataIn[i];
end else begin
DataOut_1[i] <= 1'b0;
end
end else begin
if (Condition[i]) begin
DataOut_1[i] <= DataIn[i];
end else begin
DataOut_1[i] <= 1'b0;
end
end
end
end
// CODE 2
always_ff #(posedge Clk) begin
for (int i = 0; i < LEN; i++) begin
int select = (OPTION == 1'b0) ? 0 : i;
if (Condition[select]) begin
DataOut_2[i] <= DataIn[i];
end else begin
DataOut_2[i] <= 1'b0;
end
end
end
endmodule
OPTION can be either 0 of 1.
I would like CODE 1 and 2 to do the same thing, and I am trying to simplify CODE 1.
DataOut_1 and DataOut_2 return the same value, but I get the following errors in CODE 2 in line
int select = (OPTION == 1'b0) ? 0 : i;
Local static variable with initializer requires 'static' keyword
automatic variable illegal in static variable initializer
And I am not sure if there is a way to do it
This code is illegal because you are not allowed to declare an implicitly static variable select with an initialization expression.
The reason for this restriction is exactly for the mistake you have made thinking that select will get initialized each time through the loop. Variables with static lifetimes only get initialized once at time zero, whereas variables with automatic lifetimes get initialized each time they enter the procedural block they are declared in.
Verilog declarations inside procedural block are implicitly static (exceptions are variables i declared as part of a for loop, and variables declared inside class methods, which are automatic.
There are a number of ways to fix this.
Explictly declare select with an automatic lifetime so that it gets initialized each iteration of the for loop.
Separate the declaration and initialization into a declaration and assignment statements. The assigment statement executes each iteration of the loop
Get rid of the variable and embed it onto the other expressions. That is essentially what code 1 and another answers does.
You can simplify CODE 1 by using a ternary and bitwise operator instead of the for loop:
module testModule #( parameter LEN = 4,
parameter logic [0:0] OPTION = 1'b0 )
(
input Clk,
input [LEN-1:0] DataIn,
input [LEN-1:0] Condition,
output reg [LEN-1:0] DataOut_1
);
always_ff #(posedge Clk) begin
if (OPTION == 1'b0) begin
DataOut_1 <= (Condition[0]) ? DataIn : '0;
end else begin
DataOut_1 <= DataIn & Condition;
end
end
endmodule

Verilog error: not a valid l-value

I'm trying to test if a wire(s) is on or not to signify if there is an error/overflow in my alu code. Given this code:
output reg[3:0]x; // line 149
output wire error;
output wire overflow;
always #* begin
if(error || overflow) begin
assign x = 4'b1111; // line 155
assign error = ~error;
assign overflow = ~overflow;
end else begin
assign x = opcode;
end
end
I get following error messages:
uut is my instantiation unit in my testbench called main
The code in the example has several issues.
1) you tried to use 'procedural assignments' which is an advanced verilog topic. In other words assign statement inside of an always block. This is not synthesizable, can only be used on reg types, and is there in verilog for very special cases. Do not use it.
You error messages coming from the fact that error and overflow are declared as wire.
2) you are trying to assign inverted version of a value to itself in a non-clocked logic. It will not behave the way you expect. Depending on usage it can either not toggle or will cause an infinite zero-delay loop, or in your case it could just generate a glitch.
So, potentially, your code should look something like the following:
input wire clk; // << you need clock
output reg[3:0]x; // line 149
output wire error;
output wire overflow;
reg error_reg, overflow_reg;
always #(posedge clk) begin
if(error || overflow) begin
x <= 4'b1111; // line 155
error_reg <= ~error;
overflow_reg <= ~overflow;
end else begin
x <= opcode;
end
assign error = error_reg;
assign overflow = overflow_reg;
end
Your using the assign incorrectly. That can be used outside of a always process, but not inside of one.
Also, the type wire, is required for an assign
wire [3:0] x;
assign x = 4'b1111;
Inside the always process, remove the assign statement and just say
reg [3:0] x; // Note that this is assigned as a reg now
always #* begin
if(blah) begin
x = 4'b1111;
end else begin
x = opcode;
end
end

Module Reference Error

I am attempting to initialize my memory to zeros so that later I can initialize my memory with a file. My memory is composed of sram blocks, each of which is 32-lines and 32-bits per line. The sram32x32 have a member in the module called reg [31:0] mem [31:0]. Each bank contains some blocksPerBank amount of these 32x32 blocks. There are sramBanks=8 banks right now.
Consecutive memory addresses interleave through each bank. After going through each bank, it goes to the next line. After going through all of the lines, it goes to the next block. After that, it rolls back around (this can be seen in the nested for-loop ordering in the initial block). Here is how I instantiate and initialize my memory. I think this should be sufficient information, but let me know if more is necessary.
generate
for(i=0; i<sramBanks; i=i+1) begin : bank
sram32x32$ block [blocksPerBank-1:0]
(obtag[tagLineMSB:tagLineLSB],
cdb[i*32 +: 32], 1'b0,
FSM_memWR, FSM_ceEnAdj
);
end
integer b, l, k;
initial begin
for(b=0; b<blocksPerBank; b=b+1) begin : bpb
for(l=0; l<32; l=l+1) begin : ln
for(k=0; k<sramBanks; k=k+1) begin : sbnk
bank[k].block[b].mem[l] = 32'b0;
end
end
end
end
endgenerate
But the error I get is:
Error-[XMRE] Cross-module reference resolution error
MainMemory.v, 149
Error found while trying to resolve cross-module reference.
token 'bank'. Originating module 'MainMemory'.
Source info: bank[k].block[b].mem[l] = 32'b0;
How do I reference the modules from the generate loop while in my initial statements?
The index of an arrayed module instance needs to constant. Therefore, b and k need to be genvar.
genvar b, k;
generate
for(b=0; b<blocksPerBank; b=b+1) begin : bpb
for(k=0; k<sramBanks; k=k+1) begin : sbnk
integer l;
initial begin
for(l=0; l<32; l=l+1) begin : ln
bank[k].block[b].mem[l] = 32'b0;
end
end
end
end
endgenerate
Note that integer l is defined inside the for-loop. Each look creates a l visable to the local scope. This prevents clobbering when the generated b*k initial blocks execute in parallel.

Unknown verilog error 'expecting "endmodule"'

In verilog I have an error that I can't get past. this is the first bit of the code then the last bit
module Decoder(op,funct,aluop,mwr,mreg,mrd,alusrc,regdst,regwr,btype);
input[5:0] op,funct;
output[2:0] aluop;
output[1:0] btype;
output mwr,mreg,mrd,alusrc,regdst,regwr;
wire aluop,mwr,mreg,mrd,alusrc,regdst,regwr,btype;
case(op)
6'b000000: begin
case(funct)
6'b001010:
assign aluop = 3'b010;
6'b001100:
assign aluop = 3'b111;
6'b010001:
assign aluop = 3'b011;
default:
assign aluop = 3'b000;
endcase
assign btype = 2'b00;
assign mwr = 1'b0;
assign mreg = 1'b0;
assign mrd = 1'b0;
assign alusrc = 1'b0;
assign regdst = 1'b1;
assign regwr = 1'b1;
end
...
default: begin
assign aluop = 3'b000;
assign mwr = 0;
assign mreg = 0;
assign mrd = 0;
assign alusrc = 0;
assign btype = 2'b00;
assign regdst = 0;
assign regwr = 0;
end
endcase
endmodule
it keeps giving me the following errors
Error (10170): Verilog HDL syntax error at Decoder.v(7) near text "case"; expecting "endmodule"
Error (10170): Verilog HDL syntax error at Decoder.v(14) near text "6"; expecting "endmodule"
It also does this at every end statement and default and endcase
I have no idea why it's doing this, I'm fairly new to verilog.
thanks in advance
I believe you're only allowed to use a case statement or if/else inside of an always block. I'm not sure why your error message doesn't say something a little more helpful, but that is likely to be the problem.
Try rewriting your code like the following:
//change wire types to reg type
always #*
begin
case (op)
6'b000000: begin
aluop = 3'b000
end
...
endcase
end
This is a guess, but the compiler is complaining because it is likely expecting IEEE 1364-2001 verilog and your code isn't valid for this version of the language. In any case, Tim's code is probably the functionality you're looking for.
As to why it isn't valid, Verilog contains essentially two 'contexts' inside every module declaration. Anything that appears directly in the module is a module item. These include reg/wire declarations, assign statements, always statements, generate constructs and module instances.
module mod;
reg reg1; //Module item
wire wire1; //Module item
assign wire1 = 0; //Module item
always reg1 = 0; //Module item
parameter con1 = 0; //Module item
//Instances a different module based on con1
case(con1) //Module item
0:mod2 inst1(reg1);
1:mod3 inst1(reg1);
2:mod4 inst1(reg1);
endcase
endmodule
Second, there are procedural contexts in which there can be procedural statements. This is any code inside a task declaration, function declaration, always block, initial block and a few other areas.
module mod2;
reg a;
always
begin
a = 0; //Procedural statement
end
initial
a = 0; //Procedural statement
function func1(input arg1);
case (arg1) //Procedural statement
0:func1 = 0;
default:func1 = 9;
endcase
endfunction
endmodule
Since 2001, Verilog contains two types of case statements, procedural case statements and generate case statements. Procedural case statements work just like they do in procedural languages but must appear in a procedural context. Generate case statements are evaluated statically before simulation starts and may only appear in a module declaration context as a module item. Note that the second context requires the case expression to be constant.
In the latest version of verilog, 1364-2005, a generate case may appear directly in the module scope however in the 2001 version of the language any generate item must be surrounded with generate..endgenerate keywords. If your compiler is expecting IEEE 1364-2001 then the error message you see makes sense.

Resources