searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

FPGA编写模块将avalon memory mapped接口转为apb接口

2025-09-26 10:17:47
1
0

在FPGA开发过程中,我们会用到各种协议的接口。有的模块之间接口协议不同,则需要自行实现转接模块。近期我们某个工程需要将avalon memory mapped格式的接口转为apb格式的接口,以控制IP核的配置寄存器。使用system verilog语言可以编写简易模块实现。

首先简单介绍一下这两种接口协议。Avalon Memory-Mapped(Avalon-MM)协议是Altera公司在其 FPGA 产品中广泛采用的一种总线接口协议。它采用存储器映射方式,将所有外围设备映射到统一地址空间,主设备可通过地址对从设备进行读写操作。除clock和reset之外,基本的信号定义如下。

名称 方向 解释
addr i 地址
read i 读信号
write i 写信号
readdata o 读出数据
readvalid o 读出数据有效
writedata i 写入数据
waitrequest o 当为1时,表明从设备繁忙,需要保持输入接口状态不变,直到waitrequest拉低

APB总线则是ARM公司推出的AMBA(Advanced Microcontroller Bus Architecture)总线架构中的一员,主打低功耗、低成本、简化接口,专为连接低速、低带宽的外围设备设计以 “简单稳定” 为核心优势。除clock和reset之外,基本信号如下。

名称 方向 解释
sel i 从设备选择信号,表示正在选择该从设备
enable i 传输使能信号,表明在传输阶段
addr i 地址
write i 写标记,如果等于0则是读操作,否则是写操作。
writedata i 写入数据
readdata o 读出数据
ready o 当为1时,表示从设备准备就绪

APB总线从机接口具有3种状态,IDLE,SETUP和ACCESS,分别表示等待、传输建立和传输执行。采用enum结构进行实现,并将其作为状态机。

typedef enum logic [1:0] {
         IDLE   = 2'b00,
         SETUP  = 2'b01,
         ACCESS = 2'b10 
} state_t;

状态变迁则根据apb总线的定义执行,当收到avmm总线的read或write信号后,接下来两周期进入SETUP和ACCESS。随后根据后面从机是否ready,确定这一次传输结束或者继续等在这里。

always_comb begin
        next_state = current_state;        
        case (current_state)
            IDLE: begin
                if (avmm_read || avmm_write) begin
                    next_state = SETUP;
                end
            end           
            SETUP: begin
                next_state = ACCESS;
            end            
            ACCESS: begin
                if (apb_ready) begin
                    next_state = IDLE;
                end
            end            
            default: begin
                next_state = IDLE;
            end
        endcase
    end

如果是写数据过程,则需要在IDLE时刻,当avmm总线给出写数据请求时,锁存住需要写的地址和数据。如果是读数据过程,则需要在apb总线传输ACCESS时刻,将数据锁存住,等待返回给avmm。

