[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/MKcUyHgS)
# ARC4 Cracking Competition

## Contents

* [The competition](#the-competition)
* [Submission logistics](#submission-logistics)
* [Evaluation protocol](#evaluation-protocol)
* [Suggestions](#suggestions)

## The competition

Time to get into the NSA business. For bonus credit in the course, you may improve upon your ARC4 cracker and enter a competition to decrypt messages the fastest.

The bonus credit you will receive will depend on the performance of your circuit. An extremely fast implementation might receive up to **5%** of the course marks; on the other hand, an implementation that is not much faster than a carefully written `doublecrack` from the lab will receive no extra credit.

To give you an idea of what might constitute decent performance, our example implementation processes well over 11 million keys per second in the DE1-SoC. This design took us at most 30 extra minutes over `doublecrack`, and it is very possible to achieve _much_ higher performance with a little more effort.

Unlike in the course labs, we will measure the speed by loading your design _directly on the DE1-SoC_. This means that there are no stringent requirements for module port names, instance hierarchy, and so forth. Because we still have to automate the testing, however, you will have to implement a protocol that will allow us to communicate with the FPGA; read [Evaluation protocol](#evaluation-protocol) below for details.

If you don't have a DE1-SoC, you can still enter the competition. You can estimate performance by simulating your design to crack ciphertexts with smaller keys, or by measuring the average number of keys processed per second. If you have a DE0-CV, or DE10 Lite you can use it to help development; however, be aware that you will need to submit a design for the DE1-SoC, and that the DE1-SoC FPGA has more resources than the DE0-CV or DE10 Lite.


## Submission logistics

If you wish to enter the competition, you will need to submit both your sources and an FPGA image.

In the `src` folder, you will need to submit
- all of your design files, with the toplevel instance named `competition`,
- a Quartus project file `competition.qpf`,
- a pin assignment file called `competition.qsf`, and
- optionally, a timing constraints file called `competition.sdc`.

In the `sof` folder, you will need to submit
- a `competition.sof` FPGA image **for the DE1-SoC**.

You will also need to describe the optimizations you implemented (including an estimate of your speed-up with a justification) in [`SUBMISSION.md`](SUBMISSION.md).
In addition, in the `screenshots` folder, submit screenshots of your:
- synthesis report (showing stats of logic utilization)
- timing analysis reports (showing clock frequency Fmax and slack/critical paths)

For evaluation, we may either use your SOF file directly or re-synthesize from your sources. When running Quartus, we will include all `.sv` and `.v` files in the `src` folder. In the event that you implement your design using a higher-level compiler such as Bluespec, Chisel, Intel HLS, etc., you must include the original sources and build instructions as well as the generated `.sv`/`.v` files.

If you are missing parts of the submission or your sources do not synthesize to something resembling your `sof`, your entry will be disqualified.

## Demo

You are required to demo your lab 3 bonus similar to previous labs. A sign-up sheet will be posted in advance. Note that if you choose to submit and demo this assignment, you need to let the teaching team know in advance. A sign-up sheet will be posted next week, with a signup deadline - March 27, EOD. Only students who signed up for this lab are allowed to submit and demo. So please make sure you start lab 3 early to get an understanding of how realistic is to complete the bonus part.  

## Evaluation protocol

To facilitate automated timing of your submission on the DE1-SoC board, you will need to have three single-ported RAMs just like _S_ (8 bits wide and 256 addresses deep) with the instance IDs of _MBOX_, _PT_, and _CT_. All addresses should be initialized to 0 at boot time. Both memories must be editable using the In-System Memory Content Editor, since this is how we will access them. Be careful to make other memories in your design non-editable or rename them to something other than _PT_ and _CT_; if you instantiate multiple memories with the same instance ID, an arbitrary memory might get accessed instead of the one you want.

We will use these memories to communicate with your circuit as follows:

1. We will load your `.sof` onto a DE1-SoC. Make sure your circuit works once loaded _without any intervention_; since we will test submissions automatically, we will not be pushing any buttons or setting any switches.
2. We will load the length-prefixed ciphertext into the memory with instance ID _CT_. Once this is done, we will set the contents of address 0 in the memory with instance ID _MBOX_ to 'hFF. Your circuit will need to monitor _MBOX_ to discover when to start cracking.
3. We will repeatedly read the contents of _MBOX_ at address 1. Once the value becomes 'hFF, we will also read addresses 2, 3, and 4 to recover the key (again, big-endian) and the contents of _PT_ to recover the length-prefixed plaintext. Both of these must be correct for your entry to be valid.
4. To repeat the experiment, we will set _MBOX_[0] to 0, wait one second, and repeat the process starting at step 2. This means your circuit needs to notice this happening and make itself ready to process a new request.

Be sure to test all of this, including the last point. It's easy to get everything right but not make the cracking repeatable, in which case the evaluation will fail after decrypting the first ciphertext.


## Suggestions

Some things you might want to think about:

- Can you add more `crack` cores? (You might find it useful to do so in a way that allows you to quickly change the core count.)
- Can you run the clock faster? (You can generate clocks using the PLL IP and set the target frequency for synthesis using an `.sdc` constraint file.)
- Can you run the clock even faster? (You will want to look at the critical paths reported by the timing analysis phase.)
- Can you get squeeze out any unnecessary states in your FSMs? (Think about where the ultimate bottleneck is.)
- Can you use the memory blocks instances more efficiently than in the lab, or remove some of them altogether? (Look up the actual M10K memory parameters in the Cyclone V documentation.)
- Can you share some modules or memory blocks among multiple cores? (But think about how this kind of reuse would affect core utilization.)
