Forum: FPGA, VHDL & Co. Logic Analyzer Core (Logic Analyzer)


von ope (Gast)


Lesenswert?

Hi,

wie versprochen kommt forengerecht der VHDL Teil des Logik Analyser
Threads aus
http://www.mikrocontroller.net/forum/read-1-204570.html#new, der auch
der Haupt- und Initialthread ist. Wem es zu lang ist, eine halbwegs
aktuelle Zusammenfassung gibt's im Wiki
http://www.mikrocontroller.net/articles/Logic_Analyzer.

Daneben exisitiert noch:
- Pegelkomparator für High-Speed-Digital (Logic Analyzer)
http://www.mikrocontroller.net/forum/read-1-208137.html#new
- CPLD und AVR Kombo (Logic Analyzer)
http://www.mikrocontroller.net/forum/read-9-207389.html#new

Derzeit arbeitet Dirk am SRAM Interface und ich am Trigger; so nun zu
meinem Problem - irgendwie ist mein Gehirn während des Urlaubs
eingerostet (oder ich habe ein grundlegendes Problem):
1
entity counter_g is
2
  generic(
3
    BIT_WIDTH : positive  := 8;
4
    CLOCK_ENABLE: boolean := true;
5
    DOWN_COUNTER: boolean := false;
6
    LOADABLE    : boolean := false;
7
    RESET_ACTIVE: std_logic := '1'
8
  );
9
  port(
10
    clk   : in  std_logic;        -- rising edge trigger count
11
    reset   : in  std_logic;        -- asynchronous reset
12
    en      : in  std_logic := '0';   -- clock enable, high active
13
    ld      : in  std_logic := '0';   -- data load with rising edge 
14
    data    : in  std_logic_vector(BIT_WIDTH-1 downto 0) := (others =>
15
'0');-- preload data
16
    count   : out std_logic_vector(BIT_WIDTH-1 downto 0)  -- counter
17
output
18
  );
19
end counter_g;
20
21
22
architecture behavioral of counter_g is
23
  signal m_count : std_logic_vector(BIT_WIDTH-1 downto 0);
24
begin
25
  process(clk, reset)
26
  begin
27
    if(reset = RESET_ACTIVE) then
28
      m_count <= (others => '0');
29
    elsif(rising_edge(clk)) then
30
      if(LOADABLE) then
31
        if(ld = '1') then
32
          m_count <= data;
33
        end if;
34
      end if;
35
      if(CLOCK_ENABLE) then
36
        if(en = '1') then
37
          if(not DOWN_COUNTER) then
38
            m_count <= m_count + 1;
39
          else
40
            m_count <= m_count - 1;
41
          end if;
42
        end if;
43
      else
44
        if(not DOWN_COUNTER) then
45
          m_count <= m_count + 1;
46
        else
47
          m_count <= m_count - 1;
48
        end if;
49
      end if;
50
    end if;
51
  end process;
52
53
  count <= m_count;
54
55
end behavioral;

möchte ich gerne überall einsetzten. Konkret hier für einen Trigger hit
counter, d.h. in einer entity setze ich trig_hit auf '1', wenn das
bit/edge pattern gefunden wurde. Es soll nun n-mal auftauchen um den
Capture auszulösen (hier noch nicht implementiert). Die Variante, die
den Counter benutzt "cntrl_proc", klappt nicht so, wie ich es
eigentlich wie in "proc" haben möchte:
1
entity hitlength_trigger is
2
  generic(
3
    COUNT_BITS    : positive := 5;
4
    RESET_ACTIVE  : std_logic := '1'
5
  );
6
  port(
7
    clk         : in  std_logic;
8
    reset       : in  std_logic;
9
    trig_hit    : in  std_logic;    
10
    n_hits      : in  std_logic_vector(COUNT_BITS-1 downto 0);
11
    match       : out std_logic
12
  );
13
end hitlength_trigger;
14
15
16
architecture behavioral of hitlength_trigger is
17
18
  signal m_reset    : std_logic := not RESET_ACTIVE;
19
  signal m_clear    : std_logic := not RESET_ACTIVE;  
20
  signal m_hitcount : std_logic_vector(COUNT_BITS-1 downto 0);
21
  signal m_hitcount2: std_logic_vector(COUNT_BITS-1 downto 0);
22
23
begin
24
25
  cnt_i: entity work.counter_g
26
  generic map(
27
    BIT_WIDTH     => COUNT_BITS,    -- max N clock cycles
28
    RESET_ACTIVE  => RESET_ACTIVE,
29
    CLOCK_ENABLE  => true,
30
    LOADABLE      => false
31
  )
32
  port map(
33
    clk       => clk,
34
    reset     => m_reset,
35
    count     => m_hitcount,
36
    en        => trig_hit,
37
    ld        => open,      -- warning on input never used
38
    data      => open     -- warning on input never used
39
    );
40
41
   m_reset <= reset or m_clear;
42
43
  ctrl_proc: process(reset, clk, trig_hit)
44
  begin
45
46
    if(reset = RESET_ACTIVE) then
47
      match   <= '0';
48
    elsif rising_edge(clk) then
49
      if(trig_hit = '0') then
50
        m_clear <= RESET_ACTIVE;
51
      else
52
        m_clear <= not RESET_ACTIVE;
53
      end if;
54
    end if;
55
56
  end process;
57
58
59
  proc: process(clk, reset)
60
  begin
61
    if(reset = RESET_ACTIVE) then
62
      m_hitcount2 <= (others => '0');
63
    elsif rising_edge(clk) then
64
      if(trig_hit = '0') then 
65
        m_hitcount2 <= (others => '0');
66
      else
67
        m_hitcount2 <= m_hitcount2 + 1;
68
      end if;
69
    end if;
70
  end process;

Die Entities sind noch im Design Stadium, also noch nicht komplett. Das
unterschiedliche Verhalten ist im TB zu sehen:
1
entity tb_hitlength_trigger is
2
end tb_hitlength_trigger;
3
4
architecture behavior of tb_hitlength_trigger is 
5
6
   constant COUNT_BITS: positive  := 5;
7
   constant PERIOD  : time      := 10 ns;   
8
   
9
   signal clk     : std_logic     := '0';
10
   signal reset     : std_logic     := '0';
11
   
12
  --inputs
13
  signal n_hits   : std_logic_vector(COUNT_BITS-1 downto 0) := (others
14
=> '0');
15
  signal hit      : std_logic := '0';
16
17
  --outputs
18
  signal match    : std_logic := '0';
19
   
20
begin
21
22
  -- instantiate the unit under test (uut)
23
  uut: entity work.hitlength_trigger
24
  generic map(
25
    COUNT_BITS  => COUNT_BITS
26
  )
27
  port map(
28
    clk     => clk,
29
    reset     => reset,
30
    n_hits    => n_hits,
31
    trig_hit    => hit,
32
    match     => match
33
  );
34
35
   -- sample clock
36
   clock_proc: process(clk)
37
   begin
38
      clk <= not clk after PERIOD/2;
39
   end process;
40
   
41
42
  tb : process
43
  begin
44
   
45
      reset <= '1';
46
47
    -- wait for global reset to finish
48
    wait for PERIOD;
49
    reset <= '0';
50
    
51
    -- simulate trigger hit
52
    wait for PERIOD;
53
    hit <= '1';
54
55
    wait for 2*PERIOD;
56
      hit <= '0';
57
58
      -- finish      
