Eliminar el bloqueo inferido de VHDL en la declaración del caso

0

Soy un EE mayormente analógico que está tratando de configurar un kit de desarrollo de fpga (terasic de0-nano) para girar los bits de control en algunas partes de control de pulso para las que estoy haciendo una placa de evaluación. Estoy usando un interruptor DIP externo para cambiar el ancho de pulso de salida y quiero confirmar en qué selección de ancho de pulso me encuentro encendiendo los indicadores LED incorporados.

Sé muy poco acerca de los FPGA; Implementé una máquina de estado temporizada ya que parecía un buen punto de partida. Estoy seguro de que estoy haciendo muchas cosas malas en general, pero tengo un problema en particular: los indicadores LED de estado no funcionan.

Estoy tratando de deshacerme de un cierre inferido que "tiene un comportamiento inseguro". Estaba obteniendo latches inferidos tanto para txTime como para ledOut en algún código anterior. Seguí el consejo en

enlace

y ponga las diferentes opciones para el conmutador dip de 8 bits cfgDIP en una declaración de caso. Me aseguré de que hubiera otro caso para manejar los estados que no abordé explícitamente. Esto hizo que el pestillo txTime desapareciera; sin embargo, no solucionó el comportamiento inseguro del pestillo ledOut. Y de cualquier manera, los cierres inferidos todavía están allí, así que parece que hay un problema más fundamental.

Preguntas 1) ¿Cuál es una buena manera de que alguien como yo aprenda a implementar el código FPGA vhdl práctico muy rápidamente? Mis viejos libros de lógica digital de licenciatura son difíciles de obtener consejos prácticos de codificación de.

2) ¿Cómo corrijo el comportamiento inseguro del pestillo ledOut?

3) ¿Cómo elimino los cierres inferidos por completo? Hay cierres inferidos para triggerOut, rxTime, ledOut, clampToRxTime y clampToTxTime. No entiendo por qué no hay un pestillo inferido de txTime ya que también se usa en dos estados.

Mi código VHDL:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;

ENTITY pulserLogic IS
    PORT(   clk, reset_n                    : IN STD_LOGIC; 
            cfgDIP, stIn, maxIn         : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 
            stOut, maxOut                   : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
            ledOut                          : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
            triggerOut                      : OUT STD_LOGIC);               
END pulserLogic;

ARCHITECTURE logic OF pulserLogic IS
    SIGNAL              timeCounter         : INTEGER  RANGE 0 TO 300_000;          --timing counter
    TYPE                state IS (state_init,state_TxVPP,state_clampToRx,state_Rx,state_clampToTx);
    SIGNAL          pr_state, nx_state: state;


BEGIN
--reset and clocked state machine controller process
    PROCESS (clk,reset_n)
        VARIABLE count : INTEGER RANGE 0 to 300_000;
    BEGIN
        IF(reset_n = '0') THEN                 --asynchronous reset 
            pr_state <= state_init;
            count := 0;
        ELSIF(RISING_EDGE(clk)) THEN                --stay in current state for set number of clock cycles then move to next state
            count := count + 1;
            IF (count = timeCounter) THEN
                pr_state <= nx_state;
                count := 0;
            END IF;
        END IF;
    END PROCESS;

