Forum: FPGA, VHDL & Co. FF mapping auf array


von Daniel R. (dan066)


Lesenswert?

Also ich hab ein array von vectoren und einige Werte in diesem array 
sollen immer gleich sein. Deswegen initialisiere ich das array gleich 
bei dessen Erstellung mit diesen Werten.
Einige Speicherfelder sollen jedoch den Inhalt separater Vectoren 
weiterleiten und dabei hätte ich gerne, dass das array an diesen Stellen 
nichts speichert. Ich will das array also als Adressraum benutzen, wobei 
hinter einigen Indizes der array-Speicher liegt und hinter anderen 
Eingänge oder Vectoren. Wie bekomm ich das hin? Ich hab schon versucht 
don't-cares bei der Initialisierung einzubauen, aber es werden trotzdem 
immer alle Speicherplätze erzeugt.

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


Lesenswert?

Du denkst viel zu abstrakt. Falls du aus deinem Design Hardware (FPGA 
oder ASIC) machen willst, dann musst du deine Aufgabe für die zur 
Verfügung stehenden Hardware beschreiben. Wenn die deine abstrakten 
Arrays (oder wie auch immer) nicht abbilden kann, sondern einen Speicher 
draus macht, dann hast du die falsche Hardware oder die falsche 
Beschreibung.

Man könnte natürlich alles auch mal an einem richtigen Beispiel 
anschauen. Dann müsste man nicht die Prosa oben entschlüsseln. Denn: 
lies deinen Post mal durch, als ob du dein Problem nicht kennen würdest. 
Wirst du schlau daraus?

Ich vermute, du brauchst einen einfachen Adressdecoder, der im tiefsten 
Inneren gar nichts mit Arrays oder Speichern zu tun hat...

von Daniel R. (dan066)


Lesenswert?

Ja verstehe;)
So sieht mein Problem am Beispiel aus:
1
constant ram_max : integer := 9;
2
type ram_type is array (0 to ram_max) of std_logic_vector (7 downto 0);                 
3
signal RAM : ram_type := (X"55", X"61", X"6c",X"75", X"65", X"20", X"35", X"3a", X"20", X"3f");
Das array dient dazu Bytes zu speichern, die zu einem Display übertragen 
werden. Alle Bytes bis auf das Letzte werden nie verändert. Nur RAM(9) 
wird durch ein von außen übertragenes Byte ersetzt.
1
 RAM(9) <= ram_val_cs;
Um FFs zu sparen möchte ich vermeiden, direkt das array oben zu 
benutzen, da ich den Wert von RAM(9) ja sowieso in ram_val_cs 
gespeichert hab.

Das ist wirklich nicht sehr hardwarenah gedacht, denn anschließend gehe 
ich mit einem counter das array durch gebe nacheinander alle array-Werte 
aus. Wie ließe sich diese Funktion anders erreichen? (Mit hardwarenaher 
Denkweise, wobei man genau weiß was aus dem Code synthetisiert wird)

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


Lesenswert?

Daniel R. schrieb:
> Um FFs zu sparen möchte ich vermeiden, direkt das array oben zu
> benutzen, da ich den Wert von RAM(9) ja sowieso in ram_val_cs
> gespeichert hab.
Du wirst einen Adressdecoder und einen Multiplexer brauchen. Ein Array 
in dieser Größe wird wahrscheinlich sowieso als Distributed RAM 
angelegt. Ein ganzer RAM-Block wäre dafür fast zu schade...

von Daniel R. (dan066)


Lesenswert?

Ja im Moment ist es Distrubuted RAM. Meines Wissens nach braucht Block 
RAM auch einen Takt zum Auslesen. Ich habe eigentlich vor den Code so 
anzupassen, dass eine Block-RAM inference rauskommt. Denn die vielen 
Block-RAM-Blöcke die ich zur Verfügung hab, brauche ich erstens für 
nichts und außerdem umfasst mein array eine Vielzahl solcher Zeilen wie 
oben dargestellt.

