第1章 使用SF1的硬核1.1 使用IP Generator生成RISC-V硬核和PLL核创建工程并选择器件为SF160CG121I。 点击Tools->IP Generator,选择Create an IP core,生成RISC-V核SF1_MCU和PLL核sys_pll。 1.2 设计GPIO接口电路在创建SF1_MCU IP的时候,选中了3个GPIO输出,在左侧的示意图上会出现三组GPIO相关的端口。 每组端口由gpiox_in、gpiox_out、gpiox_dir(x=0,1,2,3….n),与 FPGA的物理端口连接需要添加一个控制电路,该控制电路中gpio_dir控制物理端口和gpio0_in还是和gpio0_out相连接。具体代码如下: - module gpio_controller(
- output wire O_gpio_in,
- input wire I_gpio_dir,//1'b0:input ,1'b1:output
- input wire I_gpio_out,
-
- inout wire IO_gpio
- );
- assign IO_gpio = I_gpio_dir?I_gpio_out:1'bz;
- assign O_gpio_in=IO_gpio;
- endmodule
复制代码 1.3 设计SOC模块以及使用结合上述配置好的RISC-V IP核和GPIO接口电路模块,组成一个可以供外部调用的SOC模块,具体代码如下: - module SF1_SOC(
- input wire I_clk,
- input wire I_rst,
- input wire I_timer_clk,
-
- input wire I_jtag_tck,
- output wire O_jtag_tdo,
- input wire I_jtag_tms,
- input wire I_jtag_tdi,
- input wire I_uart_rx,
- output wire O_uart_tx,
-
- //
- inout wire IO_gpio_LED_R,
- inout wire IO_gpio_LED_G,
- inout wire IO_gpio_LED_B,
-
- inout wire IO_gpio_OLED_DC,
- inout wire IO_gpio_OLED_RST,
- inout wire IO_gpio_OLED_SDA,
- inout wire IO_gpio_OLED_SCK,
- inout wire IO_gpio_KEY_K2,
-
- output wire[1:0] O_ahb_htrans,
- output wire O_ahb_hwrite,
- output wire[31:0] O_ahb_haddr,
- output wire[2:0] O_ahb_hsize,
- output wire[2:0] O_ahb_hburst,
- output wire[3:0] O_ahb_hprot,
- output wire O_ahb_hmastlock,
- output wire[31:0] O_ahb_hwdata,
- input wire I_ahb_hclk,
- input wire[31:0] I_ahb_hrdata,
- input wire[1:0] I_ahb_hresp,
- input wire I_ahb_hready
- );
- //LED Group
- wire S_gpio0_out;
- wire S_gpio0_dir;
- wire S_gpio0_in;
- wire S_gpio1_out;
- wire S_gpio1_dir;
- wire S_gpio1_in;
- wire S_gpio2_out;
- wire S_gpio2_dir;
- wire S_gpio2_in;
- //gpio_controller instances LED Controller Pins
- gpio_controller u0_gpio_controller(
- .O_gpio_in(S_gpio0_in),
- .I_gpio_dir(S_gpio0_dir),
- .I_gpio_out(S_gpio0_out),
-
- .IO_gpio(IO_gpio_LED_R)
- );
- gpio_controller u1_gpio_controller(
- .O_gpio_in(S_gpio1_in),
- .I_gpio_dir(S_gpio1_dir),
- .I_gpio_out(S_gpio1_out),
-
- .IO_gpio(IO_gpio_LED_G)
- );
-
- gpio_controller u2_gpio_controller(
- .O_gpio_in(S_gpio2_in),
- .I_gpio_dir(S_gpio2_dir),
- .I_gpio_out(S_gpio2_out),
-
- .IO_gpio(IO_gpio_LED_B)
- );
-
- //OLED Pins
- wire S_gpioDC_out;
- wire S_gpioDC_dir;
- wire S_gpioDC_in;
- wire S_gpioRST_out;
- wire S_gpioRST_dir;
- wire S_gpioRST_in;
- wire S_gpioSDA_out;
- wire S_gpioSDA_dir;
- wire S_gpioSDA_in;
- wire S_gpioSCK_out;
- wire S_gpioSCK_dir;
- wire S_gpioSCK_in;
- //OLED Controller Pin
- gpio_controller u3_gpio_controller(
- .O_gpio_in(S_gpioDC_in),
- .I_gpio_dir(S_gpioD_dir),
- .I_gpio_out(S_gpioDC_out),
-
- .IO_gpio(IO_gpio_OLED_DC)
- );
- gpio_controller u4_gpio_controller(
- .O_gpio_in(S_gpioRST_in),
- .I_gpio_dir(S_gpioRST_dir),
- .I_gpio_out(S_gpioRST_out),
-
- .IO_gpio(IO_gpio_OLED_RST)
- );
-
- gpio_controller u5_gpio_controller(
- .O_gpio_in(S_gpioSDA_in),
- .I_gpio_dir(S_gpioSDA_dir),
- .I_gpio_out(S_gpioSDA_out),
-
- .IO_gpio(IO_gpio_OLED_SDA)
- );
- gpio_controller u6_gpio_controller(
- .O_gpio_in(S_gpioSCK_in),
- .I_gpio_dir(S_gpioSCK_dir),
- .I_gpio_out(S_gpioSCK_out),
-
- .IO_gpio(IO_gpio_OLED_SCK)
- );
- //K2
- wire S_gpioK2_out;
- wire S_gpioK2_dir;
- wire S_gpioK2_in;
- gpio_controller u7_gpio_controller(
- .O_gpio_in(S_gpioK2_in),
- .I_gpio_dir(S_gpioK2_dir),
- .I_gpio_out(S_gpioK2_out),
-
- .IO_gpio(IO_gpio_KEY_K2)
- );
- //SF1_MCU Instance
- //SF1_MCU
- SF1_MCU u_SF1_MCU(
- .core_clk(I_clk),
- .timer_clk(I_timer_clk),
- .core_reset(I_rst),
-
- .jtag_tck(I_jtag_tck),
- .jtag_tdo(O_jtag_tdo),
- .jtag_tms(I_jtag_tms),
- .jtag_tdi(I_jtag_tdi),
-
-
- .soft_ip_apbm_en(1'b0),
- .qspi0cfg1_mode(1'b1),
- .qspi0cfg2_mode(1'b1),
-
- .uart_tx(O_uart_tx),
- .uart_rx(I_uart_rx),
- .gpio0_out(S_gpio0_out),
- .gpio0_dir(S_gpio0_dir),
- .gpio0_in(S_gpio0_in),
-
- .gpio1_out(S_gpio1_out),
- .gpio1_dir(S_gpio1_dir),
- .gpio1_in(S_gpio1_in),
-
- .gpio2_out(S_gpio2_out),
- .gpio2_dir(S_gpio2_dir),
- .gpio2_in(S_gpio2_in),
- .gpio3_out(S_gpioDC_out),
- .gpio3_dir(S_gpioDC_dir),
- .gpio3_in(S_gpioDC_in),
-
- .gpio4_out(S_gpioRST_out),
- .gpio4_dir(S_gpioRST_dir),
- .gpio4_in(S_gpioRST_in),
-
- .gpio5_out(S_gpioSDA_out),
- .gpio5_dir(S_gpioSDA_dir),
- .gpio5_in(S_gpioSDA_in),
- .gpio6_out(S_gpioSCK_out),
- .gpio6_dir(S_gpioSCK_dir),
- .gpio6_in(S_gpioSCK_in),
-
- .gpio7_out(S_gpioK2_out),
- .gpio7_dir(S_gpioK2_dir),
- .gpio7_in(S_gpioK2_in),
- // .mtip(),
- // .apb_clk(),
- // .apb_paddr(),
- // .apb_pwrite(),
- // .apb_penable(),
- // .apb_pprot(),
- // .apb_pstrobe(),
- // .apb_psel(),
- // .apb_pwdata(),
- // .apb_prdata(),
- // .apb_pready(),
- // .apb_pslverr(),
- .nmi(),
- .clic_irq(),
- .sysrstreq(),
- .apb_clk_down(),
- .apb_paddr_down(),
- .apb_penable_down(),
- .apb_pprot_down(),
- .apb_prdata_down(),
- .apb_pready_down(),
- .apb_pslverr_down(),
- .apb_pstrobe_down(),
- .apb_pwdata_down(),
- .apb_pwrite_down(),
- .apb_psel0_down(),
- .apb_psel1_down(),
- .apb_psel2_down(),
-
- .htrans ( O_ahb_htrans ),
- .hwrite ( O_ahb_hwrite ),
- .haddr ( O_ahb_haddr ),
- .hsize ( O_ahb_hsize ),
- .hburst ( O_ahb_hburst ),
- .hprot ( O_ahb_hprot ),
- .hmastlock ( O_ahb_hmastlock ),
- .hwdata ( O_ahb_hwdata ),
- .hclk ( I_ahb_hclk ),
- .hrdata ( I_ahb_hrdata ),
- .hresp ( I_ahb_hresp ),
- .hready ( I_ahb_hready )
- );
- endmodule
复制代码
在TOP模块中调用,SOC模块和PLL模块 - module top(
- input wire I_clk_25m,
- input wire I_rst_n,
- input wire I_jtag_tck,
- output wire O_jtag_tdo,
- input wire I_jtag_tms,
- input wire I_jtag_tdi,
-
- input wire I_uart_rx,
- output wire O_uart_tx,
- output wire O_led0,
- output wire O_led1,
- output wire O_led2,
- output wire O_oled_dc,
- output wire O_oled_rst,
- output wire O_oled_sda,
- output wire O_oled_sck,
-
- inout wire I_KEY_K2
- );
-
-
- localparam FPGA_VERSION = 32'h22060901;
-
- wire S_sys_clk_100m;
- wire S_rst;
- wire[1:0] S_ahb_htrans_master;
- wire S_ahb_hwrite_master;
- wire[31:0] S_ahb_haddr_master;
- wire[2:0] S_ahb_hsize_master;
- wire[2:0] S_ahb_hburst_master;
- wire[3:0] S_ahb_hprot_master;
- wire S_ahb_hmastlock_master;
- wire[31:0] S_ahb_hwdata_master;
- wire[31:0] S_ahb_hrdata_master;
- wire[1:0] S_ahb_hresp_master;
- wire S_ahb_hready_master;
-
- assign S_rst = ~I_rst_n;
- sys_pll u_pll(
- .refclk ( I_clk_25m ),
- .reset ( S_rst ),
- .clk0_out ( S_sys_clk_100m )
- );
- SF1_SOC u_SF1_SOC(
- .I_clk ( S_sys_clk_100m ),
- .I_timer_clk ( I_clk_25m ),
- .I_rst ( S_rst ),
- .I_jtag_tck ( I_jtag_tck ),
- .O_jtag_tdo ( O_jtag_tdo ),
- .I_jtag_tms ( I_jtag_tms ),
- .I_jtag_tdi ( I_jtag_tdi ),
-
- .I_uart_rx ( I_uart_rx ),
- .O_uart_tx ( O_uart_tx ),
- .IO_gpio_LED_R ( O_led0 ),
- .IO_gpio_LED_G ( O_led1 ),
- .IO_gpio_LED_B ( O_led2 ),
-
- .IO_gpio_OLED_DC(O_oled_dc),
- .IO_gpio_OLED_RST(O_oled_rst),
- .IO_gpio_OLED_SDA(O_oled_sda),
- .IO_gpio_OLED_SCK(O_oled_sck),
- .IO_gpio_KEY_K2(I_KEY_K2)
- );
- ahb_to_register u_ahb_to_register(
- .I_ahb_clk ( S_clk_70m ),
- .I_rst ( S_rst ),
-
- .I_ahb_htrans ( S_ahb_htrans_master ),
- .I_ahb_hwrite ( S_ahb_hwrite_master ),
- .I_ahb_haddr ( S_ahb_haddr_master ),
- .I_ahb_hsize ( S_ahb_hsize_master ),
- .I_ahb_hburst ( S_ahb_hburst_master ),
- .I_ahb_hprot ( S_ahb_hprot_master ),
- .I_ahb_hmastlock ( S_ahb_hmastlock_master ),
- .I_ahb_hwdata ( S_ahb_hwdata_master ),
- .O_ahb_hrdata ( S_ahb_hrdata_master ),
- .O_ahb_hresp ( S_ahb_hresp_master ),
- .O_ahb_hready ( S_ahb_hready_master ),
-
- .I_pl_version ( 32'h22060901 ),
- .O_pl_led ( O_led )
- );
- endmodule
复制代码
添加管脚约束,通过查看硬件原理图,可以整理出使用到的IO端口连接 TOP端口 | FPGA端口 | 外设 | I_clk_25m | D7 | 25M无源晶振 | I_rst_n | H3 | 按键K0 | I_jtag_tck | C7 | JTAG TCK引脚 | O_jtag_tdo | C6 | JTAG TDO引脚 | I_jtag_tms | D6 | JTAG TMS引脚 | I_jtag_tdi | D5 | JTAG TDI引脚 | O_led0 | J4 | LED0 | O_led1 | H5 | LED1 | O_led2 | J5 | LED2 | I_uart_rx | E4 | SF1_UART_RX | O_uart_tx | A4 | SF1_UART_TX |
添加完成IO约束和时序约束后,就可以生成位流文件,准备接下来的下载了。
第2章 RISC-V程序编写上述过程完成了RISC-V硬核的实现,接下来需要在编写运行在RISC-V处理器上程序。 2.1 开发环境准备SF1上的RISC-V硬核的程序是在Future Dynasty(FD)集成开发环境中进行的,开发工具直接将压缩包解压到硬盘上即可,注意在路径中不要有中文,否则会有乱码、编译器无法执行等问题。 2.2 创建工程在File->New中选择Project,按下图中所示的流程创建gpio_demo工程。 2.3下载工程创建完成后,由于串口驱动中的波特率驱动存在bug,需要对驱动程序进行修改,修改的地方位于
修改后就可以正常使用UART了。编译工程后,在工程的Debug文件夹下查看可产生的二进制文件。回到TD软件中,点击工具栏中的Download按钮。在页面中选择FPGA的位留文件和RISC-V工程的Hex文件,下载方式选择PROGRAM RISCV IMG,下载时,记得点击文件列表中的位流文件,这样下载时才不会报错。 实际运行效果如图所示
|