Verilog减法和加法

时间:2016-02-07 04:59:52

标签: verilog digital-logic digital-design

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

这是我的代码:     模块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

当我运行教练测试台时,所有线路都是绿色的,除了显示器。它显示显示[6:0] xxxxxxx,然后是红线。我花了两天时间看着这个试图解决它。有什么帮助吗?

2 个答案:

答案 0 :(得分: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 Coding Guidelines

此外,我已经分配了" x"在代码中,根据您的原始代码。但我强烈建议不要使用" x"分配RTL代码。

答案 1 :(得分:0)

一行看起来很奇怪:

if (S == 0'b0)

基本上这意味着“数字零,零位”。在verilog中,我认为格式是'b 。将十六进制格式的 b 替换为 h (并使用谷歌获取其余选项;)

与其他海报一样, S 似乎是2位向量,但只使用了MSB。

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

否则我无法看到在不同的始终块中相同信号的分配位置超过两次?当在同一块中完成时,应该没问题。后一个值只是覆盖了前一个值。 Google可以阻止非阻止获取更多信息。

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