inserting stuck at..faults to memory

D

Daniel Prego

Guest
Hi to all
I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];

now i need to inject faults to this memory module
for example: i need ram[3][4][1] to be stuck permanently at zero
that mean rows 3 column 4 , second lsb to be 0
constantly, even if a write operation is on

how can i do it? i wrote some code but its not very sophisticated, and not usable if i need to inject, lets say, 20 faults like this

so, how can i inject a permanent fault into a specific bit inside an array?
 
On Tuesday, November 19, 2013 9:23:16 PM UTC+2, gabor wrote:
GaborSzakacs wrote:

Daniel Prego wrote:

Hi to all

I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];



now i need to inject faults to this memory module

for example: i need ram[3][4][1] to be stuck permanently at zero

that mean rows 3 column 4 , second lsb to be 0

constantly, even if a write operation is on



how can i do it? i wrote some code but its not very sophisticated,

and not usable if i need to inject, lets say, 20 faults like this



so, how can i inject a permanent fault into a specific bit inside an

array?



If you're doing this for simulation, I would think that the "force"

command should do what you want. This might depend on the simulator

you use, though. It's not really part of Verilog. The question is

whether the simulator's force command supports targets that are a

subset of a multidimensional array...





Sorry about that, I was thinking of the command line "force" rather

than the Verilog "force." If you want to add the force to the

test bench, then it would be a Verilog command (clearly not

synthesizable).



something like:



initial begin

#1000 force ram[3] [4] [1] = 1'b0;

end



--

Gabor

thanks, i need to write a code that identify the errors
for that i need to module a rem and inject errors, so i dont think i need to synthesize this for now. a few questions :
1) if i am not mistaken, force cannot be applied to a specific bit inside a vector?
not sure

2)also, regarding your suggestion, if i put the force at the initial block. what happens when i try to write to that cell later on? or the #(insert time longer than all simulation) takes care of that?

3) if youre example works (going to try it now), is there a nice way i can load or generate several injections like this' instead of 25 lines with different addresses?
 
On Tuesday, November 19, 2013 9:51:53 PM UTC+2, Daniel wrote:
On Tuesday, November 19, 2013 9:23:16 PM UTC+2, gabor wrote:

GaborSzakacs wrote:



Daniel Prego wrote:



Hi to all



I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];







now i need to inject faults to this memory module



for example: i need ram[3][4][1] to be stuck permanently at zero



that mean rows 3 column 4 , second lsb to be 0



constantly, even if a write operation is on







how can i do it? i wrote some code but its not very sophisticated,



and not usable if i need to inject, lets say, 20 faults like this







so, how can i inject a permanent fault into a specific bit inside an



array?







If you're doing this for simulation, I would think that the "force"



command should do what you want. This might depend on the simulator



you use, though. It's not really part of Verilog. The question is



whether the simulator's force command supports targets that are a



subset of a multidimensional array...











Sorry about that, I was thinking of the command line "force" rather



than the Verilog "force." If you want to add the force to the



test bench, then it would be a Verilog command (clearly not



synthesizable).







something like:







initial begin



#1000 force ram[3] [4] [1] = 1'b0;



end







--



Gabor



thanks, i need to write a code that identify the errors

for that i need to module a rem and inject errors, so i dont think i need to synthesize this for now. a few questions :

1) if i am not mistaken, force cannot be applied to a specific bit inside a vector?

not sure



2)also, regarding your suggestion, if i put the force at the initial block. what happens when i try to write to that cell later on? or the #(insert time longer than all simulation) takes care of that?



3) if youre example works (going to try it now), is there a nice way i can load or generate several injections like this' instead of 25 lines with different addresses?

well, can i use an initial inside my memory module? or only inside the testbanch?
if only inside the TB, its a bit problematic. as the RAM configuration sits as a register inside the memory module and cannot be seen from the TB
TB access: addresses,data,clk,en. thats it
 
Daniel Prego wrote:
Hi to all
I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];

now i need to inject faults to this memory module
for example: i need ram[3][4][1] to be stuck permanently at zero
that mean rows 3 column 4 , second lsb to be 0
constantly, even if a write operation is on