59
      write(output, string'("TB done."));
60
      
61
    wait; -- will wait forever
62
  end process;
63
64
end;

Konkret zählt ctrl_proc einen hit zu wenig und geht nicht wieder auf
Null, wenn trig_hit != 0 ist.

Tja, wie bekomme ich das Verhalten von proc in ctrl_proc realisiert,
ich grübbele schon den ganzen Tag 'dran.

Viele Grüße
Olaf

PS: Da es keine Vorschau gibt - ist es für das nächste mal besser die
sourcen als Anhang zu machen?

von high_speed (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Olaf

Beim ersten Überschauen über deinen Code ist mir aufgefallen, dass du
viel mit verschachtelten IF- Strukturen arbeitest.

Für die Übersichtlichkeit finde ich das nicht gerade optimal.
Der Code wird so nur länger und schwerer durchschaubar.
1
-- deine Version
2
if(LOADABLE) then 
3
   if(ld = '1') then 
4
      m_count <= data; 
5
   end if; 
6
end if; 
7
8
-- meine Version
9
if LOADABLE and ld = '1' then 
10
   m_count <= data; 
11
end if;

> Konkret zählt ctrl_proc einen hit zu wenig und geht
> nicht wieder auf Null, wenn trig_hit != 0 ist.

> m_reset <= reset or m_clear;

...

> elsif rising_edge(clk) then
>   if(trig_hit = '0') then
>      m_clear <= RESET_ACTIVE;
>   else
>      m_clear <= not RESET_ACTIVE;
>   end if;
> end if;

m_clear wird im schlimmsten Fall um eine Taktperiode verzögert.
Der Reset wird doch bei trig_hit = '0' gemacht?
Deine OR- Verknüpfung solltest du noch mal überdenken.
Dein Quelltext machst du sehr flexibel, aber dieses OR macht alles
wieder zugrunde.

Warum willst du mit aller Gewalt ein Zählerdesign nutzen?

> Tja, wie bekomme ich das Verhalten von proc
> in ctrl_proc realisiert, ich grübbele schon
> den ganzen Tag 'dran.

Weist du was der Vorteil von proc gegenüber ctrl_proc ist?
Mann kann es einfach lesen und versteht es sofort.

Wenn man ein Projekt in Teilefunktionen zerlegt, muss das eine Sinn
machen. Nur für deinen Zähler sehe ich da einfach keinen Sinn.
Du musst dir nur mal überlegen, wo welches Signal herkommt und um wie
viele Takte es gegenüber einem anderen verschoben ist.

Im Anhang ist dein Zähler ein bisschen aufgeräumt.

MfG
Holger

von high_speed (Gast)


Angehängte Dateien:

Lesenswert?

Noch einmal vereinfacht. :-)

MfG
Holger

von ope (Gast)


Lesenswert?

>Beim ersten Überschauen über deinen Code ist mir aufgefallen, dass du
>viel mit verschachtelten IF- Strukturen arbeitest.
>
>Für die Übersichtlichkeit finde ich das nicht gerade optimal.
>Der Code wird so nur länger und schwerer durchschaubar.

das kommt vom "Kästchen"-Denken - da muss ich meiner Brainware mehr
Flexibilität antrainieren ;-)

>m_clear wird im schlimmsten Fall um eine Taktperiode verzögert.

das würde auch das "Eins-zu-wenig-gezählt" erklären.

>Der Reset wird doch bei trig_hit = '0' gemacht?

yep, es kommt kein trigger hit und der counter wird zurück gesetzt. Vom
Prinzip her ist es ein Monoflop.

>Deine OR- Verknüpfung solltest du noch mal überdenken.
>Dein Quelltext machst du sehr flexibel, aber dieses OR macht alles
>wieder zugrunde.

wie soll ich es anders lösen? Am reset "Knopf" des Zählers zerrt zum
einem der reset der ganzen entity und zum anderen der interne reset
m_clear aus ctrl_proc.

>Warum willst du mit aller Gewalt ein Zählerdesign nutzen?

Evtl. versuche ich die reuseablity etwas auf die Spitze zu treiben, das
mag sein ;-) und wenn ich sehe, wieviel Zeit ich darin bereits
reingesteckt habe ... Aber rein hypothetisch/interessenhalber, wie kann
man es machen?

Auch muss ich noch einen Vergleich einführen auf eine vorgegebene
Anzahl von hit events, zB. 3 clock periods continuous trig_hit. Was
wird besser synthetisiert, ein Vergleich (cnt = cnt_soll) oder einen
Zähler mit cnt_soll laden und runterzählen und bei cnt=0 den match
ausgeben? Daher auch die Idee mit der Zähler entity.

Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

inzwischen habe ich die einzelnen trigger condition entities (zum
Großteil) zusammen und wollte sie in einen gemeinsamen "trigger"
verpacken.

In diesem Testbench ist mir nun aufgefallen, dass der match m_hitlength
2 Takte später kommt als ich ich erwartet hätte (1 Takt). Im Testbench
für hithlength_trigger kommt er wie erwartet mit der nächsten
steigenden Flanke.

Woran liegt diese unerwartete Verzögerung eines Clocks und wie kann ich
sie umgehen, da ich ja alles nur zusammen geknippert habe.

Letzlich werden die Ereignisse auseinandergezogen, wodurch imo die
Kausalität verloren geht, wenn dann alles x Takte später kommt.

Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

hier mal ein Bild vom TB.

von ope (Gast)


Angehängte Dateien:

Lesenswert?

Neuer Tag, neues Problem:
1
entity latch_g is
2
  generic(
3
    BIT_WIDTH : positive  := 8;
4
    RESET_ACTIVE: std_logic := '1'
5
  );
6
  port(
7
    clk     : in  std_logic;
8
    reset     : in  std_logic;
9
    en        : in  std_logic;
10
    D       : in  std_logic_vector(BIT_WIDTH-1 downto 0);
11
    Q       : out std_logic_vector(BIT_WIDTH-1 downto 0)
12
  );
13
end latch_g;
14
15
16
architecture behavioral of latch_g is
17
18
  constant ZERO : std_logic_vector(BIT_WIDTH-1 downto 0) := (others =>
19
'0');
20
21
begin
22
23
  process(clk, reset, en, D)
24
  begin
25
    if(reset = RESET_ACTIVE) then
26
      Q <= ZERO;
27
    elsif rising_edge(clk) then
28
      if(en = '1') then
29
        Q <= D;
30
      end if;
31
    end if;
32
  end process;
33
34
end behavioral;

Der Entity name ist nicht ganz korrekt, besser währe wohl register,
aber was soll's.
1
entity la is
2
  generic(
3
    BIT_WIDTH   : positive  := 16;  -- probe bit width
4
    RESET_ACTIVE  : std_logic := '1'
5
  );
6
  port(
7
    clk     : in  std_logic;    -- Master clock
8
    reset     : in  std_logic;    -- asynchr. reset
9
    probe     : in  std_logic_vector(BIT_WIDTH-1 downto 0);
10
  );
11
end la;
12
13
14
architecture behavioral of la is
15
16
  signal sample_en  : std_logic;
17
  signal sample_t0  : std_logic_vector(BIT_WIDTH-1 downto 0);
18
  signal sample_t1  : std_logic_vector(BIT_WIDTH-1 downto 0);
19
  signal sample_trans: std_logic;
20
  
21
begin
22
23
  -- TEST ONLY
24
  sample_en <= '1';
25
26
  probe_latch_i: entity work.latch_g
27
  generic map(
28
      BIT_WIDTH => BIT_WIDTH,
29
      RESET_ACTIVE   => RESET_ACTIVE
30
  )
31
  port map(
32
    clk   => clk,      -- sample clock
33
    reset   => reset,
34
    en   => sample_en,
35
    D   => probe,
36
    Q   => sample_t0
37
  );
38
39
   sample_proc: process(clk, reset, sample_t0)
40
41
    constant ZERO : std_logic_vector(BIT_WIDTH-1 downto 0) := (others
42
=> '0');
43
44
   begin
45
      
46
      -- synchronuous store sample t-1
47
    if(reset = RESET_ACTIVE) then
48
      sample_t0   <= ZERO;
49
      sample_t1   <= ZERO;
50
      sample_trans <= '0';
51
      elsif rising_edge(clk) then
52
         sample_t1 <= sample_t0;   -- sample(t-1) <= sample(t0)   
