Remove MemToReg.
Pretty sure MemToReg is a MIPS relic, it is redundant so long as all memory reads are put into registers.
This commit is contained in:
parent
743734c346
commit
8dc92fb8e1
5 changed files with 100 additions and 35 deletions
|
@ -46,13 +46,13 @@ class Decoder() extends Module {
|
||||||
*/
|
*/
|
||||||
val opcodeMap: Array[(BitPat, List[UInt])] = Array(
|
val opcodeMap: Array[(BitPat, List[UInt])] = Array(
|
||||||
|
|
||||||
// signal memToReg, regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
||||||
LW -> List(Y, Y, Y, N, N, N, branchType.DC, rs1, imm, ITYPE, ALUOps.ADD),
|
LW -> List(Y, Y, N, N, N, branchType.DC, rs1, imm, ITYPE, ALUOps.ADD),
|
||||||
|
|
||||||
SW -> List(N, N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD),
|
SW -> List(N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD),
|
||||||
|
|
||||||
ADD -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD),
|
ADD -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD),
|
||||||
SUB -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB),
|
SUB -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
TODO: Fill in the blanks
|
TODO: Fill in the blanks
|
||||||
|
@ -60,23 +60,22 @@ class Decoder() extends Module {
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
val NOP = List(N, N, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.DC)
|
val NOP = List(N, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.DC)
|
||||||
|
|
||||||
val decodedControlSignals = ListLookup(
|
val decodedControlSignals = ListLookup(
|
||||||
io.instruction.asUInt(),
|
io.instruction.asUInt(),
|
||||||
NOP,
|
NOP,
|
||||||
opcodeMap)
|
opcodeMap)
|
||||||
|
|
||||||
io.controlSignals.memToReg := decodedControlSignals(0)
|
io.controlSignals.regWrite := decodedControlSignals(0)
|
||||||
io.controlSignals.regWrite := decodedControlSignals(1)
|
io.controlSignals.memRead := decodedControlSignals(1)
|
||||||
io.controlSignals.memRead := decodedControlSignals(2)
|
io.controlSignals.memWrite := decodedControlSignals(2)
|
||||||
io.controlSignals.memWrite := decodedControlSignals(3)
|
io.controlSignals.branch := decodedControlSignals(3)
|
||||||
io.controlSignals.branch := decodedControlSignals(4)
|
io.controlSignals.jump := decodedControlSignals(4)
|
||||||
io.controlSignals.jump := decodedControlSignals(5)
|
|
||||||
|
|
||||||
io.branchType := decodedControlSignals(6)
|
io.branchType := decodedControlSignals(5)
|
||||||
io.op1Select := decodedControlSignals(7)
|
io.op1Select := decodedControlSignals(6)
|
||||||
io.op2Select := decodedControlSignals(8)
|
io.op2Select := decodedControlSignals(7)
|
||||||
io.immType := decodedControlSignals(9)
|
io.immType := decodedControlSignals(8)
|
||||||
io.ALUop := decodedControlSignals(10)
|
io.ALUop := decodedControlSignals(9)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ object Instruction {
|
||||||
|
|
||||||
|
|
||||||
class ControlSignals extends Bundle(){
|
class ControlSignals extends Bundle(){
|
||||||
val memToReg = Bool()
|
|
||||||
val regWrite = Bool()
|
val regWrite = Bool()
|
||||||
val memRead = Bool()
|
val memRead = Bool()
|
||||||
val memWrite = Bool()
|
val memWrite = Bool()
|
||||||
|
@ -51,7 +50,6 @@ class ControlSignals extends Bundle(){
|
||||||
object ControlSignals {
|
object ControlSignals {
|
||||||
def nop: ControlSignals = {
|
def nop: ControlSignals = {
|
||||||
val b = Wire(new ControlSignals)
|
val b = Wire(new ControlSignals)
|
||||||
b.memToReg := false.B
|
|
||||||
b.regWrite := false.B
|
b.regWrite := false.B
|
||||||
b.memRead := false.B
|
b.memRead := false.B
|
||||||
b.memWrite := false.B
|
b.memWrite := false.B
|
||||||
|
|
|
@ -23,6 +23,7 @@ case class TestOptions(
|
||||||
printVMtrace : Boolean,
|
printVMtrace : Boolean,
|
||||||
printVMfinal : Boolean,
|
printVMfinal : Boolean,
|
||||||
printMergedTrace : Boolean,
|
printMergedTrace : Boolean,
|
||||||
|
printBinary : Boolean,
|
||||||
nopPadded : Boolean,
|
nopPadded : Boolean,
|
||||||
breakPoints : List[Int], // Not implemented
|
breakPoints : List[Int], // Not implemented
|
||||||
testName : String,
|
testName : String,
|
||||||
|
@ -35,7 +36,8 @@ case class TestResult(
|
||||||
program : String,
|
program : String,
|
||||||
vmTrace : String,
|
vmTrace : String,
|
||||||
vmFinal : String,
|
vmFinal : String,
|
||||||
sideBySide : String
|
sideBySide : String,
|
||||||
|
binary : String
|
||||||
)
|
)
|
||||||
|
|
||||||
object TestRunner {
|
object TestRunner {
|
||||||
|
@ -59,6 +61,7 @@ object TestRunner {
|
||||||
val vmTraceString = printVMtrace(trace, program)
|
val vmTraceString = printVMtrace(trace, program)
|
||||||
val vmFinalState = finalVM.regs.show
|
val vmFinalState = finalVM.regs.show
|
||||||
val traceString = printLogSideBySide(trace, chiselTrace, program)
|
val traceString = printLogSideBySide(trace, chiselTrace, program)
|
||||||
|
val binaryString = printBinary(binary)
|
||||||
|
|
||||||
val regError = compareRegs(trace, chiselTrace)
|
val regError = compareRegs(trace, chiselTrace)
|
||||||
val memError = compareMem(trace, chiselTrace)
|
val memError = compareMem(trace, chiselTrace)
|
||||||
|
@ -69,7 +72,8 @@ object TestRunner {
|
||||||
programString,
|
programString,
|
||||||
vmTraceString,
|
vmTraceString,
|
||||||
vmFinalState.toString,
|
vmFinalState.toString,
|
||||||
traceString)
|
traceString,
|
||||||
|
binaryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
testResults.left.foreach{ error =>
|
testResults.left.foreach{ error =>
|
||||||
|
@ -79,15 +83,16 @@ object TestRunner {
|
||||||
testResults.map{ testResults =>
|
testResults.map{ testResults =>
|
||||||
val successful = List(testResults.regError, testResults.memError).flatten.headOption.map(_ => false).getOrElse(true)
|
val successful = List(testResults.regError, testResults.memError).flatten.headOption.map(_ => false).getOrElse(true)
|
||||||
if(successful)
|
if(successful)
|
||||||
say(s"${testOptions.testName} succesful")
|
sayGreen(s"${testOptions.testName} succesful")
|
||||||
else
|
else
|
||||||
say(s"${testOptions.testName} failed")
|
sayRed(s"${testOptions.testName} failed")
|
||||||
|
|
||||||
if(testOptions.printIfSuccessful && successful){
|
if(testOptions.printIfSuccessful && successful){
|
||||||
if(testOptions.printParsedProgram) say(testResults.program)
|
if(testOptions.printParsedProgram) say(testResults.program)
|
||||||
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
||||||
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
||||||
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
||||||
|
if(testOptions.printBinary) say(testResults.binary)
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(testOptions.printErrors){
|
if(testOptions.printErrors){
|
||||||
|
@ -98,6 +103,7 @@ object TestRunner {
|
||||||
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
||||||
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
||||||
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
||||||
|
if(testOptions.printBinary) say(testResults.binary)
|
||||||
}
|
}
|
||||||
successful
|
successful
|
||||||
}.toOption.getOrElse(false)
|
}.toOption.getOrElse(false)
|
||||||
|
|
85
theory1.org
85
theory1.org
|
@ -6,12 +6,15 @@
|
||||||
when grading these questions, thus even with no implementation at all you
|
when grading these questions, thus even with no implementation at all you
|
||||||
should still be able to score 100% on the theory questions.
|
should still be able to score 100% on the theory questions.
|
||||||
|
|
||||||
All questions can be answered in a few sentences. Remember that brevity is the
|
All questions can be answered in a few sentences. Remember that brevity is wit,
|
||||||
soul of wit, and also the key to getting a good score.
|
and also the key to getting a good score.
|
||||||
|
You should easily be able to fit your entire answer on a single screen.
|
||||||
|
|
||||||
** Question 1
|
** Question 1
|
||||||
2 points.
|
*2 points.*
|
||||||
*** Part 1
|
*** Part 1
|
||||||
|
**** Part 1½
|
||||||
|
*½ points.*
|
||||||
When decoding the BNE branch instruction in the above assembly program
|
When decoding the BNE branch instruction in the above assembly program
|
||||||
#+begin_src asm
|
#+begin_src asm
|
||||||
bne x6, x2, "loop",
|
bne x6, x2, "loop",
|
||||||
|
@ -19,7 +22,21 @@
|
||||||
|
|
||||||
In your design, what is the value of each of the control signals below?
|
In your design, what is the value of each of the control signals below?
|
||||||
|
|
||||||
+ memToReg
|
+ regWrite
|
||||||
|
+ memRead
|
||||||
|
+ memWrite
|
||||||
|
+ branch
|
||||||
|
+ jump
|
||||||
|
|
||||||
|
**** Part 1¼
|
||||||
|
*½ points.*
|
||||||
|
When decoding the LW instruction in the above assembly program
|
||||||
|
#+begin_src asm
|
||||||
|
jal x1, 0x10(x1)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
In your design, what is the value of each of the control signals below?
|
||||||
|
|
||||||
+ regWrite
|
+ regWrite
|
||||||
+ memRead
|
+ memRead
|
||||||
+ memWrite
|
+ memWrite
|
||||||
|
@ -33,7 +50,6 @@
|
||||||
*** Part 2
|
*** Part 2
|
||||||
During execution, at some arbitrary cycle the control signals are:
|
During execution, at some arbitrary cycle the control signals are:
|
||||||
|
|
||||||
+ memToReg = 0
|
|
||||||
+ regWrite = 1
|
+ regWrite = 1
|
||||||
+ memRead = 0
|
+ memRead = 0
|
||||||
+ memWrite = 0
|
+ memWrite = 0
|
||||||
|
@ -48,7 +64,10 @@
|
||||||
implementation.
|
implementation.
|
||||||
|
|
||||||
** Question 2
|
** Question 2
|
||||||
4 points.
|
*4 points.*
|
||||||
|
*NO PARTIAL CREDITS*
|
||||||
|
Since you can test your solution with the testing framework I will not offer any
|
||||||
|
points for a near correct solution to this problem.
|
||||||
|
|
||||||
Reading the binary of a RISC-V program you get the following:
|
Reading the binary of a RISC-V program you get the following:
|
||||||
|
|
||||||
|
@ -77,11 +96,23 @@
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*Your answer should be in the form of a simple asm program.*
|
*Your answer should be in the form of a simple asm program.*
|
||||||
(hint 1: the original asm program had a label, you need to infer where that label was)
|
+ hint 1:
|
||||||
(hint 2: verify your conclusion by assembling your answer)
|
the original asm program had a label, you need to infer where that label was
|
||||||
|
|
||||||
|
+ hint 2:
|
||||||
|
Verify your conclusion by assembling your answer.
|
||||||
|
To do this, make an asm program, place it with the rest of the tests and set
|
||||||
|
~printBinary~ to ~true~ in ~singleTestOptions~ in ~Manifest.scala~ which will
|
||||||
|
print the full binary of your program.
|
||||||
|
As long as your program generates the same binary as the supplied your program
|
||||||
|
is correct.
|
||||||
|
|
||||||
|
|
||||||
** Question 3
|
** Question 3
|
||||||
4 points.
|
*4 points.*
|
||||||
|
*NO PARTIAL CREDITS*
|
||||||
|
Since you can test your solution with the testing framework I will not offer any
|
||||||
|
points for a near correct solution to this problem.
|
||||||
|
|
||||||
In order to load a large number LUI and ADDI are used.
|
In order to load a large number LUI and ADDI are used.
|
||||||
consider the following program
|
consider the following program
|
||||||
|
@ -94,5 +125,37 @@
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
a) Which of these instructions will be split into ADDI LUI pairs?
|
a) Which of these instructions will be split into ADDI LUI pairs?
|
||||||
b) Why do the two last instructions need to be handled differently from each other?
|
b) Explain in 3 sentences or less *how* the two last ops are handled differently and *why*.
|
||||||
(hint: The parser and assembler in the test suite can help you answer this question)
|
|
||||||
|
+ hint 1:
|
||||||
|
The parser and assembler in the test suite can help you answer the first part of
|
||||||
|
this question (a).
|
||||||
|
Create an asm file, put it with the rest of the tests and run it, setting the correct
|
||||||
|
test options in ~singleTestOptions~ defined in ~Manifest.scala~ and observe the output.
|
||||||
|
|
||||||
|
+ hint 2:
|
||||||
|
While it's probably easier to solve this problem using the internet, however you
|
||||||
|
can also figure out what is happening by browsing the assembler source code which
|
||||||
|
will hopefully give you a deeper insight into what is going on here.
|
||||||
|
|
||||||
|
Look at ~Parser.scala~, specifically what happens when an ~li~ instruction is parsed.
|
||||||
|
When parsing an instruction the parser first attempts to apply the
|
||||||
|
~singleInstruction~ rule, however this only succeeds if the immediate value
|
||||||
|
obeys certain restrictions (~nBits <= 12~), if not it fails.
|
||||||
|
|
||||||
|
If the ~singleInstruction~ rule fails the parser then attempts to apply the
|
||||||
|
~multipleInstructions~ rule instead which expands operations into a list of real ops.
|
||||||
|
When this happens the resulting operations are defined as the following:
|
||||||
|
#+begin_src scala
|
||||||
|
stringWs("li") ~> (reg <~ sep, (hex | int).map(_.splitHiLo(20))).mapN{ case(rd, (hi, lo)) => {
|
||||||
|
List(
|
||||||
|
ArithImm.add(rd, rd, lo),
|
||||||
|
LUI(rd, if(lo > 0) hi else hi+1),
|
||||||
|
)}}.map(_.widen[Op]),
|
||||||
|
#+end_src
|
||||||
|
This is quite a lot to unpack, but you can focus on the line where the ~LUI~ is constructed.
|
||||||
|
~hi~ and ~lo~ are the results of ~splitHiLo~ which splits a 32 bit word into a 12 bit and a
|
||||||
|
20 bit.
|
||||||
|
Try this for yourself on paper; what happens when ~lo~ ends up being a negative number?
|
||||||
|
What is the interplay between incrementing ~hi~ with 1 and adding a ~lo~ that is represented
|
||||||
|
as a negative value?
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
rs1: 4 || rs1: 4 || rs1: 1
|
rs1: 4 || rs1: 4 || rs1: 1
|
||||||
rs2: 5 || rs2: 6 || rs2: 2
|
rs2: 5 || rs2: 6 || rs2: 2
|
||||||
rd: 6 || rd: 4 || rd: 5
|
rd: 6 || rd: 4 || rd: 5
|
||||||
memToReg = false || memToReg = false || memToReg = false
|
|
||||||
regWrite = true || regWrite = false || regWrite = true
|
regWrite = true || regWrite = false || regWrite = true
|
||||||
memWrite = false || memWrite = false || memWrite = false
|
memWrite = false || memWrite = false || memWrite = false
|
||||||
branch = false || branch = true || branch = false
|
branch = false || branch = true || branch = false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue