mcu+cpld 聯(lián)合編程(概念及流程)
在使用mcu+cpld聯(lián)合編程之前,請(qǐng)確認(rèn)已經(jīng)熟練掌握mcu的使用方法,并且對(duì)cpld編程(verilog語(yǔ)言)有一定的基礎(chǔ)。
另外,對(duì)AHB總線(xiàn)也需要有一定的了解。
這個(gè)章節(jié)分為兩部分:
第一部分,展示聯(lián)合編程中各種概念和操作流程;
第二部分,從具體案例出發(fā),由淺到深來(lái)描述各種常用的編程技巧。
.
以下描述為第一部分(概念和流程)。如要查看實(shí)例講解,請(qǐng)參考第二部分。
.
一、前述
在AG32芯片(所有型號(hào))中,都有內(nèi)嵌2K的邏輯門(mén),可供fpga/cpld來(lái)使用。
也就是說(shuō),使用AG32的芯片時(shí),有三種選擇:
- 只使用mcu部分;
- 只使用cpld部分;
- 同時(shí)使用mcu和cpld(即:mcu和cpld聯(lián)合編程);
如果:
用于1(僅用做mcu),不必關(guān)注此文檔。
用于2(僅用做cpld),硬件設(shè)計(jì)和操作流程,請(qǐng)?zhí)D(zhuǎn)到“純粹cpld編程”,也不必關(guān)注此文檔。
用于3(mcu和cpld聯(lián)合編程):請(qǐng)按照該文檔的描述,先完整走一個(gè)流程。
.
二、基礎(chǔ)了解
1. AG32整顆芯片包含兩部分:mcu和cpld。
這兩部分是相互獨(dú)立的(各自編譯、各自下載),但又可以相互連通起來(lái)(信號(hào)連通)。
芯片要把這兩部分的bin都燒錄進(jìn)去,才能運(yùn)行起來(lái)。
2. mcu和cpld到外部Pin腳的連通,是通過(guò)VE文件來(lái)配置的。
跟ST芯片每個(gè)Gpio對(duì)應(yīng)某個(gè)固定Pin腳不同,在AG32中,所有的Gpio/大部分的外設(shè),對(duì)外引腳并不是定死的。而是需要在VE文件中指定對(duì)應(yīng)。
VE中,除了配置Gpio到Pin的關(guān)聯(lián),還可以配置mcu到cpld之間的信號(hào)關(guān)聯(lián)。
3. Mcu+cpld聯(lián)合編程時(shí),cpld工程是由vscode的“prepare LOGIC”命令自動(dòng)生成的。
注意:聯(lián)合編程時(shí),cpld工程不能手工通過(guò)supra建立。
cpld的對(duì)外接口,也是依托于vscode工程來(lái)的,不再是孤立的。
cpld中的top module的信號(hào)輸入,是關(guān)聯(lián)到mcu工程的(由VE配置出來(lái))。
4. cpld在聯(lián)合編程中的定位:
整顆芯片運(yùn)行時(shí),需要兩個(gè)bin:mcu的bin和cpld的bin。
如果芯片中只使用mcu不使用cpld:
此時(shí),VE文件里只配置mcu用到的Pin腳即可。
這種情況下,vscode工程中點(diǎn)“upload LOGIC”時(shí),會(huì)自動(dòng)生成默認(rèn)logic(該logic中“用戶(hù)邏輯”為空而已),并編譯出bin并燒錄。
整個(gè)過(guò)程中,logic部分對(duì)開(kāi)發(fā)者來(lái)說(shuō)是無(wú)感的。
如果芯片中同時(shí)使用mcu和cpld:
那么要把工程配置成“自定義logic”。
此時(shí)VE文件里需要配置用到的mcu和pin之間、mcu和cpld之間、cpld和pin之間,三種情況下的信號(hào)關(guān)聯(lián)。
這種情況下,VSCode下點(diǎn)“prepare LOGIC”按鈕,會(huì)為開(kāi)發(fā)者生成cpld的框架工程。開(kāi)發(fā)者需要在這個(gè)框架下完成cpld邏輯的編寫(xiě)。這個(gè)編寫(xiě)調(diào)試中,開(kāi)發(fā)者持有主動(dòng)權(quán)。等全部開(kāi)發(fā)完成,并編譯出bin,燒錄就又回到VSCode去燒錄。
這個(gè)過(guò)程,除了logic需要用戶(hù)自己編寫(xiě)編譯外,從更外層的視角看,整個(gè)流程還是跟“默認(rèn)Logic”是相同的。
.
三、安裝軟件
mcu需要使用到的VSCode前邊已經(jīng)安裝過(guò)了。
fpga/cpld需要使用Supra和Altera Quartus II兩個(gè)軟件來(lái)編程。
其中:
Supra.exe軟件在安裝完SDK后,已經(jīng)在SDK路徑下了,可直接使用(無(wú)需額外安裝Supra)。
(注:如果在SDK路徑下沒(méi)有找到Supra.exe,可進(jìn)入安裝路徑AgRV_piopackagestool-agrv_logicbin去找到。同時(shí)建議手工新建一個(gè)快捷方式到SDK路徑下以方便后續(xù)使用)
Altera Quartus II軟件需要用戶(hù)自行安裝,安裝后再安裝對(duì)應(yīng)的器件庫(kù)。
(注意:Quartus不能使用Lite版本,需要使用Full版本。最好使用版本:Quartus II 64-Bit Version 13.0.1 Build 232 06/12/2013 SJ Full Version)
在這兩個(gè)軟件中,
Quartus工具用來(lái)編寫(xiě)vlog代碼并導(dǎo)出vo文件,Supra工具使用vo文件來(lái)生成最終的bin。
.
四、CPLD使用流程
從使用角度來(lái)說(shuō),整體需要4個(gè)步驟:
- 1.在VE文件里配置引腳關(guān)系;
- 2.建立cpld空工程(使用prepare LOGIC命令)并編寫(xiě)邏輯;
- 3.Quartus下進(jìn)行工程轉(zhuǎn)換(和綜合);
- 4.Supra下編譯出最終的logic.bin;
下邊進(jìn)入詳細(xì)描述。
1.在VE里定義引腳和信號(hào)關(guān)系
這部分和MCU使用是相仿的。
在mcu里,都是mcu信號(hào)直接到PIN腳的映射。比如:

