【逻辑电路】for循环的等价展开电路

举报
李锐博恩 发表于 2022/05/01 22:15:35 2022/05/01
【摘要】 引言 本文讨论如何理解for循环在逻辑电路中的实现。通过各种写法的rtl电路对比,来探讨for循环的等价电路,或者for电路的等价展开电路。 for循环示例 如下给出一个for循环使用的例子,我们来...

引言

本文讨论如何理解for循环在逻辑电路中的实现。通过各种写法的rtl电路对比,来探讨for循环的等价电路,或者for电路的等价展开电路。

for循环示例

如下给出一个for循环使用的例子,我们来试图理解for循环如何体现在逻辑电路中。

`timescale 1ns / 1ps
module generate_test(
    input   wire            clk     ,
    input   wire            rst     ,
    input   wire    [2:0]   in_sel  ,
    //
    input   wire    [7:0]   in_ch0  ,
    input   wire    [7:0]   in_ch1  ,
    input   wire    [7:0]   in_ch2  ,
    
    output  reg     [7:0]   in_ch_seq 
    );

    
    wire     [7:0]   in_ch[2:0];

    assign  in_ch[0]    =   in_ch0;
    assign  in_ch[1]    =   in_ch1;
    assign  in_ch[2]    =   in_ch2;

    //输入数据串行化
    // reg     [7:0]   in_ch_seq;
    reg     [2:0]   i;
    always@(posedge clk) begin
        for(i = 0; i <= 2; i = i + 1) begin
            if(in_sel[i]) begin
                in_ch_seq       <=  in_ch[i];
            end
        end
    end



endmodule


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

很显然,这个逻辑的功能大概就是将并行的输入串行化,这可不必关心。本文的重点是这个for循环怎么理解?

先看它对应的RTL电路:

rtl

很容易看出,in_sel的各bit用于选择哪个in_sel输出;

无优先级的if

那既然如此,是不是可以这么实现for循环的替代呢?即
用如下逻辑:

    always@(posedge clk) begin
        if(in_sel[0]) begin
            in_ch_seq       <=  in_ch[0];
        end
        if(in_sel[1]) begin
            in_ch_seq       <=  in_ch[1];
        end
        if(in_sel[2]) begin
            in_ch_seq       <=  in_ch[2];
        end
    end

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

替换逻辑:

    reg     [2:0]   i;
    always@(posedge clk) begin
        for(i = 0; i <= 2; i = i + 1) begin
            if(in_sel[i]) begin
                in_ch_seq       <=  in_ch[i];
            end
        end
    end

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

我们看下替换后的逻辑电路:
无优先级的if
可见, 几乎与for循环写法没有区别,可见,for循环的逻辑电路,可以等价于这种if展开。

问题本科到此结束,但仍需看下其他几种写法;

有优先级的if

    always@(posedge clk) begin
        if(in_sel[0]) begin
            in_ch_seq       <=  in_ch[0];
        end
        else if(in_sel[1]) begin
            in_ch_seq       <=  in_ch[1];
        end
        else if(in_sel[2]) begin
            in_ch_seq       <=  in_ch[2];
        end
    end

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

相信我们的设计,使用这种写法也可以实现我们的功能,其rtl为:

有优先级的if

和上述for循环几乎没有区别,区别仅在于in_sel[0]以及in_ch[0]会被优先判断。

case

使用case写法替换for:

    always@(posedge clk) begin
        case(1'b1)
            in_sel[0]: in_ch_seq   <=  in_ch[0];
            in_sel[1]: in_ch_seq   <=  in_ch[1];
            in_sel[2]: in_ch_seq   <=  in_ch[2];
            default:    in_ch_seq   <=  in_ch_seq;
        endcase
    end


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

其rtl电路如下:
rtl
我相信仅从功能的角度,这种方式最容易理解。

将for循环的逻辑电路想象成这种形式的电路最容易理解。

总结

从功能的角度来看,上述这几种方式去替代我们的for写法均可,但是有时候,使用for循环最为方便,例如我们的输入特别多,我们使用if,那样会让我们的代码行数非常多,显得臃肿不堪,可效率低下,这时候for循环就可大显身手。

还有一个问题就是为什么我们的示例,不是仅为单纯的for,还加入了if,有多方面的考虑:

一方面,是这样看起来我们的for循环更像是一个多驱动的电路,可实际并非如此,可见我们的等价写法;

另一方面,更多的趣味性(没必要找更多有点了)。

最后,不免有人抬杠,说有漏洞之类,没关系,你是对的。

需要之人,自能得到其价值,用于自身。

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/124226809

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。