那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在SOC環(huán)境里面C代碼是怎么執(zhí)行的?

sanyue7758 ? 來源:處芯積律 ? 2023-11-06 09:38 ? 次閱讀

不少同學很好奇在SOC環(huán)境里面C代碼是怎么執(zhí)行的?

是通過DPI實現(xiàn)SV和C的交互,然后用 SV的task將C的數(shù)據(jù)轉成對應的總線數(shù)據(jù)下發(fā)到各個外設?

DPI 調用例子

e97f59dc-7bcc-11ee-939d-92fbcf53809c.png

e9916852-7bcc-11ee-939d-92fbcf53809c.png

是在verilog里面調用PLI獲取C里面的內容?

PLI調用例子

e97f59dc-7bcc-11ee-939d-92fbcf53809c.png

e9a8b7aa-7bcc-11ee-939d-92fbcf53809c.png

還是通過TLM1.0 或者TLM2.0 完成C和verilog 的交互?

TLM2.0 使用例子

e9b9a614-7bcc-11ee-939d-92fbcf53809c.png

e9dd319c-7bcc-11ee-939d-92fbcf53809c.png

實際上,以上三種都不是!

在SOC驗證環(huán)境中,需要仿真一顆芯片真實的工作狀態(tài)。通過上面三種手段驗證不CPU boot的過程,CPU處理 interrupt的過程,芯片進出低功耗的過程。

在SOC環(huán)境中怎么模擬芯片的工作過程呢?

下面是一個典型的RISCV CPU。在這個系統(tǒng)中,CPU會通過指令總線獲取執(zhí)行的程序指令,然后通過數(shù)據(jù)總線訪問存儲的數(shù)據(jù)和外設等。

e9f03922-7bcc-11ee-939d-92fbcf53809c.png

在下面的這個系統(tǒng)中,我們將RISCV的指令總線和數(shù)據(jù)總線作為兩個master 掛在AHB總線上,將程序指令存儲在SRAM中,當SOC啟動時,會通過指令總線訪問SRAM獲取指令信息

CPU中拿到指令后會進行解碼,然后通過執(zhí)行單元執(zhí)行解碼的指令,如果需要用到外部的存儲數(shù)據(jù),則會通過數(shù)據(jù)總線訪問SRAM獲取存儲的數(shù)據(jù)內容。如果解碼內容配置外設寄存器,則通過數(shù)據(jù)總線訪問外設,對外設進行配置等等。

ea08378e-7bcc-11ee-939d-92fbcf53809c.png

這里需要注意的是程序代碼放在SRAM里面,一些數(shù)據(jù)內容也是分在SRAM中,假如中間不作分割,那么指令和數(shù)據(jù)會混在一起,導致RISCV在執(zhí)行程序的時候會跑飛。所以我們在后面編譯指令的時候,需要對memory空間進行分割。

通過上面的描述,我們大概清楚了CPU是怎么工作起來的,但是這個和我們的C程序有什么關系呢?

CPU執(zhí)行的是機器碼指令,這些指令是由一個個特定數(shù)據(jù)和擺放的格式決定的。

下面是32bit RISCV的部分指令格式。

ea168f32-7bcc-11ee-939d-92fbcf53809c.png

在這里R,I S,B U,J分別代表6種不同的指令。

R-formatfor register-register arithmetic/logical operations

I-formatfor register-immediate arith/logical operations and loads

S-formatfor stores

B-formatfor branches

U-formatfor 20-bit upper immediate instructions

J-formatfor jumps

R是寄存器類型指令, I是立即數(shù)類型指令,S是存儲類指令,B是分支類指令,U是高20bit立即數(shù)指令,J是跳轉指令。

我們以簡單的立即數(shù)加法運算為例,比如我想做一個 a0= s0+16 這樣一個立即數(shù)加法運算,偽代碼就是 add a0,s0,16 。這個案例中我們用的是立即數(shù)類型的指令。

根據(jù)上述表格,該指令格式為

ea2a0832-7bcc-11ee-939d-92fbcf53809c.png

funct3,opcode又是什么呢?通過查詢 riscv 手冊可以查到以下結果。

ea387142-7bcc-11ee-939d-92fbcf53809c.png

這個立即數(shù)加法最終編譯成機器碼 0x01048513

ea4812b4-7bcc-11ee-939d-92fbcf53809c.png

將這個機器放在地址0x29a 的位置。

ea660c10-7bcc-11ee-939d-92fbcf53809c.png

我們把這些機器碼放在SRAM里面,CPU看到拿到 0x01048513 就可以解碼出來這是一個a0=s0+16的立即數(shù)操作。