how can i do it? i wrote some code but its not very sophisticated, and not usable if i need to inject, lets say, 20 faults like this

so, how can i inject a permanent fault into a specific bit inside an array?

If you're doing this for simulation, I would think that the "force"
command should do what you want. This might depend on the simulator
you use, though. It's not really part of Verilog. The question is
whether the simulator's force command supports targets that are a
subset of a multidimensional array...

--
Gabor
 
GaborSzakacs wrote:
Daniel Prego wrote:
Hi to all
I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];

now i need to inject faults to this memory module
for example: i need ram[3][4][1] to be stuck permanently at zero
that mean rows 3 column 4 , second lsb to be 0
constantly, even if a write operation is on

how can i do it? i wrote some code but its not very sophisticated,
and not usable if i need to inject, lets say, 20 faults like this

so, how can i inject a permanent fault into a specific bit inside an
array?

If you're doing this for simulation, I would think that the "force"
command should do what you want. This might depend on the simulator
you use, though. It's not really part of Verilog. The question is
whether the simulator's force command supports targets that are a
subset of a multidimensional array...

Sorry about that, I was thinking of the command line "force" rather
than the Verilog "force." If you want to add the force to the
test bench, then it would be a Verilog command (clearly not
synthesizable).

something like:

initial begin
#1000 force ram[3] [4] [1] = 1'b0;
end

--
Gabor
 
Daniel wrote:
[snip]

well, can i use an initial inside my memory module? or only inside the testbanch?
if only inside the TB, its a bit problematic. as the RAM configuration sits as a register inside the memory module and cannot be seen from the TB
TB access: addresses,data,clk,en. thats it

Inside your synthesizable code you can place simulation-only
code if you use the synthesis translate_on/off pragmas:

// synthesis translate_off
initial begin
#1000 force ram[3] [4] [1] = 1'b0;
end
// synthesis translate_on

Some synthesizers will not complain even if you don't use the pragmas,
or you'll just get a warning that the force statement was ignored for
synthesis.

If you want to do this from the test bench, then you need to use the
hierarchical naming like:

// synthesis translate_off
initial begin
#1000 force uut.ram_instance.ram[3] [4] [1] = 1'b0;
end
// synthesis translate_on

Where in this case your synthesizable code is instantiated as "uut"
in the testbench and the RAM was one level down in a module instantiated
as "ram_instance."

Note that placing code for simulation inside your synthesizable code
will not work for post-synthesis timing simulation. That's because
the code is not translated during synthesis and thus doesn't end up
in the post synthesis simulation timing model. Also hierarchical
access from the test bench to the RAM bit gets tricky for post synthesis
translation because the name or path may change depending on synthesis
settings.

If you find that this works for individual bits (have you tried it yet?)
then I suppose you could make a memory-like structure in your test
bench that loads a list of bit locations and values from a file and
then use a loop to apply a force command for each entry in the file.

--
Gabor
 
On Tuesday, November 19, 2013 11:06:08 PM UTC+2, gabor wrote:
Daniel wrote:

[snip]





well, can i use an initial inside my memory module? or only inside the testbanch?

if only inside the TB, its a bit problematic. as the RAM configuration sits as a register inside the memory module and cannot be seen from the TB

TB access: addresses,data,clk,en. thats it



Inside your synthesizable code you can place simulation-only

code if you use the synthesis translate_on/off pragmas:



// synthesis translate_off

initial begin

#1000 force ram[3] [4] [1] = 1'b0;

end

// synthesis translate_on



Some synthesizers will not complain even if you don't use the pragmas,

or you'll just get a warning that the force statement was ignored for

synthesis.



If you want to do this from the test bench, then you need to use the

hierarchical naming like:



// synthesis translate_off

initial begin

#1000 force uut.ram_instance.ram[3] [4] [1] = 1'b0;

end

// synthesis translate_on



Where in this case your synthesizable code is instantiated as "uut"

in the testbench and the RAM was one level down in a module instantiated

as "ram_instance."



Note that placing code for simulation inside your synthesizable code

will not work for post-synthesis timing simulation. That's because

the code is not translated during synthesis and thus doesn't end up

in the post synthesis simulation timing model. Also hierarchical

access from the test bench to the RAM bit gets tricky for post synthesis

translation because the name or path may change depending on synthesis

settings.



If you find that this works for individual bits (have you tried it yet?)

then I suppose you could make a memory-like structure in your test

bench that loads a list of bit locations and values from a file and

then use a loop to apply a force command for each entry in the file.



--

Gabor

i tried this in my memory module and ran a simulation. didnt get any error on compile, but also cant see that the bit was really stuck as i wanted it to be
 
On Wednesday, November 20, 2013 7:24:57 PM UTC+2, Daniel wrote:
On Tuesday, November 19, 2013 11:06:08 PM UTC+2, gabor wrote:

Daniel wrote:



[snip]











well, can i use an initial inside my memory module? or only inside the testbanch?



if only inside the TB, its a bit problematic. as the RAM configuration sits as a register inside the memory module and cannot be seen from the TB



TB access: addresses,data,clk,en. thats it







Inside your synthesizable code you can place simulation-only



code if you use the synthesis translate_on/off pragmas:







// synthesis translate_off



initial begin



#1000 force ram[3] [4] [1] = 1'b0;



end



// synthesis translate_on







Some synthesizers will not complain even if you don't use the pragmas,



or you'll just get a warning that the force statement was ignored for



synthesis.







If you want to do this from the test bench, then you need to use the



hierarchical naming like:







// synthesis translate_off



initial begin



#1000 force uut.ram_instance.ram[3] [4] [1] = 1'b0;



end



// synthesis translate_on







Where in this case your synthesizable code is instantiated as "uut"



in the testbench and the RAM was one level down in a module instantiated



as "ram_instance."







Note that placing code for simulation inside your synthesizable code



will not work for post-synthesis timing simulation. That's because



the code is not translated during synthesis and thus doesn't end up



in the post synthesis simulation timing model. Also hierarchical



access from the test bench to the RAM bit gets tricky for post synthesis



translation because the name or path may change depending on synthesis



settings.







If you find that this works for individual bits (have you tried it yet?)



then I suppose you could make a memory-like structure in your test



bench that loads a list of bit locations and values from a file and



then use a loop to apply a force command for each entry in the file.







--



Gabor



i tried this in my memory module and ran a simulation. didnt get any error on compile, but also cant see that the bit was really stuck as i wanted it to be

Inserted it in the TB file and it worked great
so, if i want to make this "nice looking" or code writing apropriate, if i want to inject 20 faults like this? how can i do it beside writing 20+ lines of :
#1000 force uut.ram_instance.ram[3] [4] [1] = 1'b0;
 
On Wednesday, November 20, 2013 9:02:18 PM UTC+2, gabor wrote:
Daniel Prego wrote:

Hi to all

I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];



now i need to inject faults to this memory module

for example: i need ram[3][4][1] to be stuck permanently at zero

that mean rows 3 column 4 , second lsb to be 0

constantly, even if a write operation is on



how can i do it? i wrote some code but its not very sophisticated, and not usable if i need to inject, lets say, 20 faults like this



so, how can i inject a permanent fault into a specific bit inside an array?



This may be simulator dependent. I tried it in Xilinx ISIM, and it

refused to force any part of an array or vector giving this error:



Bit-select or part-select is not allowed in a force statement for

non-net ram



where "ram" was the name of the array as in your example.



However I was able to effect a similar behavior with this code:



always @ (ram[2][2]) ram[2][2][2] = 0; // 0 after any attempt to change



This is of course permanently stuck, not just after some particular

time, however it could use an if statement to limit the "force" to

a particular time period.



--

Gabor

thanks Gabor!
as i mentioned, it worked ok for me through the TB
now i want to do this using a file
so, i thought of doing it using 3 different text files, one for rows one for column and one for bit select

i am trying to figure out how to do it using %fgets and a for loop.
thought about dong it like this:
initial
begin
for (i=0; i<10; i+1) begin // not sure how to move through the lines in text file
row=%fgets( not sure of opcode here)
column=%fgets( not sure of opcode here)
bit_select==%fgets( not sure of opcode here)
#1000 force memory.ram[row][column][bit_select] = 1'b0;
end
end
 
