openrisc / orpsoc-cores

Core description files for FuseSoC
124 stars 79 forks source link

how do I synthesize this in quartus for the de0 nano #86

Open salmansheikh opened 8 years ago

salmansheikh commented 8 years ago

I am trying to add the top level in a quartus project but many hdl files are missing from the core dir that the top level calls out.

olofk commented 8 years ago

Have you installed FuseSoC? That will take care of pulling in all the files, create a Quartus project for you and build the design. Just run 'fusesoc build de0_nano' after you have installed FuseSoC. After that, you can open the Quartus project file (located in build/de0_nano/bld_quartus) if you prefer to work from Quartus

salmansheikh commented 8 years ago

Okay, I did get fusesoc from the git, ran

autconf -i ./configure --prefix=/home/ssheikh And make install.

When I run ~/bin/fusesoc, I get the following (i do have a ~/lib/python2.7 directory created). I am not admin so, is that okay to have them there or should I have him do an install as root?

ssheikh@gs-560g3080090e:~$ ~/bin/fusesoc Traceback (most recent call last): File "/home/ssheikh/bin/fusesoc", line 23, in from fusesoc.build import BackendFactory ImportError: No module named fusesoc.build

salmansheikh commented 8 years ago

Never mind...I set PYTHONPATH=/home/ssheikh/lib/site-packages and fusesoc is cranking on quartus for my de0-nano....too cool if it works!!

salmansheikh commented 8 years ago

I programmed the de0_nano. Now how do I load the program?

In the orpsoc-cores/systems/de0_nano/utils, I see a program called flash-helper.sh

It seems it run a mkimage. Where does that come from? I have a linux 12.04 and don't see it.

Salman

On Thu, Aug 13, 2015 at 7:02 AM, Olof Kindgren notifications@github.com wrote:

Have you installed FuseSoC? That will take care of pulling in all the files, create a Quartus project for you and build the design. Just run 'fusesoc build de0_nano' after you have installed FuseSoC. After that, you can open the Quartus project file (located in build/de0_nano/bld_quartus) if you prefer to work from Quartus

— Reply to this email directly or view it on GitHub https://github.com/openrisc/orpsoc-cores/issues/86#issuecomment-130617645 .

Even a Smile is charity :)

olofk commented 8 years ago

Hi,

Sorry for the late reply. mkimage is part of u-boot.

There are several ways to load a program. Either you can connect via JTAG, write the program to RAM and run it directly from there. In that case I recommend you to read up a bit on openocd. I've also outlined the procedure for another project here https://github.com/myriadrf/STREAM/blob/master/stream_openrisc_soc/doc/quickstart.html The part about openocd should be very similar on the de0 nano

The other way is to put a program into the SPI Flash and boot it from there. In that case flash_helper.sh will help you put together an image and put it into the Flash.

Hope this helps

salmansheikh commented 8 years ago

I am attemping to add another uart to the de0_nano. I modified the orpsoc_top.v in the de0_nano orpsoc-cores/systems but the problem when I try to run fusesoc is there is no signal declaration of wb_2ms_uart1_adr. I saw it in the wb_intercon.v but that file said its autogenerated by web_intercon_gen.

How do I do run that program and where is it?

Salman

Error (10161): Verilog HDL error at orpsoc_top.v(631): object "wb_m2s_uart1_adr" is not declared File: /home/ssheikh/tmp/build/de0_nano/src/de0_nano/rtl/verilog/orpsoc_top.v Line: 631

On Tue, Sep 22, 2015 at 3:13 PM, Olof Kindgren notifications@github.com wrote:

Hi,

Sorry for the late reply. mkimage is part of u-boot.

There are several ways to load a program. Either you can connect via JTAG, write the program to RAM and run it directly from there. In that case I recommend you to read up a bit on openocd. I've also outlined the procedure for another project here https://github.com/myriadrf/STREAM/blob/master/stream_openrisc_soc/doc/quickstart.html The part about openocd should be very similar on the de0 nano

The other way is to put a program into the SPI Flash and boot it from there. In that case flash_helper.sh will help you put together an image and put it into the Flash.

Hope this helps

— Reply to this email directly or view it on GitHub https://github.com/openrisc/orpsoc-cores/issues/86#issuecomment-142389452 .

Even a Smile is charity :)

fjullien commented 8 years ago

Hi,

