Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

verilog - Passing packed data to a task to be compared with an unpacked data array for uvm constraints

I'm trying to create a task for a UVM sequence that takes a packed data input and uses it for a constraint on an unpacked value.

The goal is to have something that looks like this:

if((!msg.randomize() with
{
 {msg_pld[0], msg_pld[1], msg_pld[2], msg_pld[3]} == 32'h01234567; //address
 {msg_pld[4], msg_pld[5], msg_pld[6], msg_pld[7]} == 32'hDEADBEEF; //data
}))
`uvm_fatal("EX_SEQ", "failed to randomize message")

(the above code works just fine)

But have be it's own task that can be called with the data and address values passed in.

The code I have written to do this is as follows:

task send_message (wr_req_item msg, bit[31:0] addr, bit[31:0] data);
  if((!msg.randomize() with
  {
   {msg_pld[0], msg_pld[1], msg_pld[2], msg_pld[3]} == addr; //address
   {msg_pld[4], msg_pld[5], msg_pld[6], msg_pld[7]} == data; //data
  }))
  `uvm_fatal("EX_SEQ", "failed to randomize message")

 //some other things that are also done in this sequence but are irrelevant to this question
endtask;

With a call looking like this:

send_message(ex_msg , 32'h01234567, 32'hDEADBEEF)

When I try to execute this though I get a compilation error saying "cannot mix packed and unpacked types in this operation"

What syntax or data types should I be using so I can have my task take in basic 32 bit values as listed for the constraints?

Edit: Added info

The error says it occurs on the following line:

 {msg_pld[4], msg_pld[5], msg_pld[6], msg_pld[7]} == data; //data

msg_pld is defined as:

rand bit [7:0] msg_pld[ ];

EDIT 2:

I have a solution but it is very clunky.

The following works:

task send_message (wr_req_item msg, bit[31:0] addr, bit[31:0] data);
  
 bit [63:0] addrdata = {addr, data}

  if((!msg.randomize() with
  {
   {msg_pld[0], msg_pld[1], msg_pld[2], msg_pld[3], msg_pld[4], msg_pld[5], msg_pld[6], msg_pld[7]} == addrdata; 
  }))
  `uvm_fatal("EX_SEQ", "failed to randomize message")

endtask;

However: A) This solution is clunky, ugly code B) I don't understand why this solution works and the original code does not C) I don't understand why with this solution it only works when addrdata is declared as it's own variable and I can't just concatenate addr and data on the line I do the comparison (I tried this and it didn't work)

It's possible all of this lies buried deep inside legacy code seeing as in a basic setting it appears what I originally wrote would work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...