windows下使用vivado将ibex_demo_system移植至XILINX-SP701开发板并使用串口调试助手成功打印helloworld

一 引言

        公司正在进行小型低功耗SOC的内核选型,Ibex作为一款优秀的RISC-V core自然成为首选目标。Ibex最早从PULP平台下的zero-riscy发展而来,目前由非盈利组织LowRISC发展和维护,Ibex有官方文档,并且有simple_system与demo_system两个系统,简单来说,simple_system系统除了挂载ram之外,还挂载有simulator_ctrl和timer两个外设,并且有一个tracing模块用于记录ibex core读取总线数据的记录,是一个主要用于simulation的system;而demo_system主要针对 FPGA 实现,包含一些额外的外设如uart、gpio、pwm等以及 RISC-V 调试模块的集成。

二 环境准备

       ibex_demo_system Github链接:GitHub - lowRISC/ibex-demo-system: A demo system for Ibex including debug support and some peripherals

        想要在windoibex_demo_system移植至FPGA开发板上前提是在linux环境下跑通ibex_simple_system,因为我在win下搭建FPGA环境时发现有几个设计文件是在linux下用官方给的脚本自动生成的,在如下文件夹中,如果不在linux下跑通simple_system,在vivado中添加设计文件时,将出现找不到的情况。在linux下跑通simple_system请参考Ibex环境建立及CoreMark测试_riscvibex-CSDN博客。后续内容默认在此基础上进行。

三 FPGA环境搭建

       本人使用的vivado版本为2018.3,使用的FPGA型号为XILINX-SP701,芯片型号为XC7S100系列,本实验对FPGA型号应该没有要求,在vivado中选择自己FPGA的芯片型号即可。

(1)add design sources

       在vivado中添加设计文件不要一股脑添加全部文件夹,建议先添加顶层ibex_demo_system,在一层一层往下添加,在文件夹中一个一个找,比较费时间,耐心添加完即可。注意有几个design source不在文件夹中,这时候就要在ibex\build文件夹中找,如上图。

(2)编写FPGA top层

       根据自己的需要编写顶层代码,我的代码如下:

// This is the top level SystemVerilog file that connects the IO on the board to the Ibex Demo System on Nexys-A7 board.

module top_sp701 (
  // These inputs are defined in data/pins_nexysa7.xdc
  input               clk_in1_p,//clk200mhz
  input               clk_in1_n,//clk200mhz
  input               IO_RST_N,//cpu_resetn
  input  [ 3:0]       SW,//SW
  output [ 3:0]       LED,//LED
//output [ 3:0]       RGB_LED,//[0:5] = led16_b/led16_g/led16_r/led17_b/led17_g/led17_r
  input               UART_RX,//uart_rxd_out
  output              UART_TX,//uart_txd_in
  output logic        led_bootok,
//  input               SPI_RX,
//  output              SPI_TX,
//  output              SPI_SCK
  input  logic        tck_i,    // JTAG test clock pad
  input  logic        tms_i,    // JTAG test mode select pad
  input  logic        td_i,     // JTAG test data input pad
  output logic        td_o      // JTAG test data output pad
  
);
  parameter SRAMInitFile = "";
 
  logic clk_sys, rst_sys_n;
