【NiosII学习】第六篇、从零搭建属于自己的SOPC系统

本文详细介绍了如何从零开始搭建基于FPGA的SOPC系统,包括单片机芯片组成、系统时钟、新建工程、软核配置、时钟锁相环、NiosII CPU、SDRAM控制器、ROM添加、总线连接、地址分配以及I/O外设添加等步骤。通过实例展示了如何在QuartusII和Eclipse中编写Verilog代码和应用程序,最终实现LED闪烁功能,提供了一个完整的SOPC系统搭建教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

第一部分、搭建自己的系统时的储备知识

1、单片机芯片的组成

2、系统的时钟

第二部分、新建工程

1、注意

2、新建工程

第三部分、搭建自己的软核

1、添加(晶振)锁相环IP核配置的详细步骤

2、添加(CPU)nios II核的详细步骤

3、添加(RAM)SDRAM核的详细步骤

4、添加(ROM)EPCS核的步骤

5、连接总线的步骤

6、配置(CPU)nios II的Vectors参数步骤

7、给软核分配地址的步骤

第四部分、给自己的软核添加添加第一个片上外设(I/O口)

第五部分、编写Quartus中的verilog代码

第六部分、编写自己ecplise软件中的代码

1、代码功能阐述

2、原码

3、编译、烧录和仿真

第七部分、总结

1、闲话

2、结果演示

3、完整资料


第一部分、搭建自己的系统时的储备知识

1、单片机芯片的组成

我相信开始学FPGA的SOPC技术,我敢赌100块,你以前一定玩过单片机(例如:51、430、32等),既然你有了这些基础那我就好解释了,SOPC技术就是你自己搭建单片机的主控芯片。而我们接触的这些单片机,它的主控芯片又是由:CPU、RAM(运行内存)、ROM(空间内存)、I/O(端口)、UART(串口)、Timer(定时器)、Interrupt(中断)所构成。其中CPU、RAM、ROM这三个最必须也是最重要。其它可以理解成片上外设。

好,既然知道了单片机的结构那把这个思维放到我们这里也一样,我们要搭建一个软核,那么我们也需要添加这些东西到我们的软核中去,只不过在这里的这些东西换了名称而已。

下面三个是我搭建系统时用到的。(注:这里面左边对应到右边不是唯一的哦,比如RAM就有好几种类型)

2、系统的时钟

当然单片机除了主控芯片这个大脑,它还有一个不可缺的就是晶振这颗心脏。说这个的原因是,因为这里面默认的时钟是50MHz,但是有时候我们还嫌弃这个心脏跳的太慢,不能满足我们的需求,所以这里我加入了PLL锁相环将系统时钟倍频到100MHz,让心脏跳到飞起的那种。(关于锁相环是啥,我们不需要知道,只需要知道这个玩意能把50MHz的时钟变成100MHz的时钟)。

第二部分、新建工程

1、注意

前面五篇文章都是基于别人的工程上面修改的,通过修改别人的软核来实现自己想要的目的。这一篇就叫你如何从零搭建属于自己的SOPC系统。

2、新建工程

第一步、新建工程QuartusII工程

第二步、选择FPGA对应的芯片型号,我用的是小梅哥家的AC620。(不吹牛,我的学长做的)

我想这里没有没有什么难点,只要芯片型号选对了,一般不会出现问题。

第三步、给自己的工程添加Verilog HDL File文件

第四步、将Verilog HDL文件保存的名称和工程名一样,如图

 

第三部分、搭建自己的软核

1、添加(晶振)锁相环IP核配置的详细步骤

第一步、确定自己的时钟,这里我通过锁相环将自己的时钟倍频到100Mhz,关于锁相环的配置如下图

 配置锁相环的输入时钟50Mhz

输入所有选项取消勾选,只要一个时钟输入和输出

另外两个窗口默认就可以了

将输出的c0时钟配置为如图一样的参数,频率为100MHz

 

将输出的c1时钟配置为如图一样的参数,频率为100MHz,时钟相移为-90,别问我,问就是不知道,小梅哥是这么搞得;

注意:我询问老师的时候老师和我说,添加时钟相移是为了防止系统出错,如果时钟和这个同步的话容易出错

 其他窗口全部默认就可以了

2、添加(CPU)nios II核的详细步骤

第一步、接着给系统添加CPU(Nios II Processor)

这里面Vectors要等连完线过后,再过来配置

3、添加(RAM)SDRAM核的详细步骤

第一步、接着给系统添加RAM(SDRAM Controller)

将SDRAM配置成128Mbits,位宽是16位,地址宽度位12和9,最后结果位128Mbit

4、添加(ROM)EPCS核的步骤

第一步、接着给系统添加ROM(Legacy EPCS/EPCQx1 Flash Controller),里面的参数配置为默认。

