• 【数字IC手撕代码】Verilog固定优先级仲裁器|题目|原理|设计|仿真


    芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球
    四社区联合力荐!近500篇数字IC精品文章收录
    【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍

    在这里插入图片描述

    一、前言

    本系列旨在提供100%准确的数字IC设计/验证手撕代码环节的题目,原理,RTL设计,Testbench和参考仿真波形,每篇文章的内容都经过仿真核对。快速导航链接如下:

    1.奇数分频
    2.偶数分频
    3.半整数分批
    4.小数/分数分频
    5.序列检测器
    6.模三检测器
    7.饮料机
    8.异步复位,同步释放
    9.边沿检测(上升沿,下降沿,双边沿)
    10.全加器,半加器
    11.格雷码转二进制
    12.单bit跨时钟域(打两拍,边沿同步,脉冲同步)
    13.奇偶校验
    14.伪随机数生成器[线性反馈移位寄存器]
    15.同步FIFO
    16.无毛刺时钟切换电路
    17.固定优先级仲裁器
    18.轮询仲裁器

    应当说,手撕代码环节是面试流程中既重要又简单的一个环节,跟软件类的岗位相比起来,数字IC的手撕代码题目固定,数量有限,属于整个面试中必得分的一个环节,在这个系列以外,笔者同样推荐数字IC求职者使用“HdlBits”进行代码的训练
    链接如下
    HDLBits — Verilog Practice

    二、题目

    数字IC工程师在使用多主设备的总线过程中,需要考虑到不同主设备申请总线控制权的优先级问题,请使用Verilog语言,考虑四个主设备,设计固定优先级仲裁器,该仲裁器默认时的总线控制的优先级永远保持为为A>B>C>D

    三、原理

    默认情况下的优先级排序为A>B>C>D,input 请求情况request 的四位二进制,从高到低也分别代表主设备A、B、C、D的总线控制请求,output的grant输出one hot编码,即“1000,0100,0010,0001”四种情况中的一种,给出的案例如下,按照四个周期依次输入控制请求,仲裁器在按照固定优先级算法的条件下会依次响应设备A,D,A,B

    周期请求情况(request)优先级排序响应情况(grant)
    11010ABCD1000(A)
    20001ABCD0001(D)
    31111ABCD1000(A)
    40011ABCD0010(B)

    需要注意的是,虽然我们在上面的例子中提出周期的概念,但对于仲裁器来讲,它是一个纯组合逻辑电路

    3.1 case/if语句法

    我们有很多种方法来实现固定优先级仲裁器,第一种介绍的方法为if/case法:
    说起来其实非常简单,使用if语句先断request的最高位,假如为1,输出1000,假如不为1,再判断request的次高位是否唯一,去输出0100,以此类推进行设计即可。

    需要注意的是,上述的语句除了可以使用if来完成外,也可以使用case来完成。初学者常常用if语句是串行的,有判断优先级,而case语句是并行的,没有判断优先级的角度去理解verilog语言对于if语句和case语句的综合过程,在这个思路下,if语句对应综合出来的逻辑具有优先级,靠前的逻辑少,路径短,靠后的逻辑多,路径长,而case语句的综合是一个parallel的结构,这个说法对于if语句是正确的,而对于case语句来说对也不对
    一个正确的说法是,case语句,即可以实现parallel结构,也可以实现优先级编码
    具体内容可参见case语句的综合结果,你究竟会了吗?
    因此,我们可以使用case语句代替if语句去判断固定优先级的仲裁器应该输出什么grant值,RTL代码参见下文即可

    3.2 for循环法

    除此以外,for语句也可以用来设计固定优先级仲裁器,对于固定主设备数量的固定优先级仲裁器而言,固定循环次数的for语句可以综合成实际电路,这个原则是我们为什么可以使用for语句进行固定优先级仲裁器的基础,但是受限于篇幅有限,我们不给出具体的for循环rtl代码了。

    3.3 补码相与法

    这是一个很巧妙的方法,而我们使用到了2进制的补码的一个特性,即一个数和它的补码相与,得到的结果是一个独热码,独热码为1的那一位是这个数最低的1,这个特性和我们想要寻找,四位二进制的1,在什么时候第一次出现的想法,不谋而合。

    需要注意的是,我们这里把现在给出的request当作补码,去求它的原码,再相与,以下会给处详细解释:

    我们可以这么去思考这个问题,一个二进制4bit的数,减去1,会向这个数第一个非零的位置借位,改变这一位的值,假如与减1后的数进行与操作,那么只有产生进位的这一位在取反后依旧为1,二者相与,得到一个独热码

    举例:(注意这里的request是[0:3]而非[3:0])

    request[0:3]request原码相与出现1的位数
    100100010001第零位
    010011000100第二位
    011110010001第零位
    000111110001第零位
    0000(这里要在前面做一个1的位扩展)11110000

    四、RTL设计

    4.1 case语句法固定优先级仲裁器

    module fixed_arb(request,grant);
    input  [3:0] request;
    output [3:0] grant;
    
    reg    [3:0] grant_reg;
    
    always@(*)
    	case(1'b1)
    	request[3] : grant_reg = 4'b1000;
    	request[2] : grant_reg = 4'b0100;
    	request[1] : grant_reg = 4'b0010;
    	request[0] : grant_reg = 4'b0001;
    	default: grant_reg = 4'b0000;
    	endcase
    
    assign grant = grant_reg;
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    根据原理可知,这种写法的case语句实际上是一个串行结构,以上的内容当然也可以使用if嵌套的形式进行替代,if先判断最高位,依次判断至第零位,default条件下,grant输出4‘b0000,这里就不再赘述

    4.2 加法器法固定优先级仲裁器

    我们之所以在下文的rtl设计中去颠倒grant的高低位,是跟A>B>C>D还是A相关,其中{A,B,C,D}分别代表grant[3:0]从高到低的四位,若为A,则其实不需要高低位颠倒,而对于前者来说则需要,这里请读者注意,为了考虑4’b0000的情况,我们还做了一个位扩展,当然,assign的等式左边与等式右边位宽不相等,lint肯定会有error,但我们这里忽略,并按照舍弃高位保留低位的方式来进行默认操作。

    module fixed_arb_2(request,grant);
    
    input  [3:0] request;
    output [3:0] grant;
    
    assign {grant[0],grant[1],grant[2],grant[3]}= 
    			{1'b1,request[0],request[1],request[2],request[3]} & 
    			~({1'b1,request[0],request[1],request[2],request[3]}-1'b1);
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    五、仿真

    5.1 case法仿真文件

    `timescale 1ns / 1ps
    module fixed_arb_tb();
    reg  [3:0] request;
    wire [3:0] grant;
    
    fixed_arb u1(request,grant);
    
    always #5 request = $random;
    
    initial
    begin
    request = 4'b0000;
    #200;
    $stop;
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5.2 补码相与法仿真文件

    `timescale 1ns / 1ps
    module fixed_arb_tb_2();
    reg  [3:0] request;
    wire [3:0] grant;
    
    fixed_arb_2 u1(request,grant);
    
    always #5 request = $random;
    
    initial
    begin
    request = 4'b0000;
    #200;
    $stop;
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    六、仿真结果分析

    6.1 case法结果分析

    在这里插入图片描述
    可以发现,第一个输出1的request对应的位置,为grant信号输出唯一的1的位置,设计成立。

    6.2 补码相与法结果分析

    在这里插入图片描述
    效果与6.1一样,即从左到右判断第一个出现1的位置,grant输出对应位置的信号

  • 相关阅读:
    【AI】Course1 Introduction of Arificial Intelligence
    【软考】UML中的图之对象图
    回归测试策略指南
    遗传算法GA求解非连续函数问题
    基础会计学
    【Ray】ray.remote和option
    自动驾驶行业源代码防泄漏解决方案
    不容易解的题10.10
    利用Jdk动态代理模拟MyBatis的Mapper功能
    【重识云原生】第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
  • 原文地址:https://blog.csdn.net/weixin_43698385/article/details/125983047