verilog 写rtl注意事项_Verilog设计与逻辑综合实例解析(含代码)

e92183e82236f4c912b657eafc41d730.png

本文讨论Verilog HDL与综合相关的问题。

一、赋值

本节讨论如何在Verilog中的实现不同的赋值,以及它们在逻辑综合中会推断出什么样的电路。

1.1、当对同一个net,使用多个assign语句,会综合出什么样的逻辑?

在可综合的verilog代码中,为同一个net使用多个assign语句是错误的。综合工具会报出语法错误,即“net is being driven by more than one source”。 例如,以下是错误的:

//only one type of output assignment is legal for synthesis
wire tmp ;
assign tmp = in1 & in2 ;
assign tmp = in1 | in2 ;

但是,使用多个assign来驱动三态net 是合法的语句,如下示例所示:

input enable1 , enable2 ;
wire tmp ;
assigm tmp = (enable1 == 1’b1) ? (in1 & in2) : 1’bz ;
assigm tmp = (enable2 == 1’b1) ? (in3 & in3) : 1’bz ;

1.2、条件赋值在逻辑综合时会推断出什么电路?

条件赋值通过“?:”实现。条件赋值在逻辑综合时被推断为MUX。 例如,以下示例是一个简单的MUX:

wire wire1 ;
assign wire1 = (sel == 1’b1) ? a : b ;

dc1525c10c7cd3bae12e562f3098e2fd.png

1.3、条件赋值嵌套会综合出什么样的电路?

如下例所示,条件赋值嵌套会被综合成MUX “tree ”:

assign out1 = (sel1 == 1’b1) ? in1 :
(sel2 == 1’b1) ? in2 :
(sel3 == 1’b1) ? in3 :in4 ; 

fbef2fb6d50e560ab932947b7c285697.png

1.4 在同一个always语句块中,对同一个reg变量多次赋值会综合出什么电路 ?

在同一个always语句块中,对同一个reg变量进行多次非阻塞赋值时,逻辑综合时会选择最后一个赋值。 例如:

module lower(clk ,in1 ,in2 ,out2) ;
	input clk ,in1 , in2 ;
	outout out2 ;
	reg tmp ;
	always@(posedge clk) begin
		tmp <= (in1 ^ in2) ; 
tmp <= (in1 & in2) ;
tmp <= (in1 | in2) ;
end
assign out2 = tmp ;
endmodule

100160466af932118a2933497bfd7df6.png

在刚刚的示例中,OR逻辑是最后一个赋值。因此,综合出来的逻辑是OR门。 如果最后一个赋值是“&”运算符,它会综合成一个AND逻辑。

对于组合逻辑中always语句块中的阻塞赋值来说,情况也是如此。

always@(in1 , in2) begin
	tmp = (in1 & in2) ;
	tmp = (in1 ^ in2) ;
	tmp = (in1 | in2) ;  // The final logic picked up is the OR gate
end

如果多次赋值存在于if-else或case语句中。 例如,

a269851e00c7cb775f492af3cad436e6.png

在这种情况下,在每个时钟周期仅执行一个唯一的赋值。

在上面的例子中,没有关于哪个语句会被执行赋值的歧义,因为分支控制是明确定义的。

1.5 为什么时序逻辑应该用非阻塞赋值,如果用阻塞赋值会发生什么?并且与组合逻辑进行比较。

阻塞赋值和非阻塞赋值之间的主要区别是阻塞赋值中的RHS会被立即赋值到LHS,而非阻塞赋值,LHS的赋值是发生在RHS值被计算之后。

以下说明了在时序逻辑中使用阻塞赋值和非阻塞赋值的不同场景:

1.5.1 在时序逻辑中使用阻塞赋值

以下是时序逻辑中使用阻塞赋值的Verilog模块示例:

bba39b74da3b77c62dec89b4506c813e.png

在上面的例子中,reg1,reg2,reg3,out1都是阻塞赋值。 综合结果是单个FF触发器,输入为in1,q输出为out1,如图下图所示:

bd4b4d485796811576b3b77864407b8c.png

这是因为in1和out1之间的中间结果是以阻塞赋值形式存储在reg1,reg2和reg3中。 结果,对out1的RHS最终计算会被立即赋值到out1, reg1,reg2和reg3已经通过综合进行了优化。

1.5.2 在时序逻辑中使用非阻塞赋值

以下代码示例了时序逻辑中使用非阻塞赋值:

7c7d498402e852fa0e297c05faf87ffc.png

在上面的例子中,reg1,reg2,reg3,out1为非阻塞赋值。 综合结果为4个触发器。

d9a174a37215a9180e2583c9804b42db.png

这是因为in1和out1之间的中间结果是以非阻塞赋值存储在reg1,reg2和reg3中。在这种情况下,输出是由clk事件控制的移位寄存器。

1.5.3 在组合逻辑中使用阻塞赋值

以下示例说明了组合逻辑中的阻塞赋值的用法:

