在下面的代码中,我们定义了一组32位宽的inout双向引脚。要给这32个端口赋值,需要用32个assign语句,写起来比较麻烦。有没有更简单的方法呢?
module test(
input clock,
inout [31:0] io
);
reg [31:0] io_link;
reg [31:0] io_output;
assign io[0] = (io_link[0]) ? io_output[0] : 1'bz;
assign io[1] = (io_link[1]) ? io_output[1] : 1'bz;
assign io[2] = (io_link[2]) ? io_output[2] : 1'bz;
assign io[3] = (io_link[3]) ? io_output[3] : 1'bz;
endmodule
添加一个always语句块,循环32次,给inout数组赋值, 但是编译会报错:
Error (10137): Verilog HDL Procedural Assignment error at test.v(11): object "io" on left-hand side of assignment must have a variable data type
Error: Quartus II 64-Bit Analysis & Synthesis was unsuccessful. 1 error, 0 warnings
Error (293001): Quartus II Full Compilation was unsuccessful. 3 errors, 0 warnings
module test(
input clock,
inout [31:0] io
);
reg [5:0] i;
reg [31:0] io_link;
reg [31:0] io_output;
always @(*) begin
for (i = 0; i < 32; i = i + 1) begin
io[i] = (io_link[i]) ? io_output[i] : 1'bz;
end
end
endmodule
普通的wire型端口可以修改成reg,然后在always (*)组合逻辑语句块内赋值。难道inout就不行了吗?
inout双向口不能声明为reg型,所以无法在always块内赋值,也没有办法在always块内使用assign语句。
我们可以改成generate语句块,将循环变量声明为genvar型,问题就解决了:
module test(
input clock,
inout [31:0] io
);
generate
genvar i;
reg [31:0] io_link;
reg [31:0] io_output;
for (i = 0; i < 32; i = i + 1) begin : IO_GEN
assign io[i] = (io_link[i]) ? io_output[i] : 1'bz;
end
endgenerate
// 可以在generate块外面对里面的寄存器赋值
always @(*) begin
io_link = 32'haabb;
io_output = 32'hfedc;
end
endmodule
我们可以看到,for循环里面也可以用assign语句哦。