53
54
         if(sample_t0 /= sample_t1) then
55
             sample_trans <= '1';
56
         else   
57
             sample_trans <= '0';
58
         end if;
59
      end if;  
60
   end process;
61
   
62
end behavioral;

und nun der TB:
1
architecture behavior of tb_la is 
2
3
   -- Constants
4
   constant PERIOD  : time   := 10 ns;   
5
   
6
   --Inputs
7
   signal clk :  std_logic := '0';
8
   signal reset :  std_logic := '0';
9
   signal probe :  std_logic_vector(7 downto 0) := (others=>'0');
10
11
begin
12
13
   -- simulate DUT, signals are slower than LA clk
14
   my_probe: block
15
      signal clk   : std_logic := '0';
16
   begin
17
      probe_clk_proc: process(clk)
18
      begin
19
         clk <= not clk after 3*PERIOD/5;
20
      end process;
21
22
      probe_prbs_i: entity work.LFSR8
23
      port map(
24
         clk   => clk,
25
         q   => probe 
26
      );  
27
   end block;
28
29
  -- Instantiate the Unit Under Test (UUT)
30
  uut: entity work.la
31
  generic map(
32
      BIT_WIDTH => 8,
33
      RESET_ACTIVE   => '1'    
34
  )
35
  port map(
36
    clk => clk,
37
    reset => reset,
38
    probe => probe,
39
    led_0 => led_0,
40
    led_1 => led_1
41
  );
42
43
   -- clock
44
   clock_proc: process(clk)
45
   begin
46
      clk <= not clk after PERIOD/2;
47
   end process;
48
   
49
  tb : process
50
  begin
51
52
    write(output, string'("run this TB 100 ns!"));
53
    reset <= '1', '0' after PERIOD;
54
    wait; -- will wait forever
55
56
  end process;
57
58
end;

Das verblüffende ist im Screenshot zu sehen, er übernimmt die Samples
von Probe nict in sample_t0. Anscheinend werden nur die '0'
übernommen.

Sinnigerweise bekomme ich die Warnung

All outputs of the instance <probe_latch_i> of the block <latch_g> are
unconnected in block <la>.

bei der Synthese. Ich behaupte jedoch, es richtig verknippert zu haben
- oder wer reisst mit das Brett vor'm Kopf weg?

Viele Grüße
Olaf

von Dirk (Gast)


Lesenswert?

Hi,

wenn es sich um vectoren handeln musst du diese auch mit angeben beim
connecten. z.B. portx(7 downto 0) => output(7 downto 0)

Gruß,
Dirk

von FPGA-User (Gast)


Lesenswert?

@Dirk
muss man nicht, es sei denn, sie haben unterschiedliche Bit-Breiten.

von Dirk (Gast)


Lesenswert?

Hi,

@FPGA-USER

hm ich hatte das selbe Problem und konnte es nur so loesen. Ich dachte
auch das es nur bei unterschiedlichen Bitbreiten angegeben werden muss.


Es soll nur ein Tipp sein und Ope kann es mal gerne ausprobieren. Waere
nett ein Feedback zukriegen.

Gruß,
Dirk

von Jörn (Gast)


Lesenswert?

>signal clk :  std_logic := '0';
>signal reset :  std_logic := '0';
>signal probe :  std_logic_vector(7 downto 0) := (others=>'0');

Lass mal die (others=>'0') Zuweisung weg. Zu hast zwei oder mehrere
Treiber, die auf sample_t0 gegeneinander arbeiten. Anders kann ich mir
es im Moment nicht erklären.

Gruß Jörn

von ope (Gast)


Lesenswert?

die defaults bei probe habe ich weggelassen, es half leider nichts. MXE
auch:

Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
operand, the result will be 'X'(es).
#    Time: 25 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 35 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 35 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 45 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 45 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 55 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 55 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 65 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 65 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 75 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 75 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 85 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 85 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 95 ns  Iteration: 0  Instance: /tb_la8/uut
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 95 ns  Iteration: 0  Instance: /tb_la8/uut

nichts neues aber auch nicht sehr hilfreich imo. Jede einzelne Entity
in ihrem TB funktioniert wie erwartet, nur für TB_la net :/

Was mich irritiert ist die Warnung von XST: All outputs of the instance
<probe_latch_i> of the block <latch_g> are unconnected in block <la>.

Versuche ich mir die RTL Schematics bzw Technologie Schematics
anzusehen, sind diese leer!

Viele Grüße
Olaf


PS: Ein
sample_t1(BIT_WIDTH-1 downto 0) <= sample_t0(BIT_WIDTH-1 downto 0)
hat auch nichts gebracht.

von ope (Gast)


Angehängte Dateien:

Lesenswert?

habe eben die Konstante
ONE : std_logic_vector(7 downto 0) := (others => '1');
im TB eingeführt und den Eingang probe der entity la damit verbunden
und bekomme als wave diesmal nur XXXXX, siehe Anhang. Evtl. hilft ja
dies.

von Jörn (Gast)


Lesenswert?

Kannst du deinen akutellen Stand mal anhängen.

von ope (Gast)


Angehängte Dateien:

Lesenswert?

habe eben die Stelle ausfindig gemacht, an der die Probleme verursacht
werden, aber warum ist mir noch nicht klar:

[vhd]

   sample_proc: process(clk, reset, sample_t0)

    constant ZERO : std_logic_vector(BIT_WIDTH-1 downto 0) := (others
=> '0');

   begin

      -- synchronuous store sample t-1
    if(reset = RESET_ACTIVE) then
--      sample_t0   <= ZERO;
--      sample_t1   <= ZERO;
        sample_trans <= '0';
      elsif rising_edge(clk) then

[/vhdl]

und es gibt nur noch eine Warnung von MXE:

Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
operand, the result will be 'X'(es).
#    Time: 15 ns  Iteration: 0  Instance: /tb_la8/uut

die, so denke ich, von dem uninitialisierten Werten her kommen dürfte.


Ich mache demnächst ein Archive vom aktuellen Stand.

Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

da isser.

von ope (Gast)


Lesenswert?

ich denke, ich habe es:
1
   smpl_t1_proc: process(clk, reset, sample_t0)
2
3
    constant ZERO : std_logic_vector(BIT_WIDTH-1 downto 0) := (others
4
=> '0');
5
6
   begin
7
      
8
      -- synchronuous store sample t-1
9
    if(reset = RESET_ACTIVE) then
10
--      sample_t0   <= ZERO;
11
        sample_t1   <= ZERO;
12
      elsif rising_edge(clk) then
13
         sample_t1 <= sample_t0;   -- sample(t-1) <= sample(t0)   
14
    end if;  
15
   end process;

Ich darf im reset process sample_t0 nicht resetten. Evtl., weil dies
bereits im probe_latch_i geschieht? Aber warum dieses so nachhaltige
Wirkung zeigt, ist mir allerdings ein Rästel.

Das sich bei diesem synchronen? (bis auf dem reset) Design alles
verzögert, ist schon ätzend imo. Hier bekomme ich zB. einen Takt später
mit, dass sich die sampels geändert haben; kann es also im TB nicht mehr
so einfach nachprüfen. Für die Cotrl Logik wird's dann interessant.

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

ein weiterer Tag ;-)
1
entity la_config is
2
  port(
3
    hw_conf_field : in  std_logic_vector(3 downto 0);
4
    num_of_sram   : out std_logic_vector(1 downto 0); -- max=4
5
    error       : out std_logic
6
  );
7
end la_config;
8
9
10
architecture behavioral of la_config is
11
12
begin
13
  
14
  sram_conf_proc: process(hw_conf_field)
15
  begin
16
    -- Bit 0,1: number of sram soldered
17
    case hw_conf_field(1 to 0) is
18
      when "01"   => num_of_sram <= conv_std_logic_vector(1, 2); -- 1
19
sram
20
      when "10"   => num_of_sram <= conv_std_logic_vector(1, 2); -- 2
