RoadTest: Cmod S7: Breadboardable Spartan-7 FPGA Module
Author: Fred27
Creation date:
Evaluation Type: Development Boards & Tools
Did you receive all parts the manufacturer stated would be included in the package?: True
What other parts do you consider comparable to this product?: Other FPGA - especially Spartan 7 - boards
What were the biggest problems encountered?: As always, Viviado installation size and versioning
Detailed Review:
In this road test I intend to give you a view of what the Cmod S7 is, what it's suitable for, what it's not and how it compares to alternatives that may or may not fit your own use case. I won't give you a detailed unboxing. (It's a small development board and it came in a small box.) I suspect my fellow road testers will adequately cover getting started, so I probably won't dwell too long on this either. I hope to give you a good idea if a Spartan 7 board is right for you and if so whether the Cmod S7 is the right one.
The Cmod S7 is a small form factor development board containing a Xilinx Spartan-7 FPGA. It's been designed with two rows of 0.1" male headers (facing downwards, if you insist that there is a right way up for a development board) specifically to fit into the holes on a bread board. These two rows of pins are 0.6" apart so will fit into a standard breadboard with enough room to comfortably connect a jumper wire or two.
The Spartan 7 is Xilinx's current range of "cost-optimised" FPGAs. I suppose cost-optimised can be taken to mean low-end but don't be fooled, this is still a seriously powerful device. To be honest, all FPGAs can surprise you with their power and flexibility. Ease of use - maybe less so!
If you do feel a need to step upwards from the Spartan-7 then in the family of Xilinx devices there is also the Artix-7, which has been designed with on-board transceivers for high bandwidth I/O. If you decide that you want a microcontroller right next to your FPGA then there is the Zynq range - basically a Spartan-7 and an ARM A9 or two on the same silicon. However, that's not the only way to combine a microcontroller and FPGA as we'll find out later.
These days, if you were building a device one familiar path would be to grab your favourite microcontroller board and start coding away in C. How we laugh at the old guys who had to get loads of individual logic ICs and start working out how to combine all those AND gates, NOR gates, flip-flops and transistors. Practically prehistoric! To be honest though, doing something which a physical piece of silicon has a couple of advantages that a microcontroller just can't touch.
Hardware logic is quick. Blindingly quick. How many clock cycles does it take a microcontroller to AND and OR some signals together to decide whether to light that LEDs? A few. It probably depends on how many signals and how complicated the combination. How many cycles does it take a logic gate? None. None at all. We may worry a little about how quickly electrons can move and signals can propagate, but we'll be measuring it in nanoseconds.
What is you took that logic combination and repeated it a hundred-fold? A thousand-fold? Well it will take 100 or 1000 times as long. Of course it would! Well, not with logic gates. Just buy some more and they'll still run at exactly the same speed.
Logic gates may have some advantages, but all that soldering! What a pain. And what if you need to change it? That means respinning a board. It'll take weeks! What if I told you that an FPGA was an enormous virtual bag of logic chips. A bag that can be rewired and reconnected with just a few ones and zeroes? Interested now? I'm sure you are! Well that in essence is an FPGA.
My apologies to these of you who are familiar with FPGAs for my enormous over-simplification. I have also been known to describe Verilog as a C program where all the lines of code are running at the same time! Sorry if that made you spit your coffee all over the keyboard.
You won't be surprised to hear that the Spartan-7 is available on development boards in a number of form factors. Here are a few alternatives:
Board | Notable features |
---|---|
Arty S7 (Digilent) This is a larger form factor board. It has Arduino-style headers, 4 Pmod connectors (as opposed to the Cmod S7's single one) and a few more buttons, switches and LEDs. It is available with exactly the same XC7S25 Spartan 7 chip as the Cmod, or an XC7S50 with double the number of logic cells. It's a little more expensive at $ for the | |
SP701 (Xilinx) Even bigger board. Even bigger XC7S100 FPGA. This is Xilinx's own offering. Plenty more IO including video and ethernet. It uses the largest of the Spartan 7 family which is 4 times the size of the one on the Cmod S7. It's also almost 10x the cost at $645. | |
Cmod A7 (Digilent) Hang on. That just the same one again, isn't it? Well, not quite.
If you like the Cmod S7 form factor but want something a little beefier, there's the Artix-7 bearing Cmod A7. It's available in two sizes with the XC7A15T or the XC7A35T FPGA on it and cost a bit more than the S7 ($75 and $99). It is a bit more powerful but considering the Artix's main strength is high speed I/O it feels a little wasted using 0.1" headers. |
This is not an exhaustive list. There are also a few Spartan-6 boards available but I didn't include those. Whilst the Spartan-6 isn't hugely different from the 7 series, it would mean that you need to use the much older and now retired Xilinx ISE design suite. I'd class the 6 series as legacy devices and say they're probably not worth your while. If you do like the Cmod form factor though, the Spartan-6 and the much simpler Coolrunner-II CPLD can be found in this format.
It's small. I don't really know why that surprised me. I suppose what I was pleasantly surprised by is that it also came simply packaged in a small box - about the size of a lipstick. I'm also not sure why I'm describing electronics with beauty products as a reference. Maybe I should say a lipstick is about that same size as a Spartan 7 with a single Pmod header. There. That's better.
The main reason for the small box is that it didn't come with any of that unnecessary stuff like yet another micro USB cable and a piece of card telling you to go to a web page for the getting started guide. All that was in there was the device itself and some foam to protect the header pins. It's refreshing to see this sort of minimal packaging and lack of wastefulness. (Of course, it was in a UPS box about 20 times the size it needed to be, but there you go.)
You'll see a photo of it running the out-of the box demo that flashed the four green user LEDs in turn and changes the colour of the RGB LED. As FPGAs have no onboard flash, the Cmod S7 is configured to load a bitstream that has been flashed to the quad-SPI flash that on the PCB (but quite separate from the FPGA). When you create the bitstream to be loaded onto the device it can either be programmed directly over JTAG for temporary use whilst developing, or programmed into the flash so it runs on start-up.
So I assume that most E14 members are familiar with microcontrollers. They're great for so many things, but they have their limitations. I mentioned earlier that the strengths of an FPGA include speed and scalability. You can do things very fast on an FPGA. This speed is also very deterministic and if done right can be completely unaffected by other things that you're also trying to do. My simple example is to take 3 inputs, combine them with a simple operation and output them elsewhere. I'm gong to demonstrate how these compare on a microcontroller and the Spartan 7 FPGA in the Cmod S7.
In the microcontroller side I used an MSP430RF2433 microcontroller running at 16Mhz. I sample 3 inputs, which I placed on 3 different ports just to more realistically represent a likely scenario. I read these in a fixed loop with nothing else going on. This is a snippet of my sample code:
P1OUT &= ~BIT0; // Clear P1.0 output latch for a defined power-on state P1DIR |= BIT0; // Set P1.0 to output direction P1DIR &= ~BIT1; // Set P1.1 as input P2DIR &= ~BIT2; // Set P2.2 as input P3DIR &= ~BIT2; // Set P3.2 as input PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode to activate previously configured port settings while (1) { unsigned char in1 = (P1IN & BIT1); unsigned char in2 = (P2IN & BIT2); unsigned char in3 = (P3IN & BIT2); if ((in1 > 0) && (in2 > 0) && (in3 > 0)) P1OUT |= BIT0; else P1OUT &= ~BIT0; // else reset }
I set up a pattern generator on my oscilloscope as a simple 3-bit binary counter at 10kHz. From the simple code we would expect a high output only when all 3 input are high - i.e. 1/8 of the time. This was indeed what we got but there was a noticeable (and variable delay) as the three ports were read and the output written. This varies between 1us and about 2.5us. There was also the occasional glitch as the pattern sometimes changed between port reads. Obviously I could have improved this slightly by having my inputs on the same port and reading atomically. I could have sped thing sup using assembly. I could also have complicated things by having this interrupt driven and doing something else on the microcontroller too. I felt this was a good compromise for a semi-realistic example.
So I created a similar 3-input AND gate on the FPGA. This very simple piece of Verilog is all that's needed (along with a constraints file defining where the pins are).
module top( input wire logic [2:0] pattern_in, output logic gate_out ); assign gate_out = pattern_in[0] & pattern_in[1] & pattern_in[2]; endmodule
So, how does this compare on the oscilloscope? The difference is dramatic! The output - even with infinite persistence - is incredibly consistent and deterministic. The propagation delay has dropped from about 2us to about 30ns. That's an impressive improvement showing the microcontroller takes between 33 and 70 times as long to perform this action.
However, the real strength of the FPGA is that no matter what else you ask of it, it is possible to keep this gate at exactly 30ns. As I'm sure you're aware, the more that gets added to the microcontroller the more it's clock cycles have to be divided up. Even using high priority interrupts to suspend other tasks in favour of this one has some overheads. This is where FPGAs really have an advantage over traditional sequential processing.
For those of you who aren't familiar with Xilinx FPGAs, the hardware development is called Vivado. As I've mentioned in previous road tests - it's huge. Expect both a large download and a large amount of disk space taken up by the installation. As luck would have it, just as this board arrived, so did the latest 2020.01 version of Vivado. Here are a couple of tips to minimise the disk space it takes up. (I'm using Windows, so folders will be different on Linux.)
You should find that when you start a new Vivado project you can choose the Cmod S7 as the board you're developing for without having to download anything. However, when you come to specifying the output pins to use you will need a constraints file. This is not specified by default, but you will find constraints for all the Digilent boards at https://github.com/Digilent/digilent-xdc/ You can either clone this repository or just grab the file you need - Cmod-S7-25-Master.xdc.
Out earlier experiment proved that there are areas where programmable logic has the edge over a sequential processor, but they both have their strengths and weaknesses. Wouldn't it be great if you could have both? Well, you can. There are devices that combine an FPGA and an ARM processor on the same piece of silicon - the excellent Xilinx Zynq comes to mind. If road tested a couple of these and was really impressed: AVNET MicroZed™ Evaluation Kit - Review and Digilent Zybo Z7 + Pcam 5C - Review.
However, not only can programmable logic beat processors for some tasks, they can also be powerful enough to create your own! If you think about it, a microcontroller is really just a lot of logic gates arranged in a very useful way. Obviously creating your own processor isn't easy. Luckily there are a few that have already been made for you. The simplest is the Microblaze - a 16-bit microcontroller created by Xilinx and free to use on their FPGAs. ARM have also made it reasonably easy to implement an M0 or M3 core in an FPGA too with their DesignStart program, and there was recently an excellent workshop on this. You can also find some RISC-V soft cores around too. In fact, when designing a physical processor it's often easiest to prototype the concept on an FPGA first.
Anyway, I'm going to stick with Microblaze for now and show you how to create your own microcontroller within your FPGA and get it running. Obviously if you only wanted a microcontroller then you would probably just buy one, but think of all that extra FPGA fabric right next to it for the bits of you design that are better suited to running in hardware...
I decided that the best way to document this would be to screen record the process of creating and building the processor and then running some simple software on it. If you want to follow along then the prerequisites are:
Whilst the video above explains how to create a processor within your FPGA, the real power is combining the two. It's not hard to imagine taking one of the LED outputs and passing it as one of the inputs to the three-input AND gate above. You then have the flexibility of using a microcontroller to oversee the logic. You could even go as high level as a hosting a web page to enable or disable the output. However, with two inputs still connected directly to the programmable logic you still retain that impressive 30ns throughput - even if the MicroBlaze is busy responding to button presses, TCP requests, etc. Definitely the best of both worlds!
To do this, first I created a new "top.sv" source which just combined both the simple AND gate and the block design in one. They were completely separate and the Cmod S7 happily ran both independently. Then I made a single change to make the AND gate combine ja[0] and ja[1] as before but to now include led which is the output from the MicroBlaze program.
module top( input wire logic [2:0] ja, output logic ja_out, input wire logic [0:0] btn, output logic [0:0] led, input wire reset, input wire sys_clock, input wire usb_uart_rxd, output usb_uart_txd ); assign ja_out = ja[0] & ja[1] & ja[2] & led; design_1_wrapper design_1_i (.btn(btn), .led(led), .reset(reset), .sys_clock(sys_clock), .usb_uart_rxd(usb_uart_rxd), .usb_uart_txd(usb_uart_txd)); endmodule
I also modified my MicroBlaze source code to simply poll a button and pass it through. Obviously this is fairly pointless, but I wanted to keep things simple and clear.
int main() { init_platform(); print("MicroBlaze and PL test\r\n"); // Initialize GPIO XIOModule gpio; XIOModule_Initialize(&gpio, XPAR_IOMODULE_0_DEVICE_ID); XIOModule_Start(&gpio); while(1) { // Read button 1 and write to LED 0 u32 data = XIOModule_DiscreteRead(&gpio, 1); XIOModule_DiscreteWrite(&gpio, 1, data); // lazy (short) delay for(volatile u32 i=0; i<1000; i++); } cleanup_platform(); return 0; }
I regenerated the bitstream, re-exported the hardware and updated Vitis to take notice of the hardware changes. Updating Vitis normally just involves right clicking the wrapper project and selecting "Update Hardware Specification" but as mine had changed from design_wrapper.xsa to top.xsa I had a bit of a head-scratch moment and recreated the Vitis project.
Once I'd done this, it worked exactly as expected. With the button pressed my logic ran as usual and "calculated" the AND logic in 30ns. Without the button pressed (or before the MicroBlaze C code was running) the output remained low.
I'm very impressed with the Cmod S7. Whilst it's not as peripheral-rich as boards like the Arty S7, it's not supposed to be. There is just enough to make it useful on its own - a debugger, some LEDs, buttons, and a single Pmod connector - but the small form factor means that a Cmod S7 could be the easiest way to add a Spartan-7 to your own design without the worry of designing a board that can cope with a BGA chip.
The only places where I marked the board down really apply to all Xilinx FPGA / SoC products - in fact I believe much of it applies to other FPGA manufacturers too. The tools are large and unwieldy. They're not easy to get to grips with. Each year brings the usual upgrade cycle but examples and IP seem stuck on a particular version. (Most examples I found were for Vivado 2018.2 - so many version out of date.)
If the Cmod S7 fits your use case though (a reasonably powerful FPGA board in a small form factor) then I can thoroughly recommend it. In fact, after all this road testing I realised that the small box that the Cmod S7 comes in sums it all up nicely in one simple sentence. "Spartan-7 power in a 36-Pin DIP Package". I could have saved myself a lot of time!
Top Comments
Very good review!
Thanks. I meant to add a link in the road test you your excellent blog on using the Cmod S7 to learn Verilog but I forgot. I didn't want to just cover the same ground that you did.
So, if you are new…
I like your approach on covering low level Verilog and high level C code. I've always been puzzled on the proper way to review a microcontroller or FPGA, I think your approach is one of the best that…