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
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