Im Grunde sieht es so aus, dass ich meine Schaltung mittels Multiplexer 
konfigurierbar halten möchte. Gesteuert wird ein Multiplexer von FFs und 
genau deren Inhalt will ich in den Ausgabespeicher mappen (in das 
array).
Ich werde mir wohl einen Block-ROM erstellen lassen und hab dann 
default-Werte in den Speicherstellen, deren Inhalt ich von einem 
Adressdekoder beim Auslesen von woanders herholen lasse.

Was war denn damit gemeint, dass ich einen Multiplexer brauche?

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


Lesenswert?

Daniel R. schrieb:
> Was war denn damit gemeint, dass ich einen Multiplexer brauche?
Wenn du keine Latency haben willst, dann musst du das ram_val_cs ja am 
eigentlichen RAM vorbei direkt auf den "Ausgang" schleusen. Diese 
Umschaltung macht ein Multiplexer.

Du könntest natürlich auch ein DPRAM instantiieren und den ram_val_cs 
vom einen Port an die Adresse 9 speichern, und vom anderen Prot aus 
lesen. Aber das ist wie gesagt mit Verzögerung verbunden, weil das BRAM 
ja getaktet ist.

von Ottmar (Gast)


Lesenswert?

Einfach zuweisen. Den Rest macht die Synthese.
1
architecture rtl of dummy is
2
  
3
  constant ram_max : integer := 9;
4
  type ram_type is array (0 to ram_max) of std_logic_vector (7 downto 0);
5
  signal RAM       : ram_type;
6
7
begin
8
9
  RAM <= (X"55", X"61", X"6c", X"75", X"65", X"20", X"35", X"3a", X"20", ram_val_cs);
10
11
end architecture rtl;

von berndl (Gast)


Lesenswert?

Ottmar schrieb:
> Einfach zuweisen. Den Rest macht die Synthese.
> architecture rtl of dummy is
>
>   constant ram_max : integer := 9;
>   type ram_type is array (0 to ram_max) of std_logic_vector (7 downto
> 0);
>   signal RAM       : ram_type;
>
> begin
>
>   RAM <= (X"55", X"61", X"6c", X"75", X"65", X"20", X"35", X"3a", X"20",
> ram_val_cs);
>
> end architecture rtl;

Interessanter Vorschlag, wenn das so funktioniert: Daumen hoch!

Mich wuerden aber bei sowas schon die Details wie das in HW 
implementiert wird interessieren. Prinzipiell wuerde ich eher Lothars 
Vorschlag oben (dual-ported RAM) zustimmen. Man hat's dann besser unter 
Kontrolle...

Und: Meist ist der 'read' aus einem RAM/ROM der kritische Teil (vor 
allem wenn's dann noch ueber ein externes IF zu z.B. einem uC geht), das 
schreiben in ein Array kann dann meist auch mal um ein paar CLK-Zyklen 
verzoegert werden (um das Timing hinzubekommen)

von Ottmar (Gast)


Lesenswert?

berndl schrieb:
> Mich wuerden aber bei sowas schon die Details wie das in HW
> implementiert wird interessieren.

Ohne Optimierung sind für das obige statement acht 5er-LUT's zu 
erwarten. Inputs der 5er-LUT: 4bit index für RAM und 1 bit von 
ram_val_cs.

Ich glaube die Bezeichnung des Signals "RAM" hat die Diskusion etwas auf 
die Speicherzellenschiene gleitet.

von Daniel R. (dan066)


Lesenswert?

Ottmar schrieb:
> Einfach zuweisen. Den Rest macht die Synthese.
>
>
1
> ... X"20", ram_val_cs);
2
>
Also das finde ich ja höchst interessant.
Ich wusste gar nicht dass LUTs auch Eingangswerte direkt ausgeben können 
(also Eingänge durchleiten). Dachte eine LUT wird einmal konfiguriert 
und gibt dann nur die festen Werte aus...

Diese Lösung wäre wohl wohl wesentlich performanter, als ein 
selbstgebauter Adressdekoder.

von Schlumpf (Gast)


Lesenswert?

Daniel R. schrieb:
> Ich wusste gar nicht dass LUTs auch Eingangswerte direkt ausgeben können

Wäre mir auch neu :-)

Daniel R. schrieb:
> Diese Lösung wäre wohl wohl wesentlich performanter, als ein
> selbstgebauter Adressdekoder.

