硬件環境: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