c98f8f2a29046d787912f854fd7f60b4.png

在上面的使用阻塞赋值的组合逻辑语句中,没有posedge,并且“<=”被“=”替换。 由此综合的逻辑很简单,是in1到out1之间的连线。

50f8a533deded732697fc39fdeedace9.png

这是因为所有的赋值都是立即执行的,没有需要等待的事件。

2、Tasks 和Functions

Tasks 和 functions主要是有助于代码的可重用性。

2.1 function中的逻辑被综合成了什么?

由于function中没有任何时序结构,function只能综合出组合逻辑。

例如,以下function有2个输入信号和一个控制信号,输出算术运算结果。

c47415298901e56f05ed066561789a85.png

2.2Verilog function有哪些重要的注意事项?

2.2.1 每次调用function时,局部变量和返回值应该是都会被赋值,否则将导致形成锁存器。 例如,以下示例中,if条件语句没有else语句。也就是说,如果sel是false,该function将返回其先前调用的值,就好像结果被锁存住了。

6b3b84a192ae722e26cb18de21ba6cca.png

2.2.2 fucntion只用于综合成组合逻辑。但是,fucntion的最终结果可以用作D触发器的输入。

2.2.3 fucntion不应包括延迟(#)或事件控制(@,wait)语句。

2.2.4 fucntion可以调用其他fucntion,但不能调用task。

2.2.5 fucntion在调用时会返回一个值。

2.2.6 fucntion内声明的parameters,作用范围仅在本地,并且不能在fucntion之外使用。 在以下示例中,width参数在函数之外声明,double_width参数在函数内声明。

1e33199de9d71ef237fbd15c18526ce9.png

2.3 task中的逻辑被综合成了什么?

虽然在task中可以有@等时序控制结构中,它仅适用于仿真。综合工具会忽略所有task中的时序结构。因此,如果task中存在时序控制结构,可能会存在仿真和综合不匹配的现象。

因此,在可综合verilog中一般只会使用task综合基本的组合逻辑,在testbench中调用带有时序控制结构的task具有较好的通用性。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CFAR (Constant False Alarm Rate) 模块是用于雷达信号处理的模块,它可以检测出目标,并排除掉噪声和干扰。下面是一个基本的CFAR模块的RTL代码设计文档实例。 # 1. 模块介绍 该模块是一个CFAR模块,用于雷达信号处理。它使用了一个CA-CFAR(Cell Averaging Constant False Alarm Rate)算法来检测目标并排除噪声和干扰。 # 2. 输入和输出 ## 2.1 输入 - clk: 输入时钟信号 - reset: 异步复位信号 - data_in: 输入数据信号,包括雷达信号和噪声信号 - threshold: 阈值,用于检测目标 ## 2.2 输出 - target_detected: 目标是否被检测到的信号 - target_location: 目标位置的信号 # 3. 功能实现 该模块的主要功能是使用CA-CFAR算法检测目标并排除噪声和干扰。具体实现如下: 1. 将输入数据分成若干个细胞,每个细胞的大小为B x P(B为脉冲个数,P为脉冲宽度)。 2. 对每个细胞中的数据进行求和,得到细胞的能量。 3. 对每个细胞的能量进行平均值计算,得到背景噪声的能量。 4. 对每个细胞的能量与背景噪声能量进行比较,如果大于阈值,则认为该细胞中存在目标。 5. 对所有检测到的目标进行进一步处理,如计算目标位置和速度等信息。 6. 输出检测到的目标信号和目标位置信号。 # 4. RTL代码实现 以下是该模块的RTL代码实现: ```verilog module CFAR ( input clk, input reset, input [B*P-1:0] data_in, input threshold, output target_detected, output [N-1:0] target_location ); parameter B = 8; parameter P = 16; parameter N = 64; reg [B-1:0] cell_energy [N-1:0]; reg [B-1:0] background_energy [N-1:0]; reg [N-1:0] target_detected; reg [N-1:0] target_location; integer i, j; always @(posedge clk) begin if (reset) begin for (i = 0; i < N; i = i + 1) begin cell_energy[i] = 0; background_energy[i] = 0; target_detected[i] = 0; target_location[i] = 0; end end else begin for (i = 0; i < N; i = i + 1) begin cell_energy[i] = 0; for (j = 0; j < B*P; j = j + 1) begin cell_energy[i] = cell_energy[i] + data_in[i*B*P+j]; end background_energy[i] = background_energy[i] + (cell_energy[i] - background_energy[i]) / 16; if (cell_energy[i] > background_energy[i]*threshold) begin target_detected[i] = 1; end else begin target_detected[i] = 0; end if (target_detected[i] == 1) begin target_location[i] = i; end else begin target_location[i] = 0; end end end end endmodule ``` # 5. 总结 该CFAR模块使用了CA-CFAR算法来检测雷达信号中的目标,并排除噪声和干扰。通过输入数据信号和阈值信号,该模块可以输出目标是否被检测到的信号和目标位置的信号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值