return Case(csr_number, c)
+ def main_block(self, mi, m, mstatus, ft, dc, load_store_misaligned,
+ loaded_value, alu_result,
+ lui_auipc_result, fetch_output_pc):
+ c = {}
+ c[FOS.empty] = []
+ c[FOS.trap] = self.handle_trap(m, mstatus, ft, dc,
+ load_store_misaligned)
+ c[FOS.valid] = self.handle_valid(mi, m, mstatus, ft, dc,
+ load_store_misaligned,
+ loaded_value,
+ alu_result,
+ lui_auipc_result,
+ fetch_output_pc)
+ return Case(ft.output_state, c)
+
+ def handle_valid(self, mi, m, mstatus, ft, dc, load_store_misaligned,
+ loaded_value, alu_result,
+ lui_auipc_result, fetch_output_pc):
+ # fetch action ack trap
+ i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap),
+ self.handle_trap(m, mstatus, ft, dc,
+ load_store_misaligned)
+ )
+
+ # load
+ i = i.Elif((dc.act & DA.load) != 0,
+ If(~mi.rw_wait,
+ self.write_register(dc.rd, loaded_value)
+ )
+ )
+
+ # op or op_immediate
+ i = i.Elif((dc.act & DA.op_op_imm) != 0,
+ self.write_register(dc.rd, alu_result)
+ )
+
+ # lui or auipc
+ i = i.Elif((dc.act & DA.lui_auipc) != 0,
+ self.write_register(dc.rd, lui_auipc_result)
+ )
+
+ # jal/jalr
+ i = i.Elif((dc.act & (DA.jal | DA.jalr)) != 0,
+ self.write_register(dc.rd, fetch_output_pc + 4)
+ )
+
+ # fence, store, branch
+ i = i.Elif((dc.act & (DA.fence | DA.fence_i |
+ DA.store | DA.branch)) != 0,
+ # do nothing
+ )
+
+ return i
+
+ """
+ else if((decode_action & `decode_action_csr) != 0) begin:csr
+ reg [31:0] csr_output_value;
+ reg [31:0] csr_written_value;
+ csr_output_value = 32'hXXXXXXXX;
+ csr_written_value = 32'hXXXXXXXX;
+ case(csr_number)
+ `csr_cycle: begin
+ csr_output_value = cycle_counter[31:0];
+ end
+ `csr_time: begin
+ csr_output_value = time_counter[31:0];
+ end
+ `csr_instret: begin
+ csr_output_value = instret_counter[31:0];
+ end
+ `csr_cycleh: begin
+ csr_output_value = cycle_counter[63:32];
+ end
+ `csr_timeh: begin
+ csr_output_value = time_counter[63:32];
+ end
+ `csr_instreth: begin
+ csr_output_value = instret_counter[63:32];
+ end
+ `csr_mvendorid: begin
+ csr_output_value = mvendorid;
+ end
+ `csr_marchid: begin
+ csr_output_value = marchid;
+ end
+ `csr_mimpid: begin
+ csr_output_value = mimpid;
+ end
+ `csr_mhartid: begin
+ csr_output_value = mhartid;
+ end
+ `csr_misa: begin
+ csr_output_value = misa;
+ end
+ `csr_mstatus: begin
+ csr_output_value = make_mstatus(mstatus_tsr,
+ mstatus_tw,
+ mstatus_tvm,
+ mstatus_mxr,
+ mstatus_sum,
+ mstatus_mprv,
+ mstatus_xs,
+ mstatus_fs,
+ mstatus_mpp,
+ mstatus_spp,
+ mstatus_mpie,
+ mstatus_spie,
+ mstatus_upie,
+ mstatus_mie,
+ mstatus_sie,
+ mstatus_uie);
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mstatus_mpie = csr_written_value[7];
+ mstatus_mie = csr_written_value[3];
+ end
+ end
+ `csr_mie: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mie_meie;
+ csr_output_value[9] = mie_seie;
+ csr_output_value[8] = mie_ueie;
+ csr_output_value[7] = mie_mtie;
+ csr_output_value[5] = mie_stie;
+ csr_output_value[4] = mie_utie;
+ csr_output_value[3] = mie_msie;
+ csr_output_value[1] = mie_ssie;
+ csr_output_value[0] = mie_usie;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mie_meie = csr_written_value[11];
+ mie_mtie = csr_written_value[7];
+ mie_msie = csr_written_value[3];
+ end
+ end
+ `csr_mtvec: begin
+ csr_output_value = mtvec;
+ end
+ `csr_mscratch: begin
+ csr_output_value = mscratch;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mscratch = csr_written_value;
+ end
+ `csr_mepc: begin
+ csr_output_value = mepc;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mepc = csr_written_value;
+ end
+ `csr_mcause: begin
+ csr_output_value = mcause;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mcause = csr_written_value;
+ end
+ `csr_mip: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mip_meip;
+ csr_output_value[9] = mip_seip;
+ csr_output_value[8] = mip_ueip;
+ csr_output_value[7] = mip_mtip;
+ csr_output_value[5] = mip_stip;
+ csr_output_value[4] = mip_utip;
+ csr_output_value[3] = mip_msip;
+ csr_output_value[1] = mip_ssip;
+ csr_output_value[0] = mip_usip;
+ end
+ endcase
+ if(csr_reads)
+ write_register(decoder_rd, csr_output_value);
+ end
+ end
+ endcase
+ end
+ """
def __init__(self):
self.clk = ClockSignal()
self.reset = ResetSignal()
time_counter = Signal(64); # TODO: implement time_counter
instret_counter = Signal(64); # TODO: implement instret_counter
+ self.sync += If(~self.reset,
+ self.main_block(mi, m, mstatus, ft, dc,
+ load_store_misaligned,
+ loaded_value,
+ alu_result,
+ lui_auipc_result,
+ fetch_output_pc)
+ )
+
if __name__ == "__main__":
example = CPU()
print(verilog.convert(example,
"""
- wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter
- wire [63:0] time_counter = 0; // TODO: implement time_counter
- wire [63:0] instret_counter = 0; // TODO: implement instret_counter
-
always @(posedge clk) begin:main_block
if(reset) begin
reset_to_initial();