always_ff @(posedge clk or posedge rst) begin
        if (rst) begin
            apb_addr_reg    <= '0;
            apb_write_reg   <= 1'b0;
            apb_wdata_reg   <= '0;
        end else if (current_state == IDLE && (avmm_read || avmm_write)) begin
            // when access is detected in IDLE state, latch address and data
            apb_addr_reg    <= {{(APB_ADDR_WIDTH-AVMM_ADDR_WIDTH){1'b0}}, avmm_addr};
            apb_write_reg   <= avmm_write;
            apb_wdata_reg   <= avmm_wdata;
        end
    end
    
    always_ff @(posedge clk or posedge rst) begin
        if (rst) begin
            avmm_rdata_reg       <= '0;
            avmm_rdata_valid_reg <= 1'b0;
        end else if (current_state == ACCESS && apb_ready && !apb_write_reg) begin
            // when APB read operation is completed, latch read data
            avmm_rdata_reg       <= apb_rdata;
            avmm_rdata_valid_reg <= 1'b1;
        end else begin
            avmm_rdata_valid_reg <= 1'b0;
        end
    end

最后,需要返回给avmm总线的waitrequest信号。我们规定,只有模块处于IDLE状态,才允许avmm总线信号变化,否则需要保持不变。因此直接使用以下语句即可。

assign avmm_waitrequest = (current_state != IDLE);

最终实现的读写波形分别如下。
read.png

write.png

0条评论
0 / 1000
cuixinyu
8文章数
0粉丝数
cuixinyu
8 文章 | 0 粉丝
原创

FPGA编写模块将avalon memory mapped接口转为apb接口

2025-09-26 10:17:47
1
0

在FPGA开发过程中,我们会用到各种协议的接口。有的模块之间接口协议不同,则需要自行实现转接模块。近期我们某个工程需要将avalon memory mapped格式的接口转为apb格式的接口,以控制IP核的配置寄存器。使用system verilog语言可以编写简易模块实现。

首先简单介绍一下这两种接口协议。Avalon Memory-Mapped(Avalon-MM)协议是Altera公司在其 FPGA 产品中广泛采用的一种总线接口协议。它采用存储器映射方式,将所有外围设备映射到统一地址空间,主设备可通过地址对从设备进行读写操作。除clock和reset之外,基本的信号定义如下。

名称 方向 解释
addr i 地址
read i 读信号
write i 写信号
readdata o 读出数据
readvalid o 读出数据有效
writedata i 写入数据
waitrequest o 当为1时,表明从设备繁忙,需要保持输入接口状态不变,直到waitrequest拉低

APB总线则是ARM公司推出的AMBA(Advanced Microcontroller Bus Architecture)总线架构中的一员,主打低功耗、低成本、简化接口,专为连接低速、低带宽的外围设备设计以 “简单稳定” 为核心优势。除clock和reset之外,基本信号如下。

名称 方向 解释
sel i 从设备选择信号,表示正在选择该从设备
enable i 传输使能信号,表明在传输阶段
addr i 地址
write i 写标记,如果等于0则是读操作,否则是写操作。
writedata i 写入数据
readdata o 读出数据
ready o 当为1时,表示从设备准备就绪

APB总线从机接口具有3种状态,IDLE,SETUP和ACCESS,分别表示等待、传输建立和传输执行。采用enum结构进行实现,并将其作为状态机。

typedef enum logic [1:0] {
         IDLE   = 2'b00,
         SETUP  = 2'b01,
         ACCESS = 2'b10 
} state_t;

状态变迁则根据apb总线的定义执行,当收到avmm总线的read或write信号后,接下来两周期进入SETUP和ACCESS。随后根据后面从机是否ready,确定这一次传输结束或者继续等在这里。

always_comb begin
        next_state = current_state;        
        case (current_state)
            IDLE: begin
                if (avmm_read || avmm_write) begin
                    next_state = SETUP;
                end
            end           
            SETUP: begin
                next_state = ACCESS;
            end            
            ACCESS: begin
                if (apb_ready) begin
                    next_state = IDLE;
                end
            end            
            default: begin
                next_state = IDLE;
            end
        endcase
    end

如果是写数据过程,则需要在IDLE时刻,当avmm总线给出写数据请求时,锁存住需要写的地址和数据。如果是读数据过程,则需要在apb总线传输ACCESS时刻,将数据锁存住,等待返回给avmm。

always_ff @(posedge clk or posedge rst) begin
        if (rst) begin
            apb_addr_reg    <= '0;
            apb_write_reg   <= 1'b0;
            apb_wdata_reg   <= '0;
        end else if (current_state == IDLE && (avmm_read || avmm_write)) begin
            // when access is detected in IDLE state, latch address and data
            apb_addr_reg    <= {{(APB_ADDR_WIDTH-AVMM_ADDR_WIDTH){1'b0}}, avmm_addr};
            apb_write_reg   <= avmm_write;
            apb_wdata_reg   <= avmm_wdata;
        end
    end
    
    always_ff @(posedge clk or posedge rst) begin
        if (rst) begin
            avmm_rdata_reg       <= '0;
            avmm_rdata_valid_reg <= 1'b0;
        end else if (current_state == ACCESS && apb_ready && !apb_write_reg) begin
            // when APB read operation is completed, latch read data
            avmm_rdata_reg       <= apb_rdata;
            avmm_rdata_valid_reg <= 1'b1;
        end else begin
            avmm_rdata_valid_reg <= 1'b0;
        end
    end

最后,需要返回给avmm总线的waitrequest信号。我们规定,只有模块处于IDLE状态,才允许avmm总线信号变化,否则需要保持不变。因此直接使用以下语句即可。

assign avmm_waitrequest = (current_state != IDLE);

最终实现的读写波形分别如下。
read.png

write.png

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0