Der hier enthaltene Code nimmt einen Bitstrom aus Binärziffern, das niederwertigste Bit (LSB) zuerst, und gibt das Zweierkomplement des vollständigen Stroms aus, ebenfalls zuerst das LSB. Ein Moore-Zustandsdiagramm ist beigefügt.
Wenn ich jetzt versuche, den Code in einer Testbench zu testen, werden die Zustände nicht wie beabsichtigt aktualisiert.
Das FSM:
Das Design:
module seqDetector( input in,
input clk,
input rst,
output reg out);
//Moore Machine
parameter SX = 3'd4,
S0 = 3'd0,
S1 = 3'd1,
S2 = 3'd2,
S3 = 3'd3;
reg [2:0] cur_state,next_state;
//next state assignment
always @(posedge clk,negedge rst) begin
if( rst == 1'b0)
cur_state <= SX;
else
cur_state <= next_state;
end
//next state calculation
always @(cur_state,in) begin
case(cur_state)
SX: if(in == 1'b0) next_state = S0; else next_state = S1;
S0: if(in == 1'b0) next_state = S0; else next_state = S1;
S1: if(in == 1'b0) next_state = S3; else next_state = S2;
S2: if(in == 1'b0) next_state = S3; else next_state = S2;
S3: if(in == 1'b0) next_state = S3; else next_state = S2;
endcase
end
//output calculation
always @(cur_state) begin
case(cur_state)
SX: out = 1'bx;
S0: out = 1'b0;
S1: out = 1'b1;
S2: out = 1'b0;
S3: out = 1'b1;
endcase
end
endmodule
Die Prüfbank:
`timescale 1ns/1ns
module tb();
initial begin
$dumpfile("2's.vcd");
$dumpvars(0,tb);
end
reg clk;
reg in;
reg rst;
wire out;
initial begin
clk = 1'b1;
forever #5 clk = ~clk;
end
seqDetector s0(in,clk,rst,out);
initial begin
fork
#0 rst = 1'b1;
#10 rst = 1'b0;
#20 rst = 1'b1;
#10 in = 1'b0;
#20 in = 1'b1;
#30 in = 1'b0;
#40 in = 1'b1;
#50 in = 1'b1;
#60 in = 1'b0;
#70 in = 1'b0;
#80 in = 1'b1;
#90 in = 1'b1;
#100 in = 1'b1;
#110 in = 1'bx;
#120 $finish;
join
end
endmodule
Das Problem wird in der folgenden Grafik dargestellt:
Aber wenn wir die Testbench so ändern, dass die Eingänge um 1 ns nach der Taktflanke verzögert werden, wird das bestehende Problem gelöst und die Funktionalität erreicht. Aber es gibt ein paar Störungen, deren Ursprung ich nicht herausfinden kann, wie hier gezeigt:
seqDetector s0(in,clk,rst,out);
initial begin
fork
#0 rst = 1'b1;
#10 rst = 1'b0;
#20 rst = 1'b1;
#11 in = 1'b0;
#21 in = 1'b1;
#31 in = 1'b0;
#41 in = 1'b1;
#51 in = 1'b1;
#61 in = 1'b0;
#71 in = 1'b0;
#81 in = 1'b1;
#91 in = 1'b1;
#101 in = 1'b1;
#111 in = 1'bx;
#120 $finish;
join
end
Die erste Frage lautet also: Warum gibt es aus der Perspektive des Schreibens eines Verilog-Codes ein Problem, wenn ich die Eingabe am Rand der Uhr ändere?
Und die zweite Frage lautet: Was ist die Ursache für die Störungen in der next_state-Variablen?
Mit Mentor Questa 2020.1
und Cadence Xcelium 20.09
wir bekommen keine Störungen.
Mit Synopsys VCS 2020.03
und Icarus Verilog 14
wir bekommen Störungen.
Ich habe EDA Playground zum Simulieren verwendet, bei Interesse besuchen Sie bitte diesen Link.
Der Grund , warum Sie Störungen erhalten, sind Rennbedingungen / Renngefahren aufgrund der nicht deterministischen Reihenfolge gleichzeitiger Verilog- Blockierungsanweisungen in der Simulation.
Hier sind 2 Techniken, um Störungen in der sequentiellen Logiksimulation zu vermeiden:
Wenden Sie den Stimulus etwas nach der aktiven Flanke der Uhr an, indem Sie eine Verzögerung verwenden, wie Sie es in Ihrer Frage getan haben.
Mit nicht blockierenden Zuweisungen können Sie die Eingänge an der aktiven Flanke des Takts ansteuern, ohne dass es zu Störungen kommt.
Diese Testbench verwendet nicht blockierende Zuweisungen und simuliert ohne Störungen auf diesen Simulatoren: Mentor Questa 2020.1, Cadence Xcelium 20.09, Icarus Verilog 14 und Synopsys VCS 2020.03.
module tb();
initial begin
$dumpfile("dump.vcd");
$dumpvars(0,tb);
end
reg clk;
reg in;
reg rst;
wire out;
initial begin
clk = 1'b1;
forever #5 clk = ~clk;
end
seqDetector s0(in,clk,rst,out);
initial begin
fork
#0 rst <= 1'b1;
#10 rst <= 1'b0;
#20 rst <= 1'b1;
#10 in <= 1'b0;
#20 in <= 1'b1;
#30 in <= 1'b0;
#40 in <= 1'b1;
#50 in <= 1'b1;
#60 in <= 1'b0;
#70 in <= 1'b0;
#80 in <= 1'b1;
#90 in <= 1'b1;
#100 in <= 1'b1;
#110 in <= 1'bx;
#120 $finish;
join
end
endmodule
Registrieren Sie die Ausgänge . Um mehr zu erfahren, können Sie diese Antwort lesen.
Benutzer253751
hallowelt1e.
Benutzer253751