Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

Cyclone V SDRAM brige blocked and CPU DMA sync

Hi everyone,

I'm currently trying to implement a FPGA design using a 325 MHz clock, which writes to the SDRAM Controller of a Cyclone V 5CSEBA6U23I7 (Speed Grade 7).

When running my IP Core with 2 MHz everything works fine, but when I change the PLL clock to either 200 MHz or 325 MHz the data I can observe with SignalTap becomes completly random.

I've attached an image, in which I want to point out the 4th signal (bRun), which should be constant at 1, but in the observation toggles to 0 and back to 1. Some other signals also experience completly random behaviour, like some internal busses, which carry non-zero data, when they should be zero.

I don't think this is an EMC problem, because I'm using a development board (DE10-Nano from terasic) and all signals are FPGA-internal, which should be able to handle these clockspeeds.

The IP-Core is written in Verilog and I made sure to synchronize read and write operations on different edges of the respective clock to make sure, that the signals are stable and not transitioning when being read.

Following you can find the code for my RAM-write state machine, but as stated it works perfectly fine at 2 MHz.

If you guys have any idea about the reason for this behaviour I'd be very thankful.


    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 <= fifo_out;
                            avm_m0_byteenable <= 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;
                        if(state==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
No RepliesBe the first to reply