opcode = Signal(7, name="decoder_opcode")
act = Signal(decode_action, name="decoder_action")
+class MStatus:
+ def __init__(self, comb):
+ self.comb = comb
+ self.mpie = Signal(name="mstatus_mpie")
+ self.mie = Signal(name="mstatus_mie")
+ self.mprv = Signal(name="mstatus_mprv")
+ self.tsr = Signal(name="mstatus_tsr")
+ self.tw = Signal(name="mstatus_tw")
+ self.tvm = Signal(name="mstatus_tvm")
+ self.mxr = Signal(name="mstatus_mxr")
+ self._sum = Signal(name="mstatus_sum")
+ self.xs = Signal(name="mstatus_xs")
+ self.fs = Signal(name="mstatus_fs")
+ self.mpp = Signal(2, name="mstatus_mpp")
+ self.spp = Signal(name="mstatus_spp")
+ self.spie = Signal(name="mstatus_spie")
+ self.upie = Signal(name="mstatus_upie")
+ self.sie = Signal(name="mstatus_sie")
+ self.uie = Signal(name="mstatus_uie")
+
+ for n in dir(self):
+ if n in ['mpp', 'comb'] or n.startswith("_"):
+ continue
+ self.comb += getattr(self, n).eq(0x0)
+ self.comb += self.mpp.eq(0b11)
+
class CPU(Module):
"""
dc.immediate,
dc.immediate + fetch_output_pc))
+ self.comb += fetch_target_pc.eq(Cat(0,
+ Mux(dc.opcode != OP.jalr,
+ fetch_output_pc[1:32],
+ register_rs1[1:32] + dc.immediate[1:32])))
+
+ misaligned_jump_target = Signal()
+ self.comb += misaligned_jump_target.eq(fetch_target_pc[1])
+
+ branch_arg_a = Signal(32)
+ branch_arg_b = Signal(32)
+ self.comb += branch_arg_a.eq(Cat( register_rs1[0:31],
+ register_rs1[31] ^ ~dc.funct3[1]))
+ self.comb += branch_arg_b.eq(Cat( register_rs2[0:31],
+ register_rs2[31] ^ ~dc.funct3[1]))
+
+ branch_taken = Signal()
+ self.comb += branch_taken.eq(dc.funct3[0] ^
+ Mux(dc.funct3[2],
+ branch_arg_a < branch_arg_b,
+ branch_arg_a == branch_arg_b))
+
+ mcause = Signal(32)
+ mepc = Signal(32)
+ mscratch = Signal(32)
+ self.comb += mcause.eq(0)
+ self.comb += mepc.eq(0) # 32'hXXXXXXXX;
+ self.comb += mscratch.eq(0) # 32'hXXXXXXXX;
+
+ mstatus = MStatus(self.comb)
+
if __name__ == "__main__":
example = CPU()
print(verilog.convert(example,
"""
- wire [31:0] lui_auipc_result = decoder_opcode[5] ? decoder_immediate : decoder_immediate + fetch_output_pc;
-
- assign fetch_target_pc[31:1] = ((decoder_opcode != `opcode_jalr ? fetch_output_pc[31:1] : register_rs1[31:1]) + decoder_immediate[31:1]);
- assign fetch_target_pc[0] = 0;
-
- wire misaligned_jump_target = fetch_target_pc[1];
-
- wire [31:0] branch_arg_a = {register_rs1[31] ^ ~decoder_funct3[1], register_rs1[30:0]};
- wire [31:0] branch_arg_b = {register_rs2[31] ^ ~decoder_funct3[1], register_rs2[30:0]};
-
- wire branch_taken = decoder_funct3[0] ^ (decoder_funct3[2] ? branch_arg_a < branch_arg_b : branch_arg_a == branch_arg_b);
-
- reg [31:0] mcause = 0;
- reg [31:0] mepc = 32'hXXXXXXXX;
- reg [31:0] mscratch = 32'hXXXXXXXX;
-
- reg mstatus_mpie = 1'bX;
- reg mstatus_mie = 0;
- parameter mstatus_mprv = 0;
- parameter mstatus_tsr = 0;
- parameter mstatus_tw = 0;
- parameter mstatus_tvm = 0;
- parameter mstatus_mxr = 0;
- parameter mstatus_sum = 0;
- parameter mstatus_xs = 0;
- parameter mstatus_fs = 0;
- parameter mstatus_mpp = 2'b11;
- parameter mstatus_spp = 0;
- parameter mstatus_spie = 0;
- parameter mstatus_upie = 0;
- parameter mstatus_sie = 0;
- parameter mstatus_uie = 0;
-
reg mie_meie = 1'bX;
reg mie_mtie = 1'bX;
reg mie_msie = 1'bX;