Stage 6: implementation, untested
This commit is contained in:
9
bench/op/andi.s
Normal file
9
bench/op/andi.s
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# expected: 00000000, 00000010
|
||||||
|
.text
|
||||||
|
_start:
|
||||||
|
addi x1, x0, 0x100
|
||||||
|
andi x31, x1, 0x0FF
|
||||||
|
|
||||||
|
addi x1, x0, -1
|
||||||
|
andi x31, x1, 0x010
|
||||||
|
|
||||||
4
bench/op/ori.s
Normal file
4
bench/op/ori.s
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# expected: 00000000, 00000010
|
||||||
|
.text
|
||||||
|
_start:
|
||||||
|
|
||||||
@@ -4,9 +4,9 @@ import chisel3._
|
|||||||
import chisel3.util.switch
|
import chisel3.util.switch
|
||||||
import chisel3.util.is
|
import chisel3.util.is
|
||||||
|
|
||||||
object AluOpCode extends ChiselEnum
|
object AluOpCode extends ChiselEnum {
|
||||||
{
|
val Add, And, Or, Xor, ShiftLeft, ShiftRight, ShiftArithmeticRight,
|
||||||
val Add = Value
|
LessThanSigned, LessThanUnsigned = Value
|
||||||
}
|
}
|
||||||
|
|
||||||
class Alu extends Module {
|
class Alu extends Module {
|
||||||
@@ -21,12 +21,43 @@ class Alu extends Module {
|
|||||||
|
|
||||||
io.out := 0.U;
|
io.out := 0.U;
|
||||||
|
|
||||||
switch(io.opcode)
|
switch(io.opcode) {
|
||||||
{
|
is(Add) {
|
||||||
is(Add)
|
|
||||||
{
|
|
||||||
io.out := io.a + io.b;
|
io.out := io.a + io.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is(And) {
|
||||||
|
io.out := io.a & io.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Or) {
|
||||||
|
io.out := io.a | io.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Xor) {
|
||||||
|
io.out := io.a ^ io.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
is(ShiftLeft) {
|
||||||
|
io.out := io.a << io.b(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
is(ShiftRight) {
|
||||||
|
io.out := io.a >> io.b(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
is(ShiftArithmeticRight) {
|
||||||
|
// >> means arithmetic shift for SInts
|
||||||
|
io.out := (io.a.asSInt >> io.b(4, 0)).asUInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
is(LessThanUnsigned) {
|
||||||
|
io.out := io.a < io.b
|
||||||
|
}
|
||||||
|
|
||||||
|
is(LessThanSigned) {
|
||||||
|
io.out := io.a.asSInt < io.b.asSInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,18 +15,29 @@ class CUInterface extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object OpType extends ChiselEnum {
|
object OpType extends ChiselEnum {
|
||||||
val U, I = Value
|
val U, I, IR = Value
|
||||||
}
|
}
|
||||||
|
|
||||||
object OpCode extends ChiselEnum {
|
object OpCode extends ChiselEnum {
|
||||||
|
// Type U
|
||||||
val LUI = 0b0110111.U
|
val LUI = 0b0110111.U
|
||||||
val AUIPC = 0b0010111.U
|
val AUIPC = 0b0010111.U
|
||||||
val ADDI = 0b0010011.U
|
|
||||||
|
// Type I + Type IR
|
||||||
|
|
||||||
|
// Instruction format
|
||||||
|
// xxx rd, rs1 imm
|
||||||
|
// Perfomrs some operation with rs1 and immediate
|
||||||
|
// and writes back to a register
|
||||||
|
|
||||||
|
// addi, andi, ori, xori, slli, srli, srai,
|
||||||
|
// slti, sltiu
|
||||||
|
val OpImm = 0b0010011.U
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ControlUnit() extends Module {
|
|
||||||
import OpCode._
|
|
||||||
|
|
||||||
|
class ControlUnit() extends Module {
|
||||||
val io = IO(new CUInterface())
|
val io = IO(new CUInterface())
|
||||||
|
|
||||||
io.reg_file_we := false.B
|
io.reg_file_we := false.B
|
||||||
@@ -34,26 +45,111 @@ class ControlUnit() extends Module {
|
|||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
io.mux_alu_imm := true.B;
|
io.mux_alu_imm := true.B;
|
||||||
io.mux_rega_pc := true.B;
|
io.mux_rega_pc := true.B;
|
||||||
switch(io.instruction(6, 0)) {
|
|
||||||
|
// Decode instruction
|
||||||
|
val opcode = io.instruction(6, 0);
|
||||||
|
val funct3 = io.instruction(14, 12);
|
||||||
|
val funct7 = io.instruction(31, 25);
|
||||||
|
|
||||||
|
switch(opcode) {
|
||||||
|
|
||||||
// U instructions
|
// U instructions
|
||||||
is(LUI) {
|
is(OpCode.LUI) {
|
||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B
|
||||||
io.mux_alu_imm := false.B
|
io.mux_alu_imm := false.B
|
||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
}
|
}
|
||||||
is(AUIPC) {
|
is(OpCode.AUIPC) {
|
||||||
io.alu_opcode := AluOpCode.Add
|
io.alu_opcode := AluOpCode.Add
|
||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B
|
||||||
io.mux_rega_pc := false.B
|
io.mux_rega_pc := false.B
|
||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
}
|
}
|
||||||
|
|
||||||
// I instructions
|
// OpImm instructions
|
||||||
is(ADDI) {
|
is(OpCode.OpImm) {
|
||||||
io.alu_opcode := AluOpCode.Add
|
|
||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B
|
||||||
|
opImm(funct3, funct7, io);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements functions for all instruction of the opImm kind
|
||||||
|
def opImm(funct3: UInt, funct7: UInt, io: CUInterface) =
|
||||||
|
{
|
||||||
|
// Meaning of Funct3 in the context of an OpImm instruction
|
||||||
|
object Funct3 extends ChiselEnum
|
||||||
|
{
|
||||||
|
// Type I
|
||||||
|
val ADDI = 000.U
|
||||||
|
val SLTI = 010.U
|
||||||
|
val SLTIU = 011.U
|
||||||
|
val XORI = 100.U
|
||||||
|
val ORI = 110.U
|
||||||
|
val ANDI = 111.U
|
||||||
|
|
||||||
|
// Type IR
|
||||||
|
val SLLI = 001.U
|
||||||
|
val SRLI_SRAI = 101.U // Right shifts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meaning of Funct7 in the context of SHIFTR IR instructions
|
||||||
|
object IRFunct7 extends ChiselEnum
|
||||||
|
{
|
||||||
|
val SRLI = 0000000.U
|
||||||
|
val SRAI = 0100000.U
|
||||||
|
}
|
||||||
|
switch(funct3)
|
||||||
|
{
|
||||||
|
// Type I
|
||||||
|
is(Funct3.ADDI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Add
|
||||||
io.optype := OpType.I
|
io.optype := OpType.I
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is(Funct3.ANDI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.And
|
||||||
|
io.optype := OpType.I
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.ORI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Or
|
||||||
|
io.optype := OpType.I
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.XORI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Xor
|
||||||
|
io.optype := OpType.I
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.SLLI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftLeft
|
||||||
|
io.optype := OpType.I
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type IR
|
||||||
|
is(Funct3.SRLI_SRAI)
|
||||||
|
{
|
||||||
|
io.optype := OpType.IR
|
||||||
|
switch(funct7)
|
||||||
|
{
|
||||||
|
is(IRFunct7.SRLI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftRight
|
||||||
|
}
|
||||||
|
|
||||||
|
is(IRFunct7.SRAI)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftArithmeticRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ class ImmediateDecoder extends Module {
|
|||||||
})
|
})
|
||||||
io.immediate := 0.U
|
io.immediate := 0.U
|
||||||
|
|
||||||
// Decode imm-u
|
// Decode and construct immediates
|
||||||
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W));
|
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W));
|
||||||
// Decode imm-i
|
|
||||||
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20));
|
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20));
|
||||||
|
val imm_ir = io.instruction(24, 20);
|
||||||
|
|
||||||
switch(io.op_type) {
|
switch(io.op_type) {
|
||||||
is(OpType.U) {
|
is(OpType.U) {
|
||||||
io.immediate := imm_u
|
io.immediate := imm_u
|
||||||
@@ -27,5 +28,8 @@ class ImmediateDecoder extends Module {
|
|||||||
is(OpType.I) {
|
is(OpType.I) {
|
||||||
io.immediate := imm_i
|
io.immediate := imm_i
|
||||||
}
|
}
|
||||||
|
is(OpType.IR) {
|
||||||
|
io.immediate := imm_ir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ class Rv32i(sim: Boolean = true) extends Module {
|
|||||||
reg_file.io.rd_data := 0.U;
|
reg_file.io.rd_data := 0.U;
|
||||||
io.x31 := reg_file.io.x31
|
io.x31 := reg_file.io.x31
|
||||||
if (sim) {
|
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 && Delay.Delay(
|
||||||
|
!reset.asBool,
|
||||||
|
1,
|
||||||
|
false.B
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val alu = Module(new Alu());
|
val alu = Module(new Alu());
|
||||||
|
|||||||
Reference in New Issue
Block a user