Forum: FPGA, VHDL & Co. Lattice ECP3: IO Read Begrenzung


von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo leute,

Ich habe mein custom design(Lattice ECP3-LFE3-35EA-7FTN256I) aus ein vom 
Lattice
Reference Design(Versa ECP3-LFE3-35EA-8FN484C) abgeleitet.
Natürlich musste ich dann die Projekte-Eigenschafte anpassen:
Family
Device
Performance grade
Package type
Operation condition

Damit diese an mein neuen Baustein stimmen. Bisher war die Entwicklung 
und einfacher Test super gelaufen.
Die großte Änderung die ich implementiert habe betrifft nur das 
wb_tlc_dec.v
module in dem die IORequest übertragen werden im gegensatz zu Reference 
Design wo nur Memory Request behandelt werden.
4000-43ff: IO MAP (UART1,UART2)
5000-xxxx: MMAP (sonstige)

Dann habe ich seit letzter Montag das folgende Problem:

1)Lesen aus ein UART-Register durch loop bis 1000 klappt nicht
  Er liest problemlos bis 237 dann 5 Mal 0xFF danach bleibt das System 
hangen.


2)Wenn ich nun der Memory-Space 4000-43ff als MMAP definiere und der 
Test durclaufen lasse (20Uhr - 7 Uhr Morgen), wird die richtige Werte 
0xC1 gelesen bis 4000 000 loops dann meldest sich der Test Treiber ab. 
(Kling für mich as Timer Lattice IPCore bin ich nicht sicher)

Deswegen hätte ich gern ein Feedback von euch. Woran kann es liegen ?
beigefügt ist das einzige Module das ich geändert habe um die IO Request 
zu ermöglichen.

Ich bitte um Hinweise schon 4 Tagen ohne Lösung.....

 es gelingt mir bis(UART1,UART2)

von Duke Scarring (Gast)


Lesenswert?

Sind alle asynchronen Signale richtig einsynchronisiert?

Duke

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Mein Logik Analyser sieht gut aus. Da ich mit dem Counter bis 234 
getriggert habe.(Reveal_Inserter.PNG und LogikAnalyser_Output.png)
Und 0xC1 Data ist im TLP Packet.(Sieht Bilder)
Hinzu habe ich auch mein topdesign damit du siehst wie die Clock 
verteilt sind.

Die UARTs brauchen 25 MHz. Die habe ich über PLL erzeugt.

Ich möchte mal das Lattice Basic Reference Design machen und nur IO 
Request im Module wb_tlc_dec.v zulassen.
Und der selbe Test beim Lesen GPIO Adresse 0002 durführen.
Ob ich problemlos 04 bis 1000 gelesen wird?
Im gpio Module steht :
1
      9'h002: begin
2
         if (rd) wb_dat_local <= 16'h1204;
3
      end

Oder bin ich auf dem falschen Lösungsweg ? vielleicht Routing Problem ?

von Lattice User (Gast)


Lesenswert?

Das Verhalten deutet auf einen PCIe Protokollfehler.

Erstens,  das Naheliegende:

Was sagt die Timinganalyse.  sind die für PCIe nötigen 125 MHz noch 
erfüllt?

Zweitens:
Änderung Memory Access auf IO Access ist nicht trivial, IO Writes 
brauchen im Gegensatz zu Memory Writes eine Completion. Und 
Intelchipsätze reagieren allergisch auf fehlende Completions.
Die Erzeugung von Completions ist beim Lattice Core in der Verantwortung 
des Userscodes.
Ob der Latticewrapper dessen Source du hast, die Erzeugung von 
Completions für IO Writes enthält habe ich nicht nachgeprüft.

Davon abgesehen: IO Access ist angefaultes Legacy!

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

OK !

beigefügt ist meine Timing Analysis: sieht diese versprechend aus oder 
sieht man kritishe Punkte drin ?

Nach der Lattice Beschreibungen sind die Completions TLP in folgende 
Module behandelt: wb_tlc_cpld.v und wb_tlc_cpld_fifo.v

Und es scheint als Memory sowie IO TLP Completion generiert werden. Aber 
ich bin noch nicht ganz sicher, ich analysiere noch den Inhalt.

von Lattice User (Gast)


Lesenswert?

Es geht nicht um die IO Timing Analyse, die ist relativ unwichtig.

Place&Route Trace ist was du dir anschauen MUSST

von Lattice User (Gast)


Lesenswert?

>
> Und es scheint als Memory sowie IO TLP Completion generiert werden. Aber
> ich bin noch nicht ganz sicher, ich analysiere noch den Inhalt.

Bei Memoryaccess braucht nur Read eine Completion, die gelesenen Daten 
müssen ja zurück :-)

Memory Write ist postet und braucht keine.

Bei IO Access mus auch für Write eine Completion erzeugt werden, ohne 
Daten.
(siehe PCIe Spec 2.2.9)

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Danke für den Hinweis!

Hier meine Routing Report. Gibt es Problem damit ?
Wenn ja wie kann man es verbessern ?

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

OK ,

Wenn ich ein IORead mache, habe ich den richtige Daten. Das Problem 
tritt nur wenn nacheinander gelesen wird.
Also in meinem Verstandnis werden IO TLP vom cpld Module behandelt aber 
nicht vollstanding oder bist du andere Meinung ?

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Danke für den Hinweis!
>
> Hier meine Routing Report. Gibt es Problem damit ?
> Wenn ja wie kann man es verbessern ?
1
Timing summary (Setup and Hold):
2
---------------
3
Timing errors: 0 (setup), 0 (hold)
4
Score: 0 (setup), 0 (hold)
5
Cumulative negative slack: 0 (0+0)
6
--------------------------------------------------------------------------------
Das sieht ok, aus.

Aber die 125 MHz sind nur ganz knapp erfüllt, d.h. du musst bei jedem 
bauen
überprüfen ob nich alles in Ordnung ist.
1
FREQUENCY NET "clk_125_c" 125.000000 MHz (0 errors)
2
4096 items scored, 0 timing errors detected.
3
Report: 125.960MHz is the maximum frequency for this preference.

Ausserdem:
1
Constraints cover 184729 paths, 104 nets, and 62958 connections (96.1% coverage)

96% ist IMO zu wenig, da fehlen Constraints.

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> OK ,
>
> Wenn ich ein IORead mache, habe ich den richtige Daten. Das Problem
> tritt nur wenn nacheinander gelesen wird.
> Also in meinem Verstandnis werden IO TLP vom cpld Module behandelt aber
> nicht vollstanding oder bist du andere Meinung ?

Dein wb_tlc_cpld.v erzeugt nur die Completions für die WB Lesezugriffe.

Überprüfe mal ob für die IO Zugriffe eventuell auch UR Completions 
erzeugt werden (UR = Unsupported Request)

(Das ganze schreit nach einem PCIe Analyzer)

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Nach deiner Anmerkung habe ich nochmals das ganze angeschaut.
Die Äderung die ich im Module wb_tlc_dec.v gemacht habe allein reicht 
nicht
für eine effiziente Behandlung der IO TLP Transaction.
Sondern folgende Module sollen auch entprechend für eine effiziente IO 
Completion geändert werden:

UR.v
ip_rx_crpr.v

1 ) also insgesamt 3 Module meiner Meinung nach angepasst werden. Bisher 
habe ich nur wb_tlc_dec.v mit folgende hinzugefügt um IO Request zu 
laasen:
1
//////////////////////// IO Write Packets ////////////////////////////////////////
2
       8'b00x0_0010: // IO-Rd    
3
        begin
4
          fifo_wrn_p <= 1'b0;          
5
          drop <= 1'b0;
6
        end 
7
      8'b01x0_0010: // IO-Wr
8
        begin
9
          fifo_wrn_p <= 1'b1;          