Daniel Prego wrote:
Hi to all
I have a 2D array:reg [WordSize-1:0] ram[0:rows-1][0:cells-1];

now i need to inject faults to this memory module
for example: i need ram[3][4][1] to be stuck permanently at zero
that mean rows 3 column 4 , second lsb to be 0
constantly, even if a write operation is on

how can i do it? i wrote some code but its not very sophisticated, and not usable if i need to inject, lets say, 20 faults like this

so, how can i inject a permanent fault into a specific bit inside an array?

This may be simulator dependent. I tried it in Xilinx ISIM, and it
refused to force any part of an array or vector giving this error:

Bit-select or part-select is not allowed in a force statement for
non-net ram

where "ram" was the name of the array as in your example.

However I was able to effect a similar behavior with this code:

always @ (ram[2][2]) ram[2][2][2] = 0; // 0 after any attempt to change

This is of course permanently stuck, not just after some particular
time, however it could use an if statement to limit the "force" to
a particular time period.

--
Gabor
 
Daniel wrote:
thanks Gabor!
as i mentioned, it worked ok for me through the TB
now i want to do this using a file
so, i thought of doing it using 3 different text files, one for rows one for column and one for bit select

i am trying to figure out how to do it using %fgets and a for loop.
thought about dong it like this:
initial
begin
for (i=0; i<10; i+1) begin // not sure how to move through the lines in text file
row=%fgets( not sure of opcode here)
column=%fgets( not sure of opcode here)
bit_select==%fgets( not sure of opcode here)
#1000 force memory.ram[row][column][bit_select] = 1'b0;
end
end

This works for me (I know $readmemh, $readmemb better than the streaming
file operators, so I used arrays for the row, column, etc.)


reg [7:0] ram[0:3][0:7];
reg [7:0] rows [0:9];
reg [7:0] cols [0:9];
reg [7:0] bits [0:9];
reg vals [0:9];

integer k;
initial begin
$readmemh ("row.txt",rows);
$readmemh ("col.txt",cols);
$readmemh ("bit.txt",bits);
$readmemb ("val.txt",vals);
for (k = 0;k < 10;k = k + 1)
begin
$display ("Want to force ram [%d] [%d] [%d] to %d", rows[k],
cols[k], bits[k], vals[k]);
// force ram[rows[k]][cols[k]][bits[k]] = vals[k]; // Doesn't work in
ISIM
end
end


Text File contents (each column in a separate file)

row.txt col.txt bit.txt val.txt

00 01 00 0
02 01 01 1
03 02 02 1
01 02 03 0
00 05 04 1
03 07 05 0
02 04 06 1
02 06 07 1
01 00 00 0
03 03 01 1

Simulation printout:

Want to force ram [ 0] [ 1] [ 0] to 0
Want to force ram [ 2] [ 1] [ 1] to 1
Want to force ram [ 3] [ 2] [ 2] to 1
Want to force ram [ 1] [ 2] [ 3] to 0
Want to force ram [ 0] [ 5] [ 4] to 1
Want to force ram [ 3] [ 7] [ 5] to 0
Want to force ram [ 2] [ 4] [ 6] to 1
Want to force ram [ 2] [ 6] [ 7] to 1
Want to force ram [ 1] [ 0] [ 0] to 0
Want to force ram [ 3] [ 3] [ 1] to 1
 
On Wednesday, November 20, 2013 11:42:30 PM UTC+2, gabor wrote:
Daniel wrote:



thanks Gabor!

as i mentioned, it worked ok for me through the TB

now i want to do this using a file

so, i thought of doing it using 3 different text files, one for rows one for column and one for bit select



i am trying to figure out how to do it using %fgets and a for loop.

thought about dong it like this:

initial

begin

for (i=0; i<10; i+1) begin // not sure how to move through the lines in text file

row=%fgets( not sure of opcode here)

column=%fgets( not sure of opcode here)

bit_select==%fgets( not sure of opcode here)

#1000 force memory.ram[row][column][bit_select] = 1'b0;

end

end



This works for me (I know $readmemh, $readmemb better than the streaming

file operators, so I used arrays for the row, column, etc.)