Vermutlich nicht.
Denn wenn das Konstrukt überhaupt umsetzbar ist, dann auch nur mit den 
Möglichkeiten, die die Hardware bietet. Und diese Möglichkeiten kannst 
du dann auch manuell instanziieren.
Und da bin ich ganz Berndls Meinung: Ich würde solche wilden Konstrukte 
(wenn sie überhaupt synthetisierbar sind) nicht blind dem Können des 
Synthesizers überlassen.

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


Lesenswert?

berndl schrieb:
> Interessanter Vorschlag, wenn das so funktioniert: Daumen hoch!
Das muss ich auch mal ausprobieren. Ich bin gespannt, was dabei mit 
unterschiedlichen Synthesetools rauskommt...

von Daniel R. (dan066)


Lesenswert?

Schlumpf schrieb:
> Wäre mir auch neu :-)
Also stimmt die Rechnung mit 5 LUTs nicht? Oder doch?

Was könnte denn sonst anderes bei der Synthese rauskommen?

von Daniel R. (dan066)


Lesenswert?

Schlumpf schrieb:
> Vermutlich nicht.
> Denn wenn das Konstrukt überhaupt umsetzbar ist, dann auch nur mit den
> Möglichkeiten, die die Hardware bietet. Und diese Möglichkeiten kannst
> du dann auch manuell instanziieren.
Also "mein" Adressdekoder würde wohl nur aus einigen Multiplexern 
bestehen (bei Distributed RAM).
Bei Benutzung von Block RAM müsste man zusätzlich die Adresse aus LUTs 
holen und einen Takt, bis ausgelesen wurde, warten.

Ob sich der Aufwand, der für die Einbindung eines Block RAMs nötig ist 
lohnt, hängt also ganz davon ab wie groß mein Array mal werden soll und 
wie weit Anzahl der benötigten FFs ansteigt.

von Daniel R. (dan066)


Lesenswert?

Ich glaube ich hab das mit den 5 LUT-Eingängen verstanden. Man hat ja 
eine LUT pro Ausgabe-Datenbit also 8 Stück. Zeigt die Adresse die an der 
LUT anliegt auf die letzte Adresse (also 9 = "1001" als Adresse von 
ram_val_cs) dann liegt an der LUT tatsächlich aber nicht "01001" für 
Index=9 an, sondern "1001X" wobei 'X' ram_val_cs ist. In der LUT wären 
dann folgende Zuweisungen fest gespeichert: "10010" = 0 und "10011" = 1.
Es wurde also die Anzahl der Adressen verdoppelt um eine 
"Eingangsvariable" der LUT zu simulieren.
Und alle fest gespeicherten Werte sind doppelt in der LUT gespeichert, 
da unabhängig von ram_val_cs. Also einmal unter der Adresse mit 
letztes-Bit=0 und einmal unter letztes-Bit=1.
;)

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


Angehängte Dateien:

Lesenswert?

Ottmar schrieb:
> Einfach zuweisen. Den Rest macht die Synthese.
Beweisen!
Mit Xilinx klappt das nicht (wäre auch zu schön gewesen...).
Diese sehr simple Beschreibung hier:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity RamMux is
6
    Port ( dinA : in  STD_LOGIC_VECTOR (7 downto 0);
7
           dinB : in  STD_LOGIC_VECTOR (7 downto 0);
8
           dout : out  STD_LOGIC_VECTOR (7 downto 0);
9
           addr : in  STD_LOGIC_VECTOR (1 downto 0));
10
end RamMux;
11
12
architecture Behavioral of RamMux is
13
14
type ram_type is array (0 to 3) of std_logic_vector (7 downto 0);                 
15
--signal RAM : ram_type := (X"55", X"AA", X"35", X"3a");
16
signal RAM : ram_type := (X"55", X"AA", dinA, dinB);  
17
18
begin
19
   dout <= RAM(to_integer(unsigned(addr)));
20
end Behavioral;

