2011年2月28日 星期一

Multi Arm - 哲榮

-------------------------------------
2011.02.28
-------------------------------------
1.
原本DPSRAM在CPU端與FPGA端的Memory map空間是同一塊,但是有byte addressing與word addressing的差異
但是依照上述方式測試時有錯,後來發現在Driver中已經先行把輸入的address*2
使的FPGA端與CPU端的都是以word addressing的方式存取DPSRAM

2.
測試並確定
FPGA的4 bit address (0x0~0xF) 對應到CPU的address為(0x180~0x18F)

3.
DPSRAM Interface電路完成但尚未測試完全

-------------------------------------
2011.02.19
-------------------------------------
MVC100透過IDE HDD與FPGA進行溝通
溝通方式是在MVC100版子有塊Dual Port SRAM(DPSRAM)
CPU跟FPGA皆可以存取此塊DPSRAM再加上介面提供的Interrupt機制
CPU與FPGA便可以透過DPSRAM交換資料

但是交換資料的協定必須要自己設計
目前的規劃是以CPU主動下命令給FPGA
CPU把read / write command、address、size寫入到DPSRAM上,並且發出interrupt給FPGA
FPGA收到interrupt後,便讀取DPSRAM上的命令,依據讀取到的命令做動作:

1. CPU發出Read指令 :
FPGA將CPU要讀取的資料寫入到DPSRAM上,並且發出Interrupt給CPU來讀取

2. CPU發出Write指令:
FPGA等待第二次CPU發出的interrupt通知 (第一次interrupt是Read/Write命令)
收到Interrupt,便讀取DPSRAM上的data,並寫入到FPGA的SRAM

目前正在以上述的協定改電路以及Driver





-------------------------------------
2011.01.23
-------------------------------------
因為目前MVC100的板子還在測試
因此士敦學長希望可以試著在friendly arm上跑MPI測試
但由於需要額外安裝MPI所需的物件 如:python、ssh
再加上士敦學長使用的arm-linux-gcc版本不同
因此需要重編他修改過的MPI
後來直接借他一顆friendly arm移植MPI

MVC100目前已經可以跑一輝學長的sram與fpga溝通範例
OS: linux2.6.28 (沒有android)
因為排線目前只接出部分sram的address與data腳位
只能使用4個bit address[3:0]、data[3:0]
範例執行結果:













接下來會試著修改driver以及範例電路為我的InterConnect架構


-------------------------------------
2011.01.17
-------------------------------------
Friendly arm已經把傳輸的protocol寫入到driver
並且也已經改成士敦學長的架構 (每個connection對應一個file descriptor)
剩下system call poll()還沒有實做

MVC100用廠商附的linux 2.6.28加上driver編譯完成
但是廠商附得file system是read-only的,所以在開機完後drvier掛不上去
這部份文森學長還要花點時間幫忙
所以就先換跑android版本的範例,但是一輝學長給的kernel image在開機的時候會有kernel panic的問題,我會再去問一下或者我目前有也有重編的android版本的linux kernel(2.6.27)再測看看


-------------------------------------
2011.01.10
-------------------------------------
friendly arm更改linux char driver的kernel function
原先使用memcpy()去存取fpga對應的virtual address
改成宗胤學長建議的ioread() , iowrite()
發現read指令的CS , OE訊號會有兩個low trigger的情況 沒有了

把呼叫driver的file descriptor函式換成linux system call
int open(const char *pathname, int flags)
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
不使用c lib提供的fopen fread fwrite
就會解決driver command延遲的問題

mvc100目前正試著執行一輝學長的範例
目前順利編譯好linux kernel 2.6.28
但是開機後掛載driver的步驟還有問題 要再請教一下學長


-------------------------------------
2010.12.29
-------------------------------------
搞定第三顆ARM了 (把sdcard的資料刪一刪後就又可以使用了)
另外還有跟士敦學長討論MPICH2 Multi-Arm driver的部分
因為學長目前的架構是每個connection各有一個file descriptor負責處理傳輸
如下圖























因此使用者呼叫Driver時不需要給driver 目的ARM對應的memory map addr
driver自行根據fd的minor number判斷目的ARM的memory map addr
呼叫driver的方式使用linux system call :
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);


而我目前的架構是一個file descriptor負責所有的connection傳輸
如下圖




















因此使用者呼叫Driver時要給driver 目的ARM對應的memory map addr
呼叫driver的方式使用C Lib的:
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );


目前會再做一版driver配合MPICH2的修改
還有跟文森學長借MVC100測一下InterConnect Circuit、Driver、EBI...


-------------------------------------
2010.12.20
-------------------------------------
Driver裡的read , write函式
write(struct file *filp, const char *buff, size_t count, loff_t *offp)
read(struct file *filp, char *buff, size_t count, loff_t *offp)
其中count可以拿到使用者API要存取的總size大小 bytes
例:
fwrite(DataBuf , size , cnt , fd);
則driver裡收到的count大小為 size * cnt (單位bytes)

並且測試後發現說fwrite(DataBuf , size , cnt , fd);
cnt並不能決定write(struct file *filp, const char *buff, size_t count, loff_t *offp)被呼叫的次數
是write()的return值決定呼叫次數
例:
fwrite(DataBuf , size=1 , cnt=10 , fd); //總共10 bytes資料要寫入
write(struct file *filp, const char *buff, size_t count, loff_t *offp)
{
...
return 5; //假設每次呼叫都只寫入5 bytes
}
則OS會去呼叫write()兩次來符合總大小10 bytes

因此做過一個測試就是故意讓write()只return 0;
發現write()函式會一直被呼叫

但是read(struct file *filp, char *buff, size_t count, loff_t *offp)
不論fread(DataBuf , size , cnt , fd); 的 size * cnt 值為多少
count的值始終是4096
在無法得知總bytes的情況下,我改成從FPGA上的PacketSize取得要讀取的總bytes

歸納一下目前做的
1. write(struct file *filp, const char *buff, size_t count, loff_t *offp)
a . OS會一直呼叫write()直到return value總合等於API要求的大小
b . 測試發現不能寫成只呼叫一次write()就把所有資料(比如10bytes)寫到FPGA電路上
假設呼叫write()一次,寫8 bytes,則只有前2 bytes被寫出去
所以後來寫成每次呼叫只寫2 bytes
c . blocking , 直到寫完API要求的大小才停止

2. read(struct file *filp, const char *buff, size_t count, loff_t *offp)
a . OS同樣會一直呼叫read()直到return value總合等於API要求的大小
但是在return value總和還沒達到API要求的大小時 , 出現return 0
則OS不會再繼續呼叫read()並且fread()的return size為目前的總bytes(不一定等於API要求的大
小)
但是write()並不會因為有return 0出現,OS就停止呼叫write()
而是會繼續呼叫write()直到return值符合為止
b . read()可以一次呼叫就把所有的資料讀進來
假設呼叫read()一次,讀10 bytes,可以正常讀取
因此read()我實作成呼叫一次就讀完8 bytes(看API層要求的大小決定)資料
c . blocking , 直到讀完API要求的大小才停止

但是寫完上述的driver function
發現在每次讀寫memory前,必須先去檢查PacketSize的值的動作會有錯誤
(PacketSize就是記錄目前這塊memory裡面有多少bytes的資料)
原因是因為driver command延遲的問題
driver呼叫write()後memory bus應該要馬上有訊號發出
但是mini2440的卻會延遲直到read()被呼叫後memory bus才發出write()的訊號
但是write()的實作動作為 , 寫memory前要先檢查PacketSize是否為0
否則就要block , 等待PacketSize = 0時才可以做寫入的動作
但是延遲的關係 , 當下抓到的PacketSize值並不是memory bus有動作所抓到的值
例:
fwrite(); //block在迴圈裡 一直檢察PacketSize
fread(); //memory bus的訊號發出write()的訊號
如上 PacketSize的值並不是實際電路上的PacketSize值
而且也無法抓到 因為block住的關係 fread()無法被呼叫

