procedure:
1always block
assign 赋值的是个wire变量
always@(*) 赋值得到的是个reg变量
综合的结果不同
// 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@(*)
out_alwaysblock=a&b;
endmodule
2always block2
// 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@(*)
out_always_comb=a^b;
always@(posedge clk)
out_always_ff=a^b;
endmodule
3 if statement
if 的语法,用一个二选一选择器来做示例。
另外说了下if 语句综合和三目运算符?:的区别(一个综合结果是个reg ,另一个assign语句综合结果是wire变量
// 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 );
always@(*)
begin
if((sel_b1&&sel_b2))
begin
out_always=b;
end
else
begin
out_always=a;
end
end
assign out_assign=(sel_b1&&sel_b2)?b:a;
endmodule
4 if latch
Verilog hdl 编写要有硬件思维,不能用软件思维来处理程序。if --else 必须写全。这和软件是不一样的。
What you must not do is write the code first, then hope it generates a proper circuit.
- If (cpu_overheated) then shut_off_computer = 1;
- If (~arrived) then keep_driving = ~gas_tank_empty;
- The usual reason is: "What happens in the cases other than those you specified?". Verilog's answer is: Keep the outputs unchanged.
- This behaviour of "keep outputs unchanged" means the current state needs to be remembered, and thus produces a latch.
// 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)begin
shut_off_computer = 1;
end
else if(!cpu_overheated)begin
shut_off_computer = 0;
end
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
5 always case
case 语句非常类似C语言中的case用法。
6选一选择器
case十分容易,但是必须记得最后的default处理。否则会产生latch
// 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:begin
out=data0;
end
3'b001:begin
out=data1;
end
3'b010:begin
out=data2;
end
3'b011:begin
out=data3;
end
3'b100:begin
out=data4;
end
3'b101:begin
out=data5;
end
default:
out=3'b000;
endcase
end
endmodule
6 always case2
优先编码器
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)
begin
case(in)
4'b0000:pos=0;
4'b0001:pos=0;
4'b0010:pos=1;
4'b0011:pos=0;
4'b0100:pos=2;
4'b0101:pos=0;
4'b0110:pos=1;
4'b0111:pos=0;
4'b1000:pos=3;
4'b1001:pos=0;
4'b1010:pos=1;
4'b1011:pos=0;
4'b1100:pos=2;
4'b1101:pos=0;
4'b1111:pos=0;
4'b1110:pos=1;
default:pos=0;
endcase
end
endmodule
7 casez
上一篇是四位输入,这次是8位输入,如果还是按照刚才的办法,将有256个cases,无疑不能这样编写程序。
there would be 256 cases in the case statement. We can reduce this (down to 9 cases) if the case items in the case statement supported don't-care bits. This is what casez is for: It treats bits that have the value z as don't-care in the comparison.
casez 就是为了用于忽略其他位的比较
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@(*)
begin
casez(in[7:0])
8'bzzzzzzz1: pos = 3'd0;
8'bzzzzzz1z: pos = 3'd1;
8'bzzzzz1zz: pos = 3'd2;
8'bzzzz1zzz: pos = 3'd3;
8'bzzz1zzzz: pos = 3'd4;
8'bzz1zzzzz: pos = 3'd5;
8'bz1zzzzzz: pos = 3'd6;
8'b1zzzzzzz: pos = 3'd7;
default: pos = 3'd0;
endcase
end
endmodule
8 always no latches
用if 语句,包含default并不保险。考虑在case之前初始化状态,则可以免去default
原文如下:
You must assign a value to all four outputs in all four cases and the default case. This can involve a lot of unnecessary typing. One easy way around this is to assign a "default value" to the outputs before the case statement:
always @(*) begin up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0; case (scancode) ... // Set to 1 as necessary. endcase end
This style of code ensures the outputs are assigned a value (of 0) in all possible cases unless the case statement overrides the assignment. This also means that a default: case item becomes unnecessary.
程序:
// 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
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
//在case之前的初始化,即默认状态
case(scancode)
16'he06b:begin
up = 1'b0; down = 1'b0; left = 1'b1; right = 1'b0;
end
16'he072:begin
up = 1'b0; down = 1'b1; left = 1'b0; right = 1'b0;
end
16'he074:begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b1;
end
16'he075:begin
up = 1'b1; down = 1'b0; left = 1'b0; right = 1'b0;
end
endcase
end
endmodule