吴忠躺衫网络科技有限公司

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

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

3天內不再提示

如何根據自己設計中的寄存器配置總線定義來生成一套寄存器配置模版

Spinal FPGA ? 來源:Spinal FPGA ? 2024-03-04 13:56 ? 次閱讀

編 者 按

無論是FPGA還是ASIC,系統設計中總會存在配置寄存器總線的使用,我們會將各種功能、調試寄存器掛載在寄存器總線上使用。在SpinalHDL中,BusIf那套總線模型庫寫的還是相當不錯的,能夠同時生成對應的代碼和文檔(在公司里也做過一些修改,能夠直接生成整個系統的寄存器文檔而不僅僅是單個模塊的寄存器文檔)。今天就手把手來基于SpinalHDL中的BusIf來看如何根據自己設計中的寄存器配置總線定義來生成一套寄存器配置模版。

HPI總線

今天以下面一套簡單的寄存器總線為例進行設計:

caseclass Hpi(addrWidth:Int,dataWidth:Int,useStrb:Boolean) extends Bundle with IMasterSlave {
val wr,rd=Bool()
val addr=UInt(addrWidth bits)
val wdata=Bits(dataWidth bits)
val strb= useStrb generate(Bits(dataWidth/8bits))
val rvalid=Bool()
val rdata=Bits(dataWidth bits)

overridedef asMaster(): Unit = {
out(wr,rd,addr,wdata)
in(rvalid,rdata)
if(useStrb) out(strb)
}
}

HPI總線很簡單,wr用于標識寫指令、rd用于標識讀指令。addr用于指示讀/寫地址。wdata用于輸入待寫入的數據。strb如果使能則用于標識對應寫指令的位選信號。而rvalid則用于指示讀返回數據有效,rdata則表示讀返回數據(這里就不畫時序圖了)。

設計一套自己的HpiInterface

針對上面的HPI總線,這里我們基于BusIf設計一套自己的配置寄存器總線模板。

BusIf都做了什么

對于寄存器配置總線,其總線信號定義,協議交互定義總是各有千秋的,BusIf無法對寄存器配置總線的這些定義做提前預知。然而對于寄存器配置總線的用途,則相對明確,無非就是實現不同數據類型(像UVM中定義的寄存器模型)的讀寫操作。那么,當我們基于BusIf定義一套自己的配置寄存器模板時,所需要做的就無非是:

實現配置寄存器交互協議的邏輯實現

告訴BusIf如何什么情況下觸發了某個寄存器的讀/寫操作

HpiInterface

這里先貼上一個完整的代碼,隨后進行逐行解析

faef404e-d8a9-11ee-a297-92fbcf53809c.png

這里我們定義的寄存器總線相對來講較為簡單,故只有30~31行是用來進行配置寄存器總線協議時序的處理的。

line3

override defgetModuleName:String = moduleName.name

利用隱式參數獲取模塊名,BusIf中并無顯示使用。

line5~6

override defwriteAddress():UInt = bus.addr
override defreadAddress():UInt = bus.addr

這里用來告知BusIf配置寄存器總線的寫地址,讀地址分別是什么,在HPI總線中均為bus.addr

line8~9

override defreadHalt():Unit = {}
override defwriteHalt():Unit = {}

這里用來填寫發生讀阻塞或者寫阻塞時的響應動作,HPI總線中沒有阻塞的概念,直接不做任何處理即可(由于配置寄存器總線接口層協議我們會自己實現,BusIf中當前版本內部無使用的地方,故直接填空即可)。

line11

override defbusDataWidth:Int = bus.dataWidth

這里用來告知BusIf配置寄存器總線的數據位寬

line13~18

override val withStrb:Boolean = bus.useStrb
val wstrb:Bits = withStrb generate(Bits(strbWidth bit))
val wmask: Bits = withStrb generate(Bits(busDataWidth bit))
val wmaskn: Bits = withStrb generate(Bits(busDataWidth bit))
initStrbMasks()
if(bus.useStrb){wstrb:=bus.strb}

這里用于設置配置寄存器總線是否有使用掩碼功能。line13用于告知BusIf是否使用掩碼,而line14~17則是一套針對掩碼的BusIf設置(直接copy即可)。在line18行如果使能了掩碼功能,則通過用bus.strb來驅動 wstrb來告知BusIf配置寄存器總線對應的寫掩碼。

line20~26

overrideval askRead: Bool = bus.rd
overrideval askWrite: Bool = bus.wr
overrideval doWrite: Bool = bus.wr
overrideval doRead: Bool = bus.rd
overrideval readData: Bits = Bits(bus.dataWidth bits)
overrideval writeData: Bits =bus.wdata
overrideval readError: Bool = Bool()

askRead:告知BusIf什么情況下配置寄存器產生了讀請求(如果總線類型是Stream那種握手型的,則只需填valid即可,可參照regif下的AxiLite4BusInterface)。在當前版本中,askRead在BusIf中并未有使用

askWrite:告知BusIf什么情況下配置寄存器產生了寫請求,同上

doWrite:告知BusIf當前時鐘是否出發了寄存器寫操作

doRead:告知BusIf當前時鐘是否發生了寄存器讀操作

readData:為BusIf聲明一個對應總線數據位寬的信號,BusIf會將讀結果返回到當前信號上。

writeData:告知BusIf如果發生寫數據,寫入的數據是什么

readError:聲明一個Bool類型,BusIf會將是否有讀錯誤發生通過該信號進行表示。

line28

setReservedAddressReadValue(BigInt("deaddead",16))

此處用于設置當總線讀了未使用的地址時,應當返回何值。當然也可以不必在這里進行統一設置,可以在真正的例化位置為每個模塊設置一個不同的值。

line30~31

bus.rdata:=RegNext(readData)
bus.rvalid:=RegNext(bus.rd,False)

該處則用于處理Hpi總線的協議時序,我們僅需處理接口層面上的時序即可。

使用HpiInterface

定義好之后,使用就和regif文檔里的例子一樣了,下面給出一個例子:

fafef476-d8a9-11ee-a297-92fbcf53809c.png

這里定義了data0,data1,data2三個寄存器。data0,data1可讀可寫,data2只讀。

值得注意的是這里針對data0,data1采用了不同形式的API,對于data0,使用field來注冊會生成reg0_data0,其是帶有復位處理的,這里不希望其有復位邏輯,故這里添加了removeInitAssignments()

DIY時間

來看下在BusIf中針對讀邏輯是怎么處理的:

fb19a42e-d8a9-11ee-a297-92fbcf53809c.png

從FPGA的角度來看的話,這個askRead判斷是沒有必要,徒增延遲,看起來不那么優雅,而且在Hpi總線使用時往往是要求地址按位寬對齊的,所以完全可以將地址判斷抹去低比特,由于這里readGenerator定義成了private,外部無法重載,這里給出一個在HpiInterface中進行DIY的例子:

val discardAddrWidth = log2Up(busDataWidth / 8)

def hitDoWriteOverride() = {
orderdRegInsts.foreach(regInst => {
regInst.hitDoWrite.removeAssignments()
regInst.hitDoWrite := writeAddress()(bus.addrWidth - 1downto discardAddrWidth) === regInst.addr / (busDataWidth / 8) && doWrite
})
}

def reworkReadGenerate() = {
readError.removeAssignments()
readData.removeAssignments()
switch(readAddress()(bus.addrWidth - 1downto discardAddrWidth)) {
orderdRegInsts.foreach(regInst => {
if(!regInst.allIsNA) {
is(regInst.addr / (busDataWidth / 8)) {
readData := regInst.readBits
readError := Bool(regInst.haveWO)
}
}
})
default{
readData := getReservedAddressReadValue
readError := True
}
}
}

component.addPrePopTask(() => {
hitDoWriteOverride()
reworkReadGenerate()
})

這里對讀和寫均做了一些優化。對于寫操作進行地址判定時將會抹去地址相應地比特的判斷。而對于讀操作,也會抹去相應地址位,同時也刪除了askRead的判斷。

感興趣的小伙伴可自行擴展定制,比如將HPI的讀返回拆成兩排分級譯碼以獲取更好的時序等等。



審核編輯:劉清
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1630

    文章

    21796

    瀏覽量

    605996
  • 寄存器
    +關注

    關注

    31

    文章

    5363

    瀏覽量

    121158
  • UVM
    UVM
    +關注

    關注

    0

    文章

    182

    瀏覽量

    19227
  • HPI
    HPI
    +關注

    關注

    0

    文章

    36

    瀏覽量

    14545

原文標題:手把手創建自己的寄存器配置模版

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

收藏 人收藏

    評論

    相關推薦

    怎樣去配置FMC總線寄存器

    目錄1、硬件2、初始化時序3、配置FMC總線寄存器3.1 控制寄存器3.2 時序寄存器3.3 命令寄存
    發表于 01-26 07:35

    寄存器,寄存器是什么意思

    寄存器,寄存器是什么意思 寄存器定義  寄存器是中央處理內的組成部分。
    發表于 03-08 14:26 ?2.2w次閱讀

    數據寄存器,數據寄存器是什么意思

    數據寄存器,數據寄存器是什么意思 數據寄存器數據寄存器包括累加AX、基址寄存器BX、計數
    發表于 03-08 14:38 ?1.3w次閱讀

    MAXQ3180入門:寄存器配置

    MAXQ3180入門:寄存器配置 雖然多相、多功能電能計量AFE芯片MAXQ3180具有很多配置寄存器,但僅需配置幾個
    發表于 03-28 09:20 ?1204次閱讀

    MPC860寄存器配置

    MPC860 的系統接口單元(SIU)控制系統啟動、初始化、運行、保護和外部系統總線。這些功能是靠許多寄存器實現的。這篇文檔將詳細說明各個寄存器配置情況。
    發表于 06-08 17:54 ?53次下載
    MPC860<b class='flag-5'>寄存器</b><b class='flag-5'>配置</b>

    采用PCI9052芯片的配置寄存器及加載其驅動程序的開發

    的大小為256字節,分為頭標區和設備有關區。直接影響設備特性的配置寄存器在頭標區,其他部分則因設備而異。PCI總線配置空間通常與PCI接口芯片相關。該
    發表于 04-04 18:14 ?1697次閱讀
    采用PCI9052芯片的<b class='flag-5'>配置</b><b class='flag-5'>寄存器</b>及加載其驅動程序的開發

    GC1064寄存器配置參考文件下載

    GC1064寄存器配置參考文件下載
    發表于 05-21 16:17 ?9次下載

    IO口配置常用的8個寄存器 1.6

    IO,分別用大寫字母表示,即 x=A/B/C/D/E/F/G/H/I,端口X配置位0~15。OTYPER 寄存器,該寄存器僅用于輸出模式,在輸入模式(MODER[1:0]=00/11 時)下不起作用。該
    發表于 11-29 13:51 ?10次下載
    IO口<b class='flag-5'>配置</b>常用的8個<b class='flag-5'>寄存器</b> 1.6

    GPIO寄存器

    每組IO口有10個寄存器組成,如果芯片有GPIOA~GPIOI,9個組那么共有90個寄存器如果配置個IO口需要2個位,那么剛好32位
    發表于 12-08 17:06 ?5次下載
    GPIO<b class='flag-5'>寄存器</b>

    STM32寄存器點燈

    配置寄存器使STM32最小系統板上的LED燈點亮根據原理圖,要使D2點亮,需要將PC13拉低,分為以下步驟:使能GPIO的時鐘配置GPIO13為輸出模式
    發表于 12-08 17:21 ?3次下載
    STM32<b class='flag-5'>寄存器</b>點燈

    2021-04-17 STM32串口寄存器庫函數配置

    STM32串口寄存器庫函數配置方法STM32常用寄存器和庫函數串口配置般步驟(串口實例)常用的串口相關
    發表于 12-28 19:13 ?7次下載
    2021-04-17  STM32串口<b class='flag-5'>寄存器</b>庫函數<b class='flag-5'>配置</b>

    配置STM32寄存器控制GPIO點亮LED

    STM32點亮LED 寄存器方式IO簡介1、每個IO可以自由編程,但是IO口寄存器必須按照32位字被訪問。2、每個IO端口都有7個寄存器來控制。CRL 【0-7】端口配置
    發表于 01-13 16:15 ?3次下載
    <b class='flag-5'>配置</b>STM32<b class='flag-5'>寄存器</b>控制GPIO點亮LED

    如何在VHDL實現個簡單的寄存器

    存儲的位數上有所不同,具體取決于系統的配置。在本教程,我們將學習如何在 VHDL 實現個簡單的寄存器
    發表于 07-29 16:48 ?4729次閱讀
    如何在VHDL<b class='flag-5'>中</b>實現<b class='flag-5'>一</b>個簡單的<b class='flag-5'>寄存器</b>

    振弦采集模塊配置工具VMTool生成寄存器

    振弦采集模塊配置工具VMTool生成寄存器
    的頭像 發表于 01-16 10:45 ?710次閱讀
    振弦采集模塊<b class='flag-5'>配置</b>工具VMTool<b class='flag-5'>生成</b><b class='flag-5'>寄存器</b>值

    寄存器分為基本寄存器和什么兩種

    寄存器是計算機中用于存儲數據的高速存儲單元,它們是CPU內部的重要組成部分。寄存器可以分為基本寄存器和擴展寄存器兩種類型。 、基本
    的頭像 發表于 07-12 10:31 ?1619次閱讀
    广发百家乐官网的玩法技巧和规则| 猪猪棋牌游戏| 试玩区百家乐官网1000| 大发888娱乐城俄罗斯| 伯爵百家乐官网赌场娱乐网规则 | 百家乐牌路分析仪| 百家乐官网5式直缆打法| 百家乐java| 武汉百家乐官网庄闲和| 大发888娱乐场下载制度| 太阳百家乐官网网址| 澳门赌场招聘网| 百家乐投注限额| 真钱百家乐官网五湖四海全讯网 | 百家乐官网如何买大小| 德州扑克 规则| 百家乐客户端LV| 百家乐官网路单资料| 百家乐百家乐技巧| 百家乐官网娱乐平台代理佣金| 六合彩票| 百家乐注册送10彩金| 百家乐官网投注哪个信誉好| 大发888娱乐场 东南网| 任你博百家乐现金网| 百家乐官网开放词典新浪| 大发888大发娱乐城| 线上百家乐可靠吗| 百家乐官网半圆桌| 视频棋牌游戏大厅| 最新百家乐电脑游戏机| 玩网上百家乐官网的技巧| 大发888真坑阿| 新手百家乐指点迷津| 百家乐官网游戏全讯网2| 大发888dafa888| 百家乐路单之我见| 云鼎百家乐官网程序开发有限公司| 娱乐城网址| 澳门玩百家乐的玩法技巧和规则 | 牙克石市|