Bringt mit XST diese Warnings:
1
WARNING:Xst:2094 - "RamMux.vhd" line 16: Default value is ignored for signal <RAM>.
2
WARNING:Xst:2094 - "RamMux.vhd" line 16: Default value is ignored for signal <RAM>.
3
WARNING:Xst:647 - Input <dinA> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
4
WARNING:Xst:647 - Input <dinB> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
5
WARNING:Xst:653 - Signal <RAM> is used but never assigned. This sourceless signal will be automatically connected to value 00000000.
Und es wird auch nichts synthetisiert, sondern wegen der nicht 
umsetzbaren beiden variablen Initwerte gleich der komplette Initstring 
ignoriert. Heraus kommen nur Nullen.

Im Gegentest ohne die beiden Ports im Init-String wird wenigstens wie 
erwartet noch ein ROM instatiiert...

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


Angehängte Dateien:

Lesenswert?

Synplify Pro bricht mit einem Fehler ab und erzeugt gar nichts:
1
@E: CL104 :"RamMux.vhd":17:47:17:50|Couldn't find binding for variable dina
2
@E: CL104 :"RamMux.vhd":17:47:17:50|Couldn't find binding for variable dinb

Im "ROM-Fall" wird einfach Kombinatorik erzeugt (das mach XST dann aus 
diesem mickrigen 4-Byte-Rom letztendlich dann auch)...

von VHDL hotline (Gast)


Lesenswert?

Ohne es ausprobiert zu haben, aber beim Vorschlag von Ottmar wird die 
Zuweisung ja nicht als Initwert verwendet sondern als nebenläufige 
Anweisung. Warum soll das nicht funktionieren?

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


Angehängte Dateien:

Lesenswert?

VHDL hotline schrieb im Beitrag #3858187:
> Warum soll das nicht funktionieren?
Weil das der Synthesizer gar nicht kann. Du kannst nicht ein komplettes 
RAM parallel zuweisen. Wie sollte denn so ein RAM-Baustein aussehen, wo 
massiv parallel auf alles zugegriffen werden kann?

Mit VHDL beschreibt man die Hardware, von der man sich vorher ein 
Bild gemacht hat. Auf einem Blatt Papier oder im Kopf...

VHDL hotline schrieb im Beitrag #3858187:
> Ohne es ausprobiert zu haben
Tus doch, Ist nicht viel Aufwand...
Ok, mach ich das mal:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity RamMux is
6
    Port ( dinA : in  STD_LOGIC_VECTOR (7 downto 0);
7
           dinB : in  STD_LOGIC_VECTOR (7 downto 0);
8
           dout : out  STD_LOGIC_VECTOR (7 downto 0);
9
           addr : in  STD_LOGIC_VECTOR (1 downto 0));
10
end RamMux;
11
12
architecture Behavioral of RamMux is
13
14
type ram_type is array (0 to 3) of std_logic_vector (7 downto 0);                 
15
signal RAM : ram_type;
16
begin
17
    
18
   dout <= RAM(to_integer(unsigned(addr)));
19
   RAM <= (X"55", X"AA", dinA, dinB);
20
end Behavioral;
Daraus wird reinste pure Kombinatorik mit einem Multiplexer. Je größer 
der Multiplexer wird, umso mehr (teure) LUTs "gehen drauf". Es wird aber 
eben kein RAM-Block verwendet...

: Bearbeitet durch Moderator
von VHDL hotline (Gast)


Lesenswert?

Mir ging es nicht um die Verwendung eines RAM-Blocks sondern um das 
reine Sprachkonstrukt, das vorgeschlagen wurde. Ottmar hat ja selbst 
geschrieben, dass daraus LUTs werden. Das läuft, wie du festgestellt 
hast, durch und hat am Ende die (durch das VHDL-Sprachkonstrukt) 
beschriebene Funktionalität.

Um auch mal was zum Thema beizutragen: So wie ich es verstehe, geht es 
um x-mal 10 Bytes, die irgendwohin übertragen werden, wobei die ersten 9 
Bytes für jeden 10-Byte Vektor konstant sind. Die ersten x-mal 9 Bytes 
kann man quasi als ROM ablegen und das letzte Byte live bei der Ausgabe 
dran hängen (ohne es vorher in einem RAM abzulegen). Falls das letzte 
Byte nicht live verfügbar ist, einen (kleineren) RAM daneben, welcher 
nur die x-mal 1 Byte (möglicherweise mehrere in einem RAM-Wort, je nach 
RAM-Architektur) speichert und dorther holen.
Ob das so möglich ist, geht aus der Aufgabenbeschreibung des 
Fragestellers für mich nicht so ganz hervor.

von Daniel R. (dan066)


Lesenswert?

VHDL hotline schrieb im Beitrag #3858338:
> Ob das so möglich ist, geht aus der Aufgabenbeschreibung des
> Fragestellers für mich nicht so ganz hervor.

Was ich brauche ist am Besten einen BRAM, der die bei Arraydefinition 
angegebenen Werte unveränderbar speichert (wie ein ROM) und einen 
Adressdekoder, der die veränderbaren Werte in den Adressbereich des BRAM 
mappt. Im Grunde will ich einen Speicher, der Strings speichert und mir 
Bezeichner und aktuellen Wert zurückgibt. Zum Beispiel "Wert 1: ?" wobei 
das ?  einem 0x00 oder 0x01 Byte entspricht je nachdem wie der aktuelle 
Status eines gewissen FFs ist.

von VHDL hotline (Gast)


Lesenswert?

Jetzt verstehe ich was du willst. Du speicherst ASCII-Bytes und willst, 
dass der erste Teil der Ausgabe größtenteils immer gleich bleibt (Uart 0 
: ? bis Uart 50 : z.B.).
Dafür brauchst du keinen Speicher, da reicht ein konstanter Vektor in 
dem du bei der Ausgabe ein paar Bytes anpasst (nämlich die 
Adressinformation 0 bis 50 als ASCII).

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


Lesenswert?

VHDL hotline schrieb im Beitrag #3858374:
> Dafür brauchst du keinen Speicher, da reicht ein konstanter Vektor
Die Frage ist nun aber, wo der am ressourcenschonendsten abgelegt 
wird.
In aller Regel wird das ein RAM-Block sein.

Wenn man sich nicht ganz ungeschickt anstellt, kann man dieses RAM 
anfangs auch zur Initialisierung verwenden:
Beitrag "Re: EA DOG-M initialisieren"

von VHDL hotline (Gast)


Lesenswert?

Ja, natürlich ist ein RAM am ressourcenschondensten, wenn die ersten 9 
Bytes für jeden der 10-Byte-Vektoren unterschiedlich sind. So wie ich 
das verstehe, sind die aber für alle 10-Byte-Vektoren fast gleich 
(nämlich "UART 0-x :" als ASCII)? Das heißt, man braucht genau einmal 
(weniger als) 9 Bytes in LUTs. Wenn man einen 18Kb Block-RAM übrig hat, 
kann man das sicherlich darin speichern. Wäre aber im Vergleich zu einem 
std_logic_vector(71 downto 0):="..." nicht meine erste Wahl.

von Daniel R. (dan066)


Lesenswert?

Es steht noch nicht fest wie ähnlich die Textzeilen sein werden. Um auch 
total unterschiedliche speichern zu können gehe ich jetzt davon aus, 
dass sie unterschiedliche Längen und Inhalte haben.
Ablegen würde ich sie im BRAM deshalb, da ich gedenke die übrige 
Hardware des FPGAs soweit möglich auszunutzen.
In Modelsim kann ich die Initialwerte des Arrays sogar schon aus einer 
Textdatei einlesen. Nur XST macht da leider nicht mit.

von VHDL hotline (Gast)


Lesenswert?

Du willst also ein RAM, gut, dann nimm ein RAM ;-) . Gerade die Länge 
des Inhaltes ist allerdings schon relativ wichtig. Bei unterschiedlichen 
Längen einfach nacheinander abgespeichert wird die Adressierung außer 
herum etwas umständlicher. Wenn du so etwas wie eine Maximallänge 
definierst, kannst du die Addressierung einheitlicher halten und bei 
evtl. kürzeren Vektoren Speicherbereiche einfach nicht benutzen. 
Eventuell ist etwas, um das du dir erstmal Gedanken machen solltest, 
eine Art Speicherkonzept. Wie du also einen Eingangswert (eine Anfrage 
nach einem bestimmten Wert, der auch über UART kommt vermutlich?) auf 
eine RAM-Adresse mapst, was genau (Wortbreite)/wieviele (Adressbreite) 
RAM-Worte dann im RAM stehen sollen, ob du z.B. die Länge gleich mit im 
RAM abspeicherst usw. .

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


