Lattice Diamond - Fehlermeldung - State machine - Verilog - Brauche Hilfe

OP #6789290
Lesenswert?

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.
Angehängte Dateien:
OP #6789683
Lesenswert?

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!?
OP #6789924
Lesenswert?

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.
Gast #6790035
Lesenswert?

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)
Gast #6792927
Lesenswert?

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.
Moderator (Firma: Titel) Persönliche Seite #6793765
Lesenswert?

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.
Gast #6793777
Lesenswert?

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).
Gast #6794174
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren