Difference between revisions of "POD Tutorial"

From ArmadeusWiki
Jump to: navigation, search
(Drivers)
(Drivers)
 
(31 intermediate revisions by 3 users not shown)
Line 1: Line 1:

 
=Tutorial 1=
 
 
 
== Introduction ==
 
== Introduction ==
  
In this tutorial, we will learn how to use POD with a simple example project for an
+
In this first tutorial, we will learn how to use POD with a simple example project for an [[APF27]] board.
apf9328 board.
+
 
The project is described in figure 1. It is composed of 3 virtual components:
 
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.
 
*  '''blink''' : blink is the instance name of a led (virtual component) that can «blink» by simply writing a value in a register.
Line 16: Line 12:
  
 
See [[POD installation guide]] to learn how to install it.
 
See [[POD installation guide]] to learn how to install it.
 +
 +
{{Note| This tutorial is written for apf27_dev a LED is already soldered on fpga. The fpga bank1 must be powered with 3.3V (connect pin 39 and pin 1 on J20 header)}}
  
 
== POD ==
 
== POD ==
  
POD can be started by writing "pod" in the pod/bin/ directory. If you are under Windows ''python'' has to be written before:
+
If POD is [[POD_installation_guide | correctly installed]], simply type :
<source lang="bash">
+
<pre class="host">
$ python pod/bin/pod
+
$ pod  
 
POD>  
 
POD>  
</source>
+
</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 ===
 
=== Playing with POD ===
Line 38: Line 31:
 
To enter in an environment, simply write its name from the parent environment.
 
To enter in an environment, simply write its name from the parent environment.
  
<source lang="bash">
+
<pre class="host">
POD> project
+
POD> synthesis
POD.project>  
+
POD.synthesis>  
</source>
+
</pre>
  
 
For a complete list of the available commands type ''help''
 
For a complete list of the available commands type ''help''
<source lang="bash">
+
<pre class="pod">
POD.project> help
+
POD> help
  
 
Documented commands (type help <topic>):
 
Documented commands (type help <topic>):
 
========================================
 
========================================
EOF             create         help           listplatforms  setaddr 
+
EOF               create            history         ls              shell     
addbusclock    delcomponent  history         load            setgeneric
+
addbusclock      delbusconnection info            printxml        simulation
addcomponent    delconnection  info            ls              shell     
+
addinstance      delinstance      generateintercon quit            source   
autoconnectbus description    intercon        printxml        simulation
+
autoconnectbus   delpinconnection  listcomponents   report          synthesis
check          driver        listcomponents  quit            synthesis
+
check            description      listforce        savehistory    generatetop        
closeproject   eof            listinstances   savehistory    top        
+
closeproject     driver            listinstances    saveproject     version    
connectbus     exit          listinterfaces  saveproject   
+
connectbus        eof              listinterfaces  selectplatform
connectpin     getmapping     listmasters    selectplatform
+
connectinterface  exit              listmasters     setaddr     
 +
connectpin        getmapping       listplatforms    setforce     
 +
connectport      help              load            setgeneric   
  
POD.project>
+
</pre>
</source>
+
  
A short description is although available for each command.
+
A short help description is although available for each command.
  
<source lang="bash">
+
<pre class="pod">
POD.project> help listcomponents
+
POD> help listcomponents
 
  listcomponents [componenttype]
 
  listcomponents [componenttype]
 
         List components available in the library
 
         List components available in the library
 
          
 
          
POD.project>  
+
POD>  
</source>
+
</pre>
  
 
Command completion and argument completion can be done by using the <TAB> key :
 
Command completion and argument completion can be done by using the <TAB> key :
  
<source lang="bash">
+
<pre class="host">
POD.project> help list<TAB>
+
POD> help list<TAB>
 
listcomponents  listinterfaces  listplatforms   
 
listcomponents  listinterfaces  listplatforms   
 
listinstances  listmasters   
 
listinstances  listmasters   
POD.project> help list
+
POD> help list
</source>
+
</pre>
  
 
System commands can be used with «!» before:
 
System commands can be used with «!» before:
<source lang="bash">
+
<pre class="host">
POD.project> !echo "POD is really useful"
+
POD> !echo "POD is really useful"
 
POD is really useful
 
POD is really useful
POD.project>  
+
POD>  
</source>
+
</pre>
  
 
=== Project creation ===
 
=== Project creation ===
  
[[image:exemple-empty.png|center|frame|400px|'''figure 3''' - ''Empty i2cledbutton-tutorial project'']]
+
[[image:exemple-empty.png|center|frame|400px|'''figure 3''' - ''Empty i2cledbutton project'']]
  
 
To create a project, enter the ''create'' command in the ''project'' environment:
 
To create a project, enter the ''create'' command in the ''project'' environment:
<source lang="bash">
+
<pre style="host">
POD.project> create i2cledbutton-tutorial
+
POD> create i2cledbutton
Project i2cledbutton-tutorial created
+
Project i2cledbutton created
POD.project:i2cledbutton-tutorial>  
+
POD:i2cledbutton>  
</source>
+
</pre>
  
