1. 组合逻辑:assign wire = 。。。。。。;
2. 时序逻辑:always @(敏感列表) begin end
always @(*) begin end
3. module name #(parameters) (signals); .............. endmodule
4. for 循环:
genvar i;
generate
for(i=0;i<10;i=i+1)
begin
always .....
assign .....
end
endgenerate
while()
begin
.....................
end
5. case({list})
stat1:
stat2:
default:
endcase
6. task模块:task模块如果用到不可综合的语句,就无法综合,只能用在system verilog中用于描述行为。
task一般用在仿真里,在RTL不推荐使用。
从C语言的角度讲,task相当于一个函数,被调用时方可执行。
【task的一般格式】:
task ts_name; // ts_name后面不列输入输出信号列表
input .....
output .....
电路描述
endtask
task 中不能包含 initial 和 always 块。但反过来,always块中可以包含task,task中甚至可以用<=.
task 的output必须是个reg,而不是wire。
【task的调用格式】:
时序逻辑:
always @(..........)
begin
ts_name(list); //没有task字样,只有task的名字,list包括输入和输出
end //输出必须是reg
组合逻辑:
ts_name(list); //没有明显的赋值格式
这是人家对task的简单评价:“用task只能得到最终的一个值,不能得到连续值。所以task适合在某个时刻给某个信号赋值,而不适合给某个信号在一段时间内不间断的赋值,要实现仿真,只能把task的内容提到上层中。”所以task一般不用在RTL中。
7. function:功能跟task一样,但可用于RTL代码中,一般FIFO中的GRAY编码和解码使用function编写。
task的输出列在列表中,所以可以是多个,而function的输出就是function本身,只有一个输出。
【funciton的一般格式】:
function wire [1:0] func_name; //如果不写wire [1:0],默认为reg [0:0]
input ........; //注意,没有output
电路描述
func_name = ....; //最后总要得到结果
endfunction
function只能用来表示组合逻辑,表示时不用assign,也不用always。
【function的调用格式】
(1) assign a = func_name(input_list);
(2) always @()
a <= func_name(input_list);
(3) initial
a = func_name(input_list);
【举例】
function [3:0] junc;
input a,b,c,d;
reg [3:0] a1; //这里的a1,b1,c1,d1能写成reg,不能写成wire
reg [3:0] b1;
reg [3:0] c1;
reg [3:0] d1;
a1 = {3'b0,a};
b1 = {3'b0,b};
c1 = {3'b0,c};
d1 = {3'b0,d};
junc = a1+(b1<<1)+(c1<<2)+(d1<<3);
$display(junc);
上例用for循环做,和C语言一样:
parameter NUM1 = 3;
function [NUM1:0] junc1;
input [NUM1:0] a;
reg [NUM1:0] b[NUM1:0];
int cnt; //支持int,但不可综合
for(cnt=0;cnt<=NUM1;cnt++)
b[cnt] = {{NUM1{1'b0}},a[cnt]};
junc1 = b[0];
for(cnt=1;cnt<=NUM1;cnt++)
junc1 += b[cnt]<<cnt;
$display("addr=",junc1);
endfunction
注意: 可综合的function中不支持generate块。
可综合的function中电路描述必须被 begin 。。。。。end 包裹。
可综合的function中不支持int,但可以用integer代替。不如对for循环进行计数时。
8. 定义宏:
`define ABC
`ifdef ABC
`elsif CCC //不是elseif,而是elsif,和perl一样。
`endif
`ifndef ABC ....................
`include ..................
9. 数码顺序:就是DSP中所谓大端小端的问题,
verilog中,如定义 4比特信号 a = {1,0,1,0} , 则 a 表示的是4'b1010,而不是4'b0101。a[0] 是 0 而不是1,所以{1,0,1,0}只是4'b1010的一种表示方法,和C语言中初始化数组的{1,0,1,0}是反向的。