blue1025的个人空间 https://blog.eetop.cn/mj8051 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

LEON AMBA 2.0 学习

已有 2219 次阅读| 2008-10-15 21:29 |个人分类:soc leon2.1.30

转载,请注明出处

1.    LEON AMBA ARCHITECTURE

首先LEON内部总线由2部分构成,第一部分由高速的AHB总线,另外由低速的APB总线连接。AHB总线连接着CACHEMEMORYDSUDCOMAPBBRIDGE等几部分。

空间分配如下:

Figure1-2 Default AHB address allocation

可以看出,外部ram空间为0x0000_0000 – 0x7fff_ffff,而0x80000_0000 – 0x8fff_ffff空间为APB的空间,也就是所有寄存器空间。0x9000_0000 – 0x9fff_ffff空间为LEON特有的调试单元DSU的空间。0Xb000_0000 – 0Xb001_ffff空间为ETH的寄存器空间。剩余的空间还可以分配给其他用户想添加的高速设备空间。

APB总线挂接了几乎所有控制单元的寄存器。它的地址分配如图13。可以看出,APB总线专门控制各个部分寄存器的读写工作。同时还剩余很多的空间,还可以继续的添加。

1.    Ahbarb

AHBARB.vhd主要负责AHB总线的切换。

21 AHB MASTER

AHB MASTER的优先级是固定的,优先级由低到高。在LEON2-1.30中,proc模块为ahbmst(0),proc模块由IU0ICACHE/DCACHE共同构成。dcom模块为ahbmst(1),该模块主要负责debug

下面为AMBA AHM MASTERrecord定义。

   -----------------------------------------------------------------------------

   -- Definitions for AMBA(TM) AHB Masters

   -----------------------------------------------------------------------------

   -- AHB master inputs (HCLK and HRESETn routed separately)

   type AHB_Mst_In_Type is

      record

         HGRANT:     Std_ULogic;                         -- bus grant

         HREADY:     Std_ULogic;                         -- transfer done

         HRESP:      Std_Logic_Vector(1       downto 0); -- response type

         HRDATA:     Std_Logic_Vector(HDMAX-1 downto 0); -- read data bus

      end record;

 

   -- AHB master outputs

   type AHB_Mst_Out_Type is

      record

         HBUSREQ:    Std_ULogic;                         -- bus request

         HLOCK:      Std_ULogic;                         -- lock request

         HTRANS:     Std_Logic_Vector(1       downto 0); -- transfer type

         HADDR:      Std_Logic_Vector(HAMAX-1 downto 0); -- address bus (byte)

         HWRITE:     Std_ULogic;                         -- read/write

         HSIZE:      Std_Logic_Vector(2       downto 0); -- transfer size

         HBURST:     Std_Logic_Vector(2       downto 0); -- burst type

         HPROT:      Std_Logic_Vector(3       downto 0); -- protection control

         HWDATA:     Std_Logic_Vector(HDMAX-1 downto 0); -- write data bus

      end record;

   首先ahbarb.vhd的第一个工作是完成2MASTER的总线切换工作,即是那个MASTER现在控制总线。它的关键代码如下。这个代码挺有意思,我花了一定的时间才搞懂为什么这样写。其实我虽然高明白它怎么运行的,但是为什么要这样写,还是不太清楚,可能要等到多MASTER运行的时候就明白了。

   

nvalid(1 to 4) := (others => false); nvalid(5) := true;      

    nmst(1 to 4) := (others => 0); nmst(5) := defmast; nhmaster := r.hmaster;

 

    if (r.hmasterlock = '0') and (                            //bus unlock

       (msto(r.hmaster).htrans = HTRANS_IDLE) or         

       ( (msto(r.hmaster).htrans = HTRANS_NONSEQ) and

         (msto(r.hmaster).hburst = HBURST_SINGLE) ) ) then

      for i in 0 to (masters -1) loop                         //note: i start with 0 . master = 2

       if ((rsplit(i) = '0') or not AHB_SPLIT) then

          if (msto(i).hbusreq = '1') and (msto(i).htrans(1) = '1') then

           nmst(2) := i; nvalid(2) := true;

         end if;

          if (msto(i).hbusreq = '1') then

           nmst(3) := i; nvalid(3) := true;

         end if;

         if not ((nmst(4) = defmast) and nvalid(4)) then

           nmst(4) := i; nvalid(4) := true;

         end if;

       end if;

      end loop;

      for i in 1 to 5 loop

        if nvalid(i) then nhmaster := nmst(i); exit; end if;   //注意这里nmst(i)不一定就等于i.

      end loop;

    end if;

