AHB2APB 同步桥的设计代码(Verilog)


👉关于AHB2APB的设计请看:AHB2APB设计
👉关于AHB2APB的验证请看:AHB2APB验证


该简单的同步桥的功能包括:

  • 不支持PPROT、PSTRB;
  • 不支持PSLVERR反馈ERROR信号,pslverr一直置为低;
  • 不支持输出数据寄存;
  • 支持输入数据寄存;

注:下面先进行代码的拆解,完整代码附于文末。

部分代码解释


1. 数据寄存控制信号

数据是否需要寄存一拍的控制信号的产生,如下代码:

  //------数据寄存-------
  wire                   rdata_reg_param; // REGISTER_RDATA,寄存读数据
  wire                   wdata_reg_param; // REGISTER_WDATA ,寄存写数据
  assign rdata_reg_param = (REGISTER_RDATA)? 1'b1 : 1'b0;
  assign wdata_reg_param = (REGISTER_WDATA)? 1'b1 : 1'b0

2. 数据采样寄存的控制信号

输入数据什么时候采样到寄存器中停留一拍,这需要添加一个控制信号,产生如下:

  // 采样输入数据到寄存器的控制信号
  reg                    sample_wdata_flag; 
  wire sample_wdata_start     = apb_select & HWRITE ;
  wire sample_wdata_continue  = sample_wdata_flag & PCLKEN;

  always @(posedge HCLK or negedge HRESETn) begin
    if (~HRESETn)
      sample_wdata_flag <= 1'b0;
    else if (sample_wdata_start | sample_wdata_continue)
      sample_wdata_flag <= sample_wdata_start;
  end

解释上面代码:

  • 只有在 apb_select & HWRITE成立时,才会使sample_wdata_flag为高,进行HWDATA的采样寄存。
  • 如果PCLKEN有效沿到来,并且此时sample_wdata_flag为高,那么 sample_wdata_flag仍然继续保持为高;

3. APB的选通信号

产生APB的选通信号apb_select,如下代码:

  • 当AHB master开启传输时,APB才选通;
  • HTRANS[1]代表SEQ或NONSEQ状态,即有传输进行的状态;
//------产生APB的sel信号-------
  wire                   apb_sel;//状态机内部的信号
  assign apb_sel = HSEL & HREADY & HTRANS[1];

4. ahb slave的地址处理

为了保证AHB 在地址映射时不出错,要对 ahb slave的地址(PADDR)做处理,确保1KB对齐。