10
          drop <= 1'b0;
11
        end  
12
///////////////////////////////////////////////////////////////////////////

2) Wie kann man die Contraints verbessern ?

von Keller T. (fabito)


Lesenswert?

Ich habe folgende Ändeung gemacht und hoffe das Problem gelöst zu haben.
Also ich bin gespannt auf das Ergebnis mit dem Test.

Im UR.v Module:
1
    ///////vorher///////
2
        /*8'b0000_0010: begin //IO Rd
3
           one_nph <= 1'b1;
4
        end
5
        8'b0100_0010: begin //IO Wr
6
           one_nph <= 1'b1;
7
           one_npd <= 1'b1;
8
        end*/
9
    ///////Nach Änderung ////////
10
        8'b0000_0010: begin //IO Rd
11
                if (~(rx_bar_hit[1] || rx_bar_hit[0])) //8'h40: // IOWr to BAR other than 0 or 1
12
            one_nph <= 1'b1;
13
        end
14
        8'b0100_0010: begin //IO Wr
15
          if (~(rx_bar_hit[1] || rx_bar_hit[0]))
16
          begin            
17
            one_ph <= 1'b1;
18
            one_pd <= 1'b1;
19
            sm <= e_DATA_LEN;
20
          end
21
        end

Und im iprxcrpr.v Module:
1
        //////vorher/////////
2
        /*8'b0000_0010: begin //IO Rd
3
           one_nph <= 1'b1;
4
        end
5
        8'b0100_0010: begin //IO Wr
6
           one_nph <= 1'b1;
7
           one_npd <= 1'b1;
8
        end*/
9
    ///////Nach Änderung ////////
10
        8'b0000_0010: begin //IO Rd
11
                if (~(rx_bar_hit[1] || rx_bar_hit[0])) //8'h40: // IOWr to BAR other than 0 or 1
12
            one_nph <= 1'b1;
13
        end
14
        8'b0100_0010: begin //IO Wr
15
          if (~(rx_bar_hit[1] || rx_bar_hit[0]))
16
          begin            
17
            one_ph <= 1'b1;
18
            one_pd <= 1'b1;
19
            sm <= e_DATA_LEN;
20
          end
21
        end
Und die damalige Änderung gilt immer also
im wb_tlc_dec.v Module
1
/*//// Vorher //////
2
        casex (rx_din[c_DATA_WIDTH-1:c_DATA_WIDTH-8])
3
        8'b00x0_0000: // MRd
4
        begin
5
          fifo_wrn_p <= 1'b0;          
6
          drop <= 1'b0;
7
        end 
8
        8'b01x0_0000: // MWr
9
        begin
10
          fifo_wrn_p <= 1'b1;          
11
          drop <= 1'b0;
12
        end        
13
        default:  // Unsuppored by WB
14
    */
15
 ///// Nach Änderung ////////
16
        casex (rx_din[c_DATA_WIDTH-1:c_DATA_WIDTH-8])
17
        8'b00x0_0000: // MRd
18
        begin
19
          fifo_wrn_p <= 1'b0;          
20
          drop <= 1'b0;
21
        end 
22
        8'b01x0_0000: // MWr
23
        begin
24
          fifo_wrn_p <= 1'b1;          
25
          drop <= 1'b0;
26
        end 
27
        8'b00x0_0010: // IO-Rd   
28
        begin
29
          fifo_wrn_p <= 1'b0;          
30
          drop <= 1'b0;
31
        end 
32
        8'b01x0_0010: // IO-Wr
33
        begin
34
          fifo_wrn_p <= 1'b1;          
35
          drop <= 1'b0;
36
        end  
37
    default:  // Unsuppored by WB

von Lattice User (Gast)


Lesenswert?

Das ist falsch!
1
        8'b0100_0010: begin //IO Wr
2
          if (~(rx_bar_hit[1] || rx_bar_hit[0]))
3
          begin            
4
            one_ph <= 1'b1;
5
            one_pd <= 1'b1;
6
            sm <= e_DATA_LEN;
7
          end

IO Writes sind im Gegensatzt zu Memorywrites NON POSTET, d.h. dier 
muss genau wie im UR stehen:
1
        8'b0100_0010: begin //IO Wr
2
          if (~(rx_bar_hit[1] || rx_bar_hit[0]))
3
          begin            
4
            one_nph <= 1'b1;
5
            one_npd <= 1'b1;
6
            sm <= e_DATA_LEN;
7
          end

Ausserdem fehlt noch die Erzeugung der IO Write Completions, dafür gibt 
es im Latticecode kein Vorbild! (Memory Writes brauchen das nicht)

von Keller T. (fabito)


Lesenswert?

IO transactions requests are restricted to 32 bits of address using the 
3DW TLP Header format, and should only target legacy devices.

Since PCI Express still permits either 32 bit or 64 bit memory 
addressing but the size of System IO Map is limited to 32 
bits(4GB),although in many system only lower 16 bits(i.e 64 KBs) are 
used.

So you can customize the existing code as per your requirement in order 
to account for IO request and should be responsible for sending an 
Unsupported Request completion based on the capabilities of your 
customized design.

For example, if in case your custom design only works with IO 
transactions and not memory transactions, then memory transactions are 
unsupported. These types of transactions require an Unsupported Request 
completion.

However there are several instances in which an Unsupported Request must 
be generated by the user. These conditions are
listed below.

• rx_us_req port goes high with rx_st indicating a Memory Read Locked, 
Completion Locked, or Vendor Defined
Message.
• Type of TLP is not supported by the user's design (I/O or memory 
request)
Table 2 in ipug75 on page 35 shows the types of unsupported TLPs which 
can be received by the IP core and the user interaction.


Link to download ipug75

http://www.latticesemi.com/~/media/Documents/UserManuals/MQ/PCIExpress11x1x4IPCoreUsersGuide.PDF#search=%22ipug75%22

von Keller T. (fabito)


Lesenswert?

Hallo Hier die Anworte vom Lattice Support:
IO transactions requests are restricted to 32 bits of address using the 
3DW TLP Header format, and should only target legacy devices.

Since PCI Express still permits either 32 bit or 64 bit memory 
addressing but the size of System IO Map is limited to 32 
bits(4GB),although in many system only lower 16 bits(i.e 64 KBs) are 
used.

So you can customize the existing code as per your requirement in order 
to account for IO request and should be responsible for sending an 
Unsupported Request completion based on the capabilities of your 
customized design.

For example, if in case your custom design only works with IO 
transactions and not memory transactions, then memory transactions are 
unsupported. These types of transactions require an Unsupported Request 
completion.

However there are several instances in which an Unsupported Request must 
be generated by the user. These conditions are
listed below.

• rx_us_req port goes high with rx_st indicating a Memory Read Locked, 
Completion Locked, or Vendor Defined
Message.
• Type of TLP is not supported by the user's design (I/O or memory 
request)
Table 2 in ipug75 on page 35 shows the types of unsupported TLPs which 
can be received by the IP core and the user interaction.


Link to download ipug75

http://www.latticesemi.com/~/media/Documents/UserManuals/MQ/PCIExpress11x1x4IPCoreUsersGuide.PDF#search=%22ipug75%22

von Keller T. (fabito)


Lesenswert?

Hallo,

nun meine Frage glaubst du dass, das Problem nur mit Änderungen
von 2 Modules:
UR.v
und
wb_tlc_dec.v

gelöst wird ?

Da Lattice Support nicht über das Module iprxcrpr.v spricht ?

von Keller T. (fabito)


Lesenswert?

Hallo

Ich verstehe nicht was ich falsch gemacht, da du das selbe Code 
eingefügt hast.
Kannst du bitte genauer meinen Fehler erlautern ?

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Hallo
>
> Ich verstehe nicht was ich falsch gemacht, da du das selbe Code
> eingefügt hast.

