本文參考:verilog generate語法總結(jié)-CSDN博客
Verilog數(shù)組賦值_筆記大全_設(shè)計(jì)學(xué)院
for 的用法
在Verilog中,generate for
和for
都是用于循環(huán)的結(jié)構(gòu),但是它們具有不同的應(yīng)用場合和語義。
for
循環(huán):
for
循環(huán)主要用于行為描述(behavioral description),通常用于描述算法或數(shù)學(xué)運(yùn)算。
for
循環(huán)在仿真時(shí)執(zhí)行,因此,任何在for
循環(huán)中使用的變量都必須是仿真時(shí)間可訪問的。
for
循環(huán)通常在初始化代碼或在行為模型中使用,不適用于綜合。示例:
在testbanch中測試使用的for代碼
module test;
reg [7:0] vector[0:7];
integer i;
initial begin
for (i = 0; i < 8; i = i + 1) begin
vector[i] = i;
end
end
endmodule
generate for的用法
generate for
循環(huán):
generate for
循環(huán)用于結(jié)構(gòu)描述(structural description),用于實(shí)例化模塊或生成多個(gè)類似的結(jié)構(gòu)。
generate for
循環(huán)在編譯時(shí)執(zhí)行,生成的實(shí)例在編譯后的網(wǎng)表中可見。
generate for
循環(huán)可用于綜合和實(shí)現(xiàn)。示例:
實(shí)現(xiàn)批量例化的generate for 代碼
module test;
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : gen_block
my_module instance (.input(input[i]), .output(output[i]));
end
endgenerate
endmodule
在這個(gè)例子中,my_module
被實(shí)例化了8次,每次實(shí)例化都與不同的輸入和輸出相連接。genvar
關(guān)鍵字用于聲明在generate for
循環(huán)中使用的變量。
總結(jié)區(qū)別
主要區(qū)別在于for
循環(huán)用于行為描述,在仿真時(shí)執(zhí)行;
而generate for
循環(huán)用于結(jié)構(gòu)描述,在編譯時(shí)執(zhí)行。此外,它們的變量類型也不同,for
循環(huán)使用integer
類型,而generate for
循環(huán)使用genvar
類型。
使用genrate for后面跟的 begin必須要有名稱,也就是必須要有標(biāo)簽,因?yàn)闃?biāo)簽會作為generate循環(huán)的實(shí)例名稱。
補(bǔ)充
正常情況下,我們的for循環(huán)、if以及case語句都要寫在always塊中,
然而在always塊里是不能例化模塊的,
所以我們就沒有辦法使用這幾種語句去例化模塊。
可是使用了generate之后,我們就可以不在always塊中使用for循環(huán)、if以及case語句,
從而可以使用這幾種語句來例化模塊,這樣我們就可以方便的給不同的例化對象不同的參數(shù)以及實(shí)現(xiàn)在不同情況下例化不同模塊的需求。
數(shù)組的用法
一、數(shù)組基礎(chǔ)
reg [7:0] my_array [0:3];
表示數(shù)組元素個(gè)數(shù)有4個(gè),每一個(gè)元素是8位
注意my_array 前后的寫法 前面的位數(shù)是7:0 ,后面的個(gè)數(shù)是0:3
二、數(shù)組賦值
1. 聲明時(shí)初始化
reg [7:0] my_array [0:3] = '{8'h11, 8'h22, 8'h33, 8'h44};
2. 按索引賦值
my_array[1] = 8'hAA;
3. 循環(huán)賦值
integer i;
always @(*) begin
for (i=0; i<4; i=i+1) begin
my_array[i] = i+1;
end
end
可以使用循環(huán)語句在always塊中為數(shù)組元素進(jìn)行賦值。在上面的例子中,我們使用了一個(gè)for循環(huán)來遍歷數(shù)組索引,并將其值設(shè)置為在循環(huán)中計(jì)算的值。
問題:'Port' must not be declared to be an array:
端口不能定義成數(shù)組格式
修改:
示例:使用generate for 實(shí)現(xiàn)例化4個(gè)脈沖計(jì)數(shù)功能
需求
1,使用generate for 實(shí)現(xiàn)例化4個(gè)脈沖計(jì)數(shù)功能
需求分析
1,熟悉generate for 語句的用法
2,端口定義,注意端口不能出現(xiàn)數(shù)組的寫法,需列出全部接口。但wire/reg 可使用數(shù)組的寫法。
可以在generate for 例化中使用wire 類型的信號數(shù)組
最后使用assign 端口 = wire 的形式
3,數(shù)組的用法,注意 [位:0]name [0:個(gè)] name前后的 寫法。
4,在testbanch 中for 的寫法,區(qū)別于generate for。
5,rand = {random}%15 。random 的3種用法注意事項(xiàng)文章來源:http://www.zghlxwxcb.cn/news/detail-769022.html
vlg_design
/
/*
脈沖計(jì)數(shù),當(dāng)是能時(shí),對pluse脈沖計(jì)數(shù)
實(shí)現(xiàn)步驟
1)產(chǎn)生pluse 上升沿脈沖 一個(gè)clk時(shí)鐘
2)產(chǎn)生i_en 下降沿,當(dāng)下降沿 o_state=1
3)對pluse上升沿計(jì)數(shù),鎖存在r_cnt
4)當(dāng)o_state=1 時(shí),o_cnt<=r_cnt
*/
/
`timescale 1ns/1ps
module vlg_design(
input clk,//100M
input pulse,//
input reset_n,
input i_en,
output reg[31:0] o_cnt, //輸出計(jì)數(shù)值
output o_state
);
reg [1:0] r_pluse;
reg [1:0] r_en;
wire w_pluse_pos;
wire w_en_neg;
reg[31:0] r_cnt;
//產(chǎn)生一個(gè)pluse 上升沿脈沖時(shí)鐘
always @(posedge clk) begin
if(!reset_n) r_pluse <='b00;
else r_pluse <= {r_pluse[0],pulse};
end
assign w_pluse_pos = r_pluse[0] & ~r_pluse[1];
//產(chǎn)生一個(gè)i_en 下降沿脈沖時(shí)鐘
//en 下降沿時(shí) o_state =1
always @(posedge clk) begin
if(!reset_n) r_en <='b00;
else r_en <= {r_en[0],i_en};
end
assign o_state = r_en[1] & ~r_en[0];
//EN = 1時(shí)候計(jì)數(shù)
always @(posedge clk) begin
if(!reset_n) r_cnt <= 'b0;
else if(i_en)
if(w_pluse_pos)r_cnt <= r_cnt + 1'b1;
else ;
else r_cnt <= 'b0;
end
//輸出o_cnt
always @(posedge clk) begin
if(!reset_n) o_cnt <= 'b0;
else if(!i_en && r_cnt) begin
o_cnt <= r_cnt;
$display("r_cnt=%d\n",r_cnt);//顯示
end
else o_cnt <= 'b0;
end
endmodule
vlg_cnt4
/
//使用generate for 例化端口
//設(shè)計(jì)一個(gè)脈沖計(jì)數(shù)器,其功能如下
//輸入脈沖:16路脈沖信號,分別對每路進(jìn)行脈沖檢測并計(jì)數(shù)
//使能信號:高電平進(jìn)行計(jì)數(shù),低電平清零計(jì)數(shù)器
//計(jì)數(shù)器:在使能信號高電平期間,對脈沖信號的上升沿進(jìn)行檢測并遞增計(jì)數(shù)值
//編寫測試腳本,進(jìn)行仿真驗(yàn)證
/
`timescale 1ns/1ps
module vlg_cnt4(
input clk,
input [3:0]pulse,
input reset_n,
input i_en,
output [31:0]o_cnt_0,o_cnt_1,o_cnt_2,o_cnt_3,
output [3:0]o_state
);
//定義32位的w_cnt 數(shù)組,數(shù)組元素個(gè)數(shù)4
wire [31:0]w_cnt[0:3];
//使用 generate for 例化端口
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : gen_block
vlg_design uut_vlg_design (
.clk(clk),
.pulse(pulse[i]),
.reset_n(reset_n),
.i_en(i_en),
.o_cnt(w_cnt[i]),
.o_state(o_state[i])
);
end
endgenerate
//端口賦值
assign o_cnt_0 =w_cnt[0];
assign o_cnt_1 =w_cnt[1];
assign o_cnt_2 =w_cnt[2];
assign o_cnt_3 =w_cnt[3];
endmodule
testbench_top
`timescale 1ns/1ps
module testbench_top();
//參數(shù)定義
`define CLK_PERIORD 10 //時(shí)鐘周期設(shè)置為10ns(100MHz)
//接口申明
reg clk;
reg [3:0]pulse;
reg reset_n;
reg i_en;
wire[31:0]o_cnt_0;
wire[31:0]o_cnt_1;
wire[31:0]o_cnt_2;
wire[31:0]o_cnt_3;
wire [3:0]o_state;
vlg_cnt4 uut_vlg_cnt4(
.clk(clk),
.pulse(pulse),
.reset_n(reset_n),
.i_en(i_en),
.o_cnt_0(o_cnt_0),
.o_cnt_1(o_cnt_1),
.o_cnt_2(o_cnt_2),
.o_cnt_3(o_cnt_3),
.o_state(o_state)
);
//時(shí)鐘和復(fù)位初始化、復(fù)位產(chǎn)生
initial begin
clk <= 0;
reset_n <= 0;
#10;
reset_n <= 1;
clk <= 1;
pulse <= 'b0000; //初始化都為0
i_en <= 0;
end
//時(shí)鐘產(chǎn)生
always #(`CLK_PERIORD/2) clk = ~clk;
integer i;
//測試激勵產(chǎn)生
initial begin
@(posedge reset_n); //等待復(fù)位完成
@(posedge clk);
//生成一個(gè)4位的0~15的隨機(jī)數(shù),賦值給pluse
i_en <= 1;
@(posedge clk);
//10次循環(huán),給4個(gè)pluse賦值
for(i = 0;i < 10;i = i+1) begin
pulse <= {$random} % 15;
repeat(3)@(posedge clk);
end
pulse <= 'b0000;
i_en <= 0;
#2_000_000;
$stop;
end
endmodule
仿真結(jié)果
文章來源地址http://www.zghlxwxcb.cn/news/detail-769022.html
到了這里,關(guān)于【FPGA/verilog -入門學(xué)習(xí)5】verilog中的genrate for 和for 以及數(shù)組的用法的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!