Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

128 рядки
3.2KB

  1. package Core
  2. import chisel3._
  3. import chisel3.core.Input
  4. import chisel3.iotesters.PeekPokeTester
  5. import utilz._
  6. /**
  7. The daisy multiplier creates two daisy grids, one transposed, and multiplies them.
  8. */
  9. class daisyMultiplier(dims: Dims, dataWidth: Int) extends Module {
  10. val io = IO(new Bundle {
  11. val dataInA = Input(UInt(dataWidth.W))
  12. val writeEnableA = Input(Bool())
  13. val dataInB = Input(UInt(dataWidth.W))
  14. val writeEnableB = Input(Bool())
  15. val dataOut = Output(UInt(dataWidth.W))
  16. val dataValid = Output(Bool())
  17. val done = Output(Bool())
  18. })
  19. /**
  20. Your implementation here
  21. */
  22. val rowCounter = RegInit(UInt(8.W), 0.U)
  23. val colCounter = RegInit(UInt(8.W), 0.U)
  24. val rowOutputCounter = RegInit(UInt(8.W), 0.U)
  25. val calculating = RegInit(Bool(), false.B)
  26. val accumulator = RegInit(UInt(8.W), 0.U)
  27. val resultReady = RegInit(Bool(), false.B)
  28. /**
  29. Following the same principle behind the the vector matrix multiplication, by
  30. NOT transposing the dimensions.
  31. When writing a multiplier for a 3x2 matrix it's implicit that this means a
  32. 3x2 matrix and 2x3, returning a 2x2 matrix. By not transposing the dimensions
  33. we get the same effect as in VecMat
  34. */
  35. val matrixA = Module(new daisyGrid(dims, dataWidth)).io
  36. val matrixB = Module(new daisyGrid(dims, dataWidth)).io
  37. matrixA.dataIn := io.dataInA
  38. matrixA.writeEnable := io.writeEnableA
  39. matrixB.dataIn := io.dataInB
  40. matrixB.writeEnable := io.writeEnableB
  41. ////////////////////////////////////////
  42. ////////////////////////////////////////
  43. /// Set up counter statemachine
  44. io.done := false.B
  45. when(colCounter === (dims.cols - 1).U){
  46. colCounter := 0.U
  47. when(rowCounter === (dims.rows - 1).U){
  48. rowCounter := 0.U
  49. calculating := true.B
  50. when(calculating === true.B){
  51. when(rowOutputCounter === (dims.rows - 1).U){
  52. io.done := true.B
  53. }.otherwise{
  54. rowOutputCounter := rowOutputCounter + 1.U
  55. }
  56. }
  57. }.otherwise{
  58. rowCounter := rowCounter + 1.U
  59. }
  60. }.otherwise{
  61. colCounter := colCounter + 1.U
  62. }
  63. ////////////////////////////////////////
  64. ////////////////////////////////////////
  65. /// set up reading patterns depending on if we are in calculating state or not
  66. when(calculating === true.B){
  67. matrixA.rowSelect := rowOutputCounter
  68. }.otherwise{
  69. matrixA.rowSelect := rowCounter
  70. }
  71. matrixB.rowSelect := rowCounter
  72. ////////////////////////////////////////
  73. ////////////////////////////////////////
  74. /// when we're in calculating mode, check if we have valid output
  75. resultReady := false.B
  76. io.dataValid := false.B
  77. when(calculating === true.B){
  78. when(colCounter === (dims.cols - 1).U){
  79. resultReady := true.B
  80. }
  81. }
  82. ////////////////////////////////////////
  83. ////////////////////////////////////////
  84. /// when we've got a result ready we need to flush the accumulator
  85. when(resultReady === true.B){
  86. // To flush our accumulator we simply disregard previous state
  87. accumulator := (matrixA.dataOut*matrixB.dataOut)
  88. io.dataValid := true.B
  89. }.otherwise{
  90. accumulator := accumulator + (matrixA.dataOut*matrixB.dataOut)
  91. }
  92. io.dataOut := accumulator
  93. }