reg [7:0] ram[0:3][0:7];

reg [7:0] rows [0:9];

reg [7:0] cols [0:9];

reg [7:0] bits [0:9];

reg vals [0:9];



integer k;

initial begin

$readmemh ("row.txt",rows);

$readmemh ("col.txt",cols);

$readmemh ("bit.txt",bits);

$readmemb ("val.txt",vals);

for (k = 0;k < 10;k = k + 1)

begin

$display ("Want to force ram [%d] [%d] [%d] to %d", rows[k],

cols[k], bits[k], vals[k]);

// force ram[rows[k]][cols[k]][bits[k]] = vals[k]; // Doesn't work in

ISIM

end

end





Text File contents (each column in a separate file)



row.txt col.txt bit.txt val.txt



00 01 00 0

02 01 01 1

03 02 02 1

01 02 03 0

00 05 04 1

03 07 05 0

02 04 06 1

02 06 07 1

01 00 00 0

03 03 01 1



Simulation printout:



Want to force ram [ 0] [ 1] [ 0] to 0

Want to force ram [ 2] [ 1] [ 1] to 1

Want to force ram [ 3] [ 2] [ 2] to 1

Want to force ram [ 1] [ 2] [ 3] to 0

Want to force ram [ 0] [ 5] [ 4] to 1

Want to force ram [ 3] [ 7] [ 5] to 0

Want to force ram [ 2] [ 4] [ 6] to 1

Want to force ram [ 2] [ 6] [ 7] to 1

Want to force ram [ 1] [ 0] [ 0] to 0

Want to force ram [ 3] [ 3] [ 1] to 1

thanks a lot!, ill give it now a try and see
 
On Wednesday, November 20, 2013 11:42:30 PM UTC+2, gabor wrote:
Daniel wrote:



thanks Gabor!

as i mentioned, it worked ok for me through the TB

now i want to do this using a file

so, i thought of doing it using 3 different text files, one for rows one for column and one for bit select



i am trying to figure out how to do it using %fgets and a for loop.

thought about dong it like this:

initial

begin

for (i=0; i<10; i+1) begin // not sure how to move through the lines in text file

row=%fgets( not sure of opcode here)

column=%fgets( not sure of opcode here)

bit_select==%fgets( not sure of opcode here)

#1000 force memory.ram[row][column][bit_select] = 1'b0;

end

end



This works for me (I know $readmemh, $readmemb better than the streaming

file operators, so I used arrays for the row, column, etc.)





reg [7:0] ram[0:3][0:7];

reg [7:0] rows [0:9];

reg [7:0] cols [0:9];

reg [7:0] bits [0:9];

reg vals [0:9];



integer k;

initial begin

$readmemh ("row.txt",rows);

$readmemh ("col.txt",cols);

$readmemh ("bit.txt",bits);

$readmemb ("val.txt",vals);

for (k = 0;k < 10;k = k + 1)

begin

$display ("Want to force ram [%d] [%d] [%d] to %d", rows[k],

cols[k], bits[k], vals[k]);

// force ram[rows[k]][cols[k]][bits[k]] = vals[k]; // Doesn't work in

ISIM

end

end





Text File contents (each column in a separate file)



row.txt col.txt bit.txt val.txt



00 01 00 0

02 01 01 1

03 02 02 1

01 02 03 0

00 05 04 1

03 07 05 0

02 04 06 1

02 06 07 1

01 00 00 0

03 03 01 1



Simulation printout:



Want to force ram [ 0] [ 1] [ 0] to 0

Want to force ram [ 2] [ 1] [ 1] to 1

Want to force ram [ 3] [ 2] [ 2] to 1

Want to force ram [ 1] [ 2] [ 3] to 0

Want to force ram [ 0] [ 5] [ 4] to 1

Want to force ram [ 3] [ 7] [ 5] to 0

Want to force ram [ 2] [ 4] [ 6] to 1

Want to force ram [ 2] [ 6] [ 7] to 1

Want to force ram [ 1] [ 0] [ 0] to 0

Want to force ram [ 3] [ 3] [ 1] to 1

