Forum: FPGA, VHDL & Co. CPU in VHDL designen


von Max M. (maxmicr)


Lesenswert?

Ich würde gerne eine kleine CPU (ohne Interrupt, nur Befehle abarbeiten) 
in VHDL auf einem FPGA (Cyclone II) erstellen, dazu hätte ich ein paar 
Fragen:

1. Ich hab hier ein ganz gutes Dokument 
(http://users.etech.haw-hamburg.de/users/Schwarz/En/Publications/Sample/Chap8.pdf) 
gefunden, dass den Aufbau einer CPU in VHDL beschreibt, auf Seite 10 & 
11 wird der Aufbau der ALU verdeutlicht, da gibt es ein
1
generic (DEL: time:=10ns);

später bei der architecture-Definition befindet sich hinter den 
Verarbeitungsschritten ein
1
after DEL;

Warum macht man das bzw. benötigt man das zwingend?

2. Wenn ich einen Befehl "Lade Wert von Adresse xyz" mit einer 
Befehlswortbreite von 8-Bit (4-Bit Opcode und 4-Bit Daten), ich aber 
einen 8-bit breiten Adressbus habe (weil ich 256Byte adressieren können 
möchte), wie kann ich dann in 4-bit Daten trotzdem 8-bit Adressen 
adressieren?

Oder macht es mehr Sinn, die Befehlsbreite auf 12-Bit zu erhöhen (also 
4-Bit Opcode und 8-bit Daten)?

: Bearbeitet durch User
von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

Max M. schrieb:
> auf Seite 10 &
> 11 wird der Aufbau der ALU verdeutlicht, da gibt es ein
> generic (DEL: time:=10ns);
>
> später bei der architecture-Definition befindet sich hinter den
> Verarbeitungsschritten ein
> after DEL;
>
> Warum macht man das bzw. benötigt man das zwingend?

Ohne Gewähr: Das ist nur für die Simulation. Wird unter 8.3.2 näher 
erklärt.

von Guest (Gast)


Lesenswert?

Max M. schrieb:
> Warum macht man das bzw. benötigt man das zwingend?

Die Zuweisung erfolgt dann halt erst nach einer gewissen Zeit. Wo das 
synthesefähig sein soll ist mir ein Rätsel.

Max M. schrieb:
> 2. Wenn ich einen Befehl "Lade Wert von Adresse xyz" mit einer
> Befehlswortbreite von 8-Bit (4-Bit Opcode und 4-Bit Daten), ich aber
> einen 8-bit breiten Adressbus habe (weil ich 256Byte adressieren können
> möchte), wie kann ich dann in 4-bit Daten trotzdem 8-bit Adressen
> adressieren?

Zum Beispiel indem du mit den 4 Bit nur ein Register adressierst in dem 
die eigentliche Adresse steht. Sinnvoll wäre es trotzdem, längere 
Instruktionen zuzulassen. Muss ja auch nicht jede Instruktion gleich 
lang sein.

von Martin S. (strubi)


Lesenswert?

Max M. schrieb:
> Warum macht man das bzw. benötigt man das zwingend?
>

Wurde ja schon erklärt, aber der Gag daran ist wohl, dass für den 
Anfänger die Wellenformen etwas expliziter (im Sinne der Abtaktung von 
Signalen) werden. Aber daran gewöhnen sollte man sich nicht :-)

> 2. Wenn ich einen Befehl "Lade Wert von Adresse xyz" mit einer
> Befehlswortbreite von 8-Bit (4-Bit Opcode und 4-Bit Daten), ich aber
> einen 8-bit breiten Adressbus habe (weil ich 256Byte adressieren können
> möchte), wie kann ich dann in 4-bit Daten trotzdem 8-bit Adressen
> adressieren?

Na mit einem H/L-Bit, d.h. sowas wie
1
0x94 ; lade high nibble mit 0x4
2
0x1c ; lade low nibble mit 0xc

12Bit-Opcodes? Denk mal drüber nach, wie das im Speicher organisiert 
werden müsste (Stichwörter: effektive Speicherzellen-Grösse versus 
Pack-Logik-Aufwand).

von C. A. Rotwang (Gast)


Lesenswert?

Max M. schrieb:

> Oder macht es mehr Sinn, die Befehlsbreite auf 12-Bit zu erhöhen (also
> 4-Bit Opcode und 8-bit Daten)?

Ein Befehlswort sieht bei Load store maschinen gern so aus:


Instruction - SRC-Addr - Dest-Addr

