Modelsim - 模拟中的迭代次数太多(verilog)

时间:2016-07-03 11:41:57

标签: verilog simulation modelsim

我正在使用Modelsim 10.4a学生版,并编写交叉开关模块。 问题是,如果我尝试开始模拟,则会出现错误"在25 ns"时间达到迭代限制10 000 000。我知道我的代码需要太多的资源,但不能理解为什么会这样,我究竟做错了什么。

//问题解决了,我发现错误 - 错误是互补逻辑。

这是主要模块

module crossbar_2m2s(
  input wire clk,
  input wire master_1_req, master_2_req, 
  input wire slave_1_ack, slave_2_ack,
  input wire [31:0] master_1_addr, master_2_addr,
  input wire [31:0] master_1_wdata, master_2_wdata,
  input wire [31:0] slave_1_rdata, slave_2_rdata,
  input wire master_1_cmd, master_2_cmd,
  output slave_1_req, slave_2_req,
  output master_1_ack, master_2_ack,
  output [31:0] slave_1_addr, slave_2_addr,
  output [31:0] slave_1_wdata, slave_2_wdata,
  output [31:0] master_1_rdata, master_2_rdata,
  output slave_1_cmd, slave_2_cmd
);

wire req_m1;
wire req_m2;
wire [31:0] addr_m1;
wire [31:0] addr_m2;
wire ack_s1;
wire ack_s2;
wire cmd_m1;
wire cmd_m2;
wire [31:0] wdata_m1;
wire [31:0] wdata_m2;
wire [31:0] rdata_s1;
wire [31:0] rdata_s2;

wire req_m1_s1 = ~addr_m1[31] & req_m1;
wire req_m2_s1 = ~addr_m2[31] & req_m2;
wire req_m1_s2 = addr_m1[31] & req_m1;
wire req_m2_s2 = addr_m2[31] & req_m2;

wire req_s1 = req_m1_s1 | req_m2_s1;
wire req_s2 = req_m1_s2 | req_m2_s2;


reg c_appr_m1_s1;
reg c_appr_m2_s1;
reg c_appr_m1_s2;
reg c_appr_m2_s2;

wire ack_m1 = ack_s1 & c_appr_m1_s1 | ack_s2 & c_appr_m1_s2;
wire ack_m2 = ack_s1 & c_appr_m2_s1 | ack_s2 & c_appr_m2_s2;

wire cmd_s1 = cmd_m1 & c_appr_m1_s1 | cmd_m2 & c_appr_m2_s1;
wire cmd_s2 = cmd_m1 & c_appr_m1_s2 | cmd_m2 & c_appr_m2_s2;

wire [31:0] addr_s1 = addr_m1 & {32{c_appr_m1_s1}} | addr_m2 & {32{c_appr_m2_s1}};
wire [31:0] addr_s2 = addr_m1 & {32{c_appr_m1_s2}} | addr_m2 & {32{c_appr_m2_s2}};

wire [31:0] wdata_s1 = wdata_m1 & {32{c_appr_m1_s1}} | wdata_m2 & {32{c_appr_m2_s1}};
wire [31:0] wdata_s2 = wdata_m1 & {32{c_appr_m1_s2}} | wdata_m2 & {32{c_appr_m2_s2}};

wire [31:0] rdata_m1 = rdata_s1 & {32{c_appr_m1_s1}} | rdata_s2 & {32{c_appr_m1_s2}};
wire [31:0] rdata_m2 = rdata_s1 & {32{c_appr_m2_s1}} | rdata_s2 & {32{c_appr_m2_s2}};



wire c_appr_m1 = c_appr_m1_s1 | c_appr_m1_s2;
wire c_appr_m2 = c_appr_m2_s1 | c_appr_m2_s2;
wire c_appr_s1 = c_appr_m1_s1 | c_appr_m2_s1;
wire c_appr_s2 = c_appr_m1_s2 | c_appr_m2_s2;


master_if master_1(
  .req_from_master(master_1_req), 
  .addr_from_master(master_1_addr),
  .wdata_from_master(master_1_wdata),
  .cmd_from_master(master_1_cmd),

  .ack_from_crossbar(ack_m1),
  .rdata_from_crossbar(rdata_m1),

  .connect_approved_from_crossbar(c_appr_m1),

  .ack_to_master(master_1_ack),
  .rdata_to_master(master_1_rdata),

  .req_to_crossbar(req_m1), 
  .addr_to_crossbar(addr_m1),
  .wdata_to_crossbar(wdata_m1),
  .cmd_to_crossbar(cmd_m1)
);

master_if master_2(
  .req_from_master(master_2_req), 
  .addr_from_master(master_2_addr),
  .wdata_from_master(master_2_wdata),
  .cmd_from_master(master_2_cmd),

  .ack_from_crossbar(ack_m2),
  .rdata_from_crossbar(rdata_m2),

  .connect_approved_from_crossbar(c_appr_m2),

  .ack_to_master(master_2_ack),
  .rdata_to_master(master_2_rdata),

  .req_to_crossbar(req_m2), 
  .addr_to_crossbar(addr_m2),
  .wdata_to_crossbar(wdata_m2),
  .cmd_to_crossbar(cmd_m2)
);

slave_if slave_1(
  .ack_from_slave(slave_1_ack),
  .rdata_from_slave(slave_1_rdata),

  .req_from_crossbar(req_s1),
  .addr_from_crossbar(addr_s1),
  .wdata_from_crossbar(wdata_s1),
  .cmd_from_crossbar(cmd_s1),

  .connect_approved_from_crossbar(c_appr_s1),

  .ack_to_crossbar(ack_s1),    
  .rdata_to_crossbar(rdata_s1),

  .req_to_slave(slave_1_req),
  .addr_to_slave(slave_1_addr),
  .wdata_to_slave(slave_1_wdata),
  .cmd_to_slave(slave_1_cmd)
);

slave_if slave_2(
  .ack_from_slave(slave_2_ack),
  .rdata_from_slave(slave_2_rdata),

  .req_from_crossbar(req_s2),
  .addr_from_crossbar(addr_s2),
  .wdata_from_crossbar(wdata_s2),
  .cmd_from_crossbar(cmd_s2),

  .connect_approved_from_crossbar(c_appr_s2),

  .ack_to_crossbar(ack_s2),    
  .rdata_to_crossbar(rdata_s2),

  .req_to_slave(slave_2_req),
  .addr_to_slave(slave_2_addr),
  .wdata_to_slave(slave_2_wdata),
  .cmd_to_slave(slave_2_cmd)
);


//Last connection section
reg last_con_to_s1; //last connection to slave1 - wich master 1'b0 - 1st, 1'b1 - 2nd 
reg last_con_to_s2; //last connection to slave2 - wich master 1'b0 - 1st, 1'b1 - 2nd 

always @(posedge clk)
   last_con_to_s1 <= ~c_appr_m1_s1 & (c_appr_m2_s1 | last_con_to_s1); // will be 1 if last was m2

always @(posedge clk)
   last_con_to_s2 <= ~c_appr_m1_s2 & (c_appr_m2_s2 | last_con_to_s2);

//connection approvation;   resolving case if two M going to one slave
always @*
begin
if ((req_m1_s1 & req_m2_s1) | (req_m1_s2 & req_m2_s2))
 begin
    //M1 M2 to s1
        //if last connection to s1 was from m2 - connect 1st master, from m1 - connect 2nd
    //(if last_con_to_s1 = 1 last one was m2, = 0 last one was m1)
        c_appr_m1_s1 = (req_m1_s1 & req_m2_s1) & (last_con_to_s1);
        c_appr_m2_s1 = ~(c_appr_m1_s1);

    //M1 M2 to s2
        //if last connection to s2 was from m2 - connect 1st master, from m1 - connect 2nd
    //(if last_con_to_s2 = 1 last one was m2, = 0 last one was m1)
        c_appr_m1_s2 = (req_m1_s2 & req_m2_s2) & (last_con_to_s2);
        c_appr_m2_s2 = ~(c_appr_m1_s2);   
 end
else
 begin
    c_appr_m1_s1 = req_m1_s1;
    c_appr_m2_s1 = req_m2_s1;
    c_appr_m1_s2 = req_m1_s1;
    c_appr_m2_s2 = req_m2_s1;
 end

end

endmodule

这是主接口模块和从接口模块

module master_if(
  input wire req_from_master, 
  input wire [31:0] addr_from_master,
  input wire [31:0] wdata_from_master,
  input wire cmd_from_master,

  input wire ack_from_crossbar,
  input wire [31:0] rdata_from_crossbar,

  input wire connect_approved_from_crossbar,

  output wire ack_to_master,
  output [31:0] rdata_to_master,

  output reg req_to_crossbar, 
  output reg [31:0] addr_to_crossbar,
  output reg [31:0] wdata_to_crossbar,
  output reg cmd_to_crossbar
);

assign ack_to_master    = ack_from_crossbar & connect_approved_from_crossbar;
assign rdata_to_master  = rdata_from_crossbar & {32{ack_from_crossbar}} & {32{connect_approved_from_crossbar}};

