跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言

基于高云 FPGA 与 STM32 的 FMC 通信协议实现

FPGA 与 STM32 通过 FMC 协议实现高速通信。文章解析了 STM32 FSMC 控制器的优势,提供了高云 FPGA 端的 Verilog 读写逻辑代码,并梳理了关键控制信号(如片选、读写使能)及 22 个引脚的配置细节,帮助开发者快速搭建跨芯片数据交互方案。

CryptoLab发布于 2026/4/10更新于 2026/9/1063 浏览
基于高云 FPGA 与 STM32 的 FMC 通信协议实现

概述

利用高云 FPGA 与 STM32 进行 FMC 通信,核心在于地址映射与控制信号的时序配合。通过合理配置引脚和逻辑,可以实现稳定的数据交互。

FPGA Interface

STM32 侧配置

这里的 FMC_A0 表示的是地址线。系统中有 13 位地址线和 16 位数据线,行地址与列地址是公用的:作为行地址时使用了 012 位,作为列地址时使用了 08 位。

关键控制信号定义如下:

  • FMC_SDNWE:低电平时写,高电平时读;
  • FMC_SDNCAS:列地址选通信号,低电平有效;
  • FMC_SDNRAS:行地址选通信号,低电平有效;
  • FMC_SDNE0:片选信号,低电平有效;
  • FMC_BA0~1:Bank 选择信号,两位对应 4 个区域;
  • FMC_SDCKE0:时钟使能信号;
  • FMC_SDCLK:时钟信号;
  • FMC_NBL0~1:写访问的输出字节屏蔽,即数据掩码。

在实际板子中,这实际上是 FMC 控制器对内核地址映射的结果,其实质就是对于地址的控制。有没有简单的方法呢?有的!STM32 自带的 FSMC 功能,就是专门为这类存储器设计的。在 STM32 上,有一些引脚被专门设计成地址线,还有一些被专门设计成数据线,还有一些被设计成控制线。然后这些地址线和数据线对应着固定的地址,只要外部的 DRAM 等存储器将对应的数据线连接到 STM32 这些对应的引脚上,引脚功能设置为复用模式,通过配置 FSMC,你可以直接给上面那个固定的地址赋值,其他操作 STM32 都会自动给你完成,就可以把数据存储到 SRAM 中。

这里 FPGA 的通信也是如此,在配置好引脚后对其进行自动赋值,然后再对地址进行读写操作。

Pin Mapping

在高云这里,有二十二个引脚需要我们去配置。这个是目前对于 Muxed PSRAM 的配置。

Configuration

Config Detail

Config Detail 2

Config Detail 3

这里我们重点挑出 FMC_NL、FMC_NOE、FMC_NWE、FMC_NE2 进行研究。这里一共有 20 个引脚。

对应一下 FPGA 的接口定义:

FPGA Pins

FPGA 这里除了数据线外多了 RST、FPGA_WR_NWE、FPGA_RD_NOE、FPGA_NL_NADV、FPGA_CS_NEL、CLK。这里有 22 个引脚,我们可以发现,这里多了两个引脚,一个是由 PLL 来进行时钟控制,还有一个则是用于硬件的复位重启。

FPGA 逻辑实现

下面是具体的 Verilog 模块代码,实现了 FSMC 的读写逻辑。注意地址线的解码和数据的三态控制。

module fsmc (
    ab,      // address
    db,      // data
    wrn,     // write
    rdn,     // read
    resetn,  // reset
    csn,     // chip select
    ina,     // input data a
    inb,     // input data b
    inc,     // input data c
    ind,     // input data d
    ine,     // input data e
    inf,     // input data f
    ing,     // input data g
    inh,     // input data h
    outa,    // output data a
    outb,    // output data b
    outc,    // output data c
    outd,    // output data d
    oute,    // output data e
    outf,    // output data f
    outg,    // output data g
    outh     // output data h
);

input [2:0] ab;
inout [15:0] db;
input wrn;
input rdn;
input resetn;
input csn;
input [15:0] ina;
input [15:0] inb;
input [15:0] inc;
input [15:0] ind;
input [15:0] ine;
input [15:0] inf;
input [15:0] ing;
input [15:0] inh;
output reg [15:0] outa;
output reg [15:0] outb;
output reg [15:0] outc;
output reg [15:0] outd;
output reg [15:0] oute;
output reg [15:0] outf;
output reg [15:0] outg;
output reg [15:0] outh;

wire rd;
wire wr;
reg [15:0] indata;

// 生成读脉冲
assign rd = !(csn & rdn);
// 生成写脉冲
assign wr = !(csn & wrn);

// 数据总线驱动:读时输出内部数据,否则高阻
assign db = rd ? indata : 16'hzzzz;

// 写数据:根据地址线选择八个空间写入,每个空间 16 位
always @(negedge wr or negedge resetn) begin
    if (!resetn) begin
        outa <= 16'h0000;
        outb <= 16'h0000;
        outc <= 16'h0000;
        outd <= 16'h0000;
        oute <= 16'h0000;
        outf <= 16'h0000;
        outg <= 16'h0000;
        outh <= 16'h0000;
    end else begin
        case (ab)
            3'b000: outa <= db;
            3'b001: outb <= db;
            3'b010: outc <= db;
            3'b011: outd <= db;
            3'b100: oute <= db;
            3'b101: outf <= db;
            3'b110: outg <= db;
            3'b111: outh <= db;
            default: ;
        endcase
    end
end

// 读数据:根据地址线选择 8 个空间读取,每个空间 16 位
always @(rd or !resetn) begin
    if (!resetn)
        indata <= 16'h0000;
    else begin
        case (ab)
            3'b000: indata <= ina;
            3'b001: indata <= inb;
            3'b010: indata <= inc;
            3'b011: indata <= ind;
            3'b100: indata <= ine;
            3'b101: indata <= inf;
            3'b110: indata <= ing;
            3'b111: indata <= inh;
            default: ;
        endcase
    end
end

endmodule

实际运行时会遇到时序问题,建议结合仿真波形验证读写脉冲的宽度是否满足外部存储器的要求。

目录

  1. 概述
  2. STM32 侧配置
  3. FPGA 逻辑实现

更多推荐文章

查看全部
  • 面板数据模型原理与Python实现
  • DeepSeek-R1 大模型基于 MS-Swift 框架的部署、推理与微调实践
  • C++ 类和对象进阶:四大默认成员函数与 const 对象详解
  • 网络安全从业人员必考的几本核心证书
  • 位运算算法实战:判断字符唯一、丢失数字及两数之和等 5 题解析
  • 开源知识库 RAGFlow 从部署到实战操作详解
  • MySQL 运维实战:常见问题排查与解决方案
  • 基于星辰 RPA 的小红书自动发文机器人实现指南
  • 网络安全工程师职业指南:职责、技能与认证路径
  • Neo4j APOC 插件安装与配置指南
  • 高效集成 Gemini API:Zotero 学术场景 AI 辅助分析指南
  • C++ 算法刷题实战:重组偶数、体操队形及二叉树路径和
  • Python 脚本自动对齐 C++ 数组代码
  • VS Code 禁用 GitHub Copilot 代码自动补全
  • VS Code 配置 C/C++ 编程运行环境教程
  • Java 性能监控工具:jcmd 命令详解
  • VSCode 配置普通 Java 项目使用 Lombok
  • JavaScript 开发常用工具函数精选
  • 黑客入门:破除刻板印象与认知误区
  • C++ STL 容器适配器详解:stack、queue 与 priority_queue 原理

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online