HDLBits 系列(10)(Mux256to1)多路选择器的固定思维,你别想太多!

目录

抛砖引玉

思维陷阱

很有意义的语法讨论

最后想说的一些话


抛砖引玉

本文有一个诡计,先让我把你代入到多路选择器中,见如下一个小问题:

Create a 16-bit wide, 9-to-1 multiplexer. sel=0 chooses a, sel=1 chooses b, etc. For the unused cases (sel=9 to 15), set all output bits to '1'.

如何实现这个题目的要求呢?

很简单,是个人都会想到,一个一个的列出来:

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output reg [15:0] out );
    always @(*)begin
        case(sel)
            4'd0:out = a;
            4'd1:out = b;
            4'd2:out = c;
            4'd3:out = d;
            4'd4:out = e;
            4'd5:out = f;
            4'd6:out = g;
            4'd7:out = h;
            4'd8:out = i;
            default:out=16'hffff;
        endcase
    end
endmodule

顺便讲个题外话,在博文如何写出一定不生成锁存器的代码时,我们是给输出一个默认值;

这样的话,就不需要default这个情况也行了,因为如果case没有对应的选择,就将输出置为默认值。

那么这个设计可以这么来做:

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output reg [15:0] out );
    always @(*)begin
        out=16'hffff;
        case(sel)
            4'd0:out = a;
            4'd1:out = b;
            4'd2:out = c;
            4'd3:out = d;
            4'd4:out = e;
            4'd5:out = f;
            4'd6:out = g;
            4'd7:out = h;
            4'd8:out = i;
            
        endcase
    end
endmodule

差不多了,思维差不多了,应该进入了多路选择器,不,更具体的应该是case的圈套。

思维陷阱

再看题:

Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel=0 should select in[0], sel=1 selects bits in[1], sel=2 selects bits in[2], etc.

谷歌翻译一下:

创建一个1位宽的256:1多路复用器。 256个输入全部打包为单个256位输入向量。 sel = 0应该选择in [0],sel = 1选择in [1]中的位,sel = 2选择in [2]中的位,依此类推。

看到这个题目,你可能就会想了,256种情况,用case一个一个列出来的话可能会被累死,太脑残了。

怎么办呢?

用for循环?用generate for?

然后一顿操作,语法全是错的。

你百思不得其解。。。

开始抱怨网站为什么不给出标准答案供你参考,然后你去看看给出的提示,或者线索?

  • With this many options, a case statement isn't so useful.
  • Vector indices can be variable, as long as the synthesizer can figure out that the width of the bits being selected is constant. In particular, selecting one bit out of a vector using a variable index will work.

不绕圈子了,根据题目需要设计的功能,不就是就向量的元素的引用吗?只不过这个引用变量为sel了。

给出设计:

module top_module (
	input [255:0] in,
	input [7:0] sel,
	output  out
);

	assign out = in[sel];
	
endmodule

也许你没有想多,那你很优秀。


很有意义的语法讨论

那行,这样可以了,再接再厉,最后再看一题:

Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

经过了上一题的洗礼,你应该长大了,你也许会写出这样的代码:

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    assign out = in[4*sel + 3:4*sel];


endmodule

这样呢?只能表达出一个思路,思路是对的,所以可以称之为伪代码,但是在编译器那里是过不去的,也就是语法错误。

我想起了之前师弟问过我的一个问题,就是关于能不能这样写的问题?我当时也不太清楚,后来它找到了一种新的语法,Verilog 2001新加的写法,让人看了陌生不已,甚至不想接受(今天又在知乎发现了一个网站,然后对这个语法讲解的不错):

assign out = in[sel*4 +: 4];

意思是 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4];

或者

assign out = in[sel*4+3 -: 4];	

从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4];

虽然语法正确,但是至今我仍然不想使用这种写法,我太古板了吗?

既然如此,解决方法万万条,干嘛非要和自己过不去。

既然对于数组的引用只能有一个变量,也就是既然in[sel]能用,何不延用同样的方法来实现这个题目的要求,如下:

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

endmodule

这样不就很正规平常不过的写法了吗?


最后想说的一些话

在今年的秋招一开始,我就建立了一个微信群,在CSDN发布了一条博文,召集全国各地的同行朋友们共同加入,共同讨论秋招求职笔试,面试经验,目前已经有300多人加入,各位才华横溢,让我大开眼界。

到今天11月份,从西北地区最早结束到其他各地陆续结束,但是我们曾开玩笑说,本群继续召集下一届同行,作为先行者的我们也会对你们给予应有的帮助,欢迎加入,到你们晒工资的时候,会不会再次把我们倒挂呢?拭目以待。

由于人数较多,所以加我的时候务必备注:CSDN+地区或学校+职位(意向职位)+昵称。

对于后来很晚的人,也许你看到这个博客我已经工作了,也许我已经变了,不再是一个热心的博主,因此,可能我没有时间做这些事情了,还请见谅。

 

 

 

你可能感兴趣的:(#,HDLBits)