Forum: FPGA, VHDL & Co. Buchstaben werden dauernd ausgedruckt auf dem Screen.


von peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, guten Tag.
Ich habe hier eine Verilog-Beschreibung mit dem Vga-Text.
Es ist erweitert mit einer RS232 zum PC 19200 Baud.
Es funktioniert auch soweit, nur werden dauernd Buchstaben ausgedruckt 
bis meine Sreen-Abfrage bei 2399 wieder auf "0" und dann geht es wieder 
los.

Die LED_g die ich angeschlossen habe zur Konrolle zeigt auch immer nur 
den einen Buchstaben bis ich den nächsten Buchstaben vom PC übertrage.

Die RS232 läuft mit State.
Ich weiss nicht weiter.
Was muss ich jetzt hier bitte in der Schleife von dem RS232-Modul 
reinsetzen
damit der Kreislauf unterbrochen wird bis zur nächsten Taste.
-----------------------------------------
always @(posedge clock)
begin
  if(rcv_sr >=32)
  begin
    if(write_address < 2399 )
    begin
      we=1;
      write_address=write_address+1;
      dat_w=rcv_sr;
      led_g=rcv_sr;
    end
    else
      write_address=0;
  end
end
---------------------------------------
1
`include "rom.v"
2
`include "ram.v"
3
4
module vga_text_rs232(
5
 input  clock,      
6
 output hsync,
7
 output vsync,
8
 output reg [3:0] red,
9
 output reg [3:0] green,
10
 output reg [3:0] blue,
11
 output reg [7:0] led_g,
12
 input reset,
13
 input RXD
14
);
15
16
parameter rcv_bit_per = 2604; //19200 Buad
17
parameter half_rcv_bit_per = 1302; 
18
19
//--State Definitions--
20
parameter ready = 2'b00;
21
parameter start_bit = 2'b01;
22
parameter data_bits = 2'b10;
23
parameter stop_bit = 2'b11;
24
25
wire clk;
26
wire [7:0] char;
27
wire [7:0] dat;
28
wire [9:0] charLin;
29
30
wire h_enable;
31
wire v_enable;
32
wire vid_enable;
33
wire CounterXmaxed;
34
wire CounterYmaxed;
35
36
reg [16:0] qc;
37
reg [32:0] cnt;
38
reg  Pixel;
39
reg [9:0]  CounterX; // 10 Bit, range 0..799
40
reg [9:0]  CounterY; //  10 Bit, range 0..524
41
reg [11:0] Basis;    // Adr. Zeilenanfang
42
reg [6:0]  Offs;     // Pos. in Zeile 
43
reg [11:0] ZPos;     // effektive Zeichenpos. in BWS  
44
reg [11:0] write_address;    
45
reg [7:0]  dat_w;
46
reg we;
47
48
reg [12:0] counter, n_counter;  
49
reg [3:0]  data_bit_count, n_data_bit_count;
50
reg [7:0]  rcv_sr, n_rcv_sr;
51
reg [1:0]  state, n_state;
52
53
rom myRom (.addr_a(charLin), .clk(clk), .q_a(dat));   // Zeichensatz
54
ram myRam (.q(char), .read_address(ZPos), .clk(clk),.write_address(write_address), .d(dat_w),.we(we)); // Bildspeicher
55
56
assign CounterXmaxed = (CounterX==800);
57
assign CounterYmaxed = (CounterY==525);
58
59
always @(posedge clock)
60
begin
61
  qc <= qc + 1;
62
end
63
// 50Mhz  2^1 = 25MHz
64
assign clk = qc[0];
65
66
always @(posedge clock) 
67
begin
68
  if(rcv_sr >=32)
69
  begin  
70
    if(write_address < 2399 )
71
    begin
72
      we=1;
73
      write_address=write_address+1;  
74
      dat_w=rcv_sr;
75
      led_g=rcv_sr;
76
    end
77
    else
78
      write_address=0;    
79
  end
80
end
81
82
always @(posedge clk) begin 
83
// Zählen in horizontaler Richtung
84
  if(CounterXmaxed)
85
    CounterX <= 0;
86
  else begin 
87
    CounterX <= CounterX + 1;
88
    if (dat & (1 << CounterX[2:0])) 
89
      Pixel <= 1;
90
    else 
91
      Pixel <= 0;
92
  end
93
94
// Zählen in vertikaler Richtung
95
  if(CounterXmaxed) begin 
96
    if (CounterYmaxed) CounterY <= 0;
97
  else CounterY <= CounterY + 1;
98
  end
99
100
  if (CounterX[2:0] == 0) begin
101
    if (CounterX == 0 && CounterY == 0) Basis <= 0;
102
    else if (CounterX == 0 && CounterY[3:0]==0) Basis <= Basis + 80;