那么,在使用cpld里,除了上述的“mcu信號(hào)到Pin腳”關(guān)聯(lián)外,還允許“mcu信號(hào)到cpld信號(hào)”和“cpld信號(hào)到Pin腳”的兩種關(guān)聯(lián)。這里描述的三種關(guān)聯(lián),是常見(jiàn)的三種信號(hào)關(guān)聯(lián)方式。詳細(xì)使用方法,后續(xù)會(huì)介紹。
這里需要知道的是,每次VE文件修改完以后,都要重新走一遍整個(gè)流程(從prepare LOGIC開(kāi)始)。
其實(shí)不光修改完VE需要重新走一遍流程,有時(shí)修改platformio.ini也需要重新走一遍流程(比如,修改管腳數(shù)量)。
如果是第一次試驗(yàn)example例程,可以不用修改,使用默認(rèn)的VE文件即可。
2.生成空的cpld工程
仍然以example(路徑:...AgRV_pioplatformsAgRVexamplesexample)為例建立工程。
在example樣例程序中,默認(rèn)是沒(méi)有打開(kāi)自定義ip的。
首先,要通過(guò)配置打開(kāi)自定義ip
方法:在platformio.ini中打開(kāi)以下兩項(xiàng):
ip_name = analog_ip
logic_dir = logic
注意:這兩行去掉注釋的時(shí)候,前邊不要留空格。要頂格寫(xiě)。
打開(kāi)以上兩項(xiàng)并保存文件后,才能在左邊欄看到創(chuàng)建logic框架工程的選項(xiàng)(prepare LOGIC):

點(diǎn)擊該功能【Prepare LOGIC】后,可以看到在example工程目錄下生成一個(gè)logic文件夾,自動(dòng)生成的文件如下圖:

