Forum: FPGA, VHDL & Co. AHB Testbench - Signal wird nicht geschrieben


von Elvin S. (elvinsp)


Angehängte Dateien:

Lesenswert?

Hallo,

ich arbeite momentan an einer Peripherie für einen Leon3 Softcore (AHB 
Bus) von Gaisler. Um die Peripherie zu testen benutze ich den 
mitgelieferten ambatest framework von 
GRLIB(http://www.gaisler.com/index.php/downloads/leongrlib). Nun habe 
ich ein Signal ctrl das einen Master der auf den AHB Bus zugreift 
steuert. Leider werden meine, an eine PROCEDURE(ahbwrite) übergebenen 
Werte, nicht auf ctrl geschrieben.
1
ENTITY tb_noc IS
2
END tb_noc;
3
 
4
ARCHITECTURE behavior OF tb_noc IS 
5
 
6
    -- Component Declaration for the Unit Under Test (UUT)
7
    
8
9
   --Inputs
10
   signal rstn : std_logic := '0';
11
   signal clkm : std_logic := '0';
12
   signal ahbsi : ahb_slv_in_type;
13
   signal ahbso : ahb_slv_out_vector := (others => ahbs_none);
14
   signal ahbmi : ahb_mst_in_type;
15
   signal ahbmo : ahb_mst_out_vector := (others => ahbm_none);
16
  signal ctrl  : ahbtb_ctrl_type;
17
18
   -- Clock period definitions
19
   constant clk_period : time := 20 ns;
20
 
21
BEGIN
22
 
23
  -- Instantiate the Unit Under Test (UUT)
24
   uut: top_noc
25
  generic map (
26
    hindex => 0,
27
    haddr => 16#400#,
28
    hmask => 16#fff#)
29
    port map (rstn, clkm, ahbsi, ahbso(0));
30
      
31
  ahb0 : ahbctrl       -- AHB arbiter/multiplexer
32
        generic map (defmast => 0, split => 0, 
33
                  rrobin => 1, ioaddr => 16#800#,
34
                  ioen => 1, nahbm => 1, nahbs => 16, acdm => 1)
35
        port map (rstn, clkm, ahbmi, ahbmo, ahbsi, ahbso);   
36
37
  ahbtbm0 : ahbtbm
38
    generic map(hindex => 0) -- AMBA master index 0
39
    port map(rstn, clkm, ctrl.i, ctrl.o, ahbmi, ahbmo(0));
40
41
   -- Clock process definitions
42
   clk_process :process
43
   begin
44
    clkm <= '0';
45
    wait for clk_period/2;
46
    clkm <= '1';
47
    wait for clk_period/2;
48
   end process;
49
 
50
   -- Stimulus process
51
   stim_proc: process
52
   begin  
53
    rstn <= '0';
54
    wait for 100 ns;
55
    rstn <= '1';
56
    --ctrl.o.rst <= '1';
57
    wait;
58
  end process;
59
  
60
  ahb_proc: process
61
  begin
62
    wait for 40 ns;
63
    -- Initialize the control signals
64
    ahbtbminit(ctrl);
65
    -- rstn <= '0';
66
      wait for 100 ns;  
67
    -- rstn <= '1';
68
      -- wait for 100 ns;
69
     -- Write 0x12345678 to address 0x40000000. Print access.
70
    ahbwrite(x"40000000", x"12345679", "10", 2, true , ctrl);
71
    wait for 100 ns;
72
    -- Read address 0x40000000 and compare with 0x12345678. Print access.
73
    --ahbread (x"40000000", x"12345678", "10", "11", '1', 2, true , ctrl);
74
    wait for 100 ns;
75
    -- Burst write with start address 0x40000000. Data is 0xdead0000 - 0xdead0020
76
    -- No output in printed.
77
    --ahbwrite(x"40000000", x"dead0000", "10", 32, 0, ctrl);
78
    wait for 100 ns;
79
    -- Burst read with start address 0x40000000. Compare data is 
80
    -- 0xdead0000 - 0xdead0020. Print result if not equal.
81
    --ahbread (x"40000000", x"dead0000", "10", 32, 1, ctrl);
82
    wait for 100 ns;
83
    -- Stop simulation
84
    ahbtbmdone(1, ctrl); 
85
      wait;
86
   end process;
87
88
END;

Im Anhang sieht man am Console Output dass der Process bis ahbtbmdone 
durchläuft.

Gesetzt wird ctrl durch die folgende PROCEDURE:
1
procedure ahbwrite(
2
  constant address  : in  std_logic_vector(31 downto 0);
3
  constant data     : in  std_logic_vector(31 downto 0);
4
  constant size     : in  std_logic_vector(1 downto 0);
5
  constant debug    : in  integer;
6
  constant appidle  : in  boolean;
7
  signal   ctrl     : inout ahbtb_ctrl_type) is
8
begin
9
  --ctrl.o <= ctrlo_nodrive;
10
  wait until ctrl.o.update = '1' and rising_edge(ctrl.o.clk);
11
  ctrl.i.ac.ctrl.use128 <= 0;
12
  ctrl.i.ac.ctrl.dbgl <= debug;
13
  ctrl.i.ac.hburst <= "000"; ctrl.i.ac.hsize <= '0' & size;
14
  ctrl.i.ac.haddr <= address; ctrl.i.ac.hdata <= data;
15
  ctrl.i.ac.htrans <= "10"; ctrl.i.ac.hwrite <= '1'; ctrl.i.ac.hburst <= "000";
16
  ctrl.i.ac.hprot <= "1110";
17
  if appidle = true then
18
    wait until ctrl.o.update = '1' and rising_edge(ctrl.o.clk);
19
    ctrl.i <= ctrli_idle;
20
  end if;
21
end procedure ahbwrite;

Man sieht dass meine übergebenen Werte nicht geschrieben werden anhand 
der Simulation im Anhang. Im Bild sieht man ein Signalwechsel bei 210ns, 
aber die Werte ändern sich nicht.

Hier noch der Testbench AHB Master:
1
component ahbtbm is
2
  generic (
3
    hindex  : integer := 0;
4
    hirq    : integer := 0;
5
    venid   : integer := 0;
6
    devid   : integer := 0;
7
    version : integer := 0;
8
    chprot  : integer := 3;
9
    incaddr : integer := 0); 
10
  port (
11
    rst  : in  std_ulogic;
12
    clk  : in  std_ulogic;
13
    ctrli : in  ahbtbm_ctrl_in_type;
14
    ctrlo : out ahbtbm_ctrl_out_type;
15
    ahbmi : in  ahb_mst_in_type;
16
    ahbmo : out ahb_mst_out_type 
17
    );
18
end component;

Ich sitze seit Tagen an dem Problem und verstehe nicht warum nicht auf 
das Signal geschrieben wird.

MfG

: Bearbeitet durch User
von Klakx (Gast)


Lesenswert?

Initialisiere mal Ctrl.O.update mit 0

von Klakx (Gast)


Lesenswert?

Ok da hat ich mich verschaut. Versuch mal mit Text Ausgaben dich an die 
Stelle zu tasten wo es hängt.

Etwas skeptisch sehe ich die Verwendung von inout in der Prozedur

von Elvin S. (elvinsp)


Angehängte Dateien:

Lesenswert?

Leider kommt 'X' raus, weil ctrl.o.update vom ahbtbm getrieben wird :(
Der Wert wird anscheinend durch ahbtbm immer auf '1' gehalten.

von Elvin S. (elvinsp)


Lesenswert?

Ja mein Gedanke war auch das es mit dem INOUT zu tun haben muss. Ich 
habe nie mit INOUT gearbeitet bis jetzt. Ich habe versucht das INOUT zu 
entfernen aber es ist zum Chaos geworden mit der Übersicht in der 
Package, und habe es sein lassen.
Ich wollte mal schauen was man hier dazu sagen würde.
Ich habe mal eine Textausgabe eingebaut gehabt und die Prozedure läuft 
durch. Die Testbench wird ja bis ahbtbmdone ausgeführt (Sieht man in der 
Abschluss Textausgabe "AHBTBM Testbench Done").

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


Lesenswert?

Elvin S. schrieb:
> Ich habe nie mit INOUT gearbeitet bis jetzt.
Es ist innerhalb eines FPGAs auch sehr unschön, weil es weit weg von der 
tatsächlichen Hardware ist. Wenn schon records dann wenigstens getrennt 
nach Ein- und Ausgängen. Sonst versteigt man sich in aller 
Bidirektionalität und bekommt einen Buskonflikt.

Ich kann mich mit der Gaisler-Schreib- und Denkweise überhaupt nicht 
anfreunden...

von Elvin S. (elvinsp)


Lesenswert?

Ich habe jetzt die PROCEDURE umgeschrieben.
1
procedure ahbwrite(
2
  constant address  : in  std_logic_vector(31 downto 0);
3
  constant data     : in  std_logic_vector(31 downto 0);
4
  constant size     : in  std_logic_vector(1 downto 0);
5
  constant debug    : in  integer;
6
  constant appidle  : in  boolean;
7
  signal   ctrlo     : in  ahbtbm_ctrl_out_type;
8
  signal   ctrli     : out ahbtbm_ctrl_in_type) is
9
begin
10
  --ctrlo <= ctrlo_nodrive;
11
  wait until ctrlo.update = '1' and rising_edge(ctrlo.clk);
12
  ctrli.ac.ctrl.use128 <= 0;
13
  ctrli.ac.ctrl.dbgl <= debug;
14
  ctrli.ac.hburst <= "100"; ctrli.ac.hsize <= '0' & size;
15
  ctrli.ac.haddr <= address; ctrli.ac.hdata <= data;
16
  ctrli.ac.htrans <= "10"; ctrli.ac.hwrite <= '1'; ctrli.ac.hburst <= "000";
17
  ctrli.ac.hprot <= "1110";
18
  if appidle = true then
19
    wait until ctrlo.update = '1' and rising_edge(ctrlo.clk);
20
    ctrli <= ctrli_idle;
21
  end if;
22
end procedure ahbwrite;

Die Simulation sieht genauso aus wie mein erster Anhang.
???
Ich frage anscheinend wird was geschrieben bei 210ns aber es ist nach 
wie vor nicht was ich übergebe zB "010" für ctrl.i.ac.hsize.
1
ahbwrite(x"40000000", x"12345679", "10", 2, true , ctrl.o, ctrl.i);

von Lattice User (Gast)


Lesenswert?

Ich habe einen Verdacht:
Füge mal ein kleines delay nach den beiden waits in der ahbwrite 
procedure hinzu:
SO etwa:
1
  wait until ctrlo.update = '1' and rising_edge(ctrlo.clk);
2
  wait for 1 ns;

von Klakx (Gast)


Lesenswert?

Elvin S. schrieb:
> ahbwrite(x"40000000", x"12345679", "10", 2, true , ctrl.o, ctrl.i);

vielleicht geht's wenn der record ganz getrennt ist. Ich mische auch nie 
Inputs und Outputs.
1
ahbwrite(x"40000000", x"12345679", "10", 2, true , tb2master, master2tb);

nebenbei füge noch Textausgaben ein, um zu sehen wo die Prozedur hängt.

von Elvin S. (elvinsp)


Angehängte Dateien:

Lesenswert?

Lattice User schrieb:
> Ich habe einen Verdacht:
> Füge mal ein kleines delay nach den beiden waits in der ahbwrite
> procedure hinzu:

Das wars! Jetzt wo ichs sehe ^^ Oh mann
Anscheinend wird alles in einem gemacht und nicht mehr auf die nächste 
rising_edge(ctrlo.clk) gewartet so dass das idle signal wieder angelegt 
wird (Was für ein S******). Warum wartet er nicht auf die nächste 
positive Taktflanke?
1
begin
2
  --ctrlo <= ctrlo_nodrive;
3
  wait until ctrlo.update = '1' and rising_edge(ctrlo.clk);
4
  wait for 1 ns;
5
  ctrli.ac.ctrl.use128 <= 0;
6
  ctrli.ac.ctrl.dbgl <= debug;
7
  ctrli.ac.hburst <= "100"; ctrli.ac.hsize <= '0' & size;
8
  ctrli.ac.haddr <= address; ctrli.ac.hdata <= data;
9
  ctrli.ac.htrans <= "10"; ctrli.ac.hwrite <= '1'; ctrli.ac.hburst <= "000";
10
  ctrli.ac.hprot <= "1110";
11
  if appidle = true then
12
    wait until ctrlo.update = '1' and rising_edge(ctrlo.clk);
13
   wait for 1 ns;
14
    ctrli <= ctrli_idle;
15
  end if;
16
end procedure ahbwrite;

von Elvin S. (elvinsp)


Lesenswert?

Oh mann,

jetzt sehe ich auch ich muss nur appidle auf false setzen. Danke 
Lattice, Klakx, Lothar für eure Unterstützung!
Kann mir jemand noch ne Erklärung geben warum rising_edge auf die 
vergangene Taktflanke reagiert, obwohl diese 2ns her ist?

MfG

: Bearbeitet durch User
von Elvin S. (elvinsp)


Lesenswert?

Kleiner Nachtrag:

Ich habe jetzt rausgefunden, dass das Problem am ISim vom Xilinx liegt. 
Ich habe das selbe auf Modelsim probiert und es läuft wie geschmiert.

lg

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.