Skip to content

Commit a5dfc98

Browse files
committed
Merge branch 'tc-l3' into dev
2 parents c458e31 + a83cfd4 commit a5dfc98

File tree

6 files changed

+325
-0
lines changed

6 files changed

+325
-0
lines changed

rtl/.scalafmt.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ align.tokens.add = [
2424
},
2525
{
2626
code = "="
27+
},
28+
{
29+
code = "&&"
30+
},
31+
{
32+
code = "||"
33+
},
34+
{
35+
code = "==="
2736
}
2837
]
2938

rtl/tc_l3/src/main/scala/core/ALU.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,40 @@ object ALU {
1919
val ALU_COPY_B = 11.U(ALUOperLen.W)
2020
val ALU_XXX = 15.U(ALUOperLen.W)
2121
}
22+
23+
class ALUIo(implicit p: Parameters) extends Bundle {
24+
val A = Input(UInt(xlen.W))
25+
val B = Input(UInt(xlen.W))
26+
val alu_op = Input(UInt(4.W))
27+
val out = Output(UInt(xlen.W))
28+
val sum = Output(UInt(xlen.W))
29+
}
30+
31+
class ALU(implicit p: Parameters) extends Module {
32+
val sum = io.A + Mux(io.alu_op(0), -io.B, io.B)
33+
val cmp = Mux(io.A(xlen - 1) === io.B(xlen - 1), sum(xlen - 1), Mux(io.alu_op(1), io.B(xlen - 1), io.A(xlen - 1)))
34+
val shamt = io.B(4, 0).asUInt
35+
val shin = Mux(io.alu_op(3), io.A, Reverse(io.A))
36+
val shiftr = (Cat(io.alu_op(0) && shin(xlen - 1), shin).asSInt >> shamt)(xlen - 1, 0)
37+
val shiftl = Reverse(shiftr)
38+
39+
val out = MuxLookup(
40+
io.alu_op,
41+
io.B,
42+
Seq(
43+
ALU.ALU_ADD -> sum,
44+
ALU.ALU_SUB -> sum,
45+
ALU.ALU_SLT -> cmp,
46+
ALU.ALU_SLTU -> cmp,
47+
ALU.ALU_SRA -> shiftr,
48+
ALU.ALU_SRL -> shiftr,
49+
ALU.ALU_SLL -> shiftl,
50+
ALU.ALU_AND -> (io.A & io.B),
51+
ALU.ALU_OR -> (io.A | io.B),
52+
ALU.ALU_XOR -> (io.A ^ io.B),
53+
ALU.ALU_COPY_A -> io.A
54+
)
55+
)
56+
io.out := out
57+
io.sum := sum
58+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package treecorel3
2+
3+
import chisel._
4+
import chisel.uitl._
5+
6+
class BrCondIO(implicit p: Parameters) extends CoreBundle()(p) {
7+
val rs1 = Input(UInt(xlen.W))
8+
val rs2 = Input(UInt(xlen.W))
9+
val br_type = Input(UInt(3.W))
10+
val taken = Output(Bool())
11+
}
12+
13+
class BrCond(implicit val p: Parameters) extends Module {
14+
val io = IO(new BrCondIO)
15+
val diff = io.rs1 - io.rs2
16+
val neq = diff.orR
17+
val eq = !neq
18+
val isSameSign = io.rs1(xlen - 1) === io.rs2(xlen - 1)
19+
val lt = Mux(isSameSign, diff(xlen - 1), io.rs1(xlen - 1))
20+
val ltu = Mux(isSameSign, diff(xlen - 1), io.rs2(xlen - 1))
21+
val ge = !lt
22+
val geu = !ltu
23+
io.taken :=
24+
((io.br_type === Control.BR_EQ) && eq) ||
25+
((io.br_type === Control.BR_NE) && neq) ||
26+
((io.br_type === Control.BR_LT) && lt) ||
27+
((io.br_type === Control.BR_GE) && ge) ||
28+
((io.br_type === Control.BR_LTU) && ltu) ||
29+
((io.br_type === Control.BR_GEU) && geu)
30+
}
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package treecorel3
2+
3+
import chisel._
4+
import chisel.util._
5+
6+
object Const {
7+
val PC_START = 0x200
8+
val PC_EVEC = 0x100
9+
}
10+
11+
class DataPathIO(implicit p: Parameters) extends Bundle {
12+
val host = new HostIO
13+
val icache = Flipped(new CacheIO)
14+
val dcache = Flipped(new CacheIO)
15+
val ctrl = Flipped(new ControlIO)
16+
}
17+
18+
class Datapath(implicit val p: Parameters) extends Module {
19+
val io = IO(new DataPathIO)
20+
val csr = Module(new CSR)
21+
val regFile = Module(new RegFile)
22+
val alu = Module(new ALU)
23+
val immGen = Module(new IMMGen)
24+
val brCond = p(BuildBrCond)(p)
25+
26+
import Control._
27+
28+
// fetch / execute Register
29+
val fe_inst = RegInit(Instruction.NOP)
30+
val fe_pc = Reg(UInt())
31+
32+
// execute / write Back Registers
33+
val ew_inst = RegInit(Instruction.NOP)
34+
val ew_pc = Reg(UInt())
35+
val ew_alu = Reg(UInt())
36+
val csr_in = Reg(UInt())
37+
38+
// control signals
39+
val st_type = Reg(io.ctrl.st_type.cloneType)
40+
val ld_type = Reg(io.ctrl.ld_type.cloneType)
41+
val wb_sel = Reg(io.ctrl.wb_sel.cloneType)
42+
val wb_en = Reg(Bool())
43+
val csr_cmd = Reg(io.ctrl.csr_cmd.cloneType)
44+
val illegal = Reg(Bool())
45+
val pc_check = Reg(Bool())
46+
47+
// fetch
48+
val started = RegNext(reset.asBool())
49+
val stall = !io.icache.resp.valid || !io.dcache.resp.valid
50+
val pc = RegInit(Const.PC_START.U(xlen.W) - 4.U(xlen.W))
51+
val npc = Mux(
52+
stall,
53+
pc,
54+
Mux(
55+
csr.io.expt,
56+
csr.io.evec,
57+
Mux(io.ctrl.pc_sel === PC_EPC, csr.io.epc, Mux(io.ctrl.pc_sel === PC_ALU || brCond.io.taken, alu.io.sum >> 1.U << 1.U, Mux(io.ctrl.pc_sel === PC_0, pc, pc + 4.U)))
58+
)
59+
)
60+
val inst = Mux(started || io.ctrl.inst_kill || brCond.io.taken || csr.io.expt, Instruction.NOP, io.icache.resp.bits.data)
61+
pc := npc
62+
io.icache.req.bits.addr := npc
63+
io.icache.req.bits.data := 0.U
64+
io.icache.req.bits.mask := 0.U
65+
io.icache.req.valid := !stall
66+
io.icache.abort := false.B
67+
68+
// Pipelining
69+
when(!stall) {
70+
fe_pc := pc
71+
fe_inst := inst
72+
}
73+
74+
// execute
75+
// decode
76+
io.ctrl.inst := fe_inst
77+
78+
// regFile read
79+
val rd_addr = fe_inst(11, 7)
80+
val rs1_addr = fe_inst(19, 15)
81+
val rs2_addr = fe_inst(24, 20)
82+
regFile.io.raddr1 := rs1_addr
83+
regFile.io.raddr2 := rs2_addr
84+
85+
// gen immdeates
86+
immGen.io.inst := fe_inst
87+
immGen.io.sel := io.ctrl.imm_sel
88+
89+
// bypass
90+
val wb_rd_addr = ew_inst(11, 7)
91+
val rs1hazard = wb_en && rs1_addr.orR && (rs1_addr === wb_rd_addr)
92+
val rs2hazard = wb_en && rs2_addr.orR && (rs2_addr === wb_rd_addr)
93+
val rs1 = Mux(wb_sel === WB_ALU && rs1hazard, ew_alu, regFile.io.rdata1)
94+
val rs2 = Mux(wb_sel === WB_ALU && rs2hazard, ew_alu, regFile.io.rdata2)
95+
96+
// ALU operations
97+
alu.io.A := Mux(io.ctrl.A_sel === A_RS1, rs1, fe_pc)
98+
alu.io.B := Mux(io.ctrl.B_sel === B_RS2, rs2, immGen.io.out)
99+
alu.io.alu_op := io.ctrl.alu_op
100+
101+
// Branch condition calc
102+
brCond.io.rs1 := rs1
103+
brCond.io.rs2 := rs2
104+
brCond.io.br_type := io.ctrl.br_type
105+
106+
// dcache access
107+
val daddr = Mux(stall, ew_alu, alu.io.sum) >> 2.U << 2.U
108+
val woffset = alu.io.sum(1) << 4.U | alu.io.sum(0) << 3.U
109+
io.dcache.req.valid := !stall && (io.ctrl.st_type.orR || io.ctrl.ld_type.orR)
110+
io.dcache.req.bits.addr := daddr
111+
io.dcache.req.bits.data := rs2 << woffset
112+
io.dcache.req.bits.mask := MuxLookup(
113+
Mux(stall, st_type, io.ctrl.st_type),
114+
"b0000".U,
115+
Seq(
116+
ST_SW -> "b1111".U,
117+
ST_SH -> ("b11".U << alu.io.sum(1, 0)),
118+
ST_SB -> ("b1".U << alu.io.sum(1, 0))
119+
)
120+
)
121+
122+
// pipelining
123+
when(reset.asBool() || !stall && csr.io.expt) {
124+
st_type := 0.U
125+
ld_type := 0.U
126+
wb_en := false.B
127+
csr_cmd := 0.U
128+
illegal := false.B
129+
pc_check := false.B
130+
}.elsewhen(!stall && !csr.io.expt) {
131+
ew_pc := fe_pc
132+
ew_inst := fe_inst
133+
ew_alu := alu.io.out
134+
csr_in := Mux(io.ctrl.imm_sel === IMM_Z, immGen.io.out, rs1)
135+
st_type := io.ctrl.st_type
136+
ld_type := io.ctrl.ld_type
137+
wb_sel := io.ctrl.wb_sel
138+
wb_en := io.ctrl.wb_en
139+
csr_cmd := io.ctrl.csr_cmd
140+
illegal := io.ctrl.illegal
141+
pc_check := io.ctrl.pc_sel === PC_ALU
142+
}
143+
144+
// load
145+
val loffset = ew_alu(1) << 4.U | ew_alu(0) << 3.U
146+
val lshift = io.dcache.resp.bits.data >> loffset
147+
val load = MuxLookup(
148+
ld_type,
149+
io.dcache.resp.bits.data.zext,
150+
Seq(
151+
LD_LH -> lshift(15, 0).asSInt,
152+
LD_LB -> lshift(7, 0).asSInt,
153+
LD_LHU -> lshift(15, 0).zext,
154+
LD_LBU -> lshift(7, 0).zext
155+
)
156+
)
157+
158+
// CSR access
159+
csr.io.stall := stall
160+
csr.io.in := csr_in
161+
csr.io.cmd := csr_cmd
162+
csr.io.inst := ew_inst
163+
csr.io.pc := ew_pc
164+
csr.io.addr := ew_alu
165+
csr.io.illegal := illegal
166+
csr.io.pc_check := pc_check
167+
csr.io.ld_type := ld_type
168+
csr.io.st_type := st_type
169+
io.host <> csr.io.host
170+
171+
// Regfile Write
172+
val regWrite = MuxLookup(
173+
wb_sel,
174+
ew_alu.zext,
175+
Seq(
176+
WB_MEM -> load,
177+
WB_PC4 -> (ew_pc + 4.U).zext,
178+
WB_CSR -> csr.io.out.zext
179+
)
180+
).asUInt
181+
182+
regFile.io.wen := wb_en && !stall && !csr.io.expt
183+
regFile.io.waddr := wb_rd_addr
184+
regFile.io.wdata := regWrite
185+
186+
// Abort store when there's an excpetion
187+
io.dcache.abort := csr.io.expt
188+
189+
if (p(Trace)) {
190+
printf("PC: %x, INST: %x, REG[%d] <- %x\n", ew_pc, ew_inst, Mux(regFile.io.wen, wb_rd_addr, 0.U), Mux(regFile.io.wen, regFile.io.wdata, 0.U))
191+
}
192+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package treecorel3
2+
3+
import chisel._
4+
import chiesl.uitl._
5+
6+
class ImmGenIO(implicit p: Parameters) extends Bundle {
7+
val inst = Input(UInt(xlen.W))
8+
val sel = Input(UInt(3.W))
9+
val out = Output(UInt(xlen.W))
10+
}
11+
12+
class ImmGen(implicit p: Parameters) extends Module {
13+
val io = IO(new ImmGenIO)
14+
val Iimm = io.inst(31, 20).asSInt
15+
val Simm = Cat(io.inst(31, 25), io.inst(11, 7)).asSInt
16+
val Bimm = Cat(io.inst(31), io.inst(7), io.inst(30, 25), io.inst(11, 8), 0.U(1.W)).asSInt
17+
val Uimm = Cat(io.inst(31, 12), 0.U(12.W)).asSInt
18+
val Jimm = Cat(io.inst(31), io.inst(19, 12), io.inst(20), io.inst(30, 25), io.inst(24, 21), 0.U(1.W)).asSInt
19+
val Zimm = io.inst(19, 15).zext
20+
21+
io.out := MuxLookup(
22+
io.sel,
23+
Iimm & -2.S,
24+
Seq(
25+
IMM_I -> Iimm,
26+
IMM_S -> Simm,
27+
IMM_B -> Bimm,
28+
IMM_U -> Uimm,
29+
IMM_J -> Jimm,
30+
IMM_Z -> Zimm
31+
)
32+
).asUInt
33+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package treecorel3
2+
3+
import chisel._
4+
import chisel.uitl._
5+
6+
class RegFileIO(implicit p: Parameters) extends Bundle {
7+
val raddr1 = Input(UInt(5.W))
8+
val raddr2 = Input(UInt(5.W))
9+
val rdata1 = Output(UInt(xlen.W))
10+
val rdata2 = Output(UInt(xlen.W))
11+
val wen = Input(Bool())
12+
val waddr = Input(UInt(5.W))
13+
val wdata = Input(UInt(xlen.W))
14+
}
15+
16+
class RegFile(implicit val p: Parameters) extends Module {
17+
val io = IO(new RegFileIO)
18+
val regs = Mem(32, UInt(xlen.W)) // NOTE: right?
19+
io.rdata1 := Mux(io.raddr1.orR, regs(io.raddr1), 0.U)
20+
io.rdata2 := Mux(io.raddr2.orR, regs(io.raddr2), 0.U)
21+
when(io.wen & io.waddr.orR) {
22+
regs(io.waddr) := io.wdata
23+
}
24+
}

0 commit comments

Comments
 (0)