ok 2 issues:
1) i get an error regarding the selection of the specific bit: "bit select or part bit select must be constant" , if i write : force ram[rows[k]][cols[k]][3] = vals[k]; i.e the bit is constant and not read from an array, i get through the compilation, any way around that?

2) i wrote #1000 force ram[rows[k]][cols[k]][bits[k]] = vals[k];
this command is inside a for loop. how is #1000 effected when in a for loop?
 
On Thursday, November 21, 2013 9:58:04 PM UTC+2, gabor wrote:
Daniel wrote:



ok 2 issues:

1) i get an error regarding the selection of the specific bit: "bit select or part bit select must be constant" , if i write : force ram[rows[k]][cols[k]][3] = vals[k]; i.e the bit is constant and not read from an array, i get through the compilation, any way around that?



2) i wrote #1000 force ram[rows[k]][cols[k]][bits[k]] = vals[k];

this command is inside a for loop. how is #1000 effected when in a for loop?



1) At some point, it would make sense to just add the 20 lines of code

instead of making a research project out of doing it in a loop. One

suggestion if you wanted to automate this is to write a simple C program

that takes formatted values from a file, and outputs them in the form

required for the force statements, writing the output to another file.

Or you could use a Perl script to convert the number list to force

statements. Then the testbench could just `include the generated file.



2) Each #1000 will add another 1,000 time units as written. If you

wanted the bits to be permanently stuck from time zero, then just leave

the #1000 out. If you wanted to model bits becoming stuck after some

time period, then you can adjust this as necessary. If you want each

force statement to take effect at a particular absolute time, rather

than an interval since the previous force statement, you should probably

put each one in its own initial statement like:



initial #1000 force ram[<x>][<y>][<z>] = <n>;



where <x> <y> etc. are filled in by the external C program or Perl

script.



--

Gabor

:) i do have a file with 20 lines, but in the future i will have to inject other kinds of errors, and this way is so much cleaner

i tried diffrent ways, i cant seem to shake this error off, you think there is no way to do a bit select in this kind of force? any manipulation...?

by the way, thanks for all the help and explanations!
 
Daniel wrote:
ok 2 issues:
1) i get an error regarding the selection of the specific bit: "bit select or part bit select must be constant" , if i write : force ram[rows[k]][cols[k]][3] = vals[k]; i.e the bit is constant and not read from an array, i get through the compilation, any way around that?

2) i wrote #1000 force ram[rows[k]][cols[k]][bits[k]] = vals[k];
this command is inside a for loop. how is #1000 effected when in a for loop?

1) At some point, it would make sense to just add the 20 lines of code
instead of making a research project out of doing it in a loop. One
suggestion if you wanted to automate this is to write a simple C program
that takes formatted values from a file, and outputs them in the form
required for the force statements, writing the output to another file.
Or you could use a Perl script to convert the number list to force
statements. Then the testbench could just `include the generated file.

2) Each #1000 will add another 1,000 time units as written. If you
wanted the bits to be permanently stuck from time zero, then just leave
the #1000 out. If you wanted to model bits becoming stuck after some
time period, then you can adjust this as necessary. If you want each
force statement to take effect at a particular absolute time, rather
than an interval since the previous force statement, you should probably
put each one in its own initial statement like:

initial #1000 force ram[<x>][<y>][<z>] = <n>;

where <x> <y> etc. are filled in by the external C program or Perl
script.

--
Gabor
 
Daniel wrote:
:) i do have a file with 20 lines, but in the future i will have to inject other kinds of errors, and this way is so much cleaner

i tried diffrent ways, i cant seem to shake this error off, you think there is no way to do a bit select in this kind of force? any manipulation...?

by the way, thanks for all the help and explanations!