這里生成的logic文件夾,就是空的cpld工程。也是后續(xù)編寫(xiě)cpld的模板工程(后續(xù)代碼在這個(gè)基礎(chǔ)上添加)。
關(guān)于改寫(xiě)文件名:
這里的文件名字,是根據(jù)platformio.ini里邊的配置項(xiàng)來(lái)的:
board_logic.ve = example_board.ve
ip_name = analog_ip
logic_dir = logic
如果想改文件名字,可先在platformio.ini中更改名字,更改后再點(diǎn)生成按鈕來(lái)自動(dòng)生成。可更改的名字,就是上邊的三項(xiàng):
board_logic.ve 對(duì)應(yīng)logic文件夾內(nèi)example_board.v的名字
Ip_name 對(duì)應(yīng)logic文件夾內(nèi)analog_ip.v的名字
Logic_dir 對(duì)應(yīng)文件夾logic的文件夾名字
在生成后的文件夾內(nèi),注意其中的兩個(gè).v文件:analog_ip.v和example_board.v。
這兩個(gè)文件是vlog的源碼文件。
其中:
analog_ip.v是一份空的模板,用戶(hù)自己要實(shí)現(xiàn)的功能,就在這個(gè)空模板上展開(kāi);這個(gè)空的模板里邊,主要就是module analog_ip的接口定義。
example_board.v是根據(jù)工程中example_board.ve里的pin配置,Logic prepare時(shí)自動(dòng)轉(zhuǎn)換出來(lái)的v源碼,也是supra工程的top module。這部分不要手工改動(dòng)。
到這里,cpld空工程建立完畢。
注意:
后期修改完VE的配置后,Prepare LOGIC時(shí),會(huì)重新生成 cpld工程模板,這個(gè)模板文件都仍然存到logic文件夾下,且仍然是這兩個(gè).v文件。
只不過(guò)analog_ip.v對(duì)應(yīng)新增出analog_ip_tmpl.v文件,而example_board.v則是直接覆蓋。
由于analog_ip.v是用戶(hù)程序的入口,用戶(hù)程序會(huì)從這里開(kāi)始寫(xiě)。這個(gè)文件一定是會(huì)修改的。所以,每次prepare LOGIC時(shí),這個(gè)文件會(huì)對(duì)應(yīng)生成 analog_ip_tmpl.v文件,而不是覆蓋。
生成出analog_ip_tmpl.v后,用戶(hù)要根據(jù)自己的情況,把新接口手動(dòng)合并到analog_ip.v去。
注:這里只是以example來(lái)舉例。實(shí)際應(yīng)用中,在導(dǎo)出空工程前,需要先配置好platformio.ini的其他項(xiàng)和example_board.ve所需要的引腳。包括:board_logic.device配置32/48/64/100腳。
也就是第一步要做的內(nèi)容。
3. Quartus下進(jìn)行工程轉(zhuǎn)換
使用前邊安裝過(guò)的Quartus II軟件,打開(kāi)examplelogic的工程文件。打開(kāi)后如圖:

這里除了example_board.v和analog_ip.v外,還有個(gè)系統(tǒng)的alta_sim.v,這個(gè)文件是提供芯片系統(tǒng)的功能,類(lèi)似函數(shù)庫(kù),可不用關(guān)注。
此時(shí),這個(gè)工程是個(gè)空的工程,用戶(hù)要根據(jù)需求在analog_ip.v中實(shí)現(xiàn)功能。
再次回顧下3個(gè).v文件:
- analog_ip.v:用戶(hù)自定義logic的入口。用戶(hù)logic實(shí)現(xiàn)在這里展開(kāi);
- example_board.v:整個(gè)logic的top module。會(huì)關(guān)聯(lián)analog_ip的module和atla_sim下的各module。不要修改該文件。
- alta_sim.v:封裝過(guò)的跟AG32相關(guān)的各module。不要修改該文件。
接下來(lái)進(jìn)行空工程的轉(zhuǎn)換和編譯。
注意:如果不是很熟練,這里的空工程最好不要馬上添加自己的代碼。而是應(yīng)該首先工程轉(zhuǎn)換。
工程轉(zhuǎn)換的目的,是把cpld模板工程真正轉(zhuǎn)換成quartus實(shí)際運(yùn)行的狀態(tài)。
操作步驟:
打開(kāi)Quartus菜單的【tools】->【Tcl Scripts...】,彈出框如下圖:

【Run】運(yùn)行成功后,可以看到該logic占用的資源數(shù)量。

