Ich versuche, einen einfachen Multicycle-Prozessor zu implementieren, und ich stieß auf einige Probleme, die ich nicht durchkommen werde. Der Code ist unten. Ich experimentiere gerade jetzt, um das fließen zu lassen. Wenn ich fertig bin, beginne ich mit der Implementierung von Anweisungen und ALU. Allerdings stecke ich an diesem Punkt fest. In dem Code unten ist mir bewusst, dass data_memory
nie verwendet wird (Ich werde zu da, wenn ich das lösen kann), einige Eingänge und Ausgänge werden auch nicht verwendet, x1
und x2
sind nur Variablen, die ich erstellt habe, um zu sehen, was ist wirklich los. Was ist in Datei ist selbstverständlich.Iterationsgrenze bei der Implementierung eines Multicycled-Prozessors
Ich verwende Altera Quartus 15.1 mit Verilog2001. Dieser Code kompiliert genau einige Warnungen wegen unbenutztem Zeug aus, aber wenn ich versuche, es mit einer Taktperiode von 20ns zu simulieren, gibt es einen Fehler, der sagt "Error (suppressible): (vsim-3601) Iterationslimit 5000 erreicht zum Zeitpunkt 100 ns" . Es sagt auch, dass dies unterdrückbar ist, aber ich weiß auch nicht, wie ich es unterdrücken soll.
Ich habe nach diesem Fehler gesucht und ich habe gelernt, dass dies passiert, weil der Code irgendwann in eine Endlosschleife geht. Ich habe versucht, dies zu lösen, indem ich eine andere Variable ok
erstelle. Ein Zyklus beginnt mit dem Setzen von ok
auf 0
und nachdem die Mikrooperationen für diesen Zyklus abgeschlossen sind, setze ich ok
auf 1
. Der Zyklus wird sich also nicht zu einer unpassenden Zeit ändern (es ist wie das Sperren des Zyklus). Dies führte leider zu demselben Fehler.
Ich versuchte auch einen anderen Fluss. Anstelle von cycle
und next_cycle
habe ich eine Variable für den Zyklus erstellt. Bei jeder steigenden Flanke der Uhr überprüfte ich den aktuellen Zustand und tat die Dinge entsprechend, dann stellte ich den Zyklus für den nächsten Schritt ein. Beispiel:
Dies kompiliert auch gut, und kann ohne Fehler simuliert werden! Funktioniert jedoch nicht korrekt und gibt seltsame (oder unerwartete) Ergebnisse. Ich finde einen anderen Ansatz intuitiver. Also werde ich versuchen, es zum Laufen zu bringen.
Wie kann ich dies beheben/implementieren?
`include "definitions.v"
module controller(
input clk,
input nres,
output reg ire,
output reg dwe,
output reg dre,
output reg [1:0] x2,
output reg [`IADR_WIDTH-1:0] i_address,
output reg [`DADR_WIDTH-1:0] d_address,
output reg [`DATA_WIDTH-1:0] data_out);
reg [2:0] cycle = 3'b000;
reg [2:0] next_cycle;
reg [`IADR_WIDTH-1:0] PC = 6'b000000;
reg [`INST_WIDTH-1:0] IR = 12'b00000_0000000;
reg [`DADR_WIDTH-1:0] MAR = 6'b000000;
reg [4:0] OPC = 5'b00000;
wire [`DATA_WIDTH-1:0] data_in;
wire [`INST_WIDTH-1:0] instruction;
reg [1:0] x1;
data_memory dmem ( .clk (clk),
.dwe (dwe),
.dre (dre),
.nres (nres),
.d_address (d_address),
.d_data (data_out),
.d_q (data_in));
instruction_memory imem ( .clk (clk),
.ire (ire),
.i_address (i_address),
.i_q (instruction));
reg ok = 1;
always @ (posedge clk) begin
cycle = (ok) ? next_cycle : cycle;
end
always @ (cycle) begin
case (cycle)
3'b000: begin
ok = 0;
MAR = PC;
next_cycle = 3'b001;
ire = 1'b1;
x2 = 2'b00;
ok = 1;
end
3'b001: begin
ok = 0;
i_address = MAR;
IR = instruction;
ire = 1'b0;
next_cycle = 3'b010;
x2 = 2'b01;
ok = 1;
end
3'b010: begin
ok = 0;
OPC = IR;
next_cycle = 3'b011;
x2 = 2'b10;
ok = 1;
end
3'b011: begin
ok = 0;
if (OPC==5'b01011) x1 = 2'b11;
PC = PC + 1;
next_cycle = 3'b000;
x2 = 2'b11;
ok = 1;
end
endcase
end
endmodule
Einige Vorschläge: 1) Verwenden Sie 'immer @ (*)' anstelle von 'immer @ (Zyklus)' - es wird nichts reparieren, aber es ist eine gute Angewohnheit; 2) Fügen Sie einen 'Default'-Fall hinzu, um das Sperrverhalten zu verhindern - andernfalls wird Quartus auf einen Latch (statt auf einen Draht) schließen; 3) Verwenden Sie nicht-blockierende Zuordnungen ('<=') innerhalb flankengetriggerter 'always' Blöcke; 4) Veröffentlichen Sie Ihren Testbench-Code, falls darin die Fehlerquelle enthalten ist. – wilcroft
Sie haben 'PC = PC + 1;' in einem kombinatorischen Block. Dies sollte wahrscheinlich auf einer Taktflanke vorgerückt werden. – Morgan
@Morgan Aber es wird von einem Zustand (Zyklus) gesteuert, und dieser Zustand wird durch positive Flanke der Uhr gesteuert. Glaubst du, dass das das Problem verursacht? – Motun