文章目录
组合逻辑时序逻辑可综合设计模块结构缩写命令
组合逻辑
这种条件信号变化结果立即变化的 always 语句被称为“组合逻辑” 。
always @(posedge clk)begin
if(sel==0)
c <= a + b;
else
c <= a + d;
end
时序逻辑
这种信号边沿触发, 即信号上升沿或者下降沿才变化的 always, 被称为“时序逻辑” , 此时信号 clk 是时钟。
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
c <= 0;
end
else if(sel==0)
c <= a + b;
else
c <= 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 和 casealways 里面的语句, 使用 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)begin
if(rst_n==1'b0)begin
end
else begin
end
end
Shixu2
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
end
else if() begin
end
else if() begin
end
end
Zuhe
always @(*)begin
end
Zuhe2
always @(*)begin
if()begin
end
else begin
end
end
推荐阅读
发表评论