AbstractVerilog有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
執行結果 完整程式碼下載