Verilog 速查表
本页面汇总了 Verilog 编程中最常用的语法和知识点,方便快速查阅。
模块定义
module module_name #(
parameter PARAM = 8
)(
input clk,
input reset,
input [PARAM-1:0] data_in,
output [PARAM-1:0] data_out
);
// 模块内容
endmodule
数据类型
线网类型
wire signal; // 1 位 wire
wire [7:0] data_bus; // 8 位 wire
wire [31:0] address; // 32 位 wire
tri bus; // 三态线
寄存器类型
reg flag; // 1 位 reg
reg [7:0] counter; // 8 位 reg
reg [31:0] register; // 32 位 reg
reg [7:0] mem [0:255]; // 256x8 存储器
有符号类型
reg signed [7:0] signed_reg;
wire signed [15:0] signed_wire;
数值表示
4'b1010 // 4 位二进制
8'hFF // 8 位十六进制
16'd65535 // 16 位十进制
8'o377 // 8 位八进制
8'bz // 8 位高阻态
8'bx // 8 位不定态
运算符
算术运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
+ | 加法 | a + b |
- | 减法 | a - b |
* | 乘法 | a * b |
/ | 除法 | a / b |
% | 取模 | a % b |
位运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
~ | 取反 | ~a |
& | 与 | a & b |
| | 或 | a | b |
^ | 异或 | a ^ b |
~^ | 同或 | a ~^ b |
归约运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
& | 归约与 | &a |
| | 归约或 | |a |
^ | 归约异或 | ^a |
~& | 归约与非 | ~&a |
~| | 归约或非 | ~|a |
逻辑运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
! | 逻辑非 | !a |
&& | 逻辑与 | a && b |
|| | 逻辑或 | a || b |
关系运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
> | 大于 | a > b |
< | 小于 | a < b |
>= | 大于等于 | a >= b |
<= | 小于等于 | a <= b |
相等运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
== | 相等 | a == b |
!= | 不等 | a != b |
=== | 全等 | a === b |
!== | 不全等 | a !== b |
移位运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
<< | 逻辑左移 | a << n |
>> | 逻辑右移 | a >> n |
<<< | 算术左移 | a <<< n |
>>> | 算术右移 | a >>> n |
其他运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
?: | 条件 | a ? b : c |
{} | 拼接 | {a, b} |
{{}} | 重复 | {n{a}} |
连续赋值
wire [7:0] sum;
wire [7:0] a, b;
assign sum = a + b;
assign y = sel ? a : b;
过程赋值
阻塞赋值
always @(*) begin
a = b;
c = a;
end
非阻塞赋值
always @(posedge clk) begin
a <= b;
c <= a;
end
always 块
组合逻辑
always @(*) begin
case (sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
default: y = d;
endcase
end
时序逻辑
always @(posedge clk or posedge reset) begin
if (reset)
q <= 0;
else
q <= d;
end
条件语句
if-else
if (condition1)
statement1;
else if (condition2)
statement2;
else
statement3;
case
case (expression)
value1: statement1;
value2: statement2;
default: statement3;
endcase
casez/casex
casez (expression)
4'b1???: statement1;
4'b01??: statement2;
default: statement3;
endcase
循环语句
for
for (i = 0; i < 8; i = i + 1) begin
mem[i] <= 0;
end
while
while (i < 8) begin
i = i + 1;
end
repeat
repeat (8) begin
// 执行 8 次
end
forever
forever begin
#5 clk = ~clk;
end
参数
parameter
parameter WIDTH = 8;
parameter [31:0] MAX = 32'hFFFFFFFF;
localparam
localparam IDLE = 2'b00;
localparam ACTIVE = 2'b01;
生成语句
generate for
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : gen_block
assign out[i] = in[i] & enable;
end
endgenerate
generate if
generate
if (WIDTH == 8)
assign result = a + b;
else
assign result = a - b;
endgenerate
任务和函数
任务
task my_task;
input [7:0] data_in;
output [7:0] data_out;
begin
data_out = ~data_in;
end
endtask
函数
function [7:0] my_function;
input [7:0] data_in;
begin
my_function = ~data_in;
end
endfunction
系统任务
显示
$display("Value: %h", value);
$write("Value: %h", value);
$monitor("Value: %h", value);
$strobe("Value: %h", value);
文件操作
file = $fopen("file.txt", "w");
$fdisplay(file, "Value: %h", value);
$fclose(file);
$readmemh("data.hex", mem);
$readmemb("data.bin", mem);
仿真控制
$finish; // 结束仿真
$stop; // 暂停仿真
$time; // 当前时间
$random; // 随机数
编译指令
`define MACRO value
`include "file.v"
`timescale 1ns / 1ps
`ifdef CONDITION
// 代码
`else
// 代码
`endif
常用模板
D 触发器
module dff(
input clk,
input reset,
input d,
output reg q
);
always @(posedge clk or posedge reset) begin
if (reset)
q <= 0;
else
q <= d;
end
endmodule
计数器
module counter #(
parameter WIDTH = 8
)(
input clk,
input reset,
input enable,
output [WIDTH-1:0] count
);
reg [WIDTH-1:0] counter;
always @(posedge clk or posedge reset) begin
if (reset)
counter <= 0;
else if (enable)
counter <= counter + 1;
end
assign count = counter;
endmodule
多路选择器
module mux4 #(
parameter WIDTH = 8
)(
input [WIDTH-1:0] in0,
input [WIDTH-1:0] in1,
input [WIDTH-1:0] in2,
input [WIDTH-1:0] in3,
input [1:0] sel,
output [WIDTH-1:0] out
);
assign out = (sel == 2'b00) ? in0 :
(sel == 2'b01) ? in1 :
(sel == 2'b10) ? in2 : in3;
endmodule
状态机
module fsm(
input clk,
input reset,
input x,
output reg y
);
parameter S0 = 0, S1 = 1, S2 = 2;
reg [1:0] state, next_state;
always @(posedge clk or posedge reset) begin
if (reset)
state <= S0;
else
state <= next_state;
end
always @(*) begin
case (state)
S0: next_state = x ? S1 : S0;
S1: next_state = x ? S2 : S0;
S2: next_state = x ? S2 : S0;
default: next_state = S0;
endcase
end
always @(*) begin
case (state)
S0: y = 0;
S1: y = 0;
S2: y = 1;
default: y = 0;
endcase
end
endmodule
FIFO
module fifo #(
parameter DATA_WIDTH = 8,
parameter DEPTH = 16
)(
input clk,
input reset,
input wr_en,
input rd_en,
input [DATA_WIDTH-1:0] din,
output [DATA_WIDTH-1:0] dout,
output full,
output empty
);
localparam ADDR_WIDTH = $clog2(DEPTH);
reg [DATA_WIDTH-1:0] mem [0:DEPTH-1];
reg [ADDR_WIDTH:0] wr_ptr, rd_ptr;
always @(posedge clk) begin
if (wr_en && !full)
mem[wr_ptr[ADDR_WIDTH-1:0]] <= din;
end
assign dout = mem[rd_ptr[ADDR_WIDTH-1:0]];
always @(posedge clk or posedge reset) begin
if (reset) begin
wr_ptr <= 0;
rd_ptr <= 0;
end else begin
if (wr_en && !full) wr_ptr <= wr_ptr + 1;
if (rd_en && !empty) rd_ptr <= rd_ptr + 1;
end
end
assign full = (wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) &&
(wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0]);
assign empty = (wr_ptr == rd_ptr);
endmodule
格式化说明符
| 说明符 | 描述 |
|---|---|
| %h, %H | 十六进制 |
| %d, %D | 十进制 |
| %b, %B | 二进制 |
| %o, %O | 八进制 |
| %t, %T | 时间 |
| %s, %S | 字符串 |
| %c, %C | ASCII 字符 |
| %m, %M | 模块层次路径 |
运算符优先级
| 优先级 | 运算符 |
|---|---|
| 1 | ! ~ + -(一元) |
| 2 | * / % |
| 3 | + -(二元) |
| 4 | << >> <<< >>> |
| 5 | < <= > >= |
| 6 | == != === !== |
| 7 | & ~& |
| 8 | ^ ~^ |
| 9 | | ~| |
| 10 | && |
| 11 | || |
| 12 | ?: |