Hallo, ich möchte ein Modul schreiben, an dem man ein ein Bit Signal und ein 16-bit Wort anlegen kann. Bei einer positiven Flanke des 1 Bit Signals soll das 16 Bit Wort in eine reg geladen werden und die erste Hälfte des Wortes in einem 8 Bit Wort ausgegeben werden. Bei einer 2. positiven Flanke des 1 Bit Signals, soll die zweite Hälfte des 8 Bit Wortes ausgegeben werden. Bei der dritten positiven Flanke, soll das aktuelle 16 Bit Wort wieder in die reg geladen, die erste Hälfte ausgegeben werden, usw. Leider habe ich damit große Probleme, die Simulation hat am Anfang jeweils zwei undefinierte Signale, danach läuft es fast fehlerfrei weiter. Könntet Ihr mir dabei helfen und ein Grundgerüst für solch ein Modul posten? Vielen, vielen Dank, Frank
Poste du deins, dann finden wir den Fehler schnell. Die Arbeit anderer zu machen wird den wenigsten hier Vergnügen bereiten :)
>die Simulation hat am Anfang jeweils zwei undefinierte Signale Das ist an sich nicht schlimm und kann mit einer Defaultzuweisung problemlos umgangen werden. Z.B. so: signal ausgang : std_logic_vector(7 downto 0) := (others=>'0'); >danach läuft es fast fehlerfrei weiter Das Ganze passt mit viel Luft in einen getakteten Prozess, da kann es eigentlich gar keinen Platz für Fehler geben ;-)
klingt für mich wie eine einfache FSM mit 3 zuständen in einem einfachen prozess.
>klingt für mich wie eine einfache FSM mit 3 zuständen >in einem einfachen prozess. Nein, das geht noch einfacher: eine SM mit 2 Zuständen. So etwa:
1 | entity Mux is |
2 | Port ( clk : in STD_LOGIC; |
3 | din : in STD_LOGIC_VECTOR (15 downto 0); |
4 | dout : out STD_LOGIC_VECTOR (7 downto 0)); |
5 | end Mux; |
6 | |
7 | architecture Behavioral of Mux is |
8 | signal hilo : std_logic := '0'; |
9 | signal lobyte : std_logic_vector(7 downto 0) := (others=>'0'); |
10 | begin
|
11 | process(clk) |
12 | begin
|
13 | if rising_edge(clk) then |
14 | hilo <= not hilo; -- SM Zustand weiterschalten |
15 | if (hilo='0') then |
16 | dout <= din(15 downto 8); -- High-Byte ausgeben |
17 | lobyte <= din( 7 downto 0); -- Low-Byte merken |
18 | else
|
19 | dout <= lobyte; -- Low-Byte ausgeben |
20 | end if; |
21 | end if; |
22 | end process; |
23 | end Behavioral; |
Alles hübsch registriert und ohne Glitches... Simulation siehe Anhang ;-)
Ich musste mal kurz weg, deshalb jetz erst die Variante mit einem globalen (schnellen) FPGA-Takt und einem "langsamen" Mux-Takt:
1 | architecture Behavioral of Mux is |
2 | signal hilo: std_logic := '0'; |
3 | signal muxclksr: std_logic_vector(1 downto 0) := (others=>'0'); |
4 | signal lobyte: std_logic_vector(7 downto 0) := (others=>'0'); |
5 | begin
|
6 | process(clk) |
7 | begin
|
8 | if rising_edge(clk) then -- DER globale FPGA-Takt |
9 | muxclksr <= muxclksr(0) & muxclk; -- Schiebereg. für Flankenerkennung |
10 | if (muxclksr="01") then -- steigende Flanke des Mux-Taktes |
11 | hilo <= not hilo; -- SM Zustand weiterschalten |
12 | if (hilo='0') then |
13 | dout <= din(15 downto 8); -- High-Byte ausgeben |
14 | lobyte <= din( 7 downto 0); -- Low-Byte merken |
15 | else
|
16 | dout <= lobyte; -- Low-Byte ausgeben |
17 | end if; |
18 | end if; |
19 | end if; |
20 | end process; |
21 | end Behavioral; |
Waveform wie vorhin im Anhang. Viel Spass damit ;-)
@ Eman
> Schön, dann ist Frank ja schon fertig mit seinen Hausaufgaben.
Ja, aber das hilft ihm nicht wirklich. Jetzt muss er nämlich meinen Code
erst mal kapieren, und hat dann trotzdem noch ein Problem. Aber das muss
er selber erkennen... ;-)
@ Frank
Nein, mein Code ist ok. Dein Problem liegt woanders...
Hallo, danke für die vielen Antworten. Es stimmt, es wäre klüger gewesen, den Code zu posten. Ich habe den Code veressert. Es funktioniert so ähnlich, wie das bisher gepostete.
1 | module xyz (clock, reset, Ready_for_Data_in, in, out); |
2 | |
3 | //Input |
4 | input clock, reset; |
5 | input Ready_for_Data_in; |
6 | input [13:0] in; |
7 | |
8 | //Output |
9 | output [7:0] out; |
10 | |
11 | reg [7:0] highbits; |
12 | |
13 | reg [7:0] out; |
14 | |
15 | reg state; |
16 | |
17 | |
18 | |
19 | //sequenzieller Block |
20 | always @(posedge clock) |
21 | begin
|
22 | if(reset==1) |
23 | begin
|
24 | Data_to_RS232<=8'b0; |
25 | state<=1'b0; |
26 | highbits[0] <= 1'b0; |
27 | highbits[1] <= 1'b0; |
28 | highbits[2] <= 1'b0; |
29 | highbits[3] <= 1'b0; |
30 | highbits[4] <= 1'b0; |
31 | highbits[5] <= 1'b0; |
32 | highbits[6] <= 1'b0; |
33 | highbits[7] <= 1'b0; |
34 | end
|
35 | else
|
36 | begin
|
37 | if (Ready_for_Data_in==1'b1); |
38 | begin
|
39 | if (state==1'b0) |
40 | begin
|
41 | Data_to_RS232[0] <= Mikrofon_editing_input[0]; |
42 | Data_to_RS232[1] <= Mikrofon_editing_input[1]; |
43 | Data_to_RS232[2] <= Mikrofon_editing_input[2]; |
44 | Data_to_RS232[3] <= Mikrofon_editing_input[3]; |
45 | Data_to_RS232[4] <= Mikrofon_editing_input[4]; |
46 | Data_to_RS232[5] <= Mikrofon_editing_input[5]; |
47 | Data_to_RS232[6] <= Mikrofon_editing_input[6]; |
48 | Data_to_RS232[7] <= 1'b0; |
49 | |
50 | highbits[0] <= Mikrofon_editing_input[7]; |
51 | highbits[1] <= Mikrofon_editing_input[8]; |
52 | highbits[2] <= Mikrofon_editing_input[9]; |
53 | highbits[3] <= Mikrofon_editing_input[10]; |
54 | highbits[4] <= Mikrofon_editing_input[11]; |
55 | highbits[5] <= Mikrofon_editing_input[12]; |
56 | highbits[6] <= Mikrofon_editing_input[13]; |
57 | highbits[7] <= 1'b0; |
58 | |
59 | state<=1'b1; |
60 | end
|
61 | else
|
62 | begin
|
63 | Data_to_RS232[8] <= highbits[0]; |
64 | Data_to_RS232[9] <= highbits[1]; |
65 | Data_to_RS232[10] <= highbits[2]; |
66 | Data_to_RS232[11] <= highbits[3]; |
67 | Data_to_RS232[12] <= highbits[4]; |
68 | Data_to_RS232[13] <= highbits[5]; |
69 | Data_to_RS232[14] <= highbits[6]; |
70 | Data_to_RS232[15] <= highbits[7]; |
71 | state<=1'b0; |
72 | end
|
73 | end
|
74 | end
|
75 | end
|
76 | endmodule
|
Beim Compilieren kommt aber der Fehler # ** Warning: C:/xxxx: [BSOB] - Bit-select into 'Data_to_RS232' is out of bounds. Woran kann das liegen? Frank
@Frank >Woran kann das liegen? Das ist jetzt aber nicht ernst gemeint, oder? >Bit-select into 'Data_to_RS232' is out of bounds. Diese Meldung ist selbstbeschreibend. Es werden Bits von 'Data_to_RS232' ausgewählt, die es gar nicht gibt. >Data_to_RS232<=8'b0; Offenbar ist das Register 'Data_to_RS232' nur 8 Bit breit. Falls ja, wie geht das: >Data_to_RS232[8] <= highbits[0]; >Data_to_RS232[9] <= highbits[1]; >Data_to_RS232[10] <= highbits[2]; >Data_to_RS232[11] <= highbits[3]; >Data_to_RS232[12] <= highbits[4]; >Data_to_RS232[13] <= highbits[5]; >Data_to_RS232[14] <= highbits[6]; >Data_to_RS232[15] <= highbits[7]; BTW: Ich kann zwar kein Verilog, aber das müsste doch als Vector kürzer zu schreiben sein? So vielleicht (immer noch falsch): Data_to_RS232[15:8] <= highbits[7:0]; oder richtig: Data_to_RS232[7:0] <= highbits[7:0]; oder kürzer: Data_to_RS232 <= highbits; (So könnte ich das zumindest in VHDL beschreiben)
Data_to_RS232 ist soweit ich sehe nicht definiert, deshalb wird es implizit als 1-Bit breit angesehen. Schreib mal eine Definition mit 16 Bit breite hin, dann sollte es gehen. Nebenbei scheint mir, du hast beim Signal "in" aus Versehen 13:0 (14 Bits) statt 15:0 (16 Bits) geschrieben. @Lothar: Nein, es ist ganz und gar nicht selbsterklärend. Im Gegenteil ist die Fehlermeldung höchst irreführend, denn sie meldet ein zu "schmales" Signal, obwohl das eigentliche Problem die fehlende Definition ist.
@ Morin Wie gesagt, ich kann kein Verilog. Daher erst mal eine Frage: >Data_to_RS232 ist soweit ich sehe nicht definiert, >deshalb wird es implizit als 1-Bit breit angesehen Ist es bei Verilog also (wie früher zu Basic's-Zeiten) möglich, mitten im Fliesstext irgendwelche Signale zu instantiieren, ganz ohne Deklaration, einfach indem ein Name hingeschrieben wird? Falls ja, dann bin ich echt froh, dass es Sprachen wie C und VHDL gibt... >beim Signal "in" aus Versehen 13:0 statt 15:0 geschrieben ... Damit meint Frank wohl den "Mikrofon_editing_input[13:0]". Der wird btw. auch nirgends deklariert.
> Wie gesagt, ich kann kein Verilog. Das ist selbstverständlich keine Schande. > Das ist jetzt aber nicht ernst gemeint, oder? > Diese Meldung ist selbstbeschreibend. > Offenbar[...] Das hier dagegen ist extrem peinlich, wenn man selbst keine Ahnung hat. > Ist es bei Verilog also (wie früher zu Basic's-Zeiten) möglich, mitten > im Fliesstext irgendwelche Signale zu instantiieren, ganz ohne > Deklaration, einfach indem ein Name hingeschrieben wird? Ja, und diese sind dann 1 Bit breit (Bit-Signale sind, soweit ich mich erinnere, in Verilog dasselbe wie 1-Bit breite Vektoren) > Falls ja, dann bin ich echt froh, dass es Sprachen wie C und VHDL > gibt... Jo, das war einer der Gründe weshalb ich trotz der grausligen Syntax lieber VHDL benutze. > Damit meint Frank wohl den "Mikrofon_editing_input[13:0]". > Der wird btw. auch nirgends deklariert. Da hast du vermutlich Recht, wobei ich mich eigentlich auf das Signal "in" aus der Portliste bezogen hatte, aber möglicherweise sollte das ein und dasselbe Signal sein. Könnte ein weiterer Fehler zu sein, der wegen der impliziten Deklarationen nicht erkannt wurde.
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.