Verlog类似于C语言,只是在语法上有些相似,因为他们的应用场景不同,不可混淆。
数据类型:
正数-2进制b或B,8进制o或O,十进制d或D,十六进制h或H。
常数定义: parameter ----可以被重新复制的变量 localparame----局部变量,只能在.v文件内部引用
变量:
线网型变量wire,表示内部连线,没有时钟延时,不能存储数值
寄存器 reg,可以存储数值,必须在always@()中赋值
运算符
(1)算数运算符(+,-,*,/)
(2)逻辑运算符(与&& ,或||, 非!)
(3)赋值运算符(非阻塞赋值<=,阻塞赋值=)
(4)位于算符(与&,或|,反~,异或^)
(5)关系运算(>,>=,<,<=!=)
(6)拼接运算符({},{{}})
(7)三目运算符(?:)
(8)移位运算符(右移<<,左移>>)
(9)括号(括号不是运算符,但是增加程序的可以执行)
模块
Verlog设计可以采用自顶向下的设计,就是整体模块,然后是各个功能的小模块。在我们实现的过程中是把每一个的小的功能模块组合起来实现一个完整的功能比如下面的结构
Module top();
A();
B();
Endmodule
Module A();
Endmodule
Module B();
Endmodule
A,B为单个的基础模块,共同完成模块Top的功能。
单个模块的设计
- 组合逻辑
组合逻辑的特点就是会在运算的同一时间出结果,不依赖于时钟延时。
Module Add(input A, inputB, output C);
Assign C = A + B;
Endmodule
- 时序逻辑
时序逻辑的特点就是当前时刻的输出之前的状态和当前的输入有关系。
Module Add(input clk, input A, inputB, output C);
always@(posedge clk or negedge rst_n)
C <= A + B ;
Endmodule
在时钟的上升沿进行采样A,B,然后进行运算,在下一个时钟出结果。
小技巧
因为FPGA的特点比较适合做重复性的运算或者数据传输,他并不适合做类似云单片机之类的控制。但是有些控制器需要用到状态的切换进行下一个操作。举个例子,比如你早晨要(1)先起床穿衣(2)吃放(3)上班…. ;状态有明显的的先后顺序,不能颠倒,这时候我们就要用到状态机。状态机的这种设计可以方便的实现不同状态下进行不同的操作。状态机分为一段式状态机,两段式状态机,三段式状态机。
(一段式状态机:状态切换,变更条件,输出放在了一个模块)
localparam Idle = 2’d0 ;
localparam S0 = 2’d1;
localprame S1 =2’d2;
localparam S2 =2’d3;
reg [1:0] d0 ;
reg [1:0] state;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
beign
do <= 0 ;
state< = Idle;
end
else begin
case(state)
Idle:begin
state <= S0 ;
d0 <= 2'd1 ;
end
S0:begin
state <= S1 ;
d0 <= 2'd2 ;
end
S1:begin
state <= S2 ;
d0 <= 2'd3 ;
end
S2:begin
state <= Idle ;
d0 <= 2'd0 ;
end
endcase
end
end
(二段式状态机:状态切换,(变更条件,输出)两个模块)
localparam Idle = 2’d0 ;
localparam S0 = 2’d1;
localprame S1 =2’d2;
localparam S2 =2’d3;
reg [1:0] d0 ;
reg [1:0] cur_state ;
reg [1:0] next_state;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cur_state <= Idle ;
else
cur_state <= next_state ;
end
always@(*)begin
if(!rst_n)
beign
do <= 0 ;
end
else begin
case(cur_state)
Idle:begin
next_state <= S0 ;
do <= 2'd1 ;
end
S0:begin
next_state <= S1 ;
do <= 2'd2 ;
end
S1:begin
next_state <= S2 ;
do <= 2'd3 ;
end
S2:begin
next_state <= Idle ;
do <= 2'd0 ;
end
default:;
endcase
end
end
(三段式状态机:状态切换,变更条件,输出个一个模块)
localparam Idle = 2’d0 ;
localparam S0 = 2’d1;
localprame S1 =2’d2;
localparam S2 =2’d3;
reg [1:0] d0 ;
reg [1:0] cur_state ;
reg [1:0] next_state;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cur_state <= Idle ;
else
cur_state <= next_state ;
end
always@(*)begin
if(!rst_n)
beign
do <= 0 ;
end
else begin
case(cur_state)
Idle:begin
next_state <= S0 ;
end
S0:begin
next_state <= S1 ;
end
S1:begin
next_state <= S2 ;
end
S2:begin
next_state <= Idle ;
end
default:;
endcase
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
do <= 2'd0 ;
else begin
case(cur_state)
Idle:begin
do <= 2'd1 ;
end
S0:begin
do <= 2'd2 ;
end
S1:begin
do <= 2'd3 ;
end
S2:begin
do <= 2'd0 ;
end
default:;
endcase
end
end
以上模块可以作为,模板使用,比如在IIC控制器,UART控制器中都会用到。