Lattice ECP3: IO Read Begrenzung

OP #3552703
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)
Angehängte Dateien:
OP #3552772
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 ?
Angehängte Dateien:
Gast #3552843
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!
OP #3552923
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.
Angehängte Dateien:
Gast #3552944
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)
Gast #3553009
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.
Gast #3553018
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)
OP #3553098
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 ?
Angehängte Dateien:
OP #3553281
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
Gast #3553520
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)
OP #3554185
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
OP #3554186
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
Gast #3554474
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.
OP #3554479
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
Gast #3554490
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)
Gast #3554494
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)!
OP #3554728
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 ?
Angehängte Dateien:
Gast #3554889
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.
OP #3558302
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
        ..........
Gast #3561771
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"
Gast #3562706
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.
OP #3570576
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 ..
OP #3571339
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?
OP #3571581
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...
Gast #3571613
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)
Gast #3571884
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!
OP #3574481
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
OP #3577653
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
OP #3578163
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;
Gast #3578453
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.
OP #3578473
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
Angehängte Dateien:
Gast #3578722
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).
OP #3581237
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.
Angehängte Dateien:
OP #3581361
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
OP #3703780
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..
Angehängte Dateien:
OP #3704444
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 ?
Gast #3704530
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.

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