同樣read()也有此問題


-------------------------------------
2010.12.13
-------------------------------------
跟楊老師實驗室借了兩條USB轉RS232,目前可以看到同時執行的過程
所以直接開始改driver,把傳輸的protocal寫在driver裡面
以及實做Send()和Receive()兩個API函式 作為之後SPCI使用的傳輸函式

目前driver的write function可以正常執行
但是read function從OS收到的傳輸byte數的值還有問題 還在找是什麼原因

另外還有發現先前memory bus的address 0不能用的問題
並不是不能用 是因為bus沒有byte enable的控制
因此一次傳輸一定是2 bytes的data (16 bit)
因此要寫奇數的address時,bus會從address-1 寫16 bits

然而那時後的誤認,把address先往左shift 1位 (乘2)
然後在電路裡面再取addr[6:1]來使用
讓原本是byte addressing的mini2440變成是word addressing
如下所示

原先:
11111111 0x00
11111111 0x01
11111111 0x02
11111111 0x03

*2後,並且只取addr[6:1]作為address:
11111111 11111111 0x00
11111111 11111111 0x01

目前就先不修改這部份




-------------------------------------
2010.12.02
-------------------------------------
測試過後發現是V4 FPGA的 GPIO有問題 (J2.8 botton )
J2.8 botton剛好接到friendly arm2的CS pin
目前把ARM2移到J1 botton的位置
目前三顆可以正常存取FPGA上的memory

接下來會開始測大量資料的傳輸

-------------------------------------
2010.11.28
-------------------------------------
兩顆friendly arm接上fpga的GPIO了
兩顆分別測試存取InterConnect的ram可以正常存取
但是還沒有測同時跑的狀況 , 因為只PC有一條com port...
我會再寫個java層的ap去call linux driver
直接在LCD上操作來測試兩顆ARM同時跑的情況
沒問題就繼續接第三顆


-------------------------------------
2010.11.25
-------------------------------------
因為在連續讀取多筆資料時產生錯誤
後來實際去看邏輯分析儀發現讀取多筆資料時
每次的讀取訊號之間會夾雜一個單一的CS和OE的low trigger
如圖所示 : 這是連續讀兩筆的訊號







紅色框圈出來的就是夾雜的訊號
紅色框的部分系統總線給的address並不是driver所下的address
並且在這段時間任意給系統總線data值也不會影響driver實際讀到的值

實際在測時發現紅色框的訊號有時不會出現= ="
原因不明...

因此我的fifo的架構抓不準何時該讀出資料
若要解決需要改很滿多地方...
後來就還是換回用ram當儲存空間的InterConnect circuit
arm與arm之間交換資料的ram的大小為 16bit data , 0~4 address


-------------------------------------
2010.11.09
-------------------------------------
測試我的InterConnect circuit正確性
InterConnect circuit的memory用的是Xilinx ip gen產生的fifo (16bit data , 0~1024 address)
目前可以正常執行單筆資料(16bit data)的讀和寫
(friendly arm以word address來看,單一address有16bit的資料)

memory map的部分又有再更動 , 因為Friendly arm的系統總線提供的address pin
LADDR24 – not continue
LADDR0 - specific capability 要使用的話必須再去更改driver的設定 詳細我沒有去探究
總之就只剩LADDR1~LADDR6 可以用 因此調整packet size從2個word改成1個word
(1 word = 16 bit)


說明一下系統總線的存取memory的時脈波形圖
以SMIMS USB在使用的APP_CLK (48Hz)為InterConnect circuit的clk

Write :









當CS和WE為low trigger時
大約在第四個clock 系統總線Data和Address Pin的值才會開始是正確的
因此我的做法是在第四個clock去抓正確的address和data
第五個clock才把我電路fifo的write enable拉起來寫入值

Read :









當CS和OE為low trigger時
大約在第五個clock 必須把正確的data值給系統總線讀取
因此我的做法是在第三個clock去抓要讀取的address 並且把fifo的read enable拉起來
讓fifo能夠在第四個clock讀出值並在第五個clock把值給系統總線

