2016-05-23 11 views
0

Ich bin sehr neu zu vhdl und ich kann nicht finden, was diesen Fehler verursacht. Ich versuche, die Funktionalität eines CD54/74HC192 Circuit zu replizieren.Signal x kann nicht synthetisiert werden, schlechte synchrone Beschreibung

Jede Hilfe würde sehr geschätzt werden.

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all; 

entity upg1 is 
    Port (clock_up : in std_logic; 
      clock_down : in std_logic; 
      reset : in STD_LOGIC; 
      asyn_load : in STD_LOGIC; 
      bcd_in : in STD_LOGIC_VECTOR (3 downto 0); 
      bcd_ut : out STD_LOGIC_VECTOR (3 downto 0); 
      term_up : out STD_LOGIC; 
      term_down : out STD_LOGIC); 
end upg1; 

architecture Behavioral of upg1 is 
subtype state_type is integer range 0 to 15; 
signal next_state, present_state: state_type; 
signal clock : std_logic; 

begin 

process(clock_up, clock_down) 
begin 
    if clock_up = '1' then 
     clock <= clock_down; 
    else 
     if clock_down = '1' then 
     clock <= clock_up; 
    end if; 
    end if; 
end process; 


process(present_state, asyn_load, clock) -- line 65 
begin 
    if reset= '1' then 
     next_state <= 0; 
    end if; 
    if (asyn_load = '1' and (rising_edge(clock))) then 
     if present_state = 9 or present_state = 13 or present_state = 15 then 
     present_state <= 0; 
     elsif 
     present_state = 10 or present_state = 12 or present_state = 14 then 
     present_state <= 9; 
     elsif 
     present_state = 11 then 
     present_state <= 4; 
     else 
     present_state <= present_state + 1; 
     end if; 

     else 
     if rising_edge(clock) then 
      if present_state = 12 then 
      present_state <= 3; 
      elsif present_state = 13 then 
      present_state <= 4; 
      elsif present_state = 14 then 
      present_state <= 5; 
      elsif present_state = 15 then 
      present_state <= 6; 
      elsif present_state = 0 then 
      present_state <= 9; 
      else 
      present_state <= present_state - 1; 
      end if; 
    else 
     present_state <= TO_INTEGER(UNSIGNED(bcd_in)); 
    end if; 
    end if; 

end process; 
end Behavioral; 

Ich habe verschiedene Methoden versucht, den Fehler zu beheben, aber nicht dazu in der Lage.

Fehler-Konsole:

line 65: Signal present_state cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) 
+2

Es gibt viele Antworten auf diesen genauen Fehler, http://stackoverflow.com/search?q=[vhdl]+bad+synchronous_description –

+0

Ich habe sie gelesen, aber keiner von ihnen hat zu keiner Lösung beigetragen . – Frans

+1

Drei der ersten 4 Ergebnisse beantworten diese Frage. –

Antwort

1

Erstens, verwenden Sie nicht beide Pakete numeric_std und std_logic_arith/unsigned, sondern verwenden nur numeric_std, da dies ein Standard-Paket VHDL ist, wo std_logic_arith/unsigned sind Synopsys proprietär. So ändern:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.all; 

Über das eigentliche Problem, dann schaffen Zustand in VHDL durch Flip-Flops unter Verwendung einer Struktur wie:

process(clock, reset) 
begin 
    if rising_edge(clock) then 
    ... 
    end if; 
    if reset = '1' then 
    ... 
    end if; 
end if; 

Synthese wird dies erkennen und schließen Flip-Flops. Die reset und clock sollten nicht anderswo im Prozess verwendet werden.

+1

Geringfügiger Fehler in der ersten Zeile, "aber nur seit" –

+0

Ich habe diesen Codierungsstil für einen asynchronen Reset nicht gesehen, obwohl es Sinn macht. Betrachtet man die Xilinx-Syntheseanleitung, so empfiehlt sich die Verwendung eines 'if' /' elsif'-Paares, wobei die an-synchronen Sätze/klar im "if" und die Taktung im "elsif" sind. Funktioniert dieser Stil mit anderen Synthesizern/Bibliotheken? – PlayDough

+0

Wenn mehrere Flip-Flops (FFs) durch das "if/elsif" mit Reset in "if" abgeleitet werden, müssen alle FFs zurückgesetzt werden, da die nicht enthaltenen FFs ansonsten nicht getaktet werden, wenn Reset aktiviert ist nicht FF-Verhalten, z 'wenn reset = '1', dann a <= '0' elsif rising_edge (Takt), dann a <= '1'; b <= a; Ende if; '. Wenn der Reset und der Takt in zwei "if" aufgeteilt werden, dann gibt es diese Abhängigkeit nicht, und das letzte Zurücksetzen bedeutet, dass es Vorrang hat, genau wie im FF. Dies funktioniert für Altera, Xilinx und Lattice. –

