Modelsim - 模拟中的迭代太多(verilog)
Modelsim - too many iterations in simulation (verilog)
我用的是Modelsim 10.4a学生版,写的是crossbar模块。
问题是,如果我尝试开始模拟,则会出现错误 "Iteration limit 10 000 000 reached at time 25 ns"。我知道我的代码占用了太多资源,但不明白为什么会这样以及我到底做错了什么。
//问题已解决,我发现了错误-错误在互补逻辑中。
这是主模块
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
迭代极限错误通常是由设计中的某些组合循环引起的,即模拟器试图通过组合表达式的多次评估来确定值,但由于循环导致该值永远不会稳定。
所以寻找一些循环,这可以通过减少设计来完成,直到它起作用,然后查看你删除的最后一部分。
我用的是Modelsim 10.4a学生版,写的是crossbar模块。 问题是,如果我尝试开始模拟,则会出现错误 "Iteration limit 10 000 000 reached at time 25 ns"。我知道我的代码占用了太多资源,但不明白为什么会这样以及我到底做错了什么。
//问题已解决,我发现了错误-错误在互补逻辑中。
这是主模块
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
迭代极限错误通常是由设计中的某些组合循环引起的,即模拟器试图通过组合表达式的多次评估来确定值,但由于循环导致该值永远不会稳定。
所以寻找一些循环,这可以通过减少设计来完成,直到它起作用,然后查看你删除的最后一部分。