Processing math: 100%

1 votos

Modelado de circuitos a partir de FSM con Verilog

Estoy tratando de entender el concepto de modelar un circuito a partir de un FSM en Verilog.

He intentado escribir el procedimiento que he utilizado en la imagen de abajo para asegurarme de que lo he hecho bien: enter image description here

Basado en la solución, el circuito es el siguiente: enter image description here

El código Verilog que he desarrollado es:-

//----------------------------------------
//module bit stream generator
//-----------------------------------------

module generator(
clk,    
stream  //generated stream
);
output stream;
input clk;
reg c;
wire stream;
assign stream=c;

initial
begin
c=1'd0;
end

always@(posedge clk)
begin
    //c=!c;
    c = {$random} %2;
    //$display("a= %b",c);
end
endmodule

//----------------------------------------
//module D flip flip
//-----------------------------------------

module d(q_w,q0_w,d,c);
output q_w,q0_w;
input c,d;

//wire c;
reg q,q0;
wire q_w,q0_w;
assign q_w=q;
assign q0_w=q0;

    initial 
       begin
           q=1'b0; q0=1'b1;
      end
    always @ (posedge c)
       begin 
         q=d;
         q0= ~d;
       end
endmodule

//----------------------------------------
//module sequencedetector
//-----------------------------------------

module sequencedetector(
clk,
x,  //input bit stream
out //output from sequence detector
);

input x,clk;
output out;

wire x,y0,y_0,y1,y_1,g12,g32,g2d1,out;

d dff1(.q_w(y1),.q0_w(y_1),.d(g2d1),.c(clk));   //flip flop D1
d dff0(.q_w(y0),.q0_w(y_0),.d(x),.c(clk));  //Flip Flop D2

and gate1(g12,x,y0);
or gate2(g2d1,g12,g32);
and gate3(g32,y1,y0);
and gate4(out,x,y_0,y1);

endmodule

//----------------------------------------
//module sequencedetector testbench
//-----------------------------------------

module sequencedetector_tb;

reg clk;
wire out,x;

sequencedetector UUT(
.clk(clk),
.x(x),
.out(out));

generator UUTgen(
.clk(clk),
.stream(x));

initial begin
clk=1'b0;
//stream=1'b0;
//=1'b0;
end

initial  
begin
    $dumpfile ("counter.vcd"); 
    $dumpvars(0); 
end

always
    begin
    #20 clk=!clk;
    end

initial
    begin
    #20000 $finish;
    end 
endmodule

Pero lamentablemente la salida no es la esperada El circuito no detecta ninguna seqiencia ya que la salida es siempre BAJA. No soy capaz de subir la instantánea de GTKwave por falta de reputación suficiente.

Cualquier ayuda es muy apreciada

EDITAR

Acabo de descubrir que en el código del flip flop la salida (q) no seguía a la entrada (d) cuando el bit de entrada cambiaba durante un solo ciclo, probablemente porque el muestreo se hacía al mismo tiempo que los cambios (en el flujo de bits). Este código requería que los bits cambiados mantuvieran al menos 2 ciclos para ser seguidos por la salida del flip flop. Introduje un retraso de 2 ciclos en el código del flip flop y la salida es la esperada.

always @ (posedge c)
           begin 
            #2 q=d;
             q0= ~d;
           end

El problema ahora es qué debo hacer si necesito implementar el código Verilog en un hardware real. Me refiero a cuál es la alternativa de retardo (#2) si necesito hacer un código sintetizable (definitivamente no multitud de puertas) pero alguna función Verilog estándar amigable con el hardware, tal vez.

2voto

Jonas Puntos 1764

Se desea utilizar una asignación no bloqueante. Estas asignaciones cambian en el flanco de reloj.

always @ (posedge c)
begin 
    q  <= d;
    q0 <= ~d;
end

Para ilustrar las implicaciones de la asignación con bloqueo y sin bloqueo, considere el siguiente ejemplo.

Dos salidas, A y B. A es conducido por la entrada, y B es conducido por a A.

module flipflop(
    input c,
    input d,
    output reg a,
    output reg b
    );

   always@(posedge c) begin
      a        <= d;
      b        <= a;

   end
endmodule

Eso produce esto:

ab non blocking

Como puedes ver, hay un flip flop entre la salida A y la salida B.

Ahora el ejemplo de bloqueo:

module flipflop(
    input c,
    input d,
    output reg a,
    output reg b
    );

   always@(posedge c) begin
      a        = d;
      b        = a;

   end
endmodule

Eso produce esto:

ab blocking

Ya no hay retraso entre A y B.

Si quieres un retardo de varios cc, es necesario utilizar una asignación no bloqueante para inferir el número correcto de FF necesarios. Aquí hay un ejemplo de una señal registrada triple en hw que crea un retardo de 3 cc:

module flipflop(
    input c,
    input d,
    output q
    );

   reg [2:0]   q_i;

   always@(posedge c) begin
      q_i[0]   <= d;
      q_i[2:1] <= q_i[1:0];

   end

   assign q = q_i[2];

endmodule

Crea este esquema en síntesis:

triple reg blocking

Las herramientas han deducido los FDRE en estos casos. Véase el guía de bibliotecas xilinx (página 185) para darte una idea de las primitivas disponibles (altera tendrá otras similares, probablemente).

He ejecutado tu código en vivado 2015.3 y ha funcionado bien:

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X