要注意的是系統總線發出的單筆16bit的read訊號會有兩個low trigger
原先北翰的範例使用ram當儲存空間時,這兩個low trigger的讀取並不會改變ram裡面的值
但是我的InterConnect是使用fifo,因此再遇到這兩個low trigger時會讀出連續兩個address的值
並且由於是fifo,讀出的資料便會從fifo消失 因此會有問題

我的解決辦法是只再第一個low trigger時才去讀取fifo的值
並且把讀出來的值存再flip flop中維持兩個low trigger的時間
(因為兩個low trigger都要提供系統總線一樣的值,否則friendly arm讀到的值會不完整)


電路圖因為放上來有點模糊
參考投影片的82,83頁


-------------------------------------
2010.10.27
-------------------------------------
成功把北翰公司提供的範例跑起來了

範例是Friendly ARM透過系統總線(com)以排線與Xilinx V4 FPGA版的GPIO相接
fpga上的電路組成是一個state machine與一塊的 ram(16bit data , 10 bit address)
不過因為系統總線的address pin只能夠使用6 bit,因此fpga上的memory只有使用address;0~63
Friendly ARM上boot android並且在linux kernel新增driver來存取fpga上的ram
此外還有bcb實作的ui可以透過usb顯示fpga上ram的每個address的值
但是此ui在執行open實會將範例電路的bit檔燒進fpga,我又懶的再去裝bcb去改code後來就直接在friednly arm上呼叫driver去驗證ram上的值是否正確

範例發現三個問題:
1. 讀取memory的值時一些address會讀到不是我剛剛寫入的值
已解決--->因為read的時脈沒有對準,以APP_CLK為基準大約在第四個clock,friendly arm才會讀取ram的值

2. CS、OE、WE會有雜訊出現
減少雜訊--->用一個clock generator產生一個較快的時脈去過濾訊號,讓雜訊持續的時間不到一個clock

3. 對driver下的read和write指令會延遲到下一個指令系統總線才會發出訊號
比如說下兩個指令
fwrite(Buffer , 1 , DataSize , fp);
fread(...);
則在fwrite當下 系統總線並不會發出寫入ram的訊號
此訊號會在fread當下才發出
而fread的訊號只會在fwrite之後才會發出
像這個例子就是會在fread時系統總線連續發出兩個指令 : 寫入 讀取

而當連續下fread指令時只有第一個接在fwrite後的fread系統總現有讀取訊號發出
如: fwrite fread fread fread... 只有第一個fread的訊號有效

找不到原因 因此在使用driver時必須讓read write交錯呼叫才能正常運作


-------------------------------------
2010.06.18
-------------------------------------
完成SystemC model與四個Qemu相接的模擬器
其架構圖如下


















使用宗胤學長修改的android QEMU
其QEMU能透過driver去存取PC上的Posix Shared Memory
利用此功能,我再寫了四個wrapper SystemC model負責把Shared Memory的資料傳給InterConndet Module以及把InterConndet Module要丟給QEMU的資料寫入到Shared Memory

實作兩個傳輸使用的C++ API :
Void Multi_ARM_Send(int CoreID , char* Buf , int DataSize);
CoreID : 目的地ARM的ID
Buf : Data buffer
DataSize : 欲傳輸的資料大小( bytes )

Int Multi_ARM_Receive(int SourceID , int Total_Size);
SourceID : 來源ARM的ID
Total_Size : 欲接收的資料大小( bytes ) ,必須收滿Total_Size此函式才會return
Return int : 實際接收的資料大小 ( bytes )

上述兩個API會去呼叫底層的driver完成傳輸的動作
若fpga上的傳輸空間尚有資料無法寫入或者沒有資料可以讀取------------(a)
此兩個api便會以blocking的方式等待,直到空間空出來
不過後來跟張老師LAB討論過之後這兩個API會拿掉,把傳輸的動作移到driver裡
並且若發生(a)的狀況,直接return 不等待 回傳實際寫入、讀取的資料大小
以(a)的狀況而言回傳的值為 0


