Mux y Adder entrando en Infinite Loop

0

He estado tratando de aprender verilog con la ayuda de un proyecto. La mezcla que toma la salida del sumador como entrada y le da entrada al sumador según la señal de control entra en un bucle infinito, pero solo debe agregar hasta conteo = 9 y luego reiniciar. ¿Alguien puede señalar mi error?

Módulosuperior

'timescale1ns/1psmoduletop(inputCLK,inputRESETn,input[9:0]imgPixel,output[15:0]WORD_OUT);reg[3:0]counter;wireselect_in_mx1,select_out_mx1,select_in_mx2,select_out_mx2;wire[15:0]out_csr,in_mx0,out_mx0,in_mx1,out_mx1,in1_mx2,in2_mx2,out_mx2,in1_add0,in2_add0,out_add0;//InstantiatetheUnitUnderTest(UUT)cir_shift_reg_vcsr(.CLK(CLK),.RESETn(RESETn),.WORD_OUT(out_csr));assignin_mx0=out_csr;muxmx0(.WORD_IN1(in_mx0),.WORD_IN2(16'd0),.SELECT_BIT_IN(imgPixel[count_out]),.WORD_OUT(out_mx0));assignin1_add0=out_mx0;countercnt0(.CLK(CLK),.RESETn(RESETn),.count(count_out));assigncount_in=count_out;controlcrtl0(.counter(count_in),.condition(4'd0),.SELECT_BIT_OUT(select_out_mx1));assignselect_in_mx1=select_out_mx1;//assignin_mx1=out_add0;muxmx1(.WORD_IN1(16'd0),.WORD_IN2(in_mx1),.SELECT_BIT_IN(select_in_mx1),.WORD_OUT(out_mx1));assignin2_add0=out_mx1;adderadd0(.count(count_in),.WORD_IN1(in1_add0),.WORD_IN2(in2_add0),.WORD_OUT(out_add0));assignin1_mx2=out_add0;assignin_mx1=out_add0;controlcrtl1(.counter(count_in),.condition(4'd9),.SELECT_BIT_OUT(select_out_mx2));assignselect_in_mx2=select_out_mx2;assignin2_mx2=out_mx2;muxmx2(.WORD_IN1(in1_mx2),.WORD_IN2(in2_mx2),.SELECT_BIT_IN(select_in_mx2),.WORD_OUT(out_mx2));assignWORD_OUT=out_mx2;endmodule

Móduloderegistrodedesplazamientocircular

'timescale1ns/1psmodulecir_shift_reg_v(inputCLK,inputRESETn,outputreg[15:0]WORD_OUT);parameterinitialValue={16'h0,16'h1,16'h2,16'h3,16'h4,16'h5,16'h6,16'h7,16'h8,16'h9};//Thisworksbecauseconcatenationmakesita160bitwidevalue.reg[15:0]wordShiftReg[9:0];integeri;initialbeginfor(i=0;i<10;i=i+1)beginwordShiftReg[i]=initialValue[((9-i)*16)+:16];endendalways@(posedgeCLKornegedgeRESETn)beginif(RESETn==1'b0)beginfor(i=0;i<10;i=i+1)wordShiftReg[i]<=initialValue[((9-i)*16)+:16];endelsebeginWORD_OUT=wordShiftReg[0];for(i=0;i<9;i=i+1)beginwordShiftReg[i]<=wordShiftReg[i+1];endwordShiftReg[9]<=WORD_OUT;end$display("CSR op = %d",WORD_OUT);  
 end
 endmodule

Módulo Multiplexor

'timescale 1ns / 1ps
module mux(
input [15:0] WORD_IN1,
input [15:0] WORD_IN2,
input SELECT_BIT_IN,
output reg [15:0] WORD_OUT
);

always @(*) begin
$display ("SELECT BIT = %d", SELECT_BIT_IN);
$display ("WORD_IN1 = %d", WORD_IN1);
$display ("WORD_IN2 = %d", WORD_IN2);

WORD_OUT = (SELECT_BIT_IN) ? WORD_IN1 : WORD_IN2;
$display ("MUX op = %d",WORD_OUT);      
end     
endmodule

Módulo de contador

'timescale 1ns / 1ps
module counter(
input CLK,
input RESETn,
output reg [3:0] count
);

always @(posedge CLK or negedge RESETn) begin
if (RESETn == 1'd0) begin
    count <= 4'd9;
end 
else begin
    count <= ((count + 4'd1)%10);
end
//$display ("count = %d",count);
end  
endmodule

Módulo de control

'timescale 1ns / 1ps
module control(
input [3:0] counter,
input [3:0] condition,
output reg SELECT_BIT_OUT
);

always @(*) begin
$display ("Counter = %d", counter);
$display ("Condition = %d", condition);

SELECT_BIT_OUT = (counter==condition) ? 1'd1 : 1'd0;
$display ("CTRL op = %d",SELECT_BIT_OUT);       
end
endmodule

Módulo Adder

'timescale 1ns / 1ps
module adder(
input [15:0] WORD_IN1,
input [15:0] WORD_IN2,
output reg [15:0] WORD_OUT
);

always @(*) begin
$display ("WORD_IN1 = %d", WORD_IN1);
$display ("WORD_IN2 = %d", WORD_IN2);
WORD_OUT = WORD_IN1 + WORD_IN2;
$display ("ADD op = %d",WORD_OUT);      
end
endmodule

TestBench

'timescale 1ns / 1ps
module tb_top;

// Inputs
reg CLK;
reg RESETn;
reg [9:0] imgPixel;

// Outputs
wire [15:0] WORD_OUT;

// Instantiate the Unit Under Test (UUT)
top uut (
    .CLK(CLK),
    .RESETn(RESETn),    
    .imgPixel(imgPixel), 
    .WORD_OUT(WORD_OUT)
);

initial begin
    // Initialize Inputs
    RESETn = 0;
    CLK = 0;
    #10 CLK = 1;
    #10 CLK = 0;    
    // Wait 100 ns for global reset to finish
            //#100;
    #20 RESETn = 1;

    imgPixel = 10'b1000111010;
end    

    // Add stimulus here
always begin
    //if (RESETn == 1'b0) begin
        //CLK = 0;
        //RESETn = 1;
    //end   
    //else
        #10 CLK = ~CLK;
end

// monitor results
always @(negedge CLK)
$display("TOP op = %d\n",WORD_OUT);
endmodule

Indique las buenas prácticas y cualquier otra cosa que deba cambiarse. Gracias de antemano.

    
pregunta Ashutosh Jain

1 respuesta

1

Parece que mantienes el reloj bajo mientras que el reinicio es bajo. Esto puede evitar que algunas etapas se reinicien correctamente (no hay un CLK o negedge RESETn ). Observe que top reset no aparece en su salida. Generalmente, en una secuencia de encendido del mundo real, el voltaje se estabiliza, el reloj se iniciará y, una vez que esté estable y se aplique al circuito, se restablecerá el restablecimiento. Algunos circuitos requieren explícitamente una cantidad de ciclos de reloj de restablecimiento afirmados (LOW) para inicializar tuberías, etc.

// Add stimulus here 
always begin 
 // if   (RESETn == 1'b0) 
//      begin CLK = 0; not needed
//       RESETn = 1;  not needed
 // end else  
 #10 CLK = ~CLK; 
end
    
respondido por el Sean Houlihane

Lea otras preguntas en las etiquetas