本节先介绍 ISP中的transaction有哪些? 根据transaction如何配置sequence?
1. transaction
DUT接收的输入端口如下:
- i_pvsync :每一帧图像开始的标志;
- i_phsync :图像每一行开始的标志;
- i_data_en :图像有效区域的标志;
- i_data_0~n :图像在有效区域时,对应的pixel值。
图1 给出了 DUT输入端口中的部分信号,V_start对应的是i_pvsyc, H_start对应的是i_phsync, data_en对应的是i_data_en。
(1) 每行区域包括:H_frontporch + H_pulse + 图像在水平方向上的有效区域 + H_backporch,仅仅在图像的有效区域时,i_data_en为1,而在Hblank区域,i_data_en为0;故,每行的cycles数为:Hblank + 图像的宽度/channel_V,channel_V指的是每个cycle可以处理的列的数量。参考图1最底下那条波形线。
(2) 每帧区域包括:V_frontporch + V_pulse + 图像在竖直方向上的有效区域 + V_backporch,故,每帧图像的cycles数为:(Vblank + 每行的cycles数) * 图像的高度/channel_H ,channel_H指的是每个cycle可以处理的行的数量。
图1 输入transaction中的部分波形。可以参考《基于FPGA的数字图像处理原理及应用》11.2视频输出接口
综上,给出参数:channel_H, channel_V, Hblank, Vblank, 图像高度height, 图像宽度width后,对于输入而言,其共耗费的cycles数就非常明确了。如下图所示
UVM中用户定义的transaction如下:
`include "uvm_macros.svh"
import uvm_pkg::*;
import param_pkg::*;
class demo_transaction extends uvm_sequence_item;
rand bit i_data_en[0:totalcycle -1] ;
rand bit i_pvsync [0:totalcycle -1] ;
rand bit i_phsync [0:totalcycle -1] ;
rand logic [BITS-1:0] i_data [0:h_chan*v_chan -1] ;
bit o_data_en ;
bit done ;
logic [BITS-1:0] o_data_r[0:h_chan*v_chan -1];
logic [BITS-1:0] o_data_g[0:h_chan*v_chan -1];
logic [BITS-1:0] o_data_b[0:h_chan*v_chan -1];
function new (string name = "demo_transaction");
super.new(name);
endfunction
`uvm_object_utils_begin (demo_transaction)
`uvm_field_sarray_int (i_data_en , UVM_ALL_ON)
`uvm_field_sarray_int (i_pvsync , UVM_ALL_ON)
`uvm_field_sarray_int (i_phsync , UVM_ALL_ON)
`uvm_field_sarray_int (i_data , UVM_ALL_ON)
`uvm_field_sarray_int (o_data_r , UVM_ALL_ON)
`uvm_field_sarray_int (o_data_g , UVM_ALL_ON)
`uvm_field_sarray_int (o_data_b , UVM_ALL_ON)
`uvm_field_int (o_data_en , UVM_ALL_ON)
`uvm_field_int (done , UVM_ALL_ON)
`uvm_object_utils_end
endclass
经过上面介绍,应该可以明确transaction相关信息。
2. 在代码中如何实现上述波形的配置。
其配置上述波形,可以参考如下代码完成。可以参考《基于FPGA的数字图像处理原理及应用》11.2.2 VGA(书中提供了代码)
class Portsignal ;
integer width = WIDTH;
integer height = HEIGHT;
bit data_en[0:totalcycle -1] ;
bit phsync [0:totalcycle -1] ;
bit pvsync [0:totalcycle -1] ;
function void init();
foreach(data_en[i]) begin
data_en[i] = 0;
phsync [i] = 0;
pvsync [i] = 0;
end
endfunction
function void gen_ports();
integer line_cnt = 0;
integer pix_cnt = 0;
for (integer i = 0 ; i < totalcycle; i++ ) begin
if (pix_cnt < H_totalcycle - 1) begin
pix_cnt = pix_cnt + 1;
end else if (pix_cnt == H_totalcycle - 1) begin
pix_cnt = 0;
if (line_cnt < V_totalline - 1)
line_cnt = line_cnt + 1;
else
line_cnt = 0;
end
pvsync[i] = (line_cnt >= V_frontporch && line_cnt < V_frontporch + V_PULSE) ? 1 : 0;
phsync[i] = (pix_cnt >= H_frontporch && pix_cnt < H_frontporch + H_PULSE) ? 1 : 0;
data_en[i] = (pix_cnt >= H_totalcycle - H_transfercycle) && (line_cnt >= V_totalline - V_transferline);
end
endfunction
endclass
上述配置transaction的函数,要在UVM的哪个component中使用呢?
用于定义的sequence中,可能会用到`uvm_do(SEQ_OR_ITEM)系列宏,其包括 68-69行组成的start_item(),70行随机化transaction和71-74行组成的finish_item()。
用于ISP处理的sequence,只需要用下面图片中的第50行代码 替换掉 上一张图片中的第70行代码,就可以完成了适应于的demosaic的transaction的配置,可参考如下代码:
至此,输入端口中的i_pvsync, i_phsync和i_data_en已经完成了配置,但是没有配置i_data_0~n,没有配置pixel的原因是pixel值由i_data_en决定,i_data_en为0时、pixels值为0,i_data_en为1时,pixels为图像有效区域的数值,这一个过程在driver中配置效果会更合适哦。
下一节将介绍UVM中的剩余components。