Du musst genauer hinschauen, ist nicht derselbe.
1
            one_ph <= 1'b1;
2
            one_pd <= 1'b1;
versus
1
            one_nph <= 1'b1;
2
            one_npd <= 1'b1;

> Kannst du bitte genauer meinen Fehler erlautern ?

Das geht sehr ins Eingemachte, und nur einfach zu erkären wenn du weisst 
wie bei PCIe Flusskontrolle implementiert wird, was der Unterschied 
zwischen Postet und Non Postet Requests ist, und noch einiges mehr.

von Keller T. (fabito)


Lesenswert?

Hallo Gute Nachricht!

Es tut schon beim Lesen!!!!!!!!!
Habe ich 100 000 000 Loop problemlos gelesen!
Nun soll ich auch Write schaffen und da ist mir beim Credit Processing 
noch nicht klar.

reicht folgende Code für IO Write ?
1
    case (sm)    
2
    e_IDLE: // wait for TLP
3
    begin  
4
      // Decode Type of Request
5
      if (rx_st) begin
6
        sm <= e_WAIT;
7
        casex (rx_din[15:8])
8
        //8'h00: // MRd to BAR other than 0 or 1
9
        8'b00x0_0000: //0000_0000 for 3DW mrd; 0010_0000 for 4DW mrd; 
10
        begin
11
          if (~(rx_bar_hit[1])) //8'h40: // MWr to BAR other than 0 or 1
12
            one_nph <= 1'b1;
13
        end
14
        8'b00x0_0001: //0000_0001 for 3DW mrdlk; 0010_0001 for 4DW mrdlk 
15
          one_nph <= 1'b1;
16
        8'b01x0_0000: //0100_0000 for 3DW mwr; 0110_0000 for 4DW mwr
17
        begin
18
          if (~(rx_bar_hit[1]))
19
          begin            
20
            one_ph <= 1'b1;
21
            one_pd <= 1'b1;
22
            sm <= e_DATA_LEN;
23
          end
24
        end
25
        8'b0000_0010: begin //IO Rd
26
          if (~(rx_bar_hit[0])) //8'h40: // IORd to BAR other than 0
27
            one_nph <= 1'b1;
28
        end
29
        8'b0100_0010: begin //IO Wr
30
     if (~(rx_bar_hit[0])) 
31
           one_nph <= 1'b1;
32
           one_npd <= 1'b1;
33
        end

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Hallo Hier die Anworte vom Lattice Support:
> IO transactions requests are restricted to 32 bits of address using the
> 3DW TLP Header format, and should only target legacy devices.

Dem schliesse ich mich an, angefaultes stinkendes Legacy.
Warum willst du es eigentlich machen? DOS 3.3? Windows 95/98?

>
> Since PCI Express still permits either 32 bit or 64 bit memory
> addressing but the size of System IO Map is limited to 32
> bits(4GB),although in many system only lower 16 bits(i.e 64 KBs) are
> used.
>

Das bedeutet nur, dass du IO Requests mit 4 DW Headern als UR ablehnen 
sollst. Ist relativ unkritisch, da diese normalerweise nicht vorkommen 
sollten. (Ausser in Verifications Umgebungen)

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Hallo Gute Nachricht!
>
> Es tut schon beim Lesen!!!!!!!!!
> Habe ich 100 000 000 Loop problemlos gelesen!
> Nun soll ich auch Write schaffen und da ist mir beim Credit Processing
> noch nicht klar.
>
> reicht folgende Code für IO Write ?

Nein, IO Write braucht wie schon mehrmals erwähnt eine Completion (nur 
Header ohne Daten)!

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hilfe!

Es klappt immer noch nicht mit dem IO-Write:

So sieht mein ip_rx_crpr.v Module aus. Aber dann hat mein Board nicht 
mehr
gebootet:
1
        8'b0100_0010: begin //IO Wr
2
      if (~(rx_bar_hit[0])) //8'h40: // IO-Wr to BAR other than 0
3
           one_nph <= 1'b1;
4
        end

BAR-0 is IO MAP
BAR-1 is MMAP

Was mache ich falsch da. Ich habe nur Header da gelassen oder fehlt mir 
noch was ?

von Lattice User (Gast)


Lesenswert?

Du hast etwas falsch verstanden, es geht nicht um den empfangenen Header 
der war vorher schon in Ordnung.

Completion ist ein Antwortpacket das NACH einem IO Write generiert 
werden muss, genau wie bei IO Read aber ohne Daten.
Am einfachsten dürfte es sein, das in wb_tlc_cpld.v und 
wb_tlc_cpld_fifo.v mit einzubauen, aber beachten dass es bei Memory 
Writes NICHT gemacht wird.

von Keller T. (fabito)


Lesenswert?

Hallo,

letztendlich habe ich das Module ip_rx_crpr.v wie folgenden gelassen.
Folglich klappt es im UART-Register zu schreiben.
1
case (sm)    
2
    e_IDLE: // wait for TLP
3
    begin  
4
      // Decode Type of Request
5
      if (rx_st) begin
6
        sm <= e_WAIT;
7
        casex (rx_din[15:8])
8
        //8'h00: // MRd to BAR other than 0 or 1
9
        8'b00x0_0000: //0000_0000 for 3DW mrd; 0010_0000 for 4DW mrd; 
10
        begin
11
          if (~(rx_bar_hit[1])) //8'h40: // MWr to BAR other than 0 or 1
12
            one_nph <= 1'b1;
13
        end
14
        8'b00x0_0001: //0000_0001 for 3DW mrdlk; 0010_0001 for 4DW mrdlk 
15
          one_nph <= 1'b1;
16
        8'b01x0_0000: //0100_0000 for 3DW mwr; 0110_0000 for 4DW mwr
17
        begin
18
          if (~(rx_bar_hit[1]))
19
          begin            
20
            one_ph <= 1'b1;
21
            one_pd <= 1'b1;
22
            sm <= e_DATA_LEN;
23
          end
24
        end
25
        8'b0000_0010: begin //IO Rd
26
          if (~(rx_bar_hit[0])) //8'h40: // IO-Rd to BAR other than 0
27
            one_nph <= 1'b1;
28
        end
29
        8'b0100_0010: begin //IO Wr
30
      if (~(rx_bar_hit[0])) //8'h40: // IO-Wr to BAR other than 0
31
           one_nph <= 1'b1;
32
           one_npd <= 1'b1;
33
        end
34
        8'b00110xxx: // Msg
35
        begin
36
          one_ph <= 1'b1;
37
        end      
38
        8'b01110xxx: // MsgD
39
        begin
40
          one_ph <= 1'b1;
41
          one_pd <= 1'b1;
42
          sm <= e_DATA_LEN;
43
          //pd_num <= rx_din[38:32]; // get length
44
          //pd_num <= (rx_din[1:0] == 2'b00) ? rx_din[9:2] : (rx_din[9:2] + 1); // get length        
45
        end      
46
        8'h44: // CfgWr0
47
        begin
48
          one_nph <= 1'b1;
49
          one_npd <= 1'b1;
50
        end
51
        ..........

von Lattice User (Gast)


Lesenswert?

Was ist mit der Completion?

von Keller T. (fabito)


Lesenswert?

Es hat geklappt aber ich habe das Gefühl dass, es eine kleine 
Verzögerung beim IOWrite gibt.
Sonst es funktioniert...
Hat das wahrscheinlich mit der Completion zu tun ? Wenn dann wie kann 
ich diese verbessern ?

von Keller T. (fabito)


Lesenswert?

Hallo,