2.2 AHB SLAVE

       当然,当MASTER固定后,则开始这个MASTER的地址开始译码,找寻合适的SLAVE运行,并将SLAVE的值返回这个MASTER。这里SLAVE的地址空间由FIGURE1-2可以得到。其中SLAVErecord的格式如下

-----------------------------------------------------------------------------

   -- Definitions for AMBA(TM) AHB Slaves

   -----------------------------------------------------------------------------

   -- AHB slave inputs (HCLK and HRESETn routed separately)

   type AHB_Slv_In_Type is

      record

         HSEL:       Std_ULogic;                         -- slave select

         HADDR:      Std_Logic_Vector(HAMAX-1 downto 0); -- address bus (byte)

         HWRITE:     Std_ULogic;                         -- read/write

         HTRANS:     Std_Logic_Vector(1       downto 0); -- transfer type

         HSIZE:      Std_Logic_Vector(2       downto 0); -- transfer size

         HBURST:     Std_Logic_Vector(2       downto 0); -- burst type

         HWDATA:     Std_Logic_Vector(HDMAX-1 downto 0); -- write data bus

         HPROT:      Std_Logic_Vector(3       downto 0); -- protection control

         HREADY:     Std_ULogic;                         -- transfer done

         HMASTER:    Std_Logic_Vector(3       downto 0); -- current master

         HMASTLOCK:  Std_ULogic;                         -- locked access

      end record;

 

   -- AHB slave outputs

   type AHB_Slv_Out_Type is

      record

         HREADY:     Std_ULogic;                         -- transfer done

         HRESP:      Std_Logic_Vector(1       downto 0); -- response type

         HRDATA:     Std_Logic_Vector(HDMAX-1 downto 0); -- read data bus

         HSPLIT:     Std_Logic_Vector(15      downto 0); -- split completion

      end record;

关于SLAVE切换的代码如下。这段代码就比较简单了,关键是AHBSLVADDR的定义。这个定义可以在下面的文件中定义。

./config.vhd:

   constant AHBSLVADDR  : ahbslv_addr_type := ahbrange_config;

./target.vhd:

   type ahbslv_addr_type is array (0 to 15) of integer range 0 to AHB_SLV_MAX;

./device.vhd:

   constant ahbrange_config  : ahbslv_addr_type :=

        (0,0,0,0,0,0,0,0,1,2,7,7,7,7,7,7);

 

-- select slave

    ahbaddr := haddr(31 downto (31 - ahbmin));

-- pragma translate_off

    if not is_x(haddr(31 downto (31 - AHB_SLV_ADDR_MSB +1))) then

-- pragma translate_on

      nslave :=  AHBSLVADDR(conv_integer(unsigned(haddr(31 downto (31 - AHB_SLV_ADDR_MSB +1)))));

-- pragma translate_off

    end if;

-- pragma translate_on

 

--    if htrans = HTRANS_IDLE then nslave := AHB_SLV_MAX; end if;

 

    hsel := (others => '0'); hsel(nslave) := '1';

    好了ahbarb.vhd的工作分析完成。关于代码的风格,网上讨论很多,我就不讨论了。就目前看,它的风格,我感觉吗,不是很适合我。

2.    Apbmst

