Initial commit
This commit is contained in:
1
i2c_receiver_tb/.dir-locals.el
Normal file
1
i2c_receiver_tb/.dir-locals.el
Normal file
@@ -0,0 +1 @@
|
||||
((verilog-mode . ((flycheck-verilator-include-path . ("../")))))
|
||||
7
i2c_receiver_tb/Makefile
Normal file
7
i2c_receiver_tb/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
SOURCES = ../i2c_receiver.sv ./i2c_receiver_tb.sv
|
||||
|
||||
all: run
|
||||
|
||||
run: $(SOURCES)
|
||||
iverilog -g2012 -DDUMP -o out.vvp $(SOURCES)
|
||||
vvp ./out.vvp -fst
|
||||
109
i2c_receiver_tb/i2c_receiver_tb.sv
Normal file
109
i2c_receiver_tb/i2c_receiver_tb.sv
Normal file
@@ -0,0 +1,109 @@
|
||||
`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_receiver_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
|
||||
|
||||
logic i_scl;
|
||||
logic i_sdi;
|
||||
logic o_sdo;
|
||||
logic [7:0] o_data;
|
||||
logic o_strobe;
|
||||
logic o_start;
|
||||
logic o_stop;
|
||||
logic i_ack;
|
||||
|
||||
i2c_receiver 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;
|
||||
|
||||
i_ack = 1'b1;
|
||||
|
||||
send_start;
|
||||
send_byte(8'h6a);
|
||||
send_byte(8'ha5);
|
||||
send_stop;
|
||||
|
||||
repeat(1000) @(posedge clock) #1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
`ifdef DUMP
|
||||
initial begin
|
||||
$dumpfile("i2c_receiver_tb.fst");
|
||||
$dumpvars(0, i2c_receiver_tb);
|
||||
end
|
||||
`endif
|
||||
|
||||
endmodule // i2c_receiver_tb
|
||||
Reference in New Issue
Block a user