always 語(yǔ)句
always 語(yǔ)句是重復(fù)執(zhí)行的。always 語(yǔ)句塊從 0 時(shí)刻開(kāi)始執(zhí)行其中的行為語(yǔ)句;當(dāng)執(zhí)行完最后一條語(yǔ)句后,便再次執(zhí)行語(yǔ)句塊中的第一條語(yǔ)句,如此循環(huán)反復(fù)。多用于仿真時(shí)鐘的產(chǎn)生,信號(hào)行為的檢測(cè)等。
always語(yǔ)句的格式:
always @(posedge clk) begin
temp = a ;
a = b ;
b = temp ;
end
()中可以是*,表示:每當(dāng)任何輸入發(fā)生變化時(shí)執(zhí)行begin和end之間的語(yǔ)句。也可以是posedge clk,表示:時(shí)鐘上升沿時(shí)執(zhí)行begin和end之間的語(yǔ)句。assign語(yǔ)句和always @(*)創(chuàng)建相同的組合邏輯,比如下面代碼中的兩個(gè)輸出波形是一致的。
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign=a&b;
always @(*) begin
out_alwaysblock=a&b;
end
endmodule
連續(xù)性賦值,過(guò)程性賦值 :連續(xù)性賦值總是處于激活狀態(tài),任何操作數(shù)的改變都會(huì)影響表達(dá)式的結(jié)果;過(guò)程賦值只有在語(yǔ)句執(zhí)行的時(shí)候,才會(huì)起作用。
阻塞賦值與非阻塞賦值 :是過(guò)程賦值的兩種類型。
阻塞賦值 :阻塞賦值屬于順序執(zhí)行,下一條語(yǔ)句執(zhí)行前,當(dāng)前語(yǔ)句一定會(huì)執(zhí)行完畢。使用等號(hào) = 作為賦值符。initial語(yǔ)句用阻塞賦值。
非阻塞賦值 :并行執(zhí)行,即下一條語(yǔ)句的執(zhí)行和當(dāng)前語(yǔ)句的執(zhí)行是同時(shí)進(jìn)行的,它不會(huì)阻塞位于同一個(gè)語(yǔ)句塊中后面語(yǔ)句的執(zhí)行。使用 <= 作為賦值符。
使用非阻塞賦值是為了避免競(jìng)爭(zhēng)冒險(xiǎn),那么實(shí)際使用中只需要記住:always時(shí)序邏輯塊中多用非阻塞賦值<=(后面的時(shí)序邏輯電路會(huì)另外介紹),always組合邏輯塊中多用阻塞賦值=; 在仿真電路時(shí),initial 塊中一般多用阻塞賦值=。 例如下面代碼中,用assign語(yǔ)句,always組合語(yǔ)句,always時(shí)鐘語(yǔ)句實(shí)現(xiàn)異或:
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign=a^b;
always @(*) begin
out_always_comb=a^b;
end
always @(posedge clk) begin
out_always_ff<=a^b;
end
endmodule
if 語(yǔ)句格式
if (condition1) true_statement1 ;
else if (condition2) true_statement2 ;
else if (condition3) true_statement3 ;
else default_statement ;
如果只有兩種情況,就只有if和else。下面用上一節(jié)中MUX2_1做練習(xí),上一節(jié)中采用了assign的三元運(yùn)算符語(yǔ)句,這里使用always if語(yǔ)句實(shí)現(xiàn)2選1的功能:
module mux2_1
(
input wire in1,
input wire in2,
input wire sel,
output reg out
);
always@(*) begin
if(sel == 1'b1)//當(dāng)“if...else...”中只有一個(gè)變量時(shí)不需要加“begin...end".但是為了不遺漏,還是加上
out = in1; //always塊中的組合邏輯關(guān)系時(shí)使用阻塞賦值“=”進(jìn)行賦值
else
out = in2;
end
endmodule
3-8譯碼器的實(shí)現(xiàn)
從真值表看譯碼器功能:A2A1A0=000-111共8種輸入,對(duì)應(yīng)輸出Y的下標(biāo),對(duì)應(yīng)下標(biāo)的輸出為1(高電平),其他輸出為0(低電平)。3-8譯碼器的作用:按照之前點(diǎn)亮LED燈的思路,如果一個(gè)I/O端口控制一個(gè)LED燈,那么I/O端口很有可能不夠用,這時(shí)候聰明人就想出用3-8譯碼器的方式,3個(gè)I/O口就可以控制8個(gè)LED。
設(shè)計(jì)規(guī)劃
這個(gè)示例中,繪制波形圖如圖所示。
編寫代碼
module decoder3_8
(
input wire in1 ,
input wire in2 ,
input wire in3 ,
output reg [7:0] out
);
always@(*) begin
//使用"{}"位拼接符將3個(gè)1bit數(shù)據(jù)按照順序拼成一個(gè)3bit數(shù)據(jù)
if({in1, in2, in3} == 3'b000)
out = 8'b0000_0001;
else if({in1, in2, in3} == 3'b001)
out = 8'b0000_0010;
else if({in1, in2, in3} == 3'b010)
out = 8'b0000_0100;
else if({in1, in2, in3} == 3'b011)
out = 8'b0000_1000;
else if({in1, in2, in3} == 3'b100)
out = 8'b0001_0000;
else if({in1, in2, in3} == 3'b101)
out = 8'b0010_0000;
else if({in1, in2, in3} == 3'b110)
out = 8'b0100_0000;
else if({in1, in2, in3} == 3'b111)
out = 8'b1000_0000;
else
out = 8'b0000_0001;
end
endmodule
代碼中使用always組合邏輯塊。由于if對(duì)應(yīng)的執(zhí)行語(yǔ)句只有一句,可以不使用begin,end但是由于怕以后復(fù)雜代碼會(huì)遺漏,還是選擇加上。always組合邏輯使用阻塞語(yǔ)句,用=進(jìn)行賦值。
上面RTL代碼綜合出的RTL視圖:
編寫testbench
`timescale 1ns/1ns
module tb_decoder3_8();
//reg define
reg in1;
reg in2;
reg in3;
wire [7:0] out;
//初始化輸入信號(hào)
initial begin
in1 <= 1'b0;
in2 <= 1'b0;
in3 <= 1'b0;
end
always #10 in1 <= {$random} % 2;
always #10 in2 <= {$random} % 2;
always #10 in3 <= {$random} % 2;
//-------------decoder3_8_inst----------------
decoder3_8 decoder3_8_ins
(
.in1(in1),
.in2(in2),
.in3(in3),
.out(out)
);
endmodule
經(jīng)過(guò)兩個(gè)實(shí)例后,testbench已經(jīng)超級(jí)熟悉了吧。
對(duì)比波形
看看波型:
驗(yàn)證了波形的正確性
-
FPGA
+關(guān)注
關(guān)注
1630文章
21761瀏覽量
604410 -
FPGA設(shè)計(jì)
+關(guān)注
關(guān)注
9文章
428瀏覽量
26553 -
仿真
+關(guān)注
關(guān)注
50文章
4102瀏覽量
133746 -
時(shí)鐘
+關(guān)注
關(guān)注
11文章
1736瀏覽量
131596 -
譯碼器
+關(guān)注
關(guān)注
4文章
311瀏覽量
50387
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論