Altifigence Academy

56 / 63 · Concepto

Banco de registros de dos lecturas y una escritura con bypass

Implemente lecturas independientes y escritura síncrona y compruebe bypass por dirección, inicialización y valid.

Almacenamiento que entrega dos valores a la vez

Para A+B se necesitan dos operandos en el mismo ciclo. Un banco de registrosRegistro Circuito que almacena varios bits de estado. Los registros síncronos de este curso capturan la entrada especificada en el flanco de reloj. Más información 2-read/1-write ofrece dos direcciones de lectura y una de escritura. Aquí almacena ocho palabras de 16 bits y registra ambas lecturas en flanco ascendente: direcciones de tres bits y 128 bits de capacidad. La dirección 0 es normal, sin regla de registro constante.

Cada lectura tiene enable y valid propios. Una puede detenerse mientras la otra lee, y ambas pueden leer la misma dirección. Dos direcciones simultáneas añaden un coste distinto del aumento de capacidad. En bancos pequeños puede usarse una matriz de flip-flopsFlip-flop Elemento que captura la entrada en el flanco de reloj especificado y la conserva hasta el siguiente. La entrada debe cumplir setup y hold. Más información y dos redes de selección; con RAM puede replicarse el almacenamiento y compartir escrituras para obtener más lecturas. La declaración RTL no garantiza el recurso sintetizado.

Si escribe lo que se está leyendo

El contrato responde el dato nuevo si lectura y escritura coinciden en dirección y flanco. Un bypass lleva wr_data directamente a la entrada del registro de lectura, sin esperar a actualizar la matriz. Para el puerto ii:

Hi=wr_en∧(wr_addr=rd_addri)H_i=\mathrm{wr\_en}\land(\mathrm{wr\_addr}=\mathrm{rd\_addr}_i)

Si rd_eni=1\mathrm{rd\_en}_i=1:

Ri+={wr_data,Hi=1M−[rd_addri],Hi=0R_i^{+}=\begin{cases} \mathrm{wr\_data}, & H_i=1\\ M^{-}[\mathrm{rd\_addr}_i], & H_i=0 \end{cases}

M−M^{-} es el contenido previo. Compare cada dirección de lectura de forma independiente. Derivar wr_data a ambos puertos por colisión en uno corrompe el otro operando. Si se omite wr_en, el bypass se activa erróneamente incluso sin escritura cuando wr_addr coincide.

SystemVerilog
module regfile8x16_2r1w (
  input  logic        clk, rst, wr_en,
  input  logic [2:0]  wr_addr,
  input  logic [15:0] wr_data,
  input  logic        rd_en0, rd_en1,
  input  logic [2:0]  rd_addr0, rd_addr1,
  output logic [15:0] rd_data0, rd_data1,
  output logic        rd_valid0, rd_valid1
);
  timeunit 1ns;
  timeprecision 1ps;
  logic [15:0] mem [0:7];

  always_ff @(posedge clk) begin
    if (rst) begin
      rd_valid0 <= 1'b0;
      rd_valid1 <= 1'b0;
    end else begin
      rd_valid0 <= rd_en0;
      rd_valid1 <= rd_en1;
      if (wr_en)
        mem[wr_addr] <= wr_data;
      if (rd_en0)
        rd_data0 <= (wr_en && wr_addr == rd_addr0)
                  ? wr_data : mem[rd_addr0];
      if (rd_en1)
        rd_data1 <= (wr_en && wr_addr == rd_addr1)
                  ? wr_data : mem[rd_addr1];
    end
  end
endmodule

Bypass cambia la selección de entrada, pero no elimina la etapa registrada. Aplique dirección y solicitud antes del flanco y observe después; un registro posterior puede recibir la respuesta en el siguiente flanco. Cambiar a lectura combinacional altera camino y contrato temporal, no es una simple abreviatura de código.

Ejemplo: solo un puerto colisiona

Suponga M[2]=12 y M[5]=7 previamente escritos. Antes de E0, active ambas lecturas con rd_addr0=2, rd_addr1=5 y escriba 20 en 2. Después, el puerto 0 responde 20 por bypass y el 1 responde 7 almacenado. La suma es 27, frente a 19 de una implementación read-first sin bypass.

En E1, lea 2 en ambos puertos mientras escribe 30 allí: ambos responden 30. En E2, mantenga wr_addr=2, wr_data=99, pero wr_en=0 y lea 2: ambos deben responder 30. Ese ciclo detecta un bypass basado solo en igualdad de direcciones. En E3, rd_en0=0 y rd_en1=1 producen valid 0 y 1 respectivamente.

Cada columna registra un flanco ascendenteFlanco ascendente Instante en que el reloj pasa de 0 a 1. Se distingue del nivel alto, que abarca todo el intervalo con CLK=1. Más información, entradas previas y estados «después» actualizados, sin dibujar retardo físicoRetardo de propagación Tiempo desde un cambio de entrada hasta que la salida se estabiliza en el valor correcto. La equivalencia lógica y el comportamiento temporal son propiedades distintas. Más información. Se parte de M[2]=12,M[5]=7, ambas lecturas siempre activas y escritura en 2. La última columna no debe derivar 99 porque wr_en=0.

Cada puerto selecciona de forma independiente ante la misma escritura
Ver los datos de la forma de onda
Datos de la forma de onda: cada carácter es un intervalo; un punto conserva el estado anterior; p representa un ciclo de reloj.
SeñalForma de ondaValores del bus
flanco234E0 → E1 → E2
wr_en1.0
wr_data23420 → 30 → 99
rd_addr02..2
rd_addr123.5 → 2
out0 después23.20 → 30
out1 después23.7 → 30

Qué necesita inicialización

Reset síncrono activo en alto impide escribir y borra ambos valid; no resetea matriz ni datos de salida. Conservar datos antiguos con valid=0 es correcto. El contenido de la matriz permanece. Si el sistema admite solo trabajos nuevos tras reset, defina su secuencia de inicialización aparte.

Leer una dirección durante su primera escritura sí produce un valor definido mediante bypass. Leerla sin escritura antes de inicializar sigue siendo indeterminado. rd_valid indica respuesta, no un bit initialized por dirección. La referencia debe comprobar que el contenido sea conocido antes de calcular una lectura normal y tratar por separado el bypass simultáneo.

Verifique las cuatro combinaciones de enables, direcciones iguales/distintas, colisión con ningún puerto, con 0, con 1 o con ambos, escrituras consecutivas y prioridad de reset. Múltiples escrituras quedan fuera del alcance: añadirlas exige definir primero la prioridad al escribir simultáneamente la misma dirección. Más puertos cambian contrato y coste.

Inténtalo tú

M[1]=4 y M[4]=9. Con ambas lecturas activas en 1 y 4, se escribe 13 en 4: ¿qué pareja sale? En el siguiente flanco, wr_en=0, wr_addr=1, wr_data=99 y ambas lecturas en 1: ¿qué sale? Después desactive solo el puerto 0 y explique valid y consumo.

Leer la explicación

Primero (4,13): solo el puerto 1 colisiona y deriva el nuevo 13. Después (4,4): wr_en=0 impide usar 99. Al desactivar el puerto 0, rd_valid0=0 y rd_valid1=1; su registro de datos conserva el anterior, pero no debe consumirse como respuesta válida. La dirección 0 es escribible y legible como las demás.

Tu elección se aplica a este navegador. Puedes cambiarla en el pie de página.