Corrupción de datos del ciclón V a alta frecuencia

0

Actualmente estoy intentando implementar un diseño FPGA utilizando un reloj de 325 MHz, que escribe en el Controlador SDRAM de un Cyclone V 5CSEBA6U23I7 (Grado de velocidad 7).
Cuando ejecuto mi IP Core con 2 MHz, todo funciona bien, pero cuando cambio el reloj PLL a 200 MHz o 325 MHz, los datos que puedo observar con SignalTap se vuelven completamente aleatorios. He adjuntado una imagen, en la que quiero señalar la 4ª señal (bRun), que debería ser constante en 1, pero en la observación cambia a 0 y vuelve a 1. Algunas otras señales también experimentan un comportamiento completamente aleatorio, como algunos buses internos, que llevan datos que no son cero, cuando deberían estar a cero.
No creo que esto sea un problema de EMC, porque estoy usando una placa de desarrollo (DE10-Nano de terasica) y todas las señales son FPGA interno, que debería poder manejar estas velocidades de reloj.
El IP-Core está escrito en Verilog y me aseguré de sincronizar las operaciones de lectura y escritura en diferentes bordes del reloj respectivo para asegurarnos de que las señales sean estables y no estén en transición cuando se estén leyendo. A continuación, puede encontrar el código de mi máquina de estado de escritura RAM, pero como se indicó, funciona perfectamente bien a 2 MHz.
Si ustedes tuvieran alguna idea sobre la razón de este comportamiento, estaría muy agradecido.

always@(posedge clock_clk_ram or posedge reset_reset)
begin
    if(reset_reset)
    begin
        imgSize <= 32'b0;
        nCntCurPos <= 4'b0;
        nOutWord <= 256'b0;
        irqFromFPGAMaster <= 0;
        state <= 3'b0;

        fifo_read <= 0;

        avm_m0_address <= 27'b0;
        avm_m0_writedata <= 256'b0;
        avm_m0_write <= 0;
        avm_m0_byteenable <= 32'b0;
    end
    else
    begin
        if(clearIrqFromHPS||~bRun)//reset all states after irq has been handled, or if device has been stopped
        begin
            imgSize <= 32'b0;
            nCntCurPos <= 4'b0;
            nOutWord <= 256'b0;
            irqFromFPGAMaster <= 0;
            state <= 3'b0;

            fifo_read <= 0;

            avm_m0_address <= 27'b0;
            avm_m0_writedata <= 256'b0;
            avm_m0_write <= 0;
            avm_m0_byteenable <= 32'b0;
        end
        else if(bRun && ~irqFromFPGAMaster && ~clearIrqFromHPS)//RAM access okay
        begin
            case(state) 
                'b000://accumulate 256 bit data
                begin
                    if(~fifo_empty)// && fifo_rnuminfifo!='b0001)
                    begin
                        imgSize <= imgSize + 'd2;//is going to be incremented in the next cycle (d-flipflop)
                        nCntCurPos <= nCntCurPos + 4'b1;//is going to be incremented in the next cycle (d-flipflop)
                        fifo_read <= 1;
                        irqFromFPGAMaster <= 0;
                        avm_m0_address <= 27'b0;
                        avm_m0_writedata <= 256'b0;
                        avm_m0_write <= 0;

                        nOutWord[nCntCurPos*16 +: 16] <= fifo_out;
                        avm_m0_byteenable[nCntCurPos*2 +: 2] <= 2'b11;

                        if(imgSize >= maxImgSize - 32'd2)   //image done, transmit data and fire irq
                            state <= 3'b101;
                        else if(nCntCurPos=='d15)       //process transfer without irq
                            state <= 3'b001;
                        else                                    //else continue to accumulate data
                            state <= 3'b000;
                    end
                    else//FIFO is empty, wait for more data
                    begin
                        imgSize <= imgSize;
                        nCntCurPos <= nCntCurPos;
                        nOutWord <= nOutWord;
                        irqFromFPGAMaster <= 0;
                        state <= 3'b000;

                        fifo_read <= 0;

                        avm_m0_address <= 27'b0;
                        avm_m0_writedata <= 256'b0;
                        avm_m0_write <= 0;
                        avm_m0_byteenable <= avm_m0_byteenable;
                    end
                end
                'b001,//write to sdram, after that accumulate more data
                'b101://write to sdram, after that trigger interrupt
                begin
                    imgSize <= imgSize;
                    nCntCurPos <= 4'b0;
                    nOutWord <= nOutWord;
                    irqFromFPGAMaster <= 0;
                    fifo_read <= 0;
                    if(imgSize>32)  avm_m0_address <= baseAddress+((imgSize>>5)-27'd1);
                    else                avm_m0_address <= baseAddress;
                    avm_m0_writedata <= nOutWord;
                    avm_m0_write <= 1;
                    avm_m0_byteenable <= avm_m0_byteenable;
                    if(~avm_m0_waitrequest) state <= state ^ 3'b011;
                    else                            state <= state;
                end
                'b010,//end of single transmit
                'b110://end of img, 
                begin
                    imgSize <= imgSize;
                    nCntCurPos <= 4'b0;
                    nOutWord <= 256'b0;

                    fifo_read <= 0;

                    avm_m0_address <= 27'b0;
                    avm_m0_writedata <= 256'b0;
                    avm_m0_write <= 0;
                    avm_m0_byteenable <= 32'b0;

                    irqFromFPGAMaster <= state[2];
                    if(state[2]==0)     state <= 3'b000;
                    else                    state <= state;
                end
            endcase
        end
        else//Running, but IRQ hasn't been handled yet, preserve some data
        begin
            imgSize <= imgSize;
            irqFromFPGAMaster <= irqFromFPGAMaster;
            //irqFromFPGAMaster <= 0;
            //imgSize <= 32'd0;

            nCntCurPos <= 4'b0;
            nOutWord <= 256'b0;
            state <= 3'b0;
            fifo_read <= 0;
            avm_m0_address <= 27'b0;
            avm_m0_writedata <= 256'b0;
            avm_m0_write <= 0;
            avm_m0_byteenable <= 32'b0;
        end
    end
end

También solo fyi: la bRun Signal está siendo asignada por un Avalon MM-Slave conectado al procesador ARm del ciclón V. Durante el período observado no ha habido ninguna comunicación con el procesador, por lo que bRun no debería cambiar. . Esto tampoco explicaría el bus NRZ, que debería ser RZ, como se ve en el código de Verilog.

    
pregunta Krustenkaese

1 respuesta

5

Ya que dice que conoció la funcionalidad correcta a 2 MHz, pero no en una frecuencia más alta. Es muy probable que sea una violación de tiempo de configuración / espera. Realice un análisis de tiempo de todo el diseño para la restricción de reloj de 325 MHz y verifique que su diseño funcione a 325 MHz. Luego proceda a las pruebas a bordo.

    
respondido por el MITU RAJ

Lea otras preguntas en las etiquetas