The simulator I use won't do a force on a part select at all, so you're
already doing more than I can. Since your force statement can only
handle constants in the part selects, then I don't see how you could
easily read them from a file other than the `include method I mentioned.

I guess the question is how you want these to be applied. If you don't
need the faults to happen after a delay (i.e. bits are stuck permanently
from time 0), then you could use the other method I mentioned, perhaps
with a generate loop to add an always block per fault like:

generate
genvar k;
for (k = 0;k < 10;k = k + 1) begin: Fault
always @(ram[rows[k]][cols[k]][bits[k]])
ram[rows[k]][cols[k]][bits[k]] = vals[k];
end
endgenerate

Or if you need to apply the stuck bits only under some condition,
you could have a vector with a bit for each fault like:

reg [9:0] apply_fault;

generate
genvar k;
for (k = 0;k < 10;k = k + 1) begin: Fault
always @(ram[rows[k]][cols[k]][bits[k]])
if (apply_fault[k]) ram[rows[k]][cols[k]][bits[k]] = vals[k];
end
endgenerate

--
Gabor
 
GaborSzakacs wrote:
Daniel wrote:

:) i do have a file with 20 lines, but in the future i will have to
inject other kinds of errors, and this way is so much cleaner

i tried diffrent ways, i cant seem to shake this error off, you think
there is no way to do a bit select in this kind of force? any
manipulation...?

by the way, thanks for all the help and explanations!

The simulator I use won't do a force on a part select at all, so you're
already doing more than I can. Since your force statement can only
handle constants in the part selects, then I don't see how you could
easily read them from a file other than the `include method I mentioned.

I guess the question is how you want these to be applied. If you don't
need the faults to happen after a delay (i.e. bits are stuck permanently
from time 0), then you could use the other method I mentioned, perhaps
with a generate loop to add an always block per fault like:

generate
genvar k;
for (k = 0;k < 10;k = k + 1) begin: Fault
always @(ram[rows[k]][cols[k]][bits[k]])
ram[rows[k]][cols[k]][bits[k]] = vals[k];
end
endgenerate

Or if you need to apply the stuck bits only under some condition,
you could have a vector with a bit for each fault like:

reg [9:0] apply_fault;

generate
genvar k;
for (k = 0;k < 10;k = k + 1) begin: Fault
always @(ram[rows[k]][cols[k]][bits[k]])
if (apply_fault[k]) ram[rows[k]][cols[k]][bits[k]] = vals[k];
end
endgenerate

A quick response to my own post here...

The above code works for me. However there is a small difference in
simulation between the always blocks and the force statements. In
the case of force, any attempt to write the forced bit will not
happen. In the case of the always blocks, the writes happen and
then the bit gets immediately (zero simulation time) set to the
overriding value by the always block. So you'll see zero-width
glitches on the signal on a waveform. Also any code that uses
the bit as a trigger (like these always blocks) will get triggered
on that same edge, and you could have race conditions. However
this would be very unusual for a bit in a memory array. Any
well behaved code that doesn't try to use the memory bit at
the exact time it is being written should never see the write
happen on the "forced" bits.

--
Gabor
 
On Friday, November 22, 2013 1:03:02 AM UTC+2, gabor wrote:
GaborSzakacs wrote:

Daniel wrote:



:) i do have a file with 20 lines, but in the future i will have to

inject other kinds of errors, and this way is so much cleaner



i tried diffrent ways, i cant seem to shake this error off, you think

there is no way to do a bit select in this kind of force? any

manipulation...?



by the way, thanks for all the help and explanations!



The simulator I use won't do a force on a part select at all, so you're

already doing more than I can. Since your force statement can only

handle constants in the part selects, then I don't see how you could