you can find wb_intercon_gen here: https://github.com/openrisc/orpsoc-cores/blob/master/cores/wb_intercon/sw/wb_intercon_gen

So, in order to add another uart in your system you need to edit your wb_intercon.conf and add your new uart. Then ./wb_intercon_gen wb_intercon.conf wb_intercon.v

If you want quicker help you can join #openrisc on freenode IRC.

Franck.

salmansheikh commented 8 years ago

I did it manually..edited both files by hand...now I need to find some software examples of how to use the 2nd uart. How does software know printf is for the main uart and is the 2nd uart only accessible by writing to it's registers directly?

Salman

On Tue, Sep 29, 2015 at 2:44 AM, Franck Jullien notifications@github.com wrote:

Hi,

you can find wb_intercon_gen here: https://github.com/openrisc/orpsoc-cores/blob/master/cores/wb_intercon/sw/wb_intercon_gen

So, in order to add another uart in your system you need to edit your wb_intercon.conf and add your new uart. Then ./wb_intercon_gen wb_intercon.conf wb_intercon.v

If you want quicker help you can join #openrisc on freenode IRC.

Franck.

— Reply to this email directly or view it on GitHub https://github.com/openrisc/orpsoc-cores/issues/86#issuecomment-143960661 .

Even a Smile is charity :)

olofk commented 8 years ago

Hi Salman,

I assume that you are running a bare-metal program. If you are running an OS, such as Linux, the answer is different

Anyway, the bare-metal toolchain (or1k-elf-) uses newlib, which in turn calls libgloss to carry out the hardware-dependent tasks, such as reading and writing characters from/to a UART. The OpenRISC-specific code for libgloss can be found here https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=tree;f=libgloss/or1k;h=e0fb2ac034c5d238e6ec9c04b73c94b666326673;hb=HEAD

Specifically for the UART, there is or1k_uart.c which handles the low-level functions. It expects to find a UART at base address _or1k_board_uart_base, which in turn is defined in libboard. So to sum it up, a printf in your code calls the printf function in newlib, which calls _write in libgloss, which in turn calls or1k_uart_write

Looking at or1k_uart.c now, I realize that these functions aren't really built to handle additional UARTs. For now, I think your best option would be to copy or1k_uart.[c,h], and make your own version where you can set a base address to your second UART. We should probably make a better fix for this some time

//Olof

salmansheikh commented 8 years ago

Does anyone have a Openrisc fusesoc implementation for the ProASIC3 fpga?

On Thu, Oct 8, 2015 at 9:08 AM, Salman Sheikh salmanisheikh@gmail.com wrote:

Thanks..yes, I got the bare-metal working with uart one..I will attempt direct register writes on uart too..then I may do as you suggest with the copy/new version..

On Thu, Oct 8, 2015 at 6:59 AM, Olof Kindgren notifications@github.com wrote:

Hi Salman,

I assume that you are running a bare-metal program. If you are running an OS, such as Linux, the answer is different

Anyway, the bare-metal toolchain (or1k-elf-) uses newlib, which in turn calls libgloss to carry out the hardware-dependent tasks, such as reading and writing characters from/to a UART. The OpenRISC-specific code for libgloss can be found here https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=tree;f=libgloss/or1k;h=e0fb2ac034c5d238e6ec9c04b73c94b666326673;hb=HEAD

Specifically for the UART, there is or1k_uart.c which handles the low-level functions. It expects to find a UART at base address _or1k_board_uart_base, which in turn is defined in libboard. So to sum it up, a printf in your code calls the printf function in newlib, which calls _write in libgloss, which in turn calls or1k_uart_write

Looking at or1k_uart.c now, I realize that these functions aren't really built to handle additional UARTs. For now, I think your best option would be to copy or1k_uart.[c,h], and make your own version where you can set a base address to your second UART. We should probably make a better fix for this some time

//Olof

— Reply to this email directly or view it on GitHub https://github.com/openrisc/orpsoc-cores/issues/86#issuecomment-146504518 .

Even a Smile is charity :)

  • Prophet Muhammad

Even a Smile is charity :)

zavax2005 commented 7 years ago

Hi Olof

Trying to use flash_helper.sh and de0_nano.cof to merge the FPGA configuration and application firmware into one image (did I understand correct?), and then use quartus_pgm to upload the generated .jic file to EPCS flash.