Lesenswert?

VHDL hotline schrieb im Beitrag #3858514:
> Gerade die Länge des Inhaltes ist allerdings schon relativ wichtig.
Es sollte idealerweise eine auf eine Zweierpotenz passende Länge sein:
16, 32, 64 Bytes. Wenn es "nur" 20 Bytes sind (z.B. 2x20 Display), dann 
ist es trotzdem überlegenswert, für jede Zeile 32 Bytes zu verwenden. 
Das, was dort "verschwendet" wird, lässt sich anderweitig durch eine 
vereinfachte Adressierung schnell wieder herausholen...

von uwe (Gast)


Lesenswert?

Du könntest auch zwei BRAMs nehmen. Wobei in der einen immer in 32 byte 
Blöcken der String gespeichert ist. Dann noch ne Statemachine die einen 
davon ausließt(bis zum terminierungbyte). Die unteren 5 adressbits 
werden also als index genutzt (wegen der 32byte blöcke), die oberen n 
adressbits geben den Index für den anderen BRAM an oder Register in 
denen das variable ASCII Zeichen steht zum korrespondierenden string.
Somit kann man relativ Große Strings im BRAM speichern und die kleinen 
Zeichen landen in LUT RAM oder auch in einem anderen BRAM der 
komplizierter verdrahtet ist, weil die Zeichen nicht konstant sind und 
dynamisch verändert werden. Da die BRAMs Dualport fähig sind ist das 
aber auch relativ einfach hinzubekommen. Bei einem 0x00 im ersten BRAM 
stellt die statemachine den Output Mux vom ersten BRAM auf den zweiten 
um(dessen unteren adressinputs mit den oberen n adressinputs des ersten 
verdrahtet sind). Beschrieben wird das zweite BRAM halt mit ner weiteren 
statemachine mit einem Busy Flag der ersten verbunden ist, damit keine 
glitches bzw. race konditions der einzelnen bits auftreten falls die 
eine statemachine gerade etwas ausgibt und man versucht gleichzeitig 
einen neuen Wert zu schreiben.
Das schöne ist man kann dann sehr einfach erweitern und kann die BRAMs 
immer größer machen und viele Strings und Parameter darin ablegen. Für 
mehrere dynasch veränderbare ASCII Zeichen muß die statemachine 
natürlich etwas komlizierter sein. Kannst du ja mal aufzeichnen was ich 
meine...

von Ottmar (Gast)


Lesenswert?

Wenn auf Grund der Tabellengröße eine kombinatorische Implementierung 
ineffizient wird, kann man natürlich auf RAM's zurückgreifen.

Hierzu mein Vorschlag. Man legt eine ROM Tabelle an mit 9-bit breite für 
die Character an. Das 9te bit fungiert als Umschalter. Ist es 0 werden 
die unteren 8-bit direkt ausgegeben. Ist es 1 nutzt man die unteren bits 
zur Auswahl der dynamischen Signale. Somit lässt sich über einen Index 
entweder ein konstanter Wert oder eines der dynamischen Signale 
auswählen.

In Pseudocode:

Gegeben seien:
ROM_im_RAM := ('0'&X"AA", ...., '1'&X"01")
dynamic_signals = (dyn1, dyn2, ... dynn)

Algo:
flag_and_character = ROM_im_RAM(x)
if flag_and_character(8)='1' then
  dout = dynamic_signals(flag_and_character(7:0))
else
  dout = flag_and_character(7:0)
end if

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


Lesenswert?

Ottmar schrieb:
> Hierzu mein Vorschlag.
Meiner seit langem auch:
Lothar Miller schrieb:
>>>> Du wirst einen Adressdecoder und einen Multiplexer brauchen.
Und ab dieser Erkenntnis führen tausend Wege nach ROM...

: Bearbeitet durch Moderator
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.