--state declaration process
    PROCESS (pr_state,timeCounter,cfgDIP,stIn,maxIn)
        VARIABLE txTime : INTEGER RANGE 0 to 50;
        VARIABLE    rxTime  : INTEGER RANGE 0 to 250000000; --at 250MHz clock 1hz= 250000000 and 2khz = 125000, 
        VARIABLE    clampToRxTime   : INTEGER RANGE 0 to 250000000; --at 250MHz clock 1hz= 250000000 and 2khz = 125000 
        VARIABLE    clampToTxTime   : INTEGER RANGE 0 to 250000000; --at 250MHz clock 1hz= 250000000 and 2khz = 125000
        Variable ledOutVar : STD_LOGIC_VECTOR (7 DOWNTO 0);

    BEGIN
        CASE pr_state IS
            WHEN state_init =>                                  -- initialize   
                triggerOut <= '0';
                txTime := 5;                                                            -- set to nominal 20ns pulse width (4ns clock * 5)
                rxTime := 10000;                                                        -- set to nominal 40us rx time 
                ledOut <= "01000010";
                clampToRxTime := 200;                                               -- time between end of Tx and start of Rx, default 800ns (200 *4)
                clampToTxTime := 2500000-txTime-clampToRxTime-rxTime;       -- time between end of Rx and start of Tx, default to 100Hz PRF
                stOut <= "0000000000000000";                                    -- clamp all outputs
                maxOut <= "0000000000000000";                               
                timeCounter <= 10;                                                  -- nominal num of cycles in the init state
                nx_state <= state_TxVPP;  

            WHEN state_TxVPP =>                         
                stOut <= "1010101010101010";
                maxOut <= "1010101010101010";

                case cfgDIP is
                    when "00000001" => 
                        txTime := 15;
                        ledOut <= "00000001";
                    when "00000011" =>
                        txTime := 20;
                        ledOut <= "00000011";
                    when "00000111" =>
                        txTime := 25;   
                        ledOut <= "00000111";                   
                    when others =>
                        txTime := 10;
                        ledOut <= "00001111";
                end case;

                timeCounter <= txTime;  
                nx_state <= state_clampToRx;    

            WHEN state_clampToRx =>
                stOut <= "0000000000000000";
                maxOut <= "0000000000000000";
                timeCounter <= clampToRxTime;
                nx_state <= state_Rx;

            WHEN state_Rx =>
                stOut <= "1111111111111111";
                maxOut <= "1111111111111111";
                timeCounter <= rxTime;
                nx_state <= state_clampToTx;    

            WHEN state_clampToTx =>
                stOut <= "0000000000000000";
                maxOut <= "0000000000000000";
                timeCounter <= clampToTxTime;
                nx_state <= state_TxVPP;

        END CASE;
    END PROCESS;    
END logic;

Salida de Quartus:

Info (12021): Found 1 design units, including 1 entities, in source file pulserevalboardcontroller.bdf
    Info (12023): Found entity 1: pulserEvalBoardController
Info (12021): Found 2 design units, including 1 entities, in source file pulserlogic.vhd
    Info (12022): Found design unit 1: pulserLogic-logic
    Info (12023): Found entity 1: pulserLogic
Info (12021): Found 2 design units, including 1 entities, in source file pulserpll.vhd
    Info (12022): Found design unit 1: pulserpll-SYN
    Info (12023): Found entity 1: pulserPLL
Info (12021): Found 2 design units, including 1 entities, in source file pulsepll.vhd
    Info (12022): Found design unit 1: pulsepll-SYN
    Info (12023): Found entity 1: pulsePLL