这个模块是apb bridge,完成apb slave的选择,这个代码相对于ahbarb要好理解一些。首先检测Apbmst被选中,然后msbaddr一直在译码选中那个SLAVE模块。Apb slave模块的输入输出总线record定义。

   -----------------------------------------------------------------------------

   -- Definitions for AMBA(TM) APB Slaves

   -----------------------------------------------------------------------------

   -- APB slave inputs (PCLK and PRESETn routed separately)

   type APB_Slv_In_Type is

      record

         PSEL:       Std_ULogic;                         -- slave select

         PENABLE:    Std_ULogic;                         -- strobe

         PADDR:      Std_Logic_Vector(PAMAX-1 downto 0); -- address bus (byte)

         PWRITE:     Std_ULogic;                         -- write

         PWDATA:     Std_Logic_Vector(PDMAX-1 downto 0); -- write data bus

      end record;

 

   -- APB slave outputs

   type APB_Slv_Out_Type is

      record

         PRDATA:     Std_Logic_Vector(PDMAX-1 downto 0); -- read data bus

      end record;

aph slave译码过程如下。可以看出,我们可以继续增加寄存器空间。

case msbaddr is

   when "00" =>

     case apbaddr is

     when "00000000" | "00000001" | "00000010" =>

       esel := '1'; bindex := 0; -- memory controller, 0x00 - 0x08

     when "00000011" | "00000100" =>

       esel := '1'; bindex := 1; -- AHB status reg.,   0x0C - 0x10

     when "00000101" | "00000110" =>

       esel := '1'; bindex := 2; -- cache controller,  0x14 - 0x18

     when "00000111" | "00001000" =>

                           -- write protection,  0x1C - 0x20

       if WPROTEN then esel := '1'; bindex := 3; end if;

     when "00001001" =>

                          -- config register,   0x24 - 0x24

       if CFGREG then esel := '1'; bindex := 4; end if;

     when "00010000" | "00010001" | "00010010" | "00010011" |

          "00010100" | "00010101" | "00010110" | "00010111" |

          "00011000" | "00011001" | "00011010" | "00011011" =>

       esel := '1'; bindex := 5; -- timers,            0x40 - 0x6C

     when "00011100" | "00011101" | "00011110" | "00011111" =>

       esel := '1'; bindex := 6; -- uart1,             0x70 - 0x7C

     when "00100000" | "00100001" | "00100010" | "00100011" =>

       esel := '1'; bindex := 7; -- uart2,             0x80 - 0x8C

     when "00100100" | "00100101" | "00100110" | "00100111" =>

       esel := '1'; bindex := 8; -- interrupt ctrl     0x90 - 0x9C

     when "00101000" | "00101001" | "00101010" | "00101011" =>

       esel := '1'; bindex := 9; -- I/O port           0xA0 - 0xAC

     when "00101100" | "00101101" | "00101110" | "00101111" =>

                          -- 2nd interrupt ctrl 0xB0 - 0xBC

       if IRQ2EN then esel := '1'; bindex := 10; end if;

     when "00110000" | "00110001" | "00110010" | "00110011" =>

                          -- DSU uart           0xC0 - 0xCC

       if DEBUG_UNIT then esel := '1'; bindex := 11; end if;

     when "00110100"  =>

       if PCIEN  then              -- PCI target mapping 0x0D0

         esel := '1'; bindex := 12;

       end if;

     when thers =>

       if PCIEN and ( apbaddr(9 downto 8) = "01") then

         esel := '1'; bindex := 12; -- 0x100 - 0x200

       end if;

       if PCIARBEN and ( r.haddr(9 downto 8) = "10") then

         esel := '1'; bindex := 13; -- 0x200 - 0x300

       end if;

     end case;

   when thers =>

     if PCIEN and ( r.haddr(apbmax downto apbmax-1) /= "00") then

       esel := '1'; bindex := 12; -- 0x4000 - 0xFFFC

     end if;

   end case;

3.    An analysis of the AMBA BUS

4.1        Ahb master waves.

流程如下:hbusreq,htrans,hburst,hprot --- hready ---___----,完成一个存储周期。由于AMBA是流水线方式进行总线传输,所以在hbusreq使能时,其他的信号会传输到下一级进行运算。


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 13

    粉丝
  • 16

    好友
  • 15

    获赞
  • 23

    评论
  • 2824

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-27 12:47 , Processed in 0.015873 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部