-------------------------------------
2010.06.02
-------------------------------------
因為考慮到每顆ARM只有接Addr、Data、control signal到傳輸會用到的Sram上
整個memory map的大小是16KB,但是實際可以存取的只有7KB
我想把空下來沒用到的memory map拿掉

比如說
Arm0所能看到的memory map 為0x4000~0x7FFF
但是Arm0實際硬體有接線的addr為
0x4000~0x4FFF : 4KB
0x5000~0x53FF : 1KB
0x6000~0x63FF : 1KB
0x7000~0x73FF : 1KB
其它硬體沒有接線的addr且Driver必須限制不能存取的addr共有9KB

我的想法是既然只有接線到部分的sram
那沒接線的sram就不要配入Memory map裡面
所以讓每個Arm看到的Memory map都一樣而且只有8KB
比如說
Arm0所能看到的memory map 為0x1000~0x2FFF,共有8KB
[只能Write的部分]
0x1000~0x13FF : 要傳給Arm0的資料 (1KB)
0x1400~0x17FF : 要傳給Arm1的資料 (1KB)
0x1800~0x1BFF : 要傳給Arm2的資料 (1KB)
0x1C00~0x1FFF : 要傳給Arm3的資料 (1KB)

[只能Read的部分]
0x2000~0x23FF : 收來自Arm0的資料 (1KB)
0x2400~0x27FF : 收來自Arm1的資料 (1KB)
0x2800~0x2BFF : 收來自Arm2的資料 (1KB)
0x2C00~0x2FFF : 收來自Arm3的資料 (1KB)

其中0x1000~0x13FF、0x2000~0x23FF對Arm0的實際硬體來說是同一塊Sram
如下圖所示




這張圖是Arm0的memory map所對應的實際硬體
每個長方型都是一個實體的sram
裡面的兩個數字是 起始Addr 與 結束Addr
有數字的部分就是Arm0實際有接線的sram
其中左上角那塊有重複的Addr (0x1000~0x13FF 和 0x2000~0x2FF)
因為這塊是屬於Arm0丟資料給Arm0的區塊
這部分我希望直接在Driver中做判斷,假如是要丟資料給本身
即不經過硬體做資料交換,直接丟給Arm0的local memory
然後發個Interrupt告訴自己有資料進入



下面這張圖則是Arm1的memory map實際對應的硬體
Arm1同樣的也是看到8KB的Memory Map且Memory Map跟其他Arm都一樣
只是接到不同的實體Sram
[只能Write的部分]
0x1000~0x13FF : 要傳給Arm0的資料 (1KB)
0x1400~0x17FF : 要傳給Arm1的資料 (1KB)
0x1800~0x1BFF : 要傳給Arm2的資料 (1KB)
0x1C00~0x1FFF : 要傳給Arm3的資料 (1KB)

[只能Read的部分]
0x2000~0x23FF : 收來自Arm0的資料 (1KB)
0x2400~0x27FF : 收來自Arm1的資料 (1KB)
0x2800~0x2BFF : 收來自Arm2的資料 (1KB)
0x2C00~0x2FFF : 收來自Arm3的資料 (1KB)
同樣的也是會有一塊Sram是屬於丟資料給自身的部分
也就是0x1400~0x17FF、0x2400~0x27FF






下圖是Arm2的Memory對應到的實際Sram
同樣的也是會有一塊Sram是屬於丟資料給自身的部分
也就是0x1800~0x1BFF、0x2800~0x2BFF




下圖是Arm3的Memory對應到的實際Sram
同樣的也是會有一塊Sram是屬於丟資料給自身的部分
也就是0x1C00~0x1FFF 、0x2C00~0x2FFF





而上面四張圖合起來就是整個實際16塊Sram的架構
也就是說每顆Arm所能看到的Memory Map都一樣
但不一定接線到相同的實際Sram上