103
  end
104
  
105
  Offs <= CounterX[9:3];
106
  ZPos <= Basis + Offs;
107
end
108
109
always @(posedge clk)
110
begin
111
  if (vid_enable==1 && Pixel == 1)
112
    begin
113
      red = 4'b1111;
114
      blue = 4'b1111;
115
      green = 4'b1111;
116
    end 
117
    else
118
    begin
119
      red = 4'b0000;
120
      blue = 4'b1111;
121
      green = 4'b0000;
122
    end 
123
end
124
125
assign hsync = (CounterX < 655) || (CounterX > 751);
126
assign vsync = (CounterY < 489) || (CounterY > 491);  
127
128
assign charLin = {char,CounterY[3:1]};  // Zeiger fuer Zeichensatz
129
130
// Filter für video enable ableiten
131
assign h_enable = (CounterX > 4 && CounterX < 640);
132
assign v_enable = (CounterY < 480);
133
assign vid_enable = h_enable && v_enable;
134
135
always @(state, RXD, counter, data_bit_count) begin
136
  n_rcv_sr  <= rcv_sr;
137
  n_counter <= counter;
138
  n_state   <= state;
139
  n_data_bit_count <= data_bit_count;
140
141
  case (state)
142
  ready: 
143
    begin
144
      if(RXD == 0) begin
145
      n_state   <= start_bit;
146
      n_counter <= counter + 1;
147
    end
148
    else begin
149
      n_state   <= ready;
150
      n_counter <= 0;
151
      n_data_bit_count <= 0;
152
    end
153
    end
154
155
    start_bit: begin
156
    
157
    if(counter == half_rcv_bit_per) begin
158
      n_state <= data_bits;
159
      n_data_bit_count <= data_bit_count + 1;
160
      n_counter <= 0;
161
    end
162
    else begin
163
      n_state   <= start_bit;
164
      n_counter <= counter + 1;
165
    end
166
    end
167
168
    data_bits: 
169
    begin
170
    if(counter == rcv_bit_per) begin
171
      n_rcv_sr <= {RXD,rcv_sr[7:1]};
172
      n_data_bit_count <= data_bit_count + 1;
173
      n_counter <= 0;
174
      if(data_bit_count == 8)
175
        n_state <= stop_bit;
176
    end
177
    else
178
      n_counter <= counter + 1;
179
    end
180
181
    stop_bit: 
182
    begin
183
    n_counter <= counter + 1;
184
    if(counter == rcv_bit_per) 
185
      n_state <= ready;
186
    end
187
endcase
188
end 
189
190
always @(posedge clock or posedge reset) begin
191
  if(reset == 1) begin
192
    state   <= ready; 
193
    rcv_sr  <= 0;
194
    counter <= 0;
195
    data_bit_count <= 0;
196
  end
197
  else begin
198
    state   <= n_state;
199
    rcv_sr  <= n_rcv_sr;
200
    counter <= n_counter;
201
    data_bit_count <= n_data_bit_count;
202
  end
203
end
204
205
endmodule

Danke.
Gruss

von peter (Gast)


Lesenswert?

Habe ich vergessen. Es kommt auch immer mit ein Echo rein als 2. 
Buchstabe, welches nicht immer gleich ist, diesma ist es ein "+".

Gruss

von peter (Gast)


Lesenswert?

Habe ein Teilerfolg erzielt:
Habe das "we=0" in der schleife nach "else" reingesetzt , das Echo wird 
nicht mehr ausgegeben nur noch die Buchstaben die ich drücke schreiben 
den Screen voll. Sieht schon etwas besser aus....
Jetzt brauche ich bitte die Hilfe, damit der Screen immer nur ein 
Ausdruck vom Buchstaben macht.

Danke.
Gruss

von Gustl B. (-gb-)


Lesenswert?

Hier

[verilog]begin
  if(rcv_sr >=32)
  begin
    if(write_address < 2399 )
    begin
      we=1;
      write_address=write_address+1;
      dat_w=rcv_sr;
      led_g=rcv_sr;
    end
    else
      write_address=0;
  end
end[/verilog]

Schreibst du immer rcv_sr in den Textspeicher wenn rcv_sr >= 32. Diese 
Bedingung würde ich so umschreiben, dass das nur dann in den 
Textspeicher geschrieben wird, wenn ein neues Byte/Char empfangen wurde.

von peter (Gast)


Lesenswert?

Ja Gustl Buheitel.

Kannst du mal schauen, ich weiss nicht was ich aus dem RS232-Modul als 
abfrage neben kann?
rcv_sr : funktioniert nicht zb : if(rcv_sr>32)

Ich kann kein Befehl da rausfischen. Immer wird der Screen 
vollgeschrieben.

Danke.
Gruss