However, I noticed the HEX_OFFSET in the de0_nano.cof is 524288. Is it true that this offset should be >= sof size + sof starting address to avoid overlap. If the sof file I generated with Fusesoc is 709373, shall I increase the HEX_OFFSET to be greater than 709373?

Thanks, -Xueming

olofk commented 7 years ago

hmm.. good question. I'm not completely sure, but I think that the sof file is compressed somehow. Looking at https://www.altera.com/en_US/pdfs/literature/hb/cyclone-iv/cyiv-51008.pdf page 4, the sof size is larger than 524288, so you could perhaps increase the offset to be sure, but it has always worked for me to put it at the original offset.

Note however that if you change this offset, you will also need to tell the boot loader to look for the program at the new address. You can do this by entering ~/.local/share/orpsoc-cores/systems/de0_nano/sw and run BOOTROM_ADDR=0x100000 make to create a new boot ROM that will search at address 0x100000 (=1048576 = 524288*2)

zavax2005 commented 7 years ago

Hi Olof

I tried both 0x80000 and 0x100000 per your reply, but neither worked after I uploaded the jic file onto the board.

What makes me confuse here is some older tutorials I found online, in which a "bin2binsizeword" program is called to replace the first word of application image with the the size of itself. However I didn't that step in your "flash_helper.sh". Is it obsoleted?

Thanks, -Xueming

olofk commented 7 years ago

bin2binsizeword is obsoleted. It was an old, very simple image format that just used the first word to indicate the size of the image. I figured it was better to use an existing format instead and chose therefore uImage, which is the same format as uBoot is using. The spi_uimage_loader (which I assume you are using as the bootrom) expects the application image to use the uImage format. At this point it's hard to tell what could be wrong. The bootloader doesn't provide any visible clues about what is going on.

Some ideas for further investigation

zavax2005 commented 7 years ago

Hi Olof

Still struggling to compile a functional .jic file, but no luck so far. However the .jic file you provided works on my board. I'll try to debug more following your suggestion.

I have some questions after briefly reading through the source codes. Please correct me if I am wrong:

According to sw/spi_uimage_loader.S on the line

define SPI_BASE 0xB0000000

and after search 0xB0000000 from data/wb_intercon.conf, 0xB0000000 is the offset of spi0

[slave spi0] datawidth=8 offset=0xb0000000 size=8

So the flash chip (EPCS64) is wired to spi0, and looks like this could be verified from the pin map and de0_nano schematic. PIN_H2/C1/H1/D2

However, in rtl/verilog/orpsoc_top.v, I found two lines of codes causing my confusion:

or1200_top #(.boot_adr(32'hf0000000)) ... ... .OPTION_RESET_PC(32'hf0000000)

why is the boot address pointing to 0xf0000000 instead of 0xb0000000 where the spi0 locates? If I understand correctly, 0xf0000000 seems to be the offset of rom0:

[slave rom0] offset=0xf0000000 size=1024

But I couldn't find any implementation of rom0 either in source code or in the pin map. I might be complete wrong... they are two different things....

And my theory is when the FPGA gets power-on or reset, it turn to 0xf0000000 for bootrom. If 0xf0000000 were pointing to the spi0, then the FPGA configuration would be loaded from the first part of image in the flash chip through spi0, followed by the application firmware in the second part of the image being loaded by the bootloader. But I am lost here why it is 0xf0000000, what's the connection between 0xf0000000 and 0xb0000000? It is not very likely, but does it explain that my board couldn't boot because the configured FPGA turns to wrong address for the application firemware?

Thanks again for your help. -Xueming

olofk commented 7 years ago

Still struggling to compile a functional .jic file, but no luck so far. However the .jic file you provided works on my board. I'll try to debug more following your suggestion.

At least we're closing in on the error :)

So the flash chip (EPCS64) is wired to spi0, and looks like this could be verified from the pin map and de0_nano schematic. PIN_H2/C1/H1/D2

Yes, this is correct

But I couldn't find any implementation of rom0 either in source code or in the pin map. I might be complete wrong... they are two different things....

The boot ROM doesn't have any external connections. It's just a small memory that sits on the instruction bus so that mor1kx can read the instructions stored there. https://github.com/openrisc/orpsoc-cores/blob/master/systems/de0_nano/rtl/verilog/orpsoc_top.v#L486 is where you would find the instatiation of the boot ROM.

