AGM芯片AGM芯片
  • 首页
  • 产品中心
    • AGM MCU
    • AG32 MCU Series
    • AGM FPGA
    • AGM CPLD
    • AGM DEMO
  • 行业资讯
    • 行业新闻
    • 产品新闻
    • 技术专栏
    • 编程教程
  • 解决方案
    • 工业应用
    • 音视频应用
      • MCU用于Mini-LED背光控制应用方案
    • 按需定制
  • 服务支持
    • 软件下载
    • 帮助文档
    • AG32用户手册
  • 关于我们
    • 关于我们
    • 联系我们

最新资讯

  • 行业新闻
  • 产品新闻
  • 编程教程
  • 软件下载

产品中心

  • AGM MCU
  • AG32 MCU Series
  • AGM CPLD
  • AGM FPGA
  • AGM DEMO

解决方案

  • 工业应用
  • 按需定制
  • 音视频应用
  • AG32适合哪些开发者

  • AG32的并行多通道特性:MiniLED背光控制应用方案【首发】

  • 可编程系统级芯片比较:Cypress PSoC、Xilinx Zynq和AG3

  • AG32的核心价值是什么?

  • AGM:国产替代,我先行!

热门标签

  • MCU
  • AG32
  • 芯片
  • RAM
  • 国产MCU
  • GPU
  • 模拟芯片
  • FPGA
  • AI芯片
  • 汽车UWB
  • 车载信息娱乐
  • CPLD
  • 集成电路芯片
  • 小米
  • 32位车用MCU

AG32:MCU与CPLD深度交互解析与工程实践指南

2025年6月19日 106

文章目录[隐藏]

  • 引言
  • 一、MCU与CPLD交互方式概述
  • 二、MCU与CPLD直接信号交互:基础与进阶
    • 2.1 MCU传递信号给CPLD:基础实现
    • 2.2 CPLD传递信号给MCU:中断与事件处理
  • 三、MCU通过AHB总线读写CPLD:深度技术解析
    • 3.1 AHB总线基础与地址映射
    • 3.2 AHB总线协议深度解析
    • 3.3 CPLD内部寄存器映射的完整实现
  • 四、MCU通过AHB转APB的数据交互:慢速外设桥接
    • 4.1 AHB2APB桥接原理
    • 4.2 APB总线协议与信号详解
    • 4.3 APB从设备的完整实现
  • 五、DMA在CPLD中的应用:高效数据传输
    • 5.1 DMA工作流程
    • 5.2 CPLD端DMA实现
    • 5.3 MCU端DMA配置示例
  • 六、AG32 CPLD开发流程与工具链
    • 6.1 开发环境与工具
    • 6.2 开发最佳实践
  • 七、实例工程参考
  • 总结

引言

本文档详细介绍了AG32开发中MCU与CPLD交互的具体方式、技术原理以及工程实践。作为工程师,理解并掌握这些交互机制对于充分发挥AG32平台的性能优势至关重要。

CPLD工程创建及编译的操作流程,可参考文档《AG32下fpga和cpld的使用入门》。在工程中,用户逻辑部分编写从analog_ip.v的接口开始。

一、MCU与CPLD交互方式概述

MCU和CPLD之间的交互可以分为以下几种方式:

  1. 1. MCU传递信号给CPLD(如MCU的GPIO传递高低信号到CPLD)
  2. 2. CPLD传递信号给MCU(如对MCU产生中断信号)
  3. 3. MCU读写数据到CPLD(通过AHB总线)
  4. 4. MCU通过AHB转APB后的数据交互(用于慢速外设)
  5. 5. DMA在CPLD中的应用(高效数据搬运)

重要说明:不建议CPLD作为主设备对MCU写入。在MCU和CPLD交互中,CPLD更像一个外设,这种设计模式确保了系统的稳定性和可控性。

二、MCU与CPLD直接信号交互:基础与进阶

2.1 MCU传递信号给CPLD:基础实现

基础配置:在VE中定义信号:

GPIO4_1
iocvt_chn:OUTPUT

这表示用MCU的GPIO(gpio4_1)来输入信号到CPLD。

代码实现:Prepare LOGIC工程后,可以看到analog_ip.v接口中的信号:

input iocvt_chn_out_data,
input iocvt_chn_out_en,

