我一直在尝试构建一个模块,它返回(3位)输入的二进制补码表示(第一位是符号)。我认为以下代码在概念上是正确的,但我可能错过了它的结构:当我尝试编译时,我得到以下错误:
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
搜索该错误表明,在同时使用变量作为输入和输出时通常会看到它,但这不是我的情况。你能指出错误的位置吗?
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
always @(a_i[2:0] or f_o[2:0])
begin
if (a_i[2] == 1)
begin
f_o[2] = a_i[2];
f_o[1:0] = (~a_i[1:0] + 'b1);
end
else
begin
f_o = a_i;
end
end
endmodule
答案 0 :(得分:2)
在Verilog中,在大多数情况下,未声明的标识符被视为隐式线程声明。由于未声明f_o,编译器认为它是连线,而不是变量。这会导致编译器抱怨所有分配。
// What was typed
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
// What the compiler implicitly declares
wire [2:0] a_i;
wire [2:0] f_o;
要修复它,您可以声明变量或声明端口和变量。
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
reg [2:0] f_o;
module ca2 (a_i,f_o);
input [2:0] a_i;
output reg [2:0] f_o;
答案 1 :(得分:1)
f_o
需要声明为reg。 output reg [2:0] f_o
。
此外,我不确定你在计算什么,这不是标准的二重补充。
module ca2 (
input [2:0] a_i,
output [2:0] twos_comp,
output [2:0] also_twos_comp
);
assign twos_comp = ~a_i + 1'b1;
assign also_twos_comp = -a_i ;
endmodule
你可能正在处理一个编码输入,但是twos_complement会否定我希望符号位(MSB)改变的数字。虽然我们将其称为符号位,但它也包含有关值的信息,因此不能仅删除并保持数字不变。
答案 2 :(得分:0)
第一种解决方案 -> 在时序电路中,输出必须是 reg 的形式。 接下来我们需要知道,在二进制补码中,我们从位 0 开始到结束,因此条件不正确。 如果零位为 1,则零位不变,其余位变为非。
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always @(a_i[2:0] or f_o[2:0]) begin
if (a_i[0] == 1'b1) begin
f_o[0] = a_i[0];
f_o[2:1] = (~a_i[2:1]);
end
else
if(a_i[1]==1'b1) begin
f_o[1:0] = a_i[1:0];
f_o[2] = (~a_i[2]);
end
else
if(a_i[2] == 1'b1) begin
f_o = a_i ;
end
end
endmodule
第二种解决方案 -> 在二进制数中,如果我们用零减去这个数,我们得到二进制补码。
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always @(a_i[2:0] or f_o[2:0]) begin
f_o = 3'b000 - a_i ;
end
endmodule
第三种解决方案 -> 所有位都变为非,最后,它们被添加到数字 1 (3'b000 = 3'b0)
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
reg [2:0] finish ;
always @(a_i[2:0] or f_o[2:0]) begin
finish = (~a_i);
f_o = finish + 3'b001 ;
end
endmodule