最近在准备2026年FPGA春招,看到很多面经里提到手撕Verilog实现AXI4-Lite的SPI控制器,但面试官喜欢追问时序图怎么读。我有点搞不清楚,比如写操作时,SPI的CPOL和CPHA怎么配置,AXI4-Lite的写地址通道和数据通道时序怎么对齐?求大佬给个具体波形分析,最好能画个时序图说明关键点,谢谢!
2026年FPGA春招,手撕Verilog实现AXI4-Lite的SPI控制器,时序图怎么看?求具体波形分析
10 个回答

先搞清楚面试官要你画哪个方向:是AXI4-Lite的写数据与写地址握手对齐,还是SPI的SCK相对CS/NSS的相位。两件事分开看,AWVALID和WVALID在同周期拉高是AXI协议允许的,SPI那边CPOL/CPHA决定SCK空闲电平和采样沿,动手画波形前先确认这两个边界。

个人觉得面试官追问时序图,多半是想看你有没有真正理解握手信号之间的依赖关系,而不是死记硬背。AXI4-Lite写操作,WVALID和AWVALID可以同时有效,但WREADY、AWREADY不一定在同一周期回,所以状态机里不要假设它们总是同步。SPI那边,CPOL和CPHA一共四种组合,面试常考CPHA=0时数据在第一个跳变沿采样,CPHA=1时在第二个跳变沿采样。你手撕代码时状态机可以分IDLE、ADDR、DATA、DONE四个状态,注意在ADDR状态里把AXI的地址锁存下来,然后根据addr译码出SPI的cs和sck相位。建议你提前画一张两行波形:上面是AXI通道,下面是SPI时序,标清楚WLAST和SPI传输结束的关系。

说实话你问的这个问题挺有代表性,很多人在校准备时容易卡在波形对齐上。我建议你换个角度:不要一上来就画完整的AXI+SPI混合时序,先分别画两张独立的波形图——一张是AXI4-Lite单次写操作的协议波形,重点标出AWVALID与AWREADY的握手、WVALID与WREADY的握手,以及BVALID与BREADY的回应;另一张是SPI的四种CPOL/CPHA模式,挑一种最常用的(比如CPOL=0, CPHA=0)画清楚SCK、MOSI、MISO和CS的时序关系。然后找一张纸把两个图上下拼在一起,中间加一条虚线表示状态机在何时拉高CS、何时采样MISO。常见误区是以为AXI的WVALID必须与AWVALID严格同时有效,实际上AXI协议允许写数据和写地址在同一个周期分别握手,只要在WLAST之前数据都已准备好就行。另一个容易翻车的地方是SPI的SCK频率与AXI时钟的关系,面试官可能会问你怎么处理跨时钟域,一般做法是把AXI的请求用FIFO缓存,SPI侧用独立的计数器生成SCK。你目前是在准备笔试阶段还是已经进到面试了?如果方便说,我可以再针对你的进度给点建议。

画时序图其实不用把AXI和SPI混在一起画成一张大图,那样反而容易乱。我的做法是:先单独画出AXI4-Lite写操作的四个通道波形,重点标出AWVALID和WREADY、WVALID和WREADY、BVALID和BREADY这三组握手点,特别是WVALID和AWVALID可以同周期有效但WREADY和AWREADY可能不同时回。然后单独画SPI的时序,选一种CPOL/CPHA组合,比如CPOL=0、CPHA=1,画清楚SCK和CS的关系。最后在状态机里定一个中间信号,比如spi_start,当AXI的写地址和数据都握手成功后拉高它,启动SPI传输。面试官追问时,你就指着这个spi_start说清楚它怎么来的。你目前是卡在AXI的握手依赖上,还是SPI的相位选择上?

