在 Verilog 寄存器中将 0 转换为 Z
Converting 0 to Z in Verilog register
我正在使用连接到 FPGA 的 charlieplexed LED 板,我想将包含 1 和 0 的寄存器转换为 0 和 z。例如,8'b01000000 到 8'bz0zzzzzz.
以下代码有效:
LED = 8'b01000000;
converted = {LED[0] ? 1'b0 : 1'bz,
LED[1] ? 1'b0 : 1'bz,
LED[2] ? 1'b0 : 1'bz,
LED[3] ? 1'b0 : 1'bz,
LED[4] ? 1'b0 : 1'bz,
LED[5] ? 1'b0 : 1'bz,
LED[6] ? 1'b0 : 1'bz,
LED[7] ? 1'b0 : 1'bz};
为简单起见,我想用一行代码替换它。但是,z 的大多数逻辑运算都会导致 'unknown' 值 x,我的编译器将其解析为 0。是否有可以完成此转换的按位运算?
你可以试试for循环。这将使您的代码规模更好。
reg [7:0] converted;
integer i;
always @* for (i=0; i<8; i=i+1) converted[i] = LED[i] ? 1'b0 : 1'bz;
您还可以在生成块中使用 for 循环。如果 converted
旨在合成三态驱动程序,则此方法很有用。
wire [7:0] converted;
genvar gidx;
generate
for(gidx=0; gidx<8; gidx=gidx+1) begin : label_gen_pulldown
assign converted[gidx] = LED[gidx] ? 1'b0 : 1'bz;
end
endgenerate
LED=8'b0zzzzzzz;
这会给你答案。
像这样将每一位委托给一个模块怎么样?这是 Verilog-2001 语法:
module converter(signal, converted);
input signal;
output wire converted;
assign converted = signal ? 1'b0 : 1'bz;
endmodule
LED = 8'b01000000;
// one liner
converter _converter[7:0](.signal(LED), .converted(converted));
Documented here 第 21 页(标记为第 17 页):
module_name instance_name instance_array_range( .port_name(signal), ... );
instance_array_range
(optional) instantiates multiple modules, each instance
is connected to different bits of a vector
If the bit width of a module port is different than the width of the signal
connected to it, each module port instance is connected to a part select of
the signal, with the right-most instance index connected to the right-most
part of the vector, and progressing towards the left.
There must be the correct number of bits in each signal to connect to all
instances (the signal size and port size must be multiples).
这会将 LED
和 converted
位数组分布在 8 个实例化的 converter
中,因此 for 循环是隐式为您完成的。
我正在使用连接到 FPGA 的 charlieplexed LED 板,我想将包含 1 和 0 的寄存器转换为 0 和 z。例如,8'b01000000 到 8'bz0zzzzzz.
以下代码有效:
LED = 8'b01000000;
converted = {LED[0] ? 1'b0 : 1'bz,
LED[1] ? 1'b0 : 1'bz,
LED[2] ? 1'b0 : 1'bz,
LED[3] ? 1'b0 : 1'bz,
LED[4] ? 1'b0 : 1'bz,
LED[5] ? 1'b0 : 1'bz,
LED[6] ? 1'b0 : 1'bz,
LED[7] ? 1'b0 : 1'bz};
为简单起见,我想用一行代码替换它。但是,z 的大多数逻辑运算都会导致 'unknown' 值 x,我的编译器将其解析为 0。是否有可以完成此转换的按位运算?
你可以试试for循环。这将使您的代码规模更好。
reg [7:0] converted;
integer i;
always @* for (i=0; i<8; i=i+1) converted[i] = LED[i] ? 1'b0 : 1'bz;
您还可以在生成块中使用 for 循环。如果 converted
旨在合成三态驱动程序,则此方法很有用。
wire [7:0] converted;
genvar gidx;
generate
for(gidx=0; gidx<8; gidx=gidx+1) begin : label_gen_pulldown
assign converted[gidx] = LED[gidx] ? 1'b0 : 1'bz;
end
endgenerate
LED=8'b0zzzzzzz;
这会给你答案。
像这样将每一位委托给一个模块怎么样?这是 Verilog-2001 语法:
module converter(signal, converted);
input signal;
output wire converted;
assign converted = signal ? 1'b0 : 1'bz;
endmodule
LED = 8'b01000000;
// one liner
converter _converter[7:0](.signal(LED), .converted(converted));
Documented here 第 21 页(标记为第 17 页):
module_name instance_name instance_array_range( .port_name(signal), ... );
instance_array_range
(optional) instantiates multiple modules, each instance is connected to different bits of a vectorIf the bit width of a module port is different than the width of the signal connected to it, each module port instance is connected to a part select of the signal, with the right-most instance index connected to the right-most part of the vector, and progressing towards the left.
There must be the correct number of bits in each signal to connect to all instances (the signal size and port size must be multiples).
这会将 LED
和 converted
位数组分布在 8 个实例化的 converter
中,因此 for 循环是隐式为您完成的。