Pergunta

Preciso implementar uma função 4 para 1 no Veriog.A entrada é de 4 bits, um número de 0 a 15.A saída é um único bit, 0 ou 1.Cada entrada fornece uma saída diferente e o mapeamento de entradas para saídas é conhecido, mas as entradas e saídas em si não são.Quero que vocês otimizem o código com sucesso e também que ele seja o mais curto/organizado possível.Minha solução até agora:

wire [3:0] a;
wire b;
wire [15:0] c;

assign c = 16'b0100110010111010; //for example but could be any constant
assign b = c[a];

Ter que declarar c é feio e não sei se vcs vão reconhecer o K-map aí.Isso funcionará tão bem como uma declaração de caso ou uma atribuição na forma normal conjuntiva?

Foi útil?

Solução

O que você tem está bem.Uma declaração de caso também funcionaria igualmente bem.É apenas uma questão de quão expressivo você deseja ser.

Sua solução, indexação, funciona bem se as codificações selecionadas não tiverem nenhum significado especial (um seletor de endereço de memória, por exemplo).Se as codificações selecionadas tiverem algum significado semântico especial para você, o designer (e não houver muitas delas), use uma instrução case e enums.

Em termos de síntese, não importa qual você usa.Qualquer ferramenta de síntese decente produzirá o mesmo resultado.

Outras dicas

Concordo totalmente com Dallas.Use uma declaração de caso - isso torna sua intenção mais clara.A ferramenta de síntese irá construí-la como uma tabela de consulta (se for paralela) e otimizará tudo o que puder.

Além disso, eu não me preocuparia tanto em manter seu código RTL curto.Eu atiraria primeiro para maior clareza.As ferramentas de síntese são mais inteligentes do que você pensa...

Minha preferência - se fizer sentido para o seu problema - é por uma instrução case que faça uso de enums ou `defines.Qualquer coisa para facilitar a revisão, manutenção e verificação do código.

Para coisas como essa, a clareza RTL supera tudo por uma ampla margem.SystemVerilog tem diretivas especiais de sempre bloco para deixar claro quando o bloco deve ser sintetizado para lógica combinacional, travas ou flops (e sua ferramenta de síntese deve gerar um erro se você tiver escrito RTL que entre em conflito com isso (por exemplo,não incluindo todos os sinais na lista de sensibilidade de um bloco sempre).Esteja ciente também de que a ferramenta provavelmente substituirá qualquer codificação que você tenha pela codificação mais eficiente em termos de hardware (aquela que minimiza a área do seu design total), a menos que a própria codificação se propague para os pinos do seu módulo de nível superior.

Este conselho também vale em geral.Torne seu código fácil de entender por humanos, e provavelmente será mais compreensível também para a ferramenta de síntese, o que permite trazer literalmente de forma mais eficaz milhares de anos-homem de pesquisa de algoritmos para apoiar seu RTL.

Você também pode codificá-lo usando operadores ternários, se quiser, mas eu prefiro algo como:

always_comb //or "always @*" if you don't have an SV-enabled tool flow
begin 
  case(a)
  begin
    4'b0000: b = 1'b0;
    4'b0001: b = 1'b1;
    ...
    4'b1111: b = 1'b0;
    //If you don't specify a "default" clause, your synthesis tool
    //Should scream at you if you didn't specify all cases,
    //Which is a good thing (tm)
  endcase //a
end //always

Aparentemente estou usando uma péssima ferramenta de síntese.:-) Acabei de sintetizar as duas versões (apenas o módulo usando um modelo baseado em fan-outs para atrasos de fio) e a versão de indexação da pergunta deu melhores resultados de tempo e área do que as declarações de caso.Usando Synopsys DC Z-2007.03-SP.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top