Initial commit
This commit is contained in:
1
i2c_io_output_tb/.dir-locals.el
Normal file
1
i2c_io_output_tb/.dir-locals.el
Normal file
@@ -0,0 +1 @@
|
||||
((verilog-mode . ((flycheck-verilator-include-path . ("../")))))
|
||||
7
i2c_io_output_tb/Makefile
Normal file
7
i2c_io_output_tb/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
SOURCES = ../i2c_io_output.sv ../i2c_receiver.sv ./i2c_io_output_tb.sv
|
||||
|
||||
all: run
|
||||
|
||||
run: $(SOURCES)
|
||||
iverilog -g2012 -DDUMP -o out.vvp $(SOURCES)
|
||||
vvp ./out.vvp -fst
|
||||
111
i2c_io_output_tb/i2c_io_output_tb.sv
Normal file
111
i2c_io_output_tb/i2c_io_output_tb.sv
Normal file
@@ -0,0 +1,111 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
/* verilator lint_off MULTITOP */
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off INFINITELOOP */
|
||||
/* verilator lint_off INITIALDLY */
|
||||
|
||||
module i2c_io_output_tb;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock = ~clock;
|
||||
|
||||
parameter SCL_PERIOD = 364793; // ~300ns
|
||||
logic scl_async;
|
||||
logic sda_async;
|
||||
|
||||
event scl_low_ev;
|
||||
event scl_high_ev;
|
||||
|
||||
initial begin
|
||||
scl_async = 1'b1;
|
||||
|
||||
forever begin
|
||||
#(SCL_PERIOD/4) scl_async = 1'b1;
|
||||
#(SCL_PERIOD/4) -> scl_high_ev;
|
||||
#(SCL_PERIOD/4) scl_async = 1'b0;
|
||||
#(SCL_PERIOD/4) -> scl_low_ev;
|
||||
end
|
||||
end
|
||||
|
||||
parameter IO_BYTES_COUNT = 2;
|
||||
parameter [6:0] I2C_ADDRESS = 7'h5a;
|
||||
localparam DATA_WIDTH = IO_BYTES_COUNT * 8;
|
||||
|
||||
logic i_scl;
|
||||
logic i_sdi;
|
||||
logic o_sdo;
|
||||
logic [DATA_WIDTH-1:0] o_data;
|
||||
|
||||
i2c_io_output #(.I2C_ADDR(I2C_ADDRESS),
|
||||
.IO_BYTES_COUNT(IO_BYTES_COUNT))
|
||||
DUT (.*);
|
||||
|
||||
logic [1:0] scl_sync;
|
||||
logic [1:0] sda_sync;
|
||||
|
||||
always_ff @(posedge clock)
|
||||
if (reset) begin
|
||||
scl_sync <= '1;
|
||||
sda_sync <= '1;
|
||||
end
|
||||
else begin
|
||||
scl_sync <= {scl_sync[0], scl_async};
|
||||
sda_sync <= {sda_sync[0], sda_async};
|
||||
end
|
||||
|
||||
assign i_scl = scl_sync[1];
|
||||
assign i_sdi = sda_sync[1];
|
||||
|
||||
task send_start;
|
||||
wait(scl_async == 1'b0);
|
||||
sda_async = 1'b1;
|
||||
@(scl_high_ev);
|
||||
sda_async = 1'b0;
|
||||
endtask
|
||||
|
||||
task send_stop;
|
||||
wait(scl_async == 1'b0);
|
||||
sda_async = 1'b0;
|
||||
@(scl_high_ev);
|
||||
sda_async = 1'b1;
|
||||
endtask
|
||||
|
||||
task send_byte(logic [7:0] b);
|
||||
for (int n = 7; n >= 0; n -= 1) begin
|
||||
@(scl_low_ev);
|
||||
sda_async = b[n];
|
||||
end
|
||||
|
||||
@(scl_low_ev);
|
||||
wait(scl_async == 1'b1);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
repeat(2) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
repeat(2) @(posedge clock) #1;
|
||||
|
||||
send_start;
|
||||
send_byte(8'hb4);
|
||||
send_byte(8'ha5);
|
||||
send_byte(8'h38);
|
||||
send_byte(8'h42);
|
||||
send_stop;
|
||||
|
||||
repeat(1000) @(posedge clock) #1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
`ifdef DUMP
|
||||
initial begin
|
||||
$dumpfile("i2c_io_output_tb.fst");
|
||||
$dumpvars(0, i2c_io_output_tb);
|
||||
end
|
||||
`endif
|
||||
|
||||
endmodule // i2c_io_output_tb
|
||||
Reference in New Issue
Block a user