到這里,我們大概知道底層的CPU是怎么執(zhí)行的,現(xiàn)在要解決的問題是如何將C編譯成機器碼。

下面這個圖是C語言編譯成機器碼的過程。

ea81296e-7bcc-11ee-939d-92fbcf53809c.png

C語言首先編譯成匯編語言,再由匯編語言編譯成機器指令,最后通過鏈接形成目標機器指令。

我們以SOC3.0的環(huán)境為例子,看看這個過程怎么執(zhí)行的。

首先我們看SOC3.0的環(huán)境里面都有哪些文件。

crt0.S

"crt"代表"C runtime"(零表示"一切的開始")。

crt0是一組執(zhí)行啟動例程,編譯到程序中,在調用程序的主函數(shù)之前執(zhí)行任何必要的初始化工作——它是一個基本的運行時庫/運行時系統(tǒng)。crt0的工作取決于程序的語言、編譯器、操作系統(tǒng)和C標準庫的實現(xiàn)。

在SOC3.0里面crt0.S 是匯編語言寫的。

這段代碼做什么事情呢?

異常處理程序:

default_exc_handler 是一個通用的異常處理程序,似乎被設置為各種異常的處理程序,比如外部中斷、非法指令和系統(tǒng)調用 (ecall)。

還有其他異常向量的占位符(nop指令),表明它們可能以類似的方式處理。

復位處理程序:

reset_handler 將所有寄存器設置為零,并通過加載堆棧起始地址來初始化堆棧。

清除BSS段:

它通過用零填充來清除BSS(由符號開始的塊)段。通常這樣做是為了確保所有未初始化的全局和靜態(tài)變量都以零值開始。

跳轉到主函數(shù):

最后,它跳轉到 main 函數(shù),并將 argc 和 argv 設置為零。

注意我們C 代碼的main 函數(shù)的命名不是天生就是這么命名的,是在這里給定的。

異常向量:

.vectors 部分定義了異常向量。它似乎對各種異常使用默認的異常處理程序,還有一個重置向量指向 reset_handler。

ea97f4be-7bcc-11ee-939d-92fbcf53809c.png

2. C函數(shù)

以spi1_test test為例子

common.c ,這里定義了一些打印字符串和讀寫寄存器的函數(shù)。

eab93386-7bcc-11ee-939d-92fbcf53809c.png

spi1_test.c ,這里實現(xiàn)對spi1這個IP的配置及自我檢查。

ead9c128-7bcc-11ee-939d-92fbcf53809c.png

3. 鏈接文件link.ld

我們在上文說了,在SRAM里面如果不對程序存儲空間和數(shù)據(jù)存儲空間進行分割,那么CPU執(zhí)行的時候很可能跑飛。為了組織內存分配,需要一個鏈接文件進行配置。

link.ld是一個鏈接腳本(linker script),用于指導鏈接器如何組織程序在內存中的布局。具體來說,它包含了以下關鍵信息:

內存布局:

內存被劃分為兩個區(qū)域:rom(48 kB)和stack(16 kB)。

rom從地址0x00000000開始,stack從地址0x0000C000開始。

堆棧信息:

_min_stack設置為0x2000(8 kB),表示要保留的最小堆棧空間。

_stack_len是stack區(qū)域的長度。

_stack_start是堆棧的起始地址。

各個段:

.vectors 段包含中斷向量,位于rom的開頭。

.text 段包含程序代碼。構造函數(shù)和析構函數(shù)列表用于處理C++

.rodata 段包含只讀數(shù)據(jù)。

.shbss 段在rom中對齊并放置。

.data 段包含已初始化的數(shù)據(jù)。

.bss 段包含未初始化的數(shù)據(jù)。

.stack 段確保堆棧有足夠的空間。

特殊段(NOLOAD):

.stack 段標記為 NOLOAD,意味著它不會加載到最終的二進制文件中。它只是為堆棧保留空間。

.stab 和 .stabstr 段也被定義,但標記為 NOLOAD,表明它們是調試信息。

eafc3ad2-7bcc-11ee-939d-92fbcf53809c.png

有了上面這些文件,我們看看Makefile 怎么將spi1_test.c 編譯成機器碼的。

第一步,通過riscv提供的工具鏈將C和匯編.S的文件編譯成目標文件。

eb1e3132-7bcc-11ee-939d-92fbcf53809c.png

eb3272e6-7bcc-11ee-939d-92fbcf53809c.png??--->

eb4442fa-7bcc-11ee-939d-92fbcf53809c.png

第二步,將生成的.o目標文件鏈接成elf文件

ELF(Executable and Linkable Format)是一種用于可執(zhí)行文件、目標文件、共享庫和核心轉儲文件的標準文件格式。它是一種二進制文件格式,設計用于在多種操作系統(tǒng)上支持可執(zhí)行文件可重定位代碼的交互性。

eb518834-7bcc-11ee-939d-92fbcf53809c.png

第三步,用elf文件生成 二進制文件(機器碼) .bin文件

eb6ed77c-7bcc-11ee-939d-92fbcf53809c.png

到這里我們已經產生了機器碼的文件.bin,按理說CPU拿這個文件就可以執(zhí)行了。但是在我們環(huán)境里面,我們需要將機器碼放到verilog 的sram memory里面去。所以我們還做了第四步。

第四步,將.bin 文件轉換為一個包含二進制數(shù)據(jù)的Verilog內存初始化文件。

eb81db7e-7bcc-11ee-939d-92fbcf53809c.png

通過上面四步,我們實現(xiàn)了C到機器碼的轉換。

我們將生成的spi1_test.vmem 放到SOC環(huán)境中,sram的memory 通過readm 讀進這些機器碼。然后通過仿真,就可以模擬SOC執(zhí)行的過程。

按理說到里面我們應該結束今天的文章,但是當我們回頭看看我們環(huán)境似乎還缺些什么。

沒錯那就是機器碼的反標,當我們debug cpu的時候,cpu記錄當前執(zhí)行的指令和指令行數(shù),我們通過這些信息可以定位具體在操作哪條機器碼,但是我們怎么樣才知道當前的機器碼對應是C代碼里面的拿哪段內容呢?

這就需要機器碼的反標,在我們SOC3.0的環(huán)境里面,我們通過下面指令完成機器碼到C的反標。

eb9c247a-7bcc-11ee-939d-92fbcf53809c.png

我們看看效果。

ebacdcac-7bcc-11ee-939d-92fbcf53809c.png

非常方便。

以上是我們文章的所有內容,上述所列案例在我們SOC3.0里面都有,歡迎感興趣的小伙伴咨詢。

關于 SOC3.0,小伙伴們可以點這里。

SOC3.0有哪些東西?

或者直接聯(lián)系梨果。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5363

    瀏覽量

    121157
  • soc
    soc
    +關注

    關注

    38

    文章

    4204

    瀏覽量

    219090
  • Verilog
    +關注

    關注

    28

    文章

    1351

    瀏覽量

    110390
  • DPI
    DPI
    +關注

    關注

    0

    文章

    37

    瀏覽量

    11542
  • SRAM存儲器
    +關注

    關注

    0

    文章

    88

    瀏覽量

    13375

原文標題:干貨,在SOC驗證環(huán)境中,C代碼是怎么被執(zhí)行起來的?

文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    modustoolbox開發(fā)環(huán)境里面如何通過快捷方式批量屏蔽代碼

    modustoolbox開發(fā)環(huán)境里面如何通過快捷方式批量屏蔽代碼,目前是通過/*********/的方式來屏蔽, 謝謝!
    發(fā)表于 02-01 06:52

    芯海通用 MCU 應用筆記: MDK 開發(fā)環(huán)境代碼重定向到 RAM 執(zhí)行的幾種方法

    空間并寫入新的代碼。此外還具備執(zhí)行效率高,壽命長優(yōu)點。 本文檔介紹和說明 MDK 開發(fā)環(huán)境下將代碼重定向到 RAM 中
    發(fā)表于 05-16 11:58

    SOC快速入門

    的“gizwitsEventProcess()函數(shù)里添加驅動外設執(zhí)行事件函數(shù)即可實現(xiàn)控制設備上報云端狀態(tài)事件處理,可以“GizLamp\app\user”文件目錄下“user_main.c”文件
    發(fā)表于 02-27 18:21

    請教關于c6678的sy***ios代碼執(zhí)行疑問

    EVM_init代碼?(2)為什么不將EVM_init代碼放到main里面去?main之前執(zhí)行EVM_init有什么好處?
    發(fā)表于 07-25 06:22

    ucos執(zhí)行問題

    假設我設置了3個任務A、B、C,然后每個任務里面都有while(1),while(1)里面執(zhí)行了相應
    發(fā)表于 04-02 23:04

    如何提高C語言程序的執(zhí)行效率

    我們平常所說的執(zhí)行效率就是使用相同的算法相同輸入條件下完成相同計算所產生的系統(tǒng)開銷,目前來說一般會更多關注執(zhí)行時間方面的開銷。所有語言編寫的代碼最終要運行,都要轉化成機器碼。
    發(fā)表于 07-20 06:39

    利用Matlab的simulink搭建模型生成C代碼

    一、整體思路利用Matlab的simulink搭建模型生成C代碼,通過stm32cubemx生成工程,最后KEIL或者IAR等工具里面編譯生成代碼
    發(fā)表于 08-10 07:49

    程序的翻譯環(huán)境執(zhí)行環(huán)境有何不同

    程序的翻譯環(huán)境執(zhí)行環(huán)境ANSI C的任何一種實現(xiàn)中,存在兩個不同的環(huán)境。翻譯
    發(fā)表于 02-28 06:57

    一個優(yōu)秀的SOC驗證環(huán)境應該具備哪些功能呢

    小編前段時間幫客戶找到一些人解決了SOC驗證環(huán)境的問題。招人的時候我們和不少人進行了溝通交流,從中發(fā)現(xiàn)SOC驗證環(huán)境一千家公司有一千家公司
    發(fā)表于 05-31 11:39

    怎樣用C語言去啟動SOC驗證環(huán)境

    SOC,CPU通過總線訪問SPI,USB,PCIE,DDR,I2C等。SOC驗證環(huán)境里面,通
    發(fā)表于 06-17 14:41

    執(zhí)行環(huán)境(EE)協(xié)議棧中的定位

    執(zhí)行環(huán)境(EE)協(xié)議棧中的定位 前面提到,執(zhí)行環(huán)境應當在協(xié)議棧中相對較低的層次上實現(xiàn)。設計
    發(fā)表于 03-02 11:11 ?631次閱讀

    高效的C編程之條件執(zhí)行

    4.3 條件執(zhí)行 ARM指令都是可以條件執(zhí)行的。代碼中使用條件執(zhí)行指令可以減小代碼密度并提高程
    發(fā)表于 10-17 16:52 ?2次下載

    C語言的源代碼文件和目標文件與可執(zhí)行文件的詳細介紹

    1、源代碼文件 存放程序代碼的文件,即我們編輯代碼的文件,稱為源代碼文件。 C語言源程序文件的擴展名為“.
    的頭像 發(fā)表于 02-18 11:52 ?8815次閱讀

    使用C語言Linux環(huán)境下運行推箱子游戲的代碼免費下載

    本文檔的主要內容詳細介紹的是使用C語言Linux環(huán)境下運行推箱子游戲的代碼免費下載,現(xiàn)在分享給大家游戲游戲,現(xiàn)在有80多關。如果需要添加其他關卡,很容易擴展,僅供娛樂學習!。
    發(fā)表于 05-19 08:00 ?5次下載
    使用<b class='flag-5'>C</b>語言<b class='flag-5'>在</b>Linux<b class='flag-5'>環(huán)境</b>下運行推箱子游戲的<b class='flag-5'>代碼</b>免費下載

    MIMXRT1176代碼放在ITCM里面運行,為什么執(zhí)行速度并沒有在外部Flash里面執(zhí)行的快?

    通過IAR環(huán)境下添加__RAMFUNC,修改了函數(shù)SysTick_Ticks 以ITCM中運行,實際測得的運行速度變慢,系統(tǒng)計數(shù)累加的次數(shù)也減少了,代碼
    的頭像 發(fā)表于 01-30 09:22 ?1336次閱讀
    百家乐信誉好的平台| 利澳百家乐官网的玩法技巧和规则| 德州扑克 技巧| 水果机技术打法| 金海岸百家乐的玩法技巧和规则| 最好的百家乐投注| 金宝博百家乐现金| 找真人百家乐官网的玩法技巧和规则 | 百家乐官网长玩必输| 兴义市| 百家乐注册| 大发888手机版亚洲城| 百家乐娱乐求指点呀| 百家乐实时路单| 永利高百家乐开户| 百家乐官网第三张规则| 金榜百家乐官网的玩法技巧和规则| 广州百家乐官网桌子| 百家乐官网单机游戏下| 百家乐官网几点不用补牌| 斗首24山择日天机择日| 大世界百家乐官网的玩法技巧和规则 | 大发888 备用6222.com| 大发888 zhidu| bet365充值| 天天百家乐官网游戏| 花垣县| 百家乐官网路单纸下载| 百家乐官网楼梯缆大全| 玩百家乐官网怎么能赢呢| 百家乐园千术大全| 澳门百家乐赌| 大发888澳88| 百家乐官网怎么玩才会赢钱 | 百家乐官网园有限公司| 百家乐攻略投注法| 网上百家乐的玩法技巧和规则 | 百家乐波音平台有假吗| 百家乐网上娱乐场开户注册| 玩百家乐必赢的心法| 百家乐作弊|