FMC與FPGA雙口ram通信

硬件環境:ARM+FPGA經過FMC互聯,STM32F767和 EP4CE15F23I7異步

FMC設置,STM的系統時鐘HCLK爲216MHzspa

 1 /* FMC initialization function */
 2 void MX_FMC_Init(void)
 3 {
 4   FMC_NORSRAM_TimingTypeDef Timing;
 5 
 6   /** Perform the NOR1 memory initialization sequence
 7   */
 8   hnor1.Instance = FMC_NORSRAM_DEVICE;
 9   hnor1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
10   /* hnor1.Init */
11   hnor1.Init.NSBank = FMC_NORSRAM_BANK1;
12   hnor1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
13   hnor1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
14   hnor1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
15   hnor1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
16   hnor1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
17   hnor1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
18   hnor1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
19   hnor1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
20   hnor1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
21   hnor1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
22   hnor1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
23   hnor1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
24   hnor1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
25   hnor1.Init.PageSize = FMC_PAGE_SIZE_NONE;
26   /* Timing */
27   Timing.AddressSetupTime = 5;   
28   Timing.AddressHoldTime = 1;    
29   Timing.DataSetupTime = 4; 
30   Timing.BusTurnAroundDuration = 0;
31   Timing.CLKDivision = 0;
32   Timing.DataLatency = 0;
33   Timing.AccessMode = FMC_ACCESS_MODE_A;
34   /* ExtTiming */
35 
36   if (HAL_NOR_Init(&hnor1, &Timing, NULL) != HAL_OK)
37   {
38     _Error_Handler(__FILE__, __LINE__);
39   }
40 }

verilog核心代碼,其中雙口ram的a口與FPGA內部模塊相連,b口與ARMFMC端口相連,clk時鐘爲100MHz調試

 1 reg wr_clk1,wr_clk2;.
 2 wire rd = (cs0 | rdn);
 3 wire wr = (cs0 | wrn);
 4 wire clk_b = (!wr_clk2 | !rd);
 5 
 6 ram u1(
 7     .data_a(data_a),
 8     .address_a(address_a),
 9     .wren_a(wren_a),
10     .rden_a(rden_a),
11     .clock_a(clk_50m),
12     .q_a(dataout_a),
13     
14     .data_b(db),
15     .address_b(ab),
16     .wren_b(!wr),
17     .rden_b(!rd),
18     .clock_b(clk_b),
19     .q_b(dataout_b)
20 );
21 
22 always@(posedge clk_100m or negedge rst_n)
23     if(!rst_n)
24         begin
25             wr_clk1 <= 1'd1;
26             wr_clk2 <= 1'd1;
27         end
28     else 
29         {wr_clk2,wr_clk1} <= {wr_clk1,wr};
30         
31 assign db = !rd ? dataout_b : 16'hzzzz;

在SignalTap中調試發現有時寫入丟失(寫入後讀出不正常),時序上具體體現爲code

上圖中wr信號丟失,形成部分寫入失敗,wr由ARM輸出,與FPGA時鐘異步,這裏是時鐘匹配問題,致使信號丟失,查看STM32F7XX手冊關於FMC時序:orm

圖中能夠看到,  rd與ADDSET時間有關,wr與DATAST-1時間有關,結合前面FMC程序中blog

Timing.DataSetupTime = 4;it

那麼wr理論時間是3*HCLK = 3/216MHZ  ≈14ns, FPGA時鐘週期10ns,理論上wr信號不會丟失。猜測多是異步信號,同時信號邊沿存在斜率(有條件能夠用示波器捕捉驗證),可能存在信號丟失現象,這裏修改FMC時間配置參數。io

1 /* Timing */
2   Timing.AddressSetupTime = 9;   
3   Timing.AddressHoldTime = 1;    
4   Timing.DataSetupTime = 8;      
5   Timing.BusTurnAroundDuration = 0;
6   Timing.CLKDivision = 0;
7   Timing.DataLatency = 0;
8   Timing.AccessMode = FMC_ACCESS_MODE_A;

修改後發現以上問題獲得解決,調試時序以下:function

相關文章
相關標籤/搜索