Den ny brainer stammer fra noget kode til simulering, som bare ikke opfører sig fornuftigt. Det vil sige det gør jo præcis som det står skrevet, men kan du spotte hvor der mangler noget så det kommer til at virke som tiltænkt?
library ieee; use ieee.std_logic_1164.all; entity gizmo is port ( some_control : in std_logic_vector(3 downto 0); q : out std_logic); end entity gizmo; architecture rtl of gizmo is begin -- Not written yet end architecture rtl; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity thingy is port ( d : in std_logic_vector(1 downto 0); oe : in std_logic; -- Yes, active high! q : out std_logic); end entity thingy; architecture rtl of thingy is signal q_int : std_logic; begin q_int <= d(0) and d(1); q <= q_int when oe = '1' else 'Z'; end architecture rtl; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity simple_test is end entity simple_test; architecture sim of simple_test is signal stimulus : unsigned(6 downto 0); signal q : std_logic; begin thingy_dut : entity work.thingy port map ( d => std_logic_vector(stimulus(1 downto 0)), oe => std_logic(stimulus(2)), q => q); gizmo_dut : entity work.gizmo port map ( some_control => std_logic_vector(stimulus(6 downto 3)), q => q); process is begin stimulus <= (others => '0'); for i in 0 to 127 loop wait for 10 ns; stimulus <= stimulus+1; end loop; end process; end architecture sim;
Først med et rigtigt svar i kommentarfeltet vinder hele hæderen.
Hej, Fejlen ligger her:
q_int <= d(0) and d(1);
q <= q_int when oe = '1' else 'Z';
q_int bliver assignet i line 1 samme tid som den bliver brugt i linie 2, det betyder at q_int er un-assigned når den bruges.
Løsning:
Sæt 1ps delay ind mellem linie 1 & 2 eller lad være med at bruge 'temporary' signaler.
Det kan være q der har to drivere, hvor det ikke ser ud til at den ene kan tri-states.
Forøvrigt er det at håbe at gizmo er design top-level, hvis det skal i en FPGA (afh. af værktøj) – ikke alle værktøjer lader tri-state ‘Z’ komme op igennem hirakiporte.
/Benny
Benny er inde på noget af det rigtige: q-outputs fra de to instanser er forbundet sammen i testbenchen. Der mangler derfor enten en arbitrering i testbenchen eller en tristate funktion på gizmo, styret af “not stimulus(2)”.
En anden lille detalje i stimulus processen er, at “stimulus” signalet bliver sat til 127+1 = 128 i den sidste loop, hvor stimulus kun er defineret op til 127. Grunden til at det alligevel går godt er at processen stopper i samme iteration og straks starter forfra og nulstiller “stimulus”. Men det er ikke helt korrekt VHDL.
For at kunne benytte typen UNSIGNED skal IEEE pakken STD_LOGIC_ARITH bruges. Ønskes dette skal følgende to linjer med i koden:
library IEEE;
use IEEE.STD_LOGIC_ARITH.all;
Er dette fejlen?
mvh Thomas
Som Benny og Martin skriver, så drives q af både thingy og gizmo. Resultatet dannes af std_logic_1164′s resolution function. Resultatet vil altid være ‘U’, hvis bare et input er ‘U’.
gizmo “– Not written yet” giver q = ‘U’, så simuleringen viser ikke funktionen af thingy.
Man kunne i princippet erstatte std_logic_1164′s resolution function, eller man kan åbne q fra gizmo.
Min foretrukne løsning er dog at give q en weak default i gizmo, q <= 'W', eller 'Z', 'H', 'L'.