The ''i2cledbutton-tutorial'' project is now created, you can save it
+
The ''i2cledbutton'' project is now created and saved.  
when you want, by typing ''saveproject''.
+
  
 
The target platform has to be selected by means of the ''selectplatform'' command :
 
The target platform has to be selected by means of the ''selectplatform'' command :
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> selectplatform apf9328
+
project:i2cledbutton> selectplatform standard.apf27
Component platform added as apf9328
+
[INFO]  : No platform in project
Component imx9328_wb16_wrapper added as imx9328_wb16_wrapper00
+
Component platform added as apf27
 +
Component imx27_wb16_wrapper added as imx27_wb16_wrapper00
 
Component rstgen_syscon added as rstgen_syscon00
 
Component rstgen_syscon added as rstgen_syscon00
 
Component irq_mngr added as irq_mngr00
 
Component irq_mngr added as irq_mngr00
setting base address 0x0 for  irq_mngr00.swb16
 
  
Platform apf9328 selected
+
project:i2cledbutton>  
POD.project:i2cledbutton-tutorial>  
+
</pre>
</source>
+
  
 
By selecting this platform, several components will be automaticaly added by POD:
 
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.
+
* '''imx27_wb16_wrapper''': this component is used to convert the i.MX27 processor bus to the wishbone (16bits data) bus.
 
* '''rstgen_syscon''' : this component manages the clock and the reset for the design.
 
* '''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.
+
* '''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'']]
 
[[image:exemple-platform.png|center|frame|400px|'''figure 4''' - ''Platform loaded with their default components'']]
Line 125: Line 117:
  
 
Components are organized by category in the library, to list the categories, use ''listcomponents'':
 
Components are organized by category in the library, to list the categories, use ''listcomponents'':
<source lang="bash">
+
 
POD.project:i2cledbutton-tutorial> listcomponents
+
<pre style="host">
test  components  wrappers syscons
+
project:i2cledbutton> listcomponents  
POD.project:i2cledbutton-tutorial>
+
components  logics  syscons    test  wrappers
</source>
+
</pre>
  
 
And to list the components under a category use ''listcomponents'' again with the category name in parameter:
 
And to list the components under a category use ''listcomponents'' again with the category name in parameter:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> listcomponents components
+
project:i2cledbutton> listcomponents components
i2cocore c38a_control ledsensor led simplegpio  uart16550 irq_mngr  button
+
sp_vision_configure      bram              uart16750  spartan_selectmap
POD.project:i2cledbutton-tutorial>
+
industrial_output        anybus_interface simplegpio button         
</source>
+
industrial_serial_input led               uart16550   sja1000         
 +
i2cocore                pod_gpio          irq_mngr   
 +
</pre>
  
Three components will be loaded with the command ''addcomponents'':
+
The components will be loaded with the command ''addinstances'':
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> help addcomponent
+
POD:i2cledbutton> help addinstance
  addcomponent <componenttype>.<componentname>.[componentversion] [newinstancename]
+
  addinstance <componenttype>.<componentname>.[componentversion] [newinstancename]
 
         Add component in project
 
         Add component in project
</source>
+
</pre>
  
 
The second parameter is used to give the instance name of the component in the project.
 
The second parameter is used to give the instance name of the component in the project.
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> addcomponent components.button push
+
POD:i2cledbutton> addinstance components.button push
 
Component button added as push
 
Component button added as push
  
POD.project:i2cledbutton-tutorial> addcomponent components.led.wb16 blink
+
POD:i2cledbutton> addinstance components.led.wb16 blink
 
Component led added as blink
 
Component led added as blink
  
POD.project:i2cledbutton-tutorial> addcomponent components.i2cocore.wb16 i2c
+
POD:i2cledbutton> addinstance components.i2cocore.wb16 i2c
 
Component i2cocore added as i2c
 
Component i2cocore added as i2c
</source>
+
</pre>
  
 
Note: some components like the led may have several versions depending on the Wishbone bus size for example.
 
Note: some components like the led may have several versions depending on the Wishbone bus size for example.
Line 173: Line 167:
 
A complete description of an instance in the project can be displayed with the ''info'' command:
 
A complete description of an instance in the project can be displayed with the ''info'' command:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> info i2c
+
project:i2cledbutton> info i2c
Component name :i2c
+
Instance name :i2c
Instance name :i2cocore
+
Component name :i2cocore
 
description : A simple button ip
 
description : A simple button ip
 
->Generics
 
->Generics
Line 184: Line 178:
 
irq            :
 
irq            :
 
     inta_o          s1
 
     inta_o          s1
candr          :
 
    rst_i          s1
 
    clk_i          s1
 
 
i2c            :
 
i2c            :
 
     scl            s1
 
     scl            s1
 
     sda            s1
 
     sda            s1
 
swb16            Base address:0x0
 
