Difference between revisions of "Talk:POD Tutorial"

From ArmadeusWiki
Jump to: navigation, search
(New page: == Introduction == In this first tutorial, we will learn how to use POD with a simple example project for an APF9328 board. The project is described in figure 1. It is composed of 3 v...)
 
(Removing all content from page)
 
Line 1: Line 1:
== Introduction ==
 
  
In this first tutorial, we will learn how to use POD with a simple example project for an [[APF9328]] board.
 
The project is described in figure 1. It is composed of 3 virtual components:
 
*  '''blink''' : blink is the instance name of a led (virtual component) that can «blink» by simply writing a value in a register.
 
*  '''push''' : push is the instance name of a button (virtual component) that can generate an interrupt when pushed/released. The state of the button can be read in a register.
 
*  '''i2c''' : i2c is the instance name of the i2cocore virtual component (from OpenCores.org). This component is an i2c bus controller.
 
 
[[image:exemple-i2cledbutton.png|center|frame|400px|'''figure 1''' - ''Project example for tutorial'']]
 
 
== Installation ==
 
 
See [[POD installation guide]] to learn how to install it.
 
 
== POD ==
 
 
POD can be started by writing "pod" in the pod/bin/ directory. If you are under Windows ''python'' has to be written before:
 
<pre class="host">
 
$ python pod/bin/pod
 
POD>
 
</pre>
 
 
If you don't want to write the entire path each time, you can set your $PATH variable with the path of POD:
 
<source lang="bash">
 
export PATH=$PATH:"path_to_pod/pod/bin"
 
</source>
 
 
=== Playing with POD ===
 
 
POD is a console program composed of several environments described in figure 2.
 
 
[[image:podenvironment.png|center|frame|250px|'''figure 2''' - ''POD console architecture'']]
 
 
To enter in an environment, simply write its name from the parent environment.
 
 
<pre class="host">
 
POD> project
 
POD.project>
 
</pre>
 
 
For a complete list of the available commands type ''help''
 
<pre class="pod">
 
POD.project> help
 
 
Documented commands (type help <topic>):
 
========================================
 
EOF            create        help            listplatforms  setaddr 
 
addbusclock    delcomponent  history        load            setgeneric
 
addinstance    delconnection  info            ls              shell   
 
autoconnectbus  description    intercon        printxml        simulation
 
check          driver        listcomponents  quit            synthesis
 
closeproject    eof            listinstances  savehistory    top     
 
connectbus      exit          listinterfaces  saveproject 
 
connectpin      getmapping    listmasters    selectplatform
 
 
POD.project>
 
</pre>
 
 
A short description is although available for each command.
 
 
<pre class="pod">
 
POD.project> help listcomponents
 
listcomponents [componenttype]
 
        List components available in the library
 
       
 
POD.project>
 
</pre>
 
 
Command completion and argument completion can be done by using the <TAB> key :
 
 
<pre class="host">
 
POD.project> help list<TAB>
 
listcomponents  listinterfaces  listplatforms 
 
listinstances  listmasters 
 
POD.project> help list
 
</pre>
 
 
System commands can be used with «!» before:
 
<pre class="host">
 
POD.project> !echo "POD is really useful"
 
POD is really useful
 
POD.project>
 
</pre>
 
 
=== Project creation ===
 
 
[[image:exemple-empty.png|center|frame|400px|'''figure 3''' - ''Empty i2cledbutton-tutorial project'']]
 
 
To create a project, enter the ''create'' command in the ''project'' environment:
 
<pre style="host">
 
POD.project> create i2cledbutton-tutorial
 
Project i2cledbutton-tutorial created
 
POD.project:i2cledbutton-tutorial>
 
</pre>
 
 
The ''i2cledbutton-tutorial'' project is now created, you can save it
 
when you want, by typing ''saveproject''.
 
 
The target platform has to be selected by means of the ''selectplatform'' command :
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> selectplatform standard.apf9328
 
Component platform added as apf9328
 
Component imx9328_wb16_wrapper added as imx9328_wb16_wrapper00
 
Component rstgen_syscon added as rstgen_syscon00
 
Component irq_mngr added as irq_mngr00
 
setting base address 0x0 for  irq_mngr00.swb16
 
 
Platform apf9328 selected
 
POD.project:i2cledbutton-tutorial>
 
</pre>
 
 
By selecting this platform, several components will be automaticaly added by POD:
 
* '''imx9328_wb16_wrapper''': this component is used to convert the i.MX processor bus to the Wishbone (16bits data) bus.
 
* '''rstgen_syscon''' : this component manages the clock and the reset for the design.
 
