文章目录
- 组合逻辑
- 时序逻辑
- 可综合设计
- 模块结构
- 缩写命令
 
组合逻辑
这种条件信号变化结果立即变化的 always 语句被称为“组合逻辑” 。
always @(posedge clk)beginif(sel==0)c <= a + b;elsec <= a + d;
end
时序逻辑
这种信号边沿触发, 即信号上升沿或者下降沿才变化的 always, 被称为“时序逻辑” , 此时信号 clk 是时钟。
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginc <= 0;endelse if(sel==0)c <= a + b;elsec <= a + d;
end
需要说明的是, 多条 assign 连续赋值语句之间互相独立、 并行执行。
可综合设计
综合就是把编写的 rtl 代码转换成对应的实际电路。 比如编写代码 assign a=b&c; EDA 综合工
 具就会去元件库里调用一个二输入与门, 将输入端分别接上 b 和 c, 输出端接上 a。
不可综合, 是指找不到对应的 “门” 器件来实现相应的代码。 比如“#100” 之类的延时功能,
 简单的门器件是无法实现延时 100 个单元的, 还有打印语句等, 也是门器件无法实现的。 在设计的时候要确保所写的代码是可以综合的。
下面表格中列出了不可综合或者不推荐使用的代码。
| 代码 | 要求 | 
|---|---|
| initial | 严禁在设计中使用, 只能在测试文件中使用。 | 
| task/function | 不推荐在设计中使用, 在测试文件中可用。 | 
| for | 在设计中、 测试文件中均可以使用。 但在设计中多数会将其用错,所以建议在初期设计时不使用, 熟练后按规范使用 | 
| while/repeat/forever | 严禁在设计中使用, 只能在测试文件中使用 | 
| integer | 不推荐在设计中使用 | 
| 三态门 | 内部模块不能有三态接口, 三态门只有顶层文件才使用。 三态门目的是为了节省管脚, FPGA 内部完全没有必要使用。 | 
| casex/casez | 设计代码内部不能有 X 态和 Z 态, 因此 casez、 casex 设计时不使用。 | 
| force/wait/fork | 严禁在设计中使用, 只能在测试文件中使用 | 
| #n | 严禁在设计中使用, 只能在测试文件中使用 | 
推荐使用的代码及其说明
| 代码 | 备注 | 
|---|---|
| reg/wire | 设计中所有的信号类型定义, 只有 reg 和 wire 两种 | 
| parameter | 设计代码中所有的位宽、 长度、 状态机命名等, 建议都用参数表示, 阅读方便并且修改容易。 | 
| assign/always | 程序块主要部分, 至简设计法对 always 使用有严格规范。 | 
| if else 和 case | always 里面的语句, 使用 if else 和 case 两种方法用来作选择判断, 可以完成全部设计。 | 
| 算术运算符 | 除法和求余运算的电路面积一般比较大, 不建议直接使用除法和求余。 | 
| 赋值运算符(=, <=) | 时序逻辑用“<=” , 组合逻辑用“=” ; 其他情况不存在。 | 
模块结构
Verilog 的基本设计单元是“模块”。模块有五个主要部分: 端口定义、 参数定义(可选) 、 I/O 说明、 内部信号声明、 功能定义。
- 端口定义:
module module_name(clk , 		 //端口 1, 时钟rst_n ,		 //端口 2, 复位dout 		 //其他信号,如 dout
);
- 参数定义
parameter DATA_W = 8;
- I/O 说明
input clk ; 								//输入信号定义
input rst_n ;	 							//输入信号定义
output[DATA_W-1:0] dout; 					//输出信号定义
- 信号说明
reg [DATA_W-1:0] dout; 						//信号类型
(reg、 wire)定义 reg signal1;				//信号类型
缩写命令
在 ~/.vimrc 中可以配置map 映射来完成代码快速生成,如下:
- Shixu
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginendelse beginend
end
- Shixu2
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginendelse if() beginendelse if() beginend
end
- Zuhe
always @(*)begin
end
- Zuhe2
always @(*)beginif()beginendelse beginend
end