🐛 Fixes in scoreboard, issue and branches

This commit is contained in:
Florian Zaruba 2017-05-10 20:09:03 +02:00
parent 61afdb9e30
commit 0f1e08fb91
9 changed files with 155 additions and 126 deletions

View file

@ -125,6 +125,7 @@ module ariane
logic [63:0] operand_a_id_ex;
logic [63:0] operand_b_id_ex;
logic [63:0] operand_c_id_ex;
logic [63:0] pc_id_ex;
// ALU
logic alu_ready_ex_id;
logic alu_valid_id_ex;
@ -134,6 +135,7 @@ module ariane
exception alu_exception_ex_id;
// Branches and Jumps
logic branch_valid_id_ex;
logic predict_branch_valid_id_ex;
logic [63:0] predict_address_id_ex;
logic predict_taken_id_ex;
// LSU
@ -265,111 +267,115 @@ module ariane
.NR_WB_PORTS ( NR_WB_PORTS )
)
id_stage_i (
.test_en_i ( test_en_i ),
.flush_i ( flush ),
.instruction_i ( instr_rdata_if_id ),
.instruction_valid_i ( instr_valid_if_id ),
.is_compressed_i ( is_compressed_if_id ),
.pc_if_i ( pc_if ), // PC from if
.ex_if_i ( exception_if_id ), // exception from if
.ready_o ( ready_id_if ),
.test_en_i ( test_en_i ),
.flush_i ( flush ),
.instruction_i ( instr_rdata_if_id ),
.instruction_valid_i ( instr_valid_if_id ),
.is_compressed_i ( is_compressed_if_id ),
.pc_if_i ( pc_id_if_id ), // PC from if
.ex_if_i ( exception_if_id ), // exception from if
.ready_o ( ready_id_if ),
// Functional Units
.operator_o ( operator_id_ex ),
.operand_a_o ( operand_a_id_ex ),
.operand_b_o ( operand_b_id_ex ),
.operand_c_o ( operand_c_id_ex ),
.imm_o ( imm_id_ex ),
.trans_id_o ( trans_id_id_ex ),
.operator_o ( operator_id_ex ),
.operand_a_o ( operand_a_id_ex ),
.operand_b_o ( operand_b_id_ex ),
.operand_c_o ( operand_c_id_ex ),
.imm_o ( imm_id_ex ),
.trans_id_o ( trans_id_id_ex ),
.pc_o ( pc_id_ex ),
// ALU
.alu_ready_i ( alu_ready_ex_id ),
.alu_valid_o ( alu_valid_id_ex ),
.alu_ready_i ( alu_ready_ex_id ),
.alu_valid_o ( alu_valid_id_ex ),
// Branches and Jumps
.branch_valid_i ( branch_valid_if_id ),
.predict_address_i ( predict_address_if_id ),
.predict_taken_i ( predict_taken_if_id ),
.branch_valid_o ( branch_valid_id_ex ),
.predict_address_o ( predict_address_id_ex ),
.predict_taken_o ( predict_taken_id_ex ),
.branchpredict_i ( branchpredict ), // in order to resolve the branch
.branch_valid_i ( branch_valid_if_id ),
.predict_address_i ( predict_address_if_id ),
.predict_taken_i ( predict_taken_if_id ),
.branch_valid_o ( branch_valid_id_ex ),
.predict_branch_valid_o ( predict_branch_valid_id_ex ),
.predict_address_o ( predict_address_id_ex ),
.predict_taken_o ( predict_taken_id_ex ),
.branchpredict_i ( branchpredict ), // in order to resolve the branch
// LSU
.lsu_ready_i ( lsu_ready_ex_id ),
.lsu_valid_o ( lsu_valid_id_ex ),
.lsu_ready_i ( lsu_ready_ex_id ),
.lsu_valid_o ( lsu_valid_id_ex ),
// Multiplier
.mult_ready_i ( mult_ready_ex_id ),
.mult_valid_o ( mult_valid_id_ex ),
.mult_ready_i ( mult_ready_ex_id ),
.mult_valid_o ( mult_valid_id_ex ),
// CSR
.csr_ready_i ( csr_ready_ex_id ),
.csr_valid_o ( csr_valid_id_ex ),
.csr_ready_i ( csr_ready_ex_id ),
.csr_valid_o ( csr_valid_id_ex ),
.trans_id_i ( {alu_trans_id_ex_id, lsu_trans_id_ex_id, csr_trans_id_ex_id }),
.wdata_i ( {alu_result_ex_id, lsu_result_ex_id, csr_result_ex_id }),
.ex_ex_i ( {alu_exception_ex_id, lsu_exception_ex_id, {$bits(exception){1'b0}} }),
.wb_valid_i ( {alu_valid_ex_id, lsu_valid_ex_id, csr_valid_ex_id }),
.trans_id_i ( {alu_trans_id_ex_id, lsu_trans_id_ex_id, csr_trans_id_ex_id }),
.wdata_i ( {alu_result_ex_id, lsu_result_ex_id, csr_result_ex_id }),
.ex_ex_i ( {alu_exception_ex_id, lsu_exception_ex_id, {$bits(exception){1'b0}} }),
.wb_valid_i ( {alu_valid_ex_id, lsu_valid_ex_id, csr_valid_ex_id }),
.waddr_a_i ( waddr_a_commit_id ),
.wdata_a_i ( wdata_a_commit_id ),
.we_a_i ( we_a_commit_id ),
.waddr_a_i ( waddr_a_commit_id ),
.wdata_a_i ( wdata_a_commit_id ),
.we_a_i ( we_a_commit_id ),
.commit_instr_o ( commit_instr_id_commit ),
.commit_ack_i ( commit_ack_commit_id ),
.commit_instr_o ( commit_instr_id_commit ),
.commit_ack_i ( commit_ack_commit_id ),
.*
);
// ---------
// EX
// ---------
ex_stage ex_stage_i (
.flush_i ( flush ),
.operator_i ( operator_id_ex ),
.operand_a_i ( operand_a_id_ex ),
.operand_b_i ( operand_b_id_ex ),
.operand_c_i ( operand_c_id_ex ),
.imm_i ( imm_id_ex ),
.trans_id_i ( trans_id_id_ex ),
.flush_i ( flush ),
.operator_i ( operator_id_ex ),
.operand_a_i ( operand_a_id_ex ),
.operand_b_i ( operand_b_id_ex ),
.operand_c_i ( operand_c_id_ex ),
.imm_i ( imm_id_ex ),
.trans_id_i ( trans_id_id_ex ),
.pc_i ( pc_id_ex ),
// ALU
.alu_ready_o ( alu_ready_ex_id ),
.alu_valid_i ( alu_valid_id_ex ),
.alu_result_o ( alu_result_ex_id ),
.alu_trans_id_o ( alu_trans_id_ex_id ),
.alu_valid_o ( alu_valid_ex_id ),
.alu_exception_o ( alu_exception_ex_id ),
.alu_ready_o ( alu_ready_ex_id ),
.alu_valid_i ( alu_valid_id_ex ),
.alu_result_o ( alu_result_ex_id ),
.alu_trans_id_o ( alu_trans_id_ex_id ),
.alu_valid_o ( alu_valid_ex_id ),
.alu_exception_o ( alu_exception_ex_id ),
// Branches and Jumps
.branch_valid_i ( branch_valid_id_ex ),
.predict_address_i ( predict_address_id_ex ),
.predict_taken_i ( predict_taken_id_ex ),
.branchpredict_o ( branchpredict ),
.branch_valid_i ( branch_valid_id_ex ),
.predict_branch_valid_i ( predict_branch_valid_id_ex ),
.predict_address_i ( predict_address_id_ex ),
.predict_taken_i ( predict_taken_id_ex ),
.branchpredict_o ( branchpredict ),
// LSU
.lsu_ready_o ( lsu_ready_ex_id ),
.lsu_valid_i ( lsu_valid_id_ex ),
.lsu_result_o ( lsu_result_ex_id ),
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
.lsu_valid_o ( lsu_valid_ex_id ),
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
.lsu_exception_o ( lsu_exception_ex_id ),
.lsu_ready_o ( lsu_ready_ex_id ),
.lsu_valid_i ( lsu_valid_id_ex ),
.lsu_result_o ( lsu_result_ex_id ),
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
.lsu_valid_o ( lsu_valid_ex_id ),
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
.lsu_exception_o ( lsu_exception_ex_id ),
// CSR
.csr_ready_o ( csr_ready_ex_id ),
.csr_valid_i ( csr_valid_id_ex ),
.csr_trans_id_o ( csr_trans_id_ex_id ),
.csr_result_o ( csr_result_ex_id ),
.csr_valid_o ( csr_valid_ex_id ),
.csr_addr_o ( csr_addr_ex_csr ),
.csr_commit_i ( csr_commit_commit_ex ), // from commit
.csr_ready_o ( csr_ready_ex_id ),
.csr_valid_i ( csr_valid_id_ex ),
.csr_trans_id_o ( csr_trans_id_ex_id ),
.csr_result_o ( csr_result_ex_id ),
.csr_valid_o ( csr_valid_ex_id ),
.csr_addr_o ( csr_addr_ex_csr ),
.csr_commit_i ( csr_commit_commit_ex ), // from commit
// memory management
.enable_translation_i ( enable_translation_csr_ex ), // from CSR
.fetch_req_i ( fetch_req_if_ex ),
.fetch_gnt_o ( fetch_gnt_ex_if ),
.fetch_valid_o ( fetch_valid_ex_if ),
.fetch_err_o ( fetch_err_ex_if ),
.fetch_vaddr_i ( fetch_vaddr_if_ex ),
.fetch_rdata_o ( fetch_rdata_ex_if ),
.priv_lvl_i ( priv_lvl ), // from CSR
.flag_pum_i ( flag_pum_csr_ex ), // from CSR
.flag_mxr_i ( flag_mxr_csr_ex ), // from CSR
.pd_ppn_i ( pd_ppn_csr_ex ), // from CSR
.asid_i ( asid_csr_ex ), // from CSR
.flush_tlb_i ( flush_tlb ),
.enable_translation_i ( enable_translation_csr_ex ), // from CSR
.fetch_req_i ( fetch_req_if_ex ),
.fetch_gnt_o ( fetch_gnt_ex_if ),
.fetch_valid_o ( fetch_valid_ex_if ),
.fetch_err_o ( fetch_err_ex_if ),
.fetch_vaddr_i ( fetch_vaddr_if_ex ),
.fetch_rdata_o ( fetch_rdata_ex_if ),
.priv_lvl_i ( priv_lvl ), // from CSR
.flag_pum_i ( flag_pum_csr_ex ), // from CSR
.flag_mxr_i ( flag_mxr_csr_ex ), // from CSR
.pd_ppn_i ( pd_ppn_csr_ex ), // from CSR
.asid_i ( asid_csr_ex ), // from CSR
.flush_tlb_i ( flush_tlb ),
.mult_ready_o ( mult_ready_ex_id ),
.mult_valid_i ( mult_valid_id_ex ),
.mult_ready_o ( mult_ready_ex_id ),
.mult_valid_i ( mult_valid_id_ex ),
.*
);
// ---------
@ -425,11 +431,11 @@ module ariane
logic flush_commit_i;
logic branchpredict_i;
controller i_controller (
controller controller_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_commit_i ( flush_commit_i ),
.flush_csr_i ( flsh_csr_ctrl ),
.flush_csr_i ( flush_csr_ctrl ),
.branchpredict_i ( branchpredict )
);

View file

@ -22,13 +22,15 @@ import ariane_pkg::*;
module branch_engine (
input logic [63:0] operand_a_i,
input logic [63:0] operand_b_i,
input logic [63:0] pc_i,
input logic valid_i,
input logic comparison_result_i, // result of comparison
input logic [63:0] predict_address_i, // this is the address we predicted
input logic comparison_result_i, // result of comparison
input logic [63:0] predict_address_i, // this is the address we predicted
input logic predict_branch_valid_i, // we predicted that this was a valid branch
input logic predict_taken_i,
output branchpredict branchpredict_o, // this is the actual address we are targeting
output exception branch_ex_o // branch exception out
output branchpredict branchpredict_o, // this is the actual address we are targeting
output exception branch_ex_o // branch exception out
);
logic [63:0] target_address;
@ -41,6 +43,8 @@ module branch_engine (
branchpredict_o.is_mispredict = 1'b0;
if (valid_i) begin
// save pc
branchpredict_o.pc = pc_i;
// calculate target address simple 64 bit addition
target_address = $signed(operand_a_i) + $signed(operand_b_i);
// write target address
@ -48,7 +52,10 @@ module branch_engine (
branchpredict_o.is_taken = comparison_result_i;
// we mis-predicted e.g.: the predicted address is unequal to the actual address
if (target_address[1:0] == 2'b0) begin
if (target_address != predict_address_i || predict_taken_i != comparison_result_i) begin
if ( target_address != predict_address_i // we mis-predicted the address of the branch
|| predict_taken_i != comparison_result_i // we mis-predicted the outcome of the branch
|| predict_branch_valid_i == 1'b0 // this means branch-prediction thought it was no branch but in real it was one
) begin
branchpredict_o.is_mispredict = 1'b1;
end
end

View file

@ -402,8 +402,8 @@ module decoder (
// Exception handling
// --------------------------------
always_comb begin : exception_handling
instruction_o.ex = ex_i;
instruction_o.valid = 1'b0;
instruction_o.ex = ex_i;
instruction_o.valid = 1'b0;
// look if we didn't already get an exception in any previous
// stage - we should not overwrite it as we retain order regarding the exception
if (~ex_i.valid && illegal_instr) begin
@ -413,6 +413,8 @@ module decoder (
instruction_o.ex.valid = 1'b1;
// we decoded an illegal exception here
instruction_o.ex.cause = ILLEGAL_INSTR;
// if we decoded an illegal instruction save the faulting instruction to tval
instruction_o.ex.tval = instruction_i;
end
end
endmodule

View file

@ -32,7 +32,7 @@ module ex_stage #(
input logic [63:0] operand_c_i,
input logic [63:0] imm_i,
input logic [TRANS_ID_BITS-1:0] trans_id_i,
input logic [63:0] pc_i, // PC of current instruction
// ALU 1
output logic alu_ready_o, // FU is ready
input logic alu_valid_i, // Output is valid
@ -42,6 +42,7 @@ module ex_stage #(
output exception alu_exception_o,
// Branches and Jumps
input logic branch_valid_i,
input logic predict_branch_valid_i,
input logic [63:0] predict_address_i,
input logic predict_taken_i,
output branchpredict branchpredict_o,
@ -139,6 +140,7 @@ module ex_stage #(
.commit_i ( lsu_commit_i ),
.*
);
// -----
// CSR
// -----

View file

@ -42,6 +42,7 @@ module id_stage #(
output logic [63:0] operand_c_o,
output logic [63:0] imm_o,
output logic [TRANS_ID_BITS-1:0] trans_id_o,
output logic [63:0] pc_o,
input logic alu_ready_i,
output logic alu_valid_o,
@ -51,6 +52,7 @@ module id_stage #(
input logic predict_taken_i,
// Branch predict Out
output logic branch_valid_o,
output logic predict_branch_valid_o, // this is a valid prediction
output logic [63:0] predict_address_o,
output logic predict_taken_o,
// ex just resolved our predicted branch, we are ready to accept new requests
@ -111,11 +113,11 @@ module id_stage #(
// instructions past a branch. We need to resolve the branch beforehand.
// This limitation is in place to ease the backtracking of mis-predicted branches as they
// can simply be in the front-end of the processor.
logic unresolved_branch_n, unresolved_branch_q;
logic unresolved_branch_n, unresolved_branch_q;
// branch predict registers
logic branch_valid_n, branch_valid_q;
logic [63:0] predict_address_n, predict_address_q;
logic predict_taken_n, predict_taken_q;
logic branch_valid_n, branch_valid_q;
logic [63:0] predict_address_n, predict_address_q;
logic predict_taken_n, predict_taken_q;
always_comb begin : unresolved_branch
unresolved_branch_n = unresolved_branch_q;
@ -138,12 +140,13 @@ module id_stage #(
predict_taken_n = predict_taken_i;
end
end
// we are ready if we are not full and don't have any unresolved branches
assign ready_o = ~full & ~unresolved_branch_q;
// we are ready if we are not full and don't have any unresolved branches, but it can be
// the case that we have an unresolved branch which is cleared in that cycle (branchpredict_i.valid == 1)
assign ready_o = ~full & (~unresolved_branch_q || branchpredict_i.valid);
// output branch prediction bits
assign branch_valid_o = branch_valid_q;
assign predict_address_o = predict_address_q;
assign predict_taken_o = predict_taken_q;
assign predict_branch_valid_o = branch_valid_q;
assign predict_address_o = predict_address_q;
assign predict_taken_o = predict_taken_q;
decoder decoder_i (
.clk_i ( clk_i ),

View file

@ -45,6 +45,7 @@ module issue_read_operands (
output logic [63:0] operand_c_o,
output logic [63:0] imm_o, // output immediate for the LSU
output logic [TRANS_ID_BITS-1:0] trans_id_o,
output logic [63:0] pc_o,
// ALU 1
input logic alu_ready_i, // FU is ready
output logic alu_valid_o, // Output is valid
@ -102,7 +103,7 @@ module issue_read_operands (
// We can issue an instruction if we do not detect that any other instruction is writing the same
// destination register.
// We also need to check if there is an unresolved branch in the scoreboard.
always_comb begin : issue
always_comb begin : issue_scoreboard
// default assignment
issue_ack_o = 1'b0;
// check that we didn't stall, that the instruction we got is valid
@ -114,6 +115,11 @@ module issue_read_operands (
if (rd_clobber_i[issue_instr_i.rd] == NONE) begin
issue_ack_o = 1'b1;
end
// or check that the target destination register will be written in this cycle by the
// commit stage
if (we_a_i && waddr_a_i == issue_instr_i.rd) begin
issue_ack_o = 1'b1;
end
end
// we can also issue the instruction under the following two circumstances:
// we can do this even if we are stalled or no functional unit is ready (as we don't need one)
@ -254,7 +260,7 @@ module issue_read_operands (
// Exception pass through
// if an exception has occurred simply pass it through
// we do not want to issue this instruction
if (~issue_instr_i.ex.valid && issue_instr_valid_i) begin
if (~issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin
case (issue_instr_i.fu)
ALU:
alu_valid_n = 1'b1;
@ -301,6 +307,7 @@ module issue_read_operands (
operand_a_q <= '{default: 0};
operand_b_q <= '{default: 0};
operand_c_q <= '{default: 0};
imm_q <= 64'b0;
alu_valid_q <= 1'b0;
branch_valid_q <= 1'b0;
mult_valid_q <= 1'b0;
@ -308,10 +315,12 @@ module issue_read_operands (
csr_valid_q <= 1'b0;
operator_q <= ADD;
trans_id_q <= 5'b0;
pc_o <= 64'b0;
end else begin
operand_a_q <= operand_a_n;
operand_b_q <= operand_b_n;
operand_c_q <= operand_c_n;
imm_q <= imm_n;
alu_valid_q <= alu_valid_n;
branch_valid_q <= branch_valid_n;
mult_valid_q <= mult_valid_n;
@ -319,6 +328,7 @@ module issue_read_operands (
csr_valid_q <= csr_valid_n;
operator_q <= operator_n;
trans_id_q <= trans_id_n;
pc_o <= issue_instr_i.pc;
end
end
endmodule

View file

@ -100,6 +100,8 @@ always_comb begin : clobber_output
if (i[BITS_ENTRIES-1:0] >= commit_pointer_q && i[BITS_ENTRIES-1:0] < issue_pointer_q)
rd_clobber_o[mem_q[i].rd] = mem_q[i].fu;
end
end else if (commit_pointer_q == issue_pointer_q) begin // everything committed
rd_clobber_o = '{default: NONE};
end else begin // the issue pointer has overflowed, invert logic, depicted on the right
for (int unsigned i = 0; i < NR_ENTRIES; i++) begin
if (i[BITS_ENTRIES-1:0] >= commit_pointer_q || i[BITS_ENTRIES-1:0] < issue_pointer_q)
@ -209,7 +211,7 @@ always_comb begin : issue_instruction
// provide a combinatorial path in case the scoreboard is empty
if (top_pointer_q == issue_pointer_q) begin
if (top_pointer_q == issue_pointer_q && ~full_o) begin
issue_instr_o = decoded_instr_i;
issue_instr_o.trans_id = issue_pointer_q;
issue_instr_valid_o = decoded_instr_valid_i;
@ -218,7 +220,7 @@ always_comb begin : issue_instruction
issue_instr_o = mem_q[$unsigned(issue_pointer_q)];
// we have not reached the top of the buffer
// issue pointer has overflowed
if (issue_pointer_q <= commit_pointer_q) begin
if (issue_pointer_q < commit_pointer_q) begin
if (issue_pointer_q < top_pointer_q)
issue_instr_valid_o = 1'b1;
else
@ -272,7 +274,7 @@ always_ff @(posedge clk_i or negedge rst_ni) begin : sequential
commit_pointer_q <= commit_pointer_n;
top_pointer_q <= top_pointer_n;
mem_q <= mem_n;
if (decoded_instr_valid_i) // only advance if we decoded instruction
if (decoded_instr_valid_i && ~full_o) // only advance if we decoded instruction and we are not full
top_pointer_qq <= top_pointer_q;
end
end

View file

@ -1,20 +1,4 @@
add wave -noupdate -group instr_if /core_tb/instr_if/*
add wave -noupdate -group Core /core_tb/dut/clk_i
add wave -noupdate -group Core /core_tb/dut/clock_en_i
add wave -noupdate -group Core /core_tb/dut/test_en_i
add wave -noupdate -group Core /core_tb/dut/fetch_enable_i
add wave -noupdate -group Core /core_tb/dut/core_busy_o
add wave -noupdate -group Core /core_tb/dut/ext_perf_counters_i
add wave -noupdate -group Core /core_tb/dut/boot_addr_i
add wave -noupdate -group Core /core_tb/dut/core_id_i
add wave -noupdate -group Core /core_tb/dut/cluster_id_i
add wave -noupdate -group Core /core_tb/dut/irq_i
add wave -noupdate -group Core /core_tb/dut/irq_id_i
add wave -noupdate -group Core /core_tb/dut/irq_ack_o
add wave -noupdate -group Core /core_tb/dut/irq_sec_i
add wave -noupdate -group Core /core_tb/dut/sec_lvl_o
add wave -noupdate -group core /core_tb/dut/*
add wave -noupdate -group pcgen_stage -group btb /core_tb/dut/pcgen_i/btb_i/*
add wave -noupdate -group pcgen_stage /core_tb/dut/pcgen_i/*
add wave -noupdate -group if_stage -group prefetch_buffer -group fifo /core_tb/dut/if_stage_i/prefetch_buffer_i/fifo_i/*
@ -23,11 +7,14 @@ add wave -noupdate -group if_stage /core_tb/dut/if_stage_i/*
add wave -noupdate -group id_stage -group scoreboard /core_tb/dut/id_stage_i/scoreboard_i/*
add wave -noupdate -group id_stage -group decoder /core_tb/dut/id_stage_i/decoder_i/*
add wave -noupdate -group id_stage -group issue_read_operands /core_tb/dut/id_stage_i/issue_read_operands_i/*
add wave -noupdate -group id_stage /core_tb/dut/id_stage_i/*
add wave -noupdate -group ex_stage -group ALU /core_tb/dut/ex_stage_i/alu_i/*
add wave -noupdate -group ex_stage -group lsu /core_tb/dut/ex_stage_i/lsu_i/*
add wave -noupdate -group ex_stage -group branch_engine /core_tb/dut/ex_stage_i/branch_engine_i/*
add wave -noupdate -group ex_stage -expand -group csr_buffer /core_tb/dut/ex_stage_i/csr_buffer_i/*
add wave -noupdate -group ex_stage /core_tb/dut/ex_stage_i/*
add wave -noupdate -group commit_stage /core_tb/dut/commit_stage_i/*
add wave -noupdate -group csr_file /core_tb/dut/csr_regfile_i/*
add wave -noupdate -group controller /core_tb/dut/controller_i/*
TreeUpdate [SetDefaultTree]

View file

@ -5,6 +5,7 @@
addi x1, x0, 1
addi x2, x0, 1
add x3, x1, x2
add x3, x1, x2
add x4, x2, x3
add x5, x3, x4
add x6, x4, x5
@ -13,6 +14,15 @@
csrw mstatus, x7
add x9, x7, x8
csrr x1, mstatus
jal L1
nop
nop
nop
nop
nop
nop
nop
nop
L1: nop
nop
nop
addi x1, x0, 55