If-Bedingung nach dem Einschalten, falsch initialisiert?

OP Persönliche Seite #4293994
Lesenswert?

Hi!

ich finde den Grund für mein Problem einfach nicht herraus.

Ich habe eine LED, die bei vollgelaufenen Counter eingeschaltet werden 
soll.
Jedoch ist die LED schon zu Beginn eingeschaltet.
Warum durchläuft das "Programm" den "then"-teil des ifs obwohl der 
Counter noch 0 ist?

Verilog auf einem ICE40LP1K
1
module fillRam (clk, wclk, counter, led);
2
  input clk;
3
  output wclk;
4
  output reg [7:0] counter = 0;
5
  output reg led = 0;
6
  
7
  always @(posedge clk)
8
  begin
9
    if(counter == 8'hFF)
10
      led = 1;
11
    else
12
      counter <= counter + 1;
13
  end
14
    
15
  assign wclk = (counter == 8'hFF) ? 1'b0 : clk;
16
  //assign led = (counter == 8'hFF) ? 1'b1 : 1'b0;
17

18
endmodule
Gast #4294006
Lesenswert?

Steven (. schrieb:
> Warum durchläuft das "Programm" den "then"-teil des ifs obwohl der
> Counter noch 0 ist?
Die Formulierung wird wieder einige anziehen, die dir sagen werden, dass 
es in der Hardwarebeschreibung kein Programm gibt und nichts durchläuft. 
;-)

Erste, triviale Idee: Wie schnell ist dein Takt? Ich weiß nicht, wie 
8'hFF zu lesen ist, aber wenn das für 0xFF steht, dürfte der Zähler in 
Sekundenbruchteilen überlaufen.
Zweitens: Ich kenne mich mit Verilog nicht aus, aber warum weist du 
einmal mit '=' zu und einmal mit '<=', (led = 1 und counter <= counter + 
1) wo doch beides Register sind? Hat das damit zu tun, dass counter 
mehrere Bit hat oder ist das ein Fehler?
Moderator (Firma: Titel) Persönliche Seite #4294064
Lesenswert?

Dussel schrieb:
> Zweitens: Ich kenne mich mit Verilog nicht aus, aber warum weist du
> einmal mit '=' zu und einmal mit '<=', (led = 1 und counter <= counter +
> 1) wo doch beides Register sind?
Das sind einmal "blocking" und einmal "non blocking" Zuweisungen. Das 
scheint sowas wie "Signal vs. Variable" ind VHDL zu sein...
http://www.asic-world.com/tidbits/blocking.html

> Jedoch ist die LED schon zu Beginn eingeschaltet.
Du schaust zu langsam. Lass den Zähler mal auf 100000 zählen.

> assign wclk = (counter == 8'hFF) ? 1'b0 : clk;
So werden in FPGA niemals irgendwelche (gegateten) Takte erzeugt.
Gast #4295129
Lesenswert?

ein paar Fragen:

1.also du willst das, bei/ab einem bestimmten Zählerwert, eine Led für 
einen Takt leuchten lassen?
2.der Ausgang zur Led ist das led-Register?

Also nach deinem zweiten Code-schnipsel zu urteilen... der Zähler zählt 
einmal hoch, dann wird das Register led auf 1 "gestellt", tja und danach 
kann der Zähler fröhlich weiterzählen und es passiert nichts mehr. Weil 
du stellst das led-Register ja nirgendwo mehr zurück...
ich denke daher ist es auch die ganze zeit an.
wahrscheilich registrierst du das erste hochlaufen zeitlich gar nicht 
oder hälst es für das normale "hochfahren/programmieren" des Fpgas
1
module fillRam (clk, wclk, counter, led);
2
  input clk;
3
  output wclk;
4
  output reg [24:0] counter = 0;
5
  output reg led = 0;
6
  
7
  always @(posedge clk)
8
  begin
9
    counter <= counter + 1;
10

11
    if(counter == 24'hFFF)
12
      led = 1;
13
    else if(counter != 24'hFFF)
14
      led = 0;
15

16
      
17
  end
18

19
endmodule

das wäre mein erster Verbesserungsvorschlag, aber dann leuchtet deine 
Led für nur einen Takt... das wird man kaum wahrnehmen, daher eher 
sowas:
1
 if(counter >= 24'h0FF)
2
      led = 1;
3
    else if(counter < 24'h0FF)
4
      led = 0;

würde ich als Bedingung für das Led-Register eher sowas vorschlagen.
Kostet ein bissel mehr Hardware, aber ich denke die Led sollte jetzt 
sichtbar an und ausgehen. Ohne das jetzt zeitlich berechnet zu haben.
OP Persönliche Seite #4295138
Lesenswert?

mir ist da noch ein Fehler aufgefallen
if(counter == 24'hFFFFFF) müsste es heißen.

Trundle Trollkönig schrieb:
> 1.also du willst das, bei/ab einem bestimmten Zählerwert, eine Led für
> einen Takt leuchten lassen?
ich will ein Ram mit dem Zähwert füllen, den Takt bzw ein Enable 
abschalten und eine LED leuchten lassen, wenn der Ram voll ist.
Bisher habe ich nur das hier geschrieben, damit ich sehen kann, ob das 
Füllen überhaupt funktioniert. Und damit nicht alles wegoptimiert wird, 
gebe ich den Zählerwert (8Bit) über einen Mux auf die 4 LEDs aus.

Da ich es erst mal mit einem niedrigen Takt versucht hatte, viel mir 
auf, dass die LED schon leuchtet, wenn das Füllen begonnen hat.
Und ich würde gerne verstehen warum, dass ich eine eventuelle 
Fehlerquelle bei anderen Konsrukten vermeiden kann.

Das Programm hab ich wärend des Threads abgeändert, damit man sich nicht 
an Kleinigkeiten stört.


> 2.der Ausgang zur Led ist das led-Register?
Das geht auf die LED, ja.


Wenn ich wieder am Windowsrechner bin, lade ich mal den gesamten Code 
hoch.

Gruß
Steven
Gast #4295203
Lesenswert?

Steven (. schrieb:
1
> output reg [24:0] counter = 0;

also 25 bit (alte Informatiker-Weisheit: Es ist immer eines mehr oder 
weniger, als man so denkt...)
1
>     if(counter == 24'hFFF)

* Falscher Zaehlwert (wie Du schon geschrieben hast) +
* falsche Bitbreite
1
> led = 1;

um Probleme zu vermeiden, im getakteten Prozess non-blocking, also
1
led <= 1'b1;

verwenden
Gast #4295207
Lesenswert?

eine Sache die ich überlesen habe aber schon von anderen erwähnt wurde:
defintiv würde ich das "led =" durch ein "led <=" auswechslen, damit das 
Synthesetool ein sauberes getaktetes Register aus led macht und nicht 
irgendein mischmasch.

ob die Led ein low oder ein high braucht um zu leuchten, müsstest du in 
den Layoutdaten deines Boards nachsehen.
OP Persönliche Seite #4295381
Lesenswert?

@Trollkönig und so
Wie die LED angesteuert werden muss, ist mir schon bekannt. Zudem geht 
sie ja weder an noch aus!

@Mike
Initialisieren bringt auch nix
weder mit initial noch ohne...

1
module ram_access (         //topmodul
2
   input CLK_3P3_MHZ,
3
   output reg [3:0] LEDs,
4
   input [2:0] mux
5
);
6

7
  wire [3:0] debug;  //for debugging with the LEDs
8
  
9
  wire [7:0] fifodin;
10
  
11
  
12
  always @(mux)
13
    case (mux)
14
    3'b110: LEDs = fifodin[7:4];
15
    3'b101: LEDs = fifodin[3:0];
16
    3'b011: LEDs = debug;
17
    
18
    endcase
19
    
20
  fillRam testFill(
21
    .clk(CLK_3P3_MHZ),
22
    .wclk(debug[1]), 
23
    .counter(fifodin),
24
    .led(debug[0]));
25

26
endmodule
27

28

29
module fillRam (clk, wclk, counter, led);
30
  input clk;
31
  output wclk;
32
  output reg [24:0] counter = 0;
33
  output reg led = 1'b0;
34
  
35
  always @(posedge clk)
36
  begin
37
    if(counter[22])
38
      led <= 1'b1;
39
    else
40
      counter <= counter + 1;
41
  end
42
  
43
  assign wclk = counter[20];
44

45
endmodule

Also es blinkt langsam, aber die LED ist trotzdem schon an, bevor der 
counter das bit 22 erreicht.
Gast #4295545
Lesenswert?

>     case (mux)
>     3'b110: LEDs = fifodin[7:4];
>     3'b101: LEDs = fifodin[3:0];
>     3'b011: LEDs = debug;
[/code]

da fehlt noch einiges in der sensitivity list:
1
  always @(mux, fifodin, debug)
2
    case (mux)
3
    3'b110:  LEDs = fifodin[7:4];
4
    3'b101:  LEDs = fifodin[3:0];
5
    default: LEDs = debug; // 3'b011
6
    endcase

Mit der Aenderung macht die Simulation, was du spezifiziert hast (siehe 
Anhang, der Counter hoert auf zu zaehlen, wie im Code angegeben. Ob das 
das ist, was du willst, sein mal dahingestellt.

Wenn Du das nicht in der Hardware siehst, koennte das an location 
constraints liegen, oder aber dass Deine Hardware keine Initialisierung 
kann. Das sollte aber in den Synthesedoks beschrieben sein.
Dass die Initialisierung nicht unterstuetzt wird kenne ich nur von 
ASICs, FPGAs koennen das ueblicherweise und dein counter scheint Deiner 
Beschreibung nach auch zu funktionieren.
Ich tippe mal auf location constraints - vertausch doch mal debug[0] und 
debug[1]...

Tschaebe
Angehängte Dateien:
OP Persönliche Seite #4295604
Lesenswert?

@Tschaebe
Der Mux geht auch so. Habs aber auch mit deiner Lösung getestet.

debug[0] auf [1] und umgekerht hab ich probiert, gleiche Funktion.

Nur weiß ich nicht genau worauf du mit den Constraints hinauswillst.

Ich habe eine .pcf-File:
1
# LED outputs
2
set_io LEDs[0] A29
3
set_io LEDs[1] B20
4
set_io LEDs[2] B19
5
set_io LEDs[3] A25
6

7
# 3.3 MHz clock input
8
set_io CLK_3P3_MHZ A9
9

10
# mux
11
set_io mux[0] B4 -pullup yes
12
set_io mux[1] B3 -pullup yes
13
set_io mux[2] A4 -pullup yes

Gruß
Steven
Gast #4295794
Lesenswert?

Steven (. schrieb:
> Der Mux geht auch so. Habs aber auch mit deiner Lösung getestet.

Hm, das wundert mich jetzt ein bisschen - die Simulation sollte im 
ursprünglich geposteten Design eigentlich nicht zur Synthese passen. 
Außerdem dachte ich, dass da ev. Latches generiert würden, da du ja 
nicht alle zustände des Mux ausdekodiert hast (deshalb habe ich das 
"default" Statement verwendet), aber wenn es im Synthesereport keine 
Warnungen gibt...

Steven (. schrieb:
> Ich habe eine .pcf-File:

Das sieht plausibel aus

Irgendwie denke ich, dass das Problem nicht im geposteten Code steckt. 
Was sagen den die Synthese/P&R reports und logs?

Tschaebe
Gast #4296399
Lesenswert?

Hast du auch Lattices LSE Synthese probiert, statt Synplify Pro?
Läuft viel schneller durch und das rgebnis benötigt meist auch weniger 
LUTs.
Umschalten kannst du einfach mit Rechtsklick auf Synthesis Tool.

Synplify benutze ich nur noch um Fehler im Verilog zu finden, da ist es 
etwas besser.

Dieses Modul funktioniert auf meinem IceBlink (HX, nicht LP) tadellos, 
die LEDs zählen hoch und das ganze stoppt wenn die 4.LED leuchtet:
1
module Test (CLK_3P3_MHZ, LEDs);
2
  input        CLK_3P3_MHZ;
3
  output [3:0] LEDs;
4
  reg   [23:0] counter;
5

6
always @(posedge CLK_3P3_MHZ)
7
  if(!counter[23]) counter <= counter+1;
8

9
assign LEDs = counter[23:20];
10

11
endmodule

Andi
OP Persönliche Seite #4299479
Lesenswert?

Sorry hat bissl länger gedauert.

einmal gibt es
>Warning: The terminal testFill.counter[22]:D is driven by non-default
>constant value VCC
schaut verdächtig aus :)

und was ich auch noch gefunden habe ist
>@W: MT420 |Found inferred clock ram_access|CLK_3P3_MHZ with period 7.11ns.
>Please declare a user-defined clock on object "p:CLK_3P3_MHZ"
das würde mich mal interessieren wie ich einen Clock richtig anlege...

Gruß
Steven
OP Persönliche Seite #4299488
Lesenswert?

Lothar M. schrieb:
> Steven (. schrieb:
>>> Please declare a user-defined clock on object "p:CLK_3P3_MHZ"
> Woher kommt dieser Takt?
>
>> das würde mich mal interessieren wie ich einen Clock richtig anlege...
> Du nimmst einen Clock-Eingang, legst dort den Takt an und gibst im
> Constraints File den passenden Pin dazu bekannt.

Der Takt kommt von einem externen Oszillator. Soweit bin ich schon.
Gast #4299758
Lesenswert?

Lothar M. schrieb:
> Steven (. schrieb:
>> immernoch das gleiche Problem...
> Evtl. hatten Andere schon das selbe Problem...
> Siehe den Beitrag "Lattice Diamond: A user-defined clock should be defined"

Dort geht es um Diamond, Diamond unterstützt den ICE40 nicht.

>
> Da fällt mir gerade ein: WER aus WELCHER Toolchain bringt diese Meldung?

@W: MT420 |Found inferred clock
ist eine SynplifyPro Message, d.h. er eine etwas gefunden was als Clock 
verwendet wird, und schätzt auf Grunde der Beschreibung und dem 
konfiguriertem FPGA, dass die maximal Clock 140 MHz haben sollte. Das 
hat aber eine KEINE Auswirkung auf das entscheidende P&R im Rest der 
Toolchain.
Wie man bei IceCube2 ein Timingconstraint für P&R definert weiss ich 
nicht, aber hier ist der Unterschied zwichen 3 MHz und 140 MHz wohl 
gross genug.

Ich habe mir Mal die Hilfe bei SynplifyPro vond Diamond angeschaut (da 
sind auch die Guidlines für ICE4 enthalten). Wenn ich nicht irre, 
unterstützt SynplfyPro keine Initialwerte für Register beim ICE40.
Gast #4299760
Lesenswert?

Lattice User schrieb:
>
> Ich habe mir Mal die Hilfe bei SynplifyPro vond Diamond angeschaut (da
> sind auch die Guidlines für ICE4 enthalten). Wenn ich nicht irre,
> unterstützt SynplfyPro keine Initialwerte für Register beim ICE40.

Nachtrag: Und ohne Initialwerte wird das Register eventuell als Konstant 
erkannt und wegoptimiert.
Sollte man im HDL-Analyst von SynplifyPro (Technology View) sehen 
können.
Gast #4302492
Lesenswert?

Aus dem Synthesereport:
1
@W: CS263 :"C:\Users\wagnersn\Desktop\VerilogRamTest\RamTest\main - Kopie.v":47:11:47:17|Port-width mismatch for port counter. Formal has width 25, Actual 8
2
@W: CG360 :"C:\Users\wagnersn\Desktop\VerilogRamTest\RamTest\main - Kopie.v":14:6:14:13|No assignment to wire newclock
3
@W: CG360 :"C:\Users\wagnersn\Desktop\VerilogRamTest\RamTest\main - Kopie.v":17:6:17:13|No assignment to wire fiforclk
4
@W: CG360 :"C:\Users\wagnersn\Desktop\VerilogRamTest\RamTest\main - Kopie.v":18:12:18:19|No assignment to wire fifodout
5
@W: CG360 :"C:\Users\wagnersn\Desktop\VerilogRamTest\RamTest\main - Kopie.v":20:6:20:13|No assignment to wire fifowclk

Ah, abesehen von nicht werwendeten Signalen ist der counter  25 bit 
breit, aber fifodin nur 8 bit - muss noch kein Problem sein...

aber dann
1
@N: BN362 :"c:\users\wagnersn\desktop\verilogramtest\ramtest\main - kopie.v":90:1:90:6|Removing sequential instance led in hierarchy view:work.fillRam(verilog) because there are no references to its outputs 
2
@A: BN291 :"c:\users\wagnersn\desktop\verilogramtest\ramtest\main - kopie.v":90:1:90:6|Boundary register led packed into a complex cell. To disable register packing, set syn_keep=1 on net between register and complex cell. 
3
@N: BN362 :"c:\users\wagnersn\desktop\verilogramtest\ramtest\main - kopie.v":90:1:90:6|Removing sequential instance counter[24] in hierarchy view:work.fillRam(verilog) because there are no references to its outputs 
4
@A: BN291 :"c:\users\wagnersn\desktop\verilogramtest\ramtest\main - kopie.v":90:1:90:6|Boundary register counter[24] packed into a complex cell. To disable register packing, set syn_keep=1 on net between register and complex cell.

das sieht so aus, als ob die Synthese led und counter[24] wegopimiert. 
Counter[24] ist klar, das verwendest du nie, aber led? Sollte eigentlich 
nicht, ist aber der Grund, warum deine LED nicht das tut, was du 
erwartest...

Da ich Deine toolchain nicht kenne, ein paar Vorschlaege zum Test 
(Syntheselauf und Blick aufs log reicht, verschwindet sie Message?):

1. Kannst Du mal testweise in fillRam
1
    if(counter[22])
2
      led <= 1'b1;
mit
1
    led <= counter[22];
ersetzen? (Vielleicht kommt der Syntesizer mit er Initialisierung und 
konstanten Zuweisung durcheinander (bei Xilinx gibt es da eine Warnung, 
dass man viel einsparen koennte, wennn man der Init-Wert anedern wuerde, 
sie Synthese laeuft allerdings korrekt)

2. Mal den counter nicht als output port definieren (brauchst du ja 
aktuell nicht), sodass die erste Warnung mal verschwindet.

Ein bischen wundert mich noch, dass der Synthesereport nicht weegen den 
unbenutzten ports SCK, MISI und MISO meckert, dass die oben gepostete 
Datei main - kope.v noch zum geposteten Synthesereport?

3. Entferne mal den mux und lege den Ausgang direkt auf eine LED 
(simplest system...) und definiere dabei auch LEDs[2] und LEDs[3]...

Tschaebe

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren