core目录主要存放E203 core的RTL代码;
debug目录存放debug相关模块的RTL代码;
fab目录存放总线bus fabric的RTL代码;
general目录存放一些公用的通用RTL代码;
mems目录存放memory模块的RTL代码;
perips目录存放外设peripherals模块的RTL代码;
soc目录存放e203_soc_top.v,是用软核包括外设构成的系统芯片的顶层文件;
subsy目录存放完整子系统顶层的RTL代码;
system.v为工程的顶层文件,对蜂鸟软核进行了封装,主要功能为由输入时钟产生蜂鸟软核所需要的16MHz和32.768KHz的时钟,还包括复位电路和相关的IO缓存电路。
以上目录内都是Verilog RTL源代码,方便查看研究或移植到不同fpga芯片平台。
再看下蜂鸟软核的配置文件,具体代码如下:
`define E203_CFG_DEBUG_HAS_JTAG
`define E203_CFG_IRQ_NEED_SYNC
//`define E203_CFG_ADDR_SIZE_IS_16
//`define E203_CFG_ADDR_SIZE_IS_24
`define E203_CFG_ADDR_SIZE_IS_32
`ifdef E203_CFG_ADDR_SIZE_IS_16
`define E203_CFG_ADDR_SIZE 16
`endif
`ifdef E203_CFG_ADDR_SIZE_IS_32
`define E203_CFG_ADDR_SIZE 32
`endif
`ifdef E203_CFG_ADDR_SIZE_IS_24
`define E203_CFG_ADDR_SIZE 24
`endif
//`define E203_CFG_SUPPORT_MSCRATCH
`define E203_CFG_SUPPORT_MCYCLE_MINSTRET
`define E203_CFG_REGNUM_IS_32
/////////////////////////////////////////////////////////////////
`define E203_CFG_HAS_ITCM
// 64KB have address 16bits wide
// The depth is64*1024*8/64=8192
`define E203_CFG_ITCM_ADDR_WIDTH 16
// // 1024KB have address 20bits wide
// // The depth is1024*1024*8/64=131072
//`define E203_CFG_ITCM_ADDR_WIDTH 20
// // 2048KB have address 21bits wide
// // The depth is2*1024*1024*8/64=262144
//`define E203_CFG_ITCM_ADDR_WIDTH 21
/////////////////////////////////////////////////////////////////
`define E203_CFG_HAS_DTCM
// 16KB have address 14 wide
// The depth is16*1024*8/32=4096
// 256KB have address 18 wide
// The depth is256*1024*8/32=65536
// // 1MB have address 20bits wide
// // The depth is1024*1024*8/32=262144
/////////////////////////////////////////////////////////////////
//`define E203_CFG_REGFILE_LATCH_BASED
//
//
`define E203_CFG_ITCM_ADDR_BASE `E203_CFG_ADDR_SIZE'h8000_0000
`define E203_CFG_DTCM_ADDR_BASE `E203_CFG_ADDR_SIZE'h9000_0000
// *PPI : 0x1000 0000 -- 0x1FFF FFFF
`define E203_CFG_PPI_ADDR_BASE `E203_CFG_ADDR_SIZE'h1000_0000
`define E203_CFG_PPI_BASE_REGION `E203_CFG_ADDR_SIZE-1:`E203_CFG_ADDR_SIZE-4
// * CLINT : 0x0200 0000 -- 0x0200 FFFF
// * PLIC : 0x0C00 0000 -- 0x0CFF FFFF
`define E203_CFG_CLINT_ADDR_BASE `E203_CFG_ADDR_SIZE'h0200_0000
`define E203_CFG_CLINT_BASE_REGION `E203_CFG_ADDR_SIZE-1:`E203_CFG_ADDR_SIZE-16
`define E203_CFG_PLIC_ADDR_BASE `E203_CFG_ADDR_SIZE'h0C00_0000
`define E203_CFG_PLIC_BASE_REGION `E203_CFG_ADDR_SIZE-1:`E203_CFG_ADDR_SIZE-8
`define E203_CFG_FIO_ADDR_BASE `E203_CFG_ADDR_SIZE'hf000_0000
`define E203_CFG_FIO_BASE_REGION `E203_CFG_ADDR_SIZE-1:`E203_CFG_ADDR_SIZE-4
`define E203_CFG_HAS_ECC
`define E203_CFG_HAS_EAI
`define E203_CFG_SUPPORT_SHARE_MULDIV
`define E203_CFG_SUPPORT_AMO
`define E203_CFG_DTCM_ADDR_WIDTH 16
可以看到澎峰科技移植的蜂鸟工程配置为使用JTAG调试接口,处理器的寻址地址宽度为32位,配置使用MCYCLE和MINSTRET这两个64位的Performance Counters,配置使用32个通用寄存器(RV32I);使用64KB的ITCM,基地址是0x8000_0000,使用64KB的DTCM,基地址是0x9000_0000;配置私有外设接口(PPI: Private Peripheral Interface)的基地址是0x1000_0000,地址区间为0x1000_0000-- 0x1FFF_FFFF;配置CLINT(Core Local Interrupts Controller)接口的基地址是0x0200_0000,地址区间为0x0200_0000-- 0x0200_FFFF;配置PLIC(Platform Level InterruptController)接口的基地址是0x0C00_0000,地址区间为0x0C00_0000 -- 0x0CFF_FFFF;则配置使用面积优化的多周期乘除法单元和RISC-V的“A”指令集扩展。对比蜂鸟E203内核的推荐默认配置值,澎峰科技移植的蜂鸟工程把DTCM配置由16KB增大到64KB,其它的都是默认值。这里注意下E203_CFG_HAS_EAI表示配置使用协处理器接口,但相关文档说此选项的功能并未开源,因此相关代码并不具备,即便添加了配置宏也不起作用。
再看下蜂鸟工程连接输入和输出引脚,参见顶层文件system.v的代码如下:
module system
(
input wire CLK100MHZ,
input wire ck_rst,
//Green LEDs
inout wire led_0,
inout wire led_1,
inout wire led_2,
inout wire led_3,
//RGB LEDs, 3 pins each
output wire led0_r,
output wire led0_g,
output wire led0_b,
output wire led1_r,
output wire led1_g,
output wire led1_b,
output wire led2_r,
output wire led2_g,
output wire led2_b,
//Sliding switches, 3 used as GPIOs
//sw_3 selects input to UART0
inout wire sw_0,
inout wire sw_1,
inout wire sw_2,
inout wire sw_3,
//Buttons. First 3 used as GPIOs, the last is used as wakeup
inout wire btn_0,
inout wire btn_1,
inout wire btn_2,
inout wire btn_3,
//Dedicated QSPI interface
output wire qspi_cs,
output wire qspi_sck,
inout wire [3:0] qspi_dq,
// UART0(GPIO 16,17)
output wire uart_rxd_out,
input wire uart_txd_in,
//UART1 (GPIO 24,25) (not present on 48-pin)
inout wire ja_0,
inout wire ja_1,
//Arduino (aka chipkit) shield digital IO pins, 14 is not connected to the
//chip, used for debug.
inout wire [19:0] ck_io,
//Dedicated SPI pins on 6 pin header standard on later arduino models
//connected to SPI2 (on FPGA)
inout wire ck_miso,
inout wire ck_mosi,
inout wire ck_ss,
inout wire ck_sck,
//JD (used for JTAG connection)
inout wire jd_0, // TDO
inout wire jd_1, // TRST_n
inout wire jd_2, // TCK
inout wire jd_4, // TDI
inout wire jd_5, // TMS
input wire jd_6 // SRST_n
);
系统要求输入一个时钟信号和一个复位信号,软核连接有4个LED红灯,3个三色LED灯,4个按键开关,4个拨码开关,1个QSPI FLASH,2个UART串口,20 PIN Arduino接口,1个SPI接口,1个JTAG接口。这里QSPI FLASH根据信号所连接的FPGA管脚按脚位定义如下:
set_property PACKAGE_PIN P3 [get_ports{qspi_dq[3]}]
set_property PACKAGE_PIN P4 [get_ports{qspi_dq[2]}]
set_property PACKAGE_PIN P1 [get_ports{qspi_dq[1]}]
set_property PACKAGE_PIN N1 [get_ports{qspi_dq[0]}]
set_property PACKAGE_PIN M5 [get_portsqspi_cs]
set_property PACKAGE_PIN N4 [get_portsqspi_sck]
然后查找原理图可知是连接到用户FLASH, 如下图示:
其它外设和FPGA脚位的连接情况都可以按类似方法查到,该工程的脚位定义文件在目录:
DEMO资料\蜂鸟DEMO\蜂鸟工程文件\35T\35T\project_1.srcs\constrs_1\new\e203_0408.xdc
一般是要到相关外设时才查找确定,从软件编程的角度看,只需要了解到实际外设连接到蜂鸟软核的那部分资源,如是哪个GPIO就可,这可以从system.v顶层文件得到的连接关系,如下示例:
assign btn_0 = gpio_15;
assign btn_1 = gpio_30;
assign btn_2 = gpio_31;
//UART1 RX/TX pins are assigned to PMOD_D connector pins 0/1
assign ja_0 = gpio_25; // UART1 TX
assign ja_1 = gpio_24; // UART1 RX
//SPI2 pins mapped to 6 pin ICSP connector (standard on later arduinos)
//These are connected to some extra GPIO pads not connected on the HiFive1
//board
assign ck_ss = gpio_26;
assign ck_mosi = gpio_27;
assign ck_miso = gpio_28;
assign ck_sck = gpio_29;
//Use the LEDs for some more useful debugging things.
assign led_0 = dut_io_pads_aon_pmu_vddpaden_o_oval; //LD4
assign led_1 = dut_io_pads_aon_pmu_padrst_o_oval; //LD5
assign led_2 = dut_io_pads_aon_pmu_dwakeup_n_i_ival;
assign led_3 = gpio_14;
//model select
assign sw_0 = dut_io_pads_bootrom_n_i_ival; //
assign sw_1 = dut_io_pads_dbgmode0_n_i_ival;
assign sw_2 = dut_io_pads_dbgmode1_n_i_ival;
assign sw_3 = dut_io_pads_dbgmode2_n_i_ival;
//
也是要用到相关外设时才查找确定连接关系,这里我把Perf-V开发板的按键开关和LED的连接关系整理出来供大家参考,符号用开发板上的丝印表示,方便大家查找使用:
//LED红灯
D0 --- dut_io_pads_aon_pmu_vddpaden_o_oval
D1 ---dut_io_pads_aon_pmu_padrst_o_oval 复位信号
D2 ---dut_io_pads_aon_pmu_dwakeup_n_i_ival 唤醒信号
D3--- gpio_14
//三色灯
D4 --- R: gpio_1 G: gpio_2 B: gpio_3
D5 --- R: gpio_19 G: gpio_21 B: gpio_22
D6 --- R: gpio_11 G: gpio_12 B: gpio_13
//拨码开关
SW1 --- dut_io_pads_bootrom_n_i_ival 本工程实际没有用
SW2 --- dut_io_pads_dbgmode0_n_i_ival本工程实际没有用
SW3 --- dut_io_pads_dbgmode1_n_i_ival本工程实际没有用
SW4 --- dut_io_pads_dbgmode2_n_i_ival本工程实际没有用
//按键开关
K1 --- gpio_15
K2 --- gpio_30
K3 --- gpio_31
K4 --- iobuf_dwakeup_o唤醒信号输入,D2反映该信号的反相信号。
蜂鸟软核一共提供了32个GPIO,部分硬件功能存在IO复用,下面的GPIO接口分配表有必要了解下:
最后我们了解下该工程的资源占用情况,查看vivado软件的Report Utilization如下图示:
上个图更直观点:
可以看到蜂鸟工程大概用到了45%的Slice资源,按XC7A35器件35k的容量估计整个软核大概需要15k的资源。