Home > FPGA, Guides > Porting the LatticeMico32 to a Xilinx FPGA

Porting the LatticeMico32 to a Xilinx FPGA

I finally finished my work getting the LatticeMico32 ported to a Xilinx FPGA, namely the Spartan 6. I’ve used the ZTEX FPGA Module for development, as it contains a Spartan 6 XC6SLX25 – I wrote a short review about it here: http://blog.tkjelectronics.dk/2011/02/reviewguide-ztex-spartan-6-module/

I wrote a guide about how to port the LatticeMico32 to a Xilinx FPGA, including the C-code programming stage in the Lattice system. You can download the guide here:

The LatticeMico32 is an open source soft core processor provided by Lattice. The Lattice system makes a complete set of Verilog files, which can be ported to any FPGA. I decided to port it to the Xilinx series.

The example in the guide just blinks some LEDs, but it is not just LED blinking made with Verilog or VHDL coding, it’s made with C-coding inside an Eclipse enviroment, then compiled to the LatticeMico32. In the video above I show my first example and experience with the LM32 on the Spartan 6 FPGA.

The project files used in the video above can be downloaded here:
But please note that I recommend following the guide first, instead of just downloading the project files. The project files can then be used as a reference, to check if you did it correctly!

  1. NML
    May 2nd, 2011 at 21:20 | #1

    Great work, the tutorial is well written and complete :-)

    Can you explain what you have modified in .v files to match the xilinx fpga,
    I have tried to change the device to a Spartan 3 fpga in your ISE project, which gives the error ‘Could not find verilog include file ‘lm32_include.v’, the error disappears when I switch back to Spartan 6 or Kintex 7, so I guess there is a device dependent file structure?

  2. May 3rd, 2011 at 09:23 | #2

    Dear NML.
    The modifications, made in the .v-files, are explained in the tutorial.
    The files you replace just include changes from Lattice logic to Xilinx logic.

    Though I’ve had problems with porting the LM32 to both Spartan 3 and Spartan 3E too -- I couldn’t synthesize. I don’t know why!

    Best Regards
    Thomas Jespersen

  3. NML
    May 3rd, 2011 at 21:17 | #3

    Dear Thomas

    I have just reread the tutorial, section 2, page 8, it says that .. you need to download our replacement files, listed on the first page of this guide.’
    I am still not sure how you have modified them, is it the simulation file “pmi_def.v” that you have removed or ?
    I am asking because I would probably add a memory controller or some other device in the Lattice tool, and the .v files will have to be modified.
    Strange thing that you can’t port to Spartan 3 either, I can see that other people have done it. I am using version ISE version 13.1

  4. mooger
    June 17th, 2011 at 21:26 | #4

    Great work! Thank you for posting such an insightful tutorial!

  5. Dun
    July 22nd, 2011 at 21:28 | #5

    Hi Thomas,

    Can you tell me how fast this processor can be ran on that board (I mean highest clock frequency)?


  6. July 30th, 2011 at 10:23 | #6

    Dear Dun.
    The maximum processor frequency lies on the FPGA’s maximum operating frequency.
    In this project we are using the Spartan 6 with a speed grade of -3 (xc6slx25-3ftg256). This means that it has a maximum input operating frequency of 280MHz, but an internal maximum operating frequency (PLL) of 375MHz.

    So our maximum processor frequency would be 375MHz!

    Best Regards
    Thomas Jespersen

  7. October 10th, 2011 at 14:45 | #7


    Prior to discovering your postings concerning porting the LM32 to a Spartan, I was in the middle of investigating how to port it to another FPGA (not Xilinx, not Altera). One thing that I was struggling with was the many pmi (parameterized) modules scattered about the Verilog code that the MSB application generated. Apparently the idea is that the Lattice development system provides the code for these PMI modules during the build. It isn’t clear what I should do with these if I’m not using a Lattice development environment. PMI modules that I’ve found through Verilog source inspection are pmi_fifo_dc, pmi_fifo, pmi_ram_dp, pmi_ram_dp_true, pmi_distributed_dpram, pmi_addsub. These are instantiated multiple times with various parameters. I didn’t see any mention of pmi modules in your documentation. Am I missing something? Through some cut and try inference I could probably make replacement modules that would work but I really don’t want to go that route if I can avoid it.

    So do you have any solutions for the pmi modules?


  8. October 13th, 2011 at 17:19 | #8

    @Sid Gilmore
    Dear Sid.
    The PMI modules generated by the Lattice IDE is vendor specific which means they can only be synthesized by the Lattice suite. When you are going to use the LM32 with FPGAs from other vendors you have to change these PMI with the respective ones from the other vendor.
    For the Xilinx series you replace the generated PMI with some Xilinx compatible ones when you replace the files with the ones from the ZIP file. It was simply a matter of importing the generated files, looking in the list for “missing items” and then change them.

    Best Regards
    Thomas Jespersen

  9. Pieter
    November 18th, 2011 at 20:18 | #9


    I have problems in the ISE.

    I got this error:
    ERROR:HDLCompilers:26 -- “../../Robocup_softcore/RobocupSoftcore/soc/../components/lm32_top/rtl/verilog/lm32_addsub.v” line 28 Could not find verilog include file ‘lm32_include.v’

    I followed the tutorial, but still get the error.
    I have also problems with the block memory. The block memory is now version 6.2

    my fpga board is the Basys2 -- Spartan3E XC3S250E

  10. November 19th, 2011 at 09:34 | #10

    We are having some of the same problems when we try to synthesize this project for the Spartan 3E family.
    Currently we have only got the LM32 working on the Spartan 6 family, and we haven’t found a solution to the problem, with the Spartan 3E family, yet.

    Best Regards
    Thomas Jespersen

  11. 86krooks
    December 30th, 2011 at 07:42 | #11

    Hi Thomas, what did you change in those verilog files. How do you change the lattice logic to xilinx logic. I am having problems porting it to spartan 3e.

    Please advise

  12. December 30th, 2011 at 12:25 | #12

    We made changes in the following 4 files, changing some Lattice specific included/used modules to Xilinx specific modules.
    -- lm32_addsub.v
    -- lm32_ram.v
    -- tpio.v
    -- wb_ebr_ctrl.v

  13. 86krooks
    December 30th, 2011 at 14:21 | #13

    @ Thomas Jespersen . I know the files you changed, but what changes were made in the verilog files, to make it compatible with xilinx fpga. Could you please have a tutorial on this as well.

  14. January 3rd, 2012 at 16:35 | #14

    Unfortunately currently we are very busy, so I don’t have time for making a tutorial about that -- but it is on my tutorial to-do list.
    If you manage to get the LM32 working on the Spartan 3E please notify us, as we have been struggling with that ourselves!

    Happy new year.

  15. DigitalDesignET
    March 16th, 2012 at 00:43 | #15

    thanks for this, i would not have the courage with out it.

    I was able to port LatticeMico32 to spartan 3e. i have no verilog (l use VHDL) knowledge but was not too difficult.

  16. DigitalDesignET
    March 16th, 2012 at 01:38 | #16

    Miner modification to gpio.v was needed because Verilog doesn’t require the begin-end blocks to be named but it is required with Xilinx ISE tools. TKJ Electronics used Spartan-6 which is using the newer version of XST, therefore there was no need to modify the Generated begin-end blocks.


  17. March 16th, 2012 at 08:31 | #17

    Thank for your quick demonstration of the required changes. We will try to redo these and make a brush-up tutorial for Spartan 3E devices.
    Could please zip up the files you have been using and send them to us? You can send them to mail@tkjelectronics.dk

  18. DigitalDesignET
    March 16th, 2012 at 10:19 | #18

    @Thomas Jespersen

    no problems email on its way

  19. DigitalDesignET
    March 16th, 2012 at 18:51 | #19

    @Thomas Jespersen
    ur email address not working, keep returning back

  20. March 16th, 2012 at 18:56 | #20

    That sounds very odd. We haven’t had email problems with this mail before.
    I can also send mails to it without any problems.

    Are you sure you used: mail@tkjelectronics.dk ???
    Did you attach a large file to the mail? If so, how large?

  21. DigitalDesignET
    March 16th, 2012 at 21:57 | #21

    @Thomas Jespersen

    still no luck, i think the .rar file is the cause

    Google tried to deliver your message, but it was rejected by the recipient domain. We recommend contacting the other email provider for further information about the cause of this error. The error that the other server returned was: 552 552-5.7.0 Our system detected an illegal attachment on your message.

  22. March 16th, 2012 at 21:59 | #22

    Ahh, yes. It sure it.
    Do your .rar file contain any EXE files?
    Could you maybe instead upload it to Rapidshare or similar?

  23. Thierry Alvernhe
    July 20th, 2012 at 10:25 | #23

    Hi Thomas,

    I have problem to synthetize on Spartan 3A too. Do you finally find a solution for this?

  24. July 20th, 2012 at 23:00 | #24

    @Thierry Alvernhe
    Are you using our tutorial and our REPLACE files. If so then yes, there will be a problem synthesizing to both Spartan 3E and 3A devices.
    We are working on a new tutorial for these devices -- please be patient :-)

    Regards Thomas

  25. Thierry Alvernhe
    July 30th, 2012 at 09:09 | #25

    Yes, I’m using your tutorial and your REPLACE files. It was very usefull and I finally succed the synthetisation on Spartan 3A. But now I can’t synthesize an UART module and a FLASH controller module from MSB to ISE.
    Have you an idea of what I have to do?



  26. July 30th, 2012 at 17:32 | #26

    @Thierry Alvernhe
    Dear Thierry.
    You won’t be able to use and synthesize Mico System Builder generated modules because of the pre-existing modules only available in the Lattice software. You would have to make these on your own by changing or re-writing the modules with something that exists in the Xilinx tools.
    Fx the UART module can be found in the Xilinx tools and works almost the same, so you would be able to rewrite that and make it work.

    Regards Thomas

  27. Thierry Alvernhe
    August 9th, 2012 at 15:24 | #27

    ok thank you.
    I use the MIG of ISE to generate a DDR2 SDRAM but I don’t know how to include it in the main module. Can you help me please? My board is the the board of the spartan 3A starter kit.



  28. August 15th, 2012 at 19:41 | #28

    @Thierry Alvernhe
    I’m sorry but we haven’t tried this yet.
    It is a bit difficult to connect MIG modules into the wishbone bus so they would work as expected, especially RAM as it has to be connected for full use, but outside the peripherals scope.

    Please let us know if you manage to implement it with the wishbone. Maybe you should have a look at how a similar SDRAM module would be implemented inside the Mico System Builder.

    Regards Thomas

  29. Thierry Alvernhe
    August 31st, 2012 at 10:18 | #29

    My internship is over but I don’t succed it. Thank you for your help.

    Regards Thierry

  30. October 11th, 2012 at 12:15 | #30


    We are trying to use the uart on the Spartan 6 (ATLYS board). We have already succeeded in making work your tutorial work on the Spartan.

    We are wondering if we will need to have the replacement files for the UART. Could you tell us how to create this file (if it is needed)?

    Best regards,


  31. November 6th, 2012 at 20:17 | #31

    Hi Josep.
    Please read my response to @Thierry Alvernhe who asked almost the same question as you.

    Regards Thom.as

  32. November 13th, 2012 at 10:07 | #32

    @Thomas Jespersen
    We have already solved the UART problem that we had. Thanks for your answer and your tutorial.

    Best regards,


  33. November 13th, 2012 at 18:00 | #33

    So how did you manage to get the UART working.
    Did you implement/make your own module or did you port the original Lattice module?

  34. November 29th, 2012 at 13:48 | #34

    @Thomas Jespersen Give me your email, and I’ll send you the guide I have made.

  35. November 29th, 2012 at 15:32 | #35

    I see you found my mail.
    Thanks for the document, I will read it later and get back to you.

    Regards Thomas

  36. Chris
    November 11th, 2013 at 19:39 | #36

    I am interested in porting the latticemico32 to a non-lattice FPGA. The tutorial pdf link seems to be broken. I would really appreciate it if you could fix the link or send me that doc to help me get started. Also, where did you find the verilog? Thanks!

  37. Salman Sheikh
    November 19th, 2013 at 15:58 | #37

    The link for the Porting to a Xilinx is broken…

  38. Salman Sheikh
    November 19th, 2013 at 20:51 | #38

    Where is the xilinx to coe program?

  39. Salman Sheikh
    December 13th, 2013 at 18:22 | #39

    Isn’t there any way of using dat2mem to just modify the .bit file with the elf file instead of having to regenerate the memory in Coregen every time I create a new software program and resynthesize the design? I have done so with other opensource SoCs like the openmsp430…

  40. Salman Sheikh
    January 17th, 2014 at 16:16 | #40

    Do you have any simulation testbenches of the design? How do you take C code, compile it and run it in a simulator (Modelsim) on the LM32?

  41. January 18th, 2014 at 10:07 | #41

    @Salman Sheikh
    The link should be working again.

    @Salman Sheikh
    The HEX to COE program can be found here: http://www.tkjelectronics.dk/downloads/fpga/lm32/IHEX2COE

  42. January 18th, 2014 at 10:10 | #42

    @Salman Sheikh
    There is a similar way to quickly implement the COE file into the memory of the FPGA without having to resynthesize.
    I haven’t used it yet though, as I decided to implement a JTAG controller instead for easier upgrade.

    @Salman Sheikh
    I have no testbenches sorry. It has simply not been that necessary for me, as I’ve had the hardware with the given access to pins together with a logic analyzer.
    This has seemed to work fine for me.

    Regards Thomas

  43. Salman Sheikh
    January 26th, 2014 at 23:08 | #43

    I got the LM32 ported to an Altera and I create a hex file for the memory but I don’t see any activity on the GPIO for a program that is supposed to write out patterns on the GPIO port….I’m trying to debug with Signaltap but I don’t see any of the values I am writing on the data buses…any ideas of where to look? I don’t want to try to understand every line of verilog code to understand where things are going wrong…

  44. Salman Sheikh
    January 29th, 2014 at 17:26 | #44

    Does anyone know how to generated hex files for Altera so that they are only 32-bits wide?

    I tried

    lm32-elf-objcopy.exe hello.elf -O ihex hello.hex

    but that creates hex files with 16 words per line which Quartus complains that are too wide for the memory I created (32 bits wide)…how would I fix it? Apart from hand editing the hex file?


  45. Salman Sheikh
    January 31st, 2014 at 18:14 | #45

    How does one add debugging capabilities to this port?

  46. Jonathan Kimmitt
    March 19th, 2014 at 22:26 | #46

    I found you can generate a column of hex numbers as required using the following command:

    lm32-elf-objcopy blink.elf /dev/stdout -O srec --srec-len 4 --srec-forceS3 |grep ‘^S3′ |tr ’15′ ‘;’| sed -e ‘s=S309……..\(……..\)..=\1=’ -e ‘s=;==’ > blink.mem

    This can then be written directly to the bitstream (generating a new bitstream) with the following:

    data2mem -bm blockram_bd.bmm -bd blink.mem -bt top_level.bit -o b top_level_new.bit

    blockram_bd.bmm is generated by the xilinx toolchain if you call ngdbuild with the appropriate option e.g. -bm blockram.bmm

    ADDRESS_SPACE bram_block
    RAMB16 [0x00000000:0x0000FFFF]
    instance_name/ebr/block_memory/RAMB16_S1_S1_inst_31 [31:31];
    instance_name/ebr/block_memory/RAMB16_S1_S1_inst_30 [30:30];
    … similar statements cut here …
    instance_name/ebr/block_memory/RAMB16_S1_S1_inst_1 [1:1];
    instance_name/ebr/block_memory/RAMB16_S1_S1_inst_0 [0:0];

  47. Jonathan Kimmitt
    March 19th, 2014 at 22:31 | #47

    P.S. Don’t call your ram memory because this a keyword in the Xilinx bmm flow and does not work. If you change memory to block_memory this is good.

  48. Jonathan Kimmitt
    March 19th, 2014 at 22:34 | #48

    That tr command is
    tr ’15′ ‘;’ is to get rid of nasty DOS line endings. It probably still works without that detail
    not sure how it got corrupted in the previous comment.

  49. Jonathan Kimmitt
    March 19th, 2014 at 22:36 | #49

    The command is supposed to be:

    tr ‘\15′ ‘;’ (tee-arr-space-quote-backslash-zero-one-five-quote-space-quote-semicolon-quote

  50. May 23rd, 2014 at 22:06 | #50

    @Jonathan Kimmitt
    Hi Jonathan.
    Let me try and get your clear. The code you have written and tries to explain is to generate/update the block_memory content of the FPGA bitstream without having to re-synthesize the whole project?

    Would you mind writing these as 1-2-3 steps on how to go from LM32 generated C-code project to Block memory to combine it with existing synthesized project within Xilinx Project Navigator?
    Then we can include in the guide for later use.

    Thank you.

    Regards Thomas

  1. No trackbacks yet.