#verilog #fpga #quartus #intel-fpga
#verilog #fpga #quartus #intel-fpga
Вопрос:
Я пытаюсь реализовать тестовый стенд так, чтобы после 3 тиков каждый ввод получал новое указанное значение. Например, первые 3 секунды (или тики) A = 10, B = 0, а затем следующие 3 секунды (от 3 секунд до 6 секунд) A = 10, B = 16 и т.д. Однако на моем реальном тестовом стенде значения обновляются не так, как я хочу. Я неправильно понимаю синтаксис?
Вот скриншот текущих значений, которые я получаю. Я нарисовал красные линии вверху, чтобы представить каждые 3 тика.
https://gyazo.com/f2c0cddc192d0d6734c98334cd377f12
module ALU_tb();
reg [63:0] A, B;
reg [4:0] FS;
reg cin;
wire cout;
wire [63:0] resu<
wire [3:0] status;
Final_ALU dut (
.A(A),
.B(B),
.FS(FS),
.cin(cin),
.cout(cout),
.result(result),
.status(status)
);
initial begin //A 1 //A=10 B=0
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01000;
cin <= 1'b1;
end
always begin //A B //A=10 B=16
#3
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01000;
cin <= 1'd0;
#3;
end
always begin //A-B //A=10 B=16
#6
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01001;
cin <= 1'd1;
#6;
end
always begin //A-1 //A=10 , B=1
#9
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000001;
FS <= 5'b01001;
cin <= 1'd1;
#9;
end
always begin //-A //A=10 , B=0 (just twos complement of A)
#12
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01010;
cin <= 1'd1;
#12;
end
initial begin
#30 $finish;
end
endmodule
Ответ №1:
Вы не должны назначать один и тот же сигнал из нескольких always
блоков.
Один из способов решить проблему — использовать a fork/join
внутри initial
блока an и избавиться от always
ключевых слов. Это вносит минимальные изменения в ваш код:
initial begin
fork
begin //A 1 //A=10 B=0
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01000;
cin <= 1'b1;
end
begin //A B //A=10 B=16
#3
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01000;
cin <= 1'd0;
#3;
end
begin //A-B //A=10 B=16
#6
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01001;
cin <= 1'd1;
#6;
end
begin //A-1 //A=10 , B=1
#9
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000001;
FS <= 5'b01001;
cin <= 1'd1;
#9;
end
begin //-A //A=10 , B=0 (just twos complement of A)
#12
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01010;
cin <= 1'd1;
#12;
end
join
end
Более традиционным подходом было бы избавиться от fork
, и просто последовательно управлять всеми группами сигналов внутри initial
блока. Тогда вам придется соответствующим образом скорректировать все свои #
задержки.