错题集:HDLBits 组合逻辑 Mux256to1v 报错分析

题目: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.

提示:

  • 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. It's not always good at this. An error saying "... is not a constant" means it couldn't prove that the select width is constant.
  • In particular, in[ sel*4+3 : sel*4 ] does not work.
  • Bit slicing ("Indexed vector part select", since Verilog-2001) has an even more compact syntax.

错误答案:

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

endmodule

报错提示:

Error (10734): Verilog HDL error at top_module.v(6): sel is not a constant File: /home/h/work/hdlbits.6774772/top_module.v Line: 6

正确答案:(提供了三种方法)

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

	// We can't part-select multiple bits without an error, but we can select one bit at a time,
	// four times, then concatenate them together.
	assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

	// Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax:
	// assign out = in[sel*4 +: 4];		// Select starting at index "sel*4", then select a total width of 4 bits with increasing (+:) index number.
	// assign out = in[sel*4+3 -: 4];	// Select starting at index "sel*4+3", then select a total width of 4 bits with decreasing (-:) index number.
	// Note: The width (4 in this case) must be constant.

endmodule

总结:

1.方法归纳:

方法一:一次选择一位,使用拼接符

方法二、方法三:使用矢量索引语法(这个语法以前没学过)

2.矢量索引语法 - 格式:

(1)in[sel*4+:4],从sel*4开始往高位取4个bit。

         冒号前是起始索引位置,+号代表方向是往高位索引,冒号后面代表索引n个位。

(2)in[sel*4+3-:4],从sel*4+3开始往低位取4个bit。

         冒号前是起始索引位置,-号代表方向是往低位索引,冒号后面代表索引n个位。

注意:冒号前的位置代表的是起始位置,并不代表是高位。也就是说,这个语法,以冒号前的位置作为起始位置,往高位或者低位取4位,然后再把这四位从高到低,放进4位宽的信号里。

3.错误原因

根据编译结果的提示,in[4*sel+3:4*sel]有错,“sel不是常数”。而从题目给的提示来看,应该是因为sel不是常数,所以导致了选择的位宽不是常数。

也就是说,不仅in[4*sel+3:4*sel]不可以,in[4*sel:8]也不可以(编译试过了,会报错);所以冒号两侧都不能出现变量,否则就会报错sel is not constant。

这是因为编译器会认为位宽选择时,如果出现了变量,则无法确定位宽到底是多少。(我猜,进而编译器就无法进行寻址取值等操作。)

4.而官方提供的三种方法为什么含有变量,却可以通过编译呢?

第一种方法是使用拼接符,每次都取一位,把四位拼接起来,所以虽然in[4*sel+3]中存在变量,但也不影响,因为这个变量的位数是确定的,就是1位。

第二种方法和第三种方法又是使用了矢量检索的语法,在这种语法下,in[sel*4+:4]中虽然也出现了变量,但是冒号后的4决定了取多少个位,也就是说位宽的选择是确定了的。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值