摘要
存儲器相關的問題是DSP 應用中非常普遍的問題。本文介紹KeyStone I 系列DSP 上一些存儲器測試的方法。
1 KeyStone DSP 存儲器系統簡介
KeyStone DSP 存儲器架構如圖1 所示。
圖1 KeyStone DSP 存儲器架構
對不同的DSP,存儲器的大小可能不同,DSP 核和EDMA 傳輸控制器的個數也可能不同。表1比較了KeyStone I 系列中常用的3顆DSP。
表1 KeyStone I 存儲器系統比較
2 存儲器測試算法
本文介紹幾種存儲器測試算法,并討論這幾種算法的用途。
2.1 數據測試
下面是數據測試的偽代碼:
fill the memory with a value;
for(memory range under test)
read back the memory and compare the readback value to the written value
通常,這個測試會被執行幾次,每次填充的值不一樣。常用的填充值包括0x55555555,0xAAAAAAAA, 0x33333333, 0xCCCCCCCC, 0x0F0F0F0F, 0xF0F0F0F0, 0x00FF00FF,0xFF00FF00FF00, 0xFFFFFFFF, 0。
這個測試可以用來檢測數據比特粘連(bit-stuck)問題,例如,如果,
written value = 0, readback value = 0x8,
表示bit 3 粘連到1.
如果
written value = 0xFFFFFFFF, readback value = 0xFFFFFFFE,
表示bit 0 粘連到0.
如果能正確的寫入并讀出0x55555555(或0xAAAAAAAA),說明相鄰的兩個比特沒有粘連;如果能正確寫入并讀出0x33333333(或0xCCCCCCCC),說明相鄰的4 個比特沒有粘連;如果能正確寫入并讀出0x0F0F0F0F(或0xF0F0F0F0),說明相鄰的8 個比特沒有粘連…
這個算法既可以用來測試數據總線連接,也可以用于測試存儲器單元。當用于測試存儲器單元時則每一個存儲單元都需要寫讀所有的值,這將是比較耗時的測試;而用于測試數據總線連接時,只需要把所有的值都寫讀一遍就可以了(地址不限)。
2.2 地址測試
地址測試的偽代碼如下:
for(memory range under test)
fill each memory unit with its address value;
for(memory range under test)
read back the memory and compare the readback value to the written value
這個測試可以用來檢測地址比特粘連(bit-stuck)問題。例如,如果
written value = 0 at address 0
written value = 1 at address 1
written value = 2 at address 2
written value = 3 at address 3
……
readback value = 2 at address 0
readback value = 3 at address 1
readback value = 2 at address 2
readback value = 3 at address 3
……
則說明地址線的比特1 粘連,因為地址0,2 中的數據相同,地址1,3 中的數據相同。
這個測試的主要目的是測試地址線和存儲器中的地址譯碼單元,但它實際上對所有存儲單元都做了數據寫讀,所以在一定程度上也測試了數據總線和存儲單元。如果由于測試時間的限制,只允許對整個存儲器空間進行一遍寫讀測試時,本節介紹的地址測試是首選。
本文選自電子發燒友網6月《智能工業特刊》Change The World欄目,轉載請注明出處!
2.3 走比特測試
走比特測試包括走“1”和走“0”測試。走比特測試即可測試數據,也可以測試地址。
走“1”指測試的數據或地址中只有一個比特為“1”,而所有其它比特為“0”,而且連續的訪問中每一次“1”的位置都會移動一個比特,看起來好像是“1”在總線上走。而走“0”測試只是把測試的數據反了一下,看起來就像是一個“0”在總線上走。
2.3.1 數據走比特
數據走比特測試的偽代碼如下:
bit_mask_value = 1;
for(number of valid data bits)
{
write bit_mask_value to memory;
readback the data and compared to written value;
inversed_bit_mask_value = bit inverse of bit_mask_value;
write inversed_bit_mask_value to memory;
readback the data and compared to written value;
bit_mask_value = bit_mask_value<<1; //bit walking
}
這個測試可以檢測數據比特粘連(bit-stuck)問題,更重要的是,它還可以檢測比特間串擾。如果比特之間存在串擾,而這個測試讓一個比特與所有其它比特都是相反的,那么其它比特對它的干擾會被最大化,從而讓問題暴露出來。
例如,如果
written value = 0x00000010, readback value = 0
written value = 0xFFFFFFEF, readback value = 0xFFFFFFFF
這往往說明比特4 被其它比特干擾。
這個算法既可以用來測試數據總線連接,也可以用于測試存儲器單元。當用于測試存儲器單元時則每一個存儲單元都需要走“1”走“0”,這將是最耗時的測試;而用于測試數據總線連接時,只需要走一遍“1”,再走一遍“0”就可以了(地址不限)。
2.3.2 地址線走比特
地址走比特用于測試地址總線的連接。地址線走比特測試的偽代碼如下:
Write 0 to first address;
Write 0xFFFFFFFF to last address;
bit_mask_value = 1;
for(number of valid address bits)
{
write bit_mask_value to address of bit_mask_value;
readback the data at first address and compare to 0;
inversed_bit_mask_value = bit inverse of bit_mask_value;
write inversed_bit_mask_value to address of inversed_bit_mask_value;
readback the data at last address and compare to 0xFFFFFFFF;
bit_mask_value = bit_mask_value<<1; //bit walking
}
和數據走比特類似,這個測試既可以檢測地址比特粘連(bit-stuck)問題,還可以檢測地址比特間串擾。
例如,如果
written value = 16 at address 16
readback value = 16 at address 0
written value = 0xFFFFFFEF at address 0xFFFFFFEF
readback value = 0xFFFFFFEF at address 0xFFFFFFFF
測試中,想要寫往地址16 的數據實際被寫到地址0;而想要寫往地址0xFFFFFFEF 的數據實際被寫到最后一個地址單元。這往往說明地址比特4 被其它比特干擾。
2.4 浮動總線問題
如果測試軟件寫入并很快從相同地址讀出一個值的時候,如果數據線上存在電容特性,寫操作會給數據線上的電容充電,總線會短暫的保持它的狀態。當測試軟件讀操作時,總線會返回剛寫入的值,即使實際上該數據并沒有正確地被寫入存儲單元。這就是浮動總線(floating buses)問題。
浮動總線可能會“欺騙”簡單的測試程序,為了規避浮動總線問題,需要在緊鄰的對相同地址的寫和讀操作之間對其它地址寫入一個和原來寫的數據相反的數據。例如,
write A to address X;
write inversion of A to address Y;
read value from address X;
這樣,浮動總線的問題就可以規避了。
2.5 測試結果的深入分析
從存儲器測試結果的初步分析中,如果我們發現比特粘連或干擾,還需要進一步深入分析原因。通常原因可能來自于三方面:
1. 對于外接存儲器,PCB 出問題的可能性比較大。最常見的包括焊接問題或設計問題。例如,某個比特被短接到電源或地。通常我們可以用萬用表測量信號線之間或信號線和電源或地之間的阻抗來定位這種問題。串擾問題的定位則比較復雜,可能需要用示波器來測試所有相關的信號來確定串擾源。
2. 存儲單元失效。如果是外接存儲器,我們可以用示波器或邏輯分析儀在總線上監測寫入和讀出的數據,如果總線上監測到的寫數據是對的,而讀出的數據是錯的,則往往是存儲單元失效。
3. 存儲控制器失效。如果我們排除了以上問題而懷疑存儲控制器時,可以把好的板子和壞的板子上的控制器互換,如果問題跟著控制器走,則往往說明是控制器失效。
本文選自電子發燒友網6月《智能工業特刊》Change The World欄目,轉載請注明出處!
3 存儲器測試覆蓋率
完善的存儲器測試應該涵蓋:
·系統中所有的存儲器
·所有可以訪問存儲器的模塊,包括DSP 核和DMA 傳輸控制器
·所有不同的訪問路徑
3.1 用不同的主模塊測試
如圖1 所示,主要有三個主模塊可以訪問存儲器:
·DSP 核可以訪問所有存儲器
·EDMA 可以訪問所有存儲器
·IDMA 只可以訪問每個核本地的L1 和L2 存儲器
理論上,我們應該用所有的主模塊測試所有可訪問的存儲器,但這樣有太多組合,很多重復的測試可能浪費很多時間。所以,測試的組合需要被優化,既保證所有主模塊和存儲器都被覆蓋,又要避免無用的重復測試。
通常DMA 訪問存儲器的效率比DSP 核高很多,所以,對外部大存儲器的測試優先采用EDMA。
用DMA 測試存儲器是,我們需要一個額外的緩沖區 (buffer),測試流程如下:
DSP core wirtes test data to the DMA buffer
DMA copy the contents of the DMA buffer to the memory under test
DMA copy the contents of the memory under test back to the DMA buffer
DSP core reads the contents in DMA buffer and compare to expected value.
通常,用于DMA 測試的緩沖區是一個位于L2 中的比較小的緩沖區,而被測試的存儲器往往要大得多,所以上述測試流程需要被重復很多遍才能完成對整個存儲器的測試。
EDMA 有多個傳輸控制器,它們可以被交替使用來保證它們都被用到。例如,我們可以用EDMATC1 來填充并回讀第一組數據,然后用EDMA TC2 來填充并回讀第二組數據…
請注意,在多核DSP 中,EDMA 必須用全局地址來訪問L1 和LL2 存儲器。
3.2 測試系統中所有的存儲器
如圖1 所示,Keystone 系統中主要有4 種類型的存儲器,它們都應該被測試到。
3.2.1 內部L1 存儲器
通常,我們建議用IDMA 測試內部L1 存儲器。測試前,L1 存儲器應該被配置成普通存儲器而不是cache。
DSP 核可以測試本核的L1D 存儲器,但DSP 核不能測試本核的L1P 存儲器。
在多核DSP 上,如果我們想在一個核上運行程序來測試另一個核的L1 存儲器,我們應該用EDMA 而不能用IDMA,因為IDMA 只能訪問本核的存儲器。在對其它核的存儲器測試時,其它核不能運行程序。
3.2.2 內部LL2 存儲器
LL2 可以被系統中所有的主模塊測試。根據通常的使用情況,我們可以用DSP 核和EDMA 來測試本地LL2 存儲器。
通常,存儲器測試代碼和數據緩沖區都在本地LL2 存儲器。所以,測試程序應該檢測被測試代碼和測試緩沖區占用的空間大小,而僅對剩下的空閑空間進行測試。
盡管被測試代碼和測試緩沖區占用的存儲區沒有被嚴格的測試算法測試,通常,如果這個區域有問題,測試程序往往會失敗。所以,從一定程度上說,這塊存儲器也是被覆蓋了的。如果真的需要用嚴格的測試算法來測試所有的空間的話,我們需要兩個測試程序,一個測試程序占用存儲器前半部分,而測試后半部分;另一個測試程序占用存儲器后半部分,而測試前半部分。
在多核DSP 上,如果我們想在一個核上運行程序來測試另一個核的LL2 存儲器,EDMA 和DSP核都可以用來做測試。在對其它核的存儲器測試時,其它核不能運行程序。
3.2.3 內部共享SL2 存儲器
每個DSP 核和DMA 都有單獨的總線訪問共享SL2 存儲器,測試應該涵蓋每條總線,通過每個DSP 核和DMA 來測試SL2 存儲器。
DSP 核通過缺省地址空間(從0x0C000000 開始)訪問SL2 會經過cache 和prefetch buffer。要繞過cache 和prefetch buffer 訪問SL2,必須把SL2 重新映射到其它地址空間,并把這個地址空間設置(通過MAR 寄存器)成不可cache,不可prefetch。測試應該涵蓋這兩種情況。
3.2.4 外部DDR 存儲器
外部DDR 在測試之前需要被正確配置。如果DDR 測試在某些板子上通過,而在另一些板子上失敗,可以嘗試放松一些DDR 的時序參數,如果這樣能讓測試通過則往往說明DDR 接口存在時序問題。
DSP 核和EDMA 都應該被用來測試DDR 存儲器。而對DSP 核的測試,既需要測試通過cache訪問的情況,也需要測試沒有cache 的情況。
DDR 最大可以有8GB,對所有DDR 存儲單元的測試會消耗大量測試時間。因為EDMA 訪問效率最高,所以我們可以用EDMA 來做DDR 全空間測試。對其它主模塊,如DSP 核,我們不需要用它來訪問整個DDR 空間,只需要測試比較小的空間就可以了,目的只是要覆蓋從這個主模塊到DDR 的數據路徑,而DDR 存儲單元已經被EDMA 完整的測過了。例如,測試DSP 核通過L2cache 訪問DDR,我們只需要測試比L2 cache 大的DDR 空間就可以了,這樣就覆蓋了數據路徑和L2 cache。
本文選自電子發燒友網6月《智能工業特刊》Change The World欄目,轉載請注明出處!
3.3 通過不同數據路徑測試
由于不同的主模塊有自己的總線,同一存儲器可以被不同的主模塊從不同的數據路徑訪問。例如,DSP 核和EDMA 通過不同的數據路徑訪問LL2。
另外,同一主模塊也可以通過不同的數據路徑訪問同一存儲器。例如,DSP 核可以通過cache 或不通過cache 訪問DDR 存儲器。
所有這些不同的數據訪問路徑都應該被測試程序覆蓋。
4 KeyStone DSP 上的示例測試工程
本節介紹上述測試方法在KeyStone DSP 上實現的例子。相應的測試代碼可以從以下網址獲得:
http://www.deyisupport.com/cfs-file.ashx/__key/telligent-evolution-components-attachments/00-53-01-00-00-10-90-46/Memory_5F00_Test.zip
4.1 CCS 工程
例子工程的目錄結構如圖2 所示。
圖2 例子工程目錄結構
工程文件在“Memory_Test”目錄中。一些通用的初始化代碼,如PLL, EDMA, DDR 的初始化在“common”目錄中。主要的測試代碼在“Memory_Testsrc”子目錄中。表2 描述了主要的源文件。
表2 例子代碼的源文件
測試流程由“mem_test_main.c”中的代碼控制。基本流程如下:
Disable all caches
Test LL2 bus
Test SL2 bus
Test DDR bus
Test Local L1 with IDMA
Test other core’s L1 with EDMA
Enable 32KB L1P cache
Test Local L2 with DSP core
Test other core’s L2 with DSP core
Test Shared L2 with DSP core
Test 1KB of external memory with DSP core (just cover the data path)
Enable 32KB L1D cache
Test Local L2 with EDMA
Test Local L2 with DSP core
Test other core’s L2 with EDMA
Test other core’s L2 with DSP core
Test Shared L2 with EDMA
Test Shared L2 with DSP core
Test external memory with EDMA (cover full external memory space)
Test 64KB of external memory with DSP core (just cover the data path and L1D cache)
Enable 256KB L2 cache
Test other core’s L2 with DSP core
Test 512KB external memory with DSP core (just cover the data path and L1D, L2 caches)
Test Shared L2 with DSP core through remmapped noncacheable nonprefetchable window
本文選自電子發燒友網6月《智能工業特刊》Change The World欄目,轉載請注明出處!
4.2 測試配置
測試代碼中有多個宏參數可以用來對測試進行配置。
數據測試填充的數值在“DSP_core_mem_test.c”中定義如下。用戶可以在這里添加,刪除或修改填充的數值。
unsigned long long ulDataPatternTable[ ] = {
0x0000000000000000,
0xffffffffffffffff,
0xaaaaaaaaaaaaaaaa,
0x5555555555555555,
0xcccccccccccccccc,
0x3333333333333333,
0xf0f0f0f0f0f0f0f0,
0x0f0f0f0f0f0f0f0f,
0xff00ff00ff00ff00,
0x00ff00ff00ff00ff
};
本文介紹的三個主要測試算法可以通用以下在“DSP_core_mem_test.c”和“DMA_mem_test.c”中定義的宏開關使能或禁用。“1”表示使能,“0”表示禁用。
#define BIT_PATTERN_FILLING_TEST 1
#define ADDRESS_TEST 1
#define BIT_WALKING_TEST 1
每個存儲器都可以通過“KeyStone_mem_test_main.c”中定義的宏開關控制是否被測試。
#define LL1_MEM_TEST 1
#define OTHER_L1_TEST 1
#define LL2_MEM_TEST 1
#define OTHER_L2_TEST 1
#define SL2_MEM_TEST 1
#define EXTERNAL_MEM_TEST 1
是否用DSP 和或DMA 測試存儲器也可以通過“KeyStone_mem_test_main.c”中定義的宏開關控制。
#define TEST_BY_DSP_CORE 1
#define TEST_BY_DMA 1
這個測試工程是在TI 的評估板上實現的。如果要在用戶真實的板子上運行,需要根據板子的設計在“KeyStone_DDR_Init.c”中修改相應的DDR 參數。PLL 倍頻系數也可能需要在調用KeyStone_main_PLL_init()的代碼中修改。
要讓這些修改后的配置生效,測試工程必須被重新編譯。由于測試工程用到了CSL (Chip SupportLibrary)中的頭文件,在重編之前可能還需要重新指定CSL 的包含路徑。
4.3 測試時間
測試花的時間主要取決于存儲器大小,DSP 和存儲器速度。表3 列出了本文介紹的所有存儲器測試在TI 的評估板(EVM)上測試所花的時間。
表3 在EVM 板上的測試時間
總線測試花的時間只有幾百微秒,而存儲單元全空間測試花的時間很多。其中,超過90%的時間都花在對DDR 的測試上。
對存儲單元的數據測試,地址測試,和走比特測試所花的時間的比例大概是10:1:64,因為數據測試寫讀了10 個不同的值,地址測試寫讀了1 個值,而走比特測試寫讀了64 個值。
用戶可以根據測試時間的要求選用不同的測試用例。一般可能有三種組合:
1. 用毫秒級的時間做簡單快速的總線測試。
2. 用秒級時間做全存儲器空間的基本測試。測試用例包括總線測試和地址測試。
3. 用幾分鐘甚至幾十分鐘做全存儲器空間的完善測試,執行本文介紹的所有測試用例。
本文選自電子發燒友網6月《智能工業特刊》Change The World欄目,轉載請注明出處!
?
評論