Jump to content

race condition


Recommended Posts

Hi I need some suggestions to avoid race conditions

I have two tasks : write and read

automatic task write_reg(regname,value);

.

.

.

endtask

automatic task read_reg(regname,value);

.

.

.

endtask

These tasks can be called simultaneously, so i have used a semaphore to prevent two writes happening at the same time or two reads accessing the same task , the modification being :

automatic task write_reg(regname,value);

wr_key.get(1);

.

.

.

wr_key.put(1);

endtask

automatic task read_reg(regname,value);

rd_key.get(1);

.

.

.

rd_key.put(1);

endtask

This works fine. Now when the problem is to avoid write and read happening to the same register, i am facing different sorts of race conditions when i implement different logic.

Method 1:

automatic task write_reg(regname,value);

wr_key.get(1);

wr_reg = regname;

if(wr_reg==rd_reg)

wait(rd_reg=="READ_DONE");

.

.

wr_key.put(1);

wr_reg = WRITE_DONE;

endtask

automatic task read_reg(regname,value);

rd_key.get(1);

rd_reg = regname;

if(wr_reg==rd_reg)

wait(wr_reg=="WRITE_DONE");

.

.

rd_key.put(1);

rd_reg= READ_DONE;

endtask

If i do this, the problem is solved unless and until there is a lock condition that both read and write to the same register get the read and write key at the same time. In this situation, both the tasks wait for the WRITE_DONE and READ_DONE indefinitely and it is a lock condition.

To avoid this, i decided to give priority to read in such a condition by using flags wr_flag and rd_flag.

automatic task write_reg(regname,value);

wr_key.get(1);

wr_reg = regname;

if(wr_reg==rd_reg)begin

wr_flag=1;

wait(rd_reg=="READ_DONE");

wr_flag=0;

end

.

.

wr_key.put(1);

wr_reg = WRITE_DONE;

endtask

automatic task read_reg(regname,value);

rd_key.get(1);

rd_reg = regname;

if(wr_reg==rd_reg)begin

rd_flag=1;

if(wr_flag==1)begin

$display("both rd and wr are called at same time, hence allow rd to happen");

end

else

begin

wait(wr_reg=="WRITE_DONE");

end

rd_flag=1;

end

.

.

rd_key.put(1);

rd_reg= READ_DONE;

endtask

This works fine, until and unless the time when rd_reg=READ_DONE; and the time when rd_reg=READ_DONE coincides thus again making the wait in the write task wait(rd_reg=READ_DONE) indefinite.

I tried using events, but they have also their own issues. What is the best way to manage timing and avoid race conditions in such situations?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...