个人感觉你这个问题其实可以拆成两个独立的子问题来准备,面试官问的时候也喜欢分开考。AXI4-Lite这边,写操作最容易被忽略的是WLAST信号的位置——它必须在最后一个写数据时拉高,而SPI传输的结束又依赖于你事先设定的字节数或者CS拉高的时机。如果你在状态机里把WLAST作为SPI传输结束的判断条件,那就要确保AXI的写数据数量和SPI的帧长度一致,否则会出现SPI提前结束或者多传一个字节的问题。一个常见做法是:在地址通道握手后锁存addr,然后在数据通道握手时用一个计数器记录已收到的数据个数,计数器满时拉高SPI的CS结束传输,同时回BVALID。这样WLAST只用于协议合规,不直接控制SPI。至于CPOL/CPHA,面试时如果没指定模式,你可以直接说默认用CPOL=0、CPHA=0,然后解释为什么选这个——因为数据在上升沿采样,和大多数SPI从机兼容。追问时序图时,你可以在纸上先画SCK空闲为低,再画CS拉低后第一个SCK上升沿数据采样,这样逻辑最清晰。你手头有SPI从机的datasheet吗?如果有,根据它的时序要求来画会更稳。

这个问题往深了想,其实暴露了一个很多应届生容易踩的坑:把AXI4-Lite的握手信号当成「同步触发」来用,而不是「异步握手」。实际工程里,AWVALID和WVALID虽然协议允许同周期有效,但经过总线的延迟和仲裁后,WREADY和AWREADY的返回时间可能差好几个时钟周期。所以状态机设计时,我建议你用一个独立的「地址已锁存」标志和一个「数据已接收」标志,两者都有效后才进入SPI传输阶段,而不是在同一个状态里同时等两个READY。这样代码可读性更好,也方便后期加流水。SPI那边,CPOL和CPHA的配置最好做成寄存器可配的,而不是写死在代码里。面试时你可以主动提:我会在AXI的地址空间里分配一个配置寄存器,比如偏移0x00,通过写这个寄存器来设置CPOL和CPHA,这样面试官会觉得你考虑了复用性。时序图的话,建议你分成三层来画:最上层是AXI写地址通道的AWVALID/AWREADY,中间层是写数据通道的WVALID/WREADY/WLAST,最下层是SPI的CS/SCK/MOSI。在AXI两个通道都握手完成的那个时钟周期,用一个内部信号拉高spi_en,然后spi_en持续到SPI传输结束。注意SPI的CS拉低后,SCK的第一个有效边沿要等至少半个SCK周期,这个在时序图上要标出来,面试官很在意这种细节。另一个容易漏的点是:SPI传输结束后,BVALID必须在下一个时钟周期内拉高,并且保持到BREADY有效,否则AXI协议会报错。所以你的状态机在SPI_DONE状态里要同时处理BVALID的拉高和BREADY的采样。整体来说,你把AXI当作一个「配置接口」,SPI当作一个「执行单元」,中间用一个简单的有限状态机做桥接,思路就清晰了。你准备用单周期握手还是三周期握手来实现AXI接口?不同的握手模式会影响状态机复杂度,可以提前想好。

你这个问题其实关键不在于把AXI和SPI的波形画在一起,而是先理清楚状态机的握手依赖。很多应届生一上来就想着画一个完整的时序图,结果把自己绕进去了。我建议你换个思路:先单独画出AXI4-Lite写操作的最小握手序列,重点看AWVALID和WVALID能不能同周期有效——协议允许,但实际总线仲裁后AWREADY和WREADY的返回时间可能错开,所以状态机里最好用一个临时寄存器锁存地址,等数据通道也握手成功后再一并触发SPI传输。SPI那边,CPOL和CPHA的配置不要写死在代码里,而是从AXI地址空间里映射一个配置寄存器,比如偏移0x00的低两位分别控制模式。这样面试官会觉得你考虑了复用性。画时序图时,建议你画两张独立的波形:一张是AXI的写地址和数据通道握手,标清楚WLAST的位置;另一张是SPI的SCK和CS关系,选CPOL=0、CPHA=0为例。面试官追问时,你就指着手里的波形说清楚握手信号的因果链,比硬背协议强很多。另外,注意一个常见坑:AXI的WLAST必须在最后一个写数据时拉高,而SPI的传输结束由你预设的字节数控制,两者不要绑定在一起,否则帧长度不匹配时容易提前结束或少传数据。你现在是卡在AXI的握手依赖上,还是SPI的相位选择上?

