关于SV中软约束的问题,如何解决?

使用QuestSim10.1进行路科验证实验三,编译chnl_pkg1时,报编译错误,错误是在软约束那块,删掉soft关键词后
可以编译成功,但是会导致代码随机化失败,有没有遇到类似的情况,能不能给俺讲讲,谢谢!
代码如下

package chnl_pkg1;
class chnl_trans;
rand bit[31:0] data[];
rand int ch_id;
rand int pkt_id;
rand int data_nidles;
rand int pkt_nidles;
bit rsp;
local static int obj_id = 0;
constraint cstr{
data.size inside {[4:8]};
foreach(data[i]) data[i] == 'hC000_0000 + (this.ch_id<<24) + (this.pkt_id<<8) + i;
soft ch_id == 0;
soft pkt_id == 0;
data_nidles inside {[0:2]};
pkt_nidles inside {[1:10]};
};
function new();
this.obj_id++;
endfunction
function chnl_trans clone();
chnl_trans c = new();
c.data = this.data;
c.ch_id = this.ch_id;
c.pkt_id = this.pkt_id;
c.data_nidles = this.data_nidles;
c.pkt_nidles = this.pkt_nidles;
c.rsp = this.rsp;
return c;
endfunction

function string sprint();
  string s;
  s = {s, $sformatf("=======================================\n")};
  s = {s, $sformatf("chnl_trans object content is as below: \n")};
  s = {s, $sformatf("obj_id = %0d: \n", this.obj_id)};
  foreach(data[i]) s = {s, $sformatf("data[%0d] = %8x \n", i, this.data[i])};
  s = {s, $sformatf("ch_id = %0d: \n", this.ch_id)};
  s = {s, $sformatf("pkt_id = %0d: \n", this.pkt_id)};
  s = {s, $sformatf("data_nidles = %0d: \n", this.data_nidles)};
  s = {s, $sformatf("pkt_nidles = %0d: \n", this.pkt_nidles)};
  s = {s, $sformatf("rsp = %0d: \n", this.rsp)};
  s = {s, $sformatf("=======================================\n")};
  return s;
endfunction

endclass: chnl_trans

class chnl_initiator;
local string name;
local virtual chnl_intf intf;
mailbox #(chnl_trans) req_mb;
mailbox #(chnl_trans) rsp_mb;

function new(string name = "chnl_initiator");
  this.name = name;
endfunction

function void set_name(string s);
  this.name = s;
endfunction

function void set_interface(virtual chnl_intf intf);
  if(intf == null)
    $error("interface handle is NULL, please check if target interface has been intantiated");
  else
    this.intf = intf;
endfunction

task run();
  this.drive();
endtask

task drive();
  chnl_trans req, rsp;
  @(posedge intf.rstn);
  forever begin
    this.req_mb.get(req);
    this.chnl_write(req);
    rsp = req.clone();
    rsp.rsp = 1;
    this.rsp_mb.put(rsp);
  end
endtask

task chnl_write(input chnl_trans t);
  foreach(t.data[i]) begin
    @(posedge intf.clk);
    intf.drv_ck.ch_valid <= 1;
    intf.drv_ck.ch_data <= t.data[i];
    wait(intf.ch_ready === 'b1);
    $display("%0t channel initiator [%s] sent data %x", $time, name, t.data[i]);
    repeat(t.data_nidles) chnl_idle();
  end
  repeat(t.pkt_nidles) chnl_idle();
endtask

task chnl_idle();
  @(posedge intf.clk);
  intf.drv_ck.ch_valid <= 0;
  intf.drv_ck.ch_data <= 0;
endtask

endclass: chnl_initiator

class chnl_generator;
int pkt_id;
int ch_id;
int ntrans;
int data_nidles;
mailbox #(chnl_trans) req_mb;
mailbox #(chnl_trans) rsp_mb;

function new(int ch_id, int ntrans);
  this.ch_id = ch_id;
  this.pkt_id = 0;
  this.ntrans = ntrans;
  this.req_mb = new();
  this.rsp_mb = new();
endfunction

task run();
  repeat(ntrans) send_trans();
endtask
task send_trans();
  chnl_trans req, rsp;
  req = new();
  assert(req.randomize with {ch_id == local::ch_id; pkt_id == local::pkt_id;})
    else $fatal("[RNDFAIL] channel packet randomization failure!");
  this.pkt_id++;
  $display(req.sprint());
  this.req_mb.put(req);
  this.rsp_mb.get(rsp);
  $display(rsp.sprint());
  assert(rsp.rsp)
    else $error("[RSPERR] %0t error response received!", $time);
endtask

endclass: chnl_generator

class chnl_agent;
chnl_generator gen;
chnl_initiator init;
local virtual chnl_intf vif;
function new(string name = "chnl_agent", int id = 0, int ntrans = 1);
this.gen = new(id, ntrans);
this.init = new(name);
endfunction
function void set_interface(virtual chnl_intf vif);
this.vif = vif;
init.set_interface(vif);
endfunction
task run();
this.init.req_mb = this.gen.req_mb;
this.init.rsp_mb = this.gen.rsp_mb;
fork
gen.run();
init.run();
join_any
endtask
endclass: chnl_agent

class chnl_root_test;
chnl_agent agent[3];
protected string name;
function new(int ntrans = 100, string name = "chnl_root_test");
foreach(agent[i]) begin
this.agent[i] = new($sformatf("chnl_agent%0d",i), i, ntrans);
end
this.name = name;
$display("%s instantiate objects", this.name);
endfunction
task run();
$display($sformatf("%s started", this.name));
fork
agent[0].run();
agent[1].run();
agent[2].run();
join
$display($sformatf("%s finished", this.name));
$finish();
endtask
function void set_interface(virtual chnl_intf ch0_vif, virtual chnl_intf ch1_vif, virtual chnl_intf ch2_vif);
agent[0].set_interface(ch0_vif);
agent[1].set_interface(ch1_vif);
agent[2].set_interface(ch2_vif);
endfunction
endclass

function new(int ntrans = 200, string name = "chnl_basic_test");
  super.new(ntrans, name);
endfunction

endclass: chnl_basic_test

class chnl_burst_test extends chnl_root_test;
//USER TODO
endclass: chnl_burst_test

class chnl_fifo_full_test extends chnl_root_test;
// USER TODO
endclass: chnl_fifo_full_test

endpackage