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 语句