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
|
package vexriscv.plugin
import vexriscv._
import spinal.core._
import spinal.lib.KeepAttribute
class SrcPlugin(separatedAddSub : Boolean = false, executeInsertion : Boolean = false, decodeAddSub : Boolean = false) extends Plugin[VexRiscv]{
object SRC2_FORCE_ZERO extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(SRC_ADD_ZERO, False) //TODO avoid this default to simplify decoding ?
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
decode.insert(SRC2_FORCE_ZERO) := decode.input(SRC_ADD_ZERO) && !decode.input(SRC_USE_SUB_LESS)
val insertionStage = if(executeInsertion) execute else decode
insertionStage plug new Area{
import insertionStage._
val imm = Riscv.IMM(input(INSTRUCTION))
insert(SRC1) := input(SRC1_CTRL).mux(
Src1CtrlEnum.RS -> output(RS1),
Src1CtrlEnum.PC_INCREMENT -> (if(pipeline.config.withRvc) Mux(input(IS_RVC), B(2), B(4)) else B(4)).resized,
Src1CtrlEnum.IMU -> imm.u.resized,
Src1CtrlEnum.URS1 -> input(INSTRUCTION)(Riscv.rs1Range).resized
)
insert(SRC2) := input(SRC2_CTRL).mux(
Src2CtrlEnum.RS -> output(RS2),
Src2CtrlEnum.IMI -> imm.i_sext.resized,
Src2CtrlEnum.IMS -> imm.s_sext.resized,
Src2CtrlEnum.PC -> output(PC).asBits
)
}
val addSubStage = if(decodeAddSub) decode else execute
if(separatedAddSub) {
addSubStage plug new Area {
import addSubStage._
// ADD, SUB
val add = (U(input(SRC1)) + U(input(SRC2))).asBits.addAttribute("keep")
val sub = (U(input(SRC1)) - U(input(SRC2))).asBits.addAttribute("keep")
when(input(SRC_ADD_ZERO)){ add := input(SRC1) }
// SLT, SLTU
val less = Mux(input(SRC1).msb === input(SRC2).msb, sub.msb,
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb))
insert(SRC_ADD_SUB) := input(SRC_USE_SUB_LESS) ? sub | add
insert(SRC_ADD) := add
insert(SRC_SUB) := sub
insert(SRC_LESS) := less
}
}else{
addSubStage plug new Area {
import addSubStage._
// ADD, SUB
val addSub = (input(SRC1).asSInt + Mux(input(SRC_USE_SUB_LESS), ~input(SRC2), input(SRC2)).asSInt + Mux(input(SRC_USE_SUB_LESS), S(1, 32 bits), S(0, 32 bits))).asBits
when(input(SRC2_FORCE_ZERO)){ addSub := input(SRC1) }
// SLT, SLTU
val less = Mux(input(SRC1).msb === input(SRC2).msb, addSub.msb,
Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb))
insert(SRC_ADD_SUB) := addSub
insert(SRC_ADD) := addSub
insert(SRC_SUB) := addSub
insert(SRC_LESS) := less
}
}
}
}
|