Menu Close

RISC-V CSR Read and Write Control Module(5)CSR Register Implementation 3

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

 

Posted in FPGA, RISC-V, RISC-V Textbook, Textbook and Training Project

Related Articles

Leave a Reply

Your email address will not be published.

Leave the field below empty!