Verilog有string型別,也有integer型別,但卻沒有提供string轉integer的函數,因此自己用Verilog PLI打造一個$atoi()給Verilog使用。
Abstract
Verilog有string型別,也有integer型別,但卻沒有提供string轉integer的函數,因此自己用Verilog PLI打造一個$atoi()給Verilog使用。
Introduction
使用環境:Visual C++ 6.0 + NC-Verilog 5.4
Verilog有string型別,不過基本上是使用reg vector,每8個bit存放該字元的ASCII值,Verilog也有提供integer型別,是32 bit,但如何將字串"1234”轉成integer 1234呢?Verilog並沒有提供相對應system task或system function作轉換。
在C語言,有提供atoi()將const char*轉型成int,借由Verilog PLI,我們實作出類似C語言的$atoi(),讓Verilog也能將字串轉成integer。
atoi_vpi.c / C
1
/*
2
(C) OOMusou 2009
http://oomusou.cnblogs.com
3
4
Filename : atoi_vpi.c
5
Compiler : VC++ 6.0
6
Description : $atoi() for Verilog
7
Release : 05/06/2009 1.0
8
*/
9
10
#include
<
stdlib.h
>
11
#include
"
vpi_user.h
"
12
13
//
sizetf routine
14
PLI_INT32 atoi_sizetf(PLI_BYTE8
*
user_data) {
15
return
(
32
);
//
$atoi() returns 32-bit value
16
}
17
18
//
compiletf routine
19
PLI_INT32 atoi_compiletf(PLI_BYTE8
*
user_data) {
20
vpiHandle systf_handle, arg_iterator, arg_handle;
21
PLI_INT32 arg_type;
22
int
err_flag
=
0
;
23
24
do
{
//
group all tests, so can break out of group on error
25
//
obtain a handle to the system task instance
26
systf_handle
=
vpi_handle(vpiSysTfCall, NULL);
27
if
(systf_handle
==
NULL) {
28
vpi_printf(
"
ERROR: $atoi failed to obtain systf handle\n
"
);
29
err_flag
=
1
;
30
break
;
31
}
32
33
//
obtain iterator to the system task argument
34
arg_iterator
=
vpi_iterate(vpiArgument, systf_handle);
35
if
(arg_iterator
==
NULL) {
36
vpi_printf(
"
ERROR: $atoi requires 1 arguments; has none\n
"
);
37
err_flag
=
1
;
38
break
;
39
}
40
41
//
check the type of 1st argument
42
arg_handle
=
vpi_scan(arg_iterator);
43
arg_type
=
vpi_get(vpiType, arg_handle);
44
if
((arg_type
!=
vpiReg)
&&
45
(arg_type
!=
vpiNet)
&&
46
(arg_type
!=
vpiConstant)) {
47
48
vpi_printf(
"
ERROR: $atoi arg1 must be reg, net or constant\n
"
);
49
err_flag
=
1
;
50
break
;
51
}
52
53
//
check too many argument
54
arg_handle
=
vpi_scan(arg_iterator);
55
if
(arg_handle
!=
NULL) {
56
vpi_printf(
"
ERROR: $atoi requires 1 arguments, has too many\n
"
);
57
vpi_free_object(arg_iterator);
58
err_flag
=
1
;
59
break
;
60
}
61
}
while
(
0
);
//
end of test group, only executed once
62
63
64
if
(err_flag)
65
vpi_control(vpiFinish,
1
);
66
67
return
(
0
);
68
}
69
70
//
calltf routine
71
PLI_INT32 atoi_calltf(PLI_BYTE8
*
user_data) {
72
vpiHandle systf_handle, arg_iterator, arg_handle;
73
PLI_BYTE8
*
s;
74
PLI_INT32 i;
75
s_vpi_value value_s;
76
77
systf_handle
=
vpi_handle(vpiSysTfCall, NULL);
78
arg_iterator
=
vpi_iterate(vpiArgument, systf_handle);
79
80
//
read str from systf arg 1
81
arg_handle
=
vpi_scan(arg_iterator);
82
vpi_free_object(arg_iterator);
83
value_s.format
=
vpiStringVal;
84
vpi_get_value(arg_handle,
&
value_s);
85
s
=
value_s.value.str;
86
87
//
use C's atoi()
88
i
=
atoi(s);
89
90
//
write result to simulation as return value $atoi
91
value_s.format
=
vpiIntVal;
92
value_s.value.integer
=
i;
93
vpi_put_value(systf_handle,
&
value_s, NULL, vpiNoDelay);
94
95
return
(
0
);
96
}
97
98
//
register function
99
void
atoi_register() {
100
s_vpi_systf_data tf_data;
101
102
tf_data.type
=
vpiSysFunc;
103
tf_data.sysfunctype
=
vpiSizedFunc;
104
tf_data.tfname
=
"
$atoi
"
;
105
tf_data.calltf
=
atoi_calltf;
106
tf_data.compiletf
=
atoi_compiletf;
107
tf_data.sizetf
=
atoi_sizetf;
108
tf_data.user_data
=
NULL;
109
vpi_register_systf(
&
tf_data);
110
}
atoi_tb.v / Verilog
1
/*
2
(C) OOMusou 2009
http://oomusou.cnblogs.com
3
4
Filename : atoi_tb.v
5
Simulator : NC-Verilog 5.4
6
Description : testbench for $atoi()
7
Release : 05/06/2009 1.0
8
*/
9
`timescale 1ns
/
1ns
10
11
module
atoi_tb;
12
13
reg
[
8
*
8
-
1
:
0
] s;
14
integer
i;
15
16
initial
begin
17
18
s
=
"
1234
"
;
19
i
=
$atoi(s);
20
$display(
"
s=%s
"
, s);
21
$display(
"
i=%d
"
, i);
22
23
#
50
24
$finish;
25
26
end
27
28
endmodule
執行結果
完整程式碼下載
pli_atoi.7z