Question

Dear Digilent,

I have a simple design on a BASYS3, which contains a MICROBLAZE, a LED and two PUSH BUTTONS.

I can control how fast the LED is blinking by pressing the PUSH BUTTONS.

 

The BITSTREAM of that design is stored in a non-volatile serial Flash device, which is attached to the ARTIX-7 FPGA using a dedicated quad-mode (x4) SPI bus. When the system starts, the contents of the flash memory are read and the FPGA is configured normally.

 

I would like to be able to memorize the latest configuration of the PUSH BUTTONS in a non-volatile memory, so that the system at startup can use that configuration.

In other words, I would like to allow the user, the option to write in a non-volatile memory, the latest configuration of the push buttons, without having to change the BITSTREAM all the time.

Something likes partitioning non-volatile memory into two sections:

1-      One section will be to store the BITSTREAM for configuration during system startup.

2-       The other section will be to allow the user to read, modify (write) and save parameters for the next startup.

Is it possible to do this with the BASYS3?
If so, could you please advise me how to do it?

If not, what kind of system would be needed to achieve this?

Thank you in advance for any suggestions and advices.

Regards,

H

Share this post


Link to post
Share on other sites

5 answers to this question

Recommended Posts

  • 0

@herve,

Yeah, I think I can help out a touch:

  1. You can find a fairly generic quad SPI device controller in this repo on OpenCores.  I modified it to be a SPI controller for my xulalx25soc project.  You should be able to meld the two, although you'll see more than the relevant differences when comparing them.
  2. You can find an example of the software controller I use for this device controller in both the xulalx25soc project, as well as the zbasic basic ZipCPU project.
  3. You will want to copy this software controller logic into the internals of your project in order to read/erase/program the flash from your device without an external command.  Alternatively, the specification in the doc directory of the OpenCores repo tells you how the logic is to be accessed.
  4. Each of these projects also includes the QuadSPI flash simulator--this simulator should work for a SPI flash as well as a QSPI flash.  Look at the xulalx25soc main simulation driver file to see how the simulation can be hooked up.
  5. The other thing I would recommend is that you use some form of internal scope to see what is going on within your design.  I personally use a wishbone scope.  Scope your interaction, see what's actually taking place.  Since the wishbone scope requires a wishbone bus, all of my designs have some means of converting whatever way I have of controlling them into bus commands.  Often this is via a UART, although the xulalx25soc design uses a JTAG port.  You can see an overview diagram and discussion of what I use here.  You might find by doing so that your logic isn't doing what you think it's doing.
  6. I do have a drastically simplified read-only flash controller that runs at double the speed, but ... since you want read/write capability, that driver wouldn't work here.

Keep me posted on your progress, though, I'd love to hear about your success!

Dan

Share this post


Link to post
Share on other sites
  • 0

@herve,

Is this possible?  Yes.  Doing it will be a touch of a challenge, but it is possible.

A couple things you will need to know before starting: 1) "ERASE"ing a flash turns bits from zero's to ones.  This is a long operation (2 secs, according to spec) that can only be applied to sectors.  2) "PROGRAM"ing (i.e. writing) the flash turns bits from ones to zero's.  This can be done 256 bytes at a time, never less.  While not as long as the erase, programming can still take 3ms or so to do.  During either of these operations, you will need to make certain that 1) you do not access the flash to do anything else, and 2) that you do not pull power suddenly from the device.  Pulling power from the device can result in uncertain values within the flash (i.e. unpredictable values, that can change from one read to the next).  This has been a common problem with modern solid state devices, and one of the reasons why you should always "safely remove" any thumb drives from your computer, rather than just yanking them.  But I digress.

I'm also going to assume you meant that you were going to do this with the switches on the Basys3--and not the buttons.  (I have no idea how you would physically hold the buttons on your board to accomplish this task in any reasonable manner, switches make more sense.)

Given that background, perhaps I can outline how I would go about such a task?

I would start by allocating a section of flash for this purpose.  Perhaps you'll want to grab the last sector of the flash.  Erase this sector before starting.  (This takes between 0.5 and 2 seconds to do)  Then, any time the switches's change, write the new value to a new location in flash.  For example, data[0] would be initially set to all ones.  When I wish to write a new value to it, I might write '0' to one of the bits (signifying this value is valid), and the switch state to the other bits.  When the switch changes, I'd write the new state to data[1].  When you wish to discover the last button state, read through all of the data values to find the first all ones value.  The value before this should then be the last state.

As for how to do this with MicroBlaze, I wouldn't know.  I've always used my own flash controller, and used that with the ZipCPU, rather than MicroBlaze.

Dan

@jpeyron (or other Digilent staff member),

This post really belongs in the FPGA forum, and not the microcontroller (PIC) forum.  If you'd be so kind ...

Thanks!

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi Dan,

I do not know if I should continue to interact with you on this forum or should I continue on the FPGA forum?

Anyway, I have recently purchased a Digilent PmodSF and I started to write a verilog module to interact with that memory. I successfully implemented the read identification command based on the Micron M25P16 datasheet and was able to read the manufacturer and device IDs (0x2020 15).

I also implemented two other modules based on Micron M25P16 data sheet ("write enable" and "read status register"). However, after executing the "write enable" command, the output of the "read status status" was all the time null, ie 8'b0000_0000 instead of 8'b0000_0010. I'm stuck at this level, because if the "write enable" command is not able to set the "write enable latch" bit to 1, I could not write or program the memory.

Could you please provide me a template that I could use to quickly verify that memory? I am working with a Spartan 6, Basys3 and zynq FPGAs.

The only design that I found in VHDL is based on a Nexys3 and it requires a USB controller port on the host board. Unfortunately none of my boards have that port.

https://reference.digilentinc.com/reference/pmod/pmodsf/start#example_projects

Do you have any idea and/or suggestion how to bypass that usb controller in order to directly interact with the memory?

Thank you in advance for your help!

Regards,

H

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now