8bit shift left register con serial in, serial out implementado en verilog

0

Tomé un ejemplo del sitio web que describe la serie de 8 bits en el registro de salida a la izquierda de la serie.

module shift (clk, si, so);
input        clk,si;
output       so;
reg    [7:0] tmp;
always @(posedge clk)
begin
   tmp    <= tmp << 1;
   tmp[0] <= si;
end
   assign so = tmp[7];
    endmodule

del ejemplo anterior, creo que esta es una implementación extraña. Esto se debe a que, dentro de always , cuando tmp[0] <= si; se ejecuta primero, tomaremos una salida inesperada.

Por ejemplo, supongamos que si es 1, y cuando tmp es:

1010 1010

y, cuando tmp[0] <= si; se ejecuta primero (lo que hará una salida inesperada), la salida es:

0101 0110

Pero, si las instrucciones always se ejecutan secuencialmente como se escribe en el ejemplo anterior, la salida es

0101 0101

Como resultado, no podemos garantizar que el resultado sea el que esperábamos.

Estoy en lo cierto? Por lo tanto, la implementación correcta debe ser:

tmp <= (tmp << 1) + {7'b0000_000, si};

O, ¿podemos probar que el ejemplo anterior siempre se ejecuta secuencialmente?

    
pregunta sungjun cho

1 respuesta

1

Los idiomas HDL no funcionan como otros lenguajes de computadora. Todos tienen lo que se denomina asignaciones 'concurrentes'. Lo que significa que todas las tareas tienen lugar 'al mismo tiempo'.

Por lo tanto, tmp [0] obtiene el valor si al mismo tiempo que tmp [7: 1] obtiene el valor de tmp [6: 0].

  

¿Tengo razón?

No, te sugiero que estudies Verilog y VHDL con más detalle.

Creo que veo de dónde vienes. En Verilog, cuando hay varias asignaciones simultáneas, la última gana.

Por lo tanto, a tmp [0] se le asigna un cero: tmp <= tmp << 1;
A continuación se asigna si: tmp[0] <= si;
La última anula la anterior.

Estoy de acuerdo en que es una codificación descuidada aquí.

Sin embargo, hay casos en los que usar esa técnica mejora enormemente la legibilidad del código. Siempre agrego un comentario como este:

...
... // big complex FSM 
...
// Overrides all previous assignments above!     
if (emergency_stop)
   state <= FSM_IDLE;
    
respondido por el Oldfart

Lea otras preguntas en las etiquetas