* '''irq_mngr''' : this is a Wishbone16 slave which manages the interrupts generated by the other components and which propagates them to the processor.
 
 
[[image:exemple-platform.png|center|frame|400px|'''figure 4''' - ''Platform loaded with their default components'']]
 
 
=== Adding components ===
 
 
Components are organized by category in the library, to list the categories, use ''listcomponents'':
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> listcomponents
 
test  components  wrappers  syscons
 
POD.project:i2cledbutton-tutorial>
 
</pre>
 
 
And to list the components under a category use ''listcomponents'' again with the category name in parameter:
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> listcomponents components
 
i2cocore  c38a_control  ledsensor  led  simplegpio  uart16550  irq_mngr  button
 
POD.project:i2cledbutton-tutorial>
 
</pre>
 
 
Three components will be loaded with the command ''addinstances'':
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> help addinstance
 
addinstance <componenttype>.<componentname>.[componentversion] [newinstancename]
 
        Add component in project
 
</pre>
 
 
The second parameter is used to give the instance name of the component in the project.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> addinstance components.button push
 
Component button added as push
 
 
POD.project:i2cledbutton-tutorial> addinstance components.led.wb16 blink
 
Component led added as blink
 
 
POD.project:i2cledbutton-tutorial> addinstance components.i2cocore.wb16 i2c
 
Component i2cocore added as i2c
 
</pre>
 
 
Note: some components like the led may have several versions depending on the Wishbone bus size for example.
 
 
[[image:exemple-components.png|center|frame|400px|'''figure 4''' - ''Components loaded'']]
 
 
=== Internal pin connections ===
 
 
''push'' and ''i2c'' components have output pins to generate interrupts. These pins have
 
to be connected to the interrupt manager "irq_mngr00".
 
 
 
[[image:exemple-intconnection.png|center|frame|400px|'''figure 5''' - ''Internal interrupts connections'']]
 
 
A complete description of an instance in the project can be displayed with the ''info'' command:
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> info i2c
 
Component name :i2c
 
Instance  name :i2cocore
 
description : A simple button ip
 
->Generics
 
            id : 1
 
        wb_size : 16
 
->Interfaces
 
irq            :
 
    inta_o          s1
 
candr          :
 
    rst_i          s1
 
    clk_i          s1
 
i2c            :
 
    scl            s1
 
    sda            s1
 
swb16            Base address:0x0
 
    adr_i          s4
 
    dat_i          s16
 
    dat_o          s16
 
    we_i            s1
 
    stb_i          s1
 
    ack_o          s1
 
    cyc_i          s1
 
POD.project:i2cledbutton-tutorial>
 
</pre>
 
 
This command gives the interfaces, the ports and the size of the ports (s1, s16, ...). We want to
 
connect the interrupt port pin number 0, named '''inta_o''' and part of the '''irq'''
 
interface, to the ''irq_mngr00''.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> info irq_mngr00
 
Component name :irq_mngr00
 
Instance  name :irq_mngr
 
description : Manage interruptions.
 
->Generics
 
            id : 1
 
      irq_level : '1'
 
      irq_count : 1
 
->Interfaces
 
candr          :
 
    gls_clk        s1
 
    gls_reset      s1
 
swb16            Base address:0x0
 
    wbs_s1_address  s2
 
    wbs_s1_readdata s16
 
    wbs_s1_writedata s16
 
    wbs_s1_ack      s1
 
    wbs_s1_strobe  s1
 
    wbs_s1_cycle    s1
 
    wbs_s1_write    s1
 
irq            :
 
    irqport        s16
 
ext_irq        :
 
    gls_irq        s1
 
        pin 0: -> apf9328.fpga.TIM1.0
 
</pre>
 
 
The targeted port in the irq_mngr is '''irqport''' part of the '''irq''' interface. To establish the connection, the ''connectpin'' command will be used:
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> connectpin irq_mngr00.irq.irqport.0 i2c.irq.inta_o.0
 
pin connected
 
</pre>
 
 
Same thing for the push button :
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> connectpin irq_mngr00.irq.irqport.1 push.int_button.irq.0
 
pin connected
 
</pre>
 
 
The ''info'' command can be used to verify that the connection is correctly performed:
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> info irq_mngr00
 
Component name :irq_mngr00
 
Instance  name :irq_mngr
 
description : Manage interruptions.
 
->Generics
 
            id : 1
 
      irq_level : '1'
 
      irq_count : 2
 
->Interfaces
 
candr          :
 
    gls_clk        s1
 
    gls_reset      s1
 