5、连接总线的步骤

第一步、进行连线,连完线锁定ram的起始地址为0x0000_0000

连线的规则为:

1、首先是时钟线(clk),这里面是Pllclk_100M的c0作为输出

2、其次是连接cpu上的复位(reset)线和复位线(clk_reset)

3、接着是连接cpu上数据总线(data_master),

4、最后就是连接cpu上命令总线(instruction_master),命令总线只需要连接ROM和RAM就可以了

注意:这里的名字我都修改了,不是默认的!

6、配置(CPU)nios II的Vectors参数步骤

第一步、接着配置CPU里面的(Reset vector memory和sdram.s1),配置结果如图

7、给软核分配地址的步骤

第一步、首先将sdram后面的地址进行锁定,让sdram的起始地址位0x0000_0000,然后进行自动地址分配assign address,分配完就只会出现4个警告了。

 然后按照警告的意思解决问题,

这里注意:为什么c1要导出来,老师的说的是sdram的时钟必须导出来,在外置给sdram的时钟引脚PT10

第四部分、给自己的软核添加添加第一个片上外设(I/O口)

第一步、为了测试自己的系统,首先添加LED外设,测试自己的系统,这里面省略连线、分配地址、导出端口等步骤。

第二步、保存并生成自己的软核系统,并取个名字为mysystem_(你的名字的首字母)例如我起的名称是mysystem_dpt.qsys(dpt代表大屁桃的意思),接着等待3—5分钟生成你的软核。

第三步、将这里面所有的代码全部复制出去,作为例化模块代码

注意:如果你嫌麻烦,可以直接复制我下面的代码,但是注意名称对应。

第五部分、编写Quartus中的verilog代码

第一步、首先将生成的qsys文件添加你工程的file文件夹中,添加方法按照图中序号的顺序操作!!!

添加成功后

第二步、接着编写顶层代码,并进行预编译,注意!注意!注意:这里顶层模块的名字一定要和你的文件名一致,例化模块的名字和你软核系统的名字一致。

module myself_sopc/*注意这里的名字,你的文件名如果和我不一样要记得改*/(
	
	/*时钟*/
	input  wire        clk,                           //                        clk.clk
	/*复位*/
	input  wire        reset_n,                     //                      reset.reset_n
	/*RAM*/
	output wire        sdram_clk,                     //                  sdram_clk.clk
	output wire [11:0] sdram_addr,                        //                      sdram.addr
	output wire [1:0]  sdram_ba,                          //                           .ba
	output wire        sdram_cas_n,                       //                           .cas_n
	output wire        sdram_cke,                         //                           .cke
	output wire        sdram_cs_n,                        //                           .cs_n
	inout  wire [15:0] sdram_dq,                          //                           .dq
	output wire [1:0]  sdram_dqm,                         //                           .dqm
	output wire        sdram_ras_n,                       //                           .ras_n
	output wire        sdram_we_n,                        //                           .we_n
	/*ROM*/
	output wire        epcs_rom_dclk,                         //                       epcs.dclk
	output wire        epcs_rom_sce,                          //                           .sce
	output wire        epcs_rom_sdo,                          //                           .sdo
	input  wire        epcs_rom_data0,
	/*外设*/
	output wire  [3:0] led
	
	);
	
    mysystem_dpt/*注意这里的名字,要和你软核系统的名字对应*/ u0 (
        .clk_clk        				(clk),        //       clk.clk
        .reset_reset_n 					(reset_n),  //     reset.reset_n
		  
        .epcs_rom_dclk  				(epcs_rom_dclk),  //  epcs_rom.dclk
        .epcs_rom_sce   				(epcs_rom_sce),   //          .sce
        .epcs_rom_sdo   				(epcs_rom_sdo),   //          .sdo
        .epcs_rom_data0 				(epcs_rom_data0), //          .data0
		  
        .sdram_addr     				(sdram_addr),     //     sdram.addr
        .sdram_ba       				(sdram_ba),       //          .ba
        .sdram_cas_n    				(sdram_cas_n),    //          .cas_n
        .sdram_cke      				(sdram_cke),      //          .cke
        .sdram_cs_n     				(sdram_cs_n),     //          .cs_n
        .sdram_dq       				(sdram_dq),       //          .dq
        .sdram_dqm      				(sdram_dqm),      //          .dqm
        .sdram_ras_n    				(sdram_ras_n),    //          .ras_n
        .sdram_we_n     				(sdram_we_n),     //          .we_n
        .sdram_clk_clk  				(sdram_clk),  // sdram_clk.clk
		  
        .led_export     				(led)      //       led.export
    );

endmodule 