这里的iocvt_chn_out_data就是对接到MCU的gpio4_1的信号。当控制MCU的gpio4_1高低切换时,CPLD中的iocvt_chn_out_data会对应变化。

工程实践考量:

对于来自MCU的异步信号,CPLD内部应至少使用两级触发器进行同步处理,以避免亚稳态:

// 同步器设计
reg  iocvt_chn_out_data_sync1;
reg  iocvt_chn_out_data_sync2;

always @(posedge sys_clock) begin
    iocvt_chn_out_data_sync1 <= iocvt_chn_out_data;
    iocvt_chn_out_data_sync2 <= iocvt_chn_out_data_sync1;
end

// 在CPLD内部逻辑中使用 iocvt_chn_out_data_sync2

关键设计要点:

  • • 信号电平匹配:确保MCU和CPLD之间的IO电平兼容(3.3V或1.8V)
  • • 信号完整性:对于高速信号,需要考虑信号线长度和阻抗匹配
  • • 时序约束:在VE工具中设置合适的时序约束

除了GPIO信号,PWM输出信号等也可以输入到CPLD。具体样例可参考"logic样例3.mcu信号到cpld到pin"。

2.2 CPLD传递信号给MCU:中断与事件处理

基础配置:在VE中定义信号:

GPIO4_2
iocvt_chn:INPUT

代码实现:

output iocvt_chn_in_data,

当CPLD中控制iocvt_chn_in_data信号高低时,MCU中的gpio4_2对应变化,可以触发MCU中断。

进阶中断处理设计:

// 中断信号生成逻辑
reg interrupt_pending;
reg [15:0] interrupt_counter;

always @(posedge sys_clock or negedge reset_n) begin
    if (!reset_n) begin
        interrupt_pending <= 1'b0;
        interrupt_counter <= 16'h0;
    end else begin
        // 基于特定条件生成中断
        if (data_ready && !interrupt_pending) begin
            interrupt_pending <= 1'b1;
            interrupt_counter <= 16'hFFFF; // 中断持续时间
        end else if (interrupt_pending && interrupt_counter > 0) begin
            interrupt_counter <= interrupt_counter - 1;
        end else if (interrupt_counter == 0) begin
            interrupt_pending <= 1'b0;
        end
    end
end

assign iocvt_chn_in_data = interrupt_pending;

实践考量:

  • • 中断触发方式:MCU中断可以是边沿触发或电平触发,CPLD输出信号应与MCU配置匹配
  • • 中断清除机制:设计合适的中断清除机制,避免重复触发
  • • 中断优先级:在MCU端合理设置中断优先级

三、MCU通过AHB总线读写CPLD:深度技术解析

3.1 AHB总线基础与地址映射

在地址设计中,CPLD的地址区间是:0x60000000 ~ 0x7FFFFFFF

当MCU对这个区间内的地址访问时,相当于访问了CPLD的"寄存器"。MCU端的操作非常简单:

// 读CPLD
int cpRdReg = *((int *)0x60000000);

// 写CPLD
*((int *)0x60000004) = cpWtReg;

3.2 AHB总线协议深度解析

当MCU读写动作发生时,AHB总线会将动作拆解为读写信号,传递到analog_ip.v的接口。理解AHB总线协议是设计CPLD从设备的关键。

关键信号详解:

// AHB从设备接口信号
input         Ahb_hclk;        // AHB时钟
input         Ahb_hresetn;     // AHB复位,低有效
input [31:0]  mem_ahb_haddr;   // 地址总线
input [31:0]  mem_ahb_hwdata;  // 写数据总线
input         mem_ahb_hwrite;  // 写/读控制 (1=写, 0=读)
input [1:0]   mem_ahb_htrans;  // 传输类型
input         mem_ahb_hready;  // 主设备准备好
output [31:0] mem_ahb_hrdata;  // 读数据总线
output        mem_ahb_hreadyout; // 从设备准备好
output [1:0]  mem_ahb_hresp;   // 响应信号

传输类型详解:

  • • 2'b00: IDLE - 空闲状态
  • • 2'b01: BUSY - 忙状态
  • • 2'b10: NONSEQ - 非连续传输,新传输的开始
  • • 2'b11: SEQ - 连续传输

3.3 CPLD内部寄存器映射的完整实现

以下是一个完整的CPLD AHB从设备实现示例:

