Pregunta

Así que tengo una matriz de 4 módulos de RAM en los que quiero poder leer / escribir en función de dos señales de selector diferentes. En este momento estoy instanciando la RAM usando señales intermedias:

    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

Y quiero seleccionar la RAM para usar usando señales head o tail (vectores de 2 bits). ¿Alguna idea de cómo hacer esto?

¿Fue útil?

Solución

Soy nuevo aquí y aún no puedo comentar preguntas, pero en respuesta a Marty: la mayoría de las herramientas de síntesis FPGA traducirán señales internas de múltiples fuentes con valores tristados a una lógica similar a MUX, cuando sea posible. Consulte, por ejemplo: una descripción del antiguo comportamiento de tristate-to-logic que me suena exacto .

Como una recomendación a Adam, probablemente sea mejor hacer esto explícito en su código al realizar el enmascaramiento usted mismo en lugar de usar los tristados. Esto mejorará la portabilidad, le dará resultados más predecibles y servirá como documentación propia si alguien alguna vez tiene que volver a visitar su código.

Sin embargo, haciendo algunas conjeturas basadas en su solución, probablemente tendría sentido simplemente enmascarar la activación del reloj en el puerto de escritura y silenciar la salida del puerto de lectura. Por ejemplo:

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

Esto probablemente resultará en una lógica menos compleja ( es decir, , mejor área y retraso) que su solución.

Otros consejos

Creo que lo descubrí, tengo que usar una declaración de generación:

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

me alegra saber que encontró una solución para su problema. Debo admitir que no entendí completamente lo que estabas haciendo, pero un comentario, también puedes usar if dentro de generar declaraciones y así crear instancias de diferentes módulos o usar diferentes señales dependientes de genvar , por ejemplo:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top