(原創) 如何將string轉成integer? (SOC) (Verilog PLI)
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 }
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
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