// CPLD内部寄存器定义
reg [31:0] reg_control;    // 控制寄存器 (0x00偏移)
reg [31:0] reg_data;       // 数据寄存器 (0x04偏移)
reg [31:0] reg_status;     // 状态寄存器 (0x08偏移, 只读)

// AHB响应信号
reg          hreadyout_reg;
reg [31:0]   hrdata_mux;

// 地址解码与寄存器操作逻辑
always @(posedge Ahb_hclk or negedge Ahb_hresetn) begin
    if (!Ahb_hresetn) begin
        reg_control <= 32'h0;
        reg_data    <= 32'h0;
        reg_status  <= 32'h0;
        hreadyout_reg <= 1'b1;
    end else begin
        hreadyout_reg <= 1'b1; // 默认准备好
        
        // 有效传输检测
        if (mem_ahb_hready && (mem_ahb_htrans == 2'b10 || mem_ahb_htrans == 2'b11)) begin
            if (mem_ahb_hwrite) begin
                // 写操作
                case (mem_ahb_haddr[23:2])
                    22'h0: reg_control <= mem_ahb_hwdata;
                    22'h1: reg_data    <= mem_ahb_hwdata;
                    default: ; // 无效地址忽略
                endcase
            end else begin
                // 读操作 - 准备读数据
                case (mem_ahb_haddr[23:2])
                    22'h0: hrdata_mux <= reg_control;
                    22'h1: hrdata_mux <= reg_data;
                    22'h2: hrdata_mux <= reg_status;
                    default: hrdata_mux <= 32'hDEADBEEF; // 错误标识
                endcase
            end
        end
        
        // 状态寄存器更新逻辑(示例)
        reg_status[0] <= data_ready_flag;
        reg_status[1] <= error_flag;
        // ... 其他状态位
    end
end

assign mem_ahb_hrdata    = hrdata_mux;
assign mem_ahb_hreadyout = hreadyout_reg;
assign mem_ahb_hresp     = 2'b00; // OKAY响应

原文提供的基础读写示例:

MCU读操作的CPLD响应:

// MCU端:int value = *((int *)0x60000004);
reg [31:0] hrdata_reg;
always @(posedge sys_clock) begin
    if (mem_ahb_htrans == 2'b10 &&     // NONSEQ状态
        mem_ahb_hready &&               // master已ready
        !mem_ahb_hwrite &&              // 读操作
        mem_ahb_haddr[23:0] == 'h04)    // 地址匹配
    begin
        hrdata_reg <= hwdata_reg;       // 准备读数据
    end
end
assign mem_ahb_hrdata = hrdata_reg;

MCU写操作的CPLD响应:

// MCU端:*((int *)0x60000000) = value;
reg [31:0] hwdata_reg;
always @(posedge sys_clock) begin
    if (mem_ahb_htrans == 2'b00 &&     // IDLE状态
        mem_ahb_hreadyout &&            // CPLD已ready
        mem_ahb_hwrite &&               // 写操作
        mem_ahb_haddr[23:0] == 'h00)    // 地址匹配
    begin
        hwdata_reg <= mem_ahb_hwdata;   // 接收数据
    end
end

四、MCU通过AHB转APB的数据交互:慢速外设桥接

4.1 AHB2APB桥接原理

对于串口、SPI、I2C等慢速设备,直接挂载到AHB总线效率较低且设计复杂。需要通过AHB到APB的桥接(ahb2apb.v模块)来实现。

ahb2apb.v模块功能:

  • • 地址映射:将AHB地址空间映射到APB地址空间
  • • 时序转换:将AHB的多周期、流水线式传输转换为APB的简单两周期传输
  • • 信号转换:完成AHB信号到APB信号的协议转换

4.2 APB总线协议与信号详解

APB关键信号:

input         apb_clock;      // APB总线时钟
input         apb_resetn;     // APB复位信号
input         apb_psel;       // 外设选择信号
input         apb_penable;    // 传输使能(第二周期)
input         apb_pwrite;     // 传输方向 (1=写, 0=读)
input [31:0]  apb_paddr;      // 地址总线
input [31:0]  apb_pwdata;     // 写数据总线
output [31:0] apb_prdata;     // 读数据总线

4.3 APB从设备的完整实现

APB读操作实现:

// MCU端:int value = *((int *)0x60000004);
reg [31:0] ardata_reg;
always @(posedge apb_clock) begin
    if (!apb_pwrite &&          // 读操作
        apb_penable &&          // 第二周期
        apb_psel &&             // 片选有效
        apb_paddr[11:0] == 'h04) // 地址匹配
    begin
        ardata_reg <= awdata_reg; // 准备读数据
    end
end
assign apb_prdata = ardata_reg;

APB写操作实现:

// MCU端:*((int *)0x60000000) = value;
reg [31:0] awdata_reg;
always @(posedge apb_clock) begin
    if (apb_pwrite &&           // 写操作
        apb_penable &&          // 第二周期
        apb_psel &&             // 片选有效
        apb_paddr[11:0] == 'h00) // 地址匹配
    begin
        awdata_reg <= apb_pwdata; // 接收数据
    end
end

完整的APB从设备实现:

// CPLD内部寄存器
reg [31:0] apb_reg_config;    // 配置寄存器
reg [31:0] apb_reg_data;      // 数据寄存器
reg [31:0] apb_reg_status;    // 状态寄存器

always @(posedge apb_clock or negedge apb_resetn) begin
    if (!apb_resetn) begin
        apb_reg_config <= 32'h0;
        apb_reg_data   <= 32'h0;
        apb_reg_status <= 32'h0;
    end else begin
        if (apb_psel && apb_penable) begin
            if (apb_pwrite) begin
                // 写操作
                case (apb_paddr[11:2])
                    10'h00: apb_reg_config <= apb_pwdata;
                    10'h01: apb_reg_data   <= apb_pwdata;
                    default: ; // 无效地址忽略
                endcase
            end
        end
        
        // 状态寄存器更新
        apb_reg_status[0] <= data_ready;
        apb_reg_status[1] <= error_flag;
    end
end

// APB读数据输出
assign apb_prdata = (apb_psel && apb_penable && !apb_pwrite) ?
    (apb_paddr[11:2] == 10'h00 ? apb_reg_config :
     apb_paddr[11:2] == 10'h01 ? apb_reg_data :
     apb_paddr[11:2] == 10'h02 ? apb_reg_status : 32'hFFFFFFFF) : 32'h0;

五、DMA在CPLD中的应用:高效数据传输

5.1 DMA工作流程

DMA实现的基本逻辑:

  1. 1. MCU为master,CPLD为slave:MCU对CPLD的交互方式为存取寄存器
  2. 2. MCU配置DMA:设置DMA读取CPLD中准备好的数据
  3. 3. CPLD触发DMA:数据准备好后,触发DMA信号,DMA自动搬运到MCU指定的RAM
  4. 4. DMA完成反馈:搬运一次后,DMA给CPLD一个clear信号,完成一次DMA搬运
  5. 5. 循环执行:CPLD再次准备好数据时,重复上述过程

5.2 CPLD端DMA实现

对于CPLD来说,MCU来读取数据和DMA来读取数据是一致的,DMA读取时只是每次读完后会多给CPLD一个clear信号。

DMA触发逻辑的完整实现:

// DMA相关信号
input         dma_clear_signal;    // 来自MCU的DMA清除信号
output        dma_request_signal;  // 输出给MCU的DMA请求信号

// CPLD内部数据缓冲区
reg [31:0] data_buffer [0:63];     // 64个32位数据缓冲区
reg [5:0]  write_ptr;              // 写指针
reg [5:0]  read_ptr;               // 读指针
reg        data_ready_flag;        // 数据准备就绪标志
reg        dma_request_reg;        // DMA请求寄存器

// 数据写入逻辑(示例:来自外部数据源)
always @(posedge sys_clock) begin
    if (external_data_valid) begin
        data_buffer[write_ptr] <= external_data;
        write_ptr <= write_ptr + 1;
        
        // 缓冲区满时标记数据就绪
        if (write_ptr == 6'd63) begin
            data_ready_flag <= 1'b1;
            write_ptr <= 6'd0; // 环形缓冲区
        end
    end
end

// DMA请求生成逻辑
always @(posedge sys_clock or negedge dma_clear_signal) begin
    if (!dma_clear_signal) begin
        // DMA完成,清除请求
        data_ready_flag <= 1'b0;
        read_ptr <= 6'd0;
        dma_request_reg <= 1'b0;
    end else if (data_ready_flag && !dma_request_reg) begin
        // 数据准备好且未发起DMA请求
        dma_request_reg <= 1'b1;
    end
end

assign dma_request_signal = dma_request_reg;

// 响应DMA读取(通过AHB接口)
always @(posedge Ahb_hclk) begin
    if (mem_ahb_hready && !mem_ahb_hwrite && 
        (mem_ahb_htrans == 2'b10 || mem_ahb_htrans == 2'b11)) begin
        // DMA读取时更新读指针
        read_ptr <= read_ptr + 1;
    end
end

// DMA数据输出
assign mem_ahb_hrdata = data_buffer[mem_ahb_haddr[7:2]];

5.3 MCU端DMA配置示例

// MCU端DMA配置示例
void setup_dma_from_cpld(void) {
    // 配置DMA通道
    DMA_Channel->CPAR = 0x60000000;  // CPLD数据地址
    DMA_Channel->CMAR = (uint32_t)dma_buffer; // 目标内存地址
    DMA_Channel->CNDTR = 64;         // 传输数据量
    
    // 配置DMA控制寄存器
    DMA_Channel->CCR = DMA_CCR_EN |   // 使能DMA
                       DMA_CCR_MINC | // 内存地址递增
                       DMA_CCR_PSIZE_1 | // 外设32位
                       DMA_CCR_MSIZE_1 | // 内存32位
                       DMA_CCR_TCIE;  // 传输完成中断
}

六、AG32 CPLD开发流程与工具链

6.1 开发环境与工具

  1. 1. VE工具:AG32芯片开发套件中的CPLD逻辑设计集成开发环境
    • • 工程创建与管理
    • • IP核集成与配置
    • • 引脚约束设置
    • • 逻辑综合与布局布线
  2. 2. 硬件描述语言:Verilog/VHDL语言掌握
  3. 3. 仿真验证:功能仿真和时序仿真
  4. 4. 硬件调试:JTAG下载与调试

6.2 开发最佳实践

设计原则:

  • • 合理的时钟域规划
  • • 充分的时序约束
  • • 完善的复位策略
  • • 模块化设计思想

调试技巧:

  • • 使用内部信号监测
  • • 逻辑分析仪验证时序
  • • 分阶段验证功能模块

七、实例工程参考

本文档涉及的完整代码示例可参考以下样例工程:

  1. 1. logic样例3.mcu信号到cpld到pin - MCU信号控制CPLD的基础示例
  2. 2. 5.mcu读写cpld寄存器 - AHB/APB总线交互的完整实现
  3. 3. 7.cpld中配合实现mcu的dma读取 - DMA应用的完整示例

总结

MCU与CPLD的交互是AG32平台的核心优势之一,它结合了MCU的灵活性和CPLD的并行处理能力。通过深入理解AHB/APB总线协议、掌握CPLD内部寄存器映射和逻辑设计,以及熟悉相关的开发工具和调试方法,工程师可以充分发挥AG32平台的潜力,开发出高性能、高可靠性的嵌入式系统。

关键要点回顾:

  • • CPLD设计中的同步处理和时序考量
  • • AHB/APB总线协议的正确实现
  • • DMA机制的高效数据传输
  • • 系统级的设计思考和优化策略

通过本文档的学习和实践,工程师将能够熟练运用AG32平台进行复杂嵌入式系统的开发。


可编程系统级芯片比较:Cypress PSoC、Xilinx Zynq和AG3
« 上一篇 2025年6月19日

相关推荐

AGM是领先的32位AG32芯片,MCU,AI ASIC可编程SoC、和异构(MCU)芯片和方案提供商,AGM致力于为消费电子、工控和AIoT中高量市场提供智能化的设计软件和芯片系统

产品技术

  • AGM MCU
  • AGM FPGA
  • AGM CPLD
  • AGR V2K

行业新闻

  • 行业解决方案
  • 产品新闻
  • 行业新闻
  • 关于我们

帮助文档

  • MCU入门
  • MCU驱动使用
  • 联合编程
  • 例程集合

联系我们

工程师微信
在线留言

© Copyright 2013-2025 AGM国产MCU先用AG32 AINOW旗下芯片公司 All Rights Reserved. 版权所有

增值电信业务经营许可证备案号:浙ICP备18045792号-5

返回顶部

  • 首页 首页
  • 产品 产品
  • 电话 电话
  • 微信 微信