在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2105|回复: 6

[求助] 求助!verilog基础的一个小问题

[复制链接]
发表于 2021-4-16 09:40:10 | 显示全部楼层 |阅读模式
30资产
verilog代码中经常能看到如下写法:
                       assign a_n = a;
                        ......
                       always@(posedge clk or negedge rst_n)begin
                                 if(~rst_n) a <= '0;
                                 else         a<= a_n;
                                 end


请问为什么要这样写呢?a与a_n的关系应该怎么理解呢?求指教!

最佳答案

查看完整内容

看的出你的代码是 SV语言写的 之所以这样写 一般是出于这样的考虑 我们的寄存器一般是有D端 以及 Q端 一端是输入端,正常情况下是来自于组合逻辑的输出 输出端仅仅是对输入短的寄存打拍输出 所以根据寄存器的这种特征,很多公司喜欢这样的风格,先用组合逻辑产生寄存器的输入信号,再用时序逻辑仅仅对输入信号打拍。 希望这样的解释能够帮到你!! 其实这样的代码风格不是很好,因为比较容易产生组合回环以及锁存器!!不推 ...
发表于 2021-4-16 09:40:11 | 显示全部楼层


JINNINE 发表于 2021-4-16 10:26
logic [DEPTH-1:0] valid, valid_n;    always_comb begin : valid_block       valid_n = valid;    ...


看的出你的代码是 SV语言写的

之所以这样写 一般是出于这样的考虑
我们的寄存器一般是有D端 以及 Q端
一端是输入端,正常情况下是来自于组合逻辑的输出
输出端仅仅是对输入短的寄存打拍输出

所以根据寄存器的这种特征,很多公司喜欢这样的风格,先用组合逻辑产生寄存器的输入信号,再用时序逻辑仅仅对输入信号打拍。
希望这样的解释能够帮到你!!

其实这样的代码风格不是很好,因为比较容易产生组合回环以及锁存器!!不推荐采用这样的风格!!

如果你对硬件描述语言有稍微深入的理解 其实像下面的代码风格是更好的,也便于正常人的理解,下面的分格是比较容易规避上面的组合回环以及锁存器的风险的
always@(posedge clk or negedge rst_n)
begin
      if(~rst_n)
             a <= '0;
      else         
             a<= ~a;
end


上面的代码 可以完全 等价的写成你所问的那种风格。

这两种风格的代码 在进行大规模复杂的设计的时候 分格的优劣 很容易区分出来 如果是非常简单的设计 没有深刻的感觉的
发表于 2021-4-16 10:10:33 | 显示全部楼层
assign 是数据流描述。
always块是行为描述。
assign 可以直接给等号左边赋值,不用时钟什么的。
always块如果用到了时钟,块内使用非阻塞赋值就会成为一个时序电路。对于时序电路来说,a 等于a_n上一个状态的值。也就是说,如果a_n从1变到0,那么在某一个时刻,两者同时看,会发现a_n已经到0,a是a_n上一个时刻的值,也就是1。生成电路的话是一个D触发器。
我也是刚学,如果说得不对,欢迎来纠正。
发表于 2021-4-16 10:19:59 | 显示全部楼层
我觉得你是不是将代码写错了
a_n一般用于表示a的取反 也就是~a 从命名规则上看

如果真的像你所说的  assign a_n = a;
那么你的代码就等价于
always@(posedge clk or negedge rst_n)
begin
      if(~rst_n)
             a <= '0;
      else         
             a<= a;
end

那么很明显 这段代码没什么特别的作用 a的值在复位后永远是0

如果是我所说的 a_n = ~a的话 整段代码的如下
assign a_n = ~a;
那么always块代码就等价于
always@(posedge clk or negedge rst_n)
begin
      if(~rst_n)
             a <= '0;
      else         
             a<= ~a;
end

这段代码就表示复位后 a的值 会 0->1->0...如此循环往复的反转

 楼主| 发表于 2021-4-16 10:26:23 | 显示全部楼层


buzhou2006 发表于 2021-4-16 10:19
我觉得你是不是将代码写错了
a_n一般用于表示a的取反 也就是~a 从命名规则上看


    logic [DEPTH-1:0] valid, valid_n;
   always_comb begin : valid_block
       valid_n = valid;
       if (wr)     valid_n[waddr]  = 1'b1;
   end
   always_ff @(posedge clk_i or negedge rst_ni)begin
       if(~rst_ni)begin
           valid <= '0;
       end
       else begin
           valid <= valid_n;
       end
    end


贴一下代码吧,_n的后缀不是取反
 楼主| 发表于 2021-4-16 10:30:03 | 显示全部楼层


Marion_ 发表于 2021-4-16 10:10
assign 是数据流描述。
always块是行为描述。
assign 可以直接给等号左边赋值,不用时钟什么的。


时序逻辑我也觉得应该是这样。挺多代码里面都用了这样“先在组合逻辑中赋值再用时序逻辑取值”的方式,我想知道为什么要这样做?
发表于 2021-4-17 12:09:48 | 显示全部楼层
好像状态机里常见这种写法
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-27 02:56 , Processed in 0.028902 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表