2020年4月5日日曜日

Vivadoでシミュレーション時のクロック同期タイミング仕様について


VIVADOでシミュレーション時のクロック同期タイミングについて


以下のようなテストベンチでシミュレーションした(簡略化のためシミュレーション対象はクロックに同期してabを代入する回路)
b#を使って無理やり?任意のタイミングでクロックに合わせて変化させている。



`timescale 1ns / 1ps
module sim_test;
localparam PERIOD = 8;
localparam END = 1000;
reg CLK_in;
reg NRESET_in;
reg [31:0] a;
reg [31:0] b;
always @( posedge CLK_in, negedge NRESET_in )
begin
if( ~NRESET_in )
begin
a <= 32'h0000_0000;
end
else
begin
a <= b;
end
end

always
begin
CLK_in = 1; #(PERIOD/2);
CLK_in = 0; #(PERIOD/2);
end
initial
begin
b = 0;
NRESET_in = 1;
#(PERIOD*3) NRESET_in = 0;
#(PERIOD*3) NRESET_in = 1;
#(PERIOD*3) b = 23215;
#(PERIOD * END);
$stop;
end

endmodule


シミュレーション波形は以下のようになった

bの値が変わって1クロック後にaの値が書き換わると思っていたら、bの値が変わったと同時にaも書き換わってしまった。

次にbをクロック同期のalways文で変更するようにしてシミュレーションした。





`timescale 1ns / 1ps

module sim_test;
localparam PERIOD = 8;
localparam END = 1000;
reg CLK_in;
reg NRESET_in;
reg [31:0] a;
reg [31:0] b;
always @( posedge CLK_in, negedge NRESET_in )
begin
if( ~NRESET_in )
begin
a <= 32'h0000_0000;
end
else
begin
a <= b;
end
end

always @( posedge CLK_in, negedge NRESET_in )
begin
if( ~NRESET_in )
begin
b <= 32'h0000_0000;
end
else
begin
b <= b + 32'h0000_0001;
end
end

always
begin
CLK_in = 1; #(PERIOD/2);
CLK_in = 0; #(PERIOD/2);
end
initial
begin
NRESET_in = 1;
#(PERIOD*3) NRESET_in = 0;
#(PERIOD*3) NRESET_in = 1;
#(PERIOD * END);
$stop;
end

endmodule




シミュレーション波形は以下のようになった。


想定通りbが変わって1クロック後にaも書き換わっている。

よく考えればそうなりそうではあるが、、、

今まであまり気にしていなかったが、回路によってはこの仕様を理解してテストベンチを作成しないと思った通りのシミュレーションができないので備忘録として残しておく。


0 件のコメント:

コメントを投稿