62 lines
1.9 KiB
Verilog
62 lines
1.9 KiB
Verilog
`include "VX_define.vh"
|
|
|
|
module VX_csr_data #(
|
|
parameter CORE_ID = 0
|
|
) (
|
|
input wire clk, // Clock
|
|
input wire reset,
|
|
|
|
input wire[`CSR_ADDR_SIZE-1:0] read_addr,
|
|
output reg[31:0] read_data,
|
|
input wire write_enable,
|
|
`IGNORE_WARNINGS_BEGIN
|
|
// We use a smaller storage for CSRs than the standard 4KB in RISC-V
|
|
input wire[`CSR_ADDR_SIZE-1:0] write_addr,
|
|
`IGNORE_WARNINGS_END
|
|
input wire[`CSR_WIDTH-1:0] write_data,
|
|
input wire[`NW_BITS-1:0] warp_num,
|
|
input wire wb_valid
|
|
);
|
|
reg [`CSR_WIDTH-1:0] csr_table[`NUM_CSRS-1:0];
|
|
|
|
reg [63:0] num_cycles, num_instrs;
|
|
|
|
// cast address to physical CSR range
|
|
wire [$clog2(`NUM_CSRS)-1:0] rd_addr, wr_addr;
|
|
assign rd_addr = $size(rd_addr)'(read_addr);
|
|
assign wr_addr = $size(wr_addr)'(write_addr);
|
|
|
|
always @(posedge clk) begin
|
|
if (reset) begin
|
|
num_cycles <= 0;
|
|
num_instrs <= 0;
|
|
end else begin
|
|
if (write_enable) begin
|
|
csr_table[wr_addr] <= write_data;
|
|
end
|
|
num_cycles <= num_cycles + 1;
|
|
if (wb_valid) begin
|
|
num_instrs <= num_instrs + 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
case (read_addr)
|
|
`CSR_LWID : read_data = 32'(warp_num);
|
|
`CSR_GTID ,
|
|
`CSR_GWID : read_data = CORE_ID * `NUM_WARPS + 32'(warp_num);
|
|
`CSR_GCID : read_data = CORE_ID;
|
|
`CSR_NT : read_data = `NUM_THREADS;
|
|
`CSR_NW : read_data = `NUM_WARPS;
|
|
`CSR_NC : read_data = `NUM_CORES * `NUM_CLUSTERS;
|
|
`CSR_CYCLL : read_data = num_cycles[31:0];
|
|
`CSR_CYCLH : read_data = num_cycles[63:32];
|
|
`CSR_INSTL : read_data = num_instrs[31:0];
|
|
`CSR_INSTH : read_data = num_instrs[63:32];
|
|
default: read_data = 32'(csr_table[rd_addr]);
|
|
endcase
|
|
end
|
|
|
|
endmodule
|