跳到主要内容

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, %CASCII 字符
%m, %M模块层次路径

运算符优先级

优先级运算符
1! ~ + -(一元)
2* / %
3+ -(二元)
4<< >> <<< >>>
5< <= > >=
6== != === !==
7& ~&
8^ ~^
9| ~|
10&&
11||
12?: