blob: ed7e37e7c77e1ef37a972d21d125036d1f086639 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
package vexriscv
import vexriscv.plugin._
import spinal.core._
import scala.collection.mutable.ArrayBuffer
import scala.collection.Seq
object VexRiscvConfig{
def apply(withMemoryStage : Boolean, withWriteBackStage : Boolean, plugins : Seq[Plugin[VexRiscv]]): VexRiscvConfig = {
val config = VexRiscvConfig()
config.plugins ++= plugins
config.withMemoryStage = withMemoryStage
config.withWriteBackStage = withWriteBackStage
config
}
def apply(plugins : Seq[Plugin[VexRiscv]] = ArrayBuffer()) : VexRiscvConfig = apply(true,true,plugins)
}
trait VexRiscvRegressionArg{
def getVexRiscvRegressionArgs() : Seq[String]
}
case class VexRiscvConfig(){
var withMemoryStage = true
var withWriteBackStage = true
val plugins = ArrayBuffer[Plugin[VexRiscv]]()
def add(that : Plugin[VexRiscv]) : this.type = {plugins += that;this}
def find[T](clazz: Class[T]): Option[T] = {
plugins.find(_.getClass == clazz) match {
case Some(x) => Some(x.asInstanceOf[T])
case None => None
}
}
def get[T](clazz: Class[T]): T = {
plugins.find(_.getClass == clazz) match {
case Some(x) => x.asInstanceOf[T]
}
}
def withRvc = plugins.find(_.isInstanceOf[IBusFetcher]) match {
case Some(x) => x.asInstanceOf[IBusFetcher].withRvc
case None => false
}
def withRvf = find(classOf[FpuPlugin]) match {
case Some(x) => true
case None => false
}
def withRvd = find(classOf[FpuPlugin]) match {
case Some(x) => x.p.withDouble
case None => false
}
//Default Stageables
object IS_RVC extends Stageable(Bool)
object BYPASSABLE_EXECUTE_STAGE extends Stageable(Bool)
object BYPASSABLE_MEMORY_STAGE extends Stageable(Bool)
object RS1 extends Stageable(Bits(32 bits))
object RS2 extends Stageable(Bits(32 bits))
object RS1_USE extends Stageable(Bool)
object RS2_USE extends Stageable(Bool)
object RESULT extends Stageable(UInt(32 bits))
object PC extends Stageable(UInt(32 bits))
object PC_CALC_WITHOUT_JUMP extends Stageable(UInt(32 bits))
object INSTRUCTION extends Stageable(Bits(32 bits))
object INSTRUCTION_ANTICIPATED extends Stageable(Bits(32 bits))
object LEGAL_INSTRUCTION extends Stageable(Bool)
object REGFILE_WRITE_VALID extends Stageable(Bool)
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
object MPP extends PipelineThing[UInt]
object DEBUG_BYPASS_CACHE extends PipelineThing[Bool]
object SRC1 extends Stageable(Bits(32 bits))
object SRC2 extends Stageable(Bits(32 bits))
object SRC_ADD_SUB extends Stageable(Bits(32 bits))
object SRC_ADD extends Stageable(Bits(32 bits))
object SRC_SUB extends Stageable(Bits(32 bits))
object SRC_LESS extends Stageable(Bool)
object SRC_USE_SUB_LESS extends Stageable(Bool)
object SRC_LESS_UNSIGNED extends Stageable(Bool)
object SRC_ADD_ZERO extends Stageable(Bool)
object HAS_SIDE_EFFECT extends Stageable(Bool)
//Formal verification purposes
object FORMAL_HALT extends Stageable(Bool)
object FORMAL_PC_NEXT extends Stageable(UInt(32 bits))
object FORMAL_MEM_ADDR extends Stageable(UInt(32 bits))
object FORMAL_MEM_RMASK extends Stageable(Bits(4 bits))
object FORMAL_MEM_WMASK extends Stageable(Bits(4 bits))
object FORMAL_MEM_RDATA extends Stageable(Bits(32 bits))
object FORMAL_MEM_WDATA extends Stageable(Bits(32 bits))
object FORMAL_INSTRUCTION extends Stageable(Bits(32 bits))
object Src1CtrlEnum extends SpinalEnum(binarySequential){
val RS, IMU, PC_INCREMENT, URS1 = newElement() //IMU, IMZ IMJB
}
object Src2CtrlEnum extends SpinalEnum(binarySequential){
val RS, IMI, IMS, PC = newElement() //TODO remplacing ZERO could avoid 32 muxes if SRC_ADD can be disabled
}
object SRC1_CTRL extends Stageable(Src1CtrlEnum())
object SRC2_CTRL extends Stageable(Src2CtrlEnum())
def getRegressionArgs() : Seq[String] = {
val str = ArrayBuffer[String]()
plugins.foreach{
case e : VexRiscvRegressionArg => str ++= e.getVexRiscvRegressionArgs()
case _ =>
}
str
}
}
class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
type T = VexRiscv
import config._
//Define stages
def newStage(): Stage = { val s = new Stage; stages += s; s }
val decode = newStage()
val execute = newStage()
val memory = ifGen(config.withMemoryStage) (newStage())
val writeBack = ifGen(config.withWriteBackStage) (newStage())
def stagesFromExecute = stages.dropWhile(_ != execute)
plugins ++= config.plugins
//regression usage
val lastStageInstruction = CombInit(stages.last.input(config.INSTRUCTION)).dontSimplifyIt().addAttribute (Verilator.public)
val lastStagePc = CombInit(stages.last.input(config.PC)).dontSimplifyIt().addAttribute(Verilator.public)
val lastStageIsValid = CombInit(stages.last.arbitration.isValid).dontSimplifyIt().addAttribute(Verilator.public)
val lastStageIsFiring = CombInit(stages.last.arbitration.isFiring).dontSimplifyIt().addAttribute(Verilator.public)
//Verilator perf
decode.arbitration.removeIt.noBackendCombMerge
if(withMemoryStage){
memory.arbitration.removeIt.noBackendCombMerge
}
execute.arbitration.flushNext.noBackendCombMerge
}
|