這個(gè)轉(zhuǎn)換的過(guò)程,順便進(jìn)行了cpld工程的編譯。
上圖中斜杠前邊標(biāo)識(shí)的大小就是所占的邏輯單元數(shù)(后續(xù)使用中邏輯單元不能超過(guò)2K,嚴(yán)格講,是2112個(gè)邏輯單元)
注意:第一次導(dǎo)入工程,必須執(zhí)行上圖的方式來(lái)轉(zhuǎn)換。后續(xù)編寫(xiě)和修改cpld代碼后,可以仍然執(zhí)行上圖方式,也可以直接點(diǎn)下圖的“編譯”按鈕來(lái)編譯。

執(zhí)行到這里,會(huì)在logic下生成vo文件出來(lái)(在logicsimulationmodelsim下)。
如果用戶(hù)有自己的邏輯,可以在這時(shí),把邏輯加入到analog_ip.v中去,并點(diǎn)上圖的三角號(hào)重新編譯。
到這里,Quartus工具的任務(wù)也完成了。
接下來(lái)打開(kāi)Supra來(lái)繼續(xù)生成bin文件。
4.Supra下編譯出最終的bin
在Supra工具里,打開(kāi)該工程(examplelogic)。
然后,點(diǎn)擊【左上角Tool】->【Compile】,在彈出的畫(huà)面中點(diǎn)右下角的【run】。

編譯成功后,畫(huà)面會(huì)有提示。
Compile design example_board?done?with code?0
然后在logic路徑下可以看到新編譯出來(lái)的bin。
這個(gè)bin就是要燒錄到芯片的cpld.bin。
到這里,supra工具的任務(wù)完成。
.
至于燒錄,重新回到VSCode下燒錄logic即可。如下圖:

到這里,新建一個(gè)空工程、轉(zhuǎn)換、編譯、燒錄的整個(gè)流程描述完畢。
強(qiáng)調(diào):
后續(xù)如果在VE里修改過(guò)配置,則需要走一個(gè)全過(guò)程:vscode下prepare LOGIC再生成一遍cpld模板、合并analog_ip_tmpl.v到analog_ip.v中去、啟動(dòng)quartus去轉(zhuǎn)換、supra下編譯,回到vscode下燒錄logic。
后續(xù)如果只是在quartus下編寫(xiě)cpld代碼,需要走的幾步:quartus下編譯、supra下編譯、回到vscode下燒錄logic。
.
五、上述過(guò)程中的說(shuō)明
上述流程中涉及兩個(gè)比較關(guān)鍵的點(diǎn):
1. 自定義模塊的命名
自定義的邏輯,自定義文件名必須與自定義模塊名相同,就是在platformio.ini中設(shè)置的ip_name的名字。
這個(gè)對(duì)應(yīng)關(guān)系,在上述流程點(diǎn)prepare LOGIC自動(dòng)生成代碼時(shí),會(huì)自動(dòng)完成。
如果是手工編輯的邏輯代碼,或者對(duì)這里的命名進(jìn)行過(guò)改動(dòng),會(huì)出現(xiàn)后續(xù)Quartus中使用的異常。
2. Ve中定義的信號(hào)關(guān)聯(lián)
在AG32中,mcu和cpld和外部引腳,三者是相互獨(dú)立的。
- mcu用的IO,在ve里,可以關(guān)聯(lián)到外部引腳Pin_xx;
- cpld用的IO,在ve里,可以關(guān)聯(lián)到外部引腳pin_xx;
- mcu的某一路信號(hào)又可以直接和cpld的某一路信號(hào),在ve里,關(guān)聯(lián)起來(lái);
所以,ve是很關(guān)鍵的一個(gè)橋梁。
在ve中定義好以后,運(yùn)行prepare LOGIC會(huì)自動(dòng)產(chǎn)生cpld的頂層模塊的輸入輸出接口,這些接口就是cpld和mcu與外部引腳關(guān)聯(lián)的信號(hào)通路。
這里著重描述下3種情況在VE文件里的定義。
A. mcu和外部引腳的關(guān)聯(lián)
比如,定義gpio到外部引腳:GPIO4_3 PIN_32
比如,定義串口0到外部引腳:UART0_UARTRXD PIN_31

定義格式為:mcu的FunctionName + 空格 + Pin腳ID。
這部分在 mcu 使用里描述的很多了,不再贅述。
B. cpld和外部引腳的關(guān)聯(lián)
比如,定義led到外部引腳:LED_D3 PIN_32:OUTPUT

