柚子快報邀請碼778899分享:實(shí)驗(yàn)一Nios-II編程入門
柚子快報邀請碼778899分享:實(shí)驗(yàn)一Nios-II編程入門
目錄
一、Nios II軟核實(shí)現(xiàn)流水燈(一)硬件部分設(shè)計1.完成基本的硬件部分設(shè)計2.添加其他IP核3.連接時鐘和復(fù)位4.設(shè)置led的輸出5.系統(tǒng)分配地址6.使用FPGA資源7.創(chuàng)建頂層文件8.芯片引腳設(shè)置9.編譯完成后,分配管腳
(二)軟件設(shè)計1.基本軟件設(shè)計過程2.修改代碼文件3.保存編譯
(三)下載硬件和軟件1.硬件的下載2.軟件的下載
(四)實(shí)驗(yàn)結(jié)果
二、Verilog實(shí)現(xiàn)流水燈三、Nios II軟核實(shí)現(xiàn)UART通信(一)硬件設(shè)計部分1.添加其他IP核2.系統(tǒng)分配地址3.使用FPGA資源4.創(chuàng)建頂層文件5.芯片引腳設(shè)置6.編譯完成后,分配管腳
(二)軟件設(shè)計1.修改代碼文件2.保存編譯
(三)下載硬件和軟件1.硬件下載2.軟件下載
四、Verilog實(shí)現(xiàn)UART通信
文章使用的工具及板子類型 工具:Quartus II 18.0 開發(fā)板:Cyclone IV E EP4CE115F29C7
一、Nios II軟核實(shí)現(xiàn)流水燈
(一)硬件部分設(shè)計
1.完成基本的硬件部分設(shè)計
請先參考下面鏈接中的硬件部分設(shè)計,完成相應(yīng)的硬件部分設(shè)計 https://blog.csdn.net/qq_43279579/article/details/115933154
2.添加其他IP核
添加PIO 在搜索框上輸入pio,選擇PIO(Parallel I/O),點(diǎn)擊Add 設(shè)置寬度(這里我設(shè)置為4,表示4個燈的流水燈),默認(rèn)為8,其他保持默認(rèn)設(shè)置
3.連接時鐘和復(fù)位
4.設(shè)置led的輸出
5.系統(tǒng)分配地址
選擇System->Assign Base Address
6.使用FPGA資源
選擇Generate->Generate,保持默認(rèn)設(shè)置,點(diǎn)擊Generate,選擇Save
7.創(chuàng)建頂層文件
回到Quarters,選擇New->Verilog HDL File 頂層文件內(nèi)容
module hello_world(
input clk,
input reset_n,
output [7:0] led
);
system_qsys u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.led_export (led) // led.export
);
endmodule
保存文件,并編譯
8.芯片引腳設(shè)置
菜單里選擇 Assignments-device,點(diǎn)擊 Device pin options 進(jìn)行 unused pin 設(shè)置,可能會收到外部信號的干擾,將未用引腳設(shè)置為 As input tri-stated 特殊引腳設(shè)置,設(shè)置為常規(guī)引腳
9.編譯完成后,分配管腳
(二)軟件設(shè)計
1.基本軟件設(shè)計過程
請參考下面鏈接中,軟件設(shè)計的過程,完成文件的創(chuàng)建 https://blog.csdn.net/qq_43279579/article/details/115933154
2.修改代碼文件
打開hello_world中的.c文件 內(nèi)容如下
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "stdio.h"
const alt_u8
led_data[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int main (void) {
int count=0;
alt_u8 led;
volatile int i;
while (1)
{
if (count==7)
{count=0;}
else
{count++;}
led=led_data[count];
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, led);
i = 0;
printf("Hello Nios-II\n");
while (i<500000)
i++;
}
return 0;
}
3.保存編譯
點(diǎn)擊保存,選擇hello_wold_bsp,右鍵后,選擇Nios II中的Generate BSP,編譯應(yīng)用文件,選擇hello_world右鍵后,點(diǎn)擊Build Project
(三)下載硬件和軟件
1.硬件的下載
2.軟件的下載
在Nios II - Eclipse中
(四)實(shí)驗(yàn)結(jié)果
二、Verilog實(shí)現(xiàn)流水燈
編譯燒錄以下代碼即可
module horse_led#(parameter TIME_1500MS = 75_000_000)(
input clk ,
input rst_n ,
output reg[3:0] led
);
//1.5s計數(shù)器
reg [26:0] cnt ;
wire add_cnt ;
wire end_cnt ;
reg [1:0] cnt1 ;
wire add_cnt1;
wire end_cnt1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 27'b0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 27'b0;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin
cnt <= cnt;
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == TIME_1500MS - 1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 2'b0;
end
else if(add_cnt1)begin
if(end_cnt1)begin
cnt1 <= 2'b0;
end
else begin
cnt1 <= cnt1 + 1'b1;
end
end
else begin
cnt1 <= cnt1;
end
end
assign add_cnt1 = end_cnt;
assign end_cnt1 = add_cnt1 && add_cnt == 3;
//跑馬燈
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led <= 4'b0001;
end
else if(end_cnt)begin
led <= {led[2:0],~led[3]};
end
else begin
led <= led;
end
end
endmodule
三、Nios II軟核實(shí)現(xiàn)UART通信
(一)硬件設(shè)計部分
1.添加其他IP核
添加UART 在搜索框上輸入uart,選擇UART(RS-232 Serial Port),點(diǎn)擊Add 進(jìn)行數(shù)據(jù)設(shè)置 連接時鐘和復(fù)位,以及數(shù)據(jù)位,中斷的設(shè)置,Export設(shè)置
2.系統(tǒng)分配地址
選擇System->Assign Base Address
3.使用FPGA資源
選擇Generate->Generate,保持默認(rèn)設(shè)置,點(diǎn)擊Generate,選擇Save
4.創(chuàng)建頂層文件
回到Quarters,選擇New->Verilog HDL File 頂層文件內(nèi)容
module uart(
input clk,
input reset_n,
//uart的接收和發(fā)送端
input rxd,//接收
output txd//發(fā)送
);
system_qsys u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.uart_rxd (rxd), // uart.rxd
.uart_txd (txd) // .txd
);
endmodule
保存文件,并編譯
5.芯片引腳設(shè)置
菜單里選擇 Assignments-device,點(diǎn)擊 Device pin options 進(jìn)行 unused pin 設(shè)置,可能會收到外部信號的干擾,將未用引腳設(shè)置為 As input tri-stated,特殊引腳設(shè)置,設(shè)置為常規(guī)引腳
6.編譯完成后,分配管腳
再次編譯
(二)軟件設(shè)計
1.修改代碼文件
打開uart中的hello_world.c文件 內(nèi)容如下
#include
#include "unistd.h"
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_uart_regs.h"
#include "sys\alt_irq.h"
alt_u8 txdata=0;
alt_u8 rxdata=0;
//UART中斷服務(wù)函數(shù)
void IRQ_UART_Interrupts(){
rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);//將rxdata寄存器中存儲的值讀入變量rxdata中
txdata = rxdata;//串口自收發(fā),將變量rxdata的值賦給txdata
while(!(IORD_ALTERA_AVALON_UART_STATUS(UART_BASE)& ALTERA_AVALON_UART_STATUS_TRDY_MSK));
//查詢發(fā)送準(zhǔn)備接收信號,如果沒有準(zhǔn)備好,則等待
IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,txdata);//發(fā)送準(zhǔn)備好,發(fā)送txdata
}
//中斷初始化函數(shù)
void IRQ_init()
{
//清除狀態(tài)寄存器
IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, 0);
//使能接收準(zhǔn)備中斷,給控制寄存器相應(yīng)位寫1
IORD_ALTERA_AVALON_UART_CONTROL(UART_BASE);
alt_ic_isr_register(
UART_IRQ_INTERRUPT_CONTROLLER_ID,//注冊ISR
UART_IRQ,//中斷控制器標(biāo)號,從system.h復(fù)制
IRQ_UART_Interrupts,//UART中斷服務(wù)函數(shù)
0x0,//指向與設(shè)備驅(qū)動實(shí)例相關(guān)的數(shù)據(jù)結(jié)構(gòu)體
0x0);//flags,保留未用
}
int main()
{
/*while(1){
IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, "hello world!\n");
int i=0;
while(i<5000)
{
i++;
}
}*/
IRQ_init();
while(1);
return 0;
}
2.保存編譯
點(diǎn)擊保存,選擇uart_bsp,右鍵后,選擇Nios II中的Generate BSP,編譯應(yīng)用文件,選擇uart右鍵后,點(diǎn)擊Build Project
(三)下載硬件和軟件
1.硬件下載
2.軟件下載
四、Verilog實(shí)現(xiàn)UART通信
編譯燒錄以下代碼即可
`timescale 1ns/1ns
module rs232
(
input wire sys_clk , //系統(tǒng)時鐘50MHz
input wire sys_rst_n , //全局復(fù)位
input wire rx , //串口接收數(shù)據(jù)
output wire tx //串口發(fā)送數(shù)據(jù)
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter UART_BPS = 20'd9600 , //比特率
CLK_FREQ = 26'd50_000_000 ; //時鐘頻率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS ;
//wire define
wire en_h_flag;
wire [7:0] po_data; //接收的數(shù)據(jù)
wire po_flag; //接收完1字節(jié)數(shù)據(jù)標(biāo)志位,高電平有效
wire flag; //識別到接收數(shù)據(jù)與密碼對應(yīng)標(biāo)志位
wire tx_flag; //發(fā)送完1字節(jié)數(shù)據(jù)標(biāo)志位,高電平有效
reg [39:0] datain_reg; //存儲接收的數(shù)據(jù),5字節(jié)
reg [47:0] dataout_reg;//存儲的要發(fā)送的數(shù)據(jù),6字節(jié)
reg [1:0] state; //狀態(tài)位
reg [7:0] data_tx; //發(fā)送的1字節(jié)數(shù)據(jù)
reg en_tx; //發(fā)送允許標(biāo)志位
reg [2:0] tx_cnt; //發(fā)送字節(jié)計數(shù)器,發(fā)送6個后置0
reg en; //發(fā)送控制開關(guān)
reg [12:0] baud_cnt; //收到發(fā)送成功的tx_flag后延遲1個波特
reg bit_flag; //計滿1baud有效
reg work; //波特計數(shù)器baud_cnt有效
//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//------------------------ uart_rx_inst ------------------------
uart_rx
#(
.UART_BPS (UART_BPS ), //串口波特率
.CLK_FREQ (CLK_FREQ ) //時鐘頻率
)
uart_rx_inst
(
.sys_clk (sys_clk ), //input sys_clk
.sys_rst_n (sys_rst_n ), //input sys_rst_n
.rx (rx ), //input rx
.po_data (po_data ), //output [7:0] po_data
.po_flag (po_flag ) //output po_flag
);
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
en <= 1'b1;
else if(en_h_flag)
en <= 1'b1;
else if(tx_cnt>=3'd5)
en <= 1'b0;
//接收數(shù)據(jù)寄存
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
datain_reg <= 40'd0;
else if(po_flag)
datain_reg <= {datain_reg[31:0],po_data[7:0]};
//接收到tx_flag后,延遲一個baud時間再發(fā)送下一個
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
work <= 1'b0;
else if(tx_flag)
work <= 1'b1;
else if(state != 2'd2)
work <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
baud_cnt <= 13'd0;
else if((baud_cnt == BAUD_CNT_MAX - 1) || en_tx)
baud_cnt <= 13'b0;
else if(work)
baud_cnt <= baud_cnt + 1'd1;
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
bit_flag <= 1'b0;
else if(baud_cnt == BAUD_CNT_MAX - 1)
bit_flag <= 1'b1;
else if(state != 2'd2)
bit_flag <= 1'b0;
//hello的ASCII碼
assign flag = (datain_reg == 40'h68656c6c6f)? 1'b1:1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
begin
state <= 2'd0;
dataout_reg <= 48'h6e692c68616f;//ni,hao的ASCII碼
data_tx <= 8'd0;
en_tx <= 1'b0;
tx_cnt <= 3'd0;
end
else
case(state)
2'd0:
begin
if(flag && en)
state <= 2'd1;
else
state <= 2'd0;
end
2'd1://發(fā)送數(shù)據(jù)
begin
state <= 2'd2;
data_tx <= dataout_reg[47:40];
en_tx <= 1'b1;
dataout_reg <= dataout_reg << 8;
end
2'd2://等待數(shù)據(jù)發(fā)送完成,并計數(shù)+1
begin
if(bit_flag)
begin
if(tx_cnt>=3'd5)begin
state <= 2'd0;
tx_cnt <= 3'd0;
end
else begin
state <= 2'd1;
tx_cnt <= tx_cnt + 1'd1;
end
end
else
begin
en_tx <= 1'b0;
state <= 2'd2;
end
end
default : state <= 2'd0;
endcase
//------------------------ uart_tx_inst ------------------------
uart_tx
#(
.UART_BPS (UART_BPS ), //串口波特率
.CLK_FREQ (CLK_FREQ ) //時鐘頻率
)
uart_tx_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.pi_data (data_tx ),
.pi_flag (en_tx ),
.tx (tx ),
.tx_flag (tx_flag )
);
endmodule
柚子快報邀請碼778899分享:實(shí)驗(yàn)一Nios-II編程入門
相關(guān)文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。