在我之前的一个仿真中,需要从一个txt文本中提取发送数据的文本描述,然后转化为二进制数据作为被测试module的输入。以下就是文本描述的大致格式。
K0.0
K0.7
K16.0
D28.5
K8.4
在testbench中,需要识别文本中的编码类型,如K码或D码。同时把文本中的码转换为8bits的二进制数。我通过string变量读入每一行的信息,然后使用以下的方式来识别编码类型。
$fgets(str_data, file);
i = str_data.len();
if(str_data.getc(0) == "K")
is_k = 1'b1;
else if(str_data.getc(0) == "D")
is_k = 1'b0;
else if(str_data == "") begin
end else begin
$display(" Source data syntax error, code -1!");
$finish;
end
需要注意的是,str.len()返回的长度包含换行符等,比如第一行的k0.0的长度就是5,而不是4。
接下来需要将其转换为二进制。由于当时对SV中的string不熟悉,我最开始使用了str.atohex,其转换结果如下。
Data is 00000000, Type is 1
Data is 11100000, Type is 1
Data is 00010110, Type is 1
Data is 10101000, Type is 0
Data is 10001000, Type is 1
All data has been read.
上图中,前两行文本转换正确。但是第三行的K16.0应该转换为00010000,实际结果却是00010110。说明atohex函数是将字符串中的每个数字字符独立的转换为其对应的16进制表示,所以16中的1转换为0001,6转换为0110。
接下来我又测试了atobin函数,其结果如下。可以看到,除了K16.0转换的二进制数据中出现了1,其他全为0。这说明atobin函数会将每个数字转换成1bit的二进制,所以除了1和0之外的所有数字都无法正确转换。
Data is 00000000, Type is 1
Data is 00000000, Type is 1
Data is 00000001, Type is 1
Data is 00000000, Type is 0
Data is 00000000, Type is 1
All data has been read.
最后测试了atoi函数,该函数能正确工作,他将整个字符串当做一个完整的10进制数进行转换,结果如下。
Data is 00000000, Type is 1
Data is 11100000, Type is 1
Data is 00010000, Type is 1
Data is 10111100, Type is 0
Data is 10001000, Type is 1
All data has been read.
用于转换的task如下。
task read_file;
output [DATA_WIDTH-1:0] rd_data;
output is_k;
output last_data;
integer i;
reg [ 4: 0] x;
reg [ 2: 0] y;
string strx, stry;
string str_data;
last_data = 1'b0;
$fgets(str_data, file);
i = str_data.len();
if(str_data.getc(0) == "K")
is_k = 1'b1;
else if(str_data.getc(0) == "D")
is_k = 1'b0;
else if(str_data == "") begin
end else begin
$display(" Source data syntax error, code -1!");
$finish;
end
if(i==6) begin
stry = str_data.substr(i-2, i-2);
strx = str_data.substr(1, 2);
x = strx.atoi();
y = stry.atoi();
end else if(i==5) begin
stry = str_data.substr(i-2, i-2);
strx = str_data.substr(1, 1);
x = strx.atoi();
y = stry.atoi();
end else if(str_data=="") begin
$display(" All data has been read.");
last_data = 1'b1;
end else begin
$display(" Source data syntax error, code -2!");
$finish;
end
rd_data = {y, x};
#SP;
endtask : read_file