Jaxartes

Members
  • Content count

    80
  • Joined

  • Last visited

  • Days Won

    4

Community Reputation

7 Neutral

About Jaxartes

  • Rank
    Advanced Member

Profile Information

  • Gender Not Telling
  1. Regarding video timings, the pixel rate is generally higher than the calculation of refresh*horizontal*vertical, due to periods that no pixels are being transferred. For the most common 640x480x60Hz resolution, it's 40ns per pixel instead of 54ns. http://tinyvga.com/vga-timing has more detail. One way to stretch that time is to buffer part of the screen in the FPGA's own on-chip memory. If you read and buffer one scan line at a time, you can get it to 50ns per byte, using only 640 bytes of buffer memory. (Calcuation: 640 pixels in a scan line, one byte per pixel, a buffer to hold one scan line is 640 bytes; in the standard 640x480 screen, a scan line takes 32us; 32us/640=50ns.) If you can reduce the amount of memory your screen image takes up, you might be able to fit it entirely onto the FPGA without any off-FPGA RAM. That gives you a number of benefits: It's easy to work with, it's fast, and (at least on the ones I've used) it's dual-ported. The downside is that capacity is limited (it depends on the particular FPGA). But you may be able to reduce how much you need, using techniques from back when computers' memory was much smaller: Fewer bits per pixel; text mode / tile mapped graphics. (For example, 1024x768x8bpp would be 768kB, but https://github.com/Jaxartes/fpga_robots_game/ gets 1024x768 resolution with only 12kB RAM for video.)
  2. The "FPGA reset" pin resets this FPGA itself. So maybe the Xilinx software doesn't let you use that pin. There wouldn't be any purpose in using it, since your logic wouldn't be running while the FPGA is being reset. So you'd need to find an alternative. Some that come to mind: If you've got a shield board plugged into the Papilio DUO, and that shield board has one or more buttons, you can use one of the buttons as your reset. There's a slide switch on P104. If you're not using it for anything else, you could use it as a reset. It's a little inconvenient to use a slide switch for that, because you'd have to move the switch twice (once to reset, and once to stop resetting). It's also possible to write some logic that processes the switch state, so that every movement of the slide switch generates a reset. It's not trivial but it's fairly simple. The easiest way for me to describe the logic is to write it in Verilog; here goes: module reset_finder(input clk, input slide_switch, output switch_moved); reg slide_switch_delayed = 1'd0; always @(posedge clk) slide_switch_delayed <= slide_switch; assign switch_moved = slide_switch != slide_switch_delayed; endmodule
  3. I believe that's the wrong pin [in reference to a question about the clock input, and pin P55, that has been edited out I think]. The Papilio DUO generic UCF file has the following: NET CLK LOC="P94" | IOSTANDARD=LVTTL; TIMESPEC TS_Period_1 = PERIOD "CLK" 31.25 ns HIGH 50%; See also http://forum.gadgetfactory.net/index.php?/files/file/235-papilio-duo-generic-ucf/. P55 seems to be one of the external pins on the board. Generally finding out what pins map to what, I rely on the published UCF files from this site, and then if there's a confusion I refer to the schematic. Note that there is more than one set of pin numbers (FPGA, and board) and more than one kind of thing termed "clock" (SPI bus clock signal for example). I don't see the references that identify P55 as clock or P38 as reset.
  4. The "snake" game from a few months ago inspired me to do something similar for the classic "robots" game (turned out, much more work than I'd anticipated!). It's implemented in Verilog on the Papilio Pro with the Papilio Arcade, but should be portable to other FPGA platforms with comparable basic capacity. I don't know if it would work on Papilio One; it uses a relatively small fraction of the on-chip resources but the timing margin is a kind of narrow. Source code repository at: https://github.com/Jaxartes/fpga_robots_game It displays in 1024x768 on a VGA monitor, and is controlled by keyboard. Or, it can be controlled from the serial port for those without a PS/2 keyboard hooked up. There's a one-minute demonstration video:
  5. Some miscellaneous tips; know that I'm not very advanced at this (I've been doing FPGA designs for two years, but only as a Saturday afternoon hobby). Using logic output as a clock is not recommended on FPGAs. I'm not up on what can go wrong with it, but I believe the routing for the two kinds of signals is different. Glitches (false edges produced by the logic) might be a problem too. Two alternatives are: Use one of the on-chip PLLs to convert the 32MHz clock to another speed (but 10Hz might be way out of its range). Use the higher speed clock (32MHz) and control the speed of your logic by applying a "clock enable" signal to every flip-flop. The clock enable is a synchronous signal, with 10 pulses per second, 1 clock cycle per pulse. That's is what I'd recommend here. Net names have to get mapped to the pins on the FPGA. Generally the constraints file (which in ISE is a UCF file) controls this. If your constraints file is missing or absent or ISE is not set to use it, you might have problems. (I don't know what exact problems they are.) You can find out what pin is used for what. It's in the GUI as "Pinout Report", or in a file named projectname_pad.txt. The first two columns are pin number and net name. Look for warning messages from the build tools. These give so very many warnings that it's a nuisance, and I often ignore them, but when something stops working, they might tell you something. The GUI can show them to you, or they appear in various output files. Some filename suffixes are: .syr, .par, .map, .bgn, .drc. ISE contains a simulator. If you can get that to work, it could show you what's going on inside your design. I haven't used it, so can't give many pointers, except I think you probably want to not use the 10Hz divided-down clock with it, it'll take too much time.
  6. .xise files are supposed to be opened by Xilinx's ISE toolkit. They're not PDF files, but for some reason it looks like your Windows system thinks Adobe Reader is supposed to open them anyway. Maybe ISE is not installed right or something. I wouldn't know why, I don't use Windows much. Operating systems trying to figure out what application to use to open a given file sometimes get it wrong.
  7. It may be possible to have a logic analyzer on the FPGA, and connect it only internally. Regarding what a wrong wishbone slot might do: No, there are ways it could turn out badly: If the register it's writing to controls the serial port: Then you might lose connectivity. And it might appear like a lockup, even though your code is running ok, it can't communicate. If there is no device responding to that address, not even enough to do an ACK: Then it would wait forever. I think ZPUino has something to prevent this, but I don't really know. A few more debugging ideas: Put short temporary debug prints in the sections of code you want to watch. You can see with more precision where exactly it's getting stuck. It might not be where you think it is. I'd use single characters. In place of the LEDs suggested above, use audio output as an indicator: Superimpose a particular sound on top, to indicate a particular state. It has its own difficulties -- it's not the simple on-off of LEDs, and you can't hear a 48MHz square wave (and probably wouldn't want to - ouch!). But if audio's what interests you, and what you have, you can use it.
  8. Some thoughts on debugging: I'm not aware of any general FPGA "debuggers" but I wouldn't necessarily know. (And I'm not a big fan of "debugger" tools anyway -- I often don't use them when I debug software.) Debugging is a real important thing when working with FPGAs. I recommend developing a wide variety of techniques, and patiently applying those techniques to the problem. One thing you can do is add output signals derived from whatever you want to monitor. So if you have a pair of LEDs unused, you could light one up when in a particular bus state, and light the other up when not in that particular bus state. When you get it running, if the "yes" LED is lit, and the "no" LED is not, then it's perhaps stuck in that bus state. If the "no" LED is lit, and the "yes" is not, then it's probably stuck in some other bus state. If both are lit, it's not stuck in any one bus state (but may be stuck in a cycle of them). Each time you do this, you might (or might not) get some information. Repeated several times, monitoring for different states, might get you somewhere. (Like: what's it doing? writing to an address. is it the device address? no. what address is it? the wrong address.) Make sure you got the right wishbone slot. If the one in your C++ code (6) doesn't match the one in your circuit, then you might be writing to some other device's registers, which could have unpredictable and dire consequences, such as causing a lockup (or causing a loss of communication). A "logic analyzer" tool exists in DesignLab, though I don't know much about it.
  9. Re mixing Verilog and VHDL: Yes, it can be done. I think it's not very difficult. Re Wishbone bus: It looks like both sides are using the Wishbone bus. The signal names are different, a few signals are missing from one or the other, and it's possible there are semantic differences between signals with similar names. I'd recommend looking at the wbfmtx page at OpenCores for some documentation of its Wishbone interface. Like maybe this one here: http://opencores.org/websvn,filedetails?repname=wbfmtx&path=%2Fwbfmtx%2Ftrunk%2Fdoc%2Fspec.pdf. (E.g. it says o_wb_stall is always set to zero) Also the Wishbone bus specification is worth looking at. That can be found at OpenCores too. Overall: I recommend trying a less ambitious project. Interfacing two complex cores together is tricky. Writing your own Wishbone core and interfacing to that, might be a good "warm up" exercise. When I was in a similar situation, I ended up writing a small Wishbone "timer" device. The advantage of a timer is it has easy to understand and investigate behavior, and it has no external interfacing other than the Wishbone bus.
  10. The "papilio-prog" command line tool displays the device DNA when I use it to load a bitfile on a Papilio Pro (Spartan6). Source code is in the "papilio_prog" subdirectory of https://github.com/GadgetFactory/Papilio-Loader. Example (underlining added): user@host:~ $ sudo ~/bin/papilio-prog -vf fpga_robots_game.bit Using built-in device list JTAG chainpos: 0 Device IDCODE = 0x24001093 Desc: XC6SLX9 Created from NCD file: fpga_robots_game.ncd;UserID=0xFFFFFFFF Target device: 6slx9tqg144 Created: 2016/06/25 15:02:07 Bitstream length: 2724832 bits Uploading "fpga_robots_game.bit". DNA is 0x59aa4afe43849eff Done. Programming time 684.9 ms USB transactions: Write 176 read 8 retries 7
  11. I expect so, though I haven't tried it. The Spartan6 FPGA, at least, can read its own "Device DNA" with the DNA_PORT primitive according to http://www.xilinx.com/support/documentation/user_guides/ug380.pdf. It sounds like maybe Spartan3E can't according to http://www.xilinx.com/support/documentation/user_guides/ug332.pdf. I don't know if reading it via JTAG boundary scan over the USB connection will work, but that also seems like a possibility.
  12. Regarding uses for soft-CPUs: Sending commands to / collecting results from your FPGA design (like for a user interface, or for debugging); being able to create a sort of custom microcontroller with selected (or newly created) peripherals; learning / experimenting with (small) computer architecture. Regarding your questions about next projects, and about interfacing with AVR: Why NOT do a SPI interface from scratch? It doesn't sound that complicated, and you could adapt it for controlling your future FPGA designs from the AVR. Make the FPGA act as SPI "slave", and the microcontroller as "master;" at first, just doing something simple like lighting LEDs or reading switches. There are also probably plenty of SPI implementations out there you could try to adapt to your needs. Although modifying someone else's code to fit a different purpose can be difficult in itself.
  13. Here's what I think is going on, based on looking at the code in https://github.com/jamesbowman/swapforth/tree/master/j1b/verilog. I think it indicates a read from some I/O device's registers. That is, instead of reading/writing memory, the instruction reads some data provided by one of the peripheral devices. This is one of the common ways a computer design could allow access to I/O devices. It looks like J1B uses a mixture of port-mapped and memory-mapped I/O (see https://en.wikipedia.org/wiki/Memory-mapped_I/O): as I look in xilinx-top.v I see that some memory accesses go to registers such as "uart_baud" too. Analysis in more detail: In j1.v: When "insn[6:4] == 5" then func_ior is asserted to 1. When that is true (along with some other things) then the output signal "io_rd" is asserted to 1. In xilinx-top.v: The signal io_rd is delayed one clock cycle (as io_rd_) and used, along with mem_addr (delayed as mem_addr_), to receive from the UART (see the signal uart_rd).
  14. Regarding SDRAM CKE: I'll point out that the data sheet's "recommended power-up sequence for SDRAM" includes bringing CKE low and then high again. Although it doesn't say how long it needs to be low -- Hamster's SDRAM controller only does it for a single clock cycle, no longer, so it probably doesn't make any difference.
  15. Some thoughts, more from what you're trying to do than from looking at your code: 210MHz is a rather high clock rate to get on these FPGAs. I think it can be done, but might require some trickery (especially pipelining) for it to make timing. PWM is a rather simple thing: You have a counter, and you compare the counter value with your setting, and the result of the comparison is your output. When you have more than one clock, the interaction between logic that uses the one clock, and logic which uses the other clock, can be tricky I really haven't experimented with this much, usually I use the same clock for everything. I think you're on the right track with this code -- where there's a piece which handles the Wishbone bus interaction (Wishbone_to_Registers_n, on the 96MHz clock) and another part which handles the PWM (on the >=210 MHz clock) and a simple one-way connection between them (register_out_array). But you may have to put one or two clock cycles' worth of register delays between the components, to give XST a chance to synch them up. In between, it tries to make logic respond within the worst-case period between the 210MHz clock and the 96MHz one. I think for 210MHz that's something like 300ps! Choosing your clock rate wisely might improve that: I believe for 216MHz it would be 1160ps, for 192MHz, 5200ps. All this assumes your two clocks are derived from the same off-chip source (the 32MHz clock on the Papilio board). If you have a second clock signal coming from off-chip then the situation gets more complicated. I don't see anywhere "clk_96mhz" is being supplied to your code. You use it (passing it to Wishbone_to_Registers_n) but the only clock you're getting is "PWM_clk". You need to get both from somewhere... If you want to see code which handles multiple clocks, in DesignLab, you might look for the video code. It uses multiple clocks for the video output, and presumably still uses the 96MHz system clock for its Wishbone bus interface. It's probably a rather complicated example, but at least it's an example.