根据代码风格,基本上会综合出3类Mux。
一、MUX分类
1、Binary Mux
这是最常见的一类,选择变量用普通的二进制递增的方式枚举。
case (sel)
2’b00 : z = a;
2’b01 : z = b;
2’b10 : z = c;
2’b11 : z = d;
endcase
如果配合器件的结构来描述 Binary Mux,综合后的效果会很优越。
Stratix 系列里面 Stratix II以上的器件,LUT结构是 6-input LUT。这样的结构用来构造 4:1 的 Binary Mux 是非常合适的。
对于 4-input LUT,4:1 的 Binary Mux会被放到2个LUT中。因为sel是共用的,虽然面积变大了,但速度不会有很大影响;但是如果 Mux的规模变大了,所需的LUT数量会迅速增大,而且延时会越来越大,这是值得注意的。
2、Selector Mux
Selector Mux 使用的是独热码,因此每个输入都应唯一的一条选择线与之对应。
Selector multiplexers have a separate select line foe each data input.
其常见代码风格如下:
与 Binary Mux不同,Selector Mux 一般由 “与”门、“或”门构成。相同的N输入 Mux,Selector Mux 性能逊于 Binary Mux,但是个人认为面积上 Selector Mux是占优势的(结论未经验证)。
文档里面有这样一段话值得注意:
…. However, in many cases the select signal is the output of a decoder, in which case Quartus II Synthesis will try to combine the selector and decoder into a binary multiplexer.
3、Priority Mux
Priority Mux是很不好的结构,特别是对于 4-input LUT来说,Mux链越长,延时越大。
不完整的 if…else 和 ?:就会综合出这样的结构。
如果不是关键路径、对时序要求不高,这样的结构也是没有什么问题的;不过,这样的结构要尽量避免出现在关键路径上。
二、如何避免不好的结构
1、if…else 结构
如果希望避免优先级,最好使用case。
如果优先级是必须的,去掉不必要的default。
… Avoid unnecessary default conditions in your multiplexer logic to reduce the complexity and logic utilization required to implement your design.
2、case 结构
使用default,特别是独热码的时候更应该如此。如果default的分支值不是很重要,给它赋值 X。
… If the value in the invalid cases is not important, specify those cases explicitly by assigning the X (don’t care) logic value instead of choosing another value.