Add jal instruction
This commit is contained in:
12
bench/tests/op/jal.s
Normal file
12
bench/tests/op/jal.s
Normal file
@@ -0,0 +1,12 @@
|
||||
# expected: 00000004, 0000008, 0000000C
|
||||
.text
|
||||
_start:
|
||||
jal x31, step1
|
||||
step1:
|
||||
jal x31, step2
|
||||
step2:
|
||||
jal x31, step3
|
||||
step3:
|
||||
nop
|
||||
|
||||
|
||||
46
build.sc
46
build.sc
@@ -14,28 +14,28 @@ import mill.bsp._
|
||||
// See: https://github.com/com-lihaoyi/mill/issues/3840
|
||||
|
||||
object `TPchisel` extends SbtModule { m =>
|
||||
override def millSourcePath = super.millSourcePath / os.up
|
||||
override def scalaVersion = "2.13.16"
|
||||
override def scalacOptions = Seq(
|
||||
"-language:reflectiveCalls",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-Xcheckinit",
|
||||
"-Ymacro-annotations",
|
||||
"-unchecked",
|
||||
"-Xfatal-warnings",
|
||||
"-Ywarn-dead-code",
|
||||
"-Ywarn-unused"
|
||||
)
|
||||
override def ivyDeps = Agg(
|
||||
ivy"org.chipsalliance::chisel:7.2.0",
|
||||
)
|
||||
override def scalacPluginIvyDeps = Agg(
|
||||
ivy"org.chipsalliance:::chisel-plugin:7.2.0",
|
||||
)
|
||||
object test extends SbtTests with TestModule.ScalaTest {
|
||||
override def ivyDeps = m.ivyDeps() ++ Agg(
|
||||
ivy"org.scalatest::scalatest::3.2.19"
|
||||
override def millSourcePath = super.millSourcePath / os.up
|
||||
override def scalaVersion = "2.13.16"
|
||||
override def scalacOptions = Seq(
|
||||
"-language:reflectiveCalls",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-Xcheckinit",
|
||||
"-Ymacro-annotations",
|
||||
"-unchecked",
|
||||
"-Xfatal-warnings",
|
||||
"-Ywarn-dead-code",
|
||||
"-Ywarn-unused"
|
||||
)
|
||||
}
|
||||
override def ivyDeps = Agg(
|
||||
ivy"org.chipsalliance::chisel:7.2.0"
|
||||
)
|
||||
override def scalacPluginIvyDeps = Agg(
|
||||
ivy"org.chipsalliance:::chisel-plugin:7.2.0"
|
||||
)
|
||||
object test extends SbtTests with TestModule.ScalaTest {
|
||||
override def ivyDeps = m.ivyDeps() ++ Agg(
|
||||
ivy"org.scalatest::scalatest::3.2.19"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,21 @@ class CUInterface extends Bundle {
|
||||
val alu_opcode = Output(AluOpCode())
|
||||
val optype = Output(OpType())
|
||||
|
||||
// True if the decoded instruction is a jump
|
||||
val is_jump = Output(Bool())
|
||||
|
||||
// Muxers
|
||||
// The naming convention is as follows : mux_xxx_yyy.
|
||||
// If the signal is hot, xxx is selected otherwise yyy is selected
|
||||
val mux_alu_imm = Output(Bool())
|
||||
val mux_rega_pc = Output(Bool())
|
||||
val mux_regb_imm = Output(Bool())
|
||||
val mux_incrpc4_imm = Output(Bool())
|
||||
val mux_regpc_executepc = Output(Bool())
|
||||
}
|
||||
|
||||
object OpType extends ChiselEnum {
|
||||
val U, I, IR = Value
|
||||
val U, I, IR, J = Value
|
||||
}
|
||||
|
||||
object OpCode extends ChiselEnum {
|
||||
@@ -46,6 +51,8 @@ object OpCode extends ChiselEnum {
|
||||
// add, and, or, xor, sll, srl, sra, slt, stlu
|
||||
val OpR = 0b0110011.U;
|
||||
|
||||
// Type J
|
||||
val JAL = 0b1101111.U
|
||||
}
|
||||
|
||||
|
||||
@@ -55,9 +62,12 @@ class ControlUnit() extends Module {
|
||||
io.reg_file_we := false.B
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.optype := OpType.U
|
||||
io.is_jump := false.B;
|
||||
io.mux_alu_imm := true.B;
|
||||
io.mux_rega_pc := true.B;
|
||||
io.mux_regb_imm := true.B;
|
||||
io.mux_incrpc4_imm := true.B;
|
||||
io.mux_regpc_executepc := true.B;
|
||||
|
||||
// Decode instruction
|
||||
val opcode = io.instruction(6, 0);
|
||||
@@ -76,21 +86,33 @@ class ControlUnit() extends Module {
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.reg_file_we := true.B // Write to regfile
|
||||
io.mux_rega_pc := false.B // Send PC to ALU A
|
||||
io.mux_alu_imm := false.B; // Send immu to ALU B
|
||||
io.mux_regb_imm := false.B; // Send immu to ALU B
|
||||
io.optype := OpType.U
|
||||
}
|
||||
|
||||
// OpImm instructions
|
||||
is(OpCode.OpImm) {
|
||||
io.reg_file_we := true.B
|
||||
io.reg_file_we := true.B // Write to regfile
|
||||
opImm(funct3, funct7, io);
|
||||
}
|
||||
|
||||
// OpR instructions
|
||||
is(OpCode.OpR) {
|
||||
io.reg_file_we := true.B
|
||||
io.reg_file_we := true.B // Write to regfile
|
||||
opR(funct3, funct7, io);
|
||||
}
|
||||
|
||||
// J instructions
|
||||
is(OpCode.JAL) {
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.reg_file_we := true.B // Write to regfile
|
||||
io.mux_rega_pc := false.B // Send PC to ALU A
|
||||
io.mux_regb_imm := false.B; // Send imm to ALU B
|
||||
io.is_jump := true.B
|
||||
io.mux_incrpc4_imm := false.B; // Send the immediate in PC
|
||||
io.mux_regpc_executepc := false.B; // Add the immediate to the previous PC
|
||||
io.optype := OpType.J
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,14 @@ class ImmediateDecoder extends Module {
|
||||
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W));
|
||||
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20));
|
||||
val imm_ir = io.instruction(24, 20);
|
||||
val imm_j = Cat(
|
||||
Fill(11, io.instruction(31)),
|
||||
io.instruction(31),
|
||||
io.instruction(19, 12),
|
||||
io.instruction(20),
|
||||
io.instruction(30, 21),
|
||||
0.U
|
||||
);
|
||||
|
||||
switch(io.op_type) {
|
||||
is(OpType.U) {
|
||||
@@ -31,5 +39,8 @@ class ImmediateDecoder extends Module {
|
||||
is(OpType.IR) {
|
||||
io.immediate := imm_ir
|
||||
}
|
||||
is(OpType.J) {
|
||||
io.immediate := imm_j
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,32 +12,38 @@ class Rv32i(sim: Boolean = true) extends Module {
|
||||
|
||||
val reg_pc = RegInit(0.U(32.W));
|
||||
val reg_file = Module(new RegFile(sim));
|
||||
val instruction = io.ibus.rdata;
|
||||
|
||||
reg_file.io.rd_data := 0.U;
|
||||
io.x31 := reg_file.io.x31
|
||||
if (sim) {
|
||||
io.valid_x31.get := reg_file.io.valid_x31.get && Delay.Delay(
|
||||
!reset.asBool,
|
||||
1,
|
||||
false.B
|
||||
)
|
||||
io.valid_x31.get := reg_file.io.valid_x31.get
|
||||
}
|
||||
|
||||
val alu = Module(new Alu());
|
||||
val immediate_decoder = Module(new ImmediateDecoder());
|
||||
val control_unit = Module(new ControlUnit());
|
||||
|
||||
// PC delayed to execute stage for auipc op
|
||||
val execute_pc = Delay.Delay(reg_pc, 1, 0.U);
|
||||
// True if the instruction in the execute stage is a jump
|
||||
val is_jump = Delay.Delay(control_unit.io.is_jump, 1, false.B);
|
||||
val instruction = Mux(is_jump, 0b00000000000000000000000000010011.U, io.ibus.rdata);
|
||||
|
||||
immediate_decoder.io.instruction := instruction
|
||||
immediate_decoder.io.op_type := control_unit.io.optype
|
||||
alu.io.opcode := control_unit.io.alu_opcode;
|
||||
reg_file.io.we := control_unit.io.reg_file_we
|
||||
|
||||
// Increment PC each clock
|
||||
reg_pc := reg_pc + 4.U;
|
||||
|
||||
// PC delayed to execute stage for auipc op
|
||||
val execute_pc = Delay.Delay(reg_pc, 1, 0.U);
|
||||
reg_pc := Mux(
|
||||
control_unit.io.mux_regpc_executepc,
|
||||
reg_pc,
|
||||
execute_pc
|
||||
) + Mux(
|
||||
control_unit.io.mux_incrpc4_imm,
|
||||
4.U,
|
||||
immediate_decoder.io.immediate
|
||||
);
|
||||
|
||||
// Fetch instruction
|
||||
io.ibus.en := true.B;
|
||||
|
||||
@@ -24,7 +24,7 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
|
||||
// clock et reset sont les signaux implicites
|
||||
clkg.io.clk_in1 := clock
|
||||
clkg.io.reset := reset
|
||||
val rst = (reset.asBool || !clkg.io.locked).asAsyncReset
|
||||
val rst = reset.asBool || !clkg.io.locked
|
||||
|
||||
// Ces deux IPs doivent tourner à 125 MHz
|
||||
val vmem = Module(new IDMem(sim, 17))
|
||||
@@ -34,7 +34,7 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
|
||||
vgad.io.clk := clkg.io.clk_out2 // Clock pixel
|
||||
|
||||
// Expose core for testing usage
|
||||
val core = withClockAndReset(clkg.io.clk_out1, rst) {
|
||||
withClockAndReset(clkg.io.clk_out1, rst) {
|
||||
val interconnect = Module(new BusInterconnect)
|
||||
val core = Module(new Rv32i(sim))
|
||||
val dmem = Module(new IDMem(sim, 16, file))
|
||||
@@ -70,7 +70,5 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
|
||||
io.r := vgad.io.r
|
||||
io.g := vgad.io.g
|
||||
io.b := vgad.io.b
|
||||
|
||||
core
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user