An I2C verification environment, which uses
memories and VPI (c code) to
drive and monitor data to/from DUT, will be described in this work.
-
In this site many verification environments have been presented, using,
specman
,
VHDL
etc....
The main page of this work is accessed with the following
link.
This page describes how APB transaction are done.
-
The c code prepares transactions. It places them in a memory from the
test-bench. For the test-bench it is a read only memory. The timing
of filling the memories is controlled by the test-bench.
-
Since the maximum size with icarus is 32 bits and both APB data and address
are of 32 bits I use three arrays in the test-bench:
//read only (by TB) RAM
reg [31:0] a_pwdata [`RAM_SZ-1:0];
reg [31:0] a_paddr [`RAM_SZ-1:0];
reg [ 1:0] a_ctrl [`RAM_SZ-1:0]; //pkt_end pwrite
-
The test-bench controls the timing via a state machine:
always @ (apb_ps or q_ctrl or arst_i) begin
case (apb_ps)
`APB_IDLE: begin
//get buffers from c and wait one cycle
if(arst_i) begin
$mem_wrt(a_paddr);
$mem_wrt(a_pwdata);
$mem_wrt(a_ctrl);
end
apb_ns = `APB_WAIT;
...
First it requests from c code buffers. The c code, for the
first requests, puts the address, next comes the data and last is control.
-
Some of the APB control signals, which are driven to the DUT, are decoded
from the state machine:
assign p_sel =
apb_ps == `APB_READ ? 1'b1 :
apb_ps == `APB_WRIT ? 1'b1 :
apb_ps == `APB_HOLD ? 1'b1 :
1'b0;
assign p_enable =
apb_ps == `APB_HOLD ? 1'b1 : 1'b0;
...
-
The verilog test bench checks the read data based on an expected value,
which was prepared by the c code.
//check the value read from the APB
always @ (posedge pclk) begin
if(p_sel & p_enable & ~p_writeq) begin
if(prdata_s != q_pwdata) begin
$display("ver ERROR APB data mismatch exp %x act %x at %d", q_pwdata, prdata_s, $time);
$finish;
end
end
end
-
The c code is described in the following
link.
-
A simple wave with APB multiple write transactions followed by a single read
transaction is shown below:
|