手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】

我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索和数字IC设计。
CSDN个人博客链接:https://blog.csdn.net/qq_44447544?spm=1000.2115.3001.5343
关注公众号【集成电路设计教程】,获取更多学习资料,并拉你进“IC设计交流群”。
QQIC设计交流群 群号:866169462
所用开发板:正点原子达芬奇FPGA开发板
芯片型号:Xilinx Artix-7 35T
应群友之邀,分享下集创芯来RISC-V杯赛 所用的软核 蜂鸟E203 hbirdv2移植教程。
思路: 参考Nulei开发板的顶层代码(e200_opensource-master/fpga/nucleikit/src/system.v(后缀不是.v可以自己改下然后打开))和约束文件(e200_opensource-master/fpga/nucleikit/constrs),写达芬奇开发板的顶层代码和约束文件,具体步骤如下所示。

如果觉得步骤有点多,那也可以直接用我搭建好的 Vivado( 2018.3 版本) 工程。资源链接:https://download.csdn.net/download/qq_44447544/83354895
一、管脚分析 手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

1.1 时钟管脚 首先看时钟管脚的绑定,MCU SoC 的两个输入时钟输入在 nuclei-kit 上分别按照如下方式产生:
  • 低速的实时时钟直接由 FPGA 开发板上的 32.768KHz 时钟源输入。
  • 高速时钟由 FPGA 开发板上的 100MHz 时钟经过 FPGA 内部 PLL 降频而得(16MHz)
(1)16M时钟生成
而现在达芬奇开发板上只有一个50MHz时钟源,所以我先用MMCM将50MHz时钟源降频为 16MHz ( 32.768KHz由于频率过低无法通过此IP实现,需要自己写分频器),使用的是此 IP,具体用法可参考 正点原子达芬奇之FPGA开发指南1.1 第十五章 IP核之MMCM/PLL实验 ,这里不过多讲解。
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

例化使用如下图所示,然后可以把原顶层的那个MMCM IP核例化给删了
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

(2)32.768KHz 时钟生成
分频器代码如下:
// 50MHz --> 32768Hz 约为1526倍 50MHz/1526=32765.4 HZ,作为常开域时钟 module clk_div( inputclk, inputrst_n, output regclk_div ); parameter NUM_DIV = 11'd1526; reg[10:0] cnt; always @(posedge clk or negedge rst_n) if(!rst_n) begin cnt<= 11'd0; clk_div <= 1'b0; end else if(cnt < NUM_DIV / 2 - 1) begin cnt<= cnt + 1'b1; clk_div <= clk_div; end else begin cnt<= 11'd0; clk_div <= ~clk_div; end endmodule

在顶层例化并绑定对应信号
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

这样时钟部分顶层的代码修改算是完成了,之后就是管脚约束了,将CLK50MHZ绑定到开发板的时钟源管脚即可。
1.2 复位管脚 nuclei-kit它的rtl顶层模块有两个复位信号,分别是 fpga_rstmcu_rst,即FPGA开发板自身的复位和为MCU设置的复位,这两个复位通过一个与操作生成一个为SoC使用的复位信号,即SoC复位的条件是这两个复位信号至少有一个生效。由于这两个复位信号都是低电平有效,故分别绑定到达芬奇开发板上的 RESET 和 KEY0 按键即可,其中RESET 是FPGA自身的复位键,而KEY0 是为MCU设置的复位键(达芬奇开发板上的按键都是按下去为0,松开为1,满足低电平有效的要求)。
1.3 QSPI接口 蜂鸟E203 有三个qspi接口,分别为QSPI0、QSPI1、QSPI2,其中QSPI0专门是为外部FLASH准备的,而其余两个都是通过GPIO口复用进行使用。所以rtl顶层需要绑定的是专为外部FLASH准备的QSPI接口,目前由于没有外部FLASH,所以先绑定到达芬奇开发板上的空闲IO口上。
1.4 PMU管脚 PMU用于控制主域电源,可以使主域被置于断电状态以节省功耗,或者重新唤醒。pmu_paden 用于MCU的电源指示,pmu_padrst 指示MCU的复位,这两个可以接达芬奇开发板上的LED,而mcu_wakeup 用于唤醒,低电平有效,可以接达芬奇开发板的按键。
1.5 其他管脚 32个GPIO和JTAG管脚绑定到开发板上的空闲IO口上即可,无需更改代码。
1.6 ip_reset_sys的处理 nuclei-kit的RTL顶层还使用了 Processor System Reset IP核,所以要把这个IP核添加进去(配置保持默认即可,只需把原代码中的模块名改为IP核中默认名 proc_sys_reset_0 即可)
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

1.7 上电流程控制配置 蜂鸟 E203 MCU SoC芯片顶层引脚中 io_pads_bootrom_n_i_ival 是用来配置上电地址选择的,即上电复位后处理器核从哪个地址开始上电执行,此信号为1时,处理器核从外部flash地址(0x2000_0000)开始执行,这也是默认的上电流程配置;而当此信号为0时,处理器核从内部 rom 地址(0x0000_1000)开始执行,而 rom 中存放的代码执行完后会跳转至ITCM(0x8000_0000)中继续执行。由于目前达芬奇开发板上没有第二块 flash,所以需要将此信号配置为 0.
在Nulei开发板的顶层代码 979行是对此信号的配置,将此处改为0即可。
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

修改后如下所示:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

1.8 管脚约束编写 至此就可以按照之前的分析编写管脚约束了,对应关系在 二、管脚约束概览 中,代码见 三、DaVinci约束文件代码
1.9 综合实现和生成比特流文件 【手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】】首先需要设置一下define.v文件的路径,如下图所示:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

有两个路径分别为
e200_opensource-master\rtl\e203\core e200_opensource-master\rtl\e203\perips

选中工程中这两个文件夹就可以了,如下图所示:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

RTL原理图:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

综合实现结果图:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

资源利用:
手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

二、管脚约束概览 手把手教你移植蜂鸟E203 hbridv2【集创芯来RISC-V杯】
文章图片

三、DaVinci约束文件代码
set_property CFGBVS VCCO [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design]#####create clock##### set_property -dict { PACKAGE_PIN R4IOSTANDARD LVCMOS33 } [get_ports { CLK50MHZ }]; create_clock -add -name sys_clk_pin -period 20.00 -waveform {0 5} [get_ports {CLK50MHZ}]; set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets dut_io_pads_jtag_TCK_i_ival] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets IOBUF_jtag_TCK/O]#####rst define##### set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports {fpga_rst}]; set_property -dict { PACKAGE_PIN T1 IOSTANDARD LVCMOS33 } [get_ports {mcu_rst}]; #####spi define##### set_propertyPACKAGE_PIN N15 [get_portsqspi_cs ] set_propertyPACKAGE_PIN P19 [get_portsqspi_sck] set_propertyPACKAGE_PIN R17 [get_ports{qspi_dq[3]}] set_propertyPACKAGE_PIN J16 [get_ports{qspi_dq[2]}] set_propertyPACKAGE_PIN M13 [get_ports{qspi_dq[1]}] set_propertyPACKAGE_PIN K14 [get_ports{qspi_dq[0]}]#####MCU JTAG define##### set_propertyPACKAGE_PIN Y8[get_ports mcu_TDO] set_propertyPACKAGE_PIN AA8[get_ports mcu_TCK] set_propertyPACKAGE_PIN Y7[get_ports mcu_TDI] set_propertyPACKAGE_PIN AB8[get_ports mcu_TMS]#####PMU define##### set_propertyPACKAGE_PIN R2 [get_ports pmu_paden ] set_propertyPACKAGE_PIN R3 [get_ports pmu_padrst] set_propertyPACKAGE_PIN U1 [get_ports mcu_wakeup]#####gpio define##### set_propertyPACKAGE_PIN L16 [get_ports {gpio[31]}] set_propertyPACKAGE_PIN K16 [get_ports {gpio[30]}] set_propertyPACKAGE_PIN L19 [get_ports {gpio[29]}] set_propertyPACKAGE_PIN L20 [get_ports {gpio[28]}] set_propertyPACKAGE_PIN U20 [get_ports {gpio[27]}] set_propertyPACKAGE_PIN T20 [get_ports {gpio[26]}] set_propertyPACKAGE_PIN N18 [get_ports {gpio[25]}] set_propertyPACKAGE_PIN N19 [get_ports {gpio[24]}] set_propertyPACKAGE_PIN N20 [get_ports {gpio[23]}] set_propertyPACKAGE_PIN M20 [get_ports {gpio[22]}] set_propertyPACKAGE_PIN J20 [get_ports {gpio[21]}] set_propertyPACKAGE_PIN J21 [get_ports {gpio[20]}] set_propertyPACKAGE_PIN H20 [get_ports {gpio[19]}] set_propertyPACKAGE_PIN G20 [get_ports {gpio[18]}] set_propertyPACKAGE_PIN M18 [get_ports {gpio[17]}] set_propertyPACKAGE_PIN L18 [get_ports {gpio[16]}] set_propertyPACKAGE_PIN F18 [get_ports {gpio[15]}] set_propertyPACKAGE_PIN F21 [get_ports {gpio[14]}] set_propertyPACKAGE_PIN D17 [get_ports {gpio[13]}] set_propertyPACKAGE_PIN E17 [get_ports {gpio[12]}] set_propertyPACKAGE_PIN M22 [get_ports {gpio[11]}] set_propertyPACKAGE_PIN N22 [get_ports {gpio[10]}] set_propertyPACKAGE_PIN L21 [get_ports {gpio[9]} ] set_propertyPACKAGE_PIN M21 [get_ports {gpio[8]} ] set_propertyPACKAGE_PIN K21 [get_ports {gpio[7]} ] set_propertyPACKAGE_PIN K22 [get_ports {gpio[6]} ] set_propertyPACKAGE_PIN H22 [get_ports {gpio[5]} ] set_propertyPACKAGE_PIN J22 [get_ports {gpio[4]} ] set_propertyPACKAGE_PIN G21 [get_ports {gpio[3]} ] set_propertyPACKAGE_PIN G22 [get_ports {gpio[2]} ] set_propertyPACKAGE_PIN D19 [get_ports {gpio[1]} ] set_propertyPACKAGE_PIN E19 [get_ports {gpio[0]} ]#####spi define##### set_property IOSTANDARD LVCMOS33 [get_portsqspi_cs] set_property IOSTANDARD LVCMOS33 [get_portsqspi_sck] set_property IOSTANDARD LVCMOS33 [get_ports {qspi_dq[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {qspi_dq[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {qspi_dq[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {qspi_dq[0]}]#####MCU JTAG define##### set_property IOSTANDARD LVCMOS33 [get_ports mcu_TDO] set_property IOSTANDARD LVCMOS33 [get_ports mcu_TCK] set_property IOSTANDARD LVCMOS33 [get_ports mcu_TDI] set_property IOSTANDARD LVCMOS33 [get_ports mcu_TMS]#####PMU define##### set_property IOSTANDARD LVCMOS33 [get_ports pmu_paden ] set_property IOSTANDARD LVCMOS33 [get_ports pmu_padrst] set_property IOSTANDARD LVCMOS33 [get_ports mcu_wakeup]#####gpio define##### set_property IOSTANDARD LVCMOS33 [get_ports {gpio[31]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[30]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[29]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[28]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[27]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[26]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[25]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[24]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[23]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[22]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[21]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[20]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[19]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[18]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[17]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[16]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[15]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[14]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[13]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[12]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[11]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[10]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[9]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[8]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio[0]}]#####SPI Configurate Setting####### set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] set_property CONFIG_MODE SPIx4 [current_design] set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]

  • 更多技术文章和学习资料,请关注我的公众号:【集成电路设计教程】
  • 全平台统一:【雪天鱼】

    推荐阅读