AXI和SPI的时序图分开画,别混在一起。写地址和数据通道握手不一定要同周期,状态机里加个标志位等两者都ready再启动SPI就行。CPOL/CPHA用寄存器配置,别写死。面试官问波形,你就指握手那几根线说清楚因果关系。

春招手撕这类控制器,面试官真正想看的不是你背协议,而是你如何处理跨时钟域和握手依赖。AXI4-Lite是同步总线,但SPI的SCK频率往往比系统时钟低很多,且SPI本身是同步串行接口,所以你需要一个中间状态机来做桥梁。我建议你从工程实现角度去准备:首先,AXI写操作时,地址通道和数据通道的握手虽然可以同周期发生,但为了稳健性,状态机里应该设计成先锁存地址,等数据准备好后再一起判断。具体做法是:在IDLE状态等待AWVALID和AWREADY握手,地址锁存到addr_reg,然后跳转到DATA状态;在DATA状态等待WVALID和WREADY握手,数据锁存到data_reg,同时把WLAST信号的位置处理好——注意WLAST必须在最后一个写数据时有效,而SPI传输的字节数由你预先配置的寄存器决定,所以状态机里要有一个计数器记录已接收的数据个数,计数器满时拉高CS结束SPI,同时回BVALID。SPI的CPOL和CPHA配置,建议在AXI地址空间里分配一个寄存器,比如基地址+0x00,写操作时修改该寄存器值,状态机根据该值选择SCK空闲电平和采样沿。面试官如果追问时序图,你就画三行:第一行是AXI的写地址和数据通道握手,第二行是状态机跳转,第三行是SPI的SCK、MOSI、CS。关键点在于标清楚SPI的启动信号(比如spi_start)是在AXI握手成功后拉高的,而CS的拉高和拉低则由字节计数器控制,与WLAST解耦。这样既符合协议,又避免了面试时常见的WLAST与SPI帧长度绑定的误区。另外,面试官可能会问:如果AXI写地址和数据分开到达怎么办?你的状态机需要能在一个地址下接收多笔写数据(比如burst传输),但AXI4-Lite只支持单次传输,所以不用考虑burst。如果你能主动提到这一点,说明你读透了协议。你现在是在校生还是已经投简历了?如果在校,我建议你拿Vivado或Quartus实际跑一次仿真,把波形dump出来对照协议手册看,比纯手画图有效得多。

说实话,你这个问题问得挺到位的,很多应届生春招准备时容易被面试官一句「你把这个时序图给我画一下」问懵,原因不是不懂协议,而是没想清楚面试官到底想听什么。我当年被问到类似问题时,踩过一个大坑:一上来就试图把AXI的地址通道、数据通道和SPI的SCK、CS画在同一张波形图里,结果越画越乱,面试官反而觉得我没抓住重点。后来跟一个做验证的老哥聊,他点醒了我——面试官想看的是你对手撕状态机里握手依赖关系的理解,而不是协议文档的截图。具体到你这个AXI4-Lite转SPI的问题,我建议你按这个思路准备:先单独画一张AXI4-Lite单次写操作的波形,只画三根时钟周期,重点标出AWVALID和AWREADY的握手点、WVALID和WREADY的握手点、以及BVALID和BREADY的回应,注意WVALID和AWVALID可以在同一周期有效,但WREADY和AWREADY的返回时间可能错开,所以状态机里不要假设它们总是同步返回,而是用两个寄存器分别锁存地址和数据,等两个握手都确认后再跳转到SPI启动状态。然后单独画一张SPI的时序,选一种CPOL/CPHA组合,比如CPOL=0、CPHA=0,画清楚SCK的边沿和MOSI数据的关系,以及CS拉低到第一个SCK边沿之间的建立时间。最后把两张图上下拼在一起,中间用一条虚线标注状态机何时拉高spi_start信号。面试官追问时,你就指着这个spi_start说清楚它是由AXI地址和数据握手都成功后触发的,然后SPI状态机收到spi_start后拉低CS开始传输,传输完成后回BVALID。这样既展示了你对AXI握手依赖的理解,又体现了状态机划分的清晰性。你目前是卡在AXI的WLAST和SPI传输长度怎么对齐上,还是SPI的相位选择上?
发表回答
登录后可在本页底部提交回答