Info (12127): Elaborating entity "pulserEvalBoardController" for the top level hierarchy
Info (12128): Elaborating entity "pulserLogic" for hierarchy "pulserLogic:inst"
Warning (10631): VHDL Process Statement warning at pulserLogic.vhd(38): inferring latch(es) for signal or variable "triggerOut", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at pulserLogic.vhd(38): inferring latch(es) for signal or variable "rxTime", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at pulserLogic.vhd(38): inferring latch(es) for signal or variable "ledOut", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at pulserLogic.vhd(38): inferring latch(es) for signal or variable "clampToRxTime", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at pulserLogic.vhd(38): inferring latch(es) for signal or variable "clampToTxTime", which holds its previous value in one or more paths through the process
Info (10041): Inferred latch for "clampToTxTime[0]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[1]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[2]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[3]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[4]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[5]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[6]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[7]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[8]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[9]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[10]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[11]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[12]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[13]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[14]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[15]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[16]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[17]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToTxTime[18]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[0]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[1]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[2]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[3]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[4]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[5]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[6]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[7]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[8]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[9]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[10]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[11]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[12]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[13]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[14]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[15]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[16]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[17]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "clampToRxTime[18]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[0]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[1]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[2]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[3]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[4]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[5]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[6]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "ledOut[7]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[0]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[1]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[2]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[3]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[4]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[5]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[6]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[7]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[8]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[9]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[10]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[11]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[12]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[13]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[14]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[15]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[16]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[17]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "rxTime[18]" at pulserLogic.vhd(38)
Info (10041): Inferred latch for "triggerOut" at pulserLogic.vhd(38)
Info (12128): Elaborating entity "pulsePLL" for hierarchy "pulsePLL:inst1"
Info (12128): Elaborating entity "altpll" for hierarchy "pulsePLL:inst1|altpll:altpll_component"
Info (12130): Elaborated megafunction instantiation "pulsePLL:inst1|altpll:altpll_component"
Info (12133): Instantiated megafunction "pulsePLL:inst1|altpll:altpll_component" with the following parameter:
    Info (12134): Parameter "bandwidth_type" = "AUTO"
    Info (12134): Parameter "clk0_divide_by" = "1"
    Info (12134): Parameter "clk0_duty_cycle" = "50"
    Info (12134): Parameter "clk0_multiply_by" = "5"
    Info (12134): Parameter "clk0_phase_shift" = "0"
    Info (12134): Parameter "compensate_clock" = "CLK0"
    Info (12134): Parameter "inclk0_input_frequency" = "20000"
    Info (12134): Parameter "intended_device_family" = "Cyclone IV E"
    Info (12134): Parameter "lpm_hint" = "CBX_MODULE_PREFIX=pulsePLL"
    Info (12134): Parameter "lpm_type" = "altpll"
    Info (12134): Parameter "operation_mode" = "NORMAL"
    Info (12134): Parameter "pll_type" = "AUTO"
    Info (12134): Parameter "port_activeclock" = "PORT_UNUSED"
    Info (12134): Parameter "port_areset" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkbad0" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkbad1" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkloss" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkswitch" = "PORT_UNUSED"
    Info (12134): Parameter "port_configupdate" = "PORT_UNUSED"
    Info (12134): Parameter "port_fbin" = "PORT_UNUSED"
    Info (12134): Parameter "port_inclk0" = "PORT_USED"
    Info (12134): Parameter "port_inclk1" = "PORT_UNUSED"
    Info (12134): Parameter "port_locked" = "PORT_UNUSED"
    Info (12134): Parameter "port_pfdena" = "PORT_UNUSED"
    Info (12134): Parameter "port_phasecounterselect" = "PORT_UNUSED"
    Info (12134): Parameter "port_phasedone" = "PORT_UNUSED"
    Info (12134): Parameter "port_phasestep" = "PORT_UNUSED"
    Info (12134): Parameter "port_phaseupdown" = "PORT_UNUSED"
    Info (12134): Parameter "port_pllena" = "PORT_UNUSED"
    Info (12134): Parameter "port_scanaclr" = "PORT_UNUSED"
    Info (12134): Parameter "port_scanclk" = "PORT_UNUSED"
    Info (12134): Parameter "port_scanclkena" = "PORT_UNUSED"
    Info (12134): Parameter "port_scandata" = "PORT_UNUSED"
    Info (12134): Parameter "port_scandataout" = "PORT_UNUSED"
    Info (12134): Parameter "port_scandone" = "PORT_UNUSED"
    Info (12134): Parameter "port_scanread" = "PORT_UNUSED"
    Info (12134): Parameter "port_scanwrite" = "PORT_UNUSED"
    Info (12134): Parameter "port_clk0" = "PORT_USED"
    Info (12134): Parameter "port_clk1" = "PORT_UNUSED"
    Info (12134): Parameter "port_clk2" = "PORT_UNUSED"
    Info (12134): Parameter "port_clk3" = "PORT_UNUSED"
    Info (12134): Parameter "port_clk4" = "PORT_UNUSED"
    Info (12134): Parameter "port_clk5" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena0" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena1" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena2" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena3" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena4" = "PORT_UNUSED"
    Info (12134): Parameter "port_clkena5" = "PORT_UNUSED"
    Info (12134): Parameter "port_extclk0" = "PORT_UNUSED"
    Info (12134): Parameter "port_extclk1" = "PORT_UNUSED"
    Info (12134): Parameter "port_extclk2" = "PORT_UNUSED"
    Info (12134): Parameter "port_extclk3" = "PORT_UNUSED"
    Info (12134): Parameter "width_clock" = "5"
Info (12021): Found 1 design units, including 1 entities, in source file db/pulsepll_altpll.v
    Info (12023): Found entity 1: pulsePLL_altpll
