fpga环境搭建,fpga需要
上一篇文章介绍了ARM DesignStart计划,其中提到了Cortex-M1/M3 DesignStart FPGA版本,支持Xilinx和国产Gowin平台。本文将教你如何基于ARM设计启动计划。在FPGA * *上构建** Cortex-M3软核处理器。以Xilinx Artix-7系列FPGA为例,介绍了如何定制一个ARM Cortex-M3 SoC软核,添加GPIO和UART外设,使用Keil MDK环境开发应用,Jlink下载调试ARM程序。最终实现效果是LED闪烁,串口输出Hello World信息。
目录必备基础知识Cortex-M3 FPGA IP核下载硬件准备软件准备Cortex-M3软核构建新Vivado项目添加IP核搜索路径创建BlockDesign设计添加一些必备IP核添加GPIO和UART外设引出SWinterface分配外设基址生成Wrapper并实例化到top引脚分配比特流文件生成并下载Jlink连接测试Cortex-M3软核程序设计新Keil工程设置ram和ROM地址GPIO输入并输出控制串口数据发送和接收延时功能,实现Flash编程算法生成、编译、下载和运行更多开源地址参考资料
这篇文章的内容相当长。我已经把这篇文章编译成了PDF文件。本文创建的Vivado项目、ARM Cortex-M3 IP核、Keil-MDK项目、Flash编程算法文件等都已经上传到GitHub和Gitee。可以查看文末的开源地址。
或者关注我微信官方账号后台回复:220327,获取资料下载地址。
必要的基础知识为了更快的完成ARM Cortex-M3软核在FPGA上的实现,还是需要一些必要的基础知识的!
FPGA开发的基础知识,如Xilinx Vivado开发环境的FPGA开发流程、设计、综合、布局、布线、约束和下载,如ARM Cortex-M3内核的块设计、管脚分配、比特流文件生成和下载,如STM32、MM32、GD32、CH32等微控制器的开发。使用Keil-MDK开发环境的基础,项目建立的基本过程,编译和下载。如果你具备以上所有知识,那么,恭喜你!ARM Cortex-M3软核在FPGA上的实现可以在2小时内完成。
Cortex-M3 FPGA IP核下载首先,我们需要从ARM官网获取ARM Cortex-M3 FPGA软核的IP包。
下载地址如下:
https://silver.arm.com/browse/AT426
文件名:cortex-m3 design start FPGA-Xilinx edition(r0 P1-00re 0)
文件大小:7.52兆字节
MD 5 sum:CD 67536 c 29023429 CDE 47130d 51 b 6 f 49
官网需要先注册账号才能下载。如果下载速度慢,可以在微信官方账号后台回复:220318,获取下载链接复制到浏览器下载。
压缩和解压缩后,有4个文件夹:
每个文件夹中存储的内容:
Docs存储了ARM Cortex-M3处理器的参考手册,DesignStart FPGA版本的操作说明,以及基于Arty-A7开发板的顶层BlockDesign框图。
硬件存储基于Digilent Arty-A7开发板的Vivado项目、顶级BlockDesign文件、pin约束文件、Testbench文件等。
软件存储凯尔-MDK项目、SPI Flash的编程算法文件等。
Vivado包含DesignStart Cortex-M3 Xilinx FPGA版本的IP核心文件,其中Arm_ipi_repository文件夹为核心源文件,IP文件内容加密不可读。
硬件准备为了在FPGA上完成DS CM3的构建,我们至少需要以下硬件:
ARTIX-7开发板用于构建M3软核SoC。我用的是守时atom达芬奇Pro开发板,FPGA型号是XC7A100T。Xilinx FPGA下载器,用于将软核比特流下载到FPGA,如平台Usb线、JTAG-HS2/HS3等。ARM Cortex-M3调试器用于调试ARM核心程序的下载和调试,如Jlink调试器JlinkV9、Jlink-OB等。官方DS CM3 IP核基于Digilent的Arty-A7开发板。FPGA型号为XC7A35T/100T,Vivado版本为v2019.1如果你刚好手头有这个开发板,可以直接使用官方提供的示例项目。
Digilent Arty-A7开发板:
准时原子达芬奇专业开发板:
准备软件Xilinx Vivado开发环境。官方推荐的版本是2018.2以上,我用的是2018.3版本。
Keimdk开发环境,如版本5.33
DS_CM3的Keil器件封装
从Keil官网下载DesignStart Cortex-M3专用的设备支持包。下载链接如下:
https://keilpack.azureedge.net/pack/Keil.V2M-MPS2_DSx_BSP.1.1.0 .包
Cortex-M3软核的构建以上软硬件准备就绪,就可以开始构建Cortex-M3软核了。
首先,创建一个名为cortex_m3_on_xc7a100t的新文件夹来存储该示例的所有工程文件,并创建以下文件夹:
每个文件夹的功能:
Bd文件夹
用于存储BlockDesign设计。
Cm3 _核心文件夹
用于存储ARM Cortex-M3内核的IP核文件,
文档文件夹
用于存储设计文档。
Flash文件夹
用于存储生成的bit和mcs文件。
Rtl文件夹
用于存储用户设计的verilog源文件。
Xdc文件夹
用于存储引脚和时序约束文件。
需要从官方压缩文件中的Arm_ipi_repository文件夹复制cm3_core文件夹。路径是at 426-BU-98000-r0p 1-00 rel 0 \ viva do \ ARM _ IPI _ Repository。
以上文件夹准备好之后,就可以开始新项目了。
新建Vivado项目打开Vivado 2018.3,打开项目创建向导,输入项目名称。项目的存储路径是我们之前创建的文件夹。
选择FPGA芯片的完整型号:XC7A100TFGG484。
在最终创建项目目录之后。
添加IP核搜索路径为了在BlockDesign中搜索ARM Cortex-M3处理器的IP核,我们需要将ARM软核的IP所在的路径添加到搜索路径中。
创建BlockDesign设计为了方便后续以图形化的方式连接IP核,我们采用了BlockDesign的图形化设计方法,可以快速构建定制化的软核处理器。
创建一个新的BlockDesign,命名为cm3_core,并保存在原来的bd文件夹中。
将Cortex-M3处理器内核添加到画布:
双击Cortex-M3 IP核了解一些基本配置。我们不需要追踪功能。选择无跟踪,使用SWD接口调试,并禁用JTAG端口:
指令空间和数据空间的大小,这里设置为64KB,没有初始化。
添加一些必要的IP核时钟PLL。
用于内核、总线和外设的时钟。这里,我们将其配置为50MHz单端输入和50MHz PLL输出。如果时钟频率设置较高,合成后会提示WNS,不满足TNS的时序,可能会影响系统的正常运行。
处理器复位IP
它提供内核、外设和互联组件所需的复位信号,不需要定制,所以保持默认设置。
总线互连IP
Cortex-M3核心是AHB总线,内部已经转换为AXI3总线,而Xilinx提供的GPIO/UART等外围IP核是AXI4-Lite总线,所以需要增加一个总线互连矩阵用于不同协议的转换。从机数量配置为1,主机数量配置为2,连接到处理器的SYS总线。
基本逻辑门IP
Cortex-M3内核需要低电平复位,而reset IP输出是高电平复位,中间需要插入一个NOT门进行转换。
恒定IP
这种软内核结构不涉及中断部分,因此IRQ和NMI都被赋予一个常数0。如果需要将中断连接到处理器,可以通过Concat core将多个中断源合二为一,连接到IRQ。
将上述IP添加到BlockDesign画布中,并按照下图进行连接:
从官方手册中可以知道,ITCM和DTCM内存已经包含在ARM提供的软核IP中,所以我们不需要额外增加一个BRAM作为程序和数据的存储区域。
内核中提供的ITCM和DTCM都是基于RAM实现的,也就是说我们以后用Keil下载程序的时候,只是下载到RAM,断电数据就会丢失。
至此,ARM Cortex-M3处理器内核已经构建完成。让我们添加GPIO和UART外设。
添加GPIO和UART外设,如STM32。通常有固定数量的外设,如TIM、UART、SPI、CAN等。芯片内部,但是我们用FPGA来构建ARM软核SoC更灵活。如果不需要SPI,就不需要加SPI外设,需要10个UART就加10个UART。外围配置更加灵活。当然,这些外设都是基于FPGA逻辑资源的,实际增加的数量会受到FPGA芯片逻辑资源的限制。
下面是添加一组AXI GPIO和一组AXI UART的例子,以及如何利用ARM软核控制这两个外设。
Xilinx官方提供的AXI GPIO外设具有以下特性:
有两个内部通道,通道1和通道2,每个通道最多支持32个引脚。每个引脚都可以配置为输入或输出模式,并且每个引脚都可以复位以支持中断输出。所提供的AXI UART外设具有以下特性:
全双工支持5-8位数据、奇偶校验和110-230400的可配置波特率。这里我们把GPIO配置成两个通道,通道1是输出模式,低4位用来连接LED,通道2是输入模式,低4位用来连接按键。
UART配置为115200波特率,8位数据,无奇偶校验。
配置完成后,将它们连接到互联网IP的主机接口:
这两个IP组的时钟可以和处理器使用同一个时钟,复位IP输出的外设复位信号可以用于复位。
关于AXI GPIO和AXI UART的详细使用方法,可以查看官方文档:
pg144-axi-gpio.pdf
https://www . Xilinx . com/support/documentation/IP _ documentation/axi _ gpio/v2 _ 0/pg 144-axi-gpio . pdf
pg142-axi-uartlite.pdf
https://www . Xilinx . com/support/documentation/IP _ documentation/axi _ UART lite/v2 _ 0/pg 142-axi-UART lite . pdf
在SWD接口的官方DesignStart IP核数据中,除了Cortex-M3处理器,还有一个DAP-Link调试核。如果使用DAP-Link调试器,需要添加这个IP核。
我们不使用DAP-Link调试器,而是使用Jlink SWD模式。Sw模式需要两条线,一条是SWCLK时钟信号,另一条是SWDIO双向数据信号。处理器提供三个引脚:SWDI、SWDO和SWDOEN。我们还需要实现一个双向端口模块。
基于IOBUF原语的双向端口模块,内容如下:
模块swdio_tri_buffer(
//输入
输入swd_o,
输入swd_oe,
//输出
输出swd_i,
//inout
inout swd_io
);
IOBUF swd_iobuf_inst(。O(swd_i)。我(swd_o)。IO(swd_io)。t(!swd_oe)
);
Endmodule将其添加到我们的设计中。
的最终模块设计如下图所示:
在分配了外设基址并添加了外设IP之后,我们还需要分配外设基址和空间。在地址编辑框中,右键单击以选择自动分配。
完成分配后,您可以使用验证设计功能检查当前BlockDesign设计连接的有效性。
生成包装器并将其实例化到顶层。为了以后添加定制的FPGA逻辑模块,我们实例化了Cortex-M3软核处理器作为顶层设计中的处理器。
右键单击BlockDesign源文件,选择Generate Output Products first,耐心等待生成完成,然后选择Create HDL Wrapper。
然后会生成一个_wrapper的verilog文件。
创建一个新的顶层文件top_hdl.v并保存在rtl文件夹中,实例化_wrapper到顶层。
模块top_hdl(
//输入
输入时钟,
输入rst_n,
输入swclk,
输入uart_rxd,
输入[3:0] sw,
//输出
输出[3:0] led,
输出uart_txd,
//inout
inout swdio
);
cm3 _核心_包装器cm3 _核心_包装器_ut0(
//输入
. cm3_clk(clk),
. cm3_resetn(rst_n),
. cm3_gpio_in_tri_i(sw[3:0]),
. cm3_swclk(swclk),
. cm3_uart_rxd(uart_rxd),
//输出
. cm3_gpio_out_tri_o(led[3:0]),
. cm3_uart_txd(uart_txd),
//inout
. cm3_swdio(swdio)
);
endmodule //top_hdl结束
管脚分配综合完成后,使用Vivado的图形化工具进行管脚分配,特别是将SWDIO和SWDCLK引出到管脚阵列管脚,方便后续外部Jlink调试器下载ARM程序。
或者直接创建一个新的XDC文件,并使用约束语句来分配引脚。
部分约束语句:
设置_属性包_引脚R4[获取_端口时钟]
set _ property PACKAGE _ PIN V13[get _ ports SW clk]
set _ property PACKAGE _ PIN V14[get _ ports SW dio]
set _ property PACKAGE _ PIN E14[get _ ports UART _ rxd]
set _ property PACKAGE _ PIN D17[get _ ports UART _ txd]
set _ property PACKAGE _ PIN U7[get _ ports rst _ n]
set _ property PACKAGE _ PIN V9[get _ ports { led[3]}]
set _ property PACKAGE _ PIN Y8[get _ ports { led[2]}]
set _ property PACKAGE _ PIN Y7[get _ ports { led[1]}]
set _ property PACKAGE _ PIN W7[get _ ports { led[0]}]
set _ property PACKAGE _ PIN T4[get _ ports { key[3]}]
set _ property PACKAGE _ PIN T3[get _ ports { key[2]}]
set _ property PACKAGE _ PIN R6[get _ port { key[1]}]
set _ property package _ pint 6[get _ ports { key[0]}]如果你的板和我的(守时atom达芬奇Pro)一样,可以直接使用上面的pin约束。
如果你分配的时钟管脚不是FPGA的全局时钟管脚,就需要添加BUFG原语进行缓冲。
比特流文件生成和下载我的开发板使用QSPI Flash。为了提高下载和启动速度,在生成比特流时,配置生成选项:数据压缩、50M读取速度、4位数据线。
或者直接用XDC的语句来约束:
set_property比特流。常规。压缩TRUE [current_design]
set_property比特流。配置配置率50[当前设计]
设置_属性配置_电压3.3[电流_设计]
set _ property CFGBVS VCCO[当前设计]
set _ property bitstream . config . SPI _ bus width 4[current _ design]以上约束并不是必须的,只是为了加快下载和配置的速度。
耐心等待项目合成完成,生成比特流文件。合成速度与处理器主频和内核数量有关。
就像常规的FPGA下载方式一样,通过Xilinx下载器将生成的软核位文件下载到FPGA中,不要先固化到外部SPI Flash中。
如果你手头没有Xilinx下载器,可以参考上一篇文章,自己做一个JTAG-HS2下载器!
开源低成本Xilinx FPGA下载器
Jlink连接测试下载完成后,FPGA内部现在运行着一个基于ARM Cortex-M3的软核处理器,可以使用Jlink等调试工具连接到芯片上。
将Jlink调试器的SWCLK和SWDIO连接到我们分配的引脚V13和V14。
如果手头没有Jlink,也可以参考上一篇文章,自己做一个Jlink-OB!
教你如何制作Jlink-OB调试器。
要使用Keil开发DesignStart Cortex-M3软核程序,需要先安装DesignStart专用的设备包。
下载地址如下:
https://keilpack.azureedge.net/pack/Keil.V2M-MPS2_DSx_BSP.1.1.0 .包
打开一个STM32 Keil项目,将设备修改为新安装的ARM DS_CM3。在选项-调试-设置界面选择SWD模式,第一次连接会提示选择设备。点击此处选择M3皮质:
如果上述所有配置都正确,您可以看到相连的ARM Cortex-M3核心。如果不是,说明FPGA工程配置有错误,需要确认是否与上述配置流程一致。
至此,ARM Cortex-M3软核基本建成。接下来,我们使用Keil对ARM内核进行编程,实现对GPIO和UART的控制。
Cortex-M3软核程序设计类似于常规的ARM Cortex-M3核心单片机开发流程。Keil用于创建新的项目和源文件。根据外设指令手册读写指定寄存器,实现GPIO控制、UART数据写入、编译、下载和调试。
在前面创建的cortex_m3_on_xc7a100t文件夹下,创建一个新的mdk_prj文件夹来保存基尔-MDK的项目,并创建以下三个文件夹:
应用程序//用户源文件
对象//编译生成的文件
项目//Keil的工程文件
新建Keil项目打开Keil-MDK,选择项目-新建项目,创建一个名为ds_cm3_prj的新项目,保存在项目目录中。
该设备的型号是我们新安装的ARM Cortex-M3 DS_CM3内核。
在组件管理界面,添加CMSIS内核文件和启动启动文件:
并根据以下结构组织文档:
[正在传输外部链接图片…(img-XoSYVSIO-1648394491660)]
设置RAM和ROM地址。在项目选项中,设置片内ITCM的起始地址0x0和大小64K,以及片内DTCM的起始地址0x20000000和大小64K:
起始地址来自用户手册图4-1中的系统内存地址映射。您可以看到ITCM和DTCM的起始地址:
大小是我们在Cortex-M3内核配置中设置的大小:
设置完成后,新建一个main.c文件,输入以下内容,编译项目。应该没有错误输出。
#包含 DS_CM3.h
#include system_DS_CM3.h
int main(void)
{
while(1)
{
}
}
GPIO输入/输出控制通过查AXI GPIO的用户手册,通道1的数据寄存器的偏移地址为0,通道2的数据寄存器的偏移地址为0x08。根据Vivado中的连接,LED连接到通道1,钥匙连接到通道2。因此,只有读写这两个寄存器地址才能实现LED控制和dip开关状态读取。
在Vivado地址分配界面,可以看到GPIO和UART的基址分别是0x4000_0000和0x4060_0000。
l控制和dip开关读数:
*(volatile uint 32 _ t *)(0x 400000000x 0)=0x0f;//将1写入//GPIO通道1的低4位
*(volatile uint 32 _ t *)(0x 400000000x 0)=0x 00;//将0写入//GPIO通道1的低4位。
uint 32 _ t SW=0;
SW=*(uint 32 _ t *)(0x 400000000x 08);//获取GPIO通道2的32位输入状态
串行数据发送和接收将一个字节的数据写入串行端口发送FIFO:
而((*(volatile uint 32 _ t *)(0x 406000000x 08))0x 08!=0x 08);//等待发送FIFO已满
*(volatile uint 32 _ t *)(0x 406000000x 04)=0x 41;//向串口发送FIFO写字符 A=0x41,从串口接收一个字节的数据:
uint 8 _ t dat=0;if((*(volatile uint 32 _ t *)(0x 406000000x 08))0x 01==1)//串行接收FIFO中有数据DAT=(*(volatile uint 32 _ t *)(0x 406000000x 00));//从接收FIFO读取1个字节的数据。有关AXI GPIO和AXI UART寄存器的详细描述,请参考官方文档:
pg144-axi-gpio.pdf
https://www . Xilinx . com/support/documentation/IP _ documentation/axi _ gpio/v2 _ 0/pg 144-axi-gpio . pdf
pg142-axi-uartlite.pdf
https://www . Xilinx . com/support/documentation/IP _ documentation/axi _ UART lite/v2 _ 0/pg 142-axi-UART lite . pdf
延时功能的实现为了使LED的变化能够被人眼看到,需要使用延时功能来延迟LED的开启和关闭。
利用系统滴答定时器实现延时功能;
volatile uint 32 _ t CNT=0;//volatile类型void sticky _ handler(void){ CNT;} void delay _ ms(uint 32 _ t t){ CNT=0;而(cnt-t)为了让延迟函数准确延迟,我们还需要改变项目中的系统时钟频率,使其与FPGA中配置的内核时钟一致。
完成main.c文件的内容:
# include DS _ cm3。h # include system _ DS _ cm3。h //C库#包含stdarg。h #包含字符串。h #包含stdio。h #定义base addr _ LED0x 40000000 #定义base addr _ UART0x 40600000 #定义CHANNEL _ LED 1 #定义CHANNEL _ SW 2 #定义XGPIO _ CHAN _ OFFSET 8 #定义XGPIO _ write Reg(基址,RegOffset,Data)Xil _ out 32((基址)(REG OFFSET),(uint 32 _ t)(Data))#定义XGPIO _ ReadReg(基址,Reg void sy stick _ Handler(void){ CNT;} void delay _ ms(uint 32 _ t t){ CNT=0;while(CNT-t } uint 32 _ t XGpio _ In32(uint 32 _ t Addr){ return *(volatile uint 32 _ t *)Addr;}void Xil_Out32(uint32_t Addr,uint 32 _ t Value){ volatile uint 32 _ t * LocalAddr=(volatile uint 32 _ t *)Addr;* local Addr=Value } uint 32 _ t XGpio _ discrete read(uint 32 _ t Addr,uint 8 _ t Channel){ return XGpio _ read reg(Addr,(Channel-1)* XGpio _ CHAN _ OFFSET);} void XGpio _ discrete write(uint 32 _ t Addr,uint8_t Channel,uint 32 _ t Data){ XGpio _ write reg(Addr,(Channel-1)*XGPIO_CHAN_OFFSET,Data);} void XUartLite _ SendByte(uint 32 _ t基址,uint 8 _ t数据){ while(XUartLite _ IsTransmitFull(基址));XUartLite_WriteReg(基址、XUL_TX_FIFO_OFFSET、数据);} void cm3 _ print(const char * ptr){ while(* ptr!=(char)0){ XUartLite _ SendByte(base addr _ UART,* ptr);ptr}}void MyUartPrintf(char *fmt,){ unsigned char UsartPrintfBuf[296];va _ list apunsigned char * pStr=UsartPrintfBuf;va_start(ap,fmt);vsnprintf((char *)UsartPrintfBuf,sizeof(UsartPrintfBuf),(const char *)fmt,AP);va _ end(AP);while(*pStr!=0){ XUartLite _ SendByte(base addr _ UART,* pStr);pStr } } void LED _ blink(void){ XGpio _ discrete write(base addr _ LED,CHANNEL_LED,0);delay _ ms(500);XGpio _ discrete write(base addr _ LED,CHANNEL_LED,0xf);delay _ ms(500);} int main(void){ uint 32 _ tsw=0;SystemCoreClockUpdate();sy stick _ Config(系统核心时钟/1000);cm3 _ print( Hello design start ARM Cortex-FPGA上的M3 Xilinx Artix-7 xc7a 100t \ r \ n’);MyUartPrintf( SystemCoreClock=% LD \ r \ n ,SystemCoreClock);while(1){ led _ blink();SW=XGpio _ discrete read(base addr _ LED,CHANNEL _ SW);MyUartPrintf(密钥状态=% d-% d-% d \ r \ n ,软件3,软件2 1,软件1 1,软件}}实现的功能是,4颗发光二极管每100毫秒闪烁一次,同时串口输出此时拨码开关的实时状态。
编译无误后,就可以进行程序下载了。
闪光编程算法生成使用仿真器下载程序需要指定闪光编程算法,但是凯尔自带的算法中并没有我们所需要的:
所以我们需要定制一份闪光编程算法,打开凯尔安装目录下的\ARM\Flash文件夹,将_模板文件夹复制出一份,并命名为DS_CM3,
打开其中的凯尔工程:
这个工程可以自己设置要编程的闪光起始地址、大小,擦除大小等。
闪存开发公司文件填入以下内容,和我们之前人旅行费用法的配置保持一致,起始地址0x0,大小64K:
#包含.\FlashOS。h //FLASH OS structures FLASH device const FLASH device={ FLASH _ DRV _ VERS,//驱动版本,不要修改! FPGA上的Mycm3 ,//片上器件名称,//器件类型0x0000000,//器件起始地址0x00010000,//修改为64kb1024,//编程页大小0,//保留,必须为00xFF,//擦除存储器初始内容100,//程序页超时100 mSec 3000,//擦除扇区超时3000 mSec//指定扇区大小和地址0x00000,0x0000,//起始地址只有一个扇区0 SECTOR _ END };FlashPrg.c文件,实现了擦除存储区的一些功能:
#包含.\FlashOS。h //flash OS Structures # include string . h int Init(unsigned long ADR,unsigned long clk,unsigned long fnc){ return(0);//无错误完成}int UnInit(无符号long fnc){ return(0);//完成无误} int erase chip(void){ memset((unsigned char *)0,0,0x 10000);return(0);//完成无误} int erase sector(unsigned long ADR){ memset((unsigned char *)ADR,0,1024);return(0);//完成无误} int program page(unsigned long ADR,unsigned long sz,unsigned char * buf){ memcpy((unsigned char *)ADR,buf,SZ);return(0);//完成,没有错误}编译完成后,项目目录下会生成一个FLM文件。
将其复制到上一个目录:
下载运行,然后打开我们的ARM核心Keil项目,添加DS_CM3 Flash编程算法:
点击下载按钮,将ARM程序下载到ARM内核:
可以看到LED每500ms闪烁一次,串行数据每1s输出一次,同时按键,显示串行输出键的状态。
与其他ARM核心芯片一样,它也支持在线调试:
因为ARM程序是下载到Cortex-M3软核的ram存储区,掉电后程序会丢失。我还没有成功实现如何将程序下载到SPI Flash off芯片。
开源地址:对于本文的pdf文件,Vivado项目,Keil项目,Keil设备支持包,Flash编程算法文件,外设IP参考文档,ARM3软核IP数据包等资料,我已经开源到Github和Gitee。地址如下:
博客
git克隆https://gitee.com/whik/cortex_m3_on_xc7a100t.gitGithub
git clone https://github.com/whik/cortex_m3_on_xc7a100t.git或关注我(微信官方账号:电子电路开发与学习),后台回复:220327,直接获取以上资料压缩包的下载链接,复制到浏览器直接下载即可。
参考文献本文参考了哔哩哔哩芯片设计大佬* *红白(ID: 4253239) * *发布的两个视频教程:
使用Vivado BlockDesign设计一个基于ARM design start M3(id:bv1 BP 4y 187 wf)的软核SOC
基于ARM DesignStart M3软核(id: bv1cy4y147sc)使用Keil设计软件程序
如果本文描述的方法无法成功实现,可以参考以上两个视频教程。
有兴趣研究软核处理器在FPGA上实现的朋友可以加入群交流互相学习:洪兵芯片设计协会,QQ群541294921
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。