21
sram
22
      when others => num_of_sram <= (others <= '0'); -- Line 45
23
                error <= '1';
24
    end case;
25
  end process;
26
27
end behavioral;

xst error:

Line 45. parse error, unexpected LE, expecting PIPE or ROW
Line 43. String literal "01" is not of size 0.
Line 44. String literal "10" is not of size 0.

Die erwartete size 0 verblüfft mich doch etwas, ist hier ein Syntax
Fehler? Wenn ich schreibe b"01" ändert dies auch nichts.

Viele Grüße
Olaf

von Jörn (Gast)


Lesenswert?

> case hw_conf_field(1 to 0)

müßte das nicht "downto" heißen?

von ope (Gast)


Lesenswert?

>müßte das nicht "downto" heißen?

yep - danke!, damit bleibt nur noch der Fehler auf Line 45. Ich habe
aber auch schon solche Sachen mit "to" gesehen, allerdings in einem
anderem Zusammenhang. Wann nimmt man eigentlich "downto" und "to"?

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

ich bin verblüfft:
1
  when others => num_of_sram <= conv_std_logic_vector(0, 2);

funktioniert? Aber wieso denn nicht mit (others <= '0') ?

von Jörn (Gast)


Lesenswert?

Weil es "(others=>'0');" heißen sollte ;)

Kommt drauf an wie du deinen Std_logic_vector zusammenbaust. Beides
müßte funktionieren:
(2 downto 0) oder (0 to 2)

Wenn du in deiner ersten Version 0 to 1 geschrieben hättest, wäre es
auch gegangen.

von ope (Gast)


Lesenswert?

aja, das kleine Syntaxteufelchen :-) Jetzt ist der Unterschied auch
klar.

Momentan versuche ich einiges in packages und records zu packen, um den
Überblick nicht zu verlieren und hänge hierbei:
1
package la_pkg is
2
3
  subtype pcb_ver_t is std_logic_vector(2 downto 0); -- config fields =
4
3, max=8
5
6
  type num_sram_t is (  -- config fields = 2
7
    SRAM_N0,    -- internal used (FPGA)
8
    SRAM_N1,    -- external sram = 1  -- option #1
9
    SRAM_N2,    -- external sram = 2  -- option #2
10
    SRAM_N3   -- external sram = 3
11
  );
12
13
  type la_config_t is
14
  record
15
    pcb_ver     : pcb_ver_t;  -- I/O fields=3
16
    num_sram      : num_sram_t;   -- I/O fields=2
17
  end record;
18
19
  ...
20
21
  -- will nicht, wäre aber sehr nützlich; casts wie positive()
22
  -- hilft nicht.
23
  constant LA_CONF_FIELD_WIDTH  : positive 
24
    := (num_sram_t'high) + (pcb_ver_t'high);
25
26
end la_pkg;

- wie kann ich im Nachhinein die Größe des Vectors bestimmen von
selbstdefinierten typen?
- wie kann ich attribute wie length zB für num_sram_t implementieren
1
package body la_pkg is
2
  attribute length of num_sram_t : is ????
3
  ...
- der record soll an den I/O Port, wie kann ich die bitreihenfolge
absolut herausbekommen - entspricht die Reihenfolge der Typen einer
Bitfolge am Port anschliessend?

Ich wollte ungefähr so weiter machen:
1
entity la_config is
2
  port(
3
    hw_conf_field : in  std_logic_vector(LA_CONF_FIELD_WIDTH-1 downto
4
0);
5
    has       : out la_config_t;
6
    error       : out std_logic
7
  );
8
end la_config;
9
10
11
architecture behavioral of la_config is
12
13
begin
14
  
15
  conf_proc: process(hw_conf_field)
16
  begin
17
18
    ...
19
    has.pcb_ver     <= hw_conf_field(5 downto 3); -- funzt
20
    has.num_sram    <= hw_conf_field(7 downto 6);
21
22
    -- check for misc configurations
23
    error         <= '0';
24
25
  end process;
26
27
end behavioral;

da gibt's den Error:
Line 49. Type of . is incompatible with type of hw_conf_field.

Schade ist's auch, dass ich für machen records für in und welche für
out machen muss, da beides nicht in einem geht.

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

edit : line 49 ist dabei
1
has.num_sram    <= hw_conf_field(7 downto 6);

von ope (Gast)


Lesenswert?

hat keiner eine Lösung? Es ist ein generelles Problem.

Versuche es mit einer Konvertierungsfunktion; klappt aber auch nicht so
recht:
1
  type bitwidth_t is (  -- config fields = 3
2
    BIT_WIDTH_8,
3
    BIT_WIDTH_16,
4
    BIT_WIDTH_24,
5
    BIT_WIDTH_32,
6
    BIT_WIDTH_40,
7
    BIT_WIDTH_48,
8
    BIT_WIDTH_56,
9
    BIT_WIDTH_64
10
  );
11
12
  ...
13
14
  function to_bitwidth(vec : std_logic_vector) return bitwidth_t is
15
    variable bw : bitwidth_t;
16
  begin
17
    case (vec) is -- LINE 137
18
      when x"0" => bw := BIT_WIDTH_8;
19
      when x"1" => bw := BIT_WIDTH_16;
20
      when x"2" => bw := BIT_WIDTH_24;
21
      when x"3" => bw := BIT_WIDTH_32;
22
      when x"4" => bw := BIT_WIDTH_40;
23
      when x"5" => bw := BIT_WIDTH_48;
24
      when x"6" => bw := BIT_WIDTH_56;
25
      when x"7" => bw := BIT_WIDTH_64;
26
      -- avoid xst error, all bitwidth are handled.
27
      when others => bw := BIT_WIDTH_64;
28
    end case;
29
    return bw;
30
  end;

mit Line 137. Selector (Constant 'vec' of type std_logic_vector) is
an unconstrained array.

Tja, wie bekommt man das hin? mit to_integer(vec) gibt's:
Line 137. to_integer can not have such operands in this context.

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

so, endlich mal ein pasendes Thema:
1
entity hitlength_trigger is
2
   generic (
3
      BIT_WIDTH   : positive := 8;
4
      RESET_ACTIVE  : std_logic := '1'
5
   );
6
   port (
7
      clk       : in  std_logic;
8
      reset       : in  std_logic;
9
      trig_hit      : in  std_logic;    
10
      hit_length    : in  std_logic_vector(BIT_WIDTH-1 downto 0);
11
      match       : out std_logic
12
   );
13
end hitlength_trigger;
14
15
16
architecture behavioral of hitlength_trigger is
17
18
   signal m_hitcount : std_logic_vector(BIT_WIDTH-1 downto 0);
19
   constant ZERO   : std_logic_vector(BIT_WIDTH-1 downto 0) := (others
20
=> '0');
21
22
begin
23
24
   proc: process (clk, reset) is
25
   begin
26
27
      if (reset = RESET_ACTIVE) then
28
         m_hitcount <= (others => '0');
29
         match <= '0';
30
      elsif rising_edge(clk) then
31
         if (trig_hit = '0') and (hit_length /= ZERO) then 
32
            m_hitcount <= (others => '0');
33
         elsif (hit_length /= ZERO) then
34
            m_hitcount <= m_hitcount + 1;
35
         end if;
36
37
         if (m_hitcount = hit_length) and (hit_length /= ZERO) then
38
            match <= '1';
39
         end if;
40
      end if;
41
42
   end process;
43
44
end behavioral;

Er macht das schon ganz ordentlich - hat einen Fehler: Er zählt zB.
einen hit mit einer clk cycle Länge nicht - konsequenter Weise steht
der m_hitcount bei zwei clk cycle Länge bei eins; zählt also immer eins
zuwenig. Das ist aufgrund des synchronen Designs, wie ich ihn aber zum
"richtig zählen" überzeugen kann, ist mir noch ein Rätsel. Auch der
work-arround für hit_length /= ZERO ist etwas hässlich. Hat jemand Rat
und Lösung?

Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

