Always Blocks
// synthesis verilog_input_version verilog_2001
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
Alwaysblock2
// synthesis verilog_input_version verilog_2001
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
此题要注意:
连续赋值(assign x= y; ),只能在always块外使用。
阻塞赋值(x= y; ),只能在always块内使用。
非阻塞赋值(x<= y; )只能在always块内使用。
(其实我试了一下,在这个地方的时序语句中,使用了阻塞赋值也可以运行)
If statement
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign=(sel_b1&sel_b2)?b:a;
always @* begin
if (sel_b1&sel_b2==1'b1) begin
out_always=b;
end
else out_always=a;
end
endmodule
If sattement latches
// synthesis verilog_input_version verilog_2001
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
这个问题在《夏宇闻Verilog》中有说明过,如果不对always模块中的if语句设计else,则会导致锁存器,所以还是补全为好。
Case statement
// synthesis verilog_input_version verilog_2001
module top_module (
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,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
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=3'b0;
endcase
end
endmodule
相对重要的就是case语句的声明要完全,其余情况要用default语句涵盖。
Priority
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@*begin
casez(in)
4'b0000:pos=2'b00;
4'b???1:pos=2'b00;
4'b??10:pos=2'b01;
4'b?100:pos=2'b10;
4'b1000:pos=2'b11;
endcase
end
endmodule
always语句别忘了写。
Priority encoder with casez
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@*begin
casez(in)
8'bzzzzzzz1:pos=0;
8'bzzzzzz10:pos=1;
8'bzzzzz100:pos=2;
8'bzzzz1000:pos=3;
8'bzzz10000:pos=4;
8'bzz100000:pos=5;
8'bz1000000:pos=6;
8'b10000000:pos=7;
default:pos=0;
endcase
end
endmodule
Avoiding latches
// synthesis verilog_input_version verilog_2001
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
left=0;down=0;right=0;up=0;
case(scancode)
16'he06b:left=1;
16'he072:down=1;
16'he074:right=1;
16'he075:up=1;
endcase
end
endmodule
提出的赋初值确实是一种非常好的思路,避免了default的多次使用带来的麻烦,使用了赋初值就可以类似于先打好底子,在对需要改变的值再微操,在面对大数据时,大大减少了运算量。
而且default或者赋初值都是不可避免的,否则会产生锁存器。