Verilog HDL学习
HDLBits刷题错误总结
-
always block
里误用wire
类型变量 -
16-bits,每位都是1,误表示为
{16{1}}
,应当表示为{16{1'b1}}
,事实上用'1
更简单 -
数组维度声明错误,比如,我想声明一个长度为8的
chunks
数组,数组里每个元素宽度为4位,- 错误示范
wire [7:0] chunks [3:0];
- 正确写法
wire [3:0] chunks [7:0];
-
generate_for_loop
中for
循环的begin
后容易忘记加:name_of_the_for_loop
HDLBits刷题新知
-
Use bitwise operators and part-select to do the entire calculation in one line of code.
module top_module (input [3:0] in,output [2:0] out_both,output [3:1] out_any,output [3:0] out_different );assign out_any = in[3:1] | in[2:0];assign out_both = in[2:0] & in[3:1];assign out_different = in ^ {in[0], in[3:1]}; endmodule
-
检查各bit是否相同可以用XOR
^
-
Bit-slicing(Indexed vector part-select),切片,如:
assign data_out = data_in[INDEX*4+3: INDEX*4];
要求切片下标
INDEX
必须为静态常量表达式,不能是动态变量,如果需要通过变量进行批量选位操作(例如批量赋值、切片),则要采用generate_for_loop
通过genvar
静态展开;但是数组下标可以是动态变量。Mux256to1v - HDLBits
module top_module( input [1023:0] in,input [7:0] sel,output [3:0] out );wire [3:0] chunks [255:0];genvar i;generate for (i = 0; i < 256; i++) begin: loop_blockassign chunks[i] = in[i*4+3:i*4];endendgenerateassign out = chunks[sel];endmodule
事实上,利用数组下标是动态变量,切片可以转化为拼接的数组,有更简洁的代码:
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]};endmodule
其实也并非不能用切片,但得满足特定的语法:
module top_module( input [1023:0] in,input [7:0] sel,output [3:0] out );assign out = in[sel*4 +:4];//或者是://assign out = in[sel*4+3 -: 4];endmodule
-
assign sum = x + y;
可以自动计算进位信号,比如为实现下图电路:Exams/m2014 q4j - HDLBits
可以编写如下简单的代码就能实现上述电路的功能,其中
sum[4]
就是自动进位信号。module top_module (input [3:0] x,input [3:0] y,output [4:0] sum );assign sum = x + y;endmodule
但是,
assign sum = {x + y};
则会裁切掉”溢出“的高位,不会自动扩展加法进位,在此处不可取!