Entrada única para matriz de módulos personalizados em Verilog
Pergunta
Então, eu tenho um conjunto de 4 módulos de RAM que eu quero ser capaz de leitura / gravação para baseada em dois sinais seletor diferentes. Agora eu estou instanciar a RAM através de sinais de intermediários:
genvar i;
generate
for (i = 0; i < regnum; i=i+1) begin: regs
rfram_generic rf (clk,rst,ce_a_int[i],addr_a_int[i],do_a_int[i],
ce_b_int[i],addr_b_int[i],do_b_int[i],
ce_w_int[i],we_w_int[i],addr_w_int[i],
di_w_int[i]);
end
endgenerate
E eu quero selecionar a memória RAM para usar usando tanto head
ou tail
sinais (vetores 2 bits). Alguma idéia de como fazer isso?
Solução
Eu sou novo aqui e não posso comentar sobre questões ainda, mas em resposta a Marty: a maioria das ferramentas FPGA síntese irá traduzir sinais de várias origens internas com valores tristate em MUX-como lógica, sempre que possível. Veja, por exemplo: uma descrição do comportamento antigo tristate-to-lógica que sons precisos para me .
Como recomendação para Adam, você é provavelmente melhor fora de fazer isso explícito em seu código executando a si mesmo mascarando em vez de usar os tristates. Isto irá melhorar a portabilidade, dar-lhe resultados mais previsíveis, e servem como auto-documentação, se ninguém nunca tem que rever o seu código.
No entanto, fazer algumas suposições baseadas em sua solução, ele provavelmente faria sentido simplesmente mascarar o relógio habilitar na porta de escrita e mux a saída do porto de leitura. Por exemplo:
reg [WIDTH-1:0] do_a,do_b;
always @(*) do_a = do_a_int[head];
always @(*) do_b = do_b_int[tail];
generate
genvar i;
for (i = 0; i < regnum; i=i+1) begin: regs
rfram_generic rf (clk,rst,
ce_a,addr_a,do_a_int[i],
ce_b,addr_b,do_b_int[i],
ce_w,head==i?we_w:1'b0,addr_w,di_w);
end
endgenerate
Isto irá provavelmente resultar na lógica menos complexa ( i. , melhor área e atraso) do que a sua solução.
Outras dicas
Eu acho que percebi isso, tenho que usar uma instrução gerar:
genvar i;
generate
for (i = 0; i < regnum; i=i+1) begin: sigassign
//read from the checkpoint in progress
assign ce_a_int[i] = (head == i) ? ce_a : 'bz;
assign addr_a_int[i] = (head == i) ? addr_a : 'bz;
assign do_a = (head == i) ? do_a_int[i] : 'bz;
//write to the checkpoint in progress
assign ce_w_int[i] = (head == i) ? ce_w : 'bz;
assign we_w_int[i] = (head == i) ? we_w : 'bz;
assign addr_w_int[i] = (head == i) ? addr_w : 'bz;
assign di_w_int[i] = (head == i) ? di_w : 'bz;
//read from the last stable checkpoint
assign ce_b_int[i] = (tail == i) ? ce_b : 'bz;
assign addr_b_int[i] = (tail == i) ? addr_b : 'bz;
assign do_b = (tail == i) ? do_b_int[i] : 'bz;
end
endgenerate
feliz em ouvir que você encontrou uma solução para o seu problema. Devo admitir que eu não compreender totalmente o que você estava fazendo, mas um comentário, você também pode usar if
dentro gerar instruções e módulos assim instanciar diferentes ou usar sinais diferentes dependente da genvar
, por exemplo:.
generate
genvar i;
for (i = 0; i < regnum; i=i+1) begin: regs
if (i == head) begin
rfram_generic_a rf(...);
end else if (i == tail) begin
rfram_generic_b rf(...);
end else begin
rfram_generic_c rf(...);
end
end
endgenerate