• Content count

  • Joined

  • Last visited

  • Days Won


D@n last won the day on October 22

D@n had the most liked content!

About D@n

  • Rank
    Prolific Poster

Contact Methods

  • Website URL

Profile Information

  • Gender
    Not Telling
  • Interests
    Building a resource efficient CPU, the ZipCPU!
  1. Reading and writing to QSPI on the CMOD A7

    @David1234, If your goal is to have persistent memory, the flash is usually the way to go. While it is possible to use an SD card for the same thing, SD cards take a lot of interaction with their host just to set up. Your other alternative would be to send information from the host (i.e. your PC) to the FPGA. If you have to write flash, there is one thing you *must* ensure, and that is that power cannot be removed from the flash mid-erase or mid-write operation. The problem is that, if power gets pulled, the flash may act right and it may not act right with a random probability. It may act right once, and then not the next time, etc. This has been a thorn in the side of those making flash-based devices, such as thumb drives. The software can come through checking CRC's, and sectors 1-N might pass, so software may declare those sectors good--only to have one of them not-pass later. The same would be true of an SD-card--don't pull power mid-write. The other (easier/simpler) alternative would be to pass the device its configuration from a host machine upon startup. Of course ... that only works if your device will be running in a situation where that's possible. In this case, you'd need to pick some sort of protocol to pass this information along. There are lots of possibilities, I guess. Pick the one that's right for you. Dan
  2. Stupid Q: What does a loop in a HDL really mean?

    @Tickstart, Gosh, you want examples? Let's see ... I've used loops in FIR filters to describe the logic required at each tap. I've used them within CORDIC's to describe the logic that neeeds to take place in a multi-stage algorithm. I've used them to apply the same I/O logic to multiple bits in a vector. I've used them in loops to bit-reverse vectors. I've used them within my differential pmod-challenge code to look for bit-sync across multiple synchronization possibilities. I've used them to check for the synchronization sequence within an HDMI stream, knowing it could come in at any time and in any offset. I've used loops within initial statements, to initialize any memory that wasn't initialized by my $readmemh command. Dan
  3. Stupid Q: What does a loop in a HDL really mean?

    @Tickstart, Yes. Loops in HDL just generate more logic, not sequential logic. Remember: *everything* runs in parallel. "Sequential" loops in HDL have only the appearance of being sequential--they actually just describe logic. If you can't fit the logic within one clock cycle, then you will fail to meet your timing constraints. Dan
  4. Reading and writing to QSPI on the CMOD A7

    David, eqspiflash.v would be the top-level flash component. I suspect you will have other components within your design. You may need to instantiate the STARTUPE2 primitive to get access to the output clock. Since it's shared between Xilinx's load logic, you need to do a little extra work to control it. To request a transaction with the core, set (i_wb_cyc)&&(i_wb_stb). You'll also want to set the address (zero is the beginning of the flash). If you wish to write to the core, set (i_wb_we) and the data you wish to write. The core will control the (o_wb_stall) flag. When (i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall), a transaction request has been accepted. Drop the i_wb_stb line on the next clock, lest you request multiple transactions when you only want one. (Or keep it raised, and just set the next address ...) The core will respond to your transaction request (eventually) by setting the o_wb_data and o_wb_ack lines. At that time, any read data is ready. You can drop i_wb_cyc after you get the ack from your last request. If you drop i_wb_cyc early, the ack will be suppressed. You can find an example wishbone master here, or a discussion of how to build one here. If this is still confusing, check out Fig's 3-6, 3-8, 3-11, and 3-13 of the wishbone spec, version B4. This core, as with all of my cores, uses the pipelined version of the spec. Remember, this is a flash: reading is easy. Writing is harder. There are two steps to any write to a flash. The first is to set any '0' bits to '1's. This is called erasing. You can erase sectors or subsectors, but sadly you cannot erase pages, words, or even bytes. Erases are therefore rather heavy handed. To command an erase, (check the doc's within the core) you'll write to the write protect word in the controller to turn off write protection. You'll then write to this word (again) with the erase command and the address of the area you wish to erase. The flash device will then go out to lunch for many ms (I think the spec says up to 3s), to do this erase. During this time, you can read from the status register of the core to know if it is done or not. Alternatively, once the erase is complete the core will raise an interrupt flag so you can tell it's ready to be used again. The core will turn the write protect flag back on when it is done. That's erasing. The second step to writing. This is the step that you use to turn '1's to '0's. The flash specification calls this "programming". To program a device with this core, first write to the control register to turn off the write protect bit. You can then write to a "page" containing 256 bytes. Do as instructed in the steps above, but also ... write consecutively from one value on the page to the next. The core, and indeed the flash itself, can't handle writes that jump around on the page. Second, keep the i_wb_cyc line high. Once that line goes low, your page write request will be complete, and the device will go off and write. Expect this to take several ms as well. As before, you can either read the status register from the core to know if/when it is done, or you can wait for the interrupt line to go high. If you've never worked with flash memory before .... <grin> it's not like regular memory. Hopefully you understand that by now. While you can treat reading from a flash device like reading from a slow ROM, writing to the device is much harder--so hard that most applications just treat the device like a ROM. Still, it's good for storing configuration data within it. Hope this helps, Dan
  5. Reading and writing to QSPI on the CMOD A7

    @David1234, I use the QSPI flash controller found here on opencores. I've used this in almost all of my Digilent projects. Here's a generic example project using this controller, to include a software controller that I use for programming the flash. An SD-Card controller will not work. The SD card controller uses a single wire for a bi-directional command control, and then four data lines. The four data lines are always inputs, or always outputs, based upon the command given over the bi-directional command wire. QSPI flash is completely different--there are only four data wires. Unlike SD, there's no extra command wire. Further, you have to carefully control when you are in four wire mode and when you are in standard SPI mode. Dan
  6. Clock/PLL for Cmod - A7?[SOLVED]

    @bmentink, Good catch! I was about to punt and hope someone else could solve your problem! Dan
  7. Clock/PLL for Cmod - A7?[SOLVED]

    @bmentink, What does your XDC file say about your clock? Dan
  8. Clock/PLL for Cmod - A7?[SOLVED]

    @bmentink, Ok, you got me on that one .... I was about to coach you in how to generate *any* frequency rate you needed with just a PLL and a little work, but then I checked the Artix-7 data sheet and you are right: the minimum clock speed going into the PLL is 19MHz. Ouch. I don't have an example that works in this case. However .... the minimum speed going into the MMCM is 10MHz. Further, Xilinx declares that the only difference between the two, on series-7 devices, is that the MMCM has more features. See if the MMCM will work for you. By the way, if you aren't using the wizards, you may want to get familiar with the libraries guide. That'll list all the *special* primitives Xilinx offers. It should also list the manuals where the details of the components are explained. Dan
  9. Artix-A7 non-GUI development

    @bmentink, I use Linux regularly. There should be three tarballs. Take another look to find the utilities tarball. Dan
  10. One-hot encoding mystery

    @Tickstart, I'm going to bow out at that question--I'm not familiar enough with VHDL to answer. Perhaps @hamster can come back and answer better than I. Dan
  11. Artix-A7 non-GUI development

    @bmentink, Did you download the runtime, the utilities, and the SDK? (I think the files are in the utilities, but I can't' remember ... chances are @jpeyron will answer that question in the morning.) Dan
  12. One-hot encoding mystery

    @Tickstart, Yes, latches are bad. Only transition your logic on the positive edge of the clock and you'll avoid latches. I may be strange in how I do state machines. I tend not to do them via a combinatorial process calculating the next step. Rather, I've been known to calculate the next state directly within my clocked process. It might not match the text book, but it's just as legal and I find it's easier to read. Dan
  13. Artix-A7 non-GUI development

    @bmentink, If I recall correctly, djtgcfg is part of the Adept2 utilities. A 32-bit forth CPU? I've seen 8-bit forth CPU's. A 32-bit forth CPU almost sounds ... relevant. Dan
  14. One-hot encoding mystery

    @Tickstart, S2+ = I && (!S0) This all makes sense, so ... the logic you are creating may just be due to the nature of the problem you've chosen. I remember the last time I tried doing a one-hot encoding, it didn't make sense in the end since I still needed complex combinations of the state wires to determine the output. Dan
  15. One-hot encoding mystery

    @Tickstart, Sure it's legal: replace S0+ and S1+ above with their respective formulas and you then have a formula for S2+ that doesn't depend upon S0+ or S1+. Further, since S2 is dependent upon S0 and S1 only, that formula should require only S0, S1, and I. Dan