TestBench I2C SDA 不会变低
TestBench I2C SDA won't go low
我正在用 Verilog 编写我的第一个 I2C 程序,但我正在努力使用 TestBench。
我想单独测试 I2C 从设备,但我无法设置不同的 SDA 值:SDA 始终为 1 或 X。
我要用错误的方式进行测试吗?我的想法是我应该能够在每个时钟上设置 SDA,然后看看会发生什么。
游乐场在这里:https://edaplayground.com/x/6snM
module Slave(
inout SDA,
input SCL);
reg [4:0] IDLE = 4'b0000;
reg [4:0] START = 4'b0001;
reg [4:0] ADDRESS = 4'b0010;
reg [4:0] READ_WRITE = 4'b0011;
reg [4:0] DATA = 4'b0100;
reg [4:0] WRITE_ACK = 4'b0101;
reg [4:0] STOP = 4'b0110;
reg [4:0] state = 4'b0000;
reg [6:0] slaveAddress = 7'b0001000;
reg [6:0] addressCounter = 7'b0000000;
reg readWrite = 1'b0;
reg write_ack = 0;
assign SDA = write_ack ? 0 : 1'bz;
always @(posedge SCL)
begin
case (state)
IDLE:
begin
if (SDA == 0 && SCL == 1)
begin
state <= ADDRESS;
end
end
START:
begin
readWrite <= 0;
end
ADDRESS:
begin
if (slaveAddress[addressCounter] != SDA)
begin
state <= STOP;
addressCounter <= 0;
end
addressCounter <= addressCounter + 1;
if (addressCounter >= 6)
begin
write_ack <= 1;
state <= READ_WRITE;
end
end
READ_WRITE:
begin
write_ack <= 0;
state <= DATA;
end
endcase
end
endmodule
我想驱动 SDA 以便我可以传递一个位序列,但无论我做什么,SDA 都保持不变 (1) 或 X。
module Slave_TB ();
reg clk;
wire SDA;
wire SCL;
pullup(SDA);
pullup(SCL);
reg [8:0] bitsToSend = 9'b000100010;
integer ii=0;
initial begin
clk = 0;
forever begin
clk = #1 ~clk;
end
end
Slave UUT
(.SDA(SDA),
.SCL(SCL));
initial
begin
$display("Starting Testbench...");
clk = 0;
force SCL = clk;
#10
for(ii=0; ii<9; ii=ii+1)
$display("SDA %h to %h", SDA, bitsToSend[ii]);
#1 force SDA = bitsToSend[ii];
#10;
$finish();
end
initial
begin
// Required to dump signals to EPWave
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
我在 $display
语句中添加了 $time
,这清楚地表明 SDA
正在发生变化,但它同时发生变化 (10):
10 SDA 1 to 0
10 SDA 1 to 1
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 1
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 0
您对 for
循环的缩进具有误导性,因为 #1
延迟不是循环的一部分。您需要添加 begin/end
关键字以在 for
循环中包含延迟:
for(ii=0; ii<9; ii=ii+1) begin
$display($time, " SDA %h to %h", SDA, bitsToSend[ii]);
#1 force SDA = bitsToSend[ii];
end
当我进行更改时,我看到 SDA
波形变低。这是新的打印输出:
10 SDA 1 to 0
11 SDA 0 to 1
12 SDA 1 to 0
13 SDA 0 to 0
14 SDA 0 to 0
15 SDA 0 to 1
16 SDA 1 to 0
17 SDA 0 to 0
18 SDA 0 to 0
我正在用 Verilog 编写我的第一个 I2C 程序,但我正在努力使用 TestBench。
我想单独测试 I2C 从设备,但我无法设置不同的 SDA 值:SDA 始终为 1 或 X。
我要用错误的方式进行测试吗?我的想法是我应该能够在每个时钟上设置 SDA,然后看看会发生什么。
游乐场在这里:https://edaplayground.com/x/6snM
module Slave(
inout SDA,
input SCL);
reg [4:0] IDLE = 4'b0000;
reg [4:0] START = 4'b0001;
reg [4:0] ADDRESS = 4'b0010;
reg [4:0] READ_WRITE = 4'b0011;
reg [4:0] DATA = 4'b0100;
reg [4:0] WRITE_ACK = 4'b0101;
reg [4:0] STOP = 4'b0110;
reg [4:0] state = 4'b0000;
reg [6:0] slaveAddress = 7'b0001000;
reg [6:0] addressCounter = 7'b0000000;
reg readWrite = 1'b0;
reg write_ack = 0;
assign SDA = write_ack ? 0 : 1'bz;
always @(posedge SCL)
begin
case (state)
IDLE:
begin
if (SDA == 0 && SCL == 1)
begin
state <= ADDRESS;
end
end
START:
begin
readWrite <= 0;
end
ADDRESS:
begin
if (slaveAddress[addressCounter] != SDA)
begin
state <= STOP;
addressCounter <= 0;
end
addressCounter <= addressCounter + 1;
if (addressCounter >= 6)
begin
write_ack <= 1;
state <= READ_WRITE;
end
end
READ_WRITE:
begin
write_ack <= 0;
state <= DATA;
end
endcase
end
endmodule
我想驱动 SDA 以便我可以传递一个位序列,但无论我做什么,SDA 都保持不变 (1) 或 X。
module Slave_TB ();
reg clk;
wire SDA;
wire SCL;
pullup(SDA);
pullup(SCL);
reg [8:0] bitsToSend = 9'b000100010;
integer ii=0;
initial begin
clk = 0;
forever begin
clk = #1 ~clk;
end
end
Slave UUT
(.SDA(SDA),
.SCL(SCL));
initial
begin
$display("Starting Testbench...");
clk = 0;
force SCL = clk;
#10
for(ii=0; ii<9; ii=ii+1)
$display("SDA %h to %h", SDA, bitsToSend[ii]);
#1 force SDA = bitsToSend[ii];
#10;
$finish();
end
initial
begin
// Required to dump signals to EPWave
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
我在 $display
语句中添加了 $time
,这清楚地表明 SDA
正在发生变化,但它同时发生变化 (10):
10 SDA 1 to 0
10 SDA 1 to 1
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 1
10 SDA 1 to 0
10 SDA 1 to 0
10 SDA 1 to 0
您对 for
循环的缩进具有误导性,因为 #1
延迟不是循环的一部分。您需要添加 begin/end
关键字以在 for
循环中包含延迟:
for(ii=0; ii<9; ii=ii+1) begin
$display($time, " SDA %h to %h", SDA, bitsToSend[ii]);
#1 force SDA = bitsToSend[ii];
end
当我进行更改时,我看到 SDA
波形变低。这是新的打印输出:
10 SDA 1 to 0
11 SDA 0 to 1
12 SDA 1 to 0
13 SDA 0 to 0
14 SDA 0 to 0
15 SDA 0 to 1
16 SDA 1 to 0
17 SDA 0 to 0
18 SDA 0 to 0