定義格式為:cpld信號(hào)名稱(chēng) + 空格 + Pin腳ID:方向
其中,
cpld 信號(hào)名稱(chēng),是自定義名稱(chēng),這個(gè)名稱(chēng)隨后可以在 cpld 中引用;
方向,有 3 種:OUTPUT、INPUT 和 INOUT(這個(gè)方向是 cpld 對(duì)外部引腳來(lái)說(shuō)的)。
方向是可選的,可加可不加。如果不加,則是默認(rèn)的 INOUT(雙向)。
上述定義在 ve 里添加后,執(zhí)行 prepare LOGIC 命令,在自動(dòng)生成的 cpld 工程中,可以看到輸出到 cpld 頂層模塊接口中的 item 如下:

那么,
input?BTN_L1: 是 pin 到 cpld 的信號(hào);
output?LED_D2: 是 cpld 到 pin 的信號(hào);
output?LED_D3: 是 cpld 到 pin 的信號(hào);
然后在 cpld 代碼中操作 LED_D3 這個(gè)信號(hào)的高低,最終操作的 PIN_32 管腳的高低。
(注:VE 里每行最后定義的方向是可選的)
C. mcu和cpld之間的關(guān)聯(lián)
比如,定義 gpio 信號(hào)到 cpld:GPIO4_1 iocvt_chn
比如,定義串口 1 的 tx 信號(hào)到 cpld:UART1_UARTTXD txd_chn

定義格式為:MCU的FunctionName + 空格 + cpld信號(hào)名稱(chēng)
其中,
這里的 FunctionName,同 1 中的 FunctionName,就是 mcu 里的通路定義。更多定義參考《AGRV2K_邏輯設(shè)置.pdf》,里邊有全部的 mcu 端可用的 FunctionName 列表。
除了 mcu 的 FunctionName(映射到引腳)外,mcu 對(duì) cpld 還開(kāi)放出更多的內(nèi)核級(jí)通路接口,如:mem_ahb_各通道,dma 各通道,mcu 的 reset 和 stop 等信號(hào),具體定義也參考《AGRV2K_邏輯設(shè)置.pdf》。
這里定義后,執(zhí)行 prepare LOGIC 命令,在自動(dòng)生成的 cpld 工程中,可以看到輸出到cpld頂層模塊接口的 item 如下:

對(duì)于 iocvt_chn 來(lái)說(shuō),對(duì)應(yīng)的是沒(méi)有指定方向的普通 gpio(GPIO4_3)口,則這里生成的信號(hào)同時(shí)包含有輸入和輸出兩種。
注:這里的輸入和輸出,是相對(duì)于 cpld 端來(lái)說(shuō)的。藍(lán)色的?input/output,就是該信號(hào)的方向。比如:
output?iocvt_chn_in:是 cpld 輸出到 mcu 的信號(hào);
input?iocvt_chn_out_data:是 mcu 輸出到 cpld 的信號(hào);
input?iocvt_chn_out_en:是 mcu 輸出到 cpld 的信號(hào)(en 信號(hào)很少用,一般可忽略);
對(duì)于 txd_chn 來(lái)說(shuō),由于 mcu 的串口 TX 是定義好方向的,是 mcu 的 output 方向。所以在 cpld 里只有兩個(gè) item 項(xiàng):
input?txd_chn_out_data:是 mcu 輸出到 cpld 的信號(hào);
input?txd_chn_out_en:是 mcu 輸出到 cpld 的信號(hào)(en 信號(hào)很少用,一般可忽略);
如果對(duì)普通 GPIO 也設(shè)置了方向,則導(dǎo)出到 cpld 的方向也就只有對(duì)應(yīng)方向的信號(hào)了。
如:VE 里設(shè)置 GPIO4_1 iocvt_chn 為 mcu 的輸出:

則prepare LOGIC后生成的item只有input的兩項(xiàng)。如下:

注意:在mcu和cpld信號(hào)連接中,mcu的output就是cpld的input。
.
到這里,第一部分(mcu+cpld使用的概念和流程)描述完畢。
下個(gè)章節(jié),第二部分,將以樣例為基礎(chǔ),描述mcu+cpld在具體使用中怎么體現(xiàn)。