2014-06-13 29 views
3

我有一個寄存器映射,它有16位寬的寄存器。我有一個大於16位的字段,因此它必須跨越兩個地址。如何定義對該字段的後門訪問?如何定義跨越兩個寄存器的字段的後門訪問?

這是我嘗試了我的領域test_pattern[23:0]

register_a.add_hdl_path_slice("path.to.regmap.test_pattern[15:0]", 0, 16); 
register_b.add_hdl_path_slice("path.to.regmap.test_pattern[23:16]", 0, 8); 

這種失敗,此錯誤:

ERROR: VPI TYPERR vpi_handle_by_name() cannot get a handle to a part select.

目前尚不清楚,如果這是我的工具的約束,或者如何UVM代碼使用VPI。在UVM代碼內部查看後,我看到應該處理部分選擇的代碼,但它在#ifdef QUESTA指令內,所以我認爲這是一個工具約束。

有沒有很好的解決這個問題?

+0

你可能想讓UVM開發者意識到這個問題:http://forums.accellera.org/topic/1725-uvm-12-feedback-required/ – Chiggs

回答

0

按照UVM Class Reference

function void add_hdl_path_slice(string name, 
    int offset, 
    int size, 
    bit first = 0, 
    string kind = "RTL")

我猜的解決方案應該使用offset選擇起始索引。

register_a.add_hdl_path_slice("path.to.regmap.test_pattern", 0, 16); 
register_b.add_hdl_path_slice("path.to.regmap.test_pattern", 16, 8); 

可能的替代,位選在一個for循環:

for (int i=0; i<16; i++) begin 
    string tmp_path_s; 
    tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i); 
    register_a.add_hdl_path_slice(tmp_path_s, i, 1); 
end 
for (int i=0; i<8; i++) begin 
    string tmp_path_s; 
    tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i+16); 
    register_a.add_hdl_path_slice(tmp_path_s, i, 1); 
end 
+0

不幸的是,我認爲offset指的是寄存器不是字段。 – nguthrie

0

這是一個很大的遺憾,無論誰貢獻了這段代碼(?想必導師)感到有必要增加一個非常有用的功能以通用庫包裝ifdefs。事實上,在UVM_1_2分支中,整個DPI/PLI接口文件被分成模擬器特定的實現方式,情況更是如此!

上的git的主分支看着distrib/src/dpi/uvm_hdl.c://git.code.sf.net/p/uvm/code它看起來像只QUESTA特定代碼此功能:

static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag); 
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag); 

它使用以下定義DPI值:

svLogic logic_bit; 
svGetBitselLogic(&bit_value,0); 
svLogicVecVal bit_value; 
svGetPartselLogic(&bit_value,value,i,1); 
svPutPartselLogic(value,bit_value,i,1); 

從理論上講,如果你的模擬器和導師代碼都是符合標準的,你可以刪除ifdefs,它應該仍然工作。

您也可以通過檢測路徑中的零件選擇並使用vpi_handle_by_index來讀取各個位,這在任何模擬器中都應該支持。

NB我原來的回答是關於代碼是指導者特定的錯誤 - 感謝@ dave_59直接設置我並向Mentor道歉。

+0

這些都是在IEEE 1800-2012 LRM的DPI部分定義的,比使用PLI更有效率。確保你將手指指向正確的方向。 –

+0

@dave_59關於DPI的公平點 - 但是我的主要觀點仍然存在 - 添加包含在'ifdef MY_SIMULATOR'中的功能(這不僅僅是一個特定的模擬器的解決方法)不僅是構建UVM的好方法,而且它在UVM中只會變得更糟1.2。如果它符合標準爲什麼'ifdef'?如果DPI更高效,爲什麼還要使用PLI? – Chiggs

+0

@ dave_59道歉,謝謝你指出我的錯誤。我現在更新了我的答案。由於您參與了UVM委員會,因此有可能建議其他仿真器供應商實施相同的功能(大概是通過將代碼複製到他們的文件中) - 或者更好地恢復到通用實施,以便複製「 n'paste不是必需的? – Chiggs

0

有沒有理由不將它分成2個寄存器。由於您的寄存器大小爲16位,因此聲明大於此值的寄存器是沒有意義的。

我看過大字段這樣定義的方式是聲明2個寄存器,每個寄存器都有一個單獨的字段。例如,如果你需要一個32位的指針,你就必須:

有16位字段 addr_low有16位字段addr_high

爲了方便,你可以添加將在訪問這兩個任務序列。

+0

在內部,這是一個驅動一些邏輯的24位總線。因爲寄存器寬度是16位,所以不得不將它分成幾塊。我可以將這兩部分拼接在一起,但總線不能跨越兩個地址的技術原因。我們用來生成寄存器RTL的工具支持跨越多個地址的大位字段,所以不這樣做的唯一原因是由於這種UVM限制。 – nguthrie

+0

你有沒有試過宣佈這個寄存器有24位的寬度?我沒有在我面前的uvm引用,但我認爲寄存器寬度是uvm_reg的屬性,而不是uvm_block。所以我認爲你應該可以擁有不同寬度的寄存器。然後你不需要添加分片,你可以直接在uvm_reg :: configure中傳遞hdl路徑。 –

+0

這會工作,但SPI接口在16位邊界上工作,所以一個地址只能映射到16位。無論哪種方式,我的Cadence AE已將此作爲增強請求,但我還沒有機會查看它是否有效。正如你可以從上面的評論中看到的,Mentor已經支持這個功能。不知道Synopsys。 – nguthrie