這樣一來Memory Map就只有8KB的大小
不會有Access到不屬於傳輸所允許的Addr
只需要判斷Addr是否在這8KB的範圍內

目前正在進行的工作:
1.SystemC model與四個Qemu相接(給張老師LAB測試修改的MPI)

2.Friendly Arm(mini2440)與FPGA(v4)相接

3.如果確定架構沒問題就開始寫Verilog



------------------------------------
2010.05.19
-------------------------------------
由於後來發現S5PC100的SRAM Controller最多只能控制6塊SRAM
所以後來把FPGA上的16塊SRAM改成四塊
第1塊SRAM (最上方) 是儲存Arm0要Send給其他Arm的資料
第2塊SRAM (下一塊) 是儲存Arm1要Send給其他Arm的資料
....以此類推


每一塊SRAM的第0KB~(1KB-1bit)的資料是儲存Arm0要Receive來自其他Arm的資料
每一塊SRAM的第1KB~(2KB-1bit)的資料是儲存Arm1要Receive來自其他Arm的資料
...以此類推

即是比照之前的Memory Map,只把之前16塊SRAM的每一個橫排併起來成一塊

















但是這樣的架構會在多個Arm同時Read同一塊Memory時出問題
之前會切成16塊SRAM就是為了解決同時Read Write的問題


後來品皓有個點子,如果讓Arm以為只有4塊SRAM
但是實際電路上是有16塊SRAM這樣或許可以維持原來的16塊的架構
而且原本是預計每顆Arm都可以Access到這16塊SRAM
但是這樣每個Arm就都必須拉線到16個SRAM上這樣之後Layou可能面積會很大
所以打算每個Arm都只拉線到傳輸會用到的SRAM上
但是Arm本身的Memory Map還是會保留沒有用到的Address

所以就改成以下架構:























1. Tag的更動
由於Xillinx V4的Block Memory支援Dual port(Write的同時也可Read)
所以原本用來仲裁"Write的同時是否可Read"的Tag就不需要了(原本有定memory map且用register實做)
原本Tag還有紀錄SRAM中的Data Size的功能和做為判斷SRAM是否有資料,來控制Read/Write是否允許
所以改成每個SRAM的起始4Byte作為儲存Data Size的空間,取代原本的Tag

然後Tag也作為是否該發出Interrupt通知Arm來讀取資料的依據
現在改為用Adddr以及Data值來判斷(假如Addr為Data Size的位址且Data不為0則發出Interrupt)

2. 只接線到傳輸相關的SRAM
如上圖所示
Arm0只接線到第一欄和第一列
然後透過Addr某幾個bit和CSn作為SRAM Enable的依據
這樣即使Arm0的程式寫資料到不正確的Addr
在實際電路上依然會寫在第一欄和第一列的範圍內

3. 實際有16塊SRAM,但每顆Arm以為只有1塊
Arm的SRAM controller會接出CS[0:5]做為每塊SRAM的Enable
以Arm0的觀點來看只有一顆SRAM
所以CS只會用到CS0

透過判斷Addr線、Write Enable、Output Enable , 連到不同的SRAM上

4. Initial Tag

因為本來儲存Size的Tag換成在SRAM中(原本是Register),因此需要初始化
所以我希望在每顆Arm boot好OS之後必須去把Size初始化為0
每顆Arm各自去把儲存Send資料的SRAM的Size部分歸零,然後才把Initial Tag設為1
再確認每個Initial Tag皆為1後才開始進行資料傳輸

[這邊有個問題]
就是每次Send資料時都需要去確認Initial Tag嗎?
如果確認Initial Tag是為了要確定目的Arm是否存活
但是一顆無法執行的Arm,無法去修改對應的Initial Tag,就無法判斷目的Arm是否仍然存活



------------------------------------
2010.04.07
-------------------------------------
之前定的memory map
因為要把儲存資料大小的單位換成byte比較直覺
所以重訂了一下Tag的部分(Packet Size)






Initial : 每個欄位1byte







Packet Size : 每個欄位4byte























