Verilog 条件分配输出 X 应该有 1
Verilog conditional assign outputs X where there should be 1
我目前正在基于 ARMv8 处理器中的符号扩展器在 Verilog 中构建一个符号扩展器,但是在扩展第一个结果后,每个后续结果都会将输出中的 1 变成 X。我该如何摆脱X 的?
我制作的模块和快速测试台如下图
符号扩展器:
`timescale 1ns / 1ps
module SignExtender(BusImm, ImmIns);
output [63:0] BusImm;
input [31:0] ImmIns;
wire extBit;
assign extBit = (ImmIns[31:26] == 6'bx00101) ? ImmIns[25]:
(ImmIns[31:24] == 8'bxxx10100) ? ImmIns[23]:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? ImmIns[20]:
1'b0;
assign BusImm = (ImmIns[31:26] == 6'bx00101) ? {{38{extBit}}, ImmIns[25:0]}:
(ImmIns[31:24] == 8'bxxx10100) ? {{45{extBit}}, ImmIns[23:5]}:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? {{55{extBit}}, ImmIns[20:12]}:
64'b0;
assign BusImm = 64'b0;
endmodule
测试台:
`timescale 1ns / 1ps
`define STRLEN 32
`define HalfClockPeriod 60
`define ClockPeriod `HalfClockPeriod * 2
module SignExtenderTest;
task passTest;
input [63:0] actualOut, expectedOut;
input [`STRLEN*8:0] testType;
inout [7:0] passed;
if(actualOut == expectedOut) begin $display ("%s passed", testType); passed = passed + 1; end
else $display ("%s failed: 0x%x should be 0x%x", testType, actualOut, expectedOut);
endtask
task allPassed;
input [7:0] passed;
input [7:0] numTests;
if(passed == numTests) $display ("All tests passed");
else $display("Some tests failed: %d of %d passed", passed, numTests);
endtask
reg [7:0] passed;
reg [31:0] in;
wire [63:0] out;
SignExtender uut (
.BusImm(out),
.ImmIns(in)
);
initial begin
passed = 0;
in = 32'hF84003E9;
#10;
begin
passTest(out, 63'b0, "Stuff", passed);
#10;
in = 32'hf84093ea;
#10;
passTest(out, 63'b0, "Stuff", passed);
end
end
endmodule
在您的比较中,您似乎将 x
视为“无关”值,但事实并非如此。 x
是表示“未知”的特定值。由于您将输入信号驱动为所有已知值(0 或 1),因此所有 ==
比较都解析为 x
,并且您的输出中包含 x
。您应该只比较您感兴趣的位。例如,更改:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? {{55{extBit}}, ImmIns[20:12]}:
至:
( (ImmIns[27:24] == 4'b1000) && (ImmIns[21] == 1'b0) ) ? {{55{extBit}}, ImmIns[20:12]}:
您需要对所有比较进行类似的更改。
此外,您 BusImm
连续分配了 2 个任务。去掉这一行:
assign BusImm = 64'b0;
这些更改会从您的输出中得到 x
。
也可以考虑使用 casez
。请参阅 IEEE Std 1800-2017,第 12.5.1 节 带有 do-not-cares 的 Case 语句。
我目前正在基于 ARMv8 处理器中的符号扩展器在 Verilog 中构建一个符号扩展器,但是在扩展第一个结果后,每个后续结果都会将输出中的 1 变成 X。我该如何摆脱X 的?
我制作的模块和快速测试台如下图
符号扩展器:
`timescale 1ns / 1ps
module SignExtender(BusImm, ImmIns);
output [63:0] BusImm;
input [31:0] ImmIns;
wire extBit;
assign extBit = (ImmIns[31:26] == 6'bx00101) ? ImmIns[25]:
(ImmIns[31:24] == 8'bxxx10100) ? ImmIns[23]:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? ImmIns[20]:
1'b0;
assign BusImm = (ImmIns[31:26] == 6'bx00101) ? {{38{extBit}}, ImmIns[25:0]}:
(ImmIns[31:24] == 8'bxxx10100) ? {{45{extBit}}, ImmIns[23:5]}:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? {{55{extBit}}, ImmIns[20:12]}:
64'b0;
assign BusImm = 64'b0;
endmodule
测试台:
`timescale 1ns / 1ps
`define STRLEN 32
`define HalfClockPeriod 60
`define ClockPeriod `HalfClockPeriod * 2
module SignExtenderTest;
task passTest;
input [63:0] actualOut, expectedOut;
input [`STRLEN*8:0] testType;
inout [7:0] passed;
if(actualOut == expectedOut) begin $display ("%s passed", testType); passed = passed + 1; end
else $display ("%s failed: 0x%x should be 0x%x", testType, actualOut, expectedOut);
endtask
task allPassed;
input [7:0] passed;
input [7:0] numTests;
if(passed == numTests) $display ("All tests passed");
else $display("Some tests failed: %d of %d passed", passed, numTests);
endtask
reg [7:0] passed;
reg [31:0] in;
wire [63:0] out;
SignExtender uut (
.BusImm(out),
.ImmIns(in)
);
initial begin
passed = 0;
in = 32'hF84003E9;
#10;
begin
passTest(out, 63'b0, "Stuff", passed);
#10;
in = 32'hf84093ea;
#10;
passTest(out, 63'b0, "Stuff", passed);
end
end
endmodule
在您的比较中,您似乎将 x
视为“无关”值,但事实并非如此。 x
是表示“未知”的特定值。由于您将输入信号驱动为所有已知值(0 或 1),因此所有 ==
比较都解析为 x
,并且您的输出中包含 x
。您应该只比较您感兴趣的位。例如,更改:
(ImmIns[31:21] == 11'bxxxx1000xx0) ? {{55{extBit}}, ImmIns[20:12]}:
至:
( (ImmIns[27:24] == 4'b1000) && (ImmIns[21] == 1'b0) ) ? {{55{extBit}}, ImmIns[20:12]}:
您需要对所有比较进行类似的更改。
此外,您 BusImm
连续分配了 2 个任务。去掉这一行:
assign BusImm = 64'b0;
这些更改会从您的输出中得到 x
。
也可以考虑使用 casez
。请参阅 IEEE Std 1800-2017,第 12.5.1 节 带有 do-not-cares 的 Case 语句。