ein Bild sagt mehr .... Er sollte bei t=65ns eigentlich einen match =
'1' liefern.

von ope (Gast)


Lesenswert?

Mit dem hitlength_trigger ist noch immer im Raum, keine Lösung?

Ich probiere mich momentan mit configurationen aus:
1
entity ram_1536x16 is
2
   generic (
3
      RESET_ACTIVE   : std_logic := '1';
4
      ...
5
   );
6
   port (
7
      clk            : in  std_logic;
8
      ...
9
   );
10
end entity ram_1536x16;
1
architecture RAMB4_S16_banking of ram_1536x16 is
2
   ...
3
end architecture RAMB4_S16_banking;
1
architecture infering of ram_1536x16 is
2
   ...
3
end architecture infering;

und nun der Testbench mit dem Fehler:
** Error: ../source/tb_vhdl/TB_ram_1536x16.vhd(33): (vcom-1141)
'ram_1536x16' is not a component declaration
1
entity tb_ram_1536x16 is
2
end entity tb_ram_1536x16;
3
4
architecture behavioral of tb_ram_1536x16 is
5
6
   for all : ram_1536x16 use entity work.ram_1536x16(infering); -- 33
7
8
   ...
9
begin
10
   ...
11
end architecture behavioral;

So habe ich es zumindest aus den Büchern so verstanden. Wie geht es
richtig?

Viele Grüße
Olaf

von unknown (Gast)


Lesenswert?

probier mal:

for all ram_1536x16 : use entity work.ram_1536x16.infering;

von ope (Gast)


Lesenswert?

Ist das nicht der Syntax, wie er in configurationen benutzt wird? D.h.
nach der arch noch conf ... In der archirecture selbst funzt es nicht.

von ope (Gast)


Angehängte Dateien:

Lesenswert?

OK, für folgende Probleme habe ich noch keine Lösung:

* [http://www.mikrocontroller.net/forum/read-9-234597.html#241016
hitlength]
* [http://www.mikrocontroller.net/forum/read-9-234597.html#241453 vhdl
configuration]

Ganz neu: internes sram timing eines xc2s... Das schreiben und lesen
des blockrams klappt schon recht gut. Allerdings werden alle Aktionen
auf rising_edge ausgeführt. Das hat zur Folge, das ich (ich vermute es
mal) einen Takt später auch "ein" schreibe, und man kann es im TB
auch sehen, beim Auslesen meine Daten einen Takt später bekomme.

Sehe ich mir das Timing Modell im Datenblatt
[http://direct.xilinx.com/bvdocs/publications/ds001.pdf S.35] an, so
muss/sollte die Adresse vor rising edge anliegen damit spätestens zu
fallend Flanke die Daten von der Adresse anliegen. Dies ist derzeit
nicht der Fall.

So, nun die Frage dazu: Handel ich mir damit Ärger ein, da der ram
nicht registered ist? Auf rising/falling edge irgendwelche Aktionen zu
machen, wurde irgendwo hier im Forum als kontraproduktiv eingestuft.
Wäre eine neg. clock Signal => clk180 und rising edge darauf eine
Hilfe? Was macht man wie kleverer Weise?

Nachfolgend der Anfang einer Schreib- und Lesesequenz. Man beachte, ich
schreibe (hoffentlich) auf Adr. 0x00 den Wert 0xFFD3 und lese dann bei
0x00 0x16E8 (wo immer die her kommen mögen), welches imo irgendwelcher
Datenmüll ist (Erklärung/Lösung gesucht) und auf dem nachfolgenden
rising_edge meine 0xFFD3 wieder - eben 1 clk cylce verzögert.


Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

schreibe

von ope (Gast)


Angehängte Dateien:

Lesenswert?

lese

von ope (Gast)


Angehängte Dateien:

Lesenswert?

als zip

von ope (Gast)


Angehängte Dateien:

Lesenswert?

für folgende Probleme habe ich noch immer keine Lösung:

* [http://www.mikrocontroller.net/forum/read-9-234597.html#241016
hitlength]
* [http://www.mikrocontroller.net/forum/read-9-234597.html#241453 vhdl
configuration]

Inzwischen bin ich wegen der sram Ansteuerung (Timing) in der 6 Version
angekommen, mit der FSM ist evtl. doch gar nicht so schlecht, erspare
ich mir den mux/demuxer und die Kopfstände innerhalb der fsm wegen der
Ansteuerung dieser.

Kurz zum Prinzip: XC2S100 hat 40.960 bit.
- Speicher organisiert zu 512x80 (infering z.Zt., using blockram hat
noch einen nebensächlichen bug derzeit)
- Sampels bestehen aus 10 bit timestamp und den eigentlichen Samples zu
16bit; allg. unter dem Term "samples" desweiteren benutzt
- somit passen in die 80 bit 3 sample tuple, diese werden in der fsm
eingeschrieben.
- ausgelesen werden diese 80 bit byte weise durch die fsm.
- kont. Schreiben in den Ringbuffer (noch zu implementieren)
- bei aquire Startaddr. merken und bis zu x% Vorgeschichte
vollschreiben (noch zu implementieren)

Problem:
- Beim Auslesen fehlt das erste Byte. Keine Idee, wie ich
sinnvollerweise da ran kommen, habe schon einen 'pre'-state rd_state
vor den eigentlichen rd_b{0-11}_state gesetzt, ein weiterer sollte an
sich nicht nötig sein. Evtl. schreibe ich aber in das erste Byte Mist,
aber eher unwahrscheinlich durch die (2+8) byte des Timestamps.
- Warning mit unbekannter Ursache:
# run this TB 32 us!** Warning: There is an
'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will
be 'X'(es).
#    Time: 16040 ns  Iteration: 1  Instance: /tb_sample_ram/dut/fsm
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an
arithmetic operand, the result will be 'X'(es).
#    Time: 16040 ns  Iteration: 2  Instance: /tb_sample_ram/dut/fsm

Sonstiges:
- Hinweise für den Aquire Mode?

Viele Grüße
Olaf

von ope (Gast)


Angehängte Dateien:

Lesenswert?

hier die interessante Stelle.

von ope (Gast)


Lesenswert?

0 download vom src vom 23.10.2005 17:14 ?? Hat denn keiner Interesse
mehr am logic analyser?

von Antti (Gast)


Lesenswert?

Hi Ope,

was erwartest du denn?

ein LA ist etwas dass aller gerne haben mochten, ofr frei oder
supergunstig. ein LA ipcore zu entickeln ist eigentlich kein grosseres
problem. auch die auswertung software ist nicht so schwer. und die
firmware kommunikation ist auch nichts schweres. aber das bedeutet noch
langst nicht das es so einfach ist ein 'einfaches und benutzbares
produkt' fertig zu kriegen :( lettzendlich muss jemand die handbucher
usw weiteres auch erledigen und das ist für ide hardcore entwickler
extrem langweilig.

ICH bin SEHR interessiert an LA, oder besser im OCI (On Chip
Instrumenation), dh LA inside FPGA, mess funktionenn in FPGA und mit
FPGA, aber dieses projekt hier, well... etwas fehlt. etwas fehlt um
wirklich erfolgreich zu sein.

erstens es gibt kein richtiges ziel.

falls das ziel ist unter 100EUR ein LA zu bauen denn die beste loesung
ware USB powered XC3S100E evalikit als 'basis' zu benutzen, es koster
69USD un hat 50 poliges stecker drauf. da kann mann adapter module haben
fur comparator und zusats speicher, etc.. basis system (evalkit +
adapter platine) bleibt immerhin unter 100EUR.

falls das ziel ist etwas gutes zu machen, dann sollte mann die besten
komponent aussuchen die man noch kriegt ohne ZILLION zu bezahlen. und
dann sollte man das preis ausrechnen was d sich ergibt.

FPGA is eigentlich billig und kommt immer billiger. mit low cost
FPGA's kann man LA mit sampling rate um 1GS/S machen. low speed grade
S3 geht bis mindestens 900MS/S (ich habe selber gemessesn clock speed
von etwa 470MHz in s3 fabric.)

was teuer ist ist schnelles speicher. das sollte man nicht sparen und
72 bit ZBTRAM benutzen.

und... LA und DSO sind sehr ahnlich so das man DSO funktionalitat auch
gleich mitbringen sollte. NI hat gerade 2GS/S ADC heraus gebracht. klar
die sind schweineteuer. aber ein high speed ADC add board interface furs
DSO funktionalitat sollte schon da sein.

es ist moeglich mit kommerzíellen herstellen zu konkurieren, mann
sollte einfach keine angst haben, und hoch traumend

antti

meine private seite :) w w w truedream o r g

