walkie

Xilinx FPGA 教程lab3的一些补充,并回答沈阳的刘先生的提问

0
阅读(1821)

沈阳东北大学的刘先生关于lab3,给系统添加用户自定义的IP核(PPC)的实验指导提出了一些疑问,觉得在my_led.vhd核 user_logic.vhd 中添加的HDL语言与最后的实验结果好像没有什么关系。

昨天我做了很多测试,试图去解释底层的原理。其实这些代码起到了一个在这个IP核与 OPB总线的之间桥梁的作用。根据他的疑问,我也做了一些其他的测试,发现了lab3文档中有一些冗余的设计,其中的那个软件可写的寄存器在这个设计中其 实没有用到,可以除去,因为设计中把总线上的数据直接写到了LED中,这种设计方法学不是很好的。我们在进行软件和硬件通讯的时候,一般使用寄存器,所以 在这个设计中,我们也可以去利用这个寄存器,而不是去忽视它。

以下是问题和回答。

 

Questions from Mr Liu
From: Mr liu
To: "Xilinx University Program"
Date: Mon, 17 Sep 2007 18:14:33 -0700
Subject: Creating and Adding Custom IP to an Embedded System Lab: PowerPC Processor

About the lab exercise" Creating and Adding Custom IP to an Embedded System Lab: PowerPC Processor" given by your company, I am sorry that I cannot understand it very well. How can I figure out the connection between HDL code "my_led.vhd and user_logic.vhd " and the final result the lab showed. In other words, what is the role of the HDL code in the lab? How do the codes come into effect?

Answers to Mr Liu from XUP

The final lab shows that if you switch the dip on, the led will be on counterparts. But how does the operation of dip_switch change the led? Ok, it is done by your changes in TestApp_Memory.c. By adding the following function, the dip_switch settings are written to the LEDs:

MY_LED_mWriteReg(XPAR_MY_LED_0_BASEADDR, 0 ,dip_check);

 

The value of dip_check is given by the check of the dip_switch. And it is done by the following function:

dip_check = XGpio_DiscreteRead(&dip, 1);

And the value of dip depends on the dip_switch.

 

Now I’ll try to explan the role of the HDL code in our labs and how do the codes come
into effect. The HDL code here bridges the Data from OPB Bus to the device of led.
The c code of MY_LED_mWriteReg is compiled to PPC instructions and executed by the PPC processor. The execution of the c code here will write the value of dip_check to the address which the XPAR_MY_LED_0_BASEADDR defined according to the function MY_LED_mWriteReg. (You can find the actual address of the led device from the file: ppc405_0/include/xparameters.h)

But how to write?
The picture following shows it:

Data_flow


Now we focus on the files my_led.vhd and user_logic.vhd
At first the data will be on the OPB Bus, and the PPC will try to find the device due to the address. Here it finds the led instance and will give the data to the iBus2IP_Data (a port of opb_ipif instance ) and then deliver from iBus2IP_Data to uBus2IP_Data, then to Bus2IP_Data which is the input port of the user_logic instance. These are done in the file of my_led.vhd.
And now we focus on the HDL we add to the user_logic.vhd
Code

We will find that:
LED<=LED_i<= Bus2IP_Data (28 to 31)
That’s it. Now the data delivers from OPB BUS to LED.


PS: Something about the software accessible registers in lab3 and lab4.

 

Actually in both of the labs, we never use the software accessible registers. So in lab3 when you meet the IPIF Services panel, you can uncheck User Logic S/W Register Support.

s/w register

And it will not come out the User S/W Register Dialog Box. Do the others just like the lab3 instruction says. The final result of lab3&lab4 is the same.
Actually in lab3 the data on OPB BUS is written directly to the LED. The code following shows it.

if Bus2IP_WrCE(0) = '1' then
          LED_i <= slv_reg0(28 to 31);

But we often hope that the software changes the registers and the hardware is to detect the changes of these registers, then do some operations. Of course in our lab3, we can also do the communication of the software and hardware by using the registers. And this method will help you when you need two or more software accessible registers.
What you need to do is just to change some HDL codes here. In our lab3, the instruction tells us to create one software accessible register. If you do the lab3 carefully, you will find that this register named slv_reg0 in the file of user_logic.vhd.
Form the code shows below ( it is a part of user_logic.vhd):
---------------------------------------
  -- implement slave model register(s)
  SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is
  begin

    if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
      if Bus2IP_Reset = '1' then
        slv_reg0 <= (others => '0');
      else
        case slv_reg_write_select is
          when "1" =>
            for byte_index in 0 to (C_DWIDTH/8)-1 loop
              if ( Bus2IP_BE(byte_index) = '1' ) then
                slv_reg0(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
              end if;
            end loop;
          when others => null;
        end case;
      end if;
    end if;

  end process SLAVE_REG_WRITE_PROC;


We can get that the data from the OPB BUS also writes to the register slv_reg0. And now if we changes
our HDL code as following:

  --USER logic implementation added here
  LED_PROC: process(Bus2IP_Clk) is
  begin
    if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
      if Bus2IP_Reset = '1' then
         LED_i <= "0000";
      else
        if Bus2IP_WrCE(0) = '1' then
          LED_i <= slv_reg0(28 to 31);

        else
          LED_i <= LED_i;
        end if;
      end if;
    end if;
  end process LED_PROC;
  LED <= LED_i;

Note that the red part of the code. The data of LED now comes from the register0. From this way, we can manage design with two software accessible registers or more. Only we need to do is to write the data to different registers and let the hardware detect which it focuses.