easily read them from a file other than the `include method I mentioned.



I guess the question is how you want these to be applied. If you don't

need the faults to happen after a delay (i.e. bits are stuck permanently

from time 0), then you could use the other method I mentioned, perhaps

with a generate loop to add an always block per fault like:



generate

genvar k;

for (k = 0;k < 10;k = k + 1) begin: Fault

always @(ram[rows[k]][cols[k]][bits[k]])

ram[rows[k]][cols[k]][bits[k]] = vals[k];

end

endgenerate



Or if you need to apply the stuck bits only under some condition,

you could have a vector with a bit for each fault like:



reg [9:0] apply_fault;



generate

genvar k;

for (k = 0;k < 10;k = k + 1) begin: Fault

always @(ram[rows[k]][cols[k]][bits[k]])

if (apply_fault[k]) ram[rows[k]][cols[k]][bits[k]] = vals[k];

end

endgenerate





A quick response to my own post here...



The above code works for me. However there is a small difference in

simulation between the always blocks and the force statements. In

the case of force, any attempt to write the forced bit will not

happen. In the case of the always blocks, the writes happen and

then the bit gets immediately (zero simulation time) set to the

overriding value by the always block. So you'll see zero-width

glitches on the signal on a waveform. Also any code that uses

the bit as a trigger (like these always blocks) will get triggered

on that same edge, and you could have race conditions. However

this would be very unusual for a bit in a memory array. Any

well behaved code that doesn't try to use the memory bit at

the exact time it is being written should never see the write

happen on the "forced" bits.



--

Gabor

ok, for now i decided to go with a force command inside an initial block which is inside my memory module.
I read Initial should only be on a testbanch, but since my memory module is not ment to be synthesized, i thought this should be ok.

i prefer the force instead of a writing at zero time aproach
 
In article <l6oal8$76b$1@dont-email.me>,
GaborSzakacs <gabor@alacron.com> wrote:
Daniel wrote:

ok, for now i decided to go with a force command inside an initial block which is inside my memory module.
I read Initial should only be on a testbanch, but since my memory module is not ment to be synthesized, i thought this should be ok.

initial blocks can be used in synthesizable code, but the support
varies from synthesizer to synthesizer. For Xilinx's XST for
example, it is perfectly OK to use an initial block to initialize
a ROM like:

reg [7:0] my_rom [0:1023];

initial begin
$readmemh ("my_rom_data.txt", my_rom);
end

XST also allows initial blocks for simple regs, and also
can handle initial values in the declaration like:

reg foo = 0;

reg bar;

initial begin
bar = 1;
end

There are some restrictions. For one, the initial block must be in the
same module as the reg declaration. And the fact that you can do this
is due to the underlying hardware that gets initialized by the device
bitstream during configuration.


i prefer the force instead of a writing at zero time aproach



As I said, the force is a cleaner approach. On the other hand
it won't do what you originally wanted as far as reading in
the bit locations from a file. So for now you see this as
a trade-off. There may be other ways to deal with this, and
I was hoping one of the SystemVerilog gurus would chime in on
this thread. I'm still using Verilog 2001, because that's all my
tools support.

Not having followed the entire thread - is the main problem
the variable part select in the force?

You can get around that by sticking the force inside a generate,
and the having the qualification for the force outside the force
itself. i.e. changing the variable in the part select to a genvar instead.

something like:

genvar row, column; // Maybe "bit" too?
generate
for( all rows...)
begin : gen_rows
for( all columns )
begin : gen_columns
initial
if( some_qual[ row ][ column ] ) // Maybe add timing controls too...
force mem[ row ][ column ][ bit ] = 1;
end
end
endgenerate

This might barf in the simulator though if the array size get's big. It's
effectively a large number of initial blocks. Don't know at what sizes
the simulator would start to barf...

--Mark
 
Daniel wrote:
ok, for now i decided to go with a force command inside an initial block which is inside my memory module.
I read Initial should only be on a testbanch, but since my memory module is not ment to be synthesized, i thought this should be ok.

initial blocks can be used in synthesizable code, but the support
varies from synthesizer to synthesizer. For Xilinx's XST for
example, it is perfectly OK to use an initial block to initialize
a ROM like:

reg [7:0] my_rom [0:1023];

initial begin
$readmemh ("my_rom_data.txt", my_rom);
end

XST also allows initial blocks for simple regs, and also
can handle initial values in the declaration like:

reg foo = 0;

reg bar;

initial begin
bar = 1;
end

There are some restrictions. For one, the initial block must be in the
same module as the reg declaration. And the fact that you can do this
is due to the underlying hardware that gets initialized by the device
bitstream during configuration.

i prefer the force instead of a writing at zero time aproach

As I said, the force is a cleaner approach. On the other hand
it won't do what you originally wanted as far as reading in
the bit locations from a file. So for now you see this as
a trade-off. There may be other ways to deal with this, and
I was hoping one of the SystemVerilog gurus would chime in on
this thread. I'm still using Verilog 2001, because that's all my
tools support.

--
Gabor
 

Welcome to EDABoard.com

Sponsor

Back
Top