Memory Space(Receive data from Arm) : 每個欄位 1 K byte






















-------------------------------------
2010.03.29
-------------------------------------
原本為了方便替EBI BUS加Driver
就把MVC100重新PO上linux

後來板子先借給文森學長
要先測山寨機的Android AP能不能在MVC100上跑
所以我又重PO了Android上去

可是新PO的Android螢幕左下角還是一樣會顯示Safe mode
不知道是廠商提供的Android kernel本來就是safe mode,要自己另外抓
還是其它問題,目前還在找




-------------------------------------
2010.03.11
-------------------------------------
Memory Map的部分暫定如下
Initial有四個byte 0x00~0x03分別用來儲存四個Arm是否initial完成
Tag To ArmX為就是架構圖裡面的16個Tag紅色區塊
ArmX Receive為架構圖中 , 每個Arm底下的四塊Memory

































































































-------------------------------------
2010.03.09
-------------------------------------
目的在於把四顆Arm透過FPGA上的Memory來進行溝通

1 . 架構

[架構圖]















如架構圖所示,每個Arm透過Memory Bus連接FPGA上的16塊memory
透過這16塊memory進行Arm之間的資料溝通
每個Arm下方的四塊memory是用來接收來自其它Arm的資料
比如Arm0下方的四塊memory , From Arm2這塊memory即是用來儲存來自Arm2的資料

每個Arm都可以看到這16塊Memory以及其Tag

每塊memory的總大小為1k byte , 且各自有一塊專屬的Tag , 用來紀錄儲存在此memory中的資料大小 , 而當memory中沒有資料時 , Tag儲存的資料大小為0

Initial Tag為一個大小為1 byte的register , 共有四塊 , 用來記錄四個Arm的initial是否完成
而當四塊Initial Tag的直接為initial完成時 , 才能進行Arm之間的資料傳輸
每個Arm都可以存取到這四塊Initial Tag


2 . 傳輸方式

假如Arm0希望丟一筆資料到Arm1
Arm0必須先將資料丟到FPGA上Arm1底下的From Arm0的那塊memory
然後將From Arm0的Tag設為資料的大小
此時FPGA送出Interrupt訊號給Arm1 , 告知有資料進入memory中
Arm1再主動去FPGA中抓取來自Arm0的資料


3 . boot

單顆Arm的boot動作為:
Arm裡面有個Rom , 儲存一小支程式 , 這個小程式會去抓Flash的前幾個byte看看是否Flash中有合法的可執行程式 , 如果有的話就會把Flash中的資料抓進SDRAM中 , 然後Arm在去執行SDRAM中的程式 , 如果Flash中沒有程式 , Rom中的小程式變會換成等待USB傳送PC端的資料過來 , 然後將接收到的程式分入SDRAM中讓Arm去執行

但是這樣會有個疑問就是說 , 如果四個Arm只有第一顆Arm有Flash , 那其它三顆Arm的SDRAM該如何拿到boot所需的程式?


4 . initial

當四個Arm確定都boot完成後 , 便要開始去initial FPGA上每塊Memory的Tag , 每個Arm各自去initial對應的memory的Tag , initial完成後便將對應的Initial Tag值設為1 , 直到四塊Initial Tag全部的值皆為1時 , 才能開始進行資料傳輸


5 . Memory Bus

Memory Bus有三種訊號要輸入Address , Data , Control Signal


6. Arm資料傳輸Function

Receive(int SrcCoreID , int* Buf) : 用來接收來自SrcCoreID 的資料 , 用sc_event來等待interrupt
Send(int DesCoreID , int* Buf) : 傳送資料給DesCoreID


7. 目前工作

a. 定出每塊Arm的memory map
b. 完成SystemC model

16 則留言:

SCREAMLab 提到...

狠多事可以靠適當的定址來簡化, 但是問題是我們可能會在系統運作時去踩到某些不該踩的地方, 那要怎麼解決呢?

