可综合/不可综合
可综合:语法结构能与实际硬件电路对应起来
不可综合:语法结构不能与实际硬件电路对应起来
可综合语句:input、output、parameter、reg、wire、always、assign、begin..end、case、posedge、negedge、or、and、default、if、function、generate、integer、`define,while、repeat 、for (while、repeat循环可综合时,要具有明确的循环表达式和循环条件,for可综合时也要有具体的循环范围)
不可综合语句:initial、fork.. join、wait、time、real、display、 forever 、延时控制 #xxx
基本原则:
- 不能使用initial,initial一般使用在测试程序,做初始化;
- 不建议使用延时,#1,这种只是模拟数字电路中因为布线产生的信号延时,不可综合,但也不会报错;
- 不能使用循环次数不确定的函数,但forever在综合设计中禁止使用,只能使用在仿真测试程序中;
- 尽量使用同步电路设计方式(同步电路:电路中所有受时钟控制的单元,全部由一个统一的全局时钟控制);
- 除非关键电路设计,一般不建议调用门级元件进行设计,一般使用行为级进行设计;
- 当使用always进行组合逻辑设计时,敏感列表里面的要列出所有输入信号。
- 在进行时序电路进行编写时,采用非阻塞赋值。组合逻辑设计时,采用阻塞赋值。在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
- (?)为避免产生锁存器,if、case要进行完整的语句赋值,且case语句中避免使用X值、Z值。
- 避免混合使用上升沿和下降沿触发的触发器
整数表示方法
a=8'b1011_1001 //8bit的数值,采用2进制,下划线是为了增强代码的可读性,无实际意义
a=100;//一般会根据编译器自动分频位宽,常见的为32bit
阻塞赋值和非阻塞赋值
阻塞赋值顺序执行,顺序会影响我们想要设置的功能
非阻塞赋值同时执行,但是在块语句结束后完成赋值
assign/wire
assign a=b+c; //a一定为wire类型,b,c可以是wire类型或者reg类型
assign相当于电路连线,属于组合逻辑
parameter
parameters Max=10; //和 const int/define 类似
always
always @ (a or b) begin //括号内为敏感列表,敏感列表中的任何值发生变化,都会执行always中的指令
[statements]
end
always @(posedge clk) begin //在clk上升沿执行always中的指令
[statements]
end
在描述组合逻辑的always 块中用阻塞赋值
module combo ( input a,
input b,
input c,
input d,
output reg o);
always @ (a or b or c or d) begin
o = ~((a & b) | (c^d));
end
endmodule
上面实现了一个简单的组合逻辑
在描述时序逻辑的always 块中用非阻塞赋值
module tff (input d,
clk,
rstn,
output reg q);
always @ (posedge clk or negedge rstn) begin
if (!rstn)
q <= 0;
else begin
if (d)
q <= ~q;
else
q <= q;
end
end
endmodule
上面实现了一个简单的时序逻辑
module
module定义
module add16(input [15:0] a ,
input [15:0] b ,
input cin,
output [15:0] sum,
output cout);
//Module body
endmodule
input/output 可以是 wire/reg,默认是wire
module调用
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum_low;
wire [15:0] sum_up ;
wire cout1 ;
wire cout2 ;
add16 instance1(.a (a[15:0]),
.b (b[15:0]),
.cin (1'b0) ,
.sum (sum_low),
.cout (cout1));
add16 instance2(.a (a[31:16]),
.b (b[31:16]),
.cin (cout1) ,
.sum (sum_up) ,
.cout (cout2));
assign sum = {sum_up, sum_low};
endmodule
instance1,instance2为调用add16模块的两个实例
时延 #xxx
always #10 clk = ~clk;//每10个时间单位单位执行一次翻转
always clk = ~clk;//没有时延,会出问题
标签:wire,clk,always,sum,学习,verilog,input,赋值
From: https://www.cnblogs.com/zhongzero/p/16729091.html