bitte wie kann ich IO Completion implementieren, dafür habe ich leider
kein Ausgangspunkt.

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Es hat geklappt aber ich habe das Gefühl dass, es eine kleine
> Verzögerung beim IOWrite gibt.
> Sonst es funktioniert...
> Hat das wahrscheinlich mit der Completion zu tun ?

Ja hat es.
Der Intelchipsatz, ist da gutmütig, d.h. er macht nach einem Completion 
Timeout einfach weiter. (Beim Lesen bekommt man dann 0xFFFFFFFF).
Es gibt aber andere. (Nvidia Ion friert ein).

Siehe auch ein frühres Posting:
Beitrag "Re: Lattice ECP3: IO Read Begrenzung"

von Keller T. (fabito)


Lesenswert?

OK das habe ich auch verstanden!
Wo was getan werden soll ist meine Frage. Also ich weiße nicht wo ich 
damit anfangen soll.

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> OK das habe ich auch verstanden!
> Wo was getan werden soll ist meine Frage. Also ich weiße nicht wo ich
> damit anfangen soll.

Chapter 2.2.9 in der PCIe Spec 2.1 lesen und verstehen.
Dannach verstehen was in der wb_tlc_cpld.v genau gemacht wird.
Wenn das klar ist, versuchen die FSM in der wb_tlc_cpld.v zu ergänzen.

von Keller T. (fabito)


Lesenswert?

Danke für den Hinweis und ich werde es machen.
Nach der Implementierung und Test melde ich mich......

von Keller T. (fabito)


Lesenswert?

Hallo,

Nach dem Lesen von
soll folgende angepasst werden:
1
 if (read) begin
2
         sm <= ACK; 
3
         dout_sop <= 1'b1;
4
         dout_wen <= 1'b1;