always @*
begin
  req_to_crossbar   = req_from_master; 
  addr_to_crossbar  = addr_from_master & {32{connect_approved_from_crossbar}};
  wdata_to_crossbar = wdata_from_master & {32{connect_approved_from_crossbar}};
  cmd_to_crossbar   = cmd_from_master & connect_approved_from_crossbar;
end

endmodule

module slave_if(

  input wire ack_from_slave,
  input wire [31:0] rdata_from_slave,

  input wire req_from_crossbar,
  input wire [31:0] addr_from_crossbar,
  input wire [31:0] wdata_from_crossbar,
  input wire cmd_from_crossbar,

  input wire connect_approved_from_crossbar,

  output reg ack_to_crossbar,    
  output reg [31:0] rdata_to_crossbar,

  output req_to_slave,
  output [31:0] addr_to_slave,
  output [31:0] wdata_to_slave,
  output cmd_to_slave
);

assign req_to_slave = req_from_crossbar;
assign addr_to_slave    = addr_from_crossbar & {32{connect_approved_from_crossbar}};
assign wdata_to_slave   = wdata_from_crossbar & {32{cmd_from_crossbar}} & {32{connect_approved_from_crossbar}}; //{32{cmd_from_crossbar}} <= write command
assign cmd_to_slave = cmd_from_crossbar & connect_approved_from_crossbar;

always @*
begin
  ack_to_crossbar   = ack_from_slave;
  rdata_to_crossbar = rdata_from_slave & ~{32{cmd_from_crossbar}} & {32{connect_approved_from_crossbar}}; //~{32{cmd_from_crossbar}} <= read command
end

endmodule

这是我的测试平台

module testbench;

  reg var_master_1_req;
  reg var_master_2_req;
  reg var_slave_1_ack;
  reg var_slave_2_ack;
  reg[31:0] var_master_1_addr;
  reg[31:0] var_master_2_addr;
  reg[31:0] var_master_1_wdata;
  reg[31:0] var_master_2_wdata;
  reg[31:0] var_slave_1_rdata;
  reg[31:0] var_slave_2_rdata;
  reg var_master_1_cmd;
  reg var_master_2_cmd;

wire out_slave_1_req; 
wire out_slave_2_req;
wire out_master_1_ack; 
wire out_master_2_ack;
wire out_slave_1_cmd; 
wire out_slave_2_cmd;
wire [31:0] out_master_1_rdata; 
wire [31:0] out_master_2_rdata;
wire [31:0] out_slave_1_wdata; 
wire [31:0] out_slave_2_wdata;
wire [31:0] out_slave_1_addr; 
wire [31:0] out_slave_2_addr;

//instance of module being studied
crossbar_2m2s crossbar(
  .master_1_req(var_master_1_req),
  .master_2_req(var_master_2_req),
  .slave_1_ack(var_slave_1_ack),
  .slave_2_ack(var_slave_2_ack),
  .master_1_addr(var_master_1_addr),
  .master_2_addr(var_master_2_addr),
  .master_1_wdata(var_master_1_wdata),
  .master_2_wdata(var_master_2_wdata),
  .slave_1_rdata(var_slave_1_rdata),
  .slave_2_rdata(var_slave_2_rdata),
  .master_1_cmd(var_master_1_cmd),
  .master_2_cmd(var_master_2_cmd),
  .slave_1_req(out_slave_1_req),
  .slave_2_req(out_slave_2_req),
  .master_1_ack(out_master_1_ack),
  .master_2_ack(out_master_2_ack),
  .slave_1_addr(out_slave_1_addr),
  .slave_2_addr(out_slave_2_addr),
  .slave_1_wdata(out_slave_1_wdata),
  .slave_2_wdata(out_slave_2_wdata),
  .master_1_rdata(out_master_1_rdata),
  .master_2_rdata(out_master_2_rdata),
  .slave_1_cmd(out_slave_1_cmd),
  .slave_2_cmd(out_slave_2_cmd)
);

initial
begin

var_master_1_req = 'b0;
var_master_1_cmd = 'b0;
var_slave_1_ack = 'b0;
var_master_2_req = 'b0;
var_master_2_cmd = 'b0;
var_slave_2_ack = 'b0;
 var_master_1_wdata = 'h1111;
 var_master_2_wdata = 'h2222;
 var_slave_1_rdata = 'h11;
 var_slave_2_rdata = 'h22;
 var_master_1_addr = 'hf0000000;
 var_master_2_addr = 'hf0000000;








//________WRITING TEST_________
//Write to S1 from M1
var_master_1_req = 'b1;
var_master_1_cmd = 'b1;
var_master_1_addr = 32'h7fffffff;
var_master_1_wdata = 32'h11111111;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Write to S2 from M1
var_master_1_req = 'b1;
var_master_1_cmd = 'b1;
var_master_1_addr = 32'hffffffff;
var_master_1_wdata = 32'h22221111;
#5;
var_slave_2_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_2_ack = 'b0;
#15;

