Related reference articles:
RISC-V teaching plan
This article will complete the last remaining CSR register implementation. For the CSR register implementation that has been introduced before, refer to the following two articles:
RISC-V CSR read and write control (3) CSR register implementation
RISC-V CSR read and write control (4) CSR register implementation
1.8. csr_misa
The misa register is readable only and stores information about the RISC-V CPU, such as the architecture and supported basic/compressed instruction sets. Part of the important code to implement the misa register is as follows (the code that is repeated above is omitted):
output [31:0] o_misa//output misa register assign o_misa = { 2'b1 // The highest two bits are 2b'01 for 32-bit architecture ,4'b0 // WIRI ,1'b0 // 25 Z Reserved ,1'b0 // 24 Y Reserved ,1'b0 // 23 X Non-standard extensions present ,1'b0 // 22 W Reserved ,1'b0 // 21 V Tentatively reserved for Vector extension 20 U User mode implemented ,1'b0 // 20 U User mode implemented ,1'b0 // 19 T Tentatively reserved for Transactional Memory extension ,1'b0 // 18 S Supervisor mode implemented ,1'b0 // 17 R Reserved ,1'b0 // 16 Q Quad-precision floating-point extension ,1'b0 // 15 P Tentatively reserved for Packed-SIMD extension ,1'b0 // 14 O Reserved ,1'b0 // 13 N User-level interrupts supported ,1'b0 // 12 M Integer Multiply/Divide extension ,1'b0 // 11 L Tentatively reserved for Decimal Floating-Point extension ,1'b0 // 10K Reserved ,1'b0 // 9 J Reserved ,1'b1 // <= 8 I RV32I/64I/128I base ISA//The currently implemented basic instruction set is RV32I, a 32-bit integer instruction set ,1'b0 // 7 H Hypervisor mode implemented ,1'b0 // 6 G Additional standard extensions present ,1'b0 // 5 F Single-precision floating-point extension ,1'b0 // 4 E RV32E base ISA ,1'b0 // 3 D Double-precision floating-point extension ,1'b0 // 2 C Compressed extension ,1'b0 // 1 B Tentatively reserved for Bit operations extension ,1'b0 // 0 A Atomic extension };
1.9. csr_mcounteren
The mcounteren register is readable and writable, and each bit corresponds to a counter. No matter what value is written by the CSR instruction, the counter is not affected. mcounteren controls whether the next privilege level can read the corresponding counter. Because only machine mode is implemented here, mcounteren is not used. Only the read and write of mcounteren is implemented here. Part of the important code to implement the mcounteren register is as follows (the code that is repeated above is omitted):
output [ 31: 0 ] o_mcounteren,//output mcounteren wire mcounteren_ena = (i_csr_wen & (i_csr_addr == 12'h306));//Confirm register by address index wire [31:0] mcounteren_r; wire[31:0] mcounteren_nxt = i_csr_val; fii_dfflr #(32) mtvec_dfflr (mcounteren_ena, mcounteren_nxt, mcounteren_r, sys_clk, rst_n);//latch assign o_mcounteren = mcounteren_r;//output
1.10. csr_mid
The csr_mid module combines many ID-related registers, including mvendorid, marchid, mimpid and mhartid. All four registers are read-only. For the specific meaning of the register, refer to 1.7-1.10 in RISC-V CSR register (2) CSR register . Some important codes of register implementation are as follows (the code that is repeated above is omitted):
output [31:0] o_mvendorid, //output mvendorid output [31:0] o_marchid, //output marchid output [31:0] o_mimpid, //output mimpid output [31:0] o_mhartid //output mhartid //The following three IDs are not fully implemented assign o_mvendorid = 32'b1; assign o_marchid = 32'b1; assign o_mimpid = 32'b1; assign o_mhartid = 32'b0; //hart ID is 0 means the CPU is a single core
1.11. csr_scratch
The mscratch register is readable and writable in machine mode, and there is no specified usage. Part of the important code to implement the mscratch register is as follows (the code that is repeated above is omitted):
output [ 31: 0 ] o_mscratch,//output mscratch wire mscratch_ena = (i_csr_wen & (i_csr_addr == 12'h340));//Confirm register by address index wire[31:0] mscratch_r; wire[31:0] mscratch_nxt = i_csr_val; fii_dfflr #(32) mtvec_dfflr (mscratch_ena, mscratch_nxt, mscratch_r, sys_clk, rst_n);//Latch assign o_mscratch = mscratch_r;//output
1.12. csr_mcycle
The csr_mcylce module includes two registers, mcycle and mcycleh, which are used to count how many clock cycles have passed. Two 32-bit counters form a 64-bit counter. Part of the important code to implement the counter is as follows (the code that is repeated above is omitted):
//Debug related signals input i_dbg_mode, input i_dbg_stpcyl, output reg [ 31: 0 ] o_mcycle_l,//output mcycle register, lower 32 bits output reg [ 31: 0 ] o_mcycle_h,//output mcycleh register, high 32 bits wire dbg_stop = i_dbg_mode & i_dbg_stpcyl;//Start of debugging always@( posedge sys_clk or negedge rst_n ) if ( !rst_n )//If there is no reset begin o_mcycle_l <= 32'b0; o_mcycle_h <= 32'b0; end else if ( i_csr_wen )//CSR register can be written begin case ( i_csr_addr )//CSR instruction write, index to low/high register according to address 12'hb00: o_mcycle_l <= i_csr_val; 12'hb80: o_mcycle_h <= i_csr_val; default: ; endcase end else begin if ( !dbg_stop )//If not in debugging begin if ( o_mcycle_l == 32'hffff_ffff )//If the lower 32-bit register is full begin o_mcycle_h <= o_mcycle_h + 1;//High-order carry o_mcycle_l <= 0; end else o_mcycle_l <= o_mcycle_l + 1;//Add 1 to the lower 32-bit register end end
1.13. csr_minstret
The csr_minstret module is similar to the above csr_mcycle module, including two 32-bit registers, minstret and minstreth, which are used to form a 64-bit register. minstret and minstreth are mainly used to count the instructions that have been executed. Part of the important code to implement the register is as follows (the code that is repeated above is omitted):
input i_EXE_vld,//Determine whether it is in the execution stage //Debug related signals input i_dbg_mode, input i_dbg_stpcyl, output reg [ 31: 0 ] o_minstret_l,//output mintret register, low 32 bits output reg [ 31: 0 ] o_minstret_h,//output minstreth register, high 32 bits wire dbg_stop = i_dbg_mode & i_dbg_stpcyl;//Start of debugging always@( posedge sys_clk or negedge rst_n ) if ( !rst_n )//If there is no reset begin o_minstret_l <= 32'b0; o_minstret_h <= 32'b0; end else if ( i_csr_wen )//CSR register can be written begin case ( i_csr_addr )//CSR instruction write, index to low/high register according to address 12'hb02: o_minstret_l <= i_csr_val; 12'hb82: o_minstret_h <= i_csr_val; default: ; endcase end else if ( ( i_EXE_vld ) && ( dbg_stop == 1'b0 ) )//If not in debugging, and in the execution phase begin if ( o_minstret_l == 32'hffff_ffff )//If the lower 32-bit register is full begin o_minstret_l <= 0; o_minstret_h <= o_minstret_h + 1;//High-order carry end else o_minstret_l <= o_minstret_l + 1;//Add 1 to the lower 32-bit register end