题目:
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[3:0]=in[sel*4+4:sel*4];
endmodule
结果错误,错误原因:
根据编译结果的提示,in[sel4+3:sel4]有错,因为sel不是常数,所以导致了选择的位宽不是常数。所以冒号两侧都不能出现变量,否则就会报错sel is not constant。
正确解法:
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、
assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};
使用大括号 {} 运算符,逐位选取后再进行连接。这种方法适用于选取单个位时,但如果需要选择多个连续的位,则会出现错误。示例代码中使用了这种方法,通过逐位选取并连接来实现对输入信号 in 中的特定位的选取。
该方法使用拼接符,每次都取一位,把四位拼接起来,所以虽然in[4*sel+3]中存在变量,但也不影响,因为这个变量的位数是确定的,就是1位。
2、注意该种索引方法:
assign out = in[sel*4 +: 4]; // 从索引 "sel*4" 开始选择,然后选择总宽度为 4 位,索引递增。
assign out = in[sel*4+3 -: 4]; // 从索引 "sel*4+3" 开始选择,然后选择总宽度为 4 位,索引递减。
使用“indexed vector part select”语法,这种方法对于选择连续的多个位更为方便。示例代码中提供了两种这种语法的示例,分别是正向递增选择和逆向递减选择。这种语法的特点是通过指定起始索引和位宽来进行选取,比较直观和方便。
冒号前是起始索引位置,+号代表方向是往高位索引,冒号后面代表索引n个位。-号代表方向是往低位索引,冒号后面代表索引n个位。冒号前的位置代表的是起始位置,并不代表是高位。也就是说,这个语法,以冒号前的位置作为起始位置,往高位或者低位取4位,然后再把这四位从高到低,放进4位宽的信号里。
使用了矢量检索的语法,在该种语法下,in[sel*4+:4]中虽然也出现了变量,但是冒号后的4决定了取多少个位,即位宽是确定的。