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