rtl: optimize csr regs

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-04-13 09:25:29 +08:00
parent bd2d372c66
commit e53f681063
3 changed files with 188 additions and 54 deletions

View File

@ -3,6 +3,7 @@
../rtl/core/clint.sv ../rtl/core/clint.sv
../rtl/core/csr_reg.sv ../rtl/core/csr_reg.sv
../rtl/core/csr.sv
../rtl/core/defines.sv ../rtl/core/defines.sv
../rtl/core/divider.sv ../rtl/core/divider.sv
../rtl/core/exu.sv ../rtl/core/exu.sv

42
rtl/core/csr.sv Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright 2021 Blue Liang, liangkangnan@163.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
module csr #(
parameter RESET_VAL = 32'h0
)(
input wire clk,
input wire rst_n,
input wire [31:0] wdata_i,
input wire we_i,
output wire [31:0] rdata_o
);
reg[31:0] rdata_q;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
rdata_q <= RESET_VAL;
end else if (we_i) begin
rdata_q <= wdata_i;
end
end
assign rdata_o = rdata_q;
endmodule

View File

@ -33,23 +33,33 @@ module csr_reg(
input wire clint_we_i, // clint模块写寄存器标志 input wire clint_we_i, // clint模块写寄存器标志
input wire[31:0] clint_waddr_i, // clint模块写寄存器地址 input wire[31:0] clint_waddr_i, // clint模块写寄存器地址
input wire[31:0] clint_wdata_i, // clint模块写寄存器数据 input wire[31:0] clint_wdata_i, // clint模块写寄存器数据
output wire[31:0] mtvec_o, // mtvec寄存器值 output wire[31:0] mtvec_o, // mtvec寄存器值
output wire[31:0] mepc_o, // mepc寄存器值 output wire[31:0] mepc_o, // mepc寄存器值
output wire[31:0] mstatus_o // mstatus寄存器值 output wire[31:0] mstatus_o // mstatus寄存器值
); );
reg[63:0] cycle; reg[31:0] mtvec_d;
reg[31:0] mtvec; wire[31:0] mtvec_q;
reg[31:0] mcause; reg mtvec_we;
reg[31:0] mepc; reg[31:0] mcause_d;
reg[31:0] mie; wire[31:0] mcause_q;
reg[31:0] mstatus; reg mcause_we;
reg[31:0] mscratch; reg[31:0] mepc_d;
wire[31:0] mepc_q;
reg mepc_we;
reg[31:0] mie_d;
wire[31:0] mie_q;
reg mie_we;
reg[31:0] mstatus_d;
wire[31:0] mstatus_q;
reg mstatus_we;
reg[31:0] mscratch_d;
wire[31:0] mscratch_q;
reg mscratch_we;
assign mtvec_o = mtvec; reg[63:0] cycle;
assign mepc_o = mepc;
assign mstatus_o = mstatus;
// cycle counter // cycle counter
// 复位撤销后就一直计数 // 复位撤销后就一直计数
@ -61,44 +71,9 @@ module csr_reg(
end end
end end
wire we = exu_we_i | clint_we_i; assign mtvec_o = mtvec_q;
wire[31:0] waddr = exu_we_i? exu_waddr_i: clint_waddr_i; assign mepc_o = mepc_q;
wire[31:0] wdata = exu_we_i? exu_wdata_i: clint_wdata_i; assign mstatus_o = mstatus_q;
// 写寄存器
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
mtvec <= 32'h0;
mcause <= 32'h0;
mepc <= 32'h0;
mie <= 32'h0;
mstatus <= 32'h0;
mscratch <= 32'h0;
end else begin
if (we) begin
case (waddr[11:0])
`CSR_MTVEC: begin
mtvec <= wdata;
end
`CSR_MCAUSE: begin
mcause <= wdata;
end
`CSR_MEPC: begin
mepc <= wdata;
end
`CSR_MIE: begin
mie <= wdata;
end
`CSR_MSTATUS: begin
mstatus <= wdata;
end
`CSR_MSCRATCH: begin
mscratch <= wdata;
end
endcase
end
end
end
reg[31:0] exu_rdata; reg[31:0] exu_rdata;
@ -112,22 +87,22 @@ module csr_reg(
exu_rdata = cycle[63:32]; exu_rdata = cycle[63:32];
end end
`CSR_MTVEC: begin `CSR_MTVEC: begin
exu_rdata = mtvec; exu_rdata = mtvec_q;
end end
`CSR_MCAUSE: begin `CSR_MCAUSE: begin
exu_rdata = mcause; exu_rdata = mcause_q;
end end
`CSR_MEPC: begin `CSR_MEPC: begin
exu_rdata = mepc; exu_rdata = mepc_q;
end end
`CSR_MIE: begin `CSR_MIE: begin
exu_rdata = mie; exu_rdata = mie_q;
end end
`CSR_MSTATUS: begin `CSR_MSTATUS: begin
exu_rdata = mstatus; exu_rdata = mstatus_q;
end end
`CSR_MSCRATCH: begin `CSR_MSCRATCH: begin
exu_rdata = mscratch; exu_rdata = mscratch_q;
end end
default: begin default: begin
exu_rdata = 32'h0; exu_rdata = 32'h0;
@ -137,4 +112,120 @@ module csr_reg(
assign exu_rdata_o = exu_rdata; assign exu_rdata_o = exu_rdata;
// 写CSR寄存器
wire we = exu_we_i | clint_we_i;
wire[31:0] waddr = exu_we_i? exu_waddr_i: clint_waddr_i;
wire[31:0] wdata = exu_we_i? exu_wdata_i: clint_wdata_i;
always @ (*) begin
mtvec_d = mtvec_q;
mtvec_we = 1'b0;
mcause_d = mcause_q;
mcause_we = 1'b0;
mepc_d = mepc_q;
mepc_we = 1'b0;
mie_d = mie_q;
mie_we = 1'b0;
mstatus_d = mstatus_q;
mstatus_we = 1'b0;
mscratch_d = mscratch_q;
mscratch_we = 1'b0;
if (we) begin
case (waddr[11:0])
`CSR_MTVEC: begin
mtvec_d = wdata;
mtvec_we = 1'b1;
end
`CSR_MCAUSE: begin
mcause_d = wdata;
mcause_we = 1'b1;
end
`CSR_MEPC: begin
mepc_d = wdata;
mepc_we = 1'b1;
end
`CSR_MIE: begin
mie_d = wdata;
mie_we = 1'b1;
end
`CSR_MSTATUS: begin
mstatus_d = wdata;
mstatus_we = 1'b1;
end
`CSR_MSCRATCH: begin
mscratch_d = wdata;
mscratch_we = 1'b1;
end
default:;
endcase
end
end
// mtvec
csr #(
.RESET_VAL(32'h0)
) mtvec_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mtvec_d),
.we_i(mtvec_we),
.rdata_o(mtvec_q)
);
// mcause
csr #(
.RESET_VAL(32'h0)
) mcause_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mcause_d),
.we_i(mcause_we),
.rdata_o(mcause_q)
);
// mepc
csr #(
.RESET_VAL(32'h0)
) mepc_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mepc_d),
.we_i(mepc_we),
.rdata_o(mepc_q)
);
// mie
csr #(
.RESET_VAL(32'h0)
) mie_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mie_d),
.we_i(mie_we),
.rdata_o(mie_q)
);
// mstatus
csr #(
.RESET_VAL(32'h0)
) mstatus_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mstatus_d),
.we_i(mstatus_we),
.rdata_o(mstatus_q)
);
// mscratch
csr #(
.RESET_VAL(32'h0)
) mscratch_csr (
.clk(clk),
.rst_n(rst_n),
.wdata_i(mscratch_d),
.we_i(mscratch_we),
.rdata_o(mscratch_q)
);
endmodule endmodule