swb16            Base address:0x0
 +
    rst_i          s1
 +
    clk_i          s1
 
     adr_i          s4
 
     adr_i          s4
 
     dat_i          s16
 
     dat_i          s16
Line 198: Line 191:
 
     ack_o          s1
 
     ack_o          s1
 
     cyc_i          s1
 
     cyc_i          s1
POD.project:i2cledbutton-tutorial>  
+
project:i2cledbutton>  
</source>
+
</pre>
  
 
This command gives the interfaces, the ports and the size of the ports (s1, s16, ...). We want to  
 
This command gives the interfaces, the ports and the size of the ports (s1, s16, ...). We want to  
Line 205: Line 198:
 
interface, to the ''irq_mngr00''.
 
interface, to the ''irq_mngr00''.
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> info irq_mngr00
+
POD:i2cledbutton> info irq_mngr00
 
Component name :irq_mngr00
 
Component name :irq_mngr00
 
Instance  name :irq_mngr
 
Instance  name :irq_mngr
Line 230: Line 223:
 
ext_irq        :
 
ext_irq        :
 
     gls_irq        s1
 
     gls_irq        s1
         pin 0: -> apf9328.fpga.TIM1.0
+
         pin 0: -> apf27.fpga.TIM1.0
</source>
+
</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:
 
The targeted port in the irq_mngr is '''irqport''' part of the '''irq''' interface. To establish the connection, the ''connectpin'' command will be used:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> connectpin irq_mngr00.irq.irqport.0 i2c.irq.inta_o.0
+
POD:i2cledbutton> connectpin irq_mngr00.irq.irqport.0 i2c.irq.inta_o.0
pin connected
+
 
</source>
+
</pre>
  
 
Same thing for the push button :
 
Same thing for the push button :
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> connectpin irq_mngr00.irq.irqport.1 push.int_button.irq.0
+
POD:i2cledbutton> connectpin irq_mngr00.irq.irqport.1 push.int_button.irq.0
 
pin connected
 
pin connected
</source>
+
</pre>
  
 
The ''info'' command can be used to verify that the connection is correctly performed:
 
The ''info'' command can be used to verify that the connection is correctly performed:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> info irq_mngr00
+
POD:i2cledbutton> info irq_mngr00
 
Component name :irq_mngr00
 
Component name :irq_mngr00
 
Instance  name :irq_mngr
 
Instance  name :irq_mngr
Line 276: Line 269:
 
ext_irq        :
 
ext_irq        :
 
     gls_irq        s1
 
     gls_irq        s1
         pin 0: -> apf9328.fpga.TIM1.0
+
         pin 0: -> apf27.fpga.TIM1.0
</source>
+
</pre>
  
 
=== External pin connections ===
 
