马蜂窝网站怎么做,广告学是热门还是冷门,群晖frp 外网访问wordpress,网站开发 质保金文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 … 文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 总结 一. 实验目标学习 Quartus 、Platform Designer、Nios-II SBT 的基本操作初步了解 SOPC 的开发流程基本掌握 Nios-II 软核的定制方法掌握 Nios-II 软件的开发流程软件的基本调试方法。 二. 实验过程 1、完成以下实验 在DE2-115开发板上分别用 Verilog和 Nios软件编程两种方式完成LED流水灯显示理解两种方式的差异;分别用Verilog和Nios软件编程, 实现DE2-115开发板串口输出“Hello Nios-II”字符到笔记本电脑串口助手。 3分别在DE2-115开发板和树莓派上编写串口通信程序 实现树莓派串口指令对FPGA板子上的流水灯程序的控制控制方式自定。 一 Verilog实现流水灯
使用quartus创建好工程项目将verilog文件加入项目中分析综合一次后添加引脚引脚如下 添加完后直接全编译最后连接DE2-115下载即可。 代码如下
module led_flow #(parameter TIME_0_5S 25_000_000)(input sys_clk ,input sys_rst_n ,output reg [7:0] led
);reg [24:0] cnt ;wire add_cnt ;wire end_cnt ;reg [2:0] cnt1;wire add_cnt1;wire end_cnt1;always (posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n) begincnt 25b0;endelse if(add_cnt) beginif(end_cnt) begincnt 25b0;endelse begincnt cnt1b1;endendelse begincnt cnt;endend// 异步复位always (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)begincnt1 3b0;endelse if(add_cnt1) beginif(end_cnt1)begincnt1 3b0;endelse begincnt1 cnt1 1b1;endendendalways (posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginled 8b0;endelse begincase (cnt1)3b000 : led 8b0000_0001;3b001 : led 8b0000_0010;3b010 : led 8b0000_0100;3b011 : led 8b0000_1000;3b100 : led 8b0001_0000;3b101 : led 8b0010_0000;3b110 : led 8b0100_0000;3b111 : led 8b1000_0000;default: led led;endcaseendendassign add_cnt 1b1;assign end_cnt add_cnt cnt TIME_0_5S - 1;assign add_cnt1 (cnt TIME_0_5S-1);assign end_cnt1 add_cnt1 cnt1 3b111;endmodule运行效果如下
二 Nios实现流水灯
2.1 创建项目
在文件夹下你放项目的文件夹创建一个新的项目名称任意最好和项目有关我的是NiosII并在里面创建prj目录 创建好之后打开quartus新建工程 一直next到选择型号界面。 选择芯片型号根据实际情况选择 点击finish
2.2 SOPC添加模块 这里以前是叫qsys现在变成了platform designer他俩都是为了设置sopcsystem on programmble chip在这里面可以使用一些已经写好了的模块IP核来构建你自己想完成的功能。 首先最基本的需要一个cpuNIosII处理器、ram存储器、jtag、systemid这几个是最基本的配置。其次我们需要点灯所以就需要pio。 添加基本配置cpu 在platform designer的左侧有一个IP Catalog是IP 目录的意思可以在搜索栏输入关键字查找你想添加的ip核。如下 添加之后有弹框让你配置这个模块一般保持默认。 然后点击finish。 右键Rename将名字改为cpu 添加基本配置jtag 保持默认配置finish之后改名字为uart 添加基本配置ram 这个需要修改一下Size变为40960bytes因为后续的软件代码都是存储到ram中的还包括一些指令什么的需要较大的空间你可以在这设定充足或者在后续eclipse软件中修改有点类似于cube里面的一些操作。 修改之后finish改名字为onchip_ram 添加基本配置systemid 保持默认选项finish。 添加流水灯的pio 点击finish后将名字改为pio_led并且要在led下的externel_connection该名称为out_led。这里是为了说明顶层文件中有一个输出是out_led。可以在后面看到生成的模块实例格式中输出就有这个输入包括时钟和复位信号。 以上就是你需要的所有模块接下来就是连线。过程类似你要编写顶层top文件需要把输出输出等地方连接起来。
2.3 SOPC输入输出连接
在打开这个platform designer的时候有一个clk_0模块是它本身就有的需要双击一下看其中时钟频率是多少 可以看到这里是50MHz和手里的fpga晶振是同样的频率。所以不用修改如果不同就需要做一些额外的操作比如添加一个锁相环进行倍频操作。 cpuuartonchip_rampio_led、sys_id都有clk和reset的需求所以要把他们的时钟和复位连接起来。 接着是cpu作为处理器uart以及pio、ram等都有数据相关的操作需要通过数据总线所以要将这些连接到数据总线上去。连线结果如下 连接完后再配置一下处理器双击cpu:
这些模块都是基于Avalon总线需要确保他们地址不同。 点击system-assign base address后可以看到每个模块base那一列都分配了不同的地址。 分配完成之后可以看到最下方Messages中没有报错了如果还有报错就是前面有地方没有配对。
2.4 Generate
点击generate中的generate HDL 完成之后再点击show…template可以看到现在这个模块的实例顶层格式 复制下来。可以关闭platform designer回到quartus中。 点击File,new创建一个verilog HDL file
开始编写顶层文件 创建一个顶层模块后填写庶出庶出并将刚才复制的粘贴进去作为实例化的对象。
之后再添加qip文件Assignments–Settings– Applay之后就开始分析综合、绑定引脚可参考数据手册led绑定: 然后全编译。硬件部分就编好了。
2.5 软件部分 先有点led_flow_bsp 保持硬件的最新性。 然后右键led_flowbuild project。如果编译没问题就开始下一步。 先把硬件烧录到fpga板子上。 连接板子 start。
再烧软件
会出现一个报错点击右侧的refresh…就可以了。
2.6 运行结果 三 Verilog实现串口
项目创建和以前的一样。
3.1 代码
uart.tx:
//波特率为115200bps即每秒传送115200bit的数据传送1bit数据需要434个时钟周期
//tx内部是并行数据需要串行传出去一般数据格式是1bit的起始位8bit的数据位1bit的停止位
//所以需要一个8bit的计数器计算传送了多少个bit起始位是低电平有效停止位是持续的高电平
//需要接收8bit的数据
//需要1bit的传送出去
module uart_tx(input clk ,input rst_n ,//ininput [7:0] din ,//要发送的数据input din_vld,//数据有效//outoutput reg [3:0] cnt_byte,//现在输出第几个byte了output reg tx //串口数据
);parameter Baud 434;//波特率计时器
reg [8:0] cnt_baud ;
wire add_cnt_baud ;
wire end_cnt_baud ;
reg flag;always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_baud 0;end else if(add_cnt_baud)begin if(end_cnt_baud)begincnt_baud 0;endelse begincnt_baudcnt_baud1;endend else begin cnt_baud cnt_baud;end
end
assign add_cnt_baud flag;
assign end_cnt_baud add_cnt_baud cnt_baud Baud - 1;always (posedge clk or negedge rst_n)beginif(!rst_n)beginflag 1b0;endelse if(din_vld)beginflag 1b1;endelse if(end_cnt_bit)beginflag 1b0;endelse beginflag flag;end
end//波特率计数完成就可以发送下一个bit
//表示需要把第几位发送出去
reg [3:0] cnt_bit;//最多是8
wire add_cnt_bit;
wire end_cnt_bit;
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_bit 0;end else if(add_cnt_bit)begin if(end_cnt_bit)begincnt_bit 0;endelse begincnt_bit cnt_bit 1;endend else begin cnt_bit cnt_bit;end
end
assign add_cnt_bit end_cnt_baud;
assign end_cnt_bit add_cnt_bit cnt_bit 8;//发送到第几个字符总共要发15个字符
wire add_cnt_byte ;
wire end_cnt_byte ;always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_byte 0;end else if(add_cnt_byte)begin if(end_cnt_byte)begincnt_byte 0;endelse begincnt_byte cnt_byte 1;endend else begin cnt_byte cnt_byte;end
endassign add_cnt_byte end_cnt_bit;//发送完8bit后
assign end_cnt_byte add_cnt_byte cnt_byte 14;//发送数据的逻辑先加上起始位reg [8:0] data ;
always (posedge clk or negedge rst_n)beginif(!rst_n)begindata 9h1ff;endelse if(din_vld)begindata {din,1b0}; //数据加上起始位endelse begindata data;end
end//并行转串行逻辑
always (posedge clk or negedge rst_n)begin if(!rst_n)begintx 0;end else if(cnt_baud 1)begin //每发送完1bit就发送一个tx;tx data[cnt_bit];//LSP,低位先发end else if(end_cnt_bit)begin//处理停止位tx 1b1;endelse begin tx tx;end
endendmoduletest.v
module test(input clk ,input rst_n ,input wire [3:0] cnt_byte,//现在输出第几个byte了output reg dout_vld,//表示200us间隔实现output reg [7:0] led_data//表示输出的数据
);
//总共需要发送15个字符所以需要15的计数器//200us计数器
parameter TIME_200uS 1_000_0;
reg [13:0] cnt_200uS;
wire add_cnt_200uS;
wire end_cnt_200uS;
always (posedge clk or negedge rst_n)begin if(!rst_n)begincnt_200uS 0;end else if(add_cnt_200uS)begin if(end_cnt_200uS)begin cnt_200uS 0;endelse begin cnt_200uS cnt_200uS 1;end endelse begincnt_200uS 0;end
end
assign add_cnt_200uS 1b1;
assign end_cnt_200uS add_cnt_200uS cnt_200uS TIME_200uS - 1;//定义输出数据//Hello Nios-II到串口always (posedge clk or negedge rst_n)beginif(!rst_n)begindout_vld 1b0;endelse if(end_cnt_200uS)begindout_vld 1b1;case(cnt_byte)0 : led_data 8b01001000;//H1 : led_data 8b01100101;//e2 : led_data 8b01101100;//l3 : led_data 8b01101100;//l4 : led_data 8b01101111;//o5 : led_data 8b00100000;//space6 : led_data 8b01001110;//N7 : led_data 8b01101001;//i8 : led_data 8b01101111;//o9 : led_data 8b01110011;//s10 : led_data 8b00101101;//-11 : led_data 8b01001001;//I12 : led_data 8b01001001;//I13 : led_data 8b00001101;//\r14 : led_data 8b00001010;//\ndefault : led_data 8b0;endcaseendelse begindout_vld 1b0;endendendmoduletop.v
module top(input clk ,input rst_n ,output tx
);wire [7:0] led_data ;wire [3:0] cnt_byte ;wire din_vld ;uart_tx inst_uart_tx(.clk (clk ),.rst_n (rst_n ),//in.din (led_data),//如果串口占用时uart_data.din_vld (din_vld),
//out.cnt_byte (cnt_byte),.tx (tx ) );test inst_test(.clk (clk ),.rst_n (rst_n ),//in.cnt_byte (cnt_byte),//out.led_data (led_data ),.dout_vld (din_vld));endmodule3.2 引脚
指定gpio口为tx和rx编程实现硬件逻辑
3.3 效果 四 Nios2实现串口
4.1 sopc硬件设计 4.2 top文件
module nios2_uart_top(input clk,input rst_n,input rxd,output txd
);nios2_uart u0 (.clk_clk (clk), // clk.clk.reset_reset_n (rst_n), // reset.reset_n.uart_rxd (rxd), // uart.rxd.uart_txd (txd) // .txd);
endmodule
4.3 软件代码
#include stdio.h
#include unistd.h
#include system.h
#include alt_types.h
#include altera_avalon_uart_regs.h
#include sys\alt_irq.h/** 串口发送字符串函数* */
/*
void Uart_sendString(char *data, unsigned int len)
{alt_u8 i;for(i0;ilen;i){IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, data[i]); //数据发送完将TRDY置为1while((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE) 0x40)!0x40); //判断数据(TRDY1)是否发送完毕}
}
*/int main()
{char *str hello Niosii!\r\n;while(1){alt_u8 j;for(j 0; j 17; j){IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, str[j]); //数据发送完将TRDY置为1while((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE) 0x40)!0x40); //判断数据(TRDY1)是否发送完毕}int i 0;while(i500000){i;}}return 0;
}
4.4 实现效果 五 参考资料 1、正点原子视频 2、NiosII流水灯 3、NiosII串口 六 总结
verilog和nios-II比较下来verilog编程的时候可以选择性的编程比如我现在要串口传送我可以只写一个串口传送就可以传出去但是在细节方面比如时序很容易搞混简洁但是要很细心否则就是bug。Nios-II是添加ip核使用已有的模块去建立程序逻辑相当于模拟一个电脑大致了解一下是能上手的。但是要深究还是有点难度的。相比较下来nios-ii确实方便了一点点并且它有点像拼图把模块拼起来然后软件编程实现。