2010-02-17 96 views
6

傳遞一個256位線C函數我用Verilog有256位值:通過的Verilog VPI

reg [255:0] val; 

我要定義一個系統任務$ foo的使用召喚出外部C VPI的,所以我可以調用$ foo的是這樣的:

$foo(val); 

現在,在C定義函數「富」,我不能簡單地讀取參數作爲一個整數(PLI_INT32),因爲我有太多的位適合其中之一。但是,我可以將該參數作爲字符串來讀取,這與字節數組是一樣的。下面是我寫的:

static int foo(char *userdata) { 
    vpiHandle systfref, args_iter, argh; 
    struct t_vpi_value argval; 
    PLI_BYTE8 *value; 

    systfref = vpi_handle(vpiSysTfCall, NULL); 
    args_iter = vpi_iterate(vpiArgument, systfref); 

    argval.format = vpiStringVal; 
    argh = vpi_scan(args_iter); 
    vpi_get_value(argh, &argval); 
    value = argval.value.str; 

    int i; 

    for (i = 0; i < 32; i++) { 
    vpi_printf("%.2x ", value[i]); 
    } 
    vpi_printf("\n"); 

    vpi_free_object(args_iter); 
    return 0; 
} 

正如你所看到的,此代碼讀取參數作爲一個字符串,然後打印出字符串中的每個字符(又名字節)。這工作幾乎完美。但是,字節00始終讀取爲20。例如,如果我指定的Verilog REG如下:

val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f; 

而且使用$foo(val)調用它,那麼C函數打印這在仿真時間:

VPI: 20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 

我曾與許多不同的值測試這並發現字節00始終映射到20,無論在val中出現的位置或次數。

此外,請注意,如果我讀取的值爲vpiHexStrVal,並打印字符串,它看起來很好。

於是,兩個問題:

  1. 有沒有更好的辦法從我的Verilog 256位值來讀取?
  2. 這是怎麼回事20?這是一個錯誤?我錯過了什麼嗎?

注意:我正在使用Aldec進行仿真。

回答

4

vpiStringVal用於希望值爲ASCII文本時,以便獲取值作爲指向C字符串的指針。如果要將其與C字符串(如printf()%s格式,fopen()等)一起使用,這非常有用。但是,C字符串不能包含空字符(因爲null用於終止C字符串),因此,也不能表示x或z位,所以如果你需要區分任何可能的矢量值,這不是應該使用的格式。它看起來像你正在使用的模擬器將空字符格式化爲空格(0x20);其他模擬器跳過它們,但是這對你也沒有幫助。要區分任何可能的矢量值,請使用vpiVectorVal(最簡潔的表示形式)或vpiBinStrVal(每個位具有一個0/1/x/z字符的二進制字符串)。

+0

我不想使用'vpiBinStrVal'或'vpiVectorVal',因爲一次輸入格式不一致。我實際上希望數據格式化爲32個8位值;我結束了拼接256位線並將其作爲8個32位輸入發送,可以讀作「vpiIntVal」,並簡單地將其轉換爲32字節的數組。 – pheaver

+0

確定但是'vpiVectorVal'允許你將這些位讀爲32位字;它一次不是一點點。 – mark4o

+0

是的,你是對的,我錯過了。我的意思是我想要一個實際的積分值,而不是其中有'x'和'z'的東西。沒有什麼大不了的,我可以將其轉換。 – pheaver