mann sollte traumen, und richtig! und dann was davon auch verwirklichen
naturlich ;)

PS fur LA project macht KEIN sinn gleich eine PCB zu entwickeln, nicht
gleich noetig. es gibt haufen mengen von platinen mit FPGA und JTAG
konnektor, die alle sind potentialle platforme furs LA. es ware viel
mehr besser anfangs ALLE FPGA platinen zu unterstutzen uber JTAG, die
software un ipcores fertig und testen, und DANACH eigen hw entwickeln.

von ope (Gast)


Lesenswert?

mmh, das mag ja alles richtig sein, aber wie soll ich dieses
vollbringen, wenn ich noch nicht einmal weiss, warum mein vhdl code
nicht das macht, was er soll. Soll heissen: Der Teufel liegt im
Detail.
Dennoch Danke für Deine Hinweise. Das DSO Feature wurde zB. wegen dem
Teufelchen gecancelt.

Viele Grüße
Olaf

von Andreas (Gast)


Lesenswert?

Hallo,

wie ich vorher auch schon schrieb, habe ich sehr wohl noch Interesse an
diesem Projekt. Nach anfänglicher Begeisterung scheinen aber nicht mehr
viele übrig geblieben zu sein, was schade ist. Vor allem scheint die
überwiegende Arbeit an Olaf und möglicherweise ein, zwei anderen
Aktiven zu hängen. Entweder haben die übrigen, die kompetent genug
wären, keinen Bock mehr drauf, oder das Ganze ist eben doch ein wenig
anspruchsvoller, als es viele in ihrer ersten Euphorie geglaubt haben.

Was mich betrifft, ich habe absolut keine Ahnung von FPGAs oder CPLDs,
als "Wald- und Wiesenelektroniker" hatte ich damit weder privat noch
beruflich zu tun.
Sollte das Projekt dennoch fertig gestellt werden, und es wird Hilfe
bei der Erstellung einer Doku gebraucht (was sicherlich erst ganz am
Ende des Projektes wichtig werden wird), stelle ich mich gern zur
Verfügung. Fachkenntnisse sowie ein halbwegs fehlerfreies Deutsch kann
ich immerhin bieten. :) Zumal eine gute Doku zu erstellen nicht
langweilig ist.

Gruß,
Andreas

von Jens Meyer (Gast)


Lesenswert?

Hallo,

Ich verfolge das ganze schon eine Weile und haette auch
Interesse an dem Geraet. Allerdings kann ich weder in
Sachen FPGA-Design noch bei der Eingangsstufe richtig
was beitragen (und da sehe ich die meiste Arbeit). Falls
ihr 2 seitige Musterplatinen braucht und die nicht allzu
gross sind könnte ich vielleicht helfen, einfach mal
melden wenn es soweit ist. Uebrigens habe ich den Schwenk
vom PLD zum FPGA nicht so ganz mitbekommen, gab es da
eine entsprechende Diskussion die ich uebersehen habe?

Jens

von Dirk (Gast)


Lesenswert?

Hallo,

wir haben uns auf einen FPGA geeinigt damit wir den internen Blockram
nutzen koennen und somit kein externes Sram benoetigen. Der FPGA
vereinfacht sehr das Layout.

Das schlimmste ist nur das benoetigte Teile  schwer o. garnicht
zubeschaffen sind fuer Normalsterbliche.

Im Moment haenge ich ein bischen fest, weil ich gerne das ganze Geraet
Bus Powered am Usb betreiben moechte. Leider liefert USB keine 5V
sondern diese schwankt zwischen 5,2V - 4,4V laut USB Spec..
Um jetzt eine konstante Spannung von 5V zuerhalten benoetigt man einen
StepUpDown Wandler.

Bei diesen Wandler besteht das Problem das man keinen findet der bei
Reichelt und Co zukaufen ist.

Langsam  muss ich aber einen Kompromiss finden und werde wohl oder
uebel um eine externe Versorgungsspannung nicht herumkommen dadurch
wird die Platine wieder um einiges groesser.

Gruß,
Dirk

von stromi (Gast)


Lesenswert?

Also ich lese auch mit grossem Interesse, ich schließe mich meinem
Vorredner an: Die FPGA-Geschicht, VHDL usw. ist dass, was ich nicht
checke und ich schätze, es geht vielen so.
Zum letzten Thema, Spannungsversorgung ? Da kann es doch nicht dran
hapern. Regler rein, Buchse drauf, externes Netzeil fertig.
Hier wundere ich mich, dass das überhaupt eine Frage wird.
Bei einem grösserem Projekt muss man dem die Einzelaufgaben geben, der
sich damit auskennt. Und bei VHDL und FPGA, wird es nicht so viele
geben.

von ope (Gast)


Lesenswert?

>Uebrigens habe ich den Schwenk
>vom PLD zum FPGA nicht so ganz mitbekommen, gab es da
>eine entsprechende Diskussion die ich uebersehen habe?

Ja, dieser Wandel kam still und leise, ich hatte es auch mal beiläufig
in irgendeinenen Thread hier erwähnt. Hauptgund: AVR+CPLD+SRAM kommt
auf Euro Format. Vom XC2S100 versprechen wir uns nun die schon besagte
Zigarettenschachtelgröße ;-) Leider hat er nur 40kbit intern,
entsprechend muss man diesen gut organisieren (s.o.) und damit fangen
die Probleme an.

Viele Grüße
Olaf

von Stephan (Gast)


Lesenswert?

Was wollt Ihr eigentlich noch mit 5V? Nehmt einen modernen Chip, der
läuft mit 3,3V.

Dann noch von Xilinx einen Virtex-4LX200, oder von Altera einen
CycloneII-EP1C3, dürfte das ganze Gerät machbar machen. Schnelles RAM
kann man sich auch in diese Chips hineinprogrammieren.

Allerdings wird dann der kleine, putzige Atmel arbeitslos... ;-)

Stephan.

von Antti (Gast)


Lesenswert?

;) witzigman!

I habe den preis von LX200 nicht, aber das ist der grosste von Xilinx.
und den preis von den grossten stratix weiss ich, nahmlich runde 9,000
USD. LX200 schatze is auf jeden fall auch 5,000++

EP1 ist alternative aber cyclone 2 ist jedoch preiswertiger.

mit uralten 5V bausteinen sollte man heute NICHT mehr spielen, sei den
es handelt sich um eine fertige platine.

--

Ich habe gerade das eebit FPGA logic analazer ins VHDL translier und
zusammen mit PCI-LPT IP core in Xilinx FPGA geladen. Den original
source code für die auswerung software habe ich auch kompiliert, war
gar nicht so schwierig.

dh heisst ich habe ein LA fast fertig. in null komma nichts. :)

antti

von Stephan (Gast)


Lesenswert?

@ Antti: Daumen hoch! :-)

Stephan.

von Antti (Gast)


Lesenswert?

danke Stephan!

I habe

FPGA programmier in PCI slot, und kann die LA registers lesen.
die PCI inerface emuliert den LPT so das es kenne treiber noetig sind
und die LA register sind kompatible zu dem eebit design.