0

Zuerst repliziert Ihr Code nicht die Funktionalität eines CD74HC192 oder eines anderen '192 Counters.

Es hat keine asynchrone Last, die einen Eingangswert in einen anderen konvertiert. Ihr Modell erscheint auch nicht funktional und hat keine Ausleih-/Übertragsausgaben.

ein unzulässiger Wert Last wo bei sich außerhalb der Reichweite innerhalb der Reichweite zurückzählen oder Uhren Countdown erfordert (die längste Zählung von 11 nach unten nimmt zwei Takte im Gegensatz zu den Forderungen auf der ersten Seite des CD54/74HC192 Datenblatt -

Wenn ein Jahrzehnt gegen einen illegalen Zustand voreingestellt ist oder übernimmt einen unzulässigen Zustand, wenn Spannung angelegt wird, wird es in einer Zählung der normalen Sequenz zurück, wie in Zustandsdiagramm gezeigt.

Drei Fehler wurden gefunden in das Datenblatt wurde insgesamt und nicht alle Details untersucht.

Es gibt ein Problem mit der Verfügbarkeit eines Toggle-Flipflops oder eines getakteten Flipflops, aus dem Sie in modernen Xilinx-Gerätefamilien eine bauen können. Es gab und FDCPE, das war ein D-Flip-Flop mit einer asynchronen, klaren und asynchronen Voreinstellung, die Sie hätten verwenden können. Es war so spät wie die Spartan-3-Familie, vielleicht andere. Es gibt ein VHDL-Modell, das in 9.1i verfügbar ist und vielleicht irgendwo in der Version 11. Es ist unwahrscheinlich, dass Sie auf ältere Gerätefamilien eingeschränkt werden möchten.

Die voreingestellte und klar VHDL-Codierung, die Playdough erwähnt kann bei Example : D Flip-Flop with Asynchronous Clear,Set and Clock Enable sehen werden:

process(CLR,PRE,CLK) --process with sensitivity list. 
begin --"begin" statment for the process. 

    if (CLR = '1') then --Asynchronous clear input 
      Q <= '0'; 
    else 
      if(PRE = '1') then --Asynchronous set input 
       Q <= '1'; 
      else 
       if (CE = '1' and falling_edge(CLK)) then 
        Q <= D;  
       end if; 
      end if; 
    end if; 

Wenn Sie Zugang zu einem Flip-Flop primitiv in einem anvisierten Xilinx Gerät haben, sollten Sie diese Art der Programmierung nutzen können, um darauf zuzugreifen.

Sie könnten Anbieter wechseln. Altera hat eine TFF primitive mit asynchronem Löschen und Laden (erweitern Sie Inputs/Outputs gibt es eine Wahrheitstabelle).

Sie könnten einen Toggle-Flipflop aus NAND-Gattern konstruieren. Das ist nicht so unverschämt, wie es auf den ersten Blick scheint. Das CD54/74HC192-Datenblatt gibt einen fmax von 24 MHz an. Es würde eine beschränkende Synthese erfordern, relativ langsam sein (aber wahrscheinlich mindestens zweimal so schnell wie die spezifizierte fmax) und viele LUTs erfordern.

Also mit einem Master-Slave-Toggle-Flip-Flop aus NAND-Gates und dem Logikdiagramm aus dem SN74LS192 Datenblatt ein Modell wurde konstruiert und getestet.

Das Toggle-Flip-Flop sieht etwas wie folgt aus:

t_ff_logic.png

Ein Master/Slave-Flip-Flop in einem Simulationsmodell funktionieren wird, das Design verhindert Schwingung von ausgeglichenen Rückkopplung, die in einer einzigen Stufe erfolgen kann Flip Flops.

Sobald das SN74LS192 funktionierte, wurde es so modifiziert, dass es den Zustandswechsel replizierte, der in Abbildung 9 des CD54/74HC192-Datenblattes zu finden ist. Zusätzlich zu dem Ersetzen von zwei der Umschaltzustände wurde die Ausführung während des Hochzählens modifiziert, um nur für einen Zählerwert von 9 gültig zu sein, in Übereinstimmung mit der schnellen unzulässigen Zustandswiederherstellung in TIs HC/HCT 192 Zählern.

Und das gibt:

hc_192.png

Wenn der Zähler erscheint voll funktionsfähig zu sein.

Der vollständige Code und Testbench ist vorgesehen:

library ieee; 
use ieee.std_logic_1164.all; 

entity t_ff is 
    port ( 
     t_n: in std_logic; 
     pre_n: in std_logic; 
     clear: in std_logic; 
     q:  out std_logic; 
     q_n: out std_logic 
    ); 
end entity; 

architecture masterslave of t_ff is 
    signal tclk: std_logic; 
    signal mg:  std_logic; 
    signal mg_n: std_logic; 
    signal mq:  std_logic; 
    signal mq_n: std_logic; 
    signal sg:  std_logic; 
    signal sg_n: std_logic; 
    signal sq:  std_logic; 
    signal sq_n: std_logic; 
begin 

INV_CLK: 
    tclk <= not t_n; 

NANDMG: 
    mg <= not (sq_n and t_n); 
NANDMGN: 
    mg_n <= not (sq and t_n); 

NANDMQ: 
    mq <= not (mg and  pre_n and mq_n); 
NANDMQN: 
    mq_n <= not (mg_n and not clear and mq); 

NANDSG: 
    sg <= not (mq and tclk); 
NANDSGN: 
    sg_n <= not (mq_n and tclk); 

NANDSQ: 
    sq <= not (sg and  pre_n and sq_n); -- preset/clear slave 
NANDSQN: 
    sq_n <= not (sg_n and not clear and sq); 


    q <= sq; 
    q_n <= sq_n; 

end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 

entity cd74hc192 is 
    port ( 
     up:   in std_logic;     -- clock up 
     down:  in std_logic;     -- clock down not 
     clear:  in std_logic;     -- async clear 
     load_n:  in std_logic;     -- async load 
     din:   in std_logic_vector (3 downto 0); -- parallel data in 
     qout:  out std_logic_vector (3 downto 0); -- counter out 
     co_n:  out std_logic;      -- carry 
     bo_n:  out std_logic      -- borrow 
    ); 
end entity; 

architecture tff of cd74hc192 is 
    signal clear_n:  std_logic; 
    signal down_n:  std_logic; 
    signal up_n:  std_logic; 
    signal load:  std_logic; 

    signal t_n:   std_logic_vector (3 downto 0); 
    signal pre_n:  std_logic_vector (3 downto 0); 
    signal clr:   std_logic_vector (3 downto 0); 
    signal q:   std_logic_vector (3 downto 0); 
    signal q_n:   std_logic_vector (3 downto 0); 
    -- 
    -- signal s_term:  std_logic; -- SN74LS192 

begin 

T_FLIP_FLOPS: 
    for i in 0 to 3 generate -- 0 corresponds to A ... 3 to D 
TFF: 
    entity work.t_ff 
     port map (
      t_n => t_n(i), 
      pre_n => pre_n(i), 
      clear => clr(i), 
      q  => q(i), 
      q_n => q_n(i) 
     ); 
    end generate; 

-- CARRY BORROW OUTPUTS: 

    -- co_n <= not (up_n and q(3) and q(0)); -- CARRY == SN74LS192 

    co_n <= not (up_n and q(3) and q_n(2) and q_n(1) and q(0)); -- CARRY 

    bo_n <= not (down_n and q_n(3) and q_n(2) and q_n(1) and q_n(0)); 

-- BUFFERS: 

    clear_n <= not clear; 

    down_n <= not down; 
    up_n <= not up; 

    load <= not load_n;  

    qout <= q; 

-- PRESETS: 

    pre_n(0) <= not (din(0) and load and clear_n); 
    pre_n(1) <= not (din(1) and load and clear_n); 
    pre_n(2) <= not (din(2) and load and clear_n); 
    pre_n(3) <= not (din(3) and load and clear_n); 

-- CLEARS: 

    clr(0) <= not (clear_n and not (pre_n(0) and load)); 
    clr(1) <= not (clear_n and not (pre_n(1) and load)); 
    clr(2) <= not (clear_n and not (pre_n(2) and load)); 
    clr(3) <= not (clear_n and not (pre_n(3) and load)); 

-- -- SHARED TERM: -- SN74LS192 
-- 
--  s_term <= not(q_n(1) and q_n(2) and q_n(3)); 

-- -- TOGGLES: -- SN74LS192 
-- 
--  t_n(0) <= down_n or up_n; 
-- 
--  t_n(1) <= (down_n and q_n(0) and s_term) or 
--    (q(0) and q_n(3) and up_n); 
-- 
--  t_n(2) <= (s_term and down_n and q_n(0) and q_n(1)) or 
--    (q(0) and q(1) and up_n); 
-- 
--  t_n(3) <= (down_n and q_n(0) and q_n(1) and q_n(2)) or 
--    (q(0) and q(3) and up_n) or 
--    (q(0) and q(1) and q(2) and up_n); 

-- TOGGLES: 

    t_n(0) <= down_n or up_n; 

    t_n(1) <= (down_n and (q(3) or q(2) or q(1)) and q_n(0)) or 
       (up_n and q_n(3) and q(0)) or 
       (up_n and q(3) and q(1)); 

    t_n(2) <= (down_n and (q(3) or q(2)) and q_n(1) and q_n(0)) or 
       (up_n and q(3) and q(2)) or 
       (up_n and q(1) and q(0)); 

    t_n(3) <= (down_n and q_n(2) and q_n(1) and q_n(0)) or 
       (up_n and q(3) and q(0)) or 
       (up_n and q(2) and q(1) and q(0)); 

-- These TOGGLE terms were derived from the TI CD54/74192/193 datasheet 
-- http://www.ti.com/lit/ds/symlink/cd74hc193.pdf Figure 9 through the use 
-- of logic term minimization (using espresso) by mapping the new state 
-- values as bit toggles from the previous state values and hand folding terms 
-- by using OR gates. 

end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity hc192_tb is 
end entity; 

architecture foo of hc192_tb is 
    signal up:   std_logic; 
    signal down:  std_logic; 
    signal clear:  std_logic; 
    signal load_n:  std_logic; 
    signal din:   std_logic_vector (3 downto 0); 

    signal q:   std_logic_vector (3 downto 0); 
    signal co_n:  std_logic; 
    signal bo_n:  std_logic; 
begin 
DUT: 
    entity work.cd74hc192 
     port map (
      up  => up, 
      down => down, 
      clear => clear, 
      load_n => load_n, 
      din => din, 
      qout => q, 
      co_n => co_n, 
      bo_n => bo_n 
     ); 
STIMULI: 
    process 
    begin 
     wait for 10 ns; 
     up <= '1'; 
     down <= '1'; 
     clear <= '0'; 
     load_n <= '1'; 
     din <= (others => '1'); 
     wait for 10 ns; 

     -- CLEAR TEST 
     clear <= '1'; 
     wait for 10 ns; 
     clear <= '0'; 
     wait for 10 ns; 

     -- LOAD SETUP/HOLD TEST 

     din <= x"5"; 
     load_n <= '0'; 
     wait for 5 ns; 
     din <= x"3"; 
     wait for 5 ns; 
     load_n <= '1'; 
     wait for 10 ns; 

     -- LOAD TEST 

     for i in 0 to 9 loop 
      din <= std_logic_vector(to_unsigned(i, din'length)); 
      wait for 15 ns; 
      load_n <= '0'; 
      wait for 5 ns; 
      load_n <= '1'; 
      wait for 10 ns; 
     end loop;  

     -- LOAD CORRECTING COUNT UP TESTS 

     for i in 10 to 15 loop 
      din <= std_logic_vector(to_unsigned(i, din'length)); 
      wait for 15 ns; 
      load_n <= '0'; 
      wait for 5 ns; 
      load_n <= '1'; 
      wait for 15 ns; 
      up <= '0'; 
      wait for 5 ns; 
      up <= '1'; 
      wait for 10 ns; 
     end loop; 

     -- LOAD CORRECTING COUNT DOWN TESTS 

     for i in 10 to 15 loop 
      din <= std_logic_vector(to_unsigned(i, din'length)); 
      wait for 15 ns; 
      load_n <= '0'; 
      wait for 5 ns; 
      load_n <= '1'; 
      wait for 15 ns; 
      down <= '0'; 
      wait for 5 ns; 
      down <= '1'; 
      wait for 10 ns; 
      if i = 11 then 
       wait for 5 ns; 
       down <= '0'; 
       wait for 5 ns; 
       down <= '1'; 
      end if; 
       wait for 10 ns; 
     end loop; 

     -- COUNT UP TEST 

     din <= (others => '0'); 
     wait for 15 ns; 
     load_n <= '0'; 
     wait for 5 ns; 
     load_n <= '1'; 
     for i in 0 to 9 loop 
      wait for 10 ns; 
      up <= '0'; 
      wait for 5 ns; 
      up <= '1'; 
      wait for 10 ns; 
     end loop; 

     -- COUNT DOWN TEST 

     din <= x"9"; 
     wait for 15 ns; 
     load_n <= '0'; 
     wait for 5 ns; 
     load_n <= '1'; 
     for i in 0 to 9 loop 
      wait for 10 ns; 
      down <= '0'; 
      wait for 5 ns; 
      down <= '1'; 
      wait for 10 ns; 
     end loop; 

     -- COUNT UP COUNT DOWN TEST 

     wait; 

    end process; 

end architecture; 

Der Prüfstand wurde ursprünglich für ein 74LS192 Modell gedacht und es schien mehr Mühe, als es wert zu ändern Signalnamen war die ‚HC192 Datenblatt zu entsprechen.