Испытательный стенд ALU с использованием тестового векторного файла не работает

Я новичок в этом, и вопрос может показаться глупым, но я потратил на это часы, и тестовый стенд просто не хочет загружать правильные значения в регистр перед выполнением арифметики.

Вот что происходит, когда я запускаю симуляцию

# [         0]Success: inputs: a=00000000 | b=00000000 | f=0
#       outputs: y=00000000 | y_ex=00000000 | zero=1
# [         1]Error: inputs: a=00000007 | b=ffffffff | f=0
#       outputs: y=00000007 | y_ex=fffffff8 | zero=0
# [         2]Error: inputs: a=0000000f | b=fffffff8 | f=0
#       outputs: y=00000008 | y_ex=00000000 | zero=1
# [         3]Error: inputs: a=000007f8 | b=00000008 | f=0
#       outputs: y=00000008 | y_ex=00000800 | zero=0
# [         4]Success: inputs: a=00000000 | b=00000000 | f=0
#       outputs: y=00000000 | y_ex=00000000 | zero=1
# [         5]Error: inputs: a=00000007 | b=fffffff8 | f=0
#       outputs: y=00000000 | y_ex=00000008 | zero=0
# [         6]Error: inputs: a=00000008 | b=00000008 | f=0
#       outputs: y=00000008 | y_ex=00000000 | zero=0
# [         7]Error: inputs: a=00000800 | b=00000008 | f=0
#       outputs: y=00000000 | y_ex=000007f8 | zero=1
#          8 tests completed with          6 errors

Как видите, значения f, которые используются для указания операции, которую будет выполнять АЛУ, всегда неверны. Значения a и b также читаются неправильно. Хотя чтение, кажется, происходит нормально. Я это уже тестировал.

Вот мой код ALU

module alu(input logic [31:0] a, b,
            input logic [2:0] f,
            output logic [31:0] y,
            output logic zero
    );
    
    always @*
    begin
        if (f == 3'h0) //AND
            y = a & b;
        else if (f == 3'h1) //OR
            y = a | b;
        else if (f == 3'h2) //ADD
            y = a + b;      
        else if (f == 3'h4) //AND NOT
            y = a & ~b;
        else if (f == 3'h5) //OR NOT
            y = a | ~b;
        else if (f == 3'h6) //SUBTRACT
            y = a - b;
        else if (f == 3'h7) //SET LESS THEN
            y =(a<b)?32'h00000001:32'h00000000;
        begin   
            if (y == 32'h00000000)
                zero = 1;
            else 
                zero = 0;
        end
    end 
endmodule

Код испытательного стенда

module testbench();
    logic clk;
    logic [31:0] a, b;
    logic [2:0] f;
    logic [31:0] y;
    logic zero;
    logic [31:0] y_ex;
    logic [31:0] vectornum, errors;
    logic [103:0] testvectors[10000:0];
    
    alu dut(a, b, f, y, zero);
    
    always 
        begin
            clk = 1; #5; clk = 0; #5;
        end
        
    initial 
        begin 
            $readmemh("alu.tv", testvectors); //f,a,b, y_ex, zero
            vectornum = 0; errors = 0;
        end
        
    always @(posedge clk)
        begin
            #1; {f, a, b, y_ex, zero} = testvectors[vectornum];
        end
        
    always @(negedge clk) begin
            if (y == y_ex) begin 
                $display("[%d]Success: inputs: a=%h | b=%h | f=%h",vectornum, a, b, f);
                $display("      outputs: y=%h | y_ex=%h | zero=%b", y, y_ex, zero);
            end
            else if (y !== y_ex) begin
                $display("[%d]Error: inputs: a=%h | b=%h | f=%h", vectornum, a, b, f);
                $display("      outputs: y=%h | y_ex=%h | zero=%b", y, y_ex, zero);
                errors = errors + 1;
            end
            vectornum = vectornum + 1;
            if (testvectors[vectornum] === 104'bx) begin
                $display("%d tests completed with %d errors", vectornum, errors);
        $stop;
            end
end
    endmodule

Векторный файл

2_00000000_00000000_00000000_1
2_00000000_FFFFFFFF_FFFFFFFF_0
2_00000001_FFFFFFFF_00000000_1
2_000000FF_00000001_00000100_0
6_00000000_00000000_00000000_1
6_00000000_FFFFFFFF_00000001_0
6_00000001_00000001_00000000_1
6_00000100_00000001_000000FF_0

Что я делаю не так? Был бы очень признателен за помощь.


person Pete    schedule 23.10.2020    source источник
comment
вам нужно изменить объявления f[2:0] на f[3:0], то же самое для zero[3:0]. Кроме того, начните использовать правильные неблокирующие присваивания в своем коде, иначе вы рискуете потерять один такт.   -  person Serge    schedule 23.10.2020


Ответы (1)


Вы не можете полагаться на _, чтобы разделить каждую строку на 5 чисел. Это 2_00000000_FFFFFFFF_FFFFFFFF_0 представляет собой одно 104-битное шестнадцатеричное число.

При выполнении {f, a, b, y_ex, zero} = testvectors[1]; он фактически делает:

hex |  bin  |   hex   |  bin  |   hex   |  bin  |   hex   |  bin
 2  | 000 0 | 0000000 | 111 1 | FFFFFFF | 111 1 | FFFFFFF | 000 0
 |    --- ----------------- ----------------- ----------------- -
 |     f          a                  b               y_ex       zero
 |    3'h0      32'h7          32'hffff_ffff    32'hffff_fff8   0
 V
 not used

При назначении необходимо указать диапазон:

assign tmp = testvectors[vectornum];
assign zero = tmp[...];
assign y_ex = tmp[...];

Или измените объявление битовой ширины zero/y_ex/..., как то, что @Serge упомянул в комментарии.

Есть еще одна проблема. Сеть zero в testbench управляется как выходом zero alu, так и блоком always в testbench.

person Light    schedule 23.10.2020