1. Alwaysblock1(Always blocks (combinational))
对于组合逻辑电路的always块,其敏感信号列表中建议始终为*,以确保不会漏掉所需信号。
module top_module(
output wire out_assign,
output reg out_alwaysblock,
input a,
input b
);
assign out_assign = a&b;
always @(*) begin
out_alwaysblock = a&b;
end
endmodule
2. Alwaysblock2(Always blocks (clocked))
对于组合逻辑电路的always块,赋值时使用(=);
对于时序逻辑电路的always块,赋值时使用(<=);
module top_module (
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff,
input clk,
input a,
input b
);
assign out_assign = a^b;
always @(*) begin
out_always_comb = a^b;
end
always @(posedge clk) begin
out_always_ff <= a^b;
end
endmodule
3. Always if(If statement)
条件判断语句所实现的是数据选择器
module top_module(
output wire out_assign,
output reg out_always,
input a,
input b,
input sel_b1,
input sel_b2
);
assign out_assign = (sel_b1 & sel_b2) ? b : a;
always @(*) begin
if (sel_b1 & sel_b2) begin
out_always = b;
end
else begin
out_always = a;
end
end
endmodule
4. Always if2(If statement latches)
在组合逻辑中若要实现数据选择器,则要为每一种情况设置出相应的输出,否则数据选择器会变成锁存器。
module top_module (
output reg shut_off_computer,
output reg keep_driving,
input cpu_overheated,
input arrived,
input gas_tank_empty,
);
always @(*) begin
if (cpu_overheated) begin
shut_off_computer = 1;
end
else begin
shut_off_computer = 0;
end
end
always @(*) begin
if (~arrived) begin
keep_driving = ~gas_tank_empty;
end
else begin
keep_driving = 0;
end
end
endmodule
5. Always case(Case statement)
case语句类似于if-elseif-else语句
(1)方法1:
module top_module (
output reg [3:0] out,
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5
);
always @(*) begin
case (sel)
3'b000: out = data0;
3'b001: out = data1;
3'b010: out = data2;
3'b011: out = data3;
3'b100: out = data4;
3'b101: out = data5;
default: out = 4'h0;
endcase
end
endmodule
(2)方法2:
module top_module (
output reg [3:0] out,
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5
);
always @(*) begin
case (sel)
3'd0: out = data0;
3'd1: out = data1;
3'd2: out = data2;
3'd3: out = data3;
3'd4: out = data4;
3'd5: out = data5;
default: out = 4'h0;
endcase
end
endmodule
6. Always case2(Priority encoder)
(1)方法1:
module top_module (
output reg [1:0] pos,
input [3:0] in
);
always @(*) begin
case (in)
4'h0: pos = 2'h0;
4'h1: pos = 2'h0;
4'h2: pos = 2'h1;
4'h3: pos = 2'h0;
4'h4: pos = 2'h2;
4'h5: pos = 2'h0;
4'h6: pos = 2'h1;
4'h7: pos = 2'h0;
4'h8: pos = 2'h3;
4'h9: pos = 2'h0;
4'ha: pos = 2'h1;
4'hb: pos = 2'h0;
4'hc: pos = 2'h2;
4'hd: pos = 2'h0;
4'he: pos = 2'h1;
4'hf: pos = 2'h0;
default: pos = 2'h0;
endcase
end
endmodule
(2)方法2:
module top_module (
output reg [1:0] pos,
input [3:0] in
);
always @(*) begin
case (in)
in[0]: pos = 2'h0;
in[1]: pos = 2'h1;
in[2]: pos = 2'h2;
in[3]: pos = 2'h3;
default: pos = 2'h0;
endcase
end
endmodule
7. Always casez(Priority encoder with casez)
‘z’代表不关心该位的数值。
module top_module (
output reg [2:0] pos,
input [7:0] in
);
always @(*) begin
casez (in)
8'bzzzzzzz1: pos = 3'h0;
8'bzzzzzz10: pos = 3'h1;
8'bzzzzz100: pos = 3'h2;
8'bzzzz1000: pos = 3'h3;
8'bzzz10000: pos = 3'h4;
8'bzz100000: pos = 3'h5;
8'bz1000000: pos = 3'h6;
8'b10000000: pos = 3'h7;
default: pos = 3'h0;
endcase
end
endmodule
8. Always nolatches(Avoiding latches)
给output的参数预分配一个默认值,可以省去default语句。
module top_module (
output reg left,
output reg down,
output reg right,
output reg up,
input [15:0] scancode
);
always @(*) begin
left = 1'b0;
down = 1'b0;
right = 1'b0;
up = 1'b0;
case (scancode)
16'he06b: left = 1'b1;
16'he072: down = 1'b1;
16'he074: right = 1'b1;
16'he075: up = 1'b1;
endcase
end
endmodule