=== 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  
+
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 '''apf27''' platform, the pin name  
can be found in FPGA schematic [http://www.armadeus.com/_downloads/apf9328/hardware/apf_schema.pdf] (page 13).  
+
can be found in FPGA schematic [http://www.armadeus.com/_downloads/apf27Dev/hardware/apf27_devfull_12.pdf].  
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).  
+
The name of the interface is '''fpga''' for the apf27. In this example we will connect the button, the led and the i2c to the apf27DevFull connector X7 (figure 6).  
  
[[image:devfullX7.png|center|frame|400px|'''figure 5''' - ''X7 connector'']]
+
[[image:led_apf27_dev.png|center|frame|400px|'''figure 5''' - ''FPGA led connection on apf27Devfull'']]
  
 
We just have to connect the pins as following :
 
We just have to connect the pins as following :
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> connectpin apf9328.fpga.IO_L01N_0 push.int_button.button.0
+
POD:i2cledbutton> connectpin blink.int_led.led.0 apf27.fpga.IO_L24P_1
pin connected
+
POD:i2cledbutton> connectpin push.int_button.button.0 apf27.fpga.IO_L24N_1
POD.project:i2cledbutton-tutorial> connectpin i2c.i2c.sda apf9328.fpga.IO_L32N_0
+
POD:i2cledbutton> connectpin i2c.i2c.sda apf27.fpga.IO_L20N_1
pin connected
+
POD:i2cledbutton> connectpin i2c.i2c.scl apf27.fpga.IO_L20P_1
POD.project:i2cledbutton-tutorial> connectpin i2c.i2c.scl apf9328.fpga.IO_L01P_0
+
</pre>
pin connected
+
POD.project:i2cledbutton-tutorial> connectpin blink.int_led.led.0 apf9328.fpga.IO_L32P_0
+
pin connected
+
</source>
+
  
 
[[image:exemple-extconnection.png|center|frame|400px|'''figure 6''' - ''external connections'']]
 
[[image:exemple-extconnection.png|center|frame|400px|'''figure 6''' - ''external connections'']]
Line 311: Line 300:
 
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:
 
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:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> connectbus imx9328_wb16_wrapper00.mwb16 blink.swb16
+
POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 blink.swb16
Bus connected
+
setting base address 0x0 for  blink.swb16
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
+
</source>
+
  
* '''clock'''
+
POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 push.swb16
 +
setting base address 0x4 for  push.swb16
  
[[image:exemple-clockconnection.png|center|frame|400px|'''figure 8''' - ''Syscon connection'']]
+
POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 i2c.swb16
 +
setting base address 0x20 for  i2c.swb16
  
 +
POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 irq_mngr00.swb16
 +
setting base address 0x40 for  irq_mngr00.swb16
 +
</pre>
  
The bus interconection (Intercon) need to be synchronized with a clock and reset generator. This can be done by means of the ''addbusclock'' command.
+
* '''clock & reset'''
  
<source lang="bash">
+
[[image:exemple-clockconnection.png|center|frame|400px|'''figure 8''' - ''Syscon connection'']]
POD.project:i2cledbutton-tutorial> addbusclock rstgen_syscon00.candr imx9328_wb16_wrapper00.mwb16
+
 
Connected
+
Clock and reset are seen like a standard bus, to connect it, simply use connectbus:
</source>
+
 
 +
<pre style="host">
 +
project:i2cledbutton> connectbus rstgen_syscon00.candroutput imx27_wb16_wrapper00.candrinput
 +
No addressing value in this type of bus
 +
</pre>
  
 
* '''autoconnect'''
 
* '''autoconnect'''
  
Bus and clock connections can be automaticaly performed with the ''autoconnect'' command. This command works only for "classical" architectures and with recognized buses.
+
Bus and clock connections can be automatically performed with the ''autoconnect'' command. This command works only for "classical" architectures and with recognized busses.
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> autoconnectbus
+
POD:i2cledbutton> autoconnectbus
</source>
+
</pre>
  
 
=== Intercon generation ===
 
=== Intercon generation ===
  
Once the connections done, the Intercon component has to be generated. The Intercon is a component
+
Once the connections done, the Intercons components has to be generated. Intercons are components
responsible for decoding the addresses and for routing the Wishbone bus signals.
+
responsible for decoding the addresses and for routing bus signals. Intercons must be generated for each master bus.
  
<source lang="bash">
+
* for wrapper master wishbone bus
POD.project:i2cledbutton-tutorial> intercon imx9328_wb16_wrapper00.mwb16
+
<pre style="host">
</source>
+
POD> generateintercon imx27_wb16_wrapper00.mwb16
 +
Intercon with name : imx27_wb16_wrapper00_mwb16_intercon Done
 +
Component imx27_wb16_wrapper00_mwb16 added as imx27_wb16_wrapper00_mwb16_intercon
 +
</pre>
 +
 
 +
* for syscon master candr bus
 +
<pre style="host">
 +
POD> generateintercon rstgen_syscon00.candroutput
 +
Intercon with name : rstgen_syscon00_candroutput_intercon Done
 +
Component rstgen_syscon00_candroutput added as rstgen_syscon00_candroutput_intercon
 +
</pre>
  
 
[[image:exemple-intercon.png|center|frame|400px|'''figure 8''' - ''Intercon'']]
 
[[image:exemple-intercon.png|center|frame|400px|'''figure 8''' - ''Intercon'']]
Line 355: Line 358:
 
[[image:exemple-top.png|center|frame|400px|'''figure 9''' - ''Top'']]
 
[[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
+
The Top component is the component responsible for connecting all instances in the FPGA. The Top can be generated with the ''generatetop'' command
 +
 
 +
<pre style="host">
 +
POD:i2cledbutton> generatetop
  
<source lang="bash">
+
Mapping for interface mwb16:
POD.project:i2cledbutton-tutorial> top
+
Address  | instance.interface            | size
 +
---------------------------------------------------------
 +
0x0 |                    blink.swb16 |          4
 +
0x4 |                    push.swb16 |          4
 +
0x08 |                      --void-- |        24
 +
0x20 |                      i2c.swb16 |        32
 +
0x40 |              irq_mngr00.swb16 |          8
 +
---------------------------------------------------------
  
Top generated with name : top_i2cledbutton-tutorial.vhd
+
Top generated with name : top_i2cledbutton.vhd
</source>
+
</pre>
  
 
== Synthesis ==
 
== 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  
+
In the '''apf27''' platform, the FPGA is a Spartan3A 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].
 
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 :
 
POD has to generate a project that ISE can understand. This can be accomplished from the synthesis environment :
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial> synthesis
+
POD:i2cledbutton-tutorial> synthesis
POD.project.synthesis>  
+
POD.synthesis>  
</source>
+
</pre>
  
 
Then the tool used for the synthesis has to be specified with the ''selecttoolchain'' command:
 
Then the tool used for the synthesis has to be specified with the ''selecttoolchain'' command:
  
<source lang="bash">
+
<pre style="host">
POD.project.synthesis> selecttoolchain ise
+
POD.synthesis> selecttoolchain ise
</source>
+
</pre>
  
 
After that we can generate an ISE project with the ''generateproject'' command.
 
After that we can generate an ISE project with the ''generateproject'' command.
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton-tutorial.synthesis> selecttoolchain ise
+
POD> synthesis
POD.project:i2cledbutton-tutorial.synthesis> generateproject
+
POD.synthesis> selecttoolchain ise
Make directory for imx9328_wb16_wrapper
+
POD.synthesis> generateproject
 +
Make directory for imx27_wb16_wrapper
 
Make directory for rstgen_syscon
 
Make directory for rstgen_syscon
 
Make directory for irq_mngr
 
Make directory for irq_mngr
Make directory for led
 
 
Make directory for button
 
Make directory for button
 +
Make directory for led
 
Make directory for i2cocore
 
Make directory for i2cocore
Make directory for imx9328_wb16_wrapper00_mwb16
+
Make directory for rstgen_syscon00_candroutput
 +
Make directory for imx27_wb16_wrapper00_mwb16
  
Constraint file generated with name :~/pod/tests/i2cledbutton-tutorial/synthesis/i2cledbutton-tutorial.ucf
+
Constraint file generated with name : /home/fabien/tmp/i2cledbutton/synthesis/i2cledbutton.ucf
  
TCL script generated with name : i2cledbutton-tutorial.tcl
+
TCL script generated with name : i2cledbutton.tcl
</source>
+
</pre>
  
 
As you can see, POD generates although a TCL script that can be executed by ISE. This script eases the synthesis process.  
 
As you can see, POD generates although a TCL script that can be executed by ISE. This script eases the synthesis process.  
Line 404: Line 419:
  
 
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''').
 
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''').
 +
 +
{{ Note | To use this tutorial with APF51, generate binary file '''.bin''' instead of bitstream '''.bit''' file. }}
  
 
The resulting bitstream (binary FPGA synthetized code) ''top_i2cledbutton.bit'' can be found in the ''i2cledbutton_tutorial/objs'' directory.
 
The resulting bitstream (binary FPGA synthetized code) ''top_i2cledbutton.bit'' can be found in the ''i2cledbutton_tutorial/objs'' directory.
 +
 +
{{Warning | There is a bug with ISE-13.x and upper, when tcl script is launched, the constraints file (ucf) is not read and ISE choose FPGA pinout randomly. To avoid this problem, once the script is sourced, re-launch the entire process by clicking right on «Generate Programming File» en selecting «re-run all» }}
  
 
== Simulation ==
 
== Simulation ==
Line 411: Line 430:
 
If a simulation is required, POD can generate a template for the whole project. To do this, enter in the simulation environment :
 
If a simulation is required, POD can generate a template for the whole project. To do this, enter in the simulation environment :
  
<source lang="bash">
+
<pre style="host">
 
POD.project:i2cledbutton_tutorial> simulation
 
POD.project:i2cledbutton_tutorial> simulation
 
POD.project:i2cledbutton_tutorial.simulation>  
 
POD.project:i2cledbutton_tutorial.simulation>  
</source>
+
</pre>
 +
 
 +
First select your toolchain (here it's ghdl):
 +
<pre style="host">
 +
POD.project:i2cledbutton_tutorial.simulation> selecttoolchain ghdl
 +
</pre>
  
 
To generate the testbench and the makefile use the command:
 
To generate the testbench and the makefile use the command:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton_tutorial.simulation> generatemakefile
+
POD.project:i2cledbutton_tutorial.simulation> generateproject
  
 
Testbench with name : /home/fabien/projectpod/software/pod/tests/i2cledbutton_tutorial/simulation/top_i2cledbutton_tutorial_tb.vhd Done
 
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
 
Makefile generated with name : /home/fabien/projectpod/software/pod/tests/i2cledbutton_tutorial/simulation/Makefile Done
</source>
+
</pre>
  
 
Now, you just have to modify the ''top_i2cledbutton_tutorial_tb.vhd'' file to add your own tests  
 
Now, you just have to modify the ''top_i2cledbutton_tutorial_tb.vhd'' file to add your own tests  
 
under the ''stimulis'' process.
 
under the ''stimulis'' process.
  
<source lang="vhdl">
+
<pre style="host">
 
stimulis : process
 
stimulis : process
 
begin
 
begin
Line 436: Line 460:
 
assert false report "End of test" severity error;
 
assert false report "End of test" severity error;
 
end process stimulis;
 
end process stimulis;
</source>
+
</pre>
  
 
You can then start the simulation with ''make ghdl-simu'' and launch ''make ghdl-view'' to  
 
You can then start the simulation with ''make ghdl-simu'' and launch ''make ghdl-view'' to  
Line 448: Line 472:
 
From the driver environment,
 
From the driver environment,
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton_tutorial> driver
+
POD:i2cledbutton_tutorial> driver
POD.project:i2cledbutton_tutorial.driver>  
+
POD:i2cledbutton_tutorial.driver>  
</source>
+
</pre>
  
 
choose the targeted platform:
 
choose the targeted platform:
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton_tutorial.driver> selecttoolchain armadeus
+
POD:i2cledbutton_tutorial.driver> selecttoolchain armadeus
</source>
+
</pre>
  
 
And generate the driver project :  
 
And generate the driver project :  
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton_tutorial.driver> generateproject
+
POD:i2cledbutton_tutorial.driver> generateproject
 
No driver for imx9328_wb16_wrapper
 
No driver for imx9328_wb16_wrapper
 
No driver for rstgen_syscon
 
No driver for rstgen_syscon
Line 474: Line 498:
 
Copy and fill template for led
 
Copy and fill template for led
 
Copy and fill template for i2cocore
 
Copy and fill template for i2cocore
</source>
+
</pre>
  
 
Drivers are generated and can be found in the ''i2cledbutton_tutorial/drivers/'' directory.  
 
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'':
 
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'':
  
<source lang="bash">
+
<pre style="host">
POD.project:i2cledbutton_tutorial.driver> selectprojecttree ~/armadeus/target/linux/modules/fpga/POD
+
POD:i2cledbutton_tutorial.driver> selectprojecttree ~/armadeus/target/linux/modules/fpga/POD
  
POD.project:i2cledbutton_tutorial.driver> copydrivers
+
POD:i2cledbutton_tutorial.driver> copydrivers
 +
</pre>
  
</source>
+
To compile the drivers, go to your ''armadeus/'' directory, then:
 +
<pre style="host">
 +
$ make linux-menuconfig
 +
</pre>
  
To compile the drivers, go to your ''armadeus/'' directory then type ''make linux-menuconfig''. The drivers generated by POD are located in ''Device Drivers - Armadeus specific drivers - FPGA drivers '' (see figure 11).
+
<pre class="config">
 +
Device Drivers --->
 +
        ...
 +
        [*] Support for specific Armadeus drivers --->
 +
            ...
 +
              *** FPGA related ***
 +
            [*]  FPGA specific drivers and tools  --->
 +
                ...
 +
                [*]  Board drivers generated by POD
 +
</pre>
  
[[image:exemple-linuxmenuconfig.png|center|frame|400px|'''figure 11''' - ''Linux menuconfig'']]
+
<pre style="host">
 
+
<source lang="bash">
+
$ make linux-menuconfig
+
 
$ make
 
$ make
</source>
+
</pre>
 +
 
 +
== Test ==
 +
 
 +
Once [[Target_Software_Installation#FPGA_firmware_installation | bitstream is loaded]], run linux and modprobe pod linux module :
 +
<pre class="apf">
 +
# modprobe irq_ocore
 +
# modprobe pod_irq_mng
 +
# modprobe led_ocore
 +
# modprobe pod_leds
 +
BLINK: MAJOR: 249 MINOR: 0
 +
LED module BLINK inserted
 +
# modprobe i2c-ocores-pod
 +
# modprobe pod_board_i2c
 +
PM: Adding info for platform:ocores-i2c-pod.0
 +
PM: Adding info for No Bus:i2c-2
 +
PM: Adding info for No Bus:i2c-2
 +
# modprobe button_ocore
 +
# modprobe pod_buttons
 +
probing button
 +
button button.0: PUSH: MAJOR: 248 MINOR: 0
 +
PUSH loaded
 +
</pre>
 +
 
 +
Read [[A_simple_design_with_Wishbone_bus]] to know how to use led and button.
 +
 
 +
 
 
[[Category:POD]]
 
[[Category:POD]]

Latest revision as of 16:11, 26 August 2013

Introduction

In this first tutorial, we will learn how to use POD with a simple example project for an APF27 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.
figure 1 - Project example for tutorial

Installation

See POD installation guide to learn how to install it.

Note Note: This tutorial is written for apf27_dev a LED is already soldered on fpga. The fpga bank1 must be powered with 3.3V (connect pin 39 and pin 1 on J20 header)


POD

If POD is correctly installed, simply type :

$ pod 
POD> 

Playing with POD

POD is a console program composed of several environments described in figure 2.

figure 2 - POD console architecture

To enter in an environment, simply write its name from the parent environment.

POD> synthesis 
POD.synthesis> 

For a complete list of the available commands type help

POD> help

Documented commands (type help <topic>):
========================================
EOF               create            history          ls              shell     
addbusclock       delbusconnection  info             printxml        simulation
addinstance       delinstance       generateintercon quit            source    
autoconnectbus    delpinconnection  listcomponents   report          synthesis 
check             description       listforce        savehistory     generatetop       
closeproject      driver            listinstances    saveproject     version   
connectbus        eof               listinterfaces   selectplatform
connectinterface  exit              listmasters      setaddr       
connectpin        getmapping        listplatforms    setforce      
connectport       help              load             setgeneric    

A short help description is although available for each command.

POD> help listcomponents
 listcomponents [componenttype]
        List components available in the library
        
POD> 

Command completion and argument completion can be done by using the <TAB> key :

POD> help list<TAB>
listcomponents  listinterfaces  listplatforms   
listinstances   listmasters  
POD> help list

System commands can be used with «!» before:

POD> !echo "POD is really useful"
POD is really useful
POD> 

Project creation

figure 3 - Empty i2cledbutton project

To create a project, enter the create command in the project environment:

POD> create i2cledbutton
Project i2cledbutton created
POD:i2cledbutton> 

The i2cledbutton project is now created and saved.

The target platform has to be selected by means of the selectplatform command :

project:i2cledbutton> selectplatform standard.apf27
[INFO]   : No platform in project
Component platform added as apf27
Component imx27_wb16_wrapper added as imx27_wb16_wrapper00
Component rstgen_syscon added as rstgen_syscon00
Component irq_mngr added as irq_mngr00

project:i2cledbutton> 

By selecting this platform, several components will be automaticaly added by POD:

  • imx27_wb16_wrapper: this component is used to convert the i.MX27 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.
figure 4 - Platform loaded with their default components

Adding components

Components are organized by category in the library, to list the categories, use listcomponents:

project:i2cledbutton> listcomponents 
components  logics   syscons     test   wrappers

And to list the components under a category use listcomponents again with the category name in parameter:

project:i2cledbutton> listcomponents components
sp_vision_configure      bram              uart16750   spartan_selectmap
industrial_output        anybus_interface  simplegpio  button           
industrial_serial_input  led               uart16550   sja1000          
i2cocore                 pod_gpio          irq_mngr  

The components will be loaded with the command addinstances:

POD:i2cledbutton> help addinstance
 addinstance <componenttype>.<componentname>.[componentversion] [newinstancename]
        Add component in project

The second parameter is used to give the instance name of the component in the project.

POD:i2cledbutton> addinstance components.button push
Component button added as push

POD:i2cledbutton> addinstance components.led.wb16 blink
Component led added as blink

POD:i2cledbutton> addinstance components.i2cocore.wb16 i2c
Component i2cocore added as i2c

Note: some components like the led may have several versions depending on the Wishbone bus size for example.

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".


figure 5 - Internal interrupts connections

A complete description of an instance in the project can be displayed with the info command:

project:i2cledbutton> info i2c
Instance name :i2c
Component  name :i2cocore
description : A simple button ip
->Generics
             id : 1
        wb_size : 16
->Interfaces
irq             :
     inta_o          s1
i2c             :
     scl             s1
     sda             s1
swb16            Base address:0x0
     rst_i           s1
     clk_i           s1
     adr_i           s4
     dat_i           s16
     dat_o           s16
     we_i            s1
     stb_i           s1
     ack_o           s1
     cyc_i           s1
project:i2cledbutton> 

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.

POD:i2cledbutton> 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: -> apf27.fpga.TIM1.0

The targeted port in the irq_mngr is irqport part of the irq interface. To establish the connection, the connectpin command will be used:

POD:i2cledbutton> connectpin irq_mngr00.irq.irqport.0 i2c.irq.inta_o.0

Same thing for the push button :

POD:i2cledbutton> connectpin irq_mngr00.irq.irqport.1 push.int_button.irq.0
pin connected

The info command can be used to verify that the connection is correctly performed:

POD:i2cledbutton> 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: -> apf27.fpga.TIM1.0

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 apf27 platform, the pin name can be found in FPGA schematic [1]. The name of the interface is fpga for the apf27. In this example we will connect the button, the led and the i2c to the apf27DevFull connector X7 (figure 6).

figure 5 - FPGA led connection on apf27Devfull

We just have to connect the pins as following :

POD:i2cledbutton> connectpin blink.int_led.led.0 apf27.fpga.IO_L24P_1
POD:i2cledbutton> connectpin push.int_button.button.0 apf27.fpga.IO_L24N_1 
POD:i2cledbutton> connectpin i2c.i2c.sda apf27.fpga.IO_L20N_1
POD:i2cledbutton> connectpin i2c.i2c.scl apf27.fpga.IO_L20P_1
figure 6 - external connections

Bus and clock connections

  • Bus
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:

POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 blink.swb16
setting base address 0x0 for  blink.swb16

POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 push.swb16
setting base address 0x4 for  push.swb16

POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 i2c.swb16
setting base address 0x20 for  i2c.swb16

POD:i2cledbutton> connectbus imx27_wb16_wrapper00.mwb16 irq_mngr00.swb16
setting base address 0x40 for  irq_mngr00.swb16
  • clock & reset
figure 8 - Syscon connection

Clock and reset are seen like a standard bus, to connect it, simply use connectbus:

project:i2cledbutton> connectbus rstgen_syscon00.candroutput imx27_wb16_wrapper00.candrinput
No addressing value in this type of bus
  • autoconnect

Bus and clock connections can be automatically performed with the autoconnect command. This command works only for "classical" architectures and with recognized busses.

POD:i2cledbutton> autoconnectbus

Intercon generation

Once the connections done, the Intercons components has to be generated. Intercons are components responsible for decoding the addresses and for routing bus signals. Intercons must be generated for each master bus.

  • for wrapper master wishbone bus
POD> generateintercon imx27_wb16_wrapper00.mwb16
Intercon with name : imx27_wb16_wrapper00_mwb16_intercon Done
Component imx27_wb16_wrapper00_mwb16 added as imx27_wb16_wrapper00_mwb16_intercon
  • for syscon master candr bus
POD> generateintercon rstgen_syscon00.candroutput
Intercon with name : rstgen_syscon00_candroutput_intercon Done
Component rstgen_syscon00_candroutput added as rstgen_syscon00_candroutput_intercon
figure 8 - Intercon

Top generation

figure 9 - Top

The Top component is the component responsible for connecting all instances in the FPGA. The Top can be generated with the generatetop command

POD:i2cledbutton> generatetop

Mapping for interface mwb16:
Address  | instance.interface             | size
---------------------------------------------------------
0x0 |                    blink.swb16 |          4
0x4 |                     push.swb16 |          4
0x08 |                       --void-- |         24
0x20 |                      i2c.swb16 |         32
0x40 |               irq_mngr00.swb16 |          8
---------------------------------------------------------

Top generated with name : top_i2cledbutton.vhd

Synthesis

In the apf27 platform, the FPGA is a Spartan3A 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 [2].

POD has to generate a project that ISE can understand. This can be accomplished from the synthesis environment :

POD:i2cledbutton-tutorial> synthesis
POD.synthesis> 

Then the tool used for the synthesis has to be specified with the selecttoolchain command:

POD.synthesis> selecttoolchain ise

After that we can generate an ISE project with the generateproject command.

POD> synthesis
POD.synthesis> selecttoolchain ise
POD.synthesis> generateproject
Make directory for imx27_wb16_wrapper
Make directory for rstgen_syscon
Make directory for irq_mngr
Make directory for button
Make directory for led
Make directory for i2cocore
Make directory for rstgen_syscon00_candroutput
Make directory for imx27_wb16_wrapper00_mwb16

Constraint file generated with name : /home/fabien/tmp/i2cledbutton/synthesis/i2cledbutton.ucf

TCL script generated with name : i2cledbutton.tcl

As you can see, POD generates although a TCL script that can be executed by ISE. This script eases the synthesis process.

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).

Note Note: To use this tutorial with APF51, generate binary file .bin instead of bitstream .bit file.


The resulting bitstream (binary FPGA synthetized code) top_i2cledbutton.bit can be found in the i2cledbutton_tutorial/objs directory.

Warning Warning: There is a bug with ISE-13.x and upper, when tcl script is launched, the constraints file (ucf) is not read and ISE choose FPGA pinout randomly. To avoid this problem, once the script is sourced, re-launch the entire process by clicking right on «Generate Programming File» en selecting «re-run all»


Simulation

If a simulation is required, POD can generate a template for the whole project. To do this, enter in the simulation environment :

POD.project:i2cledbutton_tutorial> simulation
POD.project:i2cledbutton_tutorial.simulation> 

First select your toolchain (here it's ghdl):

POD.project:i2cledbutton_tutorial.simulation> selecttoolchain ghdl

To generate the testbench and the makefile use the command:

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

Now, you just have to modify the top_i2cledbutton_tutorial_tb.vhd file to add your own tests under the stimulis process.

stimulis : process
begin
-- write stimulis here
wait for 10 us;
assert false report "End of test" severity error;
end process stimulis;

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,

POD:i2cledbutton_tutorial> driver
POD:i2cledbutton_tutorial.driver> 

choose the targeted platform:

POD:i2cledbutton_tutorial.driver> selecttoolchain armadeus

And generate the driver project :

POD: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

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:

POD:i2cledbutton_tutorial.driver> selectprojecttree ~/armadeus/target/linux/modules/fpga/POD

POD:i2cledbutton_tutorial.driver> copydrivers

To compile the drivers, go to your armadeus/ directory, then:

$ make linux-menuconfig
Device Drivers  --->
        ...
        [*] Support for specific Armadeus drivers --->
            ...
              *** FPGA related ***
            [*]   FPGA specific drivers and tools  --->
                ...
                [*]   Board drivers generated by POD
$ make

Test

Once bitstream is loaded, run linux and modprobe pod linux module :

# modprobe irq_ocore
# modprobe pod_irq_mng
# modprobe led_ocore
# modprobe pod_leds
BLINK: MAJOR: 249 MINOR: 0
LED module BLINK inserted
# modprobe i2c-ocores-pod
# modprobe pod_board_i2c
PM: Adding info for platform:ocores-i2c-pod.0
PM: Adding info for No Bus:i2c-2
PM: Adding info for No Bus:i2c-2
# modprobe button_ocore
# modprobe pod_buttons
probing button
button button.0: PUSH: MAJOR: 248 MINOR: 0
PUSH loaded

Read A_simple_design_with_Wishbone_bus to know how to use led and button.