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


執行結果

atoi

完整程式碼下載
pli_atoi.7z