目录
抛砖引玉
思维陷阱
很有意义的语法讨论
最后想说的一些话
本文有一个诡计,先让我把你代入到多路选择器中,见如下一个小问题:
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?
然后一顿操作,语法全是错的。
你百思不得其解。。。
开始抱怨网站为什么不给出标准答案供你参考,然后你去看看给出的提示,或者线索?
不绕圈子了,根据题目需要设计的功能,不就是就向量的元素的引用吗?只不过这个引用变量为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+地区或学校+职位(意向职位)+昵称。
对于后来很晚的人,也许你看到这个博客我已经工作了,也许我已经变了,不再是一个热心的博主,因此,可能我没有时间做这些事情了,还请见谅。