第三步、预编译完成后分配引脚,这个照着小梅哥之前的工程进行复制就可以了,或者你们前面做的工程,但是善良的我,还是把我这块小梅哥家的AC620引脚分配表放了上来,

注意:如果你的FPGA和我的一样,那你就可以直接复制。不是的话,自己慢慢搞。我赌,你的FPGA型号如果和我的不一样,你也不会看到这里!!!

当然如果你不是这个型号的单片机也没关系,按照你那个单片机的引脚功能表填写,注意引脚被搞错了,然后引脚电压是3.3VTTL。

clk

PIN_E1

epcs_rom_data0

PIN_H2

epcs_rom_dclk

PIN_H1

epcs_rom_sce

PIN_D2

epcs_rom_sdo

PIN_C1

led[3]

PIN_A3

led[2]

PIN_A4

led[1]

PIN_B3

led[0]

PIN_A2

reset_n

PIN_E16

sdram_addr[11]

PIN_R13

sdram_addr[10]

PIN_M10

sdram_addr[9]

PIN_T14

sdram_addr[8]

PIN_R14

sdram_addr[7]

PIN_T15

sdram_addr[6]

PIN_L11

sdram_addr[5]

PIN_M11

sdram_addr[4]

PIN_N12

sdram_addr[3]

PIN_T13

sdram_addr[2]

PIN_P14

sdram_addr[1]

PIN_L10

sdram_addr[0]

PIN_P11

sdram_ba[1]

PIN_M9

sdram_ba[0]

PIN_T12

sdram_cas_n

PIN_R11

sdram_cke

PIN_T11

sdram_clk

PIN_T10

sdram_cs_n

PIN_R12

sdram_dq[15]

PIN_P9

sdram_dq[14]

PIN_N8

sdram_dq[13]

PIN_M8

sdram_dq[12]

PIN_L8

sdram_dq[11]

PIN_K8

sdram_dq[10]

PIN_L9

sdram_dq[9]

PIN_K9

sdram_dq[8]

PIN_R9

sdram_dq[7]

PIN_R8

sdram_dq[6]

PIN_R6

sdram_dq[5]

PIN_T5

sdram_dq[4]

PIN_R5

sdram_dq[3]

PIN_T4

sdram_dq[2]

PIN_R4

sdram_dq[1]

PIN_T3

sdram_dq[0]

PIN_R3

sdram_dqm[1]

PIN_R10

sdram_dqm[0]

PIN_T8

sdram_ras_n

PIN_N9

sdram_we_n

PIN_T9

第四步、注意:接着将所有引脚设置为普通I/O(use as regular i/o),然后再进行全编译。

设置的地方:assignments>device>device and pin options>dual-purpose pins

第五步、自己当前工程的文件夹下面建一个sofeware文件夹。如图,按图中序号顺序操作

第六部分、编写自己ecplise软件中的代码

1、代码功能阐述

让单片机上的4个LED大约每个0.5秒闪烁一次。

2、原码

#include <stdio.h>
#include <system.h>
#include "altera_avalon_pio_regs.h"//PIO读写头文件
#include "unistd.h"                //延时函数的头文件
#include "alt_types.h"             //数据类型的头文件

alt_u8  x=0;

int main()
{
  	while(1)
	{
  		IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 0x00);
		usleep(500000);
		IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 0xff);/*0x0f也可以*/
		usleep(500000);
	}
}

3、编译、烧录和仿真

如果你忘记了怎么操作,请看以前的文章(【NiosII学习】第一篇、如何烧录NiosII工程:https://blog.youkuaiyun.com/Learning1232/article/details/110225728)。唯一要注意的就是图中的2号哪里,因为我们没有添加JART UART,所以这里没有。

第七部分、总结

1、闲话

如果你跟着操作,而且成功点亮了你开发板上的LED了,那你肯定会很,但是到这里,你就要想我自己都能搭建软核了,那我岂不是想怎么玩就怎么玩了。例如我可以把之前学的(按键、串口、定时器)这些都加入到自己的系统中,然后做一个小的工程。

比如:通过按下不同的按键控制LED闪烁的时间不同(按下key0,LED亮1s灭1s,周期为2s;按下key1,LED亮3s灭3s,周期为6s),控制时间用定时器搞,同时串口还把你LED的闪烁得周期发送到串口助手上。

还有,有问题的老铁可以加群询问,没问题的可以进去交流,🐶🐶🐶!

2、结果演示

我已经拍成视频放在群文件中,你也可以先点击这个链接直接观看(https://live.youkuaiyun.com/v/120663),这里放张图片。

3、完整资料

欢乐的白嫖时光从来不会缺席!(完整工程、演示视频、参考资料下载链接:https://download.youkuaiyun.com/download/Learning1232/13686567)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大屁桃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值