Hallo liebe Gemeinde Ich bin mit meinem Latein erstmal am Ende. Folgendes: Arbeitsumgebung - Windows10 Tool - Lattice Diamond V3.12 FPGA - XP-Serie LFXP3C-3T144C Problem - Ich arbeite gerade an einer State-machine für ein 6800er Interface zum FPGA. Darin enthalten eine State machine um Kommandos auf einem 8bit Interface (6800er) mit /RW, /CD, /E, /CS entgegen zu nehmen, auszuwerten und entsprechende Aktionen durchzuführen. Ich habe mal die betreffende Source beigegeben. Auf einem anderen FPGA läuft das ganze schon. Leider meckert Diamond mir folgendes an. ERROR - CL172 :"M6800_interface.v":64:10:64:18|Only one always block can assign a given variable cmd_stage[2:0] Ich habe doch aber nur einen Prozess wo cmd_stage etwas zugewiesen wird. Ich sehe leider den Wald vor Bäumen nicht mehr. Wer kann mir da helfen und sagen woran es etwa liegen könnte? Ob Lattice Diamond mit task nicht klar kommt oder bin ich es - ooh. Wäre echt toll diesen Fehler gelöst zu bekommen.
Jetzt hat der mal wieder das Projekt als .zip nicht genommen..
Schau mal, du schreibst auf cmd_stage von verschiedenen tasks, das lässt sich leider nicht synthetisieren.
Danke für deine Antwort User. Ja das stimmt. Ich schreibe von vielen Task's auf cmd_stage. Allerdings werden diese task's doch nur aus einem always Block aufgerufen. Das dürfte doch für die Synthese nicht verboten sein. Synopsis bemängelt ja genau dies - das es von mehr als einem always Bloch auf cmd_stage zugegriffen wird. Aber ich sehe nicht wo!?
Konstanten identisch zu Tasks nennen, ist auch nicht empfehlenswert.
Tim schrieb: > Konstanten identisch zu Tasks nennen, ist auch nicht empfehlenswert. Wo denn? -> Ah, okay - ich hab es gesehen. Ich werde dies umbenennen. Task -> mit task_ davor. Aber dies ist trotzdem nicht der Grund. Nur etwas unschön vielleicht. Trotzdem Danke Tim
:
Bearbeitet durch User
So, ich glaub ich habe den Fehler gefunden!
1 | // ============================================================================= |
2 | // command stages one-clocked always block |
3 | // ============================================================================= |
4 | always @(posedge i_clk) |
5 | if (i_reset) |
6 | begin
|
7 | cmd_stage <= (STAGE_CMD_IDLE); |
8 | sig_wr_en <= FALSE; |
9 | col_start_addr <= 'd0; |
10 | col_end_addr <= HORZ_VISIBLE; |
11 | row_start_addr <= 'd0; |
12 | row_end_addr <= VERT_VISIBLE; |
13 | col_addr <= 'd0; |
14 | row_addr <= 'd0; |
15 | r_control <= 8'b0000_0000; |
16 | end
|
17 | else
|
18 | begin
|
19 | |
20 | case (cmd_stage) |
21 | STAGE_CMD_IDLE: begin task_stage_cmd_idle(); r_led <= LOW; end |
22 | STAGE_SET_COL_ADDR: begin task_stage_set_col_addr(); r_led <= HIGH; end |
23 | STAGE_SET_ROW_ADDR: begin task_stage_set_row_addr(); r_led <= HIGH; end |
24 | STAGE_READ_RAM: begin task_stage_read_ram(); r_led <= HIGH; end |
25 | STAGE_WRITE_RAM: begin task_stage_write_ram(); r_led <= HIGH; end |
26 | STAGE_SET_PAGE: begin task_stage_set_page(); r_led <= HIGH; end |
27 | STAGE_DISP_CONTROL: begin task_stage_disp_control(); r_led <= HIGH; end |
28 | STAGE_SET_FUNCTION: begin task_stage_set_function(); r_led <= HIGH; end |
29 | default: task_stage_cmd_idle(); |
30 | endcase
|
31 | end
|
Ich habe hier eine State Machine um über das Command Register die entsprechende Aktion auszuführen. Genau da war alles okay! Obwohl gerade dies ( cmd_stage ) Synplify angemeckert und mit einer ERROR Meldung abgebrochen hat. Tatsächlich scheint es aber an der Zweiten State Machine (für den Interface FiFo) zu liegen! Denn da ist mir tatsächlich ein Fehler unterlaufen als ich die default Klausel in der FULL-CASE Anweisung noch nachgetragen habe, da Synplify auch dies angemeckert hat. Dabei habe ich den IDLE-STATE von der 1. State Machine verwendet. FALSCH:
1 | // ============================================================================= |
2 | // FiFo stages one-clocked always block |
3 | // ============================================================================= |
4 | always @(posedge i_clk) |
5 | if (i_reset) begin |
6 | fifo_stage <= STAGE_FIFO_IDLE; |
7 | fifo_rd_en <= FALSE; |
8 | sdr_wr_request <= FALSE; |
9 | sdr_wr_mask <= 2'b11; |
10 | end else |
11 | |
12 | case (fifo_stage) |
13 | STAGE_FIFO_IDLE: stage_fifo_idle(); |
14 | STAGE_FIFO_RD_PIPE: stage_fifo_rd_pipe(); |
15 | STAGE_FIFO_RD_DATA: stage_fifo_rd_data(); |
16 | STAGE_FIFO_WR_SDRAM: stage_fifo_wr_sdram(); |
17 | default: stage_cmd_idle(); // <---------- FALSCHER Task Aufruf 2.Always Block wo cmd_stage zugewiesen wird |
18 | endcase
|
RICHTIG:
1 | // ============================================================================= |
2 | // FiFo stages one-clocked always block |
3 | // ============================================================================= |
4 | always @(posedge i_clk) |
5 | if (i_reset) begin |
6 | fifo_stage <= STAGE_FIFO_IDLE; |
7 | fifo_rd_en <= FALSE; |
8 | sdr_wr_request <= FALSE; |
9 | sdr_wr_mask <= 2'b11; |
10 | end else |
11 | |
12 | case (fifo_stage) |
13 | STAGE_FIFO_IDLE: stage_fifo_idle(); |
14 | STAGE_FIFO_RD_PIPE: stage_fifo_rd_pipe(); |
15 | STAGE_FIFO_RD_DATA: stage_fifo_rd_data(); |
16 | STAGE_FIFO_WR_SDRAM: stage_fifo_wr_sdram(); |
17 | default: stage_fifo_idle(); // <---------- RICHTIGER Task Aufruf |
18 | endcase
|
Danke nochmal an Tim, denn erst durch die Änderung der Tasknamen gab eine Fehlermeldung in der 2. State Machine mit hinweis auf einem nicht definierten Task (stage_cmd_idle) da ich den ja umbenannt hatte.
:
Bearbeitet durch User
Also jetzt sollte ja wohl klar sein, dass ein Fehler ausgegeben werden muss. MMn ist aber die Fehlermeldung falsch/total irreführend, ich hatte als Tools auf die Mehrfachverwendung des Namens und nicht auf die des Signals aufmerksam gemacht. (rein aus Interesse teste ich Morgen mal das Beispiel von Oben aus, mal sehen was ISE/Vivado und Quartus ausspucken)
Sigi schrieb: > (rein aus Interesse teste ich Morgen mal das Beispiel > von Oben aus, mal sehen was ISE/Vivado und Quartus > ausspucken) Das wäre toll. Das interessiert mich auch mal.
Ich habe gerade mal dein Modul in eine TB eingebunden, die fehlenden Module MULTI, DATA_FIFO und ADDRESS_FIFO habe ich durch Dummy-Varianten ersetzt. Läuft ohne Syntax/etc.-Fehler unter ISE14.5 durch.
Da hätte die ISE doch eigentlich einen Fehler melden müssen. Denn der Zugriff auf "cmd_stage" in einem zweiten Always Block findet ja in der fehlerhaften Version definitiv statt. Das ist aber auch Komisch.
Steffen H. schrieb: > Das ist aber auch Komisch. Wenn ich da TB lese: in der Simulation juckt das erst mal nicht. Denn bei einer Kollision kommt beim std_logic dann einfach die Auflösungstabelle zum Einsatz. Und schlimmstenfalls kommt dann ein X dabei raus. Nur die Implementierung wird schiefgehen, weil der Synthesizer die "Multiple Drivers" eben nicht zum X auflösen kann.
Stimmt, hast recht: ich hatte Gestern ja nur ein TB drumrum gebaut, Mehrfachzugriffe werden dort ja ignoriert. Für ein synthesefähiges Beispiel war ich zu faul, ausserdem fehlen ja noch drei Untermodule (MULTI, **_FIFO).
Lothar M. schrieb: > Denn > bei einer Kollision kommt beim std_logic dann einfach die > Auflösungstabelle zum Einsatz. Und schlimmstenfalls kommt dann ein X > dabei raus. Deswegen nutze ich für interne Signale sehr gerne std_ulogic. Da wird schon vorher gemeckert. Auch in der Simulation... Duke
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.