5
         dout <= {8'h4a, 1'b0, tran_tc, 4'd0};
6
      end
7
    end
8
    ACK: // write header parts
9
    begin
10
      dout_wen <= 1'b1;
11
      dout_sop <= 1'b0;
12
      case (word_cnt)
13
         0: dout  <= {2'b00, tran_attr, 2'b00, tran_length};
14
         1: dout  <= comp_id; 
15
         2: dout  <= {3'b000, 1'b0, bc};
16
         3: dout  <= tran_id[23:8];
17
         4: dout  <= {tran_id[7:0], 1'b0, la};
18
      endcase

man soll IO Write auch hier berücksichtigen also nicht nur Memory Read 
wie jetzt der Fall ist oder ?
Das werde ich Morgen implementieren und testen ..

von Keller T. (fabito)


Lesenswert?

So sieht meine Completion für IOWrite TLP aus:
1
    //  if (read) begin                                                     VORHER
2
  if ((read)|| (~read && (rx_bar_hit[0])) read or write on BAR0 (IOWr) // NEUE
3
         sm <= ACK; 
4
         dout_sop <= 1'b1;
5
         dout_wen <= 1'b1;
6
         dout <= {8'h4a, 1'b0, tran_tc, 4'd0}; // first 16'b from Completion Header Fields
7
      end
8
    end
9
    ACK: // write header parts
10
    begin
11
      dout_wen <= 1'b1;
12
      dout_sop <= 1'b0;
13
      case (word_cnt)
14
         0: dout  <= {2'b00, tran_attr, 2'b00, tran_length};
15
         1: dout  <= comp_id; // CompletionID 16'b
16
         2: dout  <= {3'b000, 1'b0, bc}; // 16'b
17
         3: dout  <= tran_id[23:8];              //Request ID = 16'b
18
         4: dout  <= {tran_id[7:0], 1'b0, la};   // Tag + R + Lower Adresse = 16'b
19
      endcase
20
      
21
      if (word_cnt == 4) begin                                         // VORHER    
22
         if (~read && (rx_bar_hit[0])) begin                           // NEU: HINZU
23
        dout_eop <= 1'b1;
24
            sm <= CLEAR;
25
      end
26
     else begin
27
        sm <= DAT;
28
            word_cnt <= 1;
29
            end
30
    end
31
      else
32
         word_cnt <= word_cnt + 1;
33
    end
34
    DAT: // write data parts

Damit bin ich mit der IOWrite Completion fertig oder hast du weitere 
Anmerkung?

von Keller T. (fabito)


Lesenswert?

Hat leider nicht geklappt,

IORead klappt damit nicht mehr
Hier meine neue Implementierung:
1
    case (sm)
2
    IDLE:
3
    begin
4
      word_cnt <= 0;
5
      dout_eop <= 1'b0;
6
    //  if (read) begin   VORHER
7
  if ((read)|| (rx_din[15:8]== 8'b01x0_0010)) begin //read or write on BAR0 (IOWr) // NEUE
8
         sm <= ACK; 
9
         dout_sop <= 1'b1;
10
         dout_wen <= 1'b1;
11
         dout <= {8'h4a, 1'b0, tran_tc, 4'd0}; // first 16'b from Completion Header Fields
12
      end
13
    end
14
    ACK: // write header parts
15
    begin
16
      dout_wen <= 1'b1;
17
      dout_sop <= 1'b0;
18
      case (word_cnt)
19
         0: dout  <= {2'b00, tran_attr, 2'b00, tran_length};
20
         1: dout  <= comp_id; // CompletionID 16'b
21
         2: dout  <= {3'b000, 1'b0, bc}; // 16'b
22
         3: dout  <= tran_id[23:8];              //Request ID = 16'b
23
         4: dout  <= {tran_id[7:0], 1'b0, la};   // Tag + R + Lower Adresse = 16'b
24
      endcase
25
      
26
      if (word_cnt == 4) begin                                         // VORHER    
27
         if (rx_din[15:8]== 8'b01x0_0010) begin                           // NEU: HINZU
28
        dout_eop <= 1'b1;
29
            sm <= CLEAR;
30
      end
31
     else begin
32
        sm <= DAT;
33
            word_cnt <= 1;
34
            end
35
    end
36
      else
37
         word_cnt <= word_cnt + 1;
38
    end

Auf Hinweis würde ich mich freuen...

von Lattice User (Gast)


Lesenswert?

rx_din[15:8] und rx_bar_hit sind ganz sicher nicht mehr gültig.

Du brauchst ein zusätzliches Signal entsprechend "read", das ein iowrite 
durchreicht.

tran_length muss bei write completions auf 0 gesetzt werde, es wird ja 
nur der Header gesendet.

"bc" muss 4 sein, aber ob für "la" die byte enables ausgwertet werden 
sollen
kann ich dir jetzt nicht mit Sicherheit sagen, ich vermute nein.

(Immer daran denken, iowrite ist verfaultest Legacy, und die Behandlung 
von cfgwrites nimmt uns der core ab)

von Keller T. (fabito)


Lesenswert?

Es gelingt mir nicht Tabelle 2-21 und 2-22 in der Spezifikation zu 
finden.
schaue Mal
http://iu4ever.org/files/Skhemotekhnika_JEVS9/1697_Skhemotekhnika_JEVS9_PCI_Express_Base_r2_1.pdf

Kannst du bitte mir diese 2 Tabelle zukommen lassen ?

Ich wäre denkbar

von Keller T. (fabito)


Lesenswert?

Wenn dies sich au Power Management Messages bezieht dann habe ich....
Ich habe mit TLP gerechnet und nicht mit Power Message da ich keine 
Zusammenhang sehe.

von Lattice User (Gast)


Lesenswert?

Die Tabellennumerierung im Latticecode bezieht sich offensichtlich noch 
auf die PCIe Spec 1.1

In der 2.1 Spec sind das jetzt die Tabellen 2.31 und 2.32

von Keller T. (fabito)


Lesenswert?

Danke,

Mit tran_length = 0 verstehe ich aber bc =4 ist mir unklar weil:
 wenn First_BE = 0xF = 1111 dann BC=4

aber hier habe ich mein IOWr Paket angeschaut und First_BE=0x1=0001 also 
würde ich damit BC= 1 erwarten oder ?

von Lattice User (Gast)


Lesenswert?

>
> Mit tran_length = 0 verstehe ich aber bc =4 ist mir unklar weil:
>  wenn First_BE = 0xF = 1111 dann BC=4
>
> aber hier habe ich mein IOWr Paket angeschaut und First_BE=0x1=0001 also
> würde ich damit BC= 1 erwarten oder ?

In 2.9 Completion Rules steht, dass der BC für alle Completions ausser 
Memory Reads (und AtomicOPs hier irrelevant) 4 sein muss.
Das schliesst auch IO Reads mit ein!

von Keller T. (fabito)


Lesenswert?

Hallo ,

Ich habe schon fast alles bisher probiert.
Leider klappt es immer noch nicht.
Ich bitte um Hilfe!
1
module wb_tlc_cpld(wb_clk, rstn,
2
                din, sel, read, valid,
3
                tran_id, tran_length, tran_be, tran_addr, tran_tc, tran_attr, comp_id,
4
                dout, dout_sop, dout_eop, dout_wen,rx_din
5
);
6
7
input wb_clk;
8
input rstn;
9
input [15:0] din;
10
input [1:0] sel;
11
input read;
12
input valid;
13
input [23:0]  tran_id;  // tran_id = {req_id,tag}
14
input [9:0] tran_length;
15
input [7:0] tran_be;
16
input [4:0] tran_addr;
17
input [2:0] tran_tc;
18
input [1:0] tran_attr;
19
input [15:0] comp_id;
20
output [15:0] dout;
21
output dout_sop;
22
output dout_eop;
23
output dout_wen;
24
input  [15:0] rx_din;
25
26
reg [2:0] sm;
27
parameter IDLE = 3'b000,          
28
          ACK = 3'b001,
29
          DAT = 3'b010,
30
          CLEAR = 3'b011;
31
32
33
reg [15:0] dout, din_p, din_p2, din_p3, din_p4, din_p5;
34
reg dout_sop, dout_eop, dout_wen;
35
reg [11:0] bc;
36
reg [6:0] la;
37
reg valid_p, valid_p2, valid_p3, valid_p4, valid_p5;
38
reg [10:0] word_cnt;
39
40
41
always @(negedge rstn or posedge wb_clk)
42
begin
43
  if (~rstn)
44
  begin
45
    sm <= IDLE;
46
    dout <= 0;
47
    dout_sop <= 1'b0;
48
    dout_eop <= 1'b0;
49
    din_p <= 0;
50
    din_p2 <= 0;
51
    din_p3 <= 0;
52
    din_p4 <= 0;
53
    din_p5 <= 0;
54
   
55
    valid_p <= 1'b0;
56
    valid_p2 <= 1'b0;
57
    valid_p3 <= 1'b0;
58
    valid_p4 <= 1'b0;
59
    valid_p5 <= 1'b0;
60
    
61
    dout_wen <= 1'b0;
62
    la <= 7'b0000000;
63
    bc <= 0;
64
    word_cnt <= 0;
65
  end
66
  else
67
  begin
68
    din_p <= din;
69
    din_p2 <= din_p;  // pipe data to allow for header
70
    din_p3 <= din_p2;
71
    din_p4 <= din_p3;
72
    din_p5 <= din_p4;
73
    valid_p <= valid;
74
    valid_p2 <= valid_p; 
75
    valid_p3 <= valid_p2;  
76
    valid_p4 <= valid_p3;  
77
    valid_p5 <= valid_p4;  
78
  
79
  case (sm)
80
    IDLE:
81
    begin
82
      word_cnt <= 0;
83
      dout_eop <= 1'b0;
84
      if (read) begin
85
         sm <= ACK; 
86
         dout_sop <= 1'b1;
87
         dout_wen <= 1'b1;
88
         dout <= {8'h4a, 1'b0, tran_tc, 4'd0};
89
         end
90
    else if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
91
         sm <= ACK; 
92
         dout_sop <= 1'b1;
93
         dout_wen <= 1'b1;
94
         dout <= {8'h0a, 1'b0, tran_tc, 4'd0};
95
         end
96
    end
97
    ACK: // write header parts
98
    begin
99
      dout_wen <= 1'b1;
100
      dout_sop <= 1'b0;
101
       if (read) begin
102
    case (word_cnt)
103
         0: dout  <= {2'b00, tran_attr, 2'b00, tran_length};
104
         1: dout  <= comp_id; 
105
         2: dout  <= {3'b000, 1'b0, bc};
106
         3: dout  <= tran_id[23:8];
107
         4: dout  <= {tran_id[7:0], 1'b0, la};
108
      endcase
109
      end
110
    else if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
111
    case (word_cnt)
112
         0: dout  <= {2'b00, tran_attr, 2'b00, 10'd0};
113
         1: dout  <= comp_id; 
114
         2: dout  <= {3'b000, 1'b0, 12'd4}; // 16'b
115
         3: dout  <= tran_id[23:8];
116
         4: dout  <= {tran_id[7:0], 1'b0, la};
117
      endcase
118
    end
119
    
120
      if (word_cnt == 4) begin
121
     if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
122
      dout_eop <= 1'b1;
123
          sm <= CLEAR;
124
          end
125
     else begin
126
     sm <= DAT;
127
         word_cnt <= 1;
128
         end
129
     end
130
     else
131
        word_cnt <= word_cnt + 1;
132
    end
133
    DAT: // write data parts
134
    begin
135
      dout_wen <= valid_p5;
136
      dout <= din_p5;
137
      if (valid_p5) begin
138
         if (word_cnt == {tran_length, 1'b0}) begin
139
            dout_eop <= 1'b1;
140
            sm <= CLEAR;
141
         end
142
         else
143
            word_cnt <= word_cnt + 1;
144
      end
145
    end    
146
    CLEAR: // clean up  
147
    begin
148
      dout_wen <= 1'b0;      
149
      dout_eop <= 1'b0;      
150
      sm <= IDLE;
151
    end
152
    
153
    endcase
154
155
156
    // implementation of table 2-21 from PCIe base spec
157
    //tran_be = first, last
158
    casex(tran_be)
159
    8'b1xx10000: bc <= 12'h004;
160
    8'b01x10000: bc <= 12'h003;
161
    8'b1x100000: bc <= 12'h003;
162
    8'b00110000: bc <= 12'h002;
163
    8'b01100000: bc <= 12'h002;
164
    8'b11000000: bc <= 12'h002;
165
    8'b00010000: bc <= 12'h001;
166
    8'b00100000: bc <= 12'h001;
167
    8'b01000000: bc <= 12'h001;
168
    8'b10000000: bc <= 12'h001;
169
    8'b00000000: bc <= 12'h001;
170
    8'bxxx11xxx: bc <= (tran_length*4);
171
    8'bxxx101xx: bc <= (tran_length*4) - 1;
172
    8'bxxx1001x: bc <= (tran_length*4) - 2;
173
    8'bxxx10001: bc <= (tran_length*4) - 3;
174
    8'bxx101xxx: bc <= (tran_length*4) - 1;
175
    8'bxx1001xx: bc <= (tran_length*4) - 2;
176
    8'bxx10001x: bc <= (tran_length*4) - 3;
177
    8'bxx100001: bc <= (tran_length*4) - 4;
178
    8'bx1001xxx: bc <= (tran_length*4) - 2;
179
    8'bx10001xx: bc <= (tran_length*4) - 3;
180
    8'bx100001x: bc <= (tran_length*4) - 4;
181
    8'bx1000001: bc <= (tran_length*4) - 5;
182
    8'b10001xxx: bc <= (tran_length*4) - 3;
183
    8'b100001xx: bc <= (tran_length*4) - 4;
184
    8'b1000001x: bc <= (tran_length*4) - 5;
185
    8'b10000001: bc <= (tran_length*4) - 6;
186
    endcase
187
  
188
  
189
    // implementation of table 2-22 from PCIe base spec
190
    //tran_be = first, last
191
    casex(tran_be[7:4])
192
    4'b0000: la <= {tran_addr, 2'b00};     
193
    4'bxxx1: la <= {tran_addr, 2'b00};     
194
    4'bxx10: la <= {tran_addr, 2'b01};     
195
    4'bx100: la <= {tran_addr, 2'b10};     
196
    4'b1000: la <= {tran_addr, 2'b11};     
197
    endcase
198
199
  end //clk
200
end
201
endmodule

von Lattice User (Gast)


Lesenswert?

Wo kommt "rx_din" her? wenn es einfach rx_din vom PCIe core ist, kann es 
nicht gehen. Der Wert den du da abfragen willst, liegt da schon seit 
vielen Takten nicht mehr an.

von Keller T. (fabito)


Lesenswert?

Schau Mal ganz unten dem folgende Module. Ich habe einfach rx_din 
hinzugefügt als neu input für das Module wb_tlc_cpld.
Es wäre vielleicht einfacher wenn man folgende Signale ausnutzen würde:
1
assign write = wb_cyc_o && (wb_we_o);
2
assign read = read_comp && (~ read_comp_d);
1
module wb_tlc (clk_125, wb_clk, rstn, 
2
               rx_data, rx_st, rx_end, rx_bar_hit,
3
               wb_adr_o, wb_dat_o, wb_cti_o, wb_we_o, wb_sel_o, wb_stb_o, wb_cyc_o, wb_lock_o, 
4
               wb_dat_i, wb_ack_i,
5
               pd_cr, ph_cr, pd_num, npd_cr, nph_cr,               
6
               tx_rdy, tx_ca_cpl_recheck, tx_ca_cplh, tx_ca_cpld,
7
               tx_req, tx_data, tx_st, tx_end, 
8
               comp_id,
9
               debug
10
);
11
                    
12
input clk_125;
13
input wb_clk;
14
input rstn;
15
16
input [15:0] rx_data;
17
input rx_st;
18
input rx_end;
19
input [6:0] rx_bar_hit;
20
21
output [31:0] wb_adr_o;
22
output [15:0] wb_dat_o;
23
output [2:0] wb_cti_o;
24
output wb_we_o;
25
output [1:0] wb_sel_o;
26
output wb_stb_o;
27
output wb_cyc_o;
28
output wb_lock_o;
29
input wb_ack_i;
30
input [15:0] wb_dat_i;
31
32
output pd_cr, ph_cr, npd_cr, nph_cr;
33
output [7:0] pd_num;
34
input tx_rdy;
35
output tx_req;
36
output [15:0] tx_data;
37
output tx_st;
38
output tx_end;
39
input  tx_ca_cpl_recheck;
40
input  [8:0] tx_ca_cplh;
41
input  [12:0] tx_ca_cpld;
42
input [15:0] comp_id; // completer id = {bus_num, dev_num, func_num}
43
44
output [31:0] debug;
45
46
wire [15:0] to_req_fifo_dout;
47
wire to_req_fifo_sop;
48
wire to_req_fifo_eop;
49
wire to_req_fifo_dwen;
50
wire to_req_fifo_wrn;
51
wire to_req_fifo_wen;
52
wire [6:0] to_req_fifo_bar;
53
54
wire [15:0] from_req_fifo_dout;
55
wire from_req_fifo_sop;
56
wire from_req_fifo_eop;
57
wire from_req_fifo_wrn;
58
wire tlp_avail;
59
60
wire [15:0] read_data;
61
wire [9:0] tran_len;
62
wire [23:0] tran_id;
63
wire [7:0] tran_be;
64
wire [4:0] tran_addr;
65
wire [2:0] tran_tc;
66
wire [1:0] tran_attr;
67
68
69
wire [15:0] cmpl_d;
70
wire [6:0] from_req_fifo_bar;
71
72
reg ph_cr_wb;
73
reg [7:0] pd_num_wb;
74
reg read_comp_d;
75
reg [7:0] pd_num;
76
wb_tlc_dec #(.c_DATA_WIDTH (16)) dec(.clk_125(clk_125), .rstn(rstn),
77
               .rx_din(rx_data), .rx_sop(rx_st), .rx_eop(rx_end), .rx_dwen(1'b0), .rx_bar_hit(rx_bar_hit),
78
               .fifo_dout(to_req_fifo_dout), .fifo_sop(to_req_fifo_sop), .fifo_eop(to_req_fifo_eop),  
79
               .fifo_dwen(to_req_fifo_dwen), .fifo_wrn(to_req_fifo_wrn), .fifo_wen(to_req_fifo_wen),
80
               .fifo_bar(to_req_fifo_bar)
81
);                                           
82
83
wb_tlc_req_fifo #(.c_DATA_WIDTH (16)) req_fifo (.rstn(rstn), .clk_125(clk_125), .wb_clk(wb_clk),
84
                    .din(to_req_fifo_dout), .din_bar(to_req_fifo_bar), .din_sop(to_req_fifo_sop), .din_eop(to_req_fifo_eop), 
85
                    .din_wrn(to_req_fifo_wrn),.din_dwen(1'b0), .din_wen(to_req_fifo_wen), 
86
                    .dout(from_req_fifo_dout), .dout_sop(from_req_fifo_sop), .dout_eop(from_req_fifo_eop), .dout_wrn(from_req_fifo_wrn), 
87
                    .dout_bar(from_req_fifo_bar), .dout_dwen(),
88
                    .dout_ren(to_req_fifo_ren), .tlp_avail(tlp_avail)
89
                    
90
);
91
92
always @(posedge wb_clk or negedge rstn)
93
   if (!rstn) begin
94
      ph_cr_wb <= 0;
95
      pd_num_wb <= 8'd1;
96
   end
97
   else begin
98
      ph_cr_wb <= from_req_fifo_sop & from_req_fifo_wrn;
99
      if (ph_cr_wb)
100
         pd_num_wb <= (from_req_fifo_dout[1:0] == 2'b00) ? from_req_fifo_dout[9:2] : (from_req_fifo_dout[9:2] + 1);
101
   end
102
103
wb_tlc_cr phcr(.rstn(rstn), .clk_125(clk_125), .wb_clk(wb_clk), .cr_wb(ph_cr_wb), .cr_125(ph_cr));
104
assign pd_cr = ph_cr;          
105
106
always @(posedge clk_125 or negedge rstn)
107
   if (!rstn)
108
      pd_num <= 8'd1;
109
   else
110
      pd_num <= pd_num_wb;
111
      
112
113
114
115
116
117
wb_intf intf (.rstn(rstn), .wb_clk(wb_clk), 
118
               .din(from_req_fifo_dout), .din_sop(from_req_fifo_sop), .din_eop(from_req_fifo_eop), 
119
               .din_bar(from_req_fifo_bar), .din_wrn(from_req_fifo_wrn),
120
               .din_ren(to_req_fifo_ren), .tlp_avail(tlp_avail),
121
               .tran_id(tran_id), .tran_length(tran_len), .tran_be(tran_be), .tran_addr(tran_addr), .tran_tc(tran_tc), .tran_attr(tran_attr),
122
               .wb_adr_o(wb_adr_o), .wb_dat_o(wb_dat_o), .wb_cti_o(wb_cti_o), .wb_we_o(wb_we_o), .wb_sel_o(wb_sel_o), .wb_stb_o(wb_stb_o), .wb_cyc_o(wb_cyc_o), .wb_lock_o(wb_lock_o), .wb_ack_i(wb_ack_i)                              
123
);              
124
125
126
assign read_data = {wb_dat_i[7:0], wb_dat_i[15:8]}; // order bytes back to PCIe order
127
128
assign read_comp = wb_cyc_o && (~ wb_we_o);
129
assign write = wb_cyc_o && (wb_we_o);
130
assign read = read_comp && (~ read_comp_d);
131
132
always @(posedge wb_clk or negedge rstn)
133
   if (!rstn) begin
134
      read_comp_d <= 0;
135
   end
136
   else begin
137
      read_comp_d <= read_comp;
138
   end
139
140
wb_tlc_cpld  cpld (.wb_clk(wb_clk), .rstn(rstn),.rx_din(rx_data),
141
                .din(read_data), .sel(wb_sel_o), .read(read), .valid(wb_ack_i),
142
                .tran_id(tran_id), .tran_length(tran_len), .tran_be(tran_be), .tran_addr(tran_addr), .tran_tc(tran_tc), .tran_attr(tran_attr), .comp_id(comp_id),
143
                .dout(cmpl_d), .dout_sop(cmpl_sop), .dout_eop(cmpl_eop),  .dout_wen(cmpl_wen)                
144
);
145
146
147
wb_tlc_cpld_fifo #(.c_DATA_WIDTH (16)) cpld_fifo(.rstn(rstn), .clk_125(clk_125), .wb_clk(wb_clk),
148
                    .din(cmpl_d), .din_sop(cmpl_sop), .din_eop(cmpl_eop),  .din_dwen(1'b0), .din_wen(cmpl_wen),                  
149
                    .tx_data(tx_data), .tx_st(tx_st), .tx_end(tx_end), .tx_dwen(),  .tx_ca_cpl_recheck(tx_ca_cpl_recheck), .tx_ca_cplh(tx_ca_cplh), .tx_ca_cpld(tx_ca_cpld),
150
                    .tx_rdy(tx_rdy), .tx_req(tx_req)
151
); 
152
153
assign nph_cr = tx_st;
154
assign npd_cr = 1'b0;
155
156
endmodule

von Keller T. (fabito)


Lesenswert?

Hallo hier einen Hinweis zu la Signal:(2.2.9 Completion Rules im PCIe 
Specification 2.1)
Damit muss man la =0
• Lower Address[6:0] – lower byte address for starting byte of 
Completion
♦ For Memory Read Completions, the value in this field is the byte 
address for the first
enabled byte of data returned with the Completion (see the rules in 
Section 2.3.1.1)
♦ For AtomicOp Completions, the Lower Address field is reserved.
5 ♦ This field is set to all 0’s for all remaining types of Completions. 
Receivers may
optionally check for violations of this rule. See Section 2.3.2, second 
bullet, for details.

Ich habe auch dies aus von Xilinx Completion Module (Sieh unten)
1
procedure PROC_TX_COMPLETION (
2
 
3
  tag                      : in std_logic_vector (7 downto 0);
4
  tc                       : in std_logic_vector (2 downto 0);
5
  len                      : in std_logic_vector (9 downto 0);
6
  comp_status              : in std_logic_vector (2 downto 0);
7
  signal trn_td_c          : out std_logic_vector(63 downto 0);
8
  signal trn_tsof_n        : out std_logic;
9
  signal trn_teof_n        : out std_logic;
10
  signal trn_trem_n_c      : out std_logic_vector(7 downto 0);
11
  signal trn_tsrc_rdy_n    : out std_logic;
12
  signal trn_lnk_up_n : in std_logic;
13
  signal trn_tdst_rdy_n : in std_logic;
14
  signal trn_clk : in std_logic
15
 
16
) is
17
 
18
begin
19
 
20
  assert (trn_lnk_up_n = '0')
21
  report "TX Trn interface is MIA"
22
    severity failure;
23
 
24
 
25
  PROC_TX_SYNCHRONIZE(0, 0, trn_lnk_up_n, trn_tdst_rdy_n, trn_clk);
26
 
27
  trn_td_c          <= '0' &
28
                       "00" &
29
                       "01010" &
30
                       '0' &
31
                       tc(2 downto 0) &
32
                       "0000" &
33
                       '0' &
34
                       '0' &
35
                       "00" &
36
                       "00" &
37
                       len(9 downto 0) &
38
                       COMPLETER_ID_CFG &
39
                       comp_status(2 downto 0) &
40
                       '0' &
41
                       X"000";
42
  trn_tsof_n        <= '0';
43
  trn_teof_n        <= '1';
44
  trn_trem_n_c      <= X"00";
45
  trn_tsrc_rdy_n    <= '0';
46
 
47
  PROC_TX_SYNCHRONIZE(1,0, trn_lnk_up_n, trn_tdst_rdy_n, trn_clk);
48
 
49
  trn_td_c          <= COMPLETER_ID_CFG &
50
                       tag(7 downto 0) &
51
                       X"00" &
52
                       X"00000000";
53
  trn_tsof_n        <= '1';
54
  trn_teof_n        <= '0';
55
  trn_trem_n_c      <= X"0F";
56
 
57
  PROC_TX_SYNCHRONIZE(1, 1, trn_lnk_up_n, trn_tdst_rdy_n, trn_clk);
58
 
59
  trn_teof_n        <= '1';
60
  trn_trem_n_c      <= X"00";
61
  trn_tsrc_rdy_n    <= '1';
62
 
63
 
64
end PROC_TX_COMPLETION;

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Schau Mal ganz unten dem folgende Module. Ich habe einfach rx_din
> hinzugefügt als neu input für das Module wb_tlc_cpld.

rx_din ist wie schon mehrfach gesagt ungeignet.
Du musst dir den ganzen Ablauf in Takten vor Augen halten, sonst wird 
das nichts mit deiner Zukunft als VHDL/Verilog Entwickler.

> Es wäre vielleicht einfacher wenn man folgende Signale ausnutzen würde:
>
1
> assign write = wb_cyc_o && (wb_we_o);
2
> assign read = read_comp && (~ read_comp_d);
3
>

Schon besser, aber beachte dass das write das dem cpld übergibst nur 
einen Takt lang sein sollte, (am Ende des WB Cycles)
Ausserdem ganz wichtig, wenn du es wie bei read nur aus den Whishbone 
signalen generierts, kannst du nicht zwischen Mem und IO Writes 
unterscheiden. Und bei Mem Writes darfst du keine Completions 
generieren.


keller thomas schrieb:
> Hallo hier einen Hinweis zu la Signal:(2.2.9 Completion Rules im PCIe
> Specification 2.1)
> Damit muss man la =0

Da bin ich mir nicht sicher, aber ich habe bislang keine Write 
Completions (IO bzw CFG) implementieren müssen, und damit das ganze auch 
nicht detailiert untersucht.
Leg dir einen PCIe Analyzer zu, dann kannst du schauen was bei CFG 
Writes gemacht wird.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo ,

Habe was festgestellt, beim Read aus MemoryMap Bereiche also BAR1 wird 
das Signal read gesetzt und Completion auch.
Aber beim Read aus IO-Bereiche wird das Signal Read niemals gesetzt.
Es scheint als es ein Filter irgendwo noch gibt der nur MWr/Mrd 
ermöglicht.
Schaue Mal bitte kurz die Bilder aus LogicAnalyser aus

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Hallo ,
>
> Habe was festgestellt, beim Read aus MemoryMap Bereiche also BAR1 wird
> das Signal read gesetzt und Completion auch.
> Aber beim Read aus IO-Bereiche wird das Signal Read niemals gesetzt.
> Es scheint als es ein Filter irgendwo noch gibt der nur MWr/Mrd
> ermöglicht.

Da es schon mal funktioniert hat, mit Backup bzw älterem Zustände aus 
der Versionsverwaltung vergleichen.

> Schaue Mal bitte kurz die Bilder aus LogicAnalyser aus

Um aus denen schlau zu werden, müsste ich mich mit allen Details der 
Implementation beschäftigen. Dazu habe ich keine Zeit. Davon abgesehen
ist der Ausschnutt zu kurz: Wo ist der empfangene Request?

(Ich habe einen eigenen Wrapper und verwende nicht den von Lattice).

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo Hier ein voll Ausschnutt (Request+ Completion)

Bei IO-Read TLP wird die richtige Wert gelesen (cpld_fifo/din = 
cpld/dout = 0x0303)ohne Header. Read Signal wird niemals gesetzt obwohl 
die richtige Data zuruckkommen.

Bei Memory-Read wird 0xFF00 mit entprechende Header gelesen als 
Completion.

Hat diese vielleicht mit meinen ip_rx_crpr.v und UR_gen.v Module?

Auf Hinweis werde ich denkbar da, ich seit 1 Woche daran arbeite.

von Keller T. (fabito)


Lesenswert?

Zusammengefasst unten Linux Ausgabe:

Beim IO-Read wird 0x03 an die Adresse 0x4000 gelesen

und

Beim Memory-Read wird 0xFF an die Adresse 0x106004 gelesen

von Keller T. (fabito)


Lesenswert?

Bei IO-Read bleibt der Counter ( word_cnt ) vom cpld.v Module bei 0 aber 
trotzdem wird die richtige Daten gelesen.
Und beim IO-Write bleibt der Counter immerhin bei 0
1
case (sm)
2
    IDLE:
3
    begin
4
      word_cnt <= 0;
5
      dout_eop <= 1'b0;
6
      if (read) begin
7
         sm <= ACK; 
8
         dout_sop <= 1'b1;
9
         dout_wen <= 1'b1;
10
         dout <= {8'h4a, 1'b0, tran_tc, 4'd0};
11
         end
12
    else if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
13
         sm <= ACK; 
14
         dout_sop <= 1'b1;
15
         dout_wen <= 1'b1;
16
         dout <= {8'h0a, 1'b0, tran_tc, 4'd0};
17
         end
18
    end
19
    ACK: // write header parts
20
    begin
21
      dout_wen <= 1'b1;
22
      dout_sop <= 1'b0;
23
       if (read) begin
24
    case (word_cnt)
25
         0: dout  <= {2'b00, tran_attr, 2'b00, tran_length};
26
         1: dout  <= comp_id; 
27
         2: dout  <= {3'b000, 1'b0, bc};
28
         3: dout  <= tran_id[23:8];
29
         4: dout  <= {tran_id[7:0], 1'b0, la};
30
      endcase
31
      end
32
    else if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
33
    case (word_cnt)
34
         0: dout  <= {2'b00, tran_attr, 2'b00, 10'd0};
35
         1: dout  <= comp_id; 
36
         2: dout  <= {3'b000, 1'b0, 12'd4}; // 16'b
37
         3: dout  <= tran_id[23:8];
38
         4: dout  <= {tran_id[7:0], 1'b0, la};
39
      endcase
40
    end
41
    
42
      if (word_cnt == 4) begin
43
     if ((~read) && (rx_din[15:8]== 8'b01x0_0010))begin
44
      dout_eop <= 1'b1;
45
          sm <= CLEAR;
46
          end
47
     else begin
48
     sm <= DAT;
49
         word_cnt <= 1;
50
         end
51
     end
52
     else
53
        word_cnt <= word_cnt + 1;
54
    end
55
    DAT: // write data parts
56
    begin
57
      dout_wen <= valid_p5;
58
      dout <= din_p5;
59
      if (valid_p5) begin
60
         if (word_cnt == {tran_length, 1'b0}) begin
61
            dout_eop <= 1'b1;
62
            sm <= CLEAR;
63
         end
64
         else
65
            word_cnt <= word_cnt + 1;
66
      end
67
    end    
68
    CLEAR: // clean up  
69
    begin
70
      dout_wen <= 1'b0;      
71
      dout_eop <= 1'b0;      
72
      sm <= IDLE;
73
    end
74
    
75
    endcase

Dann lässt sich die Frage stellen Warum ? Wie soll ich ihm erzwingen 
rein zu gehen ? Es gibt meiner Meinung nach eine Zeilecode wo nur Memory 
Requests erlauben werden.
Auf Hinweise würde ich mich freuen

von Keller T. (fabito)


Lesenswert?

Ich hätte erwartet dass, das read Signale beim IO-Read zu 1 geht .
Mein naschter Schritt ist der Grund zu verstehen oder ?

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:
> Ich hätte erwartet dass, das read Signale beim IO-Read zu 1 geht .
> Mein naschter Schritt ist der Grund zu verstehen oder ?

Offensichtlich wird in wb_intf der IORead nicht erkannt

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe aus ein ECP3 PCI Express Basic Demo Design mein Design 
abgeleitet(also MMAP basiert ohne IO).
Beim Test lauft alles gut bis etwa 8 Stunden und bleibt hangen.
Ist dies ein Hardware Timer oder Timing Constrainsts ?
beigefügt is mein Place_Route_Trace_Report zu finden.

Auf Anmerkungen würde ich mich freuen..

von Lattice User (Gast)


Lesenswert?

keller thomas schrieb:

> Beim Test lauft alles gut bis etwa 8 Stunden und bleibt hangen.

Hört sich nach fehlender PCI Express Lizens an. (Eval Timer)

Disable mal in den Strategy Settings unter Translate Design die Hardware 
Evaluation.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Eigentlich habe ich eine Lizenz. Nur habe ich mein Design vom 
ReferenzDesign danach zusatzliche Komponente addiert.

Wie komme ich drauf also unter welche Menu (Sieh Bild)

von Keller T. (fabito)


Lesenswert?

Hallo,

Unter Project/Active Strategy/Translate Design Setting habe ich 
folgende:

Name                   Type      Value
Hardware Evaluation    List      Enable

Was soll ich denn hier ändern durch was ??

von Keller T. (fabito)


Lesenswert?

OK habe ich es Disable

Nun teste ich wieder .........

von Keller T. (fabito)


Lesenswert?

Hallo,

Nach der Änderung
Hardware Evaluation    List      Disable

Habe ich während der neuen Kopilierung folgende Meldung erhalten:

Your License has expired.

Feature has expired.
Feature: LSC_IP_pcie_x1_e3_ipe
Expired date 16-jan-2013

Danach bleibt meine Kompilierung hängen.Somit ist mir klar dass, es um 
eine Lizenz Problem geht oder ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

keller thomas schrieb:
> Your License has expired.
> Somit ist mir klar dass, es um eine Lizenz Problem geht oder ?
Sieht wohl so aus...

Die Lizenz des Versa-Kits gilt nur für 1 Jahr. Dann musst du dir ein 
neues Kit kaufen... ;-)

: Bearbeitet durch Moderator
von Lattice User (Gast)


Lesenswert?

Lothar Miller schrieb:
> keller thomas schrieb:
>> Your License has expired.
>> Somit ist mir klar dass, es um eine Lizenz Problem geht oder ?
> Sieht wohl so aus...
>
> Die Lizenz des Versa-Kits gilt nur für 1 Jahr. Dann musst du dir ein
> neues Kit kaufen... ;-)

Für Diamond selbst hat er ja eine gültige Versa-spezifische Lizenz, die 
freie Weblizenz gilt normalerweise nicht für die ECP3.

Also einfach mal nachfragen.

Auch bei der Verlängerung regulären Volllizenz für Diamond, muss man die 
IP Lizenzen jedesmal manuell nachtragen lassen.

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
Noch kein Account? Hier anmelden.