Skip to content

Commit eb509ad

Browse files
Merge pull request #951 from silabs-halfdan/parameterize_zicntr
Parameterize Zicntr and Xif features
2 parents 21521a2 + 306a6de commit eb509ad

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

rtl/cv32e40x_cs_registers.sv

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
131131
(32'(1) << 23) | // X - Non-standard extensions present
132132
(32'(MXL) << 30); // M-XLEN
133133

134+
localparam bit ZIHPM = 1'b1;
135+
localparam bit ZICNTR = 1'b1;
136+
134137
localparam logic [31:0] MISA_VALUE = CORE_MISA | (X_EXT ? X_MISA : 32'h0000_0000);
135138

136139
localparam logic [31:0] CSR_MTVT_MASK = {{MTVT_ADDR_WIDTH{1'b1}}, {(32-MTVT_ADDR_WIDTH){1'b0}}};
@@ -556,11 +559,21 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
556559
end
557560

558561
CSR_TIME: begin
559-
csr_rdata_int = time_i[31:0];
562+
if (ZICNTR) begin : zicntr_time
563+
csr_rdata_int = time_i[31:0];
564+
end else begin : no_zicntr_time
565+
csr_rdata_int = '0;
566+
illegal_csr_read = 1'b1;
567+
end
560568
end
561569

562570
CSR_TIMEH: begin
563-
csr_rdata_int = time_i[63:32];
571+
if (ZICNTR) begin : zicntr_timeh
572+
csr_rdata_int = time_i[63:32];
573+
end else begin : no_zicntr_timeh
574+
csr_rdata_int = '0;
575+
illegal_csr_read = 1'b1;
576+
end
564577
end
565578

566579
// Hardware Performance Monitor
@@ -573,19 +586,47 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
573586
CSR_MHPMCOUNTER16, CSR_MHPMCOUNTER17, CSR_MHPMCOUNTER18, CSR_MHPMCOUNTER19,
574587
CSR_MHPMCOUNTER20, CSR_MHPMCOUNTER21, CSR_MHPMCOUNTER22, CSR_MHPMCOUNTER23,
575588
CSR_MHPMCOUNTER24, CSR_MHPMCOUNTER25, CSR_MHPMCOUNTER26, CSR_MHPMCOUNTER27,
576-
CSR_MHPMCOUNTER28, CSR_MHPMCOUNTER29, CSR_MHPMCOUNTER30, CSR_MHPMCOUNTER31,
577-
CSR_CYCLE,
578-
CSR_INSTRET,
589+
CSR_MHPMCOUNTER28, CSR_MHPMCOUNTER29, CSR_MHPMCOUNTER30, CSR_MHPMCOUNTER31 : begin
590+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][31:0];
591+
csr_counter_read_o = 1'b1;
592+
end
593+
594+
595+
CSR_CYCLE, CSR_INSTRET : begin
596+
if (ZICNTR) begin : zicntr_counters
597+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][31:0];
598+
csr_counter_read_o = 1'b1;
599+
end else begin : no_zicntr_counters
600+
csr_rdata_int = '0;
601+
illegal_csr_read = 1'b1;
602+
end
603+
end
604+
605+
CSR_CYCLEH, CSR_INSTRETH : begin
606+
if (ZICNTR) begin : zicntr_hcounters
607+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][63:32];
608+
csr_counter_read_o = 1'b1;
609+
end else begin : no_zicntr_hcounters
610+
csr_rdata_int = '0;
611+
illegal_csr_read = 1'b1;
612+
end
613+
end
614+
579615
CSR_HPMCOUNTER3,
580616
CSR_HPMCOUNTER4, CSR_HPMCOUNTER5, CSR_HPMCOUNTER6, CSR_HPMCOUNTER7,
581617
CSR_HPMCOUNTER8, CSR_HPMCOUNTER9, CSR_HPMCOUNTER10, CSR_HPMCOUNTER11,
582618
CSR_HPMCOUNTER12, CSR_HPMCOUNTER13, CSR_HPMCOUNTER14, CSR_HPMCOUNTER15,
583619
CSR_HPMCOUNTER16, CSR_HPMCOUNTER17, CSR_HPMCOUNTER18, CSR_HPMCOUNTER19,
584620
CSR_HPMCOUNTER20, CSR_HPMCOUNTER21, CSR_HPMCOUNTER22, CSR_HPMCOUNTER23,
585621
CSR_HPMCOUNTER24, CSR_HPMCOUNTER25, CSR_HPMCOUNTER26, CSR_HPMCOUNTER27,
586-
CSR_HPMCOUNTER28, CSR_HPMCOUNTER29, CSR_HPMCOUNTER30, CSR_HPMCOUNTER31: begin
587-
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][31:0];
588-
csr_counter_read_o = 1'b1;
622+
CSR_HPMCOUNTER28, CSR_HPMCOUNTER29, CSR_HPMCOUNTER30, CSR_HPMCOUNTER31 : begin
623+
if (ZIHPM) begin : zihpm_counters
624+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][31:0];
625+
csr_counter_read_o = 1'b1;
626+
end else begin : no_zihpm_counters
627+
csr_rdata_int = '0;
628+
illegal_csr_read = 1'b1;
629+
end
589630
end
590631

591632
CSR_MCYCLEH,
@@ -597,19 +638,26 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
597638
CSR_MHPMCOUNTER16H, CSR_MHPMCOUNTER17H, CSR_MHPMCOUNTER18H, CSR_MHPMCOUNTER19H,
598639
CSR_MHPMCOUNTER20H, CSR_MHPMCOUNTER21H, CSR_MHPMCOUNTER22H, CSR_MHPMCOUNTER23H,
599640
CSR_MHPMCOUNTER24H, CSR_MHPMCOUNTER25H, CSR_MHPMCOUNTER26H, CSR_MHPMCOUNTER27H,
600-
CSR_MHPMCOUNTER28H, CSR_MHPMCOUNTER29H, CSR_MHPMCOUNTER30H, CSR_MHPMCOUNTER31H,
601-
CSR_CYCLEH,
602-
CSR_INSTRETH,
641+
CSR_MHPMCOUNTER28H, CSR_MHPMCOUNTER29H, CSR_MHPMCOUNTER30H, CSR_MHPMCOUNTER31H: begin
642+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][63:32];
643+
csr_counter_read_o = 1'b1;
644+
end
645+
603646
CSR_HPMCOUNTER3H,
604647
CSR_HPMCOUNTER4H, CSR_HPMCOUNTER5H, CSR_HPMCOUNTER6H, CSR_HPMCOUNTER7H,
605648
CSR_HPMCOUNTER8H, CSR_HPMCOUNTER9H, CSR_HPMCOUNTER10H, CSR_HPMCOUNTER11H,
606649
CSR_HPMCOUNTER12H, CSR_HPMCOUNTER13H, CSR_HPMCOUNTER14H, CSR_HPMCOUNTER15H,
607650
CSR_HPMCOUNTER16H, CSR_HPMCOUNTER17H, CSR_HPMCOUNTER18H, CSR_HPMCOUNTER19H,
608651
CSR_HPMCOUNTER20H, CSR_HPMCOUNTER21H, CSR_HPMCOUNTER22H, CSR_HPMCOUNTER23H,
609652
CSR_HPMCOUNTER24H, CSR_HPMCOUNTER25H, CSR_HPMCOUNTER26H, CSR_HPMCOUNTER27H,
610-
CSR_HPMCOUNTER28H, CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H: begin
611-
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][63:32];
612-
csr_counter_read_o = 1'b1;
653+
CSR_HPMCOUNTER28H, CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H : begin
654+
if (ZIHPM) begin : zihpm_hcounters
655+
csr_rdata_int = mhpmcounter_rdata[csr_raddr[4:0]][63:32];
656+
csr_counter_read_o = 1'b1;
657+
end else begin : no_zihpm_hcounters
658+
csr_rdata_int = '0;
659+
illegal_csr_read = 1'b1;
660+
end
613661
end
614662

615663
// mvendorid: Machine Vendor ID

rtl/cv32e40x_id_stage.sv

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,19 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
462462
.tbljmp_first_i ( tbljmp_first )
463463
);
464464

465-
// Speculatively read all source registers for illegal instr, might be required by coprocessor
466-
// Non-offloaded instructions will use maximum two read ports (rf_re from decoder is two bits, rf_re_o may be two or three bits wide)
467-
// Todo:XIF Too conservative, causes load_use stalls on offloaded instruction when the operands may not be needed at all.
468-
// issue_valid depends on halt_id (and data_rvalid) via the local instr_valid.
469-
// Can issue_valid be made fast by using the registered instr_valid and only factor in kill_id and not halt_id?
470-
// Maybe it is ok to have a late issue_valid, as accept signal will depend on late rs_valid anyway?
471-
assign rf_re_o = illegal_insn ? '1 : REGFILE_NUM_READ_PORTS'(rf_re);
465+
generate
466+
if (X_EXT) begin : x_ext_rf_re
467+
// Speculatively read all source registers for illegal instr, might be required by coprocessor
468+
// Non-offloaded instructions will use maximum two read ports (rf_re from decoder is two bits, rf_re_o may be two or three bits wide)
469+
// Todo:XIF Too conservative, causes load_use stalls on offloaded instruction when the operands may not be needed at all.
470+
// issue_valid depends on halt_id (and data_rvalid) via the local instr_valid.
471+
// Can issue_valid be made fast by using the registered instr_valid and only factor in kill_id and not halt_id?
472+
// Maybe it is ok to have a late issue_valid, as accept signal will depend on late rs_valid anyway?
473+
assign rf_re_o = illegal_insn ? '1 : REGFILE_NUM_READ_PORTS'(rf_re);
474+
end else begin : no_x_ext_rf_re
475+
assign rf_re_o = rf_re;
476+
end
477+
endgenerate
472478

473479
// Register writeback is enabled either by the decoder or by the XIF
474480
assign rf_we = rf_we_dec || xif_we;

0 commit comments

Comments
 (0)