support CSR inst

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/1/head
liangkangnan 2020-04-05 22:22:34 +08:00
parent ecb9fca8c1
commit 6660f18b3d
6 changed files with 273 additions and 5 deletions

68
rtl/core/csr_reg.v Normal file
View File

@ -0,0 +1,68 @@
/*
Copyright 2020 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.
*/
`include "defines.v"
// csr reg module
module csr_reg(
input wire clk,
input wire rst,
input wire we_i,
input wire[`MemAddrBus] raddr_i,
input wire[`MemAddrBus] waddr_i,
input wire[`RegBus] data_i,
output reg[`RegBus] data_o
);
localparam CSR_CYCLE = 12'hc00;
localparam CSR_CYCLEH = 12'hc80;
reg[63:0] cycle;
always @ (posedge clk) begin
if (rst == `RstEnable) begin
cycle <= 64'h0;
end else begin
cycle <= cycle + 1'b1;
end
end
// read reg
always @ (*) begin
if (rst == `RstEnable) begin
data_o <= `ZeroWord;
end else begin
case (raddr_i[11:0])
CSR_CYCLE: begin
data_o <= cycle[31:0];
end
CSR_CYCLEH: begin
data_o <= cycle[63:32];
end
default: begin
data_o <= `ZeroWord;
end
endcase
end
end
endmodule

View File

@ -123,6 +123,15 @@
`define INST_BLTU 3'b110
`define INST_BGEU 3'b111
// CSR inst
`define INST_CSR 7'b1110011
`define INST_CSRRW 3'b001
`define INST_CSRRS 3'b010
`define INST_CSRRC 3'b011
`define INST_CSRRWI 3'b101
`define INST_CSRRSI 3'b110
`define INST_CSRRCI 3'b111
`define RomNum 2048 // rom depth(how many words)
`define MemNum 2048 // memory depth(how many words)

View File

@ -28,6 +28,9 @@ module ex(
input wire[`RegAddrBus] reg_waddr_i,
input wire[`RegBus] reg1_rdata_i, // reg1 read data
input wire[`RegBus] reg2_rdata_i, // reg2 read data
input wire csr_we_i,
input wire[`MemAddrBus] csr_waddr_i,
input wire[`RegBus] csr_rdata_i,
// from mem
input wire[`MemBus] mem_rdata_i, // mem read data
@ -57,6 +60,11 @@ module ex(
output wire reg_we_o, // reg write enable
output wire[`RegAddrBus] reg_waddr_o, // reg write addr
// to csr reg
output reg[`RegBus] csr_wdata_o, // reg write data
output wire csr_we_o, // reg write enable
output wire[`MemAddrBus] csr_waddr_o,
// to div
output reg div_start_o,
output reg[`RegBus] div_dividend_o,
@ -90,6 +98,7 @@ module ex(
wire[2:0] funct3;
wire[6:0] funct7;
wire[4:0] rd;
wire[4:0] uimm;
reg[`RegBus] reg_wdata;
reg reg_we;
reg[`RegAddrBus] reg_waddr;
@ -107,6 +116,7 @@ module ex(
assign funct3 = inst_i[14:12];
assign funct7 = inst_i[31:25];
assign rd = inst_i[11:7];
assign uimm = inst_i[19:15];
assign sign_extend_tmp = {{20{inst_i[31]}}, inst_i[31:20]};
assign shift_bits = inst_i[24:20];
@ -125,6 +135,9 @@ module ex(
assign jump_flag_o = jump_flag || div_jump_flag;
assign jump_addr_o = jump_addr | div_jump_addr;
assign csr_we_o = csr_we_i;
assign csr_waddr_o = csr_waddr_i;
// handle interrupt
always @ (*) begin
@ -307,10 +320,12 @@ module ex(
reg_wdata <= `ZeroWord;
reg_we <= `WriteDisable;
reg_waddr <= `ZeroWord;
csr_wdata_o <= `ZeroWord;
end else begin
reg_we <= reg_we_i;
reg_waddr <= reg_waddr_i;
mem_req_o <= `RIB_NREQ;
csr_wdata_o <= `ZeroWord;
case (opcode)
`INST_TYPE_I: begin
@ -1073,6 +1088,51 @@ module ex(
jump_flag <= `JumpEnable;
jump_addr <= inst_addr_i + 4'h4;
end
`INST_CSR: begin
jump_flag <= `JumpDisable;
hold_flag <= `HoldDisable;
jump_addr <= `ZeroWord;
mem_wdata_o <= `ZeroWord;
mem_raddr_o <= `ZeroWord;
mem_waddr_o <= `ZeroWord;
mem_we_o <= `WriteDisable;
case (funct3)
`INST_CSRRW: begin
csr_wdata_o <= reg1_rdata_i;
reg_wdata <= csr_rdata_i;
end
`INST_CSRRS: begin
csr_wdata_o <= reg1_rdata_i | csr_rdata_i;
reg_wdata <= csr_rdata_i;
end
`INST_CSRRC: begin
csr_wdata_o <= csr_rdata_i & (~reg1_rdata_i);
reg_wdata <= csr_rdata_i;
end
`INST_CSRRWI: begin
csr_wdata_o <= {27'h0, uimm};
reg_wdata <= csr_rdata_i;
end
`INST_CSRRSI: begin
csr_wdata_o <= {27'h0, uimm} | csr_rdata_i;
reg_wdata <= csr_rdata_i;
end
`INST_CSRRCI: begin
csr_wdata_o <= (~{27'h0, uimm}) & csr_rdata_i;
reg_wdata <= csr_rdata_i;
end
default: begin
jump_flag <= `JumpDisable;
hold_flag <= `HoldDisable;
jump_addr <= `ZeroWord;
mem_wdata_o <= `ZeroWord;
mem_raddr_o <= `ZeroWord;
mem_waddr_o <= `ZeroWord;
mem_we_o <= `WriteDisable;
reg_wdata <= `ZeroWord;
end
endcase
end
default: begin
jump_flag <= `JumpDisable;
hold_flag <= `HoldDisable;

View File

@ -29,6 +29,9 @@ module id(
input wire[`RegBus] reg1_rdata_i, // reg1 read data
input wire[`RegBus] reg2_rdata_i, // reg2 read data
// from csr reg
input wire[`RegBus] csr_rdata_i,
// from ex
input wire ex_jump_flag_i,
input wire[`INT_BUS] ex_int_flag_i,
@ -37,6 +40,9 @@ module id(
output reg[`RegAddrBus] reg1_raddr_o, // reg1 read addr
output reg[`RegAddrBus] reg2_raddr_o, // reg2 read addr
// to csr reg
output reg[`MemAddrBus] csr_raddr_o,
output wire mem_req_o,
// to ex
@ -45,7 +51,10 @@ module id(
output reg[`RegBus] reg1_rdata_o, // reg1 read data
output reg[`RegBus] reg2_rdata_o, // reg2 read data
output reg reg_we_o, // reg write enable
output reg[`RegAddrBus] reg_waddr_o // reg write addr
output reg[`RegAddrBus] reg_waddr_o, // reg write addr
output reg csr_we_o,
output reg[`RegBus] csr_rdata_o,
output reg[`MemAddrBus] csr_waddr_o
);
@ -65,19 +74,27 @@ module id(
if (rst == `RstEnable) begin
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
csr_raddr_o <= `ZeroWord;
inst_o <= `INST_NOP;
inst_addr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
csr_rdata_o <= `ZeroWord;
reg_we_o <= `WriteDisable;
csr_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
csr_waddr_o <= `ZeroWord;
mem_req <= `RIB_NREQ;
end else begin
inst_o <= inst_i;
inst_addr_o <= inst_addr_i;
reg1_rdata_o <= reg1_rdata_i;
reg2_rdata_o <= reg2_rdata_i;
csr_rdata_o <= csr_rdata_i;
mem_req <= `RIB_NREQ;
csr_raddr_o <= `ZeroWord;
csr_waddr_o <= `ZeroWord;
csr_we_o <= `WriteDisable;
case (opcode)
`INST_TYPE_I: begin
@ -418,6 +435,65 @@ module id(
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
end
`INST_CSR: begin
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
csr_raddr_o <= {20'h0, inst_i[31:20]};
csr_waddr_o <= {20'h0, inst_i[31:20]};
case (funct3)
`INST_CSRRW: begin
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
`INST_CSRRS: begin
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
`INST_CSRRC: begin
reg1_raddr_o <= rs1;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
`INST_CSRRWI: begin
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
`INST_CSRRSI: begin
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
`INST_CSRRCI: begin
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
reg_we_o <= `WriteEnable;
reg_waddr_o <= rd;
csr_we_o <= `WriteEnable;
end
default: begin
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;
reg1_raddr_o <= `ZeroWord;
reg2_raddr_o <= `ZeroWord;
csr_we_o <= `WriteDisable;
end
endcase
end
default: begin
reg_we_o <= `WriteDisable;
reg_waddr_o <= `ZeroWord;

View File

@ -28,6 +28,9 @@ module id_ex(
input wire[`RegAddrBus] reg_waddr_i,
input wire[`RegBus] reg1_rdata_i, // reg1 read data
input wire[`RegBus] reg2_rdata_i, // reg2 read data
input wire csr_we_i,
input wire[`MemAddrBus] csr_waddr_i,
input wire[`RegBus] csr_rdata_i,
input wire[`Hold_Flag_Bus] hold_flag_i,
@ -36,7 +39,10 @@ module id_ex(
output reg reg_we_o,
output reg[`RegAddrBus] reg_waddr_o,
output reg[`RegBus] reg1_rdata_o, // reg1 read data
output reg[`RegBus] reg2_rdata_o // reg2 read data
output reg[`RegBus] reg2_rdata_o, // reg2 read data
output reg csr_we_o,
output reg[`MemAddrBus] csr_waddr_o,
output reg[`RegBus] csr_rdata_o
);
@ -48,6 +54,9 @@ module id_ex(
reg_waddr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
csr_we_o <= `WriteDisable;
csr_waddr_o <= `ZeroWord;
csr_rdata_o <= `ZeroWord;
end else begin
if (hold_flag_i >= `Hold_Id) begin
inst_o <= `INST_NOP;
@ -56,6 +65,9 @@ module id_ex(
reg_waddr_o <= `ZeroWord;
reg1_rdata_o <= `ZeroWord;
reg2_rdata_o <= `ZeroWord;
csr_we_o <= `WriteDisable;
csr_waddr_o <= `ZeroWord;
csr_rdata_o <= `ZeroWord;
end else begin
inst_o <= inst_i;
inst_addr_o <= inst_addr_i;
@ -63,6 +75,9 @@ module id_ex(
reg_waddr_o <= reg_waddr_i;
reg1_rdata_o <= reg1_rdata_i;
reg2_rdata_o <= reg2_rdata_i;
csr_we_o <= csr_we_i;
csr_waddr_o <= csr_waddr_i;
csr_rdata_o <= csr_rdata_i;
end
end
end

View File

@ -61,6 +61,10 @@ module tinyriscv(
wire[`RegBus] id_reg2_rdata_o;
wire id_reg_we_o;
wire[`RegAddrBus] id_reg_waddr_o;
wire[`MemAddrBus] id_csr_raddr_o;
wire id_csr_we_o;
wire[`RegBus] id_csr_rdata_o;
wire[`MemAddrBus] id_csr_waddr_o;
// id_ex
wire[`InstBus] ie_inst_o;
@ -69,6 +73,9 @@ module tinyriscv(
wire[`RegAddrBus] ie_reg_waddr_o;
wire[`RegBus] ie_reg1_rdata_o;
wire[`RegBus] ie_reg2_rdata_o;
wire ie_csr_we_o;
wire[`MemAddrBus] ie_csr_waddr_o;
wire[`RegBus] ie_csr_rdata_o;
// ex
wire[`MemBus] ex_mem_wdata_o;
@ -92,11 +99,17 @@ module tinyriscv(
wire ex_clint_we_o;
wire[`RegAddrBus] ex_clint_addr_o;
wire[`RegBus] ex_clint_data_o;
wire[`RegBus] ex_csr_wdata_o;
wire ex_csr_we_o;
wire[`MemAddrBus] ex_csr_waddr_o;
// regs
wire[`RegBus] regs_rdata1_o;
wire[`RegBus] regs_rdata2_o;
// csr reg
wire[`RegBus] csr_data_o;
// ctrl
wire[`Hold_Flag_Bus] ctrl_hold_flag_o;
wire ctrl_jump_flag_o;
@ -161,6 +174,16 @@ module tinyriscv(
.jtag_data_o(jtag_reg_data_o)
);
csr_reg u_csr_reg(
.clk(clk),
.rst(rst),
.we_i(ex_csr_we_o),
.raddr_i(id_csr_raddr_o),
.waddr_i(ex_csr_waddr_o),
.data_i(ex_csr_wdata_o),
.data_o(csr_data_o)
);
if_id u_if_id(
.clk(clk),
.rst(rst),
@ -187,7 +210,12 @@ module tinyriscv(
.reg1_rdata_o(id_reg1_rdata_o),
.reg2_rdata_o(id_reg2_rdata_o),
.reg_we_o(id_reg_we_o),
.reg_waddr_o(id_reg_waddr_o)
.reg_waddr_o(id_reg_waddr_o),
.csr_rdata_i(csr_data_o),
.csr_raddr_o(id_csr_raddr_o),
.csr_we_o(id_csr_we_o),
.csr_rdata_o(id_csr_rdata_o),
.csr_waddr_o(id_csr_waddr_o)
);
id_ex u_id_ex(
@ -205,7 +233,13 @@ module tinyriscv(
.reg_we_o(ie_reg_we_o),
.reg_waddr_o(ie_reg_waddr_o),
.reg1_rdata_o(ie_reg1_rdata_o),
.reg2_rdata_o(ie_reg2_rdata_o)
.reg2_rdata_o(ie_reg2_rdata_o),
.csr_we_i(id_csr_we_o),
.csr_waddr_i(id_csr_waddr_o),
.csr_rdata_i(id_csr_rdata_o),
.csr_we_o(ie_csr_we_o),
.csr_waddr_o(ie_csr_waddr_o),
.csr_rdata_o(ie_csr_rdata_o)
);
ex u_ex(
@ -244,7 +278,13 @@ module tinyriscv(
.div_dividend_o(ex_div_dividend_o),
.div_divisor_o(ex_div_divisor_o),
.div_op_o(ex_div_op_o),
.div_reg_waddr_o(ex_div_reg_waddr_o)
.div_reg_waddr_o(ex_div_reg_waddr_o),
.csr_we_i(ie_csr_we_o),
.csr_waddr_i(ie_csr_waddr_o),
.csr_rdata_i(ie_csr_rdata_o),
.csr_wdata_o(ex_csr_wdata_o),
.csr_we_o(ex_csr_we_o),
.csr_waddr_o(ex_csr_waddr_o)
);
div u_div(