Nur eine Addresse zu verwenden impliziert einen Akkumulator als 
Standard-Dest, das will keiner mehr.
Schau mal hier im Forum nach piBla - das ist ein VHDL Nachbau der 8bit 
CPU picoblaze, da ist das instruction word 16bit lang und wie folgt 
eingeteilt:
1
84     --parts within instructionword
2
85     --the coded operation (sometimes 6, sometimes 8 bit long, seldom longer
3
86     alias codewrd_6b : t_codewrd6b is instruction(17 downto 12);
4
87     alias codewrd_8b : t_codewrd8b is instruction(17 downto 10);
5
88     
6
89     --immediate (direct) operand - constant
7
90     alias immediate  : std_logic_vector(7 downto 0) is instruction(7 downto 0);
8
91   
9
92     --adress of destination register
10
93     alias reg_Sx : std_logic_vector(3 downto 0) is instruction(11 downto 8);
11
94    --address of source register 
12
95    alias reg_Sy : std_logic_vector(3 downto 0) is instruction(7 downto 4);

https://www.mikrocontroller.net/articles/PiBla
https://www.mikrocontroller.net/svnbrowser/pibla/00_hw/src/

von Max M. (maxmicr)


Lesenswert?

C. A. Rotwang schrieb:
> Nur eine Addresse zu verwenden impliziert einen Akkumulator als
> Standard-Dest, das will keiner mehr.

Ja so hatte ich das eigentlich vor, habs so auch im Studium gelernt. Mir 
ist klar, dass die CPU keiner braucht, soll ja nur für mich zum Spielen 
sein.

Mir erscheint das irgendwie simpler, es mit einem Akkumulator zu machen.
Es sollte wirklich sehr einfach sein für den Anfang, da ich mich nicht 
mit VHDL auskenne und mit CPU Design auch nicht wirklich.

Ich hab mir 16 Befehle ausgedacht die imho erstmal reichen, von daher 
würde ich den Opcode 4-bit lang machen

C. A. Rotwang schrieb:
> da ist das instruction word 16bit lang und wie folgt
> eingeteilt:

Ich hab leider auch keinen Plan, wie ich die Größe des Operanden mit 
VHDL dynamisch einteilen kann, also z.B. dass der Befehl
1
LD 0xAF ;lade Daten von Adresse 0xAF in den Akkumulator

2-Bit groß ist und ich dann den vollen Adressraum ansprechen kann, dann 
reichen 10-bit Wortbreite, oder?

Das Problem ist nur, dass ich aktuell 5 Befehle habe, die als Operanden 
eine Adresse haben (Jump wenn Carry, Jump wenn Zero, Jump wenn Equal, 
Jump zu Adresse), die passen nicht in 2-bit rein :(

Irgendwie komplizierter als ich dachte.

: Bearbeitet durch User
von Guest (Gast)


Lesenswert?

Max M. schrieb:
> Das Problem ist nur, dass ich aktuell 5 Befehle habe, die als Operanden
> eine Adresse haben (Jump wenn Carry, Jump wenn Zero, Jump wenn Equal,
> Jump zu Adresse), die passen nicht in 2-bit rein :(

Jetzt weißt du, wieso üblicherweise OPCodes mehr als 2 Bit haben...
Ist doch eigentlich ganz simpel. Entweder nimmst du eine fixe länge und 
lebst damit, am besten sowas wie 16 Bit. Oder du definierst OPCode 
Gruppen, lässt dann zB. die ersten 4 Bit die erste Gruppenhierarchie 
bestimmen, gehst dann zur nächsten usw. Dann kannst du verschiedene 
längen haben, je nach dem in welcher Gruppe ein Befehl ist eben. Dafür 
wird halt der Decoder aufwändiger.

von C. A. Rotwang (Gast)


Lesenswert?

Korrektur das Picoblaze Intructionword ist 18bit breit, beim AVR sind es 
16.

Die Arbeit mit Registerfile statt akku ist nicht viel anders, für das 
Registerfile baut man sich einen Dual Port RAM aus distributed Mem, legt 
die addressbits aus dem Instruction word an den adressbus des dualPort 
rams und muxt dann nur noch den Datenbus abhängig vom Instructionword 
(Scratchpad-Ram, IO, Register). Der Speicher den der Pibla addressieren 
kann ist aber sehr klein 1k glaube ich.

Am besten du mals erst mal ein Blockbild der Datenpfade mit 
Multiplexern, dann erklärt sich das fast von selbst. Und schau mal in 
die Doku von Picoblaze und dessen Vürgänger KCPSM:
http://www.mcu-turkey.com/wp-content/uploads/2012/12/picoblaze_Architec.jpg
http://3.bp.blogspot.com/-tL-oQJMDhQI/UXMt4lGYtxI/AAAAAAAAATc/pSKvyAKdWhw/s1600/core.jpg
https://www.xilinx.com/support/documentation/ip_documentation/ug129.pdf 
Im Anhang D ab S. 115 ist gezeigt welche bedeutung die einzelnen bits 
des Instruction words haben.

von Josef G. (bome) Benutzerseite


Lesenswert?

Max M. schrieb:
> ohne Interrupt,

Max M. schrieb:
> irgendwie simpler, es mit einem Akkumulator zu machen.

Kennst du das schon?
8bit-CPU: bo8

von Edi M. (Gast)


Lesenswert?

Naja, diese 8bit CPU ist vielleicht ein wenig schlecht handhabbar für 
jemanden, der nach einer einfachen Implementierung sucht.

Wer es etwa dicker mag, kann sich mal Renes MAIS anschauen:
Beitrag "Mais-CPU veröffentlicht 32bit Softcore"

Ich hatte mit dem Entwickler schon Kontakt und mir das auch angesehen, 
ist allerdings für meine privaten Zwecke etwas zu speziell, wenn auch 
beachtenswert.

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Guest schrieb:
> Oder du definierst OPCode
> Gruppen, lässt dann zB. die ersten 4 Bit die erste Gruppenhierarchie
> bestimmen, gehst dann zur nächsten usw. Dann kannst du verschiedene
> längen haben, je nach dem in welcher Gruppe ein Befehl ist eben. Dafür
> wird halt der Decoder aufwändiger.

Macht das Sinn, was ich hier gemacht habe (siehe Anhang)?

C. A. Rotwang schrieb:
> Am besten du mals erst mal ein Blockbild der Datenpfade mit
> Multiplexern, dann erklärt sich das fast von selbst.

Das werde ich machen, danke.

von C. A. Rotwang (Gast)


Lesenswert?

Max M. schrieb:

> Macht das Sinn, was ich hier gemacht habe (siehe Anhang)?

Hm, da fehlt meines Erachtens das wesentliche -> die Unterteilung in 
Befehl (Operation) und Daten (Operanden), siehe Wikipedia 
https://en.wikipedia.org/wiki/Instruction_set_architecture#Parts_of_an_instruction

Das  Ganze als Single-word instruction set aufzuziehen ist m.E. sehr 
Sinnvoll, und im FPGA wenn man die interne RAM-Blöcke nutz die sich zu 
unterschiedliche Busbreiten konfigurieren lassen (16/18/20/24 bit) 
einfach realisierbar. Bei Nutzung externer Speicher wird man bei 
"krummen Werten" (abseits von 8+n bits) schnell ein paar bits 
verschenken.

Es gibt ein paar Klassiker zum Thema CPU entwerfen, die finden sich in 
besseren Bibliotheken in der Abteilung Computer-Architektur. Meine 
Empfehlung: ISBN: 348659190 auch die älteren Auflagen aus dem vorherigen 
Jahrtausend sind m.E. recht brauchbar.

Bücher , die direkt mit der FPGA-Implementierung beginnen halte ich eher 
ungeeignet - bevor die erste Codezeile geschrieben wird, sollte man sich 
einige Gedanken zu Realisierung und Architektur machen. Beispielsweise 
sollte klar sein wie man den/die Arbeitsspeicher verschaltet wenn man 
sich für Hatvard und gegen v. Neumann entscheidet.

von C. A. Rotwang (Gast)


Lesenswert?

C. A. Rotwang schrieb:

> Es gibt ein paar Klassiker zum Thema CPU entwerfen, die finden sich in
> besseren Bibliotheken in der Abteilung Computer-Architektur. Meine
> Empfehlung: ISBN: 348659190 auch die älteren Auflagen aus dem vorherigen
> Jahrtausend sind m.E. recht brauchbar.

Sorry, Fehler in der ISBN, gemeint ist das: 
https://www.amazon.de/Rechnerorganisation-Rechnerentwurf-Die-Hardware-Software-Schnittstelle/dp/3486591908

von Max M. (maxmicr)


Lesenswert?

C. A. Rotwang schrieb:
> Hm, da fehlt meines Erachtens das wesentliche -> die Unterteilung in
> Befehl (Operation) und Daten (Operanden), siehe Wikipedia

Der graue Bereich sollte die Daten sein :)

C. A. Rotwang schrieb:
> bevor die erste Codezeile geschrieben wird, sollte man sich
> einige Gedanken zu Realisierung und Architektur machen. Beispielsweise
> sollte klar sein wie man den/die Arbeitsspeicher verschaltet wenn man
> sich für Hatvard und gegen v. Neumann entscheidet.

Das sehe ich auch so

C. A. Rotwang schrieb:
> Bei Nutzung externer Speicher wird man bei
> "krummen Werten" (abseits von 8+n bits) schnell ein paar bits
> verschenken.

Also sind 11-Bit eher ungeeignet als Wortbreite?

C. A. Rotwang schrieb:
> Sorry, Fehler in der ISBN, gemeint ist das:

Danke für den Tipp

von Strubi (Gast)


Lesenswert?

Moin,

wenn du keinen Systemprozessor bauen willst und mit wenig Resourcen 
auskommen musst, i.e. Distributed RAM nutzt, spricht nix gegen höhere 
Bitbreite, und beim BlockRAM sind die Breiten typischerweise in 
9-Bit-Einheiten organisiert.
Fang doch einfach mal an. Es ist ja zum Lernen, da musst du dir sowieso 
die Nase blutig rennen.
Zum Studium sollte man sich sicher mal den 8051, PDP11 und MIPS 
reinziehen. So richtig kompakt wäre dann noch die ZPU (8 bit opcodes, 32 
bit Datenbreite) oder gar die J1 (pure Stack-Maschine). Zu MIPS findet 
man an amerikanischen Unis ne Menge, z.B. 
http://db.cs.duke.edu/courses/cps104/spring10/lectures/6up-lecture05.pdf
Bisschen mehr advanced ist das RISC-V Zeug.

Zu erwähnen letztlich noch: Um nicht von Anfang an zuviel verpropfende 
Logik zu entwerfen, kann man anfangs die ganze State-Machine mit 
Pseudo-Opcodes einer deutlich höheren Breite designen und anschliessend 
einen Interpreter für die 8 bit opcodes vorschalten. Vorsehen muss man 
nur einen "Wait/Stall"-Zustand. Und dann tut man sich dasselbe ev. 
nochmal mit Pipelining an.

Und wenn du dann DOCH mal noch Exception/IRQ Handling einbauen willst, 
musst du allenfalls nur die interne FSM aufbohren oder neu machen.

VHDL ist allerdings beim CPU-Design eine rechte Bremse. Wenn du Python 
kannst, sparst du mit MyHDL massiv Zeit in der funktionalen Entwicklung, 
der Schritt zur Synthese ist dann klein. Die Risc-V-Dinger sind in 
Chisel entworfen, aber ob man sich das antun will...

von Max M. (maxmicr)


Lesenswert?

Strubi schrieb:
> Wenn du Python
> kannst, sparst du mit MyHDL massiv Zeit in der funktionalen Entwicklung

Ich kann zwar (etwas) Python, aber ich hab mir gedacht, ich arbeite mich 
in die Standard-Tools ein, und die bieten eben (zumindest Quartus II) 
nur VHDL und Verilog, außerdem mach ich das zwar aus Spaß aber ich 
wollte das auch in meine Bewerbung für eine eventuelle 
Werkstudentenstelle einbauen (falls ich da nicht zu optimistisch bin), 
ich weiß nicht, wie weit MyHDL verbreitet ist.

Strubi schrieb:
> Fang doch einfach mal an. Es ist ja zum Lernen, da musst du dir sowieso
> die Nase blutig rennen.

Ja, mach ich jetzt auch. Ich hab das FPGA hier liegen und Quartus II 
offen aber in meinem Kopf herrscht noch rechtes Wirrwarr, ich mach 
erstmal so einen Blockplan.

: Bearbeitet durch User
von Christoph db1uq K. (christoph_kessler)


Lesenswert?

http://opencores.org/projects
da gibts haufenweise Projekte zum Thema

von chris (Gast)


Lesenswert?

Mich würde mal ein Link auf die kleinst-mögliche oder einfachste CPU in 
VHDL interssieren.

von Alexander D. (abadu)


Lesenswert?

Die kleinstmögliche CPU, die ich kenne findet man bei GitHub hier: 
https://github.com/cpldcpu/MCPU . Die ist nicht nur in VHDL und Verilog 
beschrieben, sondern ein Simulator und ein Assembler in C werden auch 
mitgeliefert.

von chris (Gast)


Lesenswert?

>Die kleinstmögliche CPU, die ich kenne
Sehr schön, nur 4 Instructionen.
Ich hatte vor einiger Zeit mal mit dem Nibbler ein wenig herumprobiert:
https://www.bigmessowires.com/nibbler/
Dabei ist mir aufgefallen, dass das größte Hindernis für eine bestimmte 
Klasse von Programmen ( z.B. ein Forth Interpreter ) das fehlen von 
relative Adressierungen ist. Die braucht man unbedingt, wenn man 
Software-Stacks programmieren will.

von Max M. (maxmicr)


Lesenswert?

Hab ich dann einen Flash mit 256 x 11 Program Memory und einen RAM oder 
sind Befehle und RAM in einem Speicher?
Also was lässt sich einfacher auf einem FPGA implementieren?

von Guest (Gast)


Lesenswert?

Max M. schrieb:
> Also was lässt sich einfacher auf einem FPGA implementieren?

Lass hören, wenn dus geschafft hast, Flash in FPGA Fabric zu 
implementieren. Moderne CPUs sind harvard Architekturen, deren Cache 
Controller auf einen gemeinsamen Speicherbus zugreifen. Sprich, der Kern 
sieht getrennte Programm- und Datenspeicher, in Wirklichkeit liegt aber 
alles in einem großen RAM.

Was für deine Anwendung (welche ist das überhaupt?) sinnvoll ist musst 
du selber wissen.

von C. A. Rotwang (Gast)


Lesenswert?

Max M. schrieb:
> Strubi schrieb:
>> Fang doch einfach mal an. Es ist ja zum Lernen, da musst du dir sowieso
>> die Nase blutig rennen.
>
> Ja, mach ich jetzt auch. Ich hab das FPGA hier liegen und Quartus II
> offen aber in meinem Kopf herrscht noch rechtes Wirrwarr, ich mach
> erstmal so einen Blockplan.

Du hast sicher nicht nur den nackten FPGA sondern ein Board mit FPGA und 
anderen Chips. Leg mal fest was deine erste CPU von dem Board mit nutzen 
soll. Soll der Speicher auf dem Board (wahrscheinlich DDR-RAM, SRAM 
und7oderFlash) der Arbeitsspeicher für die CPU sein? IMHO ist es für den 
Start einfacher, den Board Speicher nicht einzubinden, sondern allein 
die Speicher-blöcke auf dem FPGA als Programm und Arbeitsspeicher zu 
nutzen.


> Fang doch einfach mal an. Es ist ja zum Lernen, da musst du dir sowieso
> die Nase blutig rennen.

Anfangen ja , losstürzen nein. Halt Dich nicht zu lang mit dem Entwurf 
des Instruction sets auf, es sollte schon lang genug sein um einen 8 bit 
Directoperanden mitaufzunehem oder eine längere (?10bit?) 
direkt-Sprungaddresse (dann kannst du problemlos 1024 Zeilen Code 
benutzen). Falls dir Registerbank zu kompliziert ist dann bau fürs erste 
ne Akku-Maschine.
Aufbohren würde ich  die erste CPU später nicht, sondern eine zweite 
from the scratch beginnen. So ne einfache CPU ist nicht übermäßig viel 
in VHDL (ca. 500 zeilen), man muss sich auch nicht viel mit 
paramtrisierbaren/skalierbaren Eigenschaften (Generics für Größe 
Arbeits-Befehlsspreicher) oder Re-Use rumschlagen. Das kann mensch bei 
CPU Nr. 3 machen. Und die gegen CPU #1 um die Wette laufen lassen um 
Optimierungsbedarf für CPU #4 zu erkennen.

> Also sind 11-Bit eher ungeeignet als Wortbreite?

Sie werden einfach nicht ausreichen für Op-code und Directoperanden. Ich 
würde auf mindestens 16 bit gehen. Wenns 15,17,18 bit sinds ists fürs 
erste auch egal, da verschwendet mal halt ein paar bits. Wenn du den 
fpga-externen Speicher nutzen willst solltest du dich natürlich an 
dessen Busbreite orientieren. Aber das würde ich eher nicht für CPU #1 
vorsehen.

von chris (Gast)


Lesenswert?

Mich wundert es ja immer, dass so viele Leute eine CPU auf dem FPGA 
implementieren wollen. Mich interessiert das zwar selber, aber weniger, 
weil ich es so verwenden will, sondern eher aus akademischem Interesse.
Ansonsten gibt es FPGAs mit integrierter CPU wie das Zynq oder die 
Möglichkeit, eine MCU mit einer FPGA zu kombinieren.

Das BlackIce MyStorm finde ich ganz interessant:
http://hamsterworks.co.nz/mediawiki/index.php/MyStorm_Blackice

Beitrag #5155502 wurde vom Autor gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Max M. schrieb:
> später bei der architecture-Definition befindet sich hinter den
> Verarbeitungsschritten einafter DEL;
> Warum macht man das
Damit der Lehrer dem Schüler schön das vorher und nachher zeigen kann.

> bzw. benötigt man das zwingend?
Meine Empfehlung: niemals symbolische Delays. Die dort angenommen Zeiten 
passen eh' nicht zur Hardware und können seltsame Effekte hervorrufen.
Siehe den Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen" und die 
darin enthaltenen Links.

Zum Thema CPU auf dem FPGA: die Arbeit führt letztlich in eine 
Sackgasse,  weil du für deine CPU sowieso keinen Assembler oder Compiler 
hast.
Ich habe auch noch nie eine gebaut, aber stattdessen schon einige 
"schlaue" Peripheriemodule, die auch programmierbar sind, und ihre 
Prozessabarbeitung selber steuern. Man könnte diese Blöcke 
"Coprozessoren" nennen.

: Bearbeitet durch Moderator
Beitrag #5155508 wurde von einem Moderator gelöscht.
von Max M. (maxmicr)


Lesenswert?

Lothar M. schrieb:
> weil du für deine CPU sowieso keinen Assembler oder Compiler
> hast.

Ich hab vor, einen Assembler dafür zu schreiben, der dann VHDL-Code 
erzeugt und ich das nur per Copy-Paste in Cyclone II übernehme, 
wahrscheinlich stelle ich mir das gerade zu einfach vor.

C. A. Rotwang schrieb:
> sondern allein
> die Speicher-blöcke auf dem FPGA als Programm und Arbeitsspeicher zu
> nutzen.

Okay, dann mache ich das.

C. A. Rotwang schrieb:
> Sie werden einfach nicht ausreichen für Op-code und Directoperanden.

Wenn es sich um einen 4-Bit Prozessor handelt? Also der Akku hat 4-bit 
und die ALU kann 4-bit Operationen verarbeiten.

C. A. Rotwang schrieb:
> Du hast sicher nicht nur den nackten FPGA sondern ein Board mit FPGA und
> anderen Chips.

Ja, das stimmt. Es ist ein Altera DE1 mit externem SRAM, SDRAM und 
Flash.

Guest schrieb:
> (welche ist das überhaupt?)

Einfach rumprobieren :D

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Ich hab mal versuch, ein Blockbild zu malen, wie ich mir das ungefähr 
vorstelle.

Was ich nicht ganz verstehe:

Bei einem Load-Befehl (also Daten aus dem RAM in das A-Register laden), 
muss in einem Takt der Program Counter auf den Wert der Instruktion 
gestellt und das Flag im Steuerwerk für "Es ist ein Load Befehl" gesetzt 
werden. Dann muss der RAM aber noch mit der neuen PC-Adresse 
aktualisiert werden, so dass er die Daten richtig an das A-Register 
weitergibt, und schließlich muss das A-Register die Daten noch 
übernehmen - klappt das überhaupt?

Edit: Okay das ist kompletter Blödsinn, bei einem Load/Store sollte der 
PC gar nichts machen -.-

Edit_2: Eher so?

: Bearbeitet durch User
von Alexander D. (abadu)


Lesenswert?

Um das zusammenzufassen: Deine Cpu enthält den Akkumulator AC, den 
Befehlszähler PC und das Befehlsregister IR. Die Register sind jeweils 
16 Bit lang und beim Befehlsregister werden 4 Bits als Opcode verwendet 
und 12 Bits als Adresse. Zum Speicher geht der Adressbus und der 
Datenbus

Die Ausführung des Load-Befehls geht dann so:
1
    PC auf den Adressbus geben
2
    Datenbus vom Speicher in das IR übertragen
3
    Funktion im IR dekodieren    
4
    ...
5
Wenn Load-Befehl
6
    12 Bits aus dem IR auf den Adressbus geben
7
    Datenbus vom Speicher in den AC übertragen
8
    zum Anfang
9
Wenn Store-Befehl
10
    12 Bits aus dem IR auf den Adressbus geben
11
    AC auf den Datenbus zum Speicher geben
12
    zum Anfang
13
Wenn Add-Befehl
14
    12 Bits aus dem IR auf den Adressbus geben
15
    AC auf AC + Datenbus vom Speicher setzen
16
    ...

Einen fertigen Befehlssatz für eine ähnliche Cpu findest Du bei
https://www.pcengines.ch/toy2.htm
Dort wird auf einen Artikel in der Byte 01/87 verwiesen, den kann man 
bei archive.org herunterladen.

von Max M. (maxmicr)


Lesenswert?

Alexander D. schrieb:
> Datenbus vom Speicher in das IR übertragen
>     Funktion im IR dekodieren

Warum geht das nicht in einem Schritt? Also die Instruktionen direkt 
dekodieren?

von Cyberpunk (Gast)


Lesenswert?

Lothar M. schrieb:
> Zum Thema CPU auf dem FPGA: die Arbeit führt letztlich in eine
> Sackgasse,  weil du für deine CPU sowieso keinen Assembler oder Compiler
> hast.

Hat jemand hier schon mal versucht ein LLVM Backend zu schreiben? Ich 
hab mal ein paar Tutorials und Anleitungen dazu angeschaut, sieht 
eigentlich machbar aus, auch wenns natürlich viel Arbeit ist.

Leitfaden:
https://llvm.org/docs/WritingAnLLVMBackend.html

Kleine Präsentation als Überblick:
https://llvm.org/devmtg/2014-04/PDFs/Talks/Building%20an%20LLVM%20backend.pdf

Beschreibung/Dokumentation eines kompletten Backends für einen Softcore:
http://jonathan2251.github.io/lbd/TutorialLLVMBackendCpu0.pdf

Ein C Compiler wäre damit locker drin, sogar C++.

von Alexander D. (abadu)


Lesenswert?

Max M. schrieb:
> Warum geht das nicht in einem Schritt? Also die Instruktionen direkt
> dekodieren?

Das Dekodieren des Befehls kann natürlich nur mit einigen Logikgattern 
geschehen und nicht in einem eigenen Zustand. Trotzdem wird ein 
Load-Befehl in zwei Schritten ausgeführt, weil man zwei Speicherzugriffe 
benötigt. Mit dem ersten Speicherzugriff holt man den Befehl und die 
Adresse für den Load-Befehl. Diese Adresse muss man zwischenspeichern, 
da sie beim zweiten Speicherzugriff für die Daten des Load-Befehls 
benötigt werden.

Das sieht man schön bei der im ersten Beitrag von mir erwähnten MCPU in 
der Datei "tb02cpu2.vhd". Die Ausführung erfolgt dort auch in zwei 
Schritten und gesteuert wird das über einen endlichen Automaten, der für 
jeden Schritt und jeden Befehl einen eigenen Zustand hat.

Das alles lässt sich natürlich mit Pipelining und einer 
Harvard-Architektur beschleunigen.

von Edi M. (Gast)


Lesenswert?

Alexander D. schrieb:
> Das alles lässt sich natürlich mit Pipelining und einer
> Harvard-Architektur beschleunigen.

Zu dem Thema würden mich Beispiele oder Literaturtipss interessieren.

von C. A. Rotwang (Gast)


Lesenswert?

Alexander D. schrieb:
> Max M. schrieb:
>> Warum geht das nicht in einem Schritt? Also die Instruktionen direkt
>> dekodieren?
>
> Das Dekodieren des Befehls kann natürlich nur mit einigen Logikgattern
> geschehen und nicht in einem eigenen Zustand. Trotzdem wird ein
> Load-Befehl in zwei Schritten ausgeführt, weil man zwei Speicherzugriffe
> benötigt. Mit dem ersten Speicherzugriff holt man den Befehl und die
> Adresse für den Load-Befehl. Diese Adresse muss man zwischenspeichern,
> da sie beim zweiten Speicherzugriff für die Daten des Load-Befehls
> benötigt werden.
> Das alles lässt sich natürlich mit Pipelining und einer
> Harvard-Architektur beschleunigen.

Nicht ganz , Havard beschleunigt nicht diesen doppelten Speicherzugriff 
sondern überführt ihn in zwei einzelne Zugriffe, weil es zwei getrennte 
Speicher für Befehle und Daten hat.

Man kann auch auf einen Datenspeicher komplett verzichten und dafür mit 
einem großen Register-file arbeiten, da gabs mal von Atmel vor 
Jahrzehnten was. Für Kaffemaschine reicht das.

Direktes Dekodieren funktioniert, siehe 
https://www.mikrocontroller.net/articles/PiBla

von Alexander D. (abadu)


Lesenswert?

Cyberpunk schrieb:
> Hat jemand hier schon mal versucht ein LLVM Backend zu schreiben?

Es gibt auch weitere Ansätze um die Erstellung der Hardware und Software 
zu beschleunigen. ArchC http://www.archc.org/doc.html versucht das zu 
automatisieren. Aus der Beschreibung des Prozessors werden ein 
angepasster GCC mit Assembler und Simulator erzeugt. So wie ich das 
verstanden habe, sind die Zielarchitekturen begrenzt.

von Max M. (maxmicr)


Lesenswert?

Wenn ich eine CPU in VHDL erstelle, ist das dann am Besten, wenn man für 
jede Komponente (ALU, Instruktionsregister, Program Counter ...) eine 
eigene Datei erstellt und die dann in einer Datei ("Entity" in Quartus 
II) alles verknüpft?

Wie erstelle ich in VHDL einen Bus, der 2 oder mehr Komponenten 
verbindet, es gibt die signal Bezeichnung, aber wie mache ich 
deutlich, dass es sich um das selbe Signal in zwei Komponenten handelt?

: Bearbeitet durch User
von Martin S. (strubi)


Lesenswert?

Cyberpunk schrieb:
> Hat jemand hier schon mal versucht ein LLVM Backend zu schreiben? Ich
> hab mal ein paar Tutorials und Anleitungen dazu angeschaut, sieht
> eigentlich machbar aus, auch wenns natürlich viel Arbeit ist.

Ja, hab ich. Für ein Community-Projekt macht es auch Sinn, aber wenn man 
als einzelner produktiv sein möchte, ist der Aufwand des Unterhalts doch 
zu gross. Für einfache DSP-Pipelines braucht/will man kein C und für 
Systemprozessoren greift man doch aus pragmatischen Gründen zu den 
GNU-Tools. Auf dem FPGA lässt sich alles wunderbar kombinieren.

Am elegantesten geht es IMHO in Python/MyHDL, da kann man aus dem 
grossen Regresstest-Skript alle benötigten Module (Hardware-Design, 
Assembler, usw) per import aufrufen und seine Testcases integrieren. 
Natürlich kann man da auch GCC/LLVM aufrufen.

C. A. Rotwang schrieb:
> Nicht ganz , Havard beschleunigt nicht diesen doppelten Speicherzugriff
> sondern überführt ihn in zwei einzelne Zugriffe, weil es zwei getrennte
> Speicher für Befehle und Daten hat.

Das liest sich etwas missverständlich. Es sind ja typischerweise 
parallel ablaufende Zugriffe, insofern schon schneller, wenn die 
Archtektur es kann (wie ein m56k).

Max M. schrieb:
> Wie erstelle ich in VHDL einen Bus, der 2 oder mehr Komponenten
> verbindet, es gibt die signal Bezeichnung, aber wie mache ich
> deutlich, dass es sich um das selbe Signal in zwei Komponenten handelt?

Du verbindest deine Komponenten einfach eine Ebene höher mit dem 
eindeutig benannten Signal, mehr deutlichermachen tust du da nicht. Hast 
du dir Wishbone schon mal angesehen?

von Cyberpunk (Gast)


Lesenswert?

E. M. schrieb:
> Alexander D. schrieb:
>> Das alles lässt sich natürlich mit Pipelining und einer
>> Harvard-Architektur beschleunigen.
>
> Zu dem Thema würden mich Beispiele oder Literaturtipss interessieren.

Wie wärs mit "Rechneraufbau und Rechnerarchitektur" von Axel Böttcher 
aus dem Springer Verlag? Hab mich ein bisschen eingelesen und mein 
Wissen wieder aufgefrischt vom Studium. Finde es eigentlich ganz gut als 
Grundlage.

Alexander D. schrieb:
> Cyberpunk schrieb:
>> Hat jemand hier schon mal versucht ein LLVM Backend zu schreiben?
>
> Es gibt auch weitere Ansätze um die Erstellung der Hardware und Software
> zu beschleunigen. ArchC http://www.archc.org/doc.html versucht das zu
> automatisieren. Aus der Beschreibung des Prozessors werden ein
> angepasster GCC mit Assembler und Simulator erzeugt. So wie ich das
> verstanden habe, sind die Zielarchitekturen begrenzt.

Interessanter Ansatz, werde ich mir demnächst mal genauer anschauen. 
Vielen Dank.

Martin S. schrieb:
> Cyberpunk schrieb:
>> Hat jemand hier schon mal versucht ein LLVM Backend zu schreiben? Ich
>> hab mal ein paar Tutorials und Anleitungen dazu angeschaut, sieht
>> eigentlich machbar aus, auch wenns natürlich viel Arbeit ist.
>
> Ja, hab ich. Für ein Community-Projekt macht es auch Sinn, aber wenn man
> als einzelner produktiv sein möchte, ist der Aufwand des Unterhalts doch
> zu gross. Für einfache DSP-Pipelines braucht/will man kein C und für
> Systemprozessoren greift man doch aus pragmatischen Gründen zu den
> GNU-Tools. Auf dem FPGA lässt sich alles wunderbar kombinieren.

Ja klar, interessant ist das ganze wirklich nur fürs Hobby. Ansonsten 
nimmt man lieber was fertiges und klatscht seine eigene Peripherie dran. 
Wie meinst du das mit den GNU-Tools? An binutils kommt man tatsächlich 
nicht drumrum (ld, gasm, objcopy...), aber so wie ich es mitbekommen 
habe ist ein LLVM-Backend einfacher Umzusetzen als so ein GCC-Backend 
und LLVM/Clang steht dem GCC kaum noch in etwas nach.

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Ich kapiers leider immer noch nicht, ich hab nun gestern mal versuch 
alle Komponenten zu erstellen.

Wie definiere ich denn einen Daten- bzw. Instruktionsbus in VHDL? Wie 
gesagt, ich hab mir das nun so überlegt, dass bei einem Load, Store oder 
Jump die ersten 8-Bit der Instruktion als Daten (Adresse) benutzt werden 
und ansonsten die ersten 4-Bit (da 4-Bit CPU).

Ich bin mir ebenfalls unsicher, wie ich den einzelnen Komponenten klar 
mache, ob es sich nun um einen Jump handelt bzw. wenn ja, um welchen? 
Ich glaube, ich hab viel zu viele Flags.

Außerdem bin ich verwirrt von den Datentypen in VHDL, ich wollte einen 
Shift-Left und Shift-Right Befehl implementieren, aber jetzt lese ich, 
dass das mit einem STD_LOGIC_VECTOR gar nicht geht sondern man einen 
bit_vector benötigt - was sind da die Unterschiede? Wenn ich den 
Datenbus als STD_LOGIC_VECTOR definiere (?), kann ich dan einen 
bit_vector überhaupt auf diesen Datenbus geben da es zwei 
unterschiedliche Datentypen sind?

Ich erwarte nicht, dass sich jemand den VHDL-Code ansieht, aber wäre 
nett wenn mir jemand Feedback dazu geben könnte.

von Martin S. (strubi)


Lesenswert?

Moin,

kurzes Feedback:

Schmeiss weg: 'use ieee.std_logic_arith.all;', das sollte man nur noch 
in Legacy-Compat-Modulen verwenden. Vielbehandelter Klassiker, nimm 
'ieee.numeric_std.all'.
'buffer' auch besser vermeiden, spendier lieber nen extra Output.

Vergiss auch bit_vector, wenn du beliebige shifts (nicht fix) machen 
willst, musst du einen Barrel-Shifter implementieren. Oder emulieren, 
wie es die kleine ZPU macht.

Womit simulierst du? Ich will ja nicht nerven, aber wenn du noch in den 
VHDL-Anfängen steckst, würde ich dir nochmals einen Anfang in MyHDL 
nahelegen. Wenn dann dein funktionales Modell sich selbst verifiziert 
hat (und damit musst du gleich als erstes parallel anfangen), ist der 
Schritt zur Ausgabe [toVHDL(entity, sig1, sig2)] nicht mehr so gross, 
und insgesamt sind deine Iterations-Zyklen deutlich kleiner als in pur 
VHDL und du kannst dich ganz auf deine Aufgabe fokussieren.

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


Lesenswert?

Max M. schrieb:
> ich hab nun gestern mal versuch alle Komponenten zu erstellen.
Wenn du jede Kombinatorik jedesmal in jedem Prozess taktest, dann wirst 
du bald Bekanntschaft mit dem Begriff "Latency" machen...
1
  process (CLK, IsJC, IsJZ, IsJP, IsJQ, QALU, ZALU, CALU)
2
  begin
3
    if(CLK'Event and CLK='0') then
In getakteten Prozessen hat nur der Takt etwas in der Senstivliste 
verloren. Denn nur nach einer Taktflanke muss der Prozess vom Simulator 
neu berechnet werden.
1
  process
2
  begin
3
    if(CLK'Event and CLK='0') then
Prozesse brauchen entweder eine Sensitivliste oder z.B. ein "wait until 
rising_edge(clk);"
Das wird dir der Synthesizer aber noch mitteilen.
1
  process
2
  begin
3
    if(CLK'Event and CLK='0') then
4
      if(CMD = b"0000") then                --Shift Right through Carry
5
        if(CONTENT(0) = '1') then
6
          CALU <= '1';
7
        else
8
          CALU <= '0';
9
        CONTENT <= CONTENT srl 1;
10
        end if;
11
      elsif(CMD = b"0001") then              --Shift Left through Carry
12
        if(CONTENT(3) = '1') then
13
          CALU <= '1';
14
        else
15
          CALU <= '0';
16
        end if;
17
        CONTENT <= CONTENT sll 1;
18
      elsif(CMD = b"0010") then              --Add
19
        if(CONTENT + DATA) > b"1111" then
20
          CALU <= '1';
21
        else
22
          CALU <= '0';
23
        end if;
Offenbar gefallen dir Prozesse und das if-elsif-endif, weil du sowas 
Ähnliches von prozeduralen Programmiersprachen her kennst. Es gibt aber 
gerade in VHDL hübsche nebenläufige Konstrukte (auf Englisch: concurrent 
assignments), die ganz ohne Prozess und Sensitivliste eine Kombinatorik 
beschreiben können.

Martin S. schrieb:
> 'buffer' auch besser vermeiden
Buffer sind eigentlich ein Kündigungsgrund, wenn sie lediglich zur 
Unterstützung der Schreibfaulheit im Stil von "Überaus praktisch, denn 
dann kann ich den Ausgang einlesen und spare mir lokale Signale!" 
verwendet werden.

: Bearbeitet durch Moderator
von Max M. (maxmicr)


Lesenswert?

Okay, ich seh schon - ich bin noch sehr am Anfang.

Martin S. schrieb:
> Ich will ja nicht nerven, aber wenn du noch in den
> VHDL-Anfängen steckst, würde ich dir nochmals einen Anfang in MyHDL
> nahelegen.

Wie schwer fällt dann später der Umstieg auf VHDL?

von Vancouver (Gast)


Lesenswert?

Also ich hatte von VHDL zu MyHDL eine gewisse Lernkurve zu durchlaufen 
(bzw. durchlaufe sie immernoch), und umgekehrt gilt sicher dasselbe. 
Beide Sprachen verwenden das gleiche Konzept der Modellierung auf 
RTL-Ebene, aber mit deutlich unterschiedlicher Syntax.
Wenn Du mit VHDL arbeiten willst, dann fang jetzt damit an. MyHDL 
erleichert die Simulation und die funktionale Verifikation, aber nicht 
das Design, und wenn Du Richtung FPGA-Design gehen willst, kommst Du an 
VHDL oder Verilog eh nicht vorbei.

Was ist eigentlich jetzt Sache mit MyHDL? Die letzte offizielle Versions 
gabs 2015 und auch die 1.0dev aus dem GIT-Repo ist nicht mehr ganz 
taufrisch. Ich will nicht hoffen, dass das Projekt einschläft, das wäre 
wirklich sehr schade.

von Martin S. (strubi)


Lesenswert?

Max M. schrieb:
> Okay, ich seh schon - ich bin noch sehr am Anfang.
>
> Martin S. schrieb:
>> Ich will ja nicht nerven, aber wenn du noch in den
>> VHDL-Anfängen steckst, würde ich dir nochmals einen Anfang in MyHDL
>> nahelegen.
>
> Wie schwer fällt dann später der Umstieg auf VHDL?

Ich würde nicht in "später" denken, der Workflow kann auch parallel 
verlaufen: Wenn alles im Simulator läuft, musst du u.U. für die Synthese 
nochmal von vorne loslegen. DAS nimmt dir MyHDL nicht ab. Ich habe mir 
anfangs die ausgegebene HDL immer noch mal separat angesehen, die muss 
man auch lesen können (oder nochmals simulieren). VHDL/Verilog nimmt 
dann die Rolle einer Transfersprache ein, du musst aber passenden 
Python-Code schreiben, der nah am VHDL-Paradigma ist.
Das mag scary klingen, aber unterm Strich spart die "doppelte Arbeit" 
Zeit.


Vancouver schrieb:
> Was ist eigentlich jetzt Sache mit MyHDL? Die letzte offizielle Versions
> gabs 2015 und auch die 1.0dev aus dem GIT-Repo ist nicht mehr ganz
> taufrisch. Ich will nicht hoffen, dass das Projekt einschläft, das wäre
> wirklich sehr schade.

Da schläft gar nix ein...MyHDL wird in seiner Community aktiv genutzt. 
Eigentlich ein gutes Zeichen, wenn nicht zuviele Aenderungen 
stattfinden. In den letzten Jahren tauchte hier grade mal ein Bug 
auf...der Rest sind Erweiterungen.
Ist nicht ganz so advokatisch wie bei VHDL, aber trotzdem genug 
konservativ..

von Josef G. (bome) Benutzerseite


Lesenswert?

Meine Meinung: Die Diskussion hier läuft schief.
Grund ist der Titel: CPU in VHDL designen.

CPU designen ist die eine Sache. Da geht es um Dinge
wie Festlegung der Breite des externen Adressbusses
und des externen Datenbusses, Festlegung der für den
Programmierer sichtbaren Register, Festlegung des
kompletten Befehlssatzes einschließlich der Dauer
der Befehle. Dann überlegt man sich einen Ringzähler,
welcher die Phasen der Befehlsausführung bereitstellt.
Man überlegt, welche zusätzlichen Register, welche
Datenpfade, welche Multiplexer, welche Funktionsnetze
(Addierer, Inkrementierer, ...) man braucht, um den
Befehlssatz mit dem angestrebten Zeitverhalten zu
realisieren. Schließlich erstellt man die Logikterme
für die Erzeugung der Steuersignale (Select-Signale
der Multiplexer, Write-Signale der Register, ...)
aus den Befehlscodes.

Die ganze Architektur dann in VHDL zu beschreiben,
ist eine andere Sache und kommt erst ganz am Schluss.

Jedenfalls hab ich es so gemacht. Ich wüsste
nicht, wie es anders gehen könnte.

: Bearbeitet durch User
von Vancouver (Gast)


Lesenswert?

@MartinS

"...MyHDL wird in seiner Community aktiv genutzt. "

Genutzt ja, aber auch weiterentwickelt? Zumindest Jan Decaluwe scheint 
momentan inaktiv zu sein. Abseits von Bugfixes gäbe es da noch Einiges 
zu verbessern, z.B. bei der Erzeugung von HDL-Code: hierachischer 
VHDL-Code mit einem Modul pro File, gleicher Funktionsumfang bei Verilog 
und VHDL, SystemVerilog-Backend usw. Und die Klimmzüge zur Konkatenation 
und Segmentierung von Bitvektoren verursachen auch erst mal 
Kopfschütteln (bis man verstanden hat, was dahinter steckt). Und noch 
einiges andere.

Leider muss man sagen, was nicht weiterentwickelt wird, stirbt 
irgendwann, da gibts ja genug Beispiele in der OpenSource-Community. Im 
Falle von MyHDL wäre das ein echter Verlust.

Wenn ich so darüber nachdenke, wäre es vielleicht gut, bei diesem 
Projekt mitzuarbeiten. Muss ich mal drüber meditieren.

von Martin S. (strubi)


Lesenswert?

Vancouver schrieb:
> Leider muss man sagen, was nicht weiterentwickelt wird, stirbt
> irgendwann, da gibts ja genug Beispiele in der OpenSource-Community. Im
> Falle von MyHDL wäre das ein echter Verlust.
>
> Wenn ich so darüber nachdenke, wäre es vielleicht gut, bei diesem
> Projekt mitzuarbeiten. Muss ich mal drüber meditieren.

Wenn keine bessere Alternative hinterm Horizont vorkommt, stirbt das 
Konzept für die damit produktiv arbeitenden sicher nicht.
MyHDL mag schon seine Quirks haben, und nicht alles ist elegant, aber es 
ist immerhin kein wüster Hack wie der Migen-Ansatz (der quasi schon tot 
ist).
MyHDL hat die kritische Masse schon erreicht und wird sicher so alt 
werden wie VHDL93.

Die Umsetzung von Hierarchien, wenn gewünscht, kann man sich leicht 
selber stricken. Dauert weniger lang als sich auf der MyHDL-Mailingliste 
die Diskussionen zu liefern..

von T.U.Darmstadt (Gast)


Lesenswert?

Martin S. schrieb:
> Die Umsetzung von Hierarchien, wenn gewünscht, kann man sich leicht
> selber stricken. Dauert weniger lang als sich auf der MyHDL-Mailingliste
> die Diskussionen zu liefern.

Wichtig ist, sowas auch beizutragen, um ein Projekt in die richtige 
Richtung zu schieben. Ansonsten verselbständigen sich die Leute in 
diesen Listendiskussionen und schieben es irgendwo hin, wo die 
Mittelmässigen es sehen und gerne hätten, denn die sind es, die in den 
Listen am Lautesten schreien.

Also am Besten Funktion bauen, unterlegen, convenience rein und dann 
raus damit als unumgängliches Paket, das Standards setzt. So habe Ich 
das beim embedded linux immer mal gemacht.

Dann übernehmen das Viele und es setzt sich automatisch durch.

Natürlich ist es das Problem Nummer 1, dass die wirklich Befähigten 
immer dick mit Arbeit zu sind und ihren hauptsächlichen output tagsüber 
in der Firma haben und meistens nichts davon herausgeben dürfen.

von Martin S. (strubi)


Lesenswert?

Thomas U. schrieb:
> Also am Besten Funktion bauen, unterlegen, convenience rein und dann
> raus damit als unumgängliches Paket, das Standards setzt. So habe Ich
> das beim embedded linux immer mal gemacht.

Gerade bei (embedded) linux habe ich es schon lange aufgegeben, 
irgendwelche Patches  oder Verbesserungen einzureichen, da der Overhead 
der Diskussionen mit teils wenig pragmatisch denkenden Coder-Egos 
einfach zu gross ist.
Solange es nur Patches sind und keine feindlichen Forks finde ich es 
ausreichend, sich einfach an die OpenSourciquette zu halten und den 
angepassten (L)GPL-Code irgendwo zu veröffentlichen oder die ganze 
Problematik so zu umgehen, dass keine Lizenzverletzungen vorliegen.

von S. R. (svenska)


Lesenswert?

Martin S. schrieb:
> Gerade bei (embedded) linux habe ich es schon lange aufgegeben,

...irgendwo geistert von mir noch ein Patch rum, der auf nem Router das 
WLAN aktiviert. War im Prinzip nur eine Liste, die auf bestimmten 
Geräten einen anders verdrahteten Pin fixt und wurde deswegen abgelehnt.

War mir dann aber auch egal, weil es auf meinem Gerät lief und m.W. 
sonst keiner Interesse hatte.

Beitrag #5178937 wurde von einem Moderator gelöscht.
Beitrag #5179294 wurde von einem Moderator gelöscht.
Beitrag #5179361 wurde von einem Moderator gelöscht.
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.