swb16            Base address:0x0
 
    wbs_s1_address  s2
 
    wbs_s1_readdata s16
 
    wbs_s1_writedata s16
 
    wbs_s1_ack      s1
 
    wbs_s1_strobe  s1
 
    wbs_s1_cycle    s1
 
    wbs_s1_write    s1
 
irq            :
 
    irqport        s16
 
        pin 0: -> i2c.irq.inta_o.0
 
        pin 1: -> push.int_button.irq.0
 
ext_irq        :
 
    gls_irq        s1
 
        pin 0: -> apf9328.fpga.TIM1.0
 
</pre>
 
 
=== External pin connections ===
 
 
Connecting an external pin is done the same way as for an internal pin by giving the name of the platform in place of the instance name. In the '''apf9328''' platform, the pin name
 
can be found in FPGA schematic [http://www.armadeus.com/_downloads/apf9328/hardware/apf_schema.pdf] (page 13).
 
The name of the interface is '''fpga''' for the apf9328. In this example we will connect the button, the led and the i2c to the APF9328DevFull connector X7 (figure 6).
 
 
[[image:devfullX7.png|center|frame|400px|'''figure 5''' - ''X7 connector'']]
 
 
We just have to connect the pins as following :
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> connectpin apf9328.fpga.IO_L01N_0 push.int_button.button.0
 
pin connected
 
POD.project:i2cledbutton-tutorial> connectpin i2c.i2c.sda apf9328.fpga.IO_L32N_0
 
pin connected
 
POD.project:i2cledbutton-tutorial> connectpin i2c.i2c.scl apf9328.fpga.IO_L01P_0
 
pin connected
 
POD.project:i2cledbutton-tutorial> connectpin blink.int_led.led.0 apf9328.fpga.IO_L32P_0
 
pin connected
 
</pre>
 
 
[[image:exemple-extconnection.png|center|frame|400px|'''figure 6''' - ''external connections'']]
 
 
=== Bus and clock connections ===
 
 
* '''Bus'''
 
 
[[image:exemple-busconnection.png|center|frame|400px|'''figure 7''' - ''Wishbone bus connections'']]
 
 
 
To connect a bus, the master bus interface is used as first argument of the ''connectbus'' command, the second argument being the slave bus interface:
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> connectbus imx9328_wb16_wrapper00.mwb16 blink.swb16
 
Bus connected
 
POD.project:i2cledbutton-tutorial> connectbus imx9328_wb16_wrapper00.mwb16 push.swb16
 
Bus connected
 
POD.project:i2cledbutton-tutorial> connectbus imx9328_wb16_wrapper00.mwb16 i2c.swb16
 
Bus connected
 
</pre>
 
 
* '''clock'''
 
 
[[image:exemple-clockconnection.png|center|frame|400px|'''figure 8''' - ''Syscon connection'']]
 
 
 
The bus interconection (Intercon) need to be synchronized with a clock and reset generator. This can be done by means of the ''addbusclock'' command.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> addbusclock rstgen_syscon00.candr imx9328_wb16_wrapper00.mwb16
 
Connected
 
</pre>
 
 
* '''autoconnect'''
 
 
Bus and clock connections can be automaticaly performed with the ''autoconnect'' command. This command works only for "classical" architectures and with recognized buses.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> autoconnectbus
 
</pre>
 
 
=== Intercon generation ===
 
 
Once the connections done, the Intercon component has to be generated. The Intercon is a component
 
responsible for decoding the addresses and for routing the Wishbone bus signals.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> intercon imx9328_wb16_wrapper00.mwb16
 
</pre>
 
 
[[image:exemple-intercon.png|center|frame|400px|'''figure 8''' - ''Intercon'']]
 
 
=== Top generation ===
 
 
[[image:exemple-top.png|center|frame|400px|'''figure 9''' - ''Top'']]
 
 
The Top component is the component responsible for connecting the non Wishbone signals in the FPGA. The Top can be generated with the ''top'' command
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> top
 
 
Top generated with name : top_i2cledbutton-tutorial.vhd
 
</pre>
 
 
== Synthesis ==
 
 
In the '''apf9328''' platform, the FPGA is a Spartan3 from Xilinx. This means that the synthesis of the project can only be done with ISE. Fortunately, Xilinx provides the ISE
 
Webpack freely on its website [http://www.xilinx.com/ise/logic_design_prod/webpack.htm].
 
 
POD has to generate a project that ISE can understand. This can be accomplished from the synthesis environment :
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial> synthesis
 
POD.project.synthesis>
 
</pre>
 
 
Then the tool used for the synthesis has to be specified with the ''selecttoolchain'' command:
 
 
<pre style="host">
 
POD.project.synthesis> selecttoolchain ise
 
</pre>
 
 
After that we can generate an ISE project with the ''generateproject'' command.
 
 
<pre style="host">
 
POD.project:i2cledbutton-tutorial.synthesis> selecttoolchain ise
 
POD.project:i2cledbutton-tutorial.synthesis> generateproject
 
Make directory for imx9328_wb16_wrapper
 
Make directory for rstgen_syscon
 
Make directory for irq_mngr
 
Make directory for led
 
Make directory for button
 
Make directory for i2cocore
 
Make directory for imx9328_wb16_wrapper00_mwb16
 
 
Constraint file generated with name :~/pod/tests/i2cledbutton-tutorial/synthesis/i2cledbutton-tutorial.ucf
 
 
TCL script generated with name : i2cledbutton-tutorial.tcl
 
</pre>
 
 
As you can see, POD generates although a TCL script that can be executed by ISE. This script eases the synthesis process.
 
 
[[image:exemple-ise.png|center|frame|400px|'''figure 10''' - ''Bitstream generation with ISE Webpack'']]
 
 
In the Tcl tab ('''1'''), change the default directory to the synthesis directory ('''2'''), find the tcl script you want to execute ('''3''', under Windows type ''dir'' instead of ''ls'') and start it with the ''source'' command ('''4''').
 
 
The resulting bitstream (binary FPGA synthetized code) ''top_i2cledbutton.bit'' can be found in the ''i2cledbutton_tutorial/objs'' directory.
 
 
== Simulation ==
 
 
If a simulation is required, POD can generate a template for the whole project. To do this, enter in the simulation environment :
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial> simulation
 
POD.project:i2cledbutton_tutorial.simulation>
 
</pre>
 
 
To generate the testbench and the makefile use the command:
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial.simulation> generateproject
 
 
Testbench with name : /home/fabien/projectpod/software/pod/tests/i2cledbutton_tutorial/simulation/top_i2cledbutton_tutorial_tb.vhd Done
 
 
Makefile generated with name : /home/fabien/projectpod/software/pod/tests/i2cledbutton_tutorial/simulation/Makefile Done
 
</pre>
 
 
Now, you just have to modify the ''top_i2cledbutton_tutorial_tb.vhd'' file to add your own tests
 
under the ''stimulis'' process.
 
 
<pre style="host">
 
stimulis : process
 
begin
 
-- write stimulis here
 
wait for 10 us;
 
assert false report "End of test" severity error;
 
end process stimulis;
 
</pre>
 
 
You can then start the simulation with ''make ghdl-simu'' and launch ''make ghdl-view'' to
 
view the generated chronograms with gtkwave.
 
 
== Drivers ==
 
 
Numbers of components have a driver template for different operating systems. POD can
 
fill these templates with the informations contained in the project.
 
 
From the driver environment,
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial> driver
 
POD.project:i2cledbutton_tutorial.driver>
 
</pre>
 
 
choose the targeted platform:
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial.driver> selecttoolchain armadeus
 
</pre>
 
 
And generate the driver project :
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial.driver> generateproject
 
No driver for imx9328_wb16_wrapper
 
No driver for rstgen_syscon
 
Create directory for irq_mngr driver
 
Create directory for button driver
 
Create directory for led driver
 
Create directory for i2cocore driver
 
No driver for imx9328_wb16_wrapper00_mwb16
 
Copy and fill template for irq_mngr
 
Copy and fill template for button
 
Copy and fill template for led
 
Copy and fill template for i2cocore
 
</pre>
 
 
Drivers are generated and can be found in the ''i2cledbutton_tutorial/drivers/'' directory.
 
POD can copy this drivers to the right place in the software development tree. Select the path with ''selectprojecttree'' then copy the files with ''copydrivers'':
 
 
<pre style="host">
 
POD.project:i2cledbutton_tutorial.driver> selectprojecttree ~/armadeus/target/linux/modules/fpga/POD
 
 
POD.project:i2cledbutton_tutorial.driver> copydrivers
 
</pre>
 
 
To compile the drivers, go to your ''armadeus/'' directory then type ''make linux26-menuconfig''. The drivers generated by POD are located in ''Device Drivers - Armadeus specific drivers - FPGA drivers '' (see figure 11).
 
 
[[image:exemple-linuxmenuconfig.png|center|frame|400px|'''figure 11''' - ''Linux menuconfig'']]
 
 
<pre style="host">
 
$ make linux-menuconfig
 
$ make
 
</pre>
 
[[Category:POD]]
 

Latest revision as of 18:12, 18 January 2013