//------产生APB的PADDR信号-------
  reg      [ADDRWIDTH-3:0] addr_reg;//HADDR
  assign PADDR  = {addr_reg, 2'b00};
 //-----锁存控制信号------
 always@(posedge HCLK or negedge HRESETn) begin
   if(! HRESETn) begin
     addr_reg  <= 0;
     write_reg <=0;
   end
   else if(apb_select) begin
     addr_reg  <= HADDR[ADDRWIDTH-1:2];//为了保证地址1KB对齐
     write_reg <= HWRITE;
   end
 end
 

5. 状态机的描述

状态机的描述,采用三段式描述如下:

/*********************************
*--------==== 状态机 ====------
*********************************/
  reg state,next_state;
  
  //状态编码
  parameter  IDLE   = 2'b00;//空闲状态
  parameter  WAIT   = 2'b01;//等待输入数据寄存一拍
  parameter  SETUP  = 2'b10;//传输建立状态,开始传输
  parameter  ENABLE = 2'b11;//传输完成状态,判断是否有下一次传输继续
 
 always @(state or PREADY or PSLVERR or apb_select or rdata_reg_param or
           PCLKEN or wdata_reg_param or HWRITE) 
    begin
    case (state)
      IDLE : begin
          if (PCLKEN & apb_select & HWRITE)
             next_state = WAIT; // 如果是写操作,就寄存一拍
          else if (apb_select)
             next_state = SETUP; // 如果是读操作,就不寄存
          else
             next_state = IDLE; // 其他情况则保持IDLE
      end
     
      WAIT : begin
        if (PCLKEN)
           next_state = SETUP; // 寄存一拍后到达SETUP状态,准备开始传输
        else
           next_state = WAIT; // PCLKEN 没到之前,保持WAIT
      end
     
     SETUP : begin
        if (PCLKEN)
           next_state = ENABLE;   // 
        else
           next_state = SETUP;   // 
     end
     
     ENABLE : begin
        if (PREADY & PCLKEN & apb_sel) 
           next_state = SETUP;  //如果紧接着还有传输  
        else if(!apb_sel)
           next_state = IDLE;
        else //如果此时PREDY为低
           next_state = ENABLE; //PCLKEN没到之前,保持ENABLE状态
     end
   
    endcase
  end

  always @(posedge HCLK or negedge HRESETn) begin
   if (~HRESETn)
      state <= 2'b00;
   else
      state <= next_state;
  end
  
  always @(posedge HCLK or negedge HRESETn) begin
   if (~HRESETn)
      wdata_reg <= {32{1'b0}};
   else if (PCLKEN & sample_wdata_flag)
      wdata_reg <= HWDATA;
   else 
      wdata_reg <= wdata_reg;
  end

6. HREADYOUT信号的产生

HREADYOUT信号的产生,如下:

//-------HREADYOUT信号的产生-------
  always @(state or PREADY or PCLKEN) begin
    case (state)
      IDLE   : HREADYOUT = 1'b1; 
      WAIT   : HREADYOUT = 1'b0; 
      SETUP  : HREADYOUT = 1'b0; 
      ENABLE : HREADYOUT = PREADY & PCLKEN;   
    endcase
  end

7. 返回给AHB的信号

返回给AHB的信号,如下:

  //------返回给AHB的信号------- 
  assign HRDATA = PRDATA;
  assign HRESP  = 1'b0;


8. APB信号的生成

传递给APB的信号,如下:

  //------产生APB的信号-------
  wire                   apb_sel;//状态机内部的信号
  reg    [ADDRWIDTH-3:0] addr_reg;//HADDR
  reg                    write_reg;//HWRITE
  
  assign apb_sel = HSEL & HREADY & HTRANS[1];
  assign PADDR   = {addr_reg, 2'b00}; 
  assign PWRITE  = write_reg; 
  assign PWDATA  = wdata_reg;
  assign PSEL    = (state == SETUP) | (state == ENABLE);
  assign PENABLE = (state == ENABLE);
  assign PSLVERR = 1'b0;
  assign APBACTIVE = (HSEL & HTRANS[1]) | (state != 2'b00);

完整代码

  • 18
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
我可以回答这个问题。以下是一个简单的AHBAPBVerilog代码: module AHB_to_APB_bridge ( input HCLK, input HRESETn, input [31:0] HADDR, input [1:0] HSIZE, input HTRANS, input HMASTLOCK, input [31:0] HWDATA, input [3:0] HSTRB, input HWRITE, input HPROT, output [31:0] PADDR, output [1:0] PSEL, output PENABLE, output PWRITE, output [31:0] PWDATA, output [3:0] PSTRB, output PREADY ); // APB slave interface signals reg [31:0] apb_addr; reg [31:0] apb_data_in; reg [31:0] apb_data_out; reg apb_write; reg [3:0] apb_strb; reg apb_enable; reg apb_ready; // AHB to APB bridge logic assign PADDR = apb_addr; assign PSEL = 2'b01; // APB slave select assign PENABLE = apb_enable; assign PWRITE = apb_write; assign PWDATA = apb_data_in; assign PSTRB = apb_strb; assign PREADY = apb_ready; always @(posedge HCLK or negedge HRESETn) begin if (~HRESETn) begin apb_addr <= 32'h0; apb_data_in <= 32'h0; apb_data_out <= 32'h0; apb_write <= 1'b0; apb_strb <= 4'h0; apb_enable <= 1'b0; apb_ready <= 1'b0; end else begin case ({HTRANS, HSIZE}) 2'b00_00: begin // IDLE apb_enable <= 1'b0; end 2'b01_10: begin // NONSEQ, 32-bit apb_addr <= HADDR; apb_data_in <= HWDATA; apb_strb <= HSTRB; apb_write <= HWRITE; apb_enable <= 1'b1; end default: begin // unsupported transfer type apb_enable <= 1'b0; end endcase end end always @(posedge HCLK or negedge HRESETn) begin if (~HRESETn) begin apb_ready <= 1'b0; end else begin case ({HTRANS, HSIZE}) 2'b01_10: begin // NONSEQ, 32-bit if (apb_enable && !apb_ready) begin apb_ready <= 1'b1; end else if (apb_ready && !apb_enable) begin apb_ready <= 1'b0; end end default: begin // unsupported transfer type apb_ready <= 1'b0; end endcase end end endmodule 希望这可以帮助你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小verifier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值