Adopting our agile mindset, some of these problems revise components introduced in prior homework assignments. Although we provide a skeleton for testers, you will need to implement them in order to use them. Be sure not to modify external IO interfaces to maintain compatability with the autograder.
Let's enhance your
ComplexALUfrom HW1 by usingBundles and encapsulation. This problem will consist of multiple parts that build from each other.
Implement the
ComplexNumbundle insrc/main/scala/hw2/Complex.scalaby adding twoSIntfields:realandimagand four methods with the following signatures:def sumReal(that: ComplexNum): SInt def sumImag(that: ComplexNum): SInt def diffReal(that: ComplexNum): SInt def diffImag(that: ComplexNum): SIntThe goal of these methods is to effectively overload the
+and-operators so we can easily work withComplexNumin future modules while hiding implementation details. Make sure the arithmetic methods allow for bit width growth.
Implement the
ComplexALUIObundle insrc/main/scala/hw2/Complex.scalaby adding threeInputfields:doAdd: Option[Bool] c0: ComplexNum c1: ComplexNumand one
Outputfield:out: ComplexNumEnsure the width of
outallows for bit width growth. For help with optional IO see the cookbook.
Implement the
ComplexALUmodule insrc/main/scala/hw2/Complex.scalausing only the methods defined inComplexNumto perform arithmetic. It will behave similarly to HW1, except that if theonlyAdderparameter is true, the generated hardware will not even include a port fordoAdd.
- if
doAddis high, sum the real inputs and sum the imaginary inputs- if
doAddis low, find the difference between the real inputs and the difference between the imaginary inputs- if
onlyAdderis true, only generate logic to sum the real inputs and sum the imaginary inputs. Since we no longer needdoAdd, it should be absent from the Verilog.
Let's enhance your
PolyEvalfrom HW1 to support arbitrary polynomials. Implement thePolyEvalmodule insrc/main/scala/hw2/PolyEval.scala. Thecoefsparameter is a list of coefficients ordered by ascending exponent powers. The generated hardware should produce the result combinatorally (within a cycle).For example:
coefs = Seq(4, 5, 6) x = 2 out = 4*x^0 + 5*x^1 + 6*x^2 = 4 + 10 + 24 = 38
Sine waves are useful in DSPs, and in this problem, you will implement a sine wave generator (
SineWaveGen). Over multiple cycles, the generated hardware will produce the output values for a sine wave. Internally, it will track where it is in the period, and use that to index into a lookup table. The lookup table will hold a single period of the sine wave sin(x) sampled atperiodpoints. Thus, due to the periodic nature of a sine wave, a point at p should be the same as a point p + period. To assist, we provideSineWave(insrc/main/scala/hw2/SineWaveGen.scala) which represents the sine wave to be turned into a hardware table, and it can also be used as a Scala functional model to get the needed points.
Since we are working with UInts instead of floating-point, we use the parameter
amplitudeto scale up the result. The generated hardware will take two inputs (enandstride). Each cycle the module will output the next sample ifenis high, or keep returning the same sample ifenis low. Thestrideinput determines how many samples to step through the ROM each cycle. Note, thatstridemay not evenly divide the period.
Implement the
SineWaveGenIObundle insrc/main/scala/hw2/SineWaveGen.scalaby adding twoInputfields:stride: UInt en: Booland one
Outputfield:out: SInt
Implement the
SineWaveGenmodule insrc/main/scala/hw2/SineWaveGen.scala, using aSineWaveGenIOas the module's IO.Example given these parameters:
val period = 16 val amplitude = 128If
strideis1thenSineWaveGenwill return one value each cycle in this order:0, 48, 90, 118, 128, 118, 90, 48, 0, -48, -90, -118, -128, -118, -90, -48If
strideis2thenSineWaveGenwill return one value each cycle in this order:0, 90, 128, 90, 0, -90, -128, -90
An XOR cipher is a simple cryptographic encryption technique based on the XOR operation. Given a secret
keyanddataof the same length, we can encryptdataby performingciphertext = data ^ key. We can decryptciphertextby performingdata = ciphertext ^ key.
You will implement a simple XOR cipher. Inside the generated hardware, there will be a register data to hold the data (potentially encrypted) and a register key to hold the key. You will use a state machine internally to keep track of the status of the system. Upon reset, the system will wait until it is given an input secret key to load in. Once the secret key is stored inside key, it is now ready to accept input data. When given input data, it will encrypt it on the way in and store it in data as ciphertext. The ciphertext in data can be decrypted, but after a cycle the decrypted data must be overwritten or zeroed out.
To encode commands, we use the following input signals:
clear: zero out both the data and the secret key
loadKey: storeininto the secret key
loadAndEnc: storeinencrypted (via XOR with the secret key) into data
decrypt: decrypt data with the secretkey
Implement the
XORCipherIObundle insrc/main/scala/hw2/XORCipher.scalaby adding twoInputfields:in: UInt cmds: XORCipherCmdsand four
Outputfields:out: UInt (output of data register) full: Bool (data register has valid data) encrypted: Bool (data register has encrypted data) state: CipherState (eases testing of FSM)
Implement the
XORCiphermodule insrc/main/scala/hw2/XORCipher.scalausingXORCipherIOas the IO. We will build a FSM with four states:
clear: data and key are both 0 (initial state)
ready: secret key is set
encrypted: data is filled with ciphertext
decypted: data is filled with decrypted data
The state transitions will follow this diagram:
In general, at most one signal in XORCipherCmds should be high at a time, but use the following precedence order when multiple are high:
clear > loadKey > loadAndEncrypt > decryptFor example, any time
clearis seen, flush the contents and go to theemptystate. If none of the transition conditions are satisfied, remain in the present state.
We recommend using the tester (after filling it in) located in
src/test/scala/hw2/XORCipherTestSuite.scalato drive your development.