//wire clk_25m;
//logic mainclk_buf;
  logic locked;
  logic rst_btn;
  assign led_bootok = rst_sys_n;
  logic clk_rst;
  
   clk_wiz_0 instance_name0
   (
    // Clock out ports
    .clk_out1(clk_sys),     // output clk_out1
    .clk_out2(clk_rst),     // output clk_out2
    // Status and control signals
    .reset(IO_RST_N), // input reset
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1_p(clk_in1_p),    // input clk_in1_p
    .clk_in1_n(clk_in1_n)    // input clk_in1_n
    );      
    
  // Instantiating the Ibex Demo System.
  ibex_demo_system #(
    .GpiWidth(4),
    .GpoWidth(4),
    .PwmWidth(4),
    .SRAMInitFile(SRAMInitFile)
  ) u_ibex_demo_system (
    //input
    .clk_sys_i(clk_sys),
    .rst_sys_ni(rst_sys_n),
    .gp_i(SW),
    .uart_rx_i(UART_RX),
 
    //output
    .gp_o(LED),
    .pwm_o(),
    .uart_tx_o(UART_TX),
 
    .spi_rx_i(1'b0),
    .spi_tx_o(),
    .spi_sck_o(),
	
	.tck_i(tck_i),
	.tms_i(tms_i),
	.trst_ni(rst_sys_n),
	.td_i(td_i),
	.td_o(td_o)
  );
  // Generating the system clock and reset for the FPGA.

  assign rst_btn = IO_RST_N;

  rst_ctrl u_rst_ctrl (
    .clk_i       (clk_rst),
    .pll_locked_i(locked),
    .rst_btn_i   (rst_btn),
    .rst_no      (rst_sys_n)
  );


endmodule

       由于跑helloworld_test只需要用到uart和jtag接口,所以其他模块我没有用到,如spi输入引脚直接给0,输出引脚直接悬空,大家可以根据自己的需要编写顶层模块。需要注意的是,我使用的SP701开发板板载时钟是频率200M的差分时钟,而ibex所需要的时钟频率为50M,所以在vivado中需要添加pll ipcore,如下图,这属于基本FPGA开发,这里就不多赘述了。需要注意的是,当时钟为差分时钟时,如下图右下角所示,时钟源需选择“Differential clock capable pin”。

       另外,我用了一个ledboot_ok信号接到板载的led灯上,目的是监测rst_ctrl模块是否正常工作并提供rst_sys_n信号,如果ledboot_ok信号接的led灯没有亮,就不要进行后续任何操作,进行了也会在jtag调试时显示no jtag device found,先检查前面的操作是否有问题。

(3)add constraints 

        编写完top层后需要添加xdc文件,完整的约束文件如下: 

## This file is a general .xdc for the SP701
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
 
## Clock signal
#set_property -dict { PACKAGE_PIN AE8 IOSTANDARD DIFF_SSTL15 } [get_ports {clk_in1_p}]; 
create_clock -period 5.00 [get_ports {clk_in1_p}];

set_property IOSTANDARD DIFF_SSTL15 [get_ports clk_in1_p]
set_property PACKAGE_PIN AE8 [get_ports clk_in1_p]

#set_property -dict { PACKAGE_PIN AE8 IOSTANDARD LVDS } [get_ports {clk_in1_n}]; 
#create_clock -add -name sys_clk_pin -period 5.00 [get_ports {clk_in1_n}];

set_property IOSTANDARD DIFF_SSTL15 [get_ports clk_in1_n]
set_property PACKAGE_PIN AE7 [get_ports clk_in1_n]
#sw5 
set_property IOSTANDARD LVCMOS33 [get_ports IO_RST_N]
set_property PACKAGE_PIN AF23 [get_ports IO_RST_N]

##Switches SW6/SW7/SW4/SW9
set_property -dict { PACKAGE_PIN AA20   IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN AB20   IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN AB22   IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN AC22   IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]

 
## LEDs GPIO_LED 0-3
set_property -dict { PACKAGE_PIN J25   IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN M24   IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN L24   IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN K25   IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
set_property -dict { PACKAGE_PIN K26   IOSTANDARD LVCMOS33 } [get_ports { led_bootok }]; #IO_L8P_T1_D11_14 Sch=led[4]

##USB-RS232 Interface PMOD1 6/8
set_property -dict { PACKAGE_PIN A14    IOSTANDARD LVCMOS33 } [get_ports { UART_RX }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN A15    IOSTANDARD LVCMOS33 } [get_ports { UART_TX }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out

#pin1
set_property IOSTANDARD LVCMOS33 [get_ports tck_i]
set_property PACKAGE_PIN C13 [get_ports tck_i]

#create_clock -name jtag_clk_pin -period 300 [get_ports {jtag_TCK}];
#pin4
set_property IOSTANDARD LVCMOS33 [get_ports tms_i]
set_property PACKAGE_PIN B15 [get_ports tms_i]
#pin2
set_property IOSTANDARD LVCMOS33 [get_ports td_i]
set_property PACKAGE_PIN D14 [get_ports td_i]
#pin3
set_property IOSTANDARD LVCMOS33 [get_ports td_o]
set_property PACKAGE_PIN B14 [get_ports td_o]
#pin7
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_i]

       本人是将uart、jtag全部接到FPGA的普通IO口上,使用外部的uart和jtag调试模块进行调试,约束文件需要注意两个点:1.注意差分时钟管脚的约束;2.由于jtag使用外部的调试器,所以引脚都直接接到开发板上的普通IO口上,所以要添加“set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_i]”,不然生成bitstream时会报错。

      至此,生成bitstream前期准备工作全部完成,接下来就是等待bitstream的生成,生成结束后烧写至开发板上,烧写后,检查ledboot_ok信号接的led灯有没有亮,如果亮了,恭喜你,已经成功将demo_system移植至FPGA开发板上,并且demo_system已经在开发板上正常运行了!

四 FPGA连线

       请正确连线,jtag中tck、tms、tdi、tdo引脚需正确连接FPGA上所绑定的对应IO口,uart调试模块中rx引脚需接FPGA上绑定的tx信号IO口,如下图所示。

        连线完毕后,我们要运行的驱动程序是ibex-demo-system\sw\c\demo\hello_world下的main.c文件,使用的是openocd.exe进行调试,这里需要编写openocd的配置文件(.cfg文件):

# script for ibex family

#
# riscv devices support jtag transports only.
#
adapter driver jlink
adapter speed 1000
transport select jtag

#source [find target/swj-dp.tcl]
#source [find mem_helper.tcl]

set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id  0x11001cdf

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME

#riscv set_reset_timeout_sec 1

riscv set_reset_timeout_sec 2000
riscv set_command_timeout_sec 2000

#gdb_report_data_abort enable
#gdb_report_register_access_error enable
#gdb_breakpoint_override hard

#reset_config none

# prefer to use sba for system bus access
riscv set_prefer_sba on

# dump jtag chain
scan_chain

init
halt

编写完配置文件后,接入openocd,成功识别jtag会打印以下信息:

     做到这儿就已经成功了,接下来的就是打开串口调试助手并运行驱动程序,可以看到,串口成功打印Hello World!

五 结语

       至此,windows下使用vivado将ibex_demo_system移植至XILINX-SP701开发板并使用串口调试助手成功打印helloworld的实验就全部完成了,在ibex-demo-system\sw\c\demo下还有别的驱动程序,大家有兴趣可以试一试。

       本人是刚踏入ic行业的小白,第一次编写文档,可能有错误或是不足之处,还望大家批评指正。

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值