另外在FPGA端會接一個大一點DRAM, 那是所有Cores都可以直接access, 那麼同樣會打架的. 你在系統圖裡沒劃出來, 該怎麼做呢?

aaa要幫忙看一下, OK?

long 提到...

問了一下AAA
可能會去填寫page table
把FPGA上的memory addr加進去,讓MMU去管控

大一點的DRAM一次只能一個ARM進去讀寫
似乎不能對每一段addr做同步的控制

SCREAMLab 提到...

AAA and Long:

可否去看一下Freescale的IMX51 EVK.
同樣是ARM Cortex A8. 便宜多了. 假如有Extension Interface. 我想再買一片來比較. 目前我找不到S5PC100有代理商在賣晶片, 不過iMX51 Avent/digikey有賣. 當然了, 文件要齊全, 有schematic才可以.

星期一跟我說.

Zhong-Ho Chen 提到...

從IMX51的datasheet來看
有External Memory Interface (EMI)
可以接SRAM, NOR-Flash

從 IMX51 EVK的Schematic來看
從裡面可以看到有個52-Pin的Socket(J16)
可以從這邊外接Flash Memory
可以卻不是全部的EMI訊號
而且從圖片中卻看不到J16在哪邊?!

買不到S5PC100, 不過應該可以跟Microvision買CPU Moudle?

Wells Wang 提到...

FreeScale Support 其差無比...
而且 Audio Codec 及Power都要配合專用的IC..除非不需要SUPPORT ,,,,
不過有Android , WinCE 及LINUX BSP, ubuntu(只有IMAGE), ChromeOS support

SCREAMLab 提到...

Wells這樣講,看來我們這種學校單位,還是不要碰比較好,還有就是TI的Cortex你覺得如何呢?

我查了一下TI的網頁,純Cortex A8的3517沒有Inventory,連Sample都沒有。倒是OMAP3530有,可是3517有EVM,3530卻沒有 EVM,真是奇怪。沒有EVM可以先試一下,我是怕怕的。

Zhong-Ho Chen 提到...

既然只有一顆比較特別, 而且只用來Porting Android, 可以考慮不用Cortex A8?

Zhong-Ho Chen 提到...

AM3517有General Purpose Memory Controller(GPMC)
- 16-bit data bus
- 8 Chip Select with 128M-Byte

3517 EVM 有接GPMC出來,不過Address只有10-bit,接頭不常見

SCREAMLab 提到...

在看TI的原因是大陸那邊有找到人快出3530的板子了,而且不貴,晶片也可以買到。

OMAP3530多了一顆64X的DSP,現在看來暫時沒有用,Samsung有的他都有,還有賣CPU Module,720MHz,看來好像萬事俱備。

我還是繼續再問Samsung的A8。以防萬一。

SCREAMLab 提到...

目前確定用S5PC100,主板不在有Android的支援,以免太複雜,要接Android那顆的話目前決定用SOcket跟人家的板子接就好。

請Long花時間看一下MV的CPU Module的架構.

long 提到...

喔好我會去看CPU Module的架構

Zhong-Ho Chen 提到...

First of all, you must totally understand how ARM controls a RAM.
More specifically, you need to describe all signals of ARM that are used to control a RAM.
Our goal is to let the FPGA act as "a" RAM in the view of a ARM.
In your plan, you want to let the FPGA act as "four" RAMs? Does this make sense? Are there 4 memory ports in you SystemC model?
16 memory blocks are not equal to 16 SRAMs.

After I coming back, I should sit behind you every moment.

long 提到...

抱歉...
我疏忽了,我會再改

網路黑貓 提到...

好一陣子沒來看了, 其實如果考慮Cortex-A8 開發板,使用 OMAP 3530的 beagleboard 應該是首選, digikey 上也能訂購, 相關資源也很多.

SCREAMLab 提到...

採用Cortex有許多考量,這是目前最多產品會用的CPU,TI也有COrtex,但是不容易買。

提醒你一下,作一下測試,弄清楚是Cable, 2440還是你的電路作怪。

long 提到...

有測了
目前三顆可以動了