-1

我正在尝试在 Verilog 中编写加法和减法程序。问题是在 Verilog 中执行和测试执行加法或减法的模块,然后多路复用器在让一个或另一个结果之间进行选择,然后将所选结果从二进制解码为 7 段显示格式。Verilog 模块将有 3 个输入:两个名为 A 和 B 的 4 位输入,以及一个选择输入 S。您的电路应将这两个数字相加,还应从 A 中减去 B(就像在代码中包含 AB 一样简单)。根据 S 的值(即它是 1 还是 0),您应该让加法的结果或减法的结果通过。

这是我拥有的代码: module AddOrSubtractThenSelectAndDecodeInto7SegmentsDisplay(A,B,S,Result,Overflow,Display);

input [3:0] A;
input [3:0] B;
input [1:0] S;

output reg [3:0] Result;
output reg Overflow;
output reg [6:0] Display;

wire [3:0] A;
wire [3:0] B;
wire [1:0] S;



always @(A,B) begin
    if (S == 0'b0)
        {Overflow, Result} = A - B;
    else if (S == 1'b1)
        {Overflow, Result} = A + B;
    end

always @(Overflow,Result) begin
    case (Result)
        4'b0000: Display = 7'b1111110;//0
        4'b0001: Display = 7'b0110000;//1
        4'b0010: Display = 7'b1101101;//2
        4'b0011: Display = 7'b1111001;//3
        4'b0100: Display = 7'b0110011;//4
        4'b0101: Display = 7'b1011011;//5
        4'b0110: Display = 7'b1011111;//6
        4'b0111: Display = 7'b1110000;//7
        4'b1000: Display = 7'b1111111;//8
        4'b1001: Display = 7'b1111011;//9
        4'b1010: Display = 7'b1110111;//A
        4'b1011: Display = 7'b0011111;//B
        4'b1100: Display = 7'b1001110;//C
        4'b1101: Display = 7'b0111101;//D
        4'b1110: Display = 7'b1001111;//E
        4'b1111: Display = 7'b1000111;//F
        default: Display = 7'bx;
    endcase

    if (Overflow == 1)begin
        Result = 4'bx;
        Display = 7'b0011101;
    end
end


endmodule

当我运行教练测试台时,除了显示之外,所有的线都是绿色的。它显示 Display[6:0] xxxxxxx,后面是红线。我花了 2 天的时间研究这个问题,试图修复它。请问有什么帮助吗?

4

2 回答 2

0

您的代码的问题是,您已经在同一个网络上完成了分配,通过超过 1 个总是阻塞。

不要从多个总是阻塞的情况下对同一个变量进行赋值。

所以你的代码应该是这样的:

input [3:0] A;
input [3:0] B;
input [1:0] S;

output [3:0] Result;
output reg Overflow;
output reg [6:0] Display;

reg [3:0] Result_reg;

wire [3:0] A;
wire [3:0] B;
wire [1:0] S;

assign Result = (Overflow) ? 4'bx : Result_reg;

always @(A,B) begin
    if (S == 0'b0)
        {Overflow, Result_reg} = A - B;
    else if (S == 1'b1)
        {Overflow, Result_reg} = A + B;
    end

always @(Overflow,Result_reg) begin
    case ({Overflow, Result_reg}) inside
        [5'b1000:5'b11111] : Display = 7'b0011101; 
        5'b00000: Display = 7'b1111110;//0
        5'b00001: Display = 7'b0110000;//1
        5'b00010: Display = 7'b1101101;//2
        5'b00011: Display = 7'b1111001;//3
        5'b00100: Display = 7'b0110011;//4
        5'b00101: Display = 7'b1011011;//5
        5'b00110: Display = 7'b1011111;//6
        5'b00111: Display = 7'b1110000;//7
        5'b01000: Display = 7'b1111111;//8
        5'b01001: Display = 7'b1111011;//9
        5'b01010: Display = 7'b1110111;//A
        5'b01011: Display = 7'b0011111;//B
        5'b01100: Display = 7'b1001110;//C
        5'b01101: Display = 7'b0111101;//D
        5'b01110: Display = 7'b1001111;//E
        5'b01111: Display = 7'b1000111;//F
        default: Display = 7'bx;
    endcase
end

对于 Verilog 编码指南,您可以查看Verilog 编码指南

此外,根据您的原始代码,我在代码中分配了“x”。但我强烈不建议对 RTL 代码使用“x”赋值。

于 2016-02-07T09:06:40.793 回答
0

一行看起来很奇怪:

if (S == 0'b0)

基本上这意味着“零位为零”。在verilog中,我认为格式是bits ´b value。将b替换为h以获取十六进制格式(并使用 google 获取其余选项;))

就像其他海报所说的那样,S似乎是 2 位向量,尽管只使用了 MSB。

而且x值在现实世界中也不存在 - 这只是模拟器说“我不知道”的一种方式。所以不会合成。

否则我看不到同一信号在不同的总是块中分配了两次以上?在同一块中完成时应该没问题。后一个值只是覆盖前一个值。谷歌阻止非阻止以获取更多信息。

编辑:你还用什么作为刺激?如果 A 和 B 是静态的,则它们不会引发事件,而这反过来又不会导致任何always块触发。因此输出保持在 7'bx。不太确定这一点,但值得检查。

于 2016-02-07T16:24:08.200 回答