玄铁C906的FPGA移植

编程入门 行业动态 更新时间:2024-10-10 01:23:13

<a href=https://www.elefans.com/category/jswz/34/1697955.html style=玄铁C906的FPGA移植"/>

玄铁C906的FPGA移植

本来准备移植玄铁C910,初步运行发现我的FPGA容量属实不太够,就退而求其次,选择移植选题C906,本人也是第一次移植,因此会出现一些非常傻逼的问题:

我使用的FPGA为XCKU060-FFVA1156-2-I

移植第一步,去玄铁的github上把玄铁C906的开源代码下载下来。

第二步,我们创建vivado工程,导入这两个文件夹里面的所有文件,先不急着关注哪些能用哪些不能用,先全导进去,后面再进行处理

先将Non-module Files 设置为global include

将这些文件添加到include

`define NOISA
`include "aq_dtu_cfig.h"
`include "aq_idu_cfig.h"
`include "aq_lsu_cfig.h"
`include "cpu_cfig.h"
`include "sysmap.h"
`include "tdt_define.h"
`include "tdt_dmi_define.h"

删除不必要的文件,例如:

最后我们可以得到类似于下图的结构,我们可以自己加一个顶层文件:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/09/02 17:51:31
// Design Name: 
// Module Name: c906_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
`include "aq_dtu_cfig.h"
`include "aq_idu_cfig.h"
`include "aq_lsu_cfig.h"
`include "cpu_cfig.h"
`include "sysmap.h"
`include "tdt_define.h"
`include "tdt_dmi_define.h"module c906_top(clk_in1_p,clk_in1_n,reset,uart0_sin_rx,uart0_sout_tx,b_pad_gpio_porta,jclk,jrst_b,nrst_b,jtg_tdi,jtg_tdo,jtg_tms);input clk_in1_p;input clk_in1_n;input reset;//input rst_b;input uart0_sin_rx;output uart0_sout_tx;inout[7:0] b_pad_gpio_porta;input jclk;input jrst_b;input nrst_b;input jtg_tdi;output jtg_tdo;input jtg_tms ;  wire clk_out1;wire clk_out2;wire clk_out3;wire locked;//instantiate soc    clk_wiz_0 u_clk_wiz_0(// Clock out ports.clk_out1(clk_out1),     // output clk_out1.clk_out2(clk_out2),     // output clk_out2// Status and control signals.resetn(reset), // 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
);soc u_soc(.i_pad_clk            ( clk_out1             ),.i_pad_uart0_sin      ( uart0_sin_rx         ),.o_pad_uart0_sout   	( uart0_sout_tx        ),.i_pad_jtg_tclk       ( jclk             ),.i_pad_jtg_trst_b     ( jrst_b                ),.i_pad_jtg_nrst_b     ( nrst_b                ),.b_pad_gpio_porta   	( b_pad_gpio_porta     ),.i_pad_jtg_tdi        ( jtg_tdi              ),.o_pad_jtg_tdo        ( jtg_tdo              ),.i_pad_jtg_tms        ( jtg_tms              ),   .i_pad_rst_b          ( reset                )
);endmodule

我们需要自己添加时钟ip然后对时钟ip进行配置:

接着,我们可以进行端口的绑定和约束的编写

我这里附一个我自己的xdc,其他的可以类似,因为没有用到那些inout口就没有管。

set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {b_pad_gpio_porta[0]}]set_property PACKAGE_PIN AK17 [get_ports clk_in1_p]
set_property IOSTANDARD DIFF_HSTL_I_18 [get_ports clk_in1_p]
set_property PACKAGE_PIN AF13 [get_ports jtg_tdi]
set_property IOSTANDARD LVCMOS33 [get_ports jtg_tdi]
set_property PACKAGE_PIN AE11 [get_ports jtg_tdo]
set_property IOSTANDARD LVCMOS33 [get_ports jtg_tdo]
set_property PACKAGE_PIN AE13 [get_ports jtg_tms]
set_property IOSTANDARD LVCMOS33 [get_ports jtg_tms]
set_property PACKAGE_PIN N23 [get_ports reset]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN AJ11 [get_ports uart0_sin_rx]
set_property IOSTANDARD LVCMOS33 [get_ports uart0_sin_rx]
set_property PACKAGE_PIN AM9 [get_ports uart0_sout_tx]
set_property IOSTANDARD LVCMOS33 [get_ports uart0_sout_tx]set_property SLEW SLOW [get_ports jtg_tdo]
set_property SLEW SLOW [get_ports uart0_sout_tx]set_property PACKAGE_PIN AF9 [get_ports {b_pad_gpio_porta[7]}]
set_property PACKAGE_PIN AF8 [get_ports {b_pad_gpio_porta[6]}]
set_property PACKAGE_PIN AE8 [get_ports {b_pad_gpio_porta[5]}]
set_property PACKAGE_PIN AE10 [get_ports {b_pad_gpio_porta[4]}]
set_property PACKAGE_PIN AD10 [get_ports {b_pad_gpio_porta[3]}]
set_property PACKAGE_PIN AP10 [get_ports {b_pad_gpio_porta[2]}]
set_property PACKAGE_PIN AP11 [get_ports {b_pad_gpio_porta[1]}]
set_property PACKAGE_PIN AN11 [get_ports {b_pad_gpio_porta[0]}]set_property PACKAGE_PIN AJ13 [get_ports jclk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jclk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jclk_IBUF_inst/O]
set_property IOSTANDARD LVCMOS33 [get_ports jclk]#5M
create_clock -period 200.000 -name jclk -waveform {0.000 100.000} [get_ports jclk]
#create_clock -period 1000.000 -name u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q -waveform {0.000 500.000} [get_pins u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q]
#create_clock -period 1000.000 -name u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q -waveform {0.000 500.000} [get_pins u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q]
#create_clock -period 50.000 -name jclk -waveform {0.000 25.000} [get_ports jclk]
#20M
create_clock -period 50.000 -name u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q -waveform {0.000 25.000} [get_pins u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q]
#20M
create_clock -period 50.000 -name u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q -waveform {0.000 25.000} [get_pins u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q]
#create_clock -period 50.000 -name u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q -waveform {0.000 25.000} [get_pins u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q]
#set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins u_clk_wiz_0/inst/mmcme3_adv_inst/CLKOUT0]]
#set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins u_clk_wiz_0/inst/mmcme3_adv_inst/CLKOUT0]] -group [get_clocks jclk] -group [get_clocks u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q] -group [get_clocks u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q]#create_clock -period 1000.000 -name u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q -waveform {0.000 500.000} [get_pins u_soc/x_cpu_sub_system_axi/x_c906_wrapper/sys_apb_clk_reg/Q]set_property IOSTANDARD LVCMOS33 [get_ports jrst_b]
set_property IOSTANDARD LVCMOS33 [get_ports nrst_b]
set_property PACKAGE_PIN AL8 [get_ports nrst_b]
set_property PACKAGE_PIN AK8 [get_ports jrst_b]set_false_path -from [get_clocks u_soc/x_apb/x_apb_bridge/apb_xx_pwrite_reg/Q] -to [get_clocks -of_objects [get_pins u_clk_wiz_0/inst/mmcme3_adv_inst/CLKOUT0]]

这时候我们可以进行synthesis,然后可以得到类似于下图结果,由于C906外挂太多存储空间会导致bram爆了:

我们可以对代码进行一定的修改,以降低bram的占用:

①打开x_axi_slave128,将下面例化的两个spsram替换为一个更小的,c906提供了一个f_spsram_32768*12,我们就把原来的换成这个就可以了

②打开mem_ctrl,先将里面例化的ram修改为fpga_ram,然后我们便可以修改里面的MEM_ADDR_WIDTH参数,来降低ram 的宽度

修改完我们再进行systhesis和implementation,便可以得到正确的结果了。

下图便是最后生成的项目的时钟域: 和C906提供的集成手册基本吻合

我们拿cklink对生成的比特流进行测试,可以成功连接上:

后面我写一下在移植过程中遇到的一些问题:

①时钟ip的设置,一定要记得点active low,我之前一直没看到这个,导致cklink连接不上,会报下面所示的错误DMI operation result busy

②本来以为这两个rst只是普通的rst信号,我将其绑到整个c906的rst端口,导致cklink连接报错

 

具体可以去看集成手册软复位的部分

③如果遇到这个问题按照error里的check一一检查,可能是连线问题,也可能是时钟频率的设置问题 C906集成手册描述了时钟关系

更多推荐

玄铁C906的FPGA移植

本文发布于:2024-02-11 21:22:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683577.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:玄铁   FPGA

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!