zoukankan      html  css  js  c++  java
  • AMBA APB总线

      前面分析了AHB总线协议。接下来分析APB总线协议。

      (一) APB总线接口:

      PCLK APB总线时钟。

      PRESETn APB总线复位。低有效。

      PADDR 地址总线。

      PSELx 从设备选择。

      PENABLE APB传输选通。

      PWRITE 高为写传输,低为读。

      PRDATA 读数据总线。

      PWDATA 写数据总线。

      接口信号定义如下:

     1 interface   apb_slv_intf #(
     2     parameter   AW  = 32,
     3                 DW  = 32
     4 ) (
     5     input   logic       PCLK,
     6     input   logic       PRESETn
     7 );
     8     logic               PSEL;
     9     logic               PENABLE;
    10     logic   [AW-1:0]    PADDR;
    11     logic               PWRITE;
    12     logic   [DW-1:0]    PWDATA;
    13     
    14     logic   [DW-1:0]    PRDATA;
    15     
    16     
    17     modport m (
    18         input   PRDATA,
    19         output  PSEL, PENABLE, PADDR, PWRITE, PWDATA
    20     );
    21     
    22     modport s (
    23         input   PSEL, PENABLE, PADDR, PWRITE, PWDATA,
    24         output  PRDATA
    25     );
    26     
    27 endinterface: apb_slv_intf

      (二) APB总线时序图:

    写传输

    读传输

      注意在PENABLE信号有效后从设备需要给出有效数据/读取有效数据。

      (三) AHB总线到APB总线转换桥

      1 module ahb2apb_bridge #(
      2     parameter   AHB_AW  = 32,
      3                 AHB_DW  = 32,
      4                 APB_AW  = 32,
      5                 APB_DW  = 32,
      6                 NSLV    = 16
      7 ) (
      8     input   logic   HCLK,
      9     input   logic   HRESETn,
     10     input   logic   PCLK,
     11     input   logic   PRESETn,
     12     ahb_slv_intf.s  ahb,
     13     apb_slv_intf.m  apbv[NSLV]
     14 );
     15     
     16     logic   ahb_work;
     17     logic   apb_work;
     18     
     19     genvar  i;
     20     
     21     typedef enum logic [1:0] {
     22         AHB_IDLE    = 2'b00,
     23         AHB_WRITE   = 2'b01,
     24         AHB_READ    = 2'b10,
     25         AHB_WAIT    = 2'b11
     26     } ahb_state_e;
     27     
     28     // Signal of AHB Domain
     29     struct {
     30         logic                   work;
     31         logic   [AHB_AW-1:0]    addr;
     32         logic   [AHB_DW-1:0]    data;
     33         logic                   write;
     34         ahb_state_e             cstate, nstate;
     35     } ahbd;
     36     
     37     typedef enum logic [1:0] {
     38         APB_IDLE    = 2'b00,
     39         APB_WRITE   = 2'b01,
     40         APB_READ    = 2'b10
     41     } apb_state_e;
     42     
     43     // Signal of APB Domain
     44     struct {
     45         logic                   work;
     46         logic   [APB_DW-1:0]    data[NSLV];
     47         logic                   PSEL[NSLV];
     48         logic                   PENABLE[NSLV];
     49         apb_state_e             cstate, nstate;
     50     } apbd;
     51     
     52     
     53     // AHB Control Logic
     54     always_comb begin
     55         case (ahbd.cstate)
     56             AHB_IDLE: begin
     57                 if (ahb.HSEL && ahb.HTRANS == HTRANS_NONSEQ) begin
     58                     if (ahb.HWRITE)
     59                         ahbd.nstate = AHB_WRITE;
     60                     else
     61                         ahbd.nstate = AHB_READ;
     62                 end
     63                 else
     64                     ahbd.nstate = AHB_IDLE;
     65             end
     66             AHB_WRITE: begin
     67                 if (apbd.work)
     68                     ahbd.nstate = AHB_WAIT;
     69                 else
     70                     ahbd.nstate = AHB_WRITE;
     71             end 
     72             AHB_READ: begin
     73                 if (apbd.work)
     74                     ahbd.nstate = AHB_WAIT;
     75                 else
     76                     ahbd.nstate = AHB_READ;
     77             end
     78             AHB_WAIT: begin
     79                 if (!apbd.work)
     80                     ahbd.nstate = AHB_IDLE;
     81                 else
     82                     ahbd.nstate = AHB_WAIT;
     83             end
     84             default: ahbd.nstate = AHB_IDLE;
     85         endcase
     86     end
     87     
     88     always_ff @(posedge HCLK or negedge HRESETn) begin
     89         if (!HRESETn)
     90             ahbd.cstate <= AHB_IDLE;
     91         else
     92             ahbd.cstate <= ahbd.nstate;
     93     end
     94     
     95     always_ff @(posedge HCLK or negedge HRESETn) begin
     96         if (!HRESETn) begin
     97             ahbd.work   <= 1'b0;
     98             ahbd.addr   <= '0;
     99             ahbd.data   <= '0;
    100             ahbd.write  <= 1'b0;
    101             ahb.HREADY  <= 1'b1;
    102             ahb.HRDATA[APB_DW-1:0]  <= '0;
    103         end
    104         else begin
    105             case (ahbd.cstate)
    106                 AHB_IDLE: begin
    107                     if (ahb.HSEL && ahb.HTRANS == HTRANS_NONSEQ) begin
    108                         ahbd.addr   <= ahb.HADDR;
    109                         ahbd.write  <= ahb.HWRITE;
    110                         ahb.HREADY  <= 1'b0;
    111                     end
    112                     else begin
    113                         ahbd.addr   <= '0;
    114                         ahbd.write  <= 1'b0;
    115                         ahb.HREADY  <= 1'b1;
    116                     end
    117                     ahbd.work   <= 1'b0;
    118                     ahbd.data   <= '0;
    119                     ahb.HRDATA[APB_DW-1:0]  <= apbd.data[ahbd.addr[AHB_AW-5:AHB_AW-8]];
    120                 end
    121                 AHB_WRITE: begin
    122                     ahb.HREADY  <= 1'b0;
    123                     ahbd.work   <= 1'b1;
    124                     ahbd.data   <= ahb.HWDATA;
    125                     ahb.HRDATA[APB_DW-1:0]  <= '0;
    126                 end
    127                 AHB_READ: begin
    128                     ahbd.work   <= 1'b1;
    129                     ahbd.data   <= '0;
    130                     ahb.HREADY  <= 1'b0;
    131                     ahb.HRDATA[APB_DW-1:0]  <= '0;
    132                 end
    133                 AHB_WAIT: begin
    134                     ahbd.work   <= 1'b0;
    135                     ahb.HREADY  <= 1'b0;
    136                     ahb.HRDATA[APB_DW-1:0]  <= '0;
    137                 end
    138             endcase
    139         end
    140     end
    141     
    142     assign  ahb.HRESP = HRESP_OKAY;
    143     // assign  ahb.HRDATA[AHB_DW-1:APB_DW] = '0;
    144     
    145     
    146     // APB Control Logic
    147     always_comb begin
    148         case (apbd.cstate)
    149             APB_IDLE: begin
    150                 if (ahbd.work) begin
    151                     if (ahbd.write)
    152                         apbd.nstate = APB_WRITE;
    153                     else
    154                         apbd.nstate = APB_READ;
    155                 end
    156                 else
    157                     apbd.nstate = APB_IDLE;
    158             end
    159             APB_WRITE:  apbd.nstate = APB_IDLE;
    160             APB_READ:   apbd.nstate = APB_IDLE;
    161             default:    apbd.nstate = APB_IDLE;
    162         endcase
    163     end
    164     
    165     always_ff @(posedge PCLK or negedge PRESETn) begin
    166         if (!PRESETn)
    167             apbd.cstate <= APB_IDLE;
    168         else
    169             apbd.cstate <= apbd.nstate;
    170     end
    171     
    172     always_ff @(posedge PCLK or negedge PRESETn) begin
    173         if (!PRESETn) begin
    174             apbd.work   <= 1'b0;
    175             for (int j = 0; j < NSLV; j++) begin
    176                 apbd.PSEL[j]    <= 1'b0;
    177                 apbd.PENABLE[j] <= 1'b0;
    178             end
    179         end
    180         else begin
    181             case (apbd.cstate)
    182                 APB_IDLE: begin
    183                     if (ahbd.work) begin
    184                         apbd.work <= 1'b1;
    185                         for (int j = 0; j < NSLV; j++)
    186                             apbd.PSEL[j] <= (ahbd.addr[AHB_AW-5:AHB_AW-8] == j) ? 1'b1 : 1'b0;
    187                     end
    188                     else begin
    189                         apbd.work <= 1'b0;
    190                         for (int j = 0; j < NSLV; j++)
    191                             apbd.PSEL[j] <= 1'b0;
    192                     end
    193                     for (int j = 0; j < NSLV; j++)
    194                         apbd.PENABLE[j] <= 1'b0;
    195                 end
    196                 APB_WRITE: begin
    197                     apbd.work <= 1'b1;
    198                     for (int j = 0; j < NSLV; j++)
    199                         apbd.PENABLE[j] <= (ahbd.addr[AHB_AW-5:AHB_AW-8] == j) ? 1'b1 : 1'b0;
    200                 end
    201                 APB_READ: begin
    202                     apbd.work <= 1'b1;
    203                     for (int j = 0; j < NSLV; j++)
    204                         apbd.PENABLE[j] <= (ahbd.addr[AHB_AW-5:AHB_AW-8] == j) ? 1'b1 : 1'b0;
    205                 end
    206             endcase
    207         end
    208     end
    209     
    210     generate
    211         for (i = 0; i < NSLV; i++) begin: apbv_loop
    212             assign apbv[i].PADDR    = {4'h0, ahbd.addr[APB_AW-4-1:0]};
    213             assign apbv[i].PWRITE   = ahbd.write;
    214             assign apbv[i].PWDATA   = ahbd.data[APB_DW-1:0];
    215             assign apbd.data[i]     = apbv[i].PRDATA;
    216             assign apbv[i].PSEL     = apbd.PSEL[i];
    217             assign apbv[i].PENABLE  = apbd.PENABLE[i];
    218         end
    219     endgenerate
    220 
    221 endmodule: ahb2apb_bridge
  • 相关阅读:
    js动态获取地址栏后的参数
    html页面保存数的两种方式
    微信开发之八 页面获取周围beacon设备
    【摄影】田子坊
    最好的时光在路上,最美的风景在远方
    【前端统计图】echarts实现简单柱状图
    js实现计时功能
    luogu 电车
    cogs luogu 砍树
    cogs 通往奥格瑞玛的道路 WD
  • 原文地址:https://www.cnblogs.com/lyuyangly/p/4853921.html
Copyright © 2011-2022 走看看