HDLBits->Circuits->Multiplexers->Mux256to1v


Verilog切片语法

题目要求如下

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 );

初次编写的代码如下

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

此时代码执行会产生报错

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

这条报错我百思不得其解,然后看到题目给出的提示信息

.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.

这条提示的意思就是说警告中的not a constant File意味着它不能够证明选择的宽度是一个常数,Verilog不支持这种语法,然后注意到最后一段说的Bit slicing(位切片)方法。通过网上查找,发现相关语法如下

[M -: N]  // negative offset from bit index M, N bit result 
[M +: N]  // positive offset from bit index M, N bit result

其中M是指的起始的我们的索引的位置,加减号是指的从索引位置位置向上还是向下切片,而N是指的我们切片的长度。
通过以下的小例子就可以解释这个语法

bit [7:0] PA, PB;
int loc;

initial begin
  loc = 3;
  PA = PB;                      // Read/Write
  PA[7:4] = 'hA;                // Read/Write of a slice
  PA[loc -:4] = PA[loc+1 +:4];  // Read/Write of a variable slice equivalent to PA[3:0] = PA[7:4];
end

所以我们将代码做如下修改

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

然后答案就正确了。