And my theory is when the FPGA gets power-on or reset, it turn to 0xf0000000 for bootrom. If 0xf0000000 were pointing to the spi0, then the FPGA configuration would be loaded from the first part of image in the flash chip through spi0, followed by the application firmware in the second part of the image being loaded by the uBoot. But I am lost here why it is 0xf0000000, what's the connection between 0xf0000000 and 0xb0000000? It is not very likely, but does it explain that my board couldn't boot because the chip turns to wrong address in the beginning?

The FPGA will automatically load the FPGA configuration from address 0 of the SPI Flash. As the FPGA is empty on power-on it must be able to do this by itself when it is empty.

Once it's loaded and the reset is released, the system is set up to always start reading it's first instructions from the boot ROM at 0xf0000000 (that's what the OPTION_RESET_PC means). You can't read instructions directly from the SPI Flash, since you need to do a a bit more to get data out from the SPI Flash. First you need to set the SPI Flash in read mode, and then you run a SPI transaction for every byte you want to read. So what happens is that the boot rom at 0xf0000000 contains a small program (if you use the spi_uimage_loader) to read out data byte by byte from the SPI Flash and copy those to the on-board RAM. After the whole program is read from Flash, it will then jump to address 0x100 where it will find the first instruction of the program that was loaded from Flash. The bootloader needs to know at which address the SPI controller is located (0xb0000000) in order to read the data from the SPI Flash

There are a few things that might be the problem now.

  1. Your FPGA image might not work correctly. Have you made any changes to the code? Are you using the latest version of orpsoc-cores? Could you verify that bootrom_file is set to spi_uimage_loader by reading build/de0_nano/bld-quartus/de0_nano.map.rpt and see that it says bootrom_file ; ../src/de0_nano_0/sw/spi_uimage_loader.vh somewhere in that file? If everything looks ok, I can generate an image and send to you, but I don't have access to my own board for a while, so I wouldn't be able to guarantee that I'm sending you a working image.
  2. The FPGA image works, but for some reason the .jic isn't properly created. Not sure what to do about that, so I really hope this isn't the problem
zavax2005 commented 7 years ago

Hi Olof

Found from the de0_nano.map.rpt that:

; bootrom_file ; ../src/de0_nano/sw/spi_uimage_loader.vh ; String ;

I believe I did use the spi_uimage_loader.vh for the build.

Th FPGA image was generated on a brand new cache of orpsoc-core as I cleared the ~/.local/share/orpsoc folder and re-initialized the fusesoc before building. I think the cores should have been downloaded freshly by the fusesoc, right?

It would be extremely helpful if you can generate an image for me to test on my board, could be a good reference whether or or not I should inspect problem No.2.....

Thanks again for your explanation of the boot ROM. So the boot ROM is some memory allocation on the FPGA silicon that stores the bootloader program (spi_uimage_loader.vh in my case.). It is assigned with address 0xf0000000, which FPGA will turn to to find out what to do next after it is configured? Then, after the FPGA is done whatever is in the boot ROM section, it will let the CPU start executing from 0x100 from the SDRAM?

A good test could be, actually you already suggested, to replace the spi_uimage_loader.vh with some LED blinking program, like this one. If the LED doesn't blink, then it is very likely the FPGA is not properly configured, or the .jic is not correctly generated?

Thanks, -Xueming

olofk commented 7 years ago

Hi Xueming,

Sorry for the late reply.

Here's a sof file that I have created. https://www.dropbox.com/s/hyms72zj1m5f4r0/de0_nano.sof?dl=0 Please note that I haven't tested it though, since I don't have access to my board.

Your thoughts are all correct, and using the led blinker as a boot ROM would give us info if the boot loader is executing correctly. You can do this by running fusesoc build de0_nano --bootrom_file=/path/to/led_blink.vh (it should be in ~/.cache/fusesoc/or1k_bootloaders-0.9/led_blink.vh)

zavax2005 commented 7 years ago

Thanks again, Olof, for sending the sof file. Here are some updates from my side.:

  1. Your soffile + led_blink.vh as bootrom file worked! And I could get my compiled sof+ led_blink.vhwork as well! Indeed, some progress :+1: Then, I changed the code of led_blink.S, and recompiled everything, the de0_nano board's behavior reflected my change!
  2. Your soffile + spi_uimage_bootloader.vh+ a uimage of elf program didn't work. And my version didn't work either......
  3. I inserted a whole bunch of LED counter codes along each steps of the spi_uimage_bootloader.S, and looks like the bootloader didn't hang anywhere, it finished all the way through...

At this point, I think the FPGA image (including the bootrom) is working correctly. Now the problem seems to be:

  1. spi_uimage_bootloader.S is not correct? Can you please take a look at line#106~117 of spi_uimage_bootloader.S, where I feel like l.jal spi_xfer should be added after #117, otherwise A0 on #117 won't be sent out at all? Also, #107 doesn't seem to be necessary? However, it still didn't work after I "corrected" the code like above ....Ugh.... I'll do more tests later.
  2. the ihex format image of elf firmware is not correctly converted? The flash_help.sh takes in sof and bin file. I didn't find any anywhere officially explaining how to generate bin file, but I guess this step is: or1k-elf-objcopy -O binary sw.elf sw.bin is this correct? And then run the sw.bin through mkimage according to the flash_helper.sh: mkimage \ -A or1k \ -C none \ -T standalone \ -a 0x00000000 \ -e 0x00000100 \ -n "Some fancy software" \ -d sw.bin \ sw.ub Finally, convert the image to ihex format: or1k-elf-objcopy -I binary -O ihex sw.ub sw.hex I noticed that one the line#52 of spi_uimage_bootloader.S, you start reading the image with an offset 0xC. Is there any reference I can read regarding the format of uimage? And what does mkimage do to the original image binary file?
  3. de0_nano.cof is not correctly generating the jic file? Not very likely as we have discussed some issues in another earlier. Shall I use big-endian or little-endian for the hex data when generating jic file? I used big-endian.

Sorry for the long reply. And I appreciate your help very much! -Xueming

zavax2005 commented 7 years ago

Hi Olof

Please ignore my Q1 as your code is correct. Just ran a test to output the "Image Magic Number" from U-Boot image on LED indicators, and it showed 0x27051956, which matches the U-Boot header definition.

zavax2005 commented 7 years ago

Hi Olof

Finally I had my build working on the board now!! I haven't completely nailed down the causes behind this, but it looks like all my issues were caused by Linux vs. Windows version of Altera Quartus software. And this is what I did:

I copied the whole folder, which was generated by the fusesoc, and was never successfully compiled to run on the de0_nano board, from Linux to a Windows computer. Compiled again with Windows version Quartus 16, converted to jic with a uimage, downloaded into the on-board flash, and it worked!

Some observation:

  1. Compilation report shows the Linux build of FPGA is using slightly more Logic Elements than Windows. ( I guess they should be exactly the same, right?) Did you also build yours on Linux? The one you provided through dropbox seems to have the same issue as mine....
  2. In order to find out why the build from Linux computer doesn't work, I tested all the way to inspect the SDRAM contents, in which I used OpenOCD/GDB to print out the binary code in the RAM. And I found that, when the FPGA is configured with Linux-built version, there are random errors from their original compiled file (.bin/.hex file) on computer. Here is the screen shot illustrating the binary discrepancy. My guess is the CPU got lost when it read those wrong instructions..... Is it possible? Have you ever heard those issues?

Thanks again for your time. -Xueming

olofk commented 7 years ago

Hi Xueming,

Sorry again for the late reply, but excellent news that you got things working, even if not everything is perfect yet. Some notes

  1. Regarding the asm instructions in spi_uimage_bootloader.S, remember that OpenRISC uses branch delay slots, so that the instruction after a jump instruction is actually executed before the jump. That's why the order of instructions look backwards.
  2. The Linux/windows issues sound strange. Are you sure you're using the same version of Quartus on both platforms? I've only been using Linux, but I haven't had any similar problems. One thing that could explain both the slight difference in logic as well as the memory read errors would be if there are some difference in the the timing constraints. For example if one of the platforms fails to pick up the constraint files properly. Would be good if you could check that. Let me know if you need more assistance
zavax2005 commented 7 years ago

Thanks again Olof for all your help. I'll keep you updated once I figured anything regarding the Linux/Windows issues, but so far I still don't know why.

So I've moved on to adding a custom core to the CPU. Where is the best place for me to ask questions regarding this? I'm pretty I'll have a lot of questions.

Best, -Xueming

olofk commented 7 years ago

Good question. I think the openrisc mailing list might be the best place. You can register at https://lists.librecores.org/listinfo/openrisc