Info (12128): Elaborating entity "pulsePLL_altpll" for hierarchy "pulsePLL:inst1|altpll:altpll_component|pulsePLL_altpll:auto_generated"
Warning (13012): Latch pulserLogic:inst|ledOut[6] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal pulserLogic:inst|pr_state.state_TxVPP
Warning (13012): Latch pulserLogic:inst|ledOut[3] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal pulserLogic:inst|pr_state.state_TxVPP
Warning (13012): Latch pulserLogic:inst|ledOut[2] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal pulserLogic:inst|pr_state.state_TxVPP
Warning (13012): Latch pulserLogic:inst|ledOut[1] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal pulserLogic:inst|pr_state.state_TxVPP
Warning (13012): Latch pulserLogic:inst|ledOut[0] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal pulserLogic:inst|pr_state.state_TxVPP
Warning (13024): Output pins are stuck at VCC or GND
    Warning (13410): Pin "triggerOut" is stuck at GND
    Warning (13410): Pin "ledOut[7]" is stuck at GND
    Warning (13410): Pin "ledOut[5]" is stuck at GND
    Warning (13410): Pin "ledOut[4]" is stuck at GND
Info (286030): Timing-Driven Synthesis is running
    
pregunta cgram

2 respuestas

3

El motivo de los enclavamientos se debe al hecho de que los resultados de su declaración de caso no se asignan para cada selección de caso posible. Así que ha creado un elemento de almacenamiento sin reloj, que es la definición de un pestillo.

¿Qué es ledOut cuando pr_state es state_Rx ? No está especificado por su declaración de caso, por lo que el sintetizador asume que necesita mantener ledOut en el valor que fuera anterior, lo que requiere un elemento de almacenamiento (memoria).

  • Por ejemplo, el siguiente diseño infiere un cierre:
entity inferred_latch is
  Port ( a  : in std_logic;
         b  : in std_logic;
         c  : out std_logic );
end inferred_latch;

architecture Behavioral of inferred_latch is begin process (a,b) begin case a is when '0' => c <= b; when others => end case; end process; end Behavioral;

Sinembargo,siasignamosunniveldeseñalacparatodoslosestadosposiblesdea,nosenecesitamemoria:

architectureBehavioralofno_latchisbeginprocess(a,b)begincaseaiswhen'0'=>c<=b;whenothers=>c<='0'endcase;endprocess;endBehavioral;

Parapregunta1:lapreguntaesunpocofueradetema,yaquesebasaenopiniones,perodiréquerecuerdohaberrecibidomuchousodellibroCircuitDesignwithVHDLporPedroni(ISBN0262162245).

Esperoqueestoayude.

editarenrespuestaalcomentario:
Creoqueeldiseñodeabajoesequivalenteasuoriginal.Nopuedodecirquesecomportecorrectamentecomoesperas.Dehecho,definitivamentehayunproblemaconelrangodelaseñaltimeCounter.Ensuestadostate_init,asignaunvaloraclampToTxTimequeesdemasiadograndeparaajustarsealrangodeclaradodetimeCounter,peromásadelanteenelestadostate_clampToTx,loasignadetodosmodos.

Tedejoparaaclararestosdetalles.Pero,creoqueestecódigoesequivalenteasuoriginal,perosinlospestillos:

LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;USEieee.numeric_std.all;ENTITYpulserLogicISPORT(clk,reset_n:INSTD_LOGIC;cfgDIP,stIn,maxIn:INSTD_LOGIC_VECTOR(7DOWNTO0);stOut,maxOut:OUTSTD_LOGIC_VECTOR(15DOWNTO0);ledOut:OUTSTD_LOGIC_VECTOR(7DOWNTO0);triggerOut:OUTSTD_LOGIC);ENDpulserLogic;ARCHITECTURElogicOFpulserLogicISSIGNALtimeCounter:INTEGERRANGE0TO300_000;--timingcounterTYPEstateIS(state_init,state_TxVPP,state_clampToRx,state_Rx,state_clampToTx);SIGNALpr_state,nx_state:state;signalpre_led:std_logic_vector(7downto0);signalcur_led:std_logic_vector(7downto0);BEGINledOut<=cur_led;triggerOut<='0';--resetandclockedstatemachinecontrollerprocessPROCESS(clk,reset_n)VARIABLEcount:INTEGERRANGE0to300_000;BEGINIF(reset_n='0')THEN--asynchronousresetpr_state<=state_init;count:=0;ELSIF(RISING_EDGE(clk))THEN--stayincurrentstateforsetnumberofclockcyclesthenmovetonextstatecount:=count+1;IF(count=timeCounter)THENpr_state<=nx_state;pre_led<=cur_led;count:=0;ENDIF;ENDIF;ENDPROCESS;--statedeclarationprocessPROCESS(pr_state,cfgDIP,pre_led)VARIABLEtxTime:INTEGERRANGE0to50;VARIABLEst_max_out:STD_LOGIC_VECTOR(15DOWNTO0):="0000000000000000";
    BEGIN

        stOut      <= st_max_out;
        maxOut     <= st_max_out;

        CASE cfgDIP IS
            WHEN "00000001" => 
                txTime := 15;
            WHEN "00000011" =>
                txTime := 20;
            WHEN "00000111" =>
                txTime := 25;   
            WHEN others =>
                txTime := 10;
        end case;

        CASE pr_state IS
            WHEN state_init =>                  -- initialize   
                cur_led <= "01000010";
                st_max_out := "0000000000000000";    -- clamp all outputs
                timeCounter <= 10;              -- nominal num of cycles in the init state
                nx_state <= state_TxVPP;  

            WHEN state_TxVPP =>
                cur_led <= cfgDIP;
                st_max_out := "1010101010101010";
                timeCounter <= txTime;  
                nx_state <= state_clampToRx;    

            WHEN state_clampToRx =>
                cur_led <= pre_led;
                st_max_out := "0000000000000000";
                timeCounter <= 200;             -- time between end of Tx and start of Rx, default 800ns (200 *4)
                nx_state <= state_Rx;

            WHEN state_Rx =>
                cur_led <= pre_led;
                st_max_out := "1111111111111111";
                timeCounter <= 10000;           -- set to nominal 40us rx time 
                nx_state <= state_clampToTx;    

            WHEN state_clampToTx =>
                cur_led <= pre_led;
                st_max_out := "0000000000000000";
                timeCounter <= 2489795;         -- time between end of Rx and start of Tx, default to 100Hz PRF
                nx_state <= state_TxVPP;
        END CASE;
    END PROCESS;    
END logic;
    
respondido por el Blair Fonville
2

pr_state se bloquea de forma asíncrona ya que reset_n es parte de la lista de sensibilidad de ese proceso. Como pr_state es parte de la lista de sensibilidad de su proceso de máquina de estado lógico de "próximo estado", todo lo que se encuentra dentro de ese proceso se marca con el tipo de advertencia "esto es una mala idea". En caso de que no lo supiera, el intérprete lógico ve la lista de sensibilidad como "si esta señal cambia, debo volver a ejecutar este proceso y ver si es necesario actualizar las salidas".

Si estás comenzando, aquí están mis sugerencias:

1) No utilice reinicios asíncronos a menos que sea absolutamente necesario. Si necesita un proceso temporizado, ponga solo la señal de reloj en la lista de sensibilidad. Aún puede implementar una lógica de reinicio, pero haga una versión síncrona (IE la declaración "if (reset_n = '0') entonces ..." va dentro de la declaración "if (rising_edge (clk)) entonces ...". La desventaja de esto es que el comportamiento de restablecimiento deseado no sucederá para 1 ciclo de reloj adicional, pero eso suele ser correcto. Además, las herramientas de ruta y lugar tienen un tiempo mucho más fácil para el enrutamiento de restablecimientos sincrónicos que los restablecimientos asíncronos globales. Hay algunos casos especiales donde deseará un comportamiento de "restablecimiento asíncrono, configuración sincrónica", pero el 99.9% de su lógica no debería ser así.

2) Combine su proceso cronometrado y el proceso lógico del "siguiente estado" en un solo proceso. Sé que muchos libros antiguos de VHDL lo hicieron de esta manera, pero generalmente me resulta más fácil escribirlo como un solo proceso. Puede deshacerse de la señal next_state y simplemente actualizar la señal pr_state directamente.

    
respondido por el user2913869

Lea otras preguntas en las etiquetas