von peter (Gast)


Lesenswert?

--------------------
...Textspeicher geschrieben wird, wenn ein neues Byte/Char empfangen 
wurde.
--------------------

Hm...wie soll ich das machen, es muss ja dann irgendwie angehalten 
werden?

Danke.
Gruss

von peter (Gast)


Lesenswert?

Ich habe ein Terminalprogramm, wo ich 1 Buchstaben verschicken kann.
Dieser eine Buchstabe schreibt dann schonden Screen voll bis die Abfrage 
:write_address <= 2399 kommt. Der Screen hat ja 2400 Zeichen.

Mehr sende ich nicht.

Gruss

von Gustl B. (-gb-)


Lesenswert?

Ich kann leider kein Verilog. Aber in dem Code gibt es

data_bit_count == 8

Diese Bedingung kannst du verwenden um einmalig den gerade empfangenen 
Buchstaben ins Textram zu schreiben.
1
always @(posedge clock) 
2
begin
3
  if(rcv_sr >=32)
4
  begin  
5
    if(write_address < 2399 )
6
    begin
7
      we=1;
8
      write_address=write_address+1;  
9
      dat_w=rcv_sr;
10
      led_g=rcv_sr;
11
    end
12
    else
13
      write_address=0;    
14
  end
15
end

Da drinnen die Zeile
1
if(rcv_sr >=32)

ersetzen durch
1
if(data_bit_count == 8)

Wobei auch das nicht funktioniert. Du musst den Übergang von 
data_bit_count von 7 nach 8 erkennen oder irgendwie eben das Ende von 
jedem Byte. Also z.B. so:
1
if(data_bit_count == 7 and rcv_bit_per == 2604)

Das wäre also dann das Ende des letzten Bits vor dem Stoppbit, wenn der 
Zähler der Bitzeit auf dem Maximum steht.

: Bearbeitet durch User
von peter (Gast)


Lesenswert?

Habe jetzt diese Zählkontrolle für "write_address" rausgenommen, 
trotzdem rattert der Screen voll durch, wenn ich mit dem Terminal nur 1 
Buchstaben sende.

[vhdl]
always @(posedge clk)
begin
  if(rcv_sr >=32)
  begin
    we=1;
    write_address=write_address+1;
    dat_w=rcv_sr;
    led_g=rcv_sr;
  end
  else
    we=0;
end
[vhdl]

Gruss

von Gustl B. (-gb-)


Lesenswert?

Ha? Wieso hast du das gemacht? Es geht um die Bedingung bei der 
geschrieben wird. Und die trifft öfter ein als du willst. Eine 
Möglichkeit das zu ändern oder was man grob beschreiben sollte habe ich 
oben geschrieben.

von peter (Gast)


Lesenswert?

Danke Gustl, bringt auch nichts.

Grus

von Christian R. (supachris)


Lesenswert?

Was sagt denn die Simulation? Da findest du doch solche Fehler schnell.

von Softwareverwickler (Gast)


Lesenswert?

Hallo Peter,

Das probelm ist, dass es hier keine möglichkeit gibt, zu erkennen, ob 
ein empfangenes zeichen bereits angezeigt wurde.

Füre noch ein flag ein. es wird gesetzt, wenn ein neues zeichen 
hineingeschrieben wurde, und zurückgesetzt, wenn das empfangene zeichen 
in den bildspeicher komiert wurde. Mein Verilog ist etwas eingerostet, 
abe so in etwa müsste es gehen:
1
reg newchar;
2
3
always @(posedge clk)
4
begin
5
  if(newchar == 1)
6
  begin
7
    if(rcv_sr >=32)
8
    begin
9
      we=1;
10
      write_address=write_address+1;
11
      dat_w=rcv_sr;
12
      led_g=rcv_sr;
13
    end
14
    else
15
      we=0;
16
   newchar<=0;
17
end

und beim empfang
1
case (state)
2
  ready: 
3
    begin
4
      if(RXD == 0 && newchar == 0) begin
5
      n_state   <= start_bit;
6
      n_counter <= counter + 1;
7
    end
8
   
9
...
10
11
  stop_bit: 
12
  begin
13
    n_counter <= counter + 1;
14
    if(counter == rcv_bit_per)
15
    begin
16
      newchar <= 1; 
17
      n_state <= ready;
18
    end
19
  end
20
endcase
21
end

von peter (Gast)


Lesenswert?

Der Compiler beanstandet, das newchar 2x angesprochen wird als 
Drahtverbindung.
Man kann zwar beliebig abfragen , aber nur einmal zuweisen.

Aber daran liegt es, nur ich finde ausgedrückt keine Beschreibung für 
einen Weg. Eine Testbench braucht man hier nicht weil es an einem Weg 
hapert.

Danke.
Gruss

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.