//Write to S1 from M2
var_master_2_req = 'b1;
var_master_2_cmd = 'b1;
var_master_2_addr = 32'h7fffffff;
var_master_2_wdata = 32'h11112222;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_2_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Write to S2 from M2
var_master_2_req = 'b1;
var_master_2_cmd = 'b1;
var_master_2_addr = 32'hffffffff;
var_master_2_wdata = 32'h22222222;
#5;
var_slave_2_ack = 'b1;
#5;
var_master_2_req = 'b0;
var_slave_2_ack = 'b0;
#15;

//________READING TEST_________
//Read from S1 to M1
var_master_1_req = 'b1;
var_master_1_cmd = 'b0;
var_master_1_addr = 'h7fffffff;
var_slave_1_rdata = 'h10000001;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Read from S2 to M1
var_master_1_req = 'b1;
var_master_1_cmd = 'b0;
var_master_1_addr = 'hffffffff;
var_slave_2_rdata = 'h20000001;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Read from S1 to M2
var_master_2_req = 'b1;
var_master_2_cmd = 'b0;
var_master_2_addr = 'h7fffffff;
var_slave_1_rdata = 'h10000002;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_2_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Read from S2 to M2
var_master_2_req = 'b1;
var_master_2_cmd = 'b0;
var_master_2_addr = 'hffffffff;
var_slave_2_rdata = 'h20000002;
#5;
var_slave_2_ack = 'b1;
#5;
var_master_2_req = 'b0;
var_slave_2_ack = 'b0;
#15;

//________2 Request situations_________
//Write to different slaves 200ns
var_master_1_req = 'b1;
var_master_1_cmd = 'b1;
var_master_1_addr = 'h7fffffff;
var_master_1_wdata = 'h11111111;

var_master_2_req = 'b1;
var_master_2_cmd = 'b1;
var_master_2_addr = 32'hffffffff;
var_master_2_wdata = 32'h22221111;
#5;
var_slave_1_ack = 'b1;
var_slave_2_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_master_2_req = 'b0;
var_slave_1_ack = 'b0;
var_slave_2_ack = 'b0;
#15;

//Read from different slaves 225ns
var_master_1_req = 'b1;
var_master_1_cmd = 'b0;
var_master_1_addr = 'h7fffffff;
var_slave_1_rdata = 'h10000001;

var_master_2_req = 'b1;
var_master_2_cmd = 'b0;
var_master_2_addr = 'hffffffff;
var_slave_2_rdata = 'h20000002;
#5;
var_slave_1_ack = 'b1;
var_slave_2_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_1_ack = 'b0;
var_master_2_req = 'b0;
var_slave_2_ack = 'b0;
#15;

//Write to the same slave (1st) 2 times  250ns
var_master_1_req = 'b1;         //1st
var_master_1_cmd = 'b1;
var_master_1_addr = 'h7fffffff;
var_master_1_wdata = 'h11111111;

var_master_2_req = 'b1;
var_master_2_cmd = 'b1;
var_master_2_addr = 32'h1fffffff;
var_master_2_wdata = 32'h11112222;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_master_2_req = 'b0;
var_slave_1_ack = 'b0;
#15;

var_master_1_req = 'b1;         //2nd
var_master_1_cmd = 'b1;
var_master_1_addr = 'h7fffffff;
var_master_1_wdata = 'h11111111;

var_master_2_req = 'b1;
var_master_2_cmd = 'b1;
var_master_2_addr = 32'h1fffffff;
var_master_2_wdata = 32'h11112222;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_master_2_req = 'b0;
var_slave_1_ack = 'b0;
#15;

//Read from the same slave  300 ns
var_master_1_req = 'b1;
var_master_1_cmd = 'b0;
var_master_1_addr = 'h7fffffff;
var_slave_1_rdata = 'h10000001;

var_master_2_req = 'b1;
var_master_2_cmd = 'b0;
var_master_2_addr = 'h1fffffff;
var_slave_2_rdata = 'h20000002;
#5;
var_slave_1_ack = 'b1;
#5;
var_master_1_req = 'b0;
var_slave_1_ack = 'b0;
var_master_2_req = 'b0;
#15;

end


endmodule

1 个答案:

答案 0 :(得分:1)

迭代限制误差通常是由设计中的某些组合循环引起的,模拟器试图通过对组合表达式的多次评估来确定该值,但该值永远不会因循环而稳定。

所以寻找一些循环,这可以通过减少设计来完成,直到它起作用,并看看你最后一部分被移除。