Como evitar travas durante a síntese

9

Quero projetar um bloco de lógica combinatória usando VHDL, mas, ocasionalmente, o resultado sintetizado contém uma trava não intencional.

Quais diretrizes de codificação eu preciso seguir para evitar que o sintetizador deduza travas?

Exemplo: no pequeno segmento de código, devo usar instruções if-else?

W5VO
fonte
Se alguém puder obter o que eu tento perguntar, informe-me
Eu não tinha certeza do que você quis dizer com o seu exemplo. Verifique se a reformulação corresponde à sua intenção original.
W5VO
@fatai, eu já comentei, existe um método específico para excluir sua conta disponível no meta.stackexchange.com. Vinculei a última pergunta em que fui sinalizada. Os moderadores no local não têm esse poder, nunca. Isso requer entrar em contato com a equipe de desenvolvimento.
precisa saber é o seguinte

Respostas:

13

Para evitar travas, é necessário garantir que todas as suas saídas sejam atribuídas em todas as possíveis ramificações do código.

por exemplo,

if a = '1' then
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

geraria uma trava, porque na primeira condição, o valor de b (1) não é especificado; portanto, o compilador decidiu que você deseja manter o valor anterior de b (1) lá. Uma maneira de escrever isso que não geraria uma trava é:

if a = '1' then
   b <= prev_b;
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

...

if rising_edge (clk)
    prev_b <= b;
end if;

Aqui, você declara explicitamente que b deve reter seu valor antigo e depois substitui b (0) pelo novo valor.

Outra maneira é dar um valor padrão ba, como na resposta do @ TomiJ.

Se você publicar o código no qual está obtendo uma trava, poderemos ajudá-lo a encontrar o motivo específico.

fbo
fonte
Não acho que sua abordagem b <= bevite uma trava, pois ainda requer a preservação do estado do sinal.
Tomi Junnila
Tu podes estar certo; Estou muito acostumado a lógica cronometrada. Eu vou editar.
fbo
6

Se você estiver usando processos para a lógica combinacional (e não aconselho isso por esse motivo), certifique-se de que todo caminho no processo atribua algo a todos os sinais que o processo conduz. Nenhuma das saídas pode depender de nenhuma das saídas da "última vez" que o processo foi executado.

Caso contrário, você deduz uma trava porque na próxima vez que o processo é agendado, ele deve manter o valor do sinal que não recebeu um novo valor da última vez.

Prefiro manter a lógica puramente combinatória como atribuições contínuas e usar processos para a lógica com clock, para que não receba travas.

Martin Thompson
fonte
5

Quatro regras para evitar travas:

  • Não leia os sinais nos quais você escreve.
  • Tenha uma lista de sensibilidade correta (todos os sinais que você lê devem estar na lista de sensibilidade)
  • Verifique se todos os sinais aos quais sua gravação está atribuída em todos os caminhos. (por exemplo: em cada ramo de uma instrução if-else)
  • Para processos que usam variáveis, verifique se todas as variáveis ​​foram inicializadas com um valor padrão antes de lê-las (em outra variável ou sinal).

Além disso, se você tiver vários processos combinacionais, certifique-se de não criar um loop.

Vários estilos de codificação podem ajudá-lo a seguir essas regras, por exemplo, o estilo na resposta do @ TomiJ. Como @Martin Thompson ressalta, pode ser melhor evitar a lógica combinacional todos juntos. Coloque tudo em um processo cronometrado.

Philippe
fonte
+1 Bom conjunto de regras. Você concorda que sua regra nº 2 (sobre a lista de sensibilidade) é realmente importante para garantir resultados consistentes entre a síntese e as simulações, mas realmente não faz diferença na inferência de travas?
Rick
@rick AFAIK, não há garantia do que uma ferramenta de síntese fará com listas de sensibilidade incompletas. O padrão IEEE para a síntese VHDL (1076.6-1999) afirma que: "A lista de sensibilidade do processo deve conter todos os sinais lidos na declaração do processo. Processos com listas de sensibilidade incompletas não são suportados". Dito isto, eu sei que certas ferramentas de síntese (talvez todas?) Aceitam listas de sensibilidade incompletas, mas simplesmente ignoram a lista de sensibilidade juntas. Se você confiar nesse comportamento, em vez do padrão IEEE mais rigoroso, acho que sua afirmação estaria correta.
Philippe
Obrigado, parece certo, isso tornaria meu modelo não compatível com esse padrão. Só fiquei curioso porque todas as ferramentas de síntese que vi até agora ignoram a lista de sensibilidade, mas ouvi rumores de que alguns poderiam inferir travas.
Rick
3

Como foi apontado por @fbo e @Martin Thompson, você precisa garantir que todo sinal acionado pelo processo receba algum valor em cada ramo do processo, e esse valor não deve depender do estado anterior de nenhuma das saídas do processo.

A maneira mais fácil de garantir isso é atribuir algum valor padrão a cada saída no início do processo, por exemplo (cooptando o exemplo do fbo):

COMBO: process(a)
begin
    b <= (others => '0'); -- Assign default value to b
    if a = '1' then
        b(0) <= '1';
    else
        b(1 downto 0) <= "00";
    end if;
end process COMBO;
Tomi Junnila
fonte
11
Este é um bom método que costumo usar. Às vezes, porém, um aviso de trava pode indicar que você esqueceu de atribuir alguns bits, enquanto esse método pode dificultar a localização do bug. Por exemplo, se você estivesse atribuindo todos os bits de um sinal amplo separadamente e acidentalmente desmontado.
fbo
2
Somente em um processo combinatório. Em um processo com relógio, você deduz um flip-flop, que pode ser exatamente o que você deseja.
Martin Thompson