noch nich alles funktionier ein paar module sind noch leere
hullen aber as ist wirklich 'piece of cake' das auch fertig
zu kriegen. aber das spater heute, jetzt is schon 00:51 :)

antti

von Antti (Gast)


Angehängte Dateien:

Lesenswert?

FERTIG.

Software und FPGA beide O.K.

screenshot ist von FPGA in PCI slot, eingang ist ein counter als test
pattern. FPGA ist Virtex2 2000, als speicher 8 bit x 64,000 samples.
Der design baisert auf den eebit 'parallel port'
version die original software kann man fast direkt benutzen.
die Altera schematics wurde ins VHDL transliert und mit
einem PCI - LPT IP core verbunden so das ganze gerat
als LPT anerkannt wird, so das man keine windows treiber braucht.
naturlich wurde es auch am richtigen printer port arbeiten oder
mit irgenwas anderes interface wenn man die software andert.

:)

Antti

von Ppp M. (sanic)


Lesenswert?

Hallo Antti,
das sieht ja wirklich gut aus!
Wie schnell ist das gute Stück denn ?
Was hat deine Software für Triggermöglichkeiten und co. ?

Grüße,
Patrick

von Antti L. (truedream)


Lesenswert?

Danke.

die hardware ist register compatible zu dem eebit design und
dieselbe software kann fast direct benutzt werden.
Es gibt haufen mengen moeglichkeiten das ganze zu verbessern.

meine test system habe ich auf einer PCI FPGA karte getestet
und auch das PCI clock als sampling clock benutzt.

Wie schnell kann man nicht antworten. In prinzip sollte es
relative leicht sein etwas uber 200MHz in low cost FPGAs zu
schaffen. Mit ein bishen mehr muhe sollten sampling rates
von circa 900MS/s in low cost PFGA (Spartan-2 zb) moeglich
sein in high end FPGAs etwas uber 1G/S. Das braucht aber
ein bishen anderungen :)

Antti

von Dirk (Gast)


Lesenswert?

Hi,

und laesst du die Allgemeinheit dran teil haben ?

Gruß,
Dirk

von Antti (Gast)


Lesenswert?

Hi Dirk,

wenn die Allgemeinheit es nicht fur zu teuer halt dann Ja.
Ist alles komplett verfugbar von shop.openchip.org

Antti

von ope (Gast)


Lesenswert?

Mal ein anderes Problem:

Ich habe 3 verschiedene Quellen Q0...Q2 (konkret Trigger), die unter
verschiedenen/bestimmten Bedingungen ein Signal abgeben, dass die
Bedingung erfüllt ist. Nun möchte ich diese Quellen kombinatorisch
vernüpfen, womit sich formal 9 Möglichkeiten ergeben, die jeweils durch
and/or/xor/not vernüpft werden können.

Konkret habe ich also die 3 Signale der Quellen, tja - und jetzt finde
ich keine einfache Lösung: Ein Register enthält eine Art Vektor 0...8,
der auf die Komb. der der Quellen zeigt (dispatched per case ...), ein
weiteres Register die Komb. and/or/xor/not. Letzlich eine einfache,
wenn auch starre Lösung.

Es kann aber auch möglich sein, (Q0 and Q1) or (not Q2) oder einfach
nur not Q0 bzw. Q0 - da wird diese Lösung kompliziert. Wer liefert
weitere Möglichkeiten, evtl. gleich mit VHDL Example?

Viele Grüße
Olaf

PS: Bin gerade am verkabeln der Entities, das Problem mit
http://www.mikrocontroller.net/forum/read-9-262347.html#new steht noch
immer.

von Antti (Gast)


Lesenswert?

in Xilinx FPGA kann man ein beliebiges funktion von 4 eingangen in einem
LUT implementieren, die LUT content kann auch der benutzer laden wenn
man den slice als SRL16 verwendet, so das man fur LA trigger kann man 4
eingange trigger match in einem LUT oder 2 eingange in einem LUT falls
die flanken auch dabei sind

antti

von ope (Gast)


Lesenswert?

@Antti: hast Du eine URL, wo man das konkrete WIE nachlesen kann?

Viele Grüße
Olaf

von Antti (Gast)


Lesenswert?

einfach ein SRL16, nichts weiteres :)

hat 4 eingange und einen ausgang,

kann als 4 eingang LUT benutzt werden,

den LUT content kan man serial einschieben

alles einfach!

Antti

von ope (Gast)


Lesenswert?

existiert auch eine portable Lösung?

Viele Grüße
Olaf

von antti (Gast)


Lesenswert?

nein.
SRL16 gibts nur bei xilinx. fur alle andere muss man normale lut oder
was immer benutzen
antti

von ope (Gast)


Lesenswert?

evtl. doch mit einem 'Combine'-Vektor? Allerdings gibt es für die
Verknüpfungen einen (2^3) und für die logischen Verknüpfungen auch noch
mal einen (xor, and, or, not 2^4) Vektor. Das schreiben macht dann auch
keinen Spass mehr, da viele case zu handeln sind. Ich hatte gehofft,
etwas mit einer Art Maske oder Ähnlichen als Lösung zu finden - komme
nur nicht 'drauf.

Viele Grüße
Olaf

von antti (Gast)


Lesenswert?

ah es ist moeglich eine ding zu machen die ein paar generics hat
und dann furs alle familien einen generate durchfurt
so das man alles frei parametrierbar kann

wenn du selber nicht weiter kannst dann lade isplever runter
da ist irgendo ein program encode.exe

mit dieser programs kann mann lava.enc datei offnen
das den quellcode von lattice ispTRACY logic analyzer enthalt
viel spass

Antti
PS ich habe schon 2 verschieden VOLL funktionerende FPGA logic
analyzer loesungen, was machst du dennn da? alles furs spass nur?

von ope (Gast)


Lesenswert?

gut, der erste wird wohl der auf ebay bzw. shop.openchip.org gegen Bares
sein. Der zweite besagter ispTRACY. Kannst Du nicht mit encode.exe und
lava.enc den ispTRACY encoden? Ich möchte nur ungern 800MB für den
ispLever reservieren, nur um ihn anschliessend wieder zu deinstallieren
um dann festzustellen, das mein Windows zerschossen ist.

Viele Grüße
Olaf

von Antti (Gast)


Lesenswert?

ja kann ich machen

von ope (Gast)


Lesenswert?

schon etwas erreicht?

von FPGA-User (Gast)


Lesenswert?

@ope

haste die 5 Dollar bezahlt ? Sonst antwortet Antti nicht ;-)))

von antti (Gast)


Lesenswert?

eigentlich antworte ich doch, aber, hmm wenn jemand einfach faul ist da
ist meine gegeisterung zu helfen auch minimal. Antworte habe ich ja
gegeben, aber ich wurde gebeten einen befehl auf meinem PC auszuführen
und dann ein datei zu schicken - und da nach ein bishen gedanken wurde
ich mich lieber zuruckhalten, eventuell konnte man ja sagen das es
irgenwelche urheberrechte verletzt. Wenn man das auf eigenen PC mach
ist es eine sache, aber weiterzugeben nicht so gut.

Grusse
Antti
PS in dem ebuch (8.30 EUR) da ist eigentlich fast nix nur gute
erklarung wie man 2 verschieden open-source logic analyzer design zum
leben bringt. die original designs sind im web frei verfugbar, aber..
die zeit die man damit auf eige faust totschlagen muss ist >2 tage so
dass das ebuch sich doch lohnen sollte.

von ope (Gast)


Lesenswert?

> Ich möchte nur ungern 800MB für den ispLever reservieren, nur um ihn
> anschliessend wieder zu deinstallieren um dann festzustellen, das
> mein Windows zerschossen ist.

Nun ja, es ist schon eine gewisse Art von Faulheit. Mein Windoze ist
gut configuriert, das möchte ich nicht mal eben so platt machen. Zumal
ich nicht weiss, dass ich dort das finde, was ich suche (s.o.). Mal
abgesehen davon habe ich den Platz gar nicht (ich platze aus allen
Nähten =).

Aber wieder zurück zum Thema:

Synthese klappt nicht: Ich bekomme von xst die ober-schlaue Error
Meldung:

Type of i is incompatible with type of ..

von
1
   tlc : process (clk, rst_triggers) is
2
      variable i      : unsigned(trigger_cond.length_value'range);
3
      variable m_down : boolean;
4
   begin
5
      if (rst_triggers = RESET_ACTIVE) then
6
         i                := (others => '0');
7
         m_down           := false;
8
         hit_length_match <= '0'; 
9
      elsif rising_edge(clk) then
10
         if (tlc_ce = '1') and not m_down then
11
            if (i = 0) then
12
               m_down           := true;
13
               hit_length_match <= '1';
14
            else
15
               i := i - 1;
16
            end if;
17
         elsif (tlc_ce = '0') then 
18
            i := trigger_cond.length_value; -- HIER IST DER ERROR
19
         end if;
20
      end if;
21
   end process;

mit
1
   type trigger_cond_t is
2
   record
3
      ...
4
      length_value : unsigned(LA_HIT_LENGTH-1 downto 0);
5
   end record;

Ich bin recht ratlos, was er von mir will. Im Grunde ein nachladbarer
Zähler, nachgeladen bei tlc_ce /= '1'. Monostabil eben.

Viele Grüße
Olaf

von Sssssss (Gast)


Lesenswert?

>variable i      : unsigned(...)
und
>i                := (others => '0');
Müsste das letzte nicht
i := 0;
heissen ?

von Antti (Gast)


Lesenswert?

guter ratschlag fur VHDL: verwende NUR std_logic und std_logic_vector da
ist es meistens immer sicher was rauskommt.

antti
tut mir leid deine festplatte, und vielleicht hatte ich ein email auch
rausgeschickt aber habe deine email nicht gefunden :(

von ope (Gast)


Lesenswert?

offenbar kann ich mir auf die Schulter klopfen - ich habe bzgl. dem tlc
Problem von oben einen bug in den xst gefunden. Packe ich den process
in eine entity - na ratet mal - klappt es.

Nicht sehr Vertauen erweckend. Offenbar muss man wie bei den C/C++
Compilern immer mehrere Synthese Tools zur Hand haben. Was nehme ich
nur? Quartus oder ispLever?

Viele Grüße
Olaf

von Thorsten (Gast)


Lesenswert?

Hallo,

welche FPGA wurde denn ausgewahelt und wie gross waere die
Speichertiefe? (Bytes x Samples)

Schoene Gruesse aus London

Thorsten

von ope (Gast)


Lesenswert?

mhh, London, coole Stadt ;-)

Momentan ist der XC2S100 bzw. XC2S200 (prefered)
(http://direct.xilinx.com/bvdocs/publications/ds001.pdf)
"state-of-the-art". Speicher ist 40k bzw 56k, wobei nur
Sampleänderungen abgespeichert werden um den Blockram (echter interner
RAM) besser ausnützen zu können. Yep, er ist veraltet etc., aber
verfügbar und im TQ144 oder PQ208 (prefered, da derzeitig bestellbar)
verhältnissmäßig preiswert zu bekommen. Siehe auch
http://www.mikrocontroller.net/forum/read-1-204570.html#new.

Z.Zt. bastel ich die einzelnen Entities zusammen und prüfe auf
Synthesefähigkeit, vereinfache und fasse signale zusammen. Aktuell ist
SPI zur Kommunikation vorgesehen, den Anschluss FPGA/SPI übernimmt dann
ein ARM (SAM7), da er billiger wird als ein FTDI. Auch ermöglicht er
einige Features wie Kompression u.a.

Als PC Frontend favorisere ich C++ und FoxToolkit, bin aber über die
Installation von mingw/msys noch nicht hiaus gekommen. Win32 Programing
ist für mich neu (endlich mal wieder etwas Neues nach VHDL).

Viele Grüße
Olaf

von Andreas (Gast)


Lesenswert?

Machst Du neben der Hardwareentwicklung auch noch die Software?
FoxToolkit? Hm ... ich kenne einige Frontends, aber davon habe ich noch
nie gehört. Wie bist Du darauf gekommen?

Gruß,
Andreas

von ope (Gast)


Lesenswert?

http://www.fox-toolkit.org
http://wiki.wxwidgets.org/wiki.pl?WxWidgets_Compared_To_Other_Toolkits
http://lists.trolltech.com/qt-interest/2002-06/msg01202.html

Für C++ ist imo WxWindows, Qt und eben Fox-Toolkit interessant.
WxWindows/WxWidgets hat Altlasten, die gehen bis Win 3.1 zurück, Qt
behagt mir die Geschichte mit den Moc Compiler nicht; auch wenn ich mit
Qt bereits (gute) Erfahrung habe, aber die neue Politik unter Windows
behagt mir nicht - der wird der Compiler vorgeschrieben, aber man wird
mit dem mingw alleine gelassen. Von der Seite her gibt's für mich
keinen Grund unbedingt Qt nehmen zu müssen. FLTK und Gtk lasse ich mal
ganz aussen vor.
Auch sollen viele Dinge in Fox besser gelöst sein, allerdings ist diese
auch jünger, so dass wohl auch einige GUI Klassen geschrieben werden
müssen. Mal sehen, ob sich Cairo
(http://cairographics.org/introduction) einbinden lässt, dann hätte man
gleich PDF Wave Plot Export prints und bessere Screen Graphic (kann aber
auch Overkill sein). Jedoch sind diese Aussagen eben ungeprüft.

Werde demnächst einen Thread unter PC Programmierung eröffnen müssen,
mal sehen, wer alles mit proggen möchte. Bis alles funktioniert, kann
man ja mit dummy Daten testen - bis alles richtig funktioniert, vergeht
eh noch etwas Zeit. Evtl. lohnt sich ja ein Projekt unter sourceforge
wegen dem cvs. Zumindest sollte es einen Grundkonsens finden um nicht
für jedes LA Projekt (alleine im Forum hier sheint es mind. 3
verschiedene Ansätze zu geben) ein neues Frontend entwerfen zu müssen
(Trennung Kommunikation/Daten und ihre Darstellung); Sprich die
klassischen OO Paradigmen.

Sicher gibt's tausende Gründe andere Sprachen zu nehmen, aber der es
programmiert sollte die Entscheidung treffen - es aber auch bis zu Ende
führen.

Derzeit bekomme ich unter mingw fox nicht als dll compiliert, scheint
ein Win32 Problem zu sein (progge selbst iA. unter unix und linux).

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

wiki update.

Letztens schrie ich noch: Er lebt noch. Inzwischen würde ich sagen, er
steckt fest und ist in einem Dämmerzustand.

Viele Grüße
Olaf

von FPGAküchle (Gast)


Lesenswert?

#offenbar kann ich mir auf die Schulter klopfen - ich habe bzgl. dem
tlc
#Problem von oben einen bug in den xst gefunden. Packe ich den process
#in eine entity - na ratet mal - klappt es.

IMHO ist es kein problem vom xst sondern von der unsigned Bibliothek.
Wahrscheinlich steht vor der entity in der du den prozess gepackt hast
ander
use anweisungen als vor der package in der das record steht. Und in den
Bibliotheken die du verwendest wird mehrmals unsigned definiert. Damit
ist
scheinen zwar zwei Signale/Variabken vom gleichen Typ (nämlich
unsigned) zusein. Wenn aber dieses Unsigned unterschiedlich definiert
ist (weil in verschiedenen benutzen Bibliotheken mehrmals) da sind die
beiden Variablen von versch. Typ obwohl beise unsigned heissen. Also
immer nur eine Bibliothek verwenden in der unsigned vorkommt.

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.