verilog 學習筆記
基礎語法
module
1 2 3
module <module name>(<parameters>); // module content endmodule
assign
1
assign out = in;
gate
- and
&
- or
|
- not
~
- xor
^
- and
wire
1
wire w1, w2, w3;
多進制表示
<位元長度> ’ <進制表示> <數值資料>
vector
1 2 3 4 5
// type [upper:lower] vector_name; output reg [0:0] y; // 1-bit reg that is also an output port (this is still a vector) input wire [3:-2] z; // 6-bit wire input (negative ranges are allowed) output [3:0] a; // 4-bit output wire. Type is 'wire' unless specified otherwise. wire [0:7] b; // 8-bit wire where b[0] is the most-significant bit.
implicit nets: 永遠都是 one-bit wire
1 2 3 4 5 6
wire [2:0] a, c; // Two vectors assign a = 3'b101; // a = 101 assign b = a; // b = 1 implicitly-created wire assign c = b; // c = 001 <-- bug my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared. // This could be a bug if the port was intended to be a vector.
part-select
1 2 3 4 5 6 7
w[3:0] // Only the lower 4 bits of w x[1] // The lowest bit of x x[1:1] // ...also the lowest bit of x z[-1:-2] // Two lowest bits of z b[3:0] // Illegal. Vector part-select must match the direction of the declaration. b[0:3] // The *upper* 4 bits of b. assign w[3:0] = b[0:3]; // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc.
bitwise/logical or
1 2 3 4 5 6 7 8 9 10 11
module top_module( input [2:0] a, input [2:0] b, output [2:0] out_or_bitwise, output out_or_logical, ); assign out_or_bitwise = a | b; assign out_or_logical = a || b; endmodule
concatenation
exmaple code
1 2 3 4 5 6 7 8 9 10
input [15:0] in; output [23:0] out; // Swap two bytes. Right side and left side are both 16-bit vectors. assign {out[7:0], out[15:8]} = in; // This is the same thing. assign out[15:0] = {in[7:0], in[15:8]}; // This is different. The 16-bit vector on the right is extended to // match the 24-bit vector on the left, so out[23:16] are zero. // In the first two examples, out[23:16] are not assigned. assign out = {in[7:0], in[15:8]};
1 2 3 4 5 6 7
module top_module ( input [4:0] a, b, c, d, e, f, output [7:0] w, x, y, z );// assign {w, x, y, z} = {a, b, c, d, e, f, 2'b11}; endmodule
replication operator
1 2 3 4 5 6 7 8
// {num{vector}} // 5'b11111 (or 5'd31 or 5'h1f) {5{1'b1}} // The same as {a,b,c,a,b,c} {2{a,b,c}} // 9'b101_110_110. It's a concatenation of 101 with // the second vector, which is two copies of 3'b110. {3'd5, {2{3'd6}}}
always
1 2 3
always@(*)begin end
case
- allow duplicate case items
- case item 有多於一個 statement 的話用
begin end
1 2 3 4 5
case(<case_expr>) condition1: statement1; condition2: statement2; default: default_statement; endcase
casez: 可以忽略一些 bit
1 2 3 4 5 6 7 8 9
always @(*) begin casez (in[3:0]) 4'bzzz1: out = 0; // in[3:1] can be anything 4'bzz1z: out = 1; 4'bz1zz: out = 2; 4'b1zzz: out = 3; // same as 4'b1??? default: out = 0; endcase end
always: 一種 procedure
- conbinational:
always @(*)
- clocked:
always @(posedge clk)
1 2 3
always @(*) begin // do something here end
- blocking v.s. non-blocking
- Continuous assignments (assign x = y;). Can only be used when not inside a procedure (“always block”).
- Procedural blocking assignment: (x = y;). Can only be used inside a procedure.
- Procedural non-blocking assignment: (x <= y;). Can only be used inside a procedure.
- conbinational:
conditional ternary operator
就類似像 C 裡面的 conditional ternary operator
1 2
always @(posedge clk) // A T-flip-flop. q <= toggle ? ~q : q;
reduction
要把所有 bit and/or/xor 起來一個一個寫很麻煩,所以可以直接寫
1
assign w = ~& a[3:0]; // or ~& a
這樣就是對 a 裡面每個 bit 做 NAND
酷酷的東西
bit slicing
可以直接寫
[M +: N]
: 拿從 M 開始正的 offset N 個 bits[M -: N]
: 拿從 M 開始負的 offset N 個 bits