學(xué)習(xí)內(nèi)容
本節(jié)使用正點(diǎn)原子提供的呼吸燈實(shí)驗(yàn)的Verilog代碼用于實(shí)現(xiàn)AXI接口的呼吸燈的IP。在 Vivado 軟件中,我們可以很方便的通過(guò)創(chuàng)建和封裝 IP 向?qū)У姆绞絹?lái)自定義 IP 核。
開發(fā)環(huán)境
vivado 18.3&SDK PYNQ-Z2開發(fā)板
自定義AXI 接口IP制作流程
首先打開Vivado軟件,在Tasks這里選擇New IP lacation
點(diǎn)擊next,對(duì)IP的信息進(jìn)行設(shè)置,這里我們使用默認(rèn)配置即可。設(shè)置好我們IP要保存的位置。
點(diǎn)擊Tools中的創(chuàng)建和封裝新的IP選項(xiàng),
點(diǎn)擊NEXT ,選擇我們的封裝類型。
這里我們要選擇AXI接口的設(shè)計(jì),所以選擇AXI4 接口,然后點(diǎn)擊NEXT。出現(xiàn)下面的界面,我們可以對(duì)我們的IP的基本信息進(jìn)行設(shè)計(jì),設(shè)置我們的IP的名字、顯示名、描述、位置、版本號(hào)等。
這里設(shè)置IP的接口為Slave,設(shè)置為從機(jī),數(shù)據(jù)位寬設(shè)置為默認(rèn)。寄存器數(shù)量設(shè)置為最少即可這里就是4個(gè)。
設(shè)置完成后,在IP 的目錄下就會(huì)出現(xiàn)我們?cè)O(shè)置好的ip,這里的IP只實(shí)現(xiàn)了AXI的接口,沒(méi)有對(duì)呼吸燈的功能進(jìn)行定義。
在我們的IP目錄下,我們選中我們?cè)O(shè)計(jì)的IP右鍵,編輯我們的IP。
添加我們的呼吸燈的Verilog代碼,在們的IP的頂層的模塊進(jìn)行例化。
這里給出的是正點(diǎn)原子的呼吸燈模塊代碼。
module breath_led(
input sys_clk , //時(shí)鐘信號(hào)
input sys_rst_n , //復(fù)位信號(hào)
input sw_ctrl , //呼吸燈開關(guān)控制信號(hào) 1:亮 0:滅
input set_en , //設(shè)置呼吸燈頻率設(shè)置使能信號(hào)
input [9:0] set_freq_step , //設(shè)置呼吸燈頻率變化步長(zhǎng)
output led //LED
);
//*****************************************************
//** main code
//*****************************************************
//parameter define
parameter START_FREQ_STEP = 10'd100; //設(shè)置頻率步長(zhǎng)初始值
//reg define
reg [15:0] period_cnt ; //周期計(jì)數(shù)器
reg [9:0] freq_step ; //呼吸燈頻率間隔步長(zhǎng)
reg [15:0] duty_cycle ; //設(shè)置高電平占空比的計(jì)數(shù)點(diǎn)
reg inc_dec_flag; //用于表示高電平占空比的計(jì)數(shù)值,是遞增還是遞減
//為1時(shí)表示占空比遞減,為0時(shí)表示占空比遞增
//wire define
wire led_t ;
//將周期信號(hào)計(jì)數(shù)值與占空比計(jì)數(shù)值進(jìn)行比較,以輸出驅(qū)動(dòng)led的PWM信號(hào)
assign led_t = ( period_cnt <= duty_cycle ) ? 1'b1 : 1'b0 ;
assign led = led_t & sw_ctrl;
//周期信號(hào)計(jì)數(shù)器在0-50_000之間計(jì)數(shù)
always @ (posedge sys_clk) begin
if (!sys_rst_n)
period_cnt <= 16'd0;
elseif(!sw_ctrl)
period_cnt <= 16'd0;
elseif( period_cnt == 16'd50_000 )
period_cnt <= 16'd0;
else
period_cnt <= period_cnt + 16'd1;
end
//設(shè)置頻率間隔
always @(posedge sys_clk) begin
if(!sys_rst_n)
freq_step <= START_FREQ_STEP;
elseif(set_en) begin
if(set_freq_step == 0)
freq_step <= 10'd1;
elseif(set_freq_step >= 10'd1_000)
freq_step <= 10'd1_000;
else
freq_step <= set_freq_step;
end
end
//設(shè)定高電平占空比的計(jì)數(shù)值
always @(posedge sys_clk) begin
if (sys_rst_n == 1'b0) begin
duty_cycle <= 16'd0;
inc_dec_flag <= 1'b0;
end
else if(!sw_ctrl) begin //呼吸燈開關(guān)關(guān)閉時(shí),信號(hào)清零
duty_cycle <= 16'd0;
inc_dec_flag <= 1'b0;
end
//每次計(jì)數(shù)完了一個(gè)周期,就調(diào)節(jié)占空比計(jì)數(shù)值
elseif( period_cnt == 16'd50_000 ) begin
if( inc_dec_flag ) begin //占空比遞減
if( duty_cycle == 16'd0 )
inc_dec_flag <= 1'b0;
elseif(duty_cycle < freq_step)
duty_cycle <= 16'd0;
else
duty_cycle <= duty_cycle - freq_step;
end
else begin //占空比遞增
if( duty_cycle >= 16'd50_000 )
inc_dec_flag <= 1'b1;
else
duty_cycle <= duty_cycle + freq_step;
end
end
else//未計(jì)數(shù)完一個(gè)周期時(shí),占空比保持不變
duty_cycle <= duty_cycle ;
end
endmodule
可以保存到和IP的路徑相同的HDL文件夾下。
在Vivado下保存導(dǎo)入工程后,我們打開下面的文件,然后對(duì)我們的呼吸燈的IP的信息進(jìn)行添加,這里xilinx給出的原始AXI接口模板留的有給用戶添加代碼的地方,為了便于維護(hù)和尋找,我們就在對(duì)應(yīng)的位置添加信息即可。添加parameters信息:
添加接口信息:
將添加的呼吸燈IP進(jìn)行實(shí)例化調(diào)用(在V文件文末添加):
完成添加后,我們還需要在頂層文件對(duì)參數(shù)進(jìn)行聲明定義,同時(shí)要定義下呼吸燈接口。
同時(shí)也要在實(shí)例化的模塊下添加相關(guān)信息。
添加完成后,進(jìn)行綜合,
無(wú)錯(cuò)誤后打開package IP界面,更新相關(guān)信息。
打開我們的參數(shù)配置界面,對(duì)剛剛添加的參數(shù)進(jìn)行配置
選擇參數(shù)在GUI界面可見,之前顯示的隱藏參數(shù)將會(huì)更新到customization parameters里。顯示名字可以自己定義,參數(shù)的類型這里設(shè)置成long。因?yàn)樵谡c(diǎn)提供的代碼中,頻率的步進(jìn)范圍是1-1000所以這里IP也就設(shè)置成1-1000。默認(rèn)值這里給出了100。(可以任意設(shè)置)
上面的IP設(shè)置全部通過(guò)后,根據(jù)以下操作完成IP的重新封裝配置。
完成后添加IP,即可和其他IP一樣配置信息進(jìn)行使用啦。