Hallo alle miteinander, ich habe eine Hardwarestruktur aufgebaut die ihre prozessierten Ergebnisse in einem FIFO zwischenspeichert. Nun gilt es dieses FIFO mit Hilfe des NiosII Prozessors auszulesen. Hat jemand von euch Erfahrung mit dieser CPU. Wie lässt sich ein solches Interface (bestehend aus einem ReadEnable + ReadData[15:0] )am besten Realisieren ? Benutze momentan zwei PIO cores zum Generieren eines FifoReadEn Signals sowie zum anschliessend Einlesen der Daten (Ziemlicher Murks, funktioniert jedoch). Wie könnte man sowas besser machen, wie etwa mit Hilfe eines Avalon-Slaves !?! Mache meine ersten Gehversuche in der Welt der Softcore-Cpus und würde mich über Hilfe freuen. Schönes WE, Martin
Ja das schreit nach einem Avalon Slave, ist eigentlich ganz simpel. Hier ein Beispiel einer einfachen PIO.
1 | entity my_pio is |
2 | Port ( |
3 | clk : in std_logic; |
4 | reset : in std_logic; |
5 | address : in std_logic_vector(0 downto 0); |
6 | chipselect : in std_logic; |
7 | write : in std_logic; |
8 | writedata : in std_logic_vector(31 downto 0); |
9 | read : in std_logic; |
10 | readdata : out std_logic_vector(31 downto 0); |
11 | |
12 | pio_output : out std_logic_vectors(31 downto 0); |
13 | pio_input : in std_logic_vectors(31 downto 0) |
14 | );
|
15 | end my_pio; |
16 | |
17 | |
18 | architecture Behavioral of my_pio is |
19 | begin
|
20 | |
21 | process(clk) |
22 | begin
|
23 | if rising_edge(clk) then |
24 | |
25 | readdata <= pio_input; |
26 | |
27 | if chipselect = '1' and write = '1' then |
28 | if address(0) = '0' then |
29 | pio_output <= writedata; -- register 0 |
30 | else
|
31 | pio_output <= not writedata; -- register 1 |
32 | end if; |
33 | end if; |
34 | |
35 | end if; |
36 | end process; |
37 | |
38 | end Behavioral; |
Das solltest du im SOPC Builder importieren koennen (New Component...). Cheers, Roger
Hi Roger, vielen Dank für deinen Post. Das klappt super und schaut um Ecken besser aus wie meine 'Notlösung'. Gruss, Martin
Wo wir schon mal dabei sind hätte ich noch mal ein Frage. In Hinblick auf ein zukünftig anstehendes Design würde ich gerne einen NiosII einsetzen der mit möglichst geringer Latenz auf einen 'NiosII externen' onchip Dual-port Speicher zugreift und diesen Ausliest ? Gibt es zudem die Möglichkeit, dass eine Custom Instruction auf einen Avalon-Speicher zugreift ? Gruss, Martin
Die Latenz vom internen Speicher hast du immer, jedoch kannst du deinem Avalon Slave piplined oder burst transfers beibringen, womit du dann den Durchsatz etwas steigern kannst. Eine Custom Instruction kann nicht direkt auf den Avalon zugreifen. Im Prinzip waehre es moeglich, wenn auch nicht sehr elegant. Fragt sich was du durch die Custom Instruction gewinnst, meistens ist es besser das ganze als core einzubinden, ein solcher kann ja neben einem Avalon Slave auch einen Avalon Master enthalten. Cheers, Roger
Hallo, wollte gerade mal den von Roger geposteten Code ausprobieren, aber irgendwie haut es nicht so ganz hin. Mein Problem besteht schon bei der Generierung der Komponente im SOPC Builder. Nach dem Einladen des Codes im Component Editor habe ich Probleme die Signale mit ihrem Typ zu spezifizieren. Wäre klasse wenn jemand mal für die von Roger erstellte Komponente diese Einstellungen mal posten könnte. Danke, Dennis
Für clk + reset bekomme ich die Warning: Signal "clk"/reset has unknown type "export" Was gilt es hier einzustellen ?????? Die übrigen Signal habe ich als new_avalon_slave_0 deklariert. Dennis
clk + reset sind "Clock Sink". Und vergiss nicht bei new_avalon_slave_0 "Clock sink" auch dann anzugeben, damit AVALON-Interface weis, in welcher Clock-Domäne er sich befindet Kest
Hallo Kest, vielen Dank für den Hinweis! Klappt nun bestens. Warum muss eigentlich das reset signal ebenfalls als "clock sink" deklariert werden ??? Danke, Dennis
Hey, hätte noch mal eine Frage zur oberen Geschichte. Wenn ich wie Martin oben beschrieben ein FIFO Speicher auslesen möchte haut es mit dem zeitlichen Ablauf bei mir nicht ganz so hin: Nachdem das Read-Enable müsste ein Takt gewartet werden bevor das Ausgabeworts des FIFOs gelesen wird. Wenn ich so vorgehe wie oben beschrieben lese ich beim ersten Zugriff eine NULL aus und erst mit dem zweiten erhalte ich mein erwartetes Datenwort. Natürlich könnte man das jetzt dadurch lösen, dass ich mein FIFO im show-ahead mode arbeiten lasse. Mich würde jedoch interresieren wie ich das Avalon intern realisieren könnte. Vielen Dank, Dennis
Beim Avalon kannst Du Readlatancy einstellen, die stellst Du dann auf 2 ein, somit sind Deine Daten dann nach zwei Takten gültig. Ich, llerdings, mache alles komplett anders. Readlatancy ist bei mir immer 0. Dafür verwende ich aber auch readdatavalid - Signal, um dem Avalon zu signalisieren, wann die Daten dann tatsächlich gültig sind. Etwa so: process(clk) begin if rising_edge(clk) then as_readdatavalid <='0'; if as_chipselect = '1' and as_read = '1' then case as_address is when x"0" => as_readdata <= x"55"; as_readdata_valid <='1'; .... end if; end process; Dann darfst Du aber nicht vergessen, maximum Pending bytes (oder wie es heißt) auf mindestens 1 zu stellen (bekommst Du aber auch eine Warnung) Grüße, Kest
Hallo Kest, vielen Dank für deine Hinweise. Habe beide von dir beschriebenen Wege zum Laufen bekommen. Gruss, Dennis
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.