parent
ecb9fca8c1
commit
6660f18b3d
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue