如何防止verilog中的线值冲突?
How to prevent conflict in wire value in verilog?
我正在设计一个 SPI 设备,它有一个主机和 3 个从机。当我尝试将数据从主机发送到 MOSI 上的一个从机时,它工作正常。但是当我在 MISO 上从一个从站向一个主站发送一个位序列时,我得到了很多 X。我知道这是由于电线中的价值观冲突而发生的,但我无法解决。
代码如下:
module Master(dataIN,dataOUT,slaveno,enable,reset,cpha,cpol,miso,mosi,clk,cs0,cs1,cs2);
input enable,reset,cpha,cpol,miso,clk;
output reg mosi,cs0,cs1,cs2;
input [1:0] slaveno;
input [7:0] dataIN;
output [7:0] dataOUT;
integer mode = 0;
reg [7:0] data;
assign dataOUT = data;
always @ (posedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
mosi <= 1'b0;
end
else if (enable === 1) begin
case(slaveno)
2'b00 : cs0 <= 1'b0;
2'b01 : cs1 <= 1'b0;
2'b10 : cs2 <= 1'b0;
2'b11 : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
default : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
endcase
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
0 : mosi <= data[7];
1 : begin
data [7:1] <= data [6:0];
data [0] <= miso;
end
endcase
end
else if (enable === 1'b0 && dataIN !== 1'b0) begin
data <= dataIN;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
end
always @ (negedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
mosi <= 1'b0;
end
else if (enable === 1'b1) begin
case(slaveno)
2'b00 : cs0 <= 1'b0;
2'b01 : cs1 <= 1'b0;
2'b10 : cs2 <= 1'b0;
2'b11 : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
default : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
endcase
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
0 : begin
data [7:1] <= data [6:0];
data [0] <= miso;
end
1 : mosi <= data[7];
endcase
end
else if (enable === 1'b0 && dataIN !== 1'b0) begin
data <= dataIN;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
end
endmodule
module Slave(slaveDataIN,slaveDataOUT,reset,cpha,cpol,miso,mosi,clk,cs);
input reset,cpha,cpol,mosi,clk,cs;
output reg miso;
input [7:0] slaveDataIN;
output [7:0] slaveDataOUT;
reg [7:0] data;
integer mode = 0;
assign slaveDataOUT = data;
always @ (posedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
miso <= 1'b0;
end
else if (cs === 1'b0) begin
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
1 : miso <= data[7];
0 : begin
data [7:1] <= data [6:0];
data [0] <= mosi;
end
endcase
end
else if (cs === 1'b1 && slaveDataIN !== 1'b0)
data <= slaveDataIN;
end
always @ (negedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
miso <= 1'b0;
end
else if (cs === 1'b0) begin
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
1 : begin
data [7:1] <= data [6:0];
data [0] <= mosi;
end
0 : miso <= data[7];
endcase
end
else if (cs === 1'b1 && slaveDataIN !== 1'b0)
data <= slaveDataIN;
end
endmodule
module SPI(masterDataIN,slave0DataIN,slave1DataIN,slave2DataIN,masterDataOUT,slave0DataOUT,
slave1DataOUT,slave2DataOUT,slaveno,enable,reset,cpha,cpol,clk);
input [7:0] masterDataIN,slave0DataIN,slave1DataIN,slave2DataIN;
output wire [7:0] masterDataOUT,slave0DataOUT,slave1DataOUT,slave2DataOUT;
input [1:0] slaveno;
input enable,reset,cpha,cpol,clk;
wire miso,mosi,cs0,cs1,cs2;
Master m (masterDataIN,masterDataOUT,slaveno,enable,reset,cpha,cpol,miso,mosi,clk,cs0,cs1,cs2);
Slave s1 (slave0DataIN,slave0DataOUT,reset,cpha,cpol,miso,mosi,clk,cs0);
Slave s2 (slave1DataIN,slave1DataOUT,reset,cpha,cpol,miso,mosi,clk,cs1);
Slave s3 (slave2DataIN,slave2DataOUT,reset,cpha,cpol,miso,mosi,clk,cs2);
endmodule
在测试台中,我尝试将数据放入 slaveDataIN
并在 8 个周期后在 masterDataOUT
上接收(我在 Xs 中获得大部分数据)。我该如何解决这个冲突?
PS: x 只代替 1 而不是 0.
您可以为每个从机的 MISO 信号创建一条单独的线路,然后使用 slaveno
到 select 等控制信号,从机将 miso
输入驱动到主机。例如:
wire miso1, miso2, miso3;
assign miso = (slaveno == 0) ? miso1 : (slaveno == 1) ? miso2 : miso3;
Slave s1 (slave0DataIN,slave0DataOUT,reset,cpha,cpol, miso1, mosi,clk,cs0);
Slave s2 (slave1DataIN,slave1DataOUT,reset,cpha,cpol, miso2, mosi,clk,cs1);
Slave s3 (slave2DataIN,slave2DataOUT,reset,cpha,cpol, miso3, mosi,clk,cs2);
//
PS。在你的代码中,如果所有 3 个从机都驱动 miso
=0,那么将不会发生争用,因为它们都是相同的值;这解释了为什么你看到 0,而不是 x。
我正在设计一个 SPI 设备,它有一个主机和 3 个从机。当我尝试将数据从主机发送到 MOSI 上的一个从机时,它工作正常。但是当我在 MISO 上从一个从站向一个主站发送一个位序列时,我得到了很多 X。我知道这是由于电线中的价值观冲突而发生的,但我无法解决。
代码如下:
module Master(dataIN,dataOUT,slaveno,enable,reset,cpha,cpol,miso,mosi,clk,cs0,cs1,cs2);
input enable,reset,cpha,cpol,miso,clk;
output reg mosi,cs0,cs1,cs2;
input [1:0] slaveno;
input [7:0] dataIN;
output [7:0] dataOUT;
integer mode = 0;
reg [7:0] data;
assign dataOUT = data;
always @ (posedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
mosi <= 1'b0;
end
else if (enable === 1) begin
case(slaveno)
2'b00 : cs0 <= 1'b0;
2'b01 : cs1 <= 1'b0;
2'b10 : cs2 <= 1'b0;
2'b11 : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
default : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
endcase
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
0 : mosi <= data[7];
1 : begin
data [7:1] <= data [6:0];
data [0] <= miso;
end
endcase
end
else if (enable === 1'b0 && dataIN !== 1'b0) begin
data <= dataIN;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
end
always @ (negedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
mosi <= 1'b0;
end
else if (enable === 1'b1) begin
case(slaveno)
2'b00 : cs0 <= 1'b0;
2'b01 : cs1 <= 1'b0;
2'b10 : cs2 <= 1'b0;
2'b11 : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
default : begin
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
endcase
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
0 : begin
data [7:1] <= data [6:0];
data [0] <= miso;
end
1 : mosi <= data[7];
endcase
end
else if (enable === 1'b0 && dataIN !== 1'b0) begin
data <= dataIN;
cs0 <= 1'b1;
cs1 <= 1'b1;
cs2 <= 1'b1;
end
end
endmodule
module Slave(slaveDataIN,slaveDataOUT,reset,cpha,cpol,miso,mosi,clk,cs);
input reset,cpha,cpol,mosi,clk,cs;
output reg miso;
input [7:0] slaveDataIN;
output [7:0] slaveDataOUT;
reg [7:0] data;
integer mode = 0;
assign slaveDataOUT = data;
always @ (posedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
miso <= 1'b0;
end
else if (cs === 1'b0) begin
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
1 : miso <= data[7];
0 : begin
data [7:1] <= data [6:0];
data [0] <= mosi;
end
endcase
end
else if (cs === 1'b1 && slaveDataIN !== 1'b0)
data <= slaveDataIN;
end
always @ (negedge clk)
begin
if (reset)
begin
data <= 8'b00000000;
miso <= 1'b0;
end
else if (cs === 1'b0) begin
if (cpha === 1'b0 && cpol === 1'b0)
mode = 1;
else if (cpha === 1'b0 && cpol === 1'b1)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b0)
mode = 0;
else if (cpha === 1'b1 && cpol === 1'b1)
mode = 1;
case (mode)
1 : begin
data [7:1] <= data [6:0];
data [0] <= mosi;
end
0 : miso <= data[7];
endcase
end
else if (cs === 1'b1 && slaveDataIN !== 1'b0)
data <= slaveDataIN;
end
endmodule
module SPI(masterDataIN,slave0DataIN,slave1DataIN,slave2DataIN,masterDataOUT,slave0DataOUT,
slave1DataOUT,slave2DataOUT,slaveno,enable,reset,cpha,cpol,clk);
input [7:0] masterDataIN,slave0DataIN,slave1DataIN,slave2DataIN;
output wire [7:0] masterDataOUT,slave0DataOUT,slave1DataOUT,slave2DataOUT;
input [1:0] slaveno;
input enable,reset,cpha,cpol,clk;
wire miso,mosi,cs0,cs1,cs2;
Master m (masterDataIN,masterDataOUT,slaveno,enable,reset,cpha,cpol,miso,mosi,clk,cs0,cs1,cs2);
Slave s1 (slave0DataIN,slave0DataOUT,reset,cpha,cpol,miso,mosi,clk,cs0);
Slave s2 (slave1DataIN,slave1DataOUT,reset,cpha,cpol,miso,mosi,clk,cs1);
Slave s3 (slave2DataIN,slave2DataOUT,reset,cpha,cpol,miso,mosi,clk,cs2);
endmodule
在测试台中,我尝试将数据放入 slaveDataIN
并在 8 个周期后在 masterDataOUT
上接收(我在 Xs 中获得大部分数据)。我该如何解决这个冲突?
PS: x 只代替 1 而不是 0.
您可以为每个从机的 MISO 信号创建一条单独的线路,然后使用 slaveno
到 select 等控制信号,从机将 miso
输入驱动到主机。例如:
wire miso1, miso2, miso3;
assign miso = (slaveno == 0) ? miso1 : (slaveno == 1) ? miso2 : miso3;
Slave s1 (slave0DataIN,slave0DataOUT,reset,cpha,cpol, miso1, mosi,clk,cs0);
Slave s2 (slave1DataIN,slave1DataOUT,reset,cpha,cpol, miso2, mosi,clk,cs1);
Slave s3 (slave2DataIN,slave2DataOUT,reset,cpha,cpol, miso3, mosi,clk,cs2);
//
PS。在你的代码中,如果所有 3 个从机都驱动 miso
=0,那么将不会发生争用,因为它们都是相同的值;这解释了为什么你看到 0,而不是 x。