I am using Modelsim 10.4a Student edition, and writing crossbar module. The problem is that if i try to start simulation, there is an error "Iteration limit 10 000 000 reached at time 25 ns". I understand that my code takes too much resourses, but don't understand why it is like that and what exactly I did wrong.
//question is solved, i found the bug - error was in complementary logic.
This is the main module
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
That's the master and slave interface modules
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
And this is my testbench
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
The iteration limit error is usually caused by some combinatorial loop in the design, whereby the simulator tries to determine the value through multiple evaluations of combinatorial expressions, but the value never settles due to the loop.
So look for some loop, which can be done by reducing the design, until it works, and the looks at he last part you removed.