init repo: update to RV32IMA (M mode)
This commit is contained in:
37
.gitignore
vendored
Normal file
37
.gitignore
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
*
|
||||
!*/
|
||||
|
||||
# track this file or dic
|
||||
!.gitignore
|
||||
!readme.md
|
||||
|
||||
doc/**
|
||||
!others/**
|
||||
|
||||
# vivado
|
||||
!rv_cpu.xpr
|
||||
|
||||
## srcs
|
||||
!rv_cpu.srcs/constrs_1/**
|
||||
|
||||
!rv_cpu.srcs/sources_1/ip/*/*.xci
|
||||
!rv_cpu.srcs/sources_1/ip/*/*.coe
|
||||
|
||||
!rv_cpu.srcs/sources_1/new/**
|
||||
!rv_cpu.srcs/sources_1/imports/**
|
||||
!rv_cpu.srcs/sources_1/bd/**
|
||||
|
||||
## sims
|
||||
!rv_cpu.srcs/sim_1/**
|
||||
|
||||
!rv_cpu.sim/sim_1/behav/modelsim/*.do
|
||||
rv_cpu.sim/sim_1/behav/xsim/*.wdb
|
||||
!rv_cpu.sim/sim_1/*.wcfg
|
||||
|
||||
## bits
|
||||
!rv_cpu.runs/impl_1/*.bit
|
||||
!rv_cpu.runs/impl_1/*.bin
|
||||
!rv_cpu.runs/impl_1/*.ltx
|
||||
!rv_cpu.runs/bits/*.bit
|
||||
!rv_cpu.runs/bits/*.bin
|
||||
!rv_cpu.runs/bits/*.ltx
|
||||
271
rv_cpu.srcs/sources_1/new/cpu_top.v
Normal file
271
rv_cpu.srcs/sources_1/new/cpu_top.v
Normal file
@@ -0,0 +1,271 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 14:00:00
|
||||
// Design Name: cpu_top
|
||||
// Module Name: cpu_top
|
||||
// Project Name: rv_cpu
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Top module for the RISC-V CPU, connecting pipeline stages.
|
||||
//
|
||||
// Dependencies: if_stage, id_stage, exe_stage, mem_stage, wb_stage
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module cpu_top (
|
||||
// Global signals
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
// Instruction SRAM interface
|
||||
output inst_sram_en_o,
|
||||
output [ 3:0] inst_sram_wen_o,
|
||||
output [31:0] inst_sram_addr_o,
|
||||
output [31:0] inst_sram_wdata_o,
|
||||
input [31:0] inst_sram_rdata_i,
|
||||
|
||||
// Data SRAM interface
|
||||
output data_sram_en_o,
|
||||
output [ 3:0] data_sram_wen_o,
|
||||
output [31:0] data_sram_addr_o,
|
||||
output [31:0] data_sram_wdata_o,
|
||||
input [31:0] data_sram_rdata_i,
|
||||
|
||||
// Debug signals from WB stage
|
||||
output [31:0] debug_wb_pc_o,
|
||||
output [ 3:0] debug_wb_rf_wen_o,
|
||||
output [ 4:0] debug_wb_rf_waddr_o,
|
||||
output [31:0] debug_wb_rf_wdata_o
|
||||
);
|
||||
|
||||
// Define local parameters for bus widths based on stage module parameters
|
||||
localparam FS_TO_DS_BUS_WIDTH = 65;
|
||||
localparam DS_TO_ES_BUS_WIDTH = 315;
|
||||
localparam ES_TO_MS_BUS_WIDTH = 164;
|
||||
localparam MS_TO_WS_BUS_WIDTH = 70;
|
||||
localparam WS_TO_DS_BUS_WIDTH = 38;
|
||||
localparam ES_TO_DS_FWD_BUS_WIDTH = 39;
|
||||
localparam MS_TO_DS_FWD_BUS_WIDTH = 38;
|
||||
|
||||
// Wires for IF <-> ID pipeline registers
|
||||
wire [FS_TO_DS_BUS_WIDTH-1:0] fs_to_ds_bus_data;
|
||||
wire fs_to_ds_bus_valid;
|
||||
wire fs_to_ds_bus_ready;
|
||||
|
||||
// Wires for ID <-> EXE pipeline registers
|
||||
wire [DS_TO_ES_BUS_WIDTH-1:0] ds_to_es_bus_data;
|
||||
wire ds_to_es_bus_valid;
|
||||
wire ds_to_es_bus_ready;
|
||||
|
||||
// Wires for EXE <-> MEM pipeline registers
|
||||
wire [ES_TO_MS_BUS_WIDTH-1:0] es_to_ms_bus_data;
|
||||
wire es_to_ms_bus_valid;
|
||||
wire es_to_ms_bus_ready;
|
||||
|
||||
// Wires for MEM <-> WB pipeline registers
|
||||
wire [MS_TO_WS_BUS_WIDTH-1:0] ms_to_ws_bus_data;
|
||||
wire ms_to_ws_bus_valid;
|
||||
wire ms_to_ws_bus_ready;
|
||||
|
||||
// Wires for WB -> ID (write-back path)
|
||||
wire [WS_TO_DS_BUS_WIDTH-1:0] ws_to_ds_bus_data;
|
||||
wire ws_to_ds_bus_valid;
|
||||
|
||||
// Wires for branch prediction (EXE -> IF)
|
||||
wire [31:0] br_target;
|
||||
wire br_taken;
|
||||
|
||||
// Fowarding buses for ID stage
|
||||
wire [ES_TO_DS_FWD_BUS_WIDTH-1:0] es_to_ds_fwd_bus_data;
|
||||
wire [MS_TO_DS_FWD_BUS_WIDTH-1:0] ms_to_ds_fwd_bus_data;
|
||||
|
||||
wire [ 1:0] csr_mpp;
|
||||
|
||||
wire es_a_ext_stall;
|
||||
wire ms_a_ext_stall;
|
||||
|
||||
wire load_stall;
|
||||
wire m_ext_stall;
|
||||
wire a_ext_stall;
|
||||
|
||||
wire csr_flush;
|
||||
wire br_flush;
|
||||
|
||||
wire es_data_sram_en;
|
||||
wire [ 3:0] es_data_sram_wen;
|
||||
wire [31:0] es_data_sram_addr;
|
||||
wire [31:0] es_data_sram_wdata;
|
||||
|
||||
wire ms_data_sram_en;
|
||||
wire [ 3:0] ms_data_sram_wen;
|
||||
wire [31:0] ms_data_sram_addr;
|
||||
wire [31:0] ms_data_sram_wdata;
|
||||
|
||||
assign a_ext_stall = es_a_ext_stall | ms_a_ext_stall;
|
||||
|
||||
// Instantiate IF Stage
|
||||
if_stage #(
|
||||
.FS_TO_DS_BUS_WIDTH(FS_TO_DS_BUS_WIDTH)
|
||||
) inst_if_stage (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
|
||||
.load_stall_i (load_stall),
|
||||
.m_ext_stall_i (m_ext_stall),
|
||||
.a_ext_stall_i (a_ext_stall),
|
||||
.br_flush_i (br_flush),
|
||||
.csr_flush_i (csr_flush),
|
||||
|
||||
.br_target_i (br_target),
|
||||
.br_taken_i (br_taken),
|
||||
|
||||
.fs_to_ds_bus_ready_i (fs_to_ds_bus_ready),
|
||||
.fs_to_ds_bus_data_o (fs_to_ds_bus_data),
|
||||
.fs_to_ds_bus_valid_o (fs_to_ds_bus_valid),
|
||||
|
||||
.inst_sram_en_o (inst_sram_en_o),
|
||||
.inst_sram_wen_o (inst_sram_wen_o),
|
||||
.inst_sram_addr_o (inst_sram_addr_o),
|
||||
.inst_sram_wdata_o (inst_sram_wdata_o),
|
||||
.inst_sram_rdata_i (inst_sram_rdata_i)
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Instantiate ID Stage
|
||||
id_stage #(
|
||||
.FS_TO_DS_BUS_WIDTH(FS_TO_DS_BUS_WIDTH),
|
||||
.DS_TO_ES_BUS_WIDTH(DS_TO_ES_BUS_WIDTH),
|
||||
.WS_TO_DS_BUS_WIDTH(WS_TO_DS_BUS_WIDTH),
|
||||
.ES_TO_DS_FWD_BUS_WIDTH(ES_TO_DS_FWD_BUS_WIDTH),
|
||||
.MS_TO_DS_FWD_BUS_WIDTH(MS_TO_DS_FWD_BUS_WIDTH)
|
||||
) inst_id_stage (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
|
||||
.csr_mpp_i (csr_mpp),
|
||||
|
||||
.csr_flush_i (csr_flush),
|
||||
.m_ext_stall_i (m_ext_stall),
|
||||
.a_ext_stall_i (a_ext_stall),
|
||||
|
||||
.fs_to_ds_bus_ready_o (fs_to_ds_bus_ready),
|
||||
.fs_to_ds_bus_data_i (fs_to_ds_bus_data),
|
||||
.fs_to_ds_bus_valid_i (fs_to_ds_bus_valid),
|
||||
|
||||
.ds_to_es_bus_ready_i (ds_to_es_bus_ready),
|
||||
.ds_to_es_bus_data_o (ds_to_es_bus_data),
|
||||
.ds_to_es_bus_valid_o (ds_to_es_bus_valid),
|
||||
|
||||
.ws_to_ds_bus_data_i (ws_to_ds_bus_data),
|
||||
.ws_to_ds_bus_valid_i (ws_to_ds_bus_valid),
|
||||
|
||||
.es_to_ds_fwd_bus_data_i (es_to_ds_fwd_bus_data),
|
||||
.ms_to_ds_fwd_bus_data_i (ms_to_ds_fwd_bus_data),
|
||||
|
||||
.br_flush_o (br_flush),
|
||||
.load_stall_o (load_stall)
|
||||
);
|
||||
|
||||
// Instantiate EXE Stage
|
||||
exe_stage #(
|
||||
.DS_TO_ES_BUS_WIDTH(DS_TO_ES_BUS_WIDTH),
|
||||
.ES_TO_MS_BUS_WIDTH(ES_TO_MS_BUS_WIDTH),
|
||||
.ES_TO_DS_FWD_BUS_WIDTH(ES_TO_DS_FWD_BUS_WIDTH)
|
||||
) inst_exe_stage (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
|
||||
.ds_to_es_bus_ready_o (ds_to_es_bus_ready),
|
||||
.ds_to_es_bus_data_i (ds_to_es_bus_data),
|
||||
.ds_to_es_bus_valid_i (ds_to_es_bus_valid),
|
||||
|
||||
.es_to_ms_bus_ready_i (es_to_ms_bus_ready),
|
||||
.es_to_ms_bus_data_o (es_to_ms_bus_data),
|
||||
.es_to_ms_bus_valid_o (es_to_ms_bus_valid),
|
||||
|
||||
.br_target_o (br_target),
|
||||
.br_taken_o (br_taken),
|
||||
|
||||
.data_sram_en_o (es_data_sram_en),
|
||||
.data_sram_wen_o (es_data_sram_wen),
|
||||
.data_sram_addr_o (es_data_sram_addr),
|
||||
.data_sram_wdata_o (es_data_sram_wdata),
|
||||
|
||||
.es_to_ds_fwd_bus_data_o(es_to_ds_fwd_bus_data),
|
||||
|
||||
.csr_mpp_o (csr_mpp),
|
||||
|
||||
.m_ext_stall_o (m_ext_stall),
|
||||
.a_ext_stall_o (es_a_ext_stall),
|
||||
.csr_flush_o (csr_flush)
|
||||
);
|
||||
|
||||
// Instantiate MEM Stage
|
||||
mem_stage #(
|
||||
.ES_TO_MS_BUS_WIDTH(ES_TO_MS_BUS_WIDTH),
|
||||
.MS_TO_WS_BUS_WIDTH(MS_TO_WS_BUS_WIDTH),
|
||||
.MS_TO_DS_FWD_BUS_WIDTH(MS_TO_DS_FWD_BUS_WIDTH)
|
||||
) inst_mem_stage (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
|
||||
.csr_flush_i (csr_flush),
|
||||
|
||||
.es_to_ms_bus_ready_o (es_to_ms_bus_ready),
|
||||
.es_to_ms_bus_data_i (es_to_ms_bus_data),
|
||||
.es_to_ms_bus_valid_i (es_to_ms_bus_valid),
|
||||
|
||||
.ms_to_ws_bus_ready_i (ms_to_ws_bus_ready),
|
||||
.ms_to_ws_bus_data_o (ms_to_ws_bus_data),
|
||||
.ms_to_ws_bus_valid_o (ms_to_ws_bus_valid),
|
||||
|
||||
.data_sram_rdata_i (data_sram_rdata_i),
|
||||
.data_sram_en_o (ms_data_sram_en),
|
||||
.data_sram_wen_o (ms_data_sram_wen),
|
||||
.data_sram_addr_o (ms_data_sram_addr),
|
||||
.data_sram_wdata_o (ms_data_sram_wdata),
|
||||
|
||||
.a_ext_stall_o (ms_a_ext_stall),
|
||||
.ms_to_ds_fwd_bus_data_o(ms_to_ds_fwd_bus_data)
|
||||
);
|
||||
|
||||
// Instantiate WB Stage
|
||||
wb_stage #(
|
||||
.MS_TO_WS_BUS_WIDTH(MS_TO_WS_BUS_WIDTH),
|
||||
.WS_TO_DS_BUS_WIDTH(WS_TO_DS_BUS_WIDTH)
|
||||
) inst_wb_stage (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
|
||||
.ms_to_ws_bus_ready_o (ms_to_ws_bus_ready),
|
||||
.ms_to_ws_bus_data_i (ms_to_ws_bus_data),
|
||||
.ms_to_ws_bus_valid_i (ms_to_ws_bus_valid),
|
||||
|
||||
.ws_to_ds_bus_data_o (ws_to_ds_bus_data),
|
||||
.ws_to_ds_bus_valid_o (ws_to_ds_bus_valid),
|
||||
|
||||
.debug_wb_pc_o (debug_wb_pc_o),
|
||||
.debug_wb_rf_wen_o (debug_wb_rf_wen_o),
|
||||
.debug_wb_rf_waddr_o (debug_wb_rf_waddr_o),
|
||||
.debug_wb_rf_wdata_o (debug_wb_rf_wdata_o)
|
||||
);
|
||||
|
||||
assign data_sram_en_o = es_data_sram_en
|
||||
| ms_data_sram_en;
|
||||
assign data_sram_wen_o = {4{es_data_sram_en}} & es_data_sram_wen
|
||||
| {4{ms_data_sram_en}} & ms_data_sram_wen;
|
||||
assign data_sram_addr_o = {32{es_data_sram_en}} & es_data_sram_addr
|
||||
| {32{ms_data_sram_en}} & ms_data_sram_addr;
|
||||
assign data_sram_wdata_o = {32{es_data_sram_en}} & es_data_sram_wdata
|
||||
| {32{ms_data_sram_en}} & ms_data_sram_wdata;
|
||||
|
||||
|
||||
endmodule
|
||||
287
rv_cpu.srcs/sources_1/new/exe_stage.v
Normal file
287
rv_cpu.srcs/sources_1/new/exe_stage.v
Normal file
@@ -0,0 +1,287 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 04:05:18
|
||||
// Design Name:
|
||||
// Module Name: exe_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Desrciption:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module exe_stage #(
|
||||
parameter DS_TO_ES_BUS_WIDTH = 315,
|
||||
parameter ES_TO_MS_BUS_WIDTH = 164,
|
||||
parameter ES_TO_DS_FWD_BUS_WIDTH = 39
|
||||
)
|
||||
(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
output ds_to_es_bus_ready_o,
|
||||
input [DS_TO_ES_BUS_WIDTH-1:0] ds_to_es_bus_data_i,
|
||||
input ds_to_es_bus_valid_i,
|
||||
|
||||
input es_to_ms_bus_ready_i,
|
||||
output [ES_TO_MS_BUS_WIDTH-1:0] es_to_ms_bus_data_o,
|
||||
output es_to_ms_bus_valid_o,
|
||||
|
||||
output [31:0] br_target_o,
|
||||
output br_taken_o,
|
||||
|
||||
output data_sram_en_o,
|
||||
output [ 3:0] data_sram_wen_o,
|
||||
output [31:0] data_sram_addr_o,
|
||||
output [31:0] data_sram_wdata_o,
|
||||
|
||||
// fowarding bus to ID stage
|
||||
output [ES_TO_DS_FWD_BUS_WIDTH-1:0] es_to_ds_fwd_bus_data_o,
|
||||
|
||||
output [ 1:0] csr_mpp_o,
|
||||
|
||||
output m_ext_stall_o,
|
||||
output a_ext_stall_o,
|
||||
output csr_flush_o
|
||||
);
|
||||
|
||||
reg ds_to_es_bus_valid;
|
||||
reg [DS_TO_ES_BUS_WIDTH-1:0] ds_to_es_bus_data;
|
||||
|
||||
wire es_pipeline_stall;
|
||||
|
||||
wire es_to_ms_bus_valid;
|
||||
|
||||
wire [31:0] es_inst;
|
||||
wire [31:0] es_pc;
|
||||
|
||||
wire [ 4:0] es_rs1;
|
||||
wire [ 4:0] es_rs2;
|
||||
wire [ 4:0] es_rd;
|
||||
wire [31:0] es_imm;
|
||||
wire [ 4:0] es_shamt;
|
||||
wire [11:0] es_csr;
|
||||
wire [ 4:0] es_zimm;
|
||||
|
||||
wire [10:0] es_alu_op;
|
||||
wire [ 3:0] es_calc_src1_sel;
|
||||
wire [ 3:0] es_calc_src2_sel;
|
||||
wire [ 1:0] es_jump_op;
|
||||
wire [ 5:0] es_load_op;
|
||||
wire [ 2:0] es_store_op;
|
||||
wire [11:0] es_amo_op;
|
||||
|
||||
wire [31:0] es_rs1_value;
|
||||
wire [31:0] es_rs2_value;
|
||||
|
||||
wire [31:0] es_br_target;
|
||||
wire es_br_taken;
|
||||
|
||||
wire [ 2:0] es_csr_op;
|
||||
wire [ 7:0] es_m_ext_op;
|
||||
|
||||
wire es_op_is_alu;
|
||||
wire es_op_is_m_ext;
|
||||
wire es_op_is_jump;
|
||||
wire es_op_is_branch;
|
||||
wire es_op_is_load;
|
||||
wire es_op_is_store;
|
||||
wire es_op_is_csr;
|
||||
wire es_op_is_amo;
|
||||
|
||||
wire [31:0] es_calc_src1;
|
||||
wire [31:0] es_calc_src2;
|
||||
|
||||
wire [31:0] es_excp_vec;
|
||||
|
||||
wire [31:0] es_alu_result;
|
||||
|
||||
wire [31:0] es_result;
|
||||
|
||||
wire [ 2:0] es_result_sel;
|
||||
wire [31:0] es_m_ext_result;
|
||||
wire es_m_ext_valid;
|
||||
|
||||
wire [31:0] es_csr_result;
|
||||
wire es_csr_taken;
|
||||
wire [31:0] es_csr_target;
|
||||
|
||||
assign es_pipeline_stall = m_ext_stall_o;
|
||||
|
||||
assign {
|
||||
es_excp_vec, // 314:283 (32 bits)
|
||||
es_amo_op, // 282:271 (12 bits)
|
||||
es_csr_op, // 270:268 (3 bits)
|
||||
es_m_ext_op, // 267:260 (8 bits)
|
||||
es_br_taken, // 259:259 (1 bit)
|
||||
es_br_target, // 258:227 (32 bits)
|
||||
es_store_op, // 226:224 (3 bits)
|
||||
es_load_op, // 223:218 (6 bits)
|
||||
es_jump_op, // 217:216 (2 bits)
|
||||
es_alu_op, // 215:205 (11 bits)
|
||||
es_calc_src2_sel, // 204:201 (4 bits)
|
||||
es_calc_src1_sel, // 200:197 (4 bits)
|
||||
es_rd, // 196:192 (5 bits)
|
||||
es_rs2, // 191:187 (5 bits)
|
||||
es_rs1, // 186:182 (5 bits)
|
||||
es_zimm, // 181:177 (5 bits)
|
||||
es_csr, // 176:165 (12 bits)
|
||||
es_shamt, // 164:160 (5 bits)
|
||||
es_imm, // 159:128 (32 bits)
|
||||
es_rs2_value, // 127:96 (32 bits)
|
||||
es_rs1_value, // 95:64 (32 bits)
|
||||
es_pc, // 63:32 (32 bits)
|
||||
es_inst // 31:0 (32 bits)
|
||||
} = ds_to_es_bus_data;
|
||||
|
||||
assign es_to_ms_bus_valid = !es_pipeline_stall;
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
ds_to_es_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (csr_flush_o) begin
|
||||
ds_to_es_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (ds_to_es_bus_ready_o) begin
|
||||
ds_to_es_bus_valid <= ds_to_es_bus_valid_i;
|
||||
end
|
||||
else begin
|
||||
ds_to_es_bus_valid <= ds_to_es_bus_valid;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
ds_to_es_bus_data <= {DS_TO_ES_BUS_WIDTH{1'b0}};
|
||||
end
|
||||
else if (ds_to_es_bus_valid_i && ds_to_es_bus_ready_o) begin
|
||||
ds_to_es_bus_data <= ds_to_es_bus_data_i;
|
||||
end
|
||||
else begin
|
||||
ds_to_es_bus_data <= ds_to_es_bus_data;
|
||||
end
|
||||
end
|
||||
|
||||
assign es_op_is_alu = |es_alu_op;
|
||||
assign es_op_is_m_ext = |es_m_ext_op;
|
||||
assign es_op_is_jump = |es_jump_op;
|
||||
assign es_op_is_branch = |es_br_taken;
|
||||
assign es_op_is_load = |es_load_op;
|
||||
assign es_op_is_store = |es_store_op;
|
||||
assign es_op_is_csr = |es_csr_op;
|
||||
assign es_op_is_amo = |es_amo_op;
|
||||
|
||||
assign es_calc_src1 = {32{es_calc_src1_sel[0]}} & es_rs1_value
|
||||
| {32{es_calc_src1_sel[1]}} & es_pc
|
||||
| {32{es_calc_src1_sel[2]}} & 32'b0
|
||||
| {32{es_calc_src1_sel[3]}} & es_zimm;
|
||||
assign es_calc_src2 = {32{es_calc_src2_sel[0]}} & es_rs2_value
|
||||
| {32{es_calc_src2_sel[1]}} & es_imm
|
||||
| {32{es_calc_src2_sel[2]}} & 32'h4
|
||||
| {32{es_calc_src2_sel[3]}} & es_shamt;
|
||||
|
||||
alu inst_alu(
|
||||
.alu_op_i (es_alu_op),
|
||||
.alu_src1_i (es_calc_src1),
|
||||
.alu_src2_i (es_calc_src2),
|
||||
.alu_result_o (es_alu_result)
|
||||
);
|
||||
|
||||
m_ext_unit inst_m_ext_unit (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
.m_ext_op_i (es_m_ext_op),
|
||||
.m_ext_src1_i (es_calc_src1),
|
||||
.m_ext_src2_i (es_calc_src2),
|
||||
.m_ext_result_o (es_m_ext_result),
|
||||
.m_ext_valid_o (es_m_ext_valid),
|
||||
.m_ext_stall_o (m_ext_stall_o)
|
||||
);
|
||||
|
||||
csr_reg_file inst_csr_reg_file (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
.csr_pc_i (es_pc),
|
||||
.csr_inst_i (es_inst),
|
||||
.csr_op_i (es_csr_op),
|
||||
.csr_addr_i (es_csr),
|
||||
.csr_wdata_i (es_calc_src1),
|
||||
.csr_rdata_o (es_csr_result),
|
||||
.csr_excp_vec_i (es_excp_vec),
|
||||
.csr_mpp_o (csr_mpp_o),
|
||||
.csr_taken_o (es_csr_taken),
|
||||
.csr_target_o (es_csr_target)
|
||||
);
|
||||
|
||||
|
||||
assign data_sram_en_o = ds_to_es_bus_valid && (es_op_is_store || es_op_is_load || es_op_is_amo);
|
||||
assign data_sram_wen_o = {4{(ds_to_es_bus_valid && es_op_is_store)}}
|
||||
& (
|
||||
(
|
||||
{4{es_store_op[0]}}
|
||||
& ({4{es_alu_result[1:0] == 2'b00}} & 4'b0001)
|
||||
| ({4{es_alu_result[1:0] == 2'b01}} & 4'b0010)
|
||||
| ({4{es_alu_result[1:0] == 2'b10}} & 4'b0100)
|
||||
| ({4{es_alu_result[1:0] == 2'b11}} & 4'b1000)
|
||||
)
|
||||
| (
|
||||
{4{es_store_op[1]}}
|
||||
& ({4{es_alu_result[1:0] == 2'b00}} & 4'b0011)
|
||||
| ({4{es_alu_result[1:0] == 2'b10}} & 4'b1100)
|
||||
)
|
||||
| (
|
||||
{4{es_store_op[2]}} & 4'b1111
|
||||
)
|
||||
);
|
||||
assign data_sram_addr_o = es_op_is_amo ? es_calc_src1 : es_alu_result;
|
||||
assign data_sram_wdata_o = ({32{es_store_op[0]}} & {4{es_rs2_value[ 7:0]}})
|
||||
| ({32{es_store_op[1]}} & {2{es_rs2_value[15:0]}})
|
||||
| ({32{es_store_op[2]}} & es_rs2_value );
|
||||
|
||||
assign es_result_sel = {es_op_is_amo, es_op_is_load, (es_op_is_csr || es_op_is_jump || (es_op_is_alu || es_op_is_m_ext) && !(es_op_is_store || es_op_is_load))};
|
||||
assign es_result = {32{es_op_is_alu }} & es_alu_result
|
||||
| {32{es_op_is_m_ext}} & es_m_ext_result
|
||||
| {32{es_op_is_csr }} & es_csr_result;
|
||||
|
||||
assign es_to_ms_bus_data_o = { // Total 164 bits
|
||||
es_result_sel, // 163:161 (3 bits)
|
||||
es_result, // 160:129 (32 bits)
|
||||
es_calc_src2, // 128:97 (32 bits)
|
||||
es_calc_src1, // 96:65 (32 bits)
|
||||
es_amo_op, // 64:53 (12 bits)
|
||||
es_load_op, // 52:47 (6 bits)
|
||||
es_rd, // 46:42 (5 bits)
|
||||
es_rs2, // 41:37 (5 bits)
|
||||
es_rs1, // 36:32 (5 bits)
|
||||
es_pc // 31:0 (32 bits)
|
||||
};
|
||||
|
||||
assign br_target_o = {32{es_br_taken}} & es_br_target
|
||||
| {32{es_csr_taken}} & es_csr_target;
|
||||
assign br_taken_o = ds_to_es_bus_valid && (es_br_taken || es_csr_taken);
|
||||
|
||||
assign ds_to_es_bus_ready_o = !ds_to_es_bus_valid || (es_to_ms_bus_valid && es_to_ms_bus_ready_i);
|
||||
assign es_to_ms_bus_valid_o = ds_to_es_bus_valid && es_to_ms_bus_valid;
|
||||
|
||||
assign es_to_ds_fwd_bus_data_o = {
|
||||
ds_to_es_bus_valid && es_op_is_load, // 38:38
|
||||
ds_to_es_bus_valid && (es_op_is_jump || es_op_is_m_ext || es_op_is_csr || (es_op_is_alu && !(es_op_is_store || es_op_is_load))), // 37:37
|
||||
es_rd, // 36:32
|
||||
es_result // 31:0
|
||||
};
|
||||
|
||||
assign a_ext_stall_o = ds_to_es_bus_valid && es_op_is_amo;
|
||||
assign csr_flush_o = ds_to_es_bus_valid && es_csr_taken;
|
||||
|
||||
endmodule
|
||||
308
rv_cpu.srcs/sources_1/new/id_stage.v
Normal file
308
rv_cpu.srcs/sources_1/new/id_stage.v
Normal file
@@ -0,0 +1,308 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 01:26:38
|
||||
// Design Name:
|
||||
// Module Name: id_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module id_stage #(
|
||||
parameter FS_TO_DS_BUS_WIDTH = 65,
|
||||
parameter DS_TO_ES_BUS_WIDTH = 315,
|
||||
parameter WS_TO_DS_BUS_WIDTH = 38,
|
||||
parameter ES_TO_DS_FWD_BUS_WIDTH = 39,
|
||||
parameter MS_TO_DS_FWD_BUS_WIDTH = 38
|
||||
)
|
||||
(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input m_ext_stall_i,
|
||||
input a_ext_stall_i,
|
||||
input csr_flush_i,
|
||||
|
||||
input [1:0] csr_mpp_i,
|
||||
|
||||
output fs_to_ds_bus_ready_o,
|
||||
input [FS_TO_DS_BUS_WIDTH-1:0] fs_to_ds_bus_data_i,
|
||||
input fs_to_ds_bus_valid_i,
|
||||
|
||||
input ds_to_es_bus_ready_i,
|
||||
output [DS_TO_ES_BUS_WIDTH-1:0] ds_to_es_bus_data_o,
|
||||
output ds_to_es_bus_valid_o,
|
||||
|
||||
input [WS_TO_DS_BUS_WIDTH-1:0] ws_to_ds_bus_data_i,
|
||||
input ws_to_ds_bus_valid_i,
|
||||
|
||||
input [ES_TO_DS_FWD_BUS_WIDTH-1:0] es_to_ds_fwd_bus_data_i,
|
||||
input [MS_TO_DS_FWD_BUS_WIDTH-1:0] ms_to_ds_fwd_bus_data_i,
|
||||
|
||||
output br_flush_o,
|
||||
output load_stall_o
|
||||
);
|
||||
|
||||
reg fs_to_ds_bus_valid;
|
||||
reg [FS_TO_DS_BUS_WIDTH-1:0] fs_to_ds_bus_data;
|
||||
|
||||
wire ds_pipeline_stall;
|
||||
wire ds_pipeline_flush;
|
||||
|
||||
wire ds_to_es_bus_valid;
|
||||
|
||||
wire [31:0] ds_inst;
|
||||
wire [31:0] ds_pc;
|
||||
|
||||
wire ds_we;
|
||||
wire [ 4:0] ds_waddr;
|
||||
wire [31:0] ds_wdata;
|
||||
|
||||
wire [ 4:0] ds_rs1;
|
||||
wire [ 4:0] ds_rs2;
|
||||
wire [ 4:0] ds_rd;
|
||||
wire [31:0] ds_imm;
|
||||
wire [ 4:0] ds_shamt;
|
||||
wire [11:0] ds_csr;
|
||||
wire [ 4:0] ds_zimm;
|
||||
|
||||
wire [10:0] ds_alu_op;
|
||||
wire [ 3:0] ds_calc_src1_sel;
|
||||
wire [ 3:0] ds_calc_src2_sel;
|
||||
wire [ 1:0] ds_jump_op;
|
||||
wire [ 5:0] ds_load_op;
|
||||
wire [ 2:0] ds_store_op;
|
||||
wire [ 5:0] ds_branch_op;
|
||||
wire [ 7:0] ds_m_ext_op;
|
||||
wire [ 2:0] ds_csr_op;
|
||||
wire [11:0] ds_amo_op;
|
||||
wire ds_excp_illegal_inst;
|
||||
wire ds_excp_breakpoint;
|
||||
wire ds_excp_env_call;
|
||||
|
||||
wire [31:0] ds_excp_vec;
|
||||
|
||||
wire ds_op_is_calc;
|
||||
wire ds_op_is_jump;
|
||||
wire ds_op_is_branch;
|
||||
wire ds_op_is_load;
|
||||
wire ds_op_is_store;
|
||||
|
||||
wire [ 4:0] ds_raddr1;
|
||||
wire [31:0] ds_rdata1;
|
||||
wire [ 4:0] ds_raddr2;
|
||||
wire [31:0] ds_rdata2;
|
||||
|
||||
wire [31:0] ds_rs1_value;
|
||||
wire [31:0] ds_rs2_value;
|
||||
|
||||
wire ds_rs1_eq_rs2;
|
||||
wire ds_rs1_lt_rs2;
|
||||
wire ds_rs1_lt_rs2u;
|
||||
|
||||
wire [31:0] ds_br_target;
|
||||
wire ds_br_taken;
|
||||
|
||||
wire es_fwd_we;
|
||||
wire [ 4:0] es_fwd_rd;
|
||||
wire [31:0] es_fwd_value;
|
||||
|
||||
wire es_load_use;
|
||||
wire ms_fwd_we;
|
||||
wire [ 4:0] ms_fwd_rd;
|
||||
wire [31:0] ms_fwd_value;
|
||||
|
||||
assign ds_pipeline_stall = load_stall_o || m_ext_stall_i || a_ext_stall_i;
|
||||
assign ds_pipeline_flush = br_flush_o || csr_flush_i;
|
||||
|
||||
assign {
|
||||
ds_excp_inst_addr_misalign, // 64:64
|
||||
ds_inst, // 63:32
|
||||
ds_pc // 31:0
|
||||
} = fs_to_ds_bus_data;
|
||||
|
||||
assign {
|
||||
ds_we, // 37:37
|
||||
ds_waddr, // 36:32
|
||||
ds_wdata // 31:0
|
||||
} = {38{ws_to_ds_bus_valid_i}} & ws_to_ds_bus_data_i;
|
||||
|
||||
assign {
|
||||
es_load_use,
|
||||
es_fwd_we,
|
||||
es_fwd_rd,
|
||||
es_fwd_value
|
||||
} = es_to_ds_fwd_bus_data_i;
|
||||
|
||||
assign {
|
||||
ms_fwd_we,
|
||||
ms_fwd_rd,
|
||||
ms_fwd_value
|
||||
} = ms_to_ds_fwd_bus_data_i;
|
||||
|
||||
assign ds_to_es_bus_valid = !ds_pipeline_stall;
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
fs_to_ds_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (ds_pipeline_flush) begin
|
||||
fs_to_ds_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (fs_to_ds_bus_ready_o) begin
|
||||
fs_to_ds_bus_valid <= fs_to_ds_bus_valid_i;
|
||||
end
|
||||
else begin
|
||||
fs_to_ds_bus_valid <= fs_to_ds_bus_valid;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
fs_to_ds_bus_data <= {FS_TO_DS_BUS_WIDTH{1'b0}};
|
||||
end
|
||||
else if (fs_to_ds_bus_valid_i && fs_to_ds_bus_ready_o) begin
|
||||
fs_to_ds_bus_data <= fs_to_ds_bus_data_i;
|
||||
end
|
||||
else begin
|
||||
fs_to_ds_bus_data <= fs_to_ds_bus_data;
|
||||
end
|
||||
end
|
||||
|
||||
inst_decoder inst_inst_decoder(
|
||||
.inst_i (ds_inst),
|
||||
.rs1_o (ds_rs1),
|
||||
.rs2_o (ds_rs2),
|
||||
.rd_o (ds_rd),
|
||||
.imm_o (ds_imm),
|
||||
.shamt_o (ds_shamt),
|
||||
.pred_o (),
|
||||
.succ_o (),
|
||||
.csr_o (ds_csr),
|
||||
.zimm_o (ds_zimm),
|
||||
.alu_op_o (ds_alu_op),
|
||||
.calc_src1_sel_o (ds_calc_src1_sel),
|
||||
.calc_src2_sel_o (ds_calc_src2_sel),
|
||||
.jump_op_o (ds_jump_op),
|
||||
.load_op_o (ds_load_op),
|
||||
.store_op_o (ds_store_op),
|
||||
.branch_op_o (ds_branch_op),
|
||||
.m_ext_op_o (ds_m_ext_op),
|
||||
.csr_op_o (ds_csr_op),
|
||||
.amo_op_o (ds_amo_op),
|
||||
.amo_aq_o (),
|
||||
.amo_rl_o (),
|
||||
.excp_illegal_inst_o (ds_excp_illegal_inst),
|
||||
.excp_breakpoint_o (ds_excp_breakpoint),
|
||||
.excp_env_call_o (ds_excp_env_call)
|
||||
);
|
||||
|
||||
reg_file inst_reg_file(
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
.raddr1_i (ds_raddr1),
|
||||
.rdata1_o (ds_rdata1),
|
||||
.raddr2_i (ds_raddr2),
|
||||
.rdata2_o (ds_rdata2),
|
||||
.we_i (ds_we),
|
||||
.waddr_i (ds_waddr),
|
||||
.wdata_i (ds_wdata)
|
||||
);
|
||||
|
||||
assign ds_excp_vec = {
|
||||
16'b0, // reserved
|
||||
1'b0, // store page fault
|
||||
1'b0, // expc code 14
|
||||
2'b0, // isnt & load page fault
|
||||
ds_excp_env_call && (csr_mpp_i == 2'b11),
|
||||
1'b0, // excp code 10
|
||||
ds_excp_env_call && (csr_mpp_i == 2'b01),
|
||||
1'b0, // env call from u mode
|
||||
4'b0, // load & store addr misalign & access fault
|
||||
ds_excp_breakpoint,
|
||||
ds_excp_illegal_inst,
|
||||
1'b0, // ds_excp_inst_access_fault
|
||||
ds_excp_inst_addr_misalign
|
||||
};
|
||||
|
||||
assign ds_op_is_calc = |ds_alu_op || |ds_m_ext_op || |ds_csr_op;
|
||||
assign ds_op_is_jump = |ds_jump_op;
|
||||
assign ds_op_is_branch = |ds_branch_op;
|
||||
assign ds_op_is_load = |ds_load_op;
|
||||
assign ds_op_is_store = |ds_store_op;
|
||||
|
||||
assign ds_raddr1 = ds_rs1;
|
||||
assign ds_raddr2 = ds_rs2;
|
||||
assign ds_rs1_value = ((es_fwd_rd != 5'b0) && es_fwd_we && (es_fwd_rd == ds_rs1)) ? es_fwd_value :
|
||||
((ms_fwd_rd != 5'b0) && ms_fwd_we && (ms_fwd_rd == ds_rs1)) ? ms_fwd_value :
|
||||
ds_rdata1;
|
||||
assign ds_rs2_value = ((es_fwd_rd != 5'b0) && es_fwd_we && (es_fwd_rd == ds_rs2)) ? es_fwd_value :
|
||||
((ms_fwd_rd != 5'b0) && ms_fwd_we && (ms_fwd_rd == ds_rs2)) ? ms_fwd_value :
|
||||
ds_rdata2;
|
||||
|
||||
assign ds_rs1_eq_rs2 = (ds_rs1_value == ds_rs2_value);
|
||||
assign ds_rs1_lt_rs2 = ($signed(ds_rs1_value) < $signed(ds_rs2_value));
|
||||
assign ds_rs1_lt_rs2u = (ds_rs1_value < ds_rs2_value);
|
||||
|
||||
assign ds_to_es_bus_data_o = { // Total 315 bits
|
||||
ds_excp_vec, // 314:283 (32 bits)
|
||||
ds_amo_op, // 282:271 (12 bits)
|
||||
ds_csr_op, // 270:268 (3 bits)
|
||||
ds_m_ext_op, // 267:260 (8 bits)
|
||||
ds_br_taken, // 259:259 (1 bit)
|
||||
ds_br_target, // 258:227 (32 bits)
|
||||
ds_store_op, // 226:224 (3 bits)
|
||||
ds_load_op, // 223:218 (6 bits)
|
||||
ds_jump_op, // 217:216 (2 bits)
|
||||
ds_alu_op, // 215:205 (11 bits)
|
||||
ds_calc_src2_sel, // 204:201 (4 bits)
|
||||
ds_calc_src1_sel, // 200:197 (4 bits)
|
||||
ds_rd, // 196:192 (5 bits)
|
||||
ds_rs2, // 191:187 (5 bits)
|
||||
ds_rs1, // 186:182 (5 bits)
|
||||
ds_zimm, // 181:177 (5 bits)
|
||||
ds_csr, // 176:165 (12 bits)
|
||||
ds_shamt, // 164:160 (5 bits)
|
||||
ds_imm, // 159:128 (32 bits)
|
||||
ds_rs2_value, // 127:96 (32 bits)
|
||||
ds_rs1_value, // 95:64 (32 bits)
|
||||
ds_pc, // 63:32 (32 bits)
|
||||
ds_inst // 31:0 (32 bits)
|
||||
};
|
||||
|
||||
|
||||
assign ds_br_target = ({32{ ds_jump_op[0] }} & (ds_pc + ds_imm) )
|
||||
| ({32{ ds_jump_op[1] }} & (ds_rs1_value + ds_imm) & ~32'b1)
|
||||
| ({32{ds_branch_op[0] & ds_rs1_eq_rs2 }} & (ds_pc + ds_imm) )
|
||||
| ({32{ds_branch_op[1] & !ds_rs1_eq_rs2 }} & (ds_pc + ds_imm) )
|
||||
| ({32{ds_branch_op[2] & ds_rs1_lt_rs2 }} & (ds_pc + ds_imm) )
|
||||
| ({32{ds_branch_op[3] & !ds_rs1_lt_rs2 }} & (ds_pc + ds_imm) )
|
||||
| ({32{ds_branch_op[4] & ds_rs1_lt_rs2u}} & (ds_pc + ds_imm) )
|
||||
| ({32{ds_branch_op[5] & !ds_rs1_lt_rs2u}} & (ds_pc + ds_imm) );
|
||||
assign ds_br_taken = ds_jump_op[0]
|
||||
| ds_jump_op[1]
|
||||
| (ds_branch_op[0] & ds_rs1_eq_rs2 )
|
||||
| (ds_branch_op[1] & !ds_rs1_eq_rs2 )
|
||||
| (ds_branch_op[2] & ds_rs1_lt_rs2 )
|
||||
| (ds_branch_op[3] & !ds_rs1_lt_rs2 )
|
||||
| (ds_branch_op[4] & ds_rs1_lt_rs2u)
|
||||
| (ds_branch_op[5] & !ds_rs1_lt_rs2u);
|
||||
|
||||
assign fs_to_ds_bus_ready_o = !fs_to_ds_bus_valid || (ds_to_es_bus_valid && ds_to_es_bus_ready_i);
|
||||
assign ds_to_es_bus_valid_o = fs_to_ds_bus_valid && ds_to_es_bus_valid;
|
||||
|
||||
assign br_flush_o = fs_to_ds_bus_valid && ds_br_taken && !ds_pipeline_stall;
|
||||
assign load_stall_o = fs_to_ds_bus_valid && es_load_use && (ds_op_is_branch || ds_op_is_jump || (ds_op_is_calc && !(ds_op_is_store || ds_op_is_load))) && ((es_fwd_rd != 5'b0) && (es_fwd_rd == ds_rs1 || (es_fwd_rd == ds_rs2)));
|
||||
endmodule
|
||||
146
rv_cpu.srcs/sources_1/new/if_stage.v
Normal file
146
rv_cpu.srcs/sources_1/new/if_stage.v
Normal file
@@ -0,0 +1,146 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/16 19:31:31
|
||||
// Design Name:
|
||||
// Module Name: if_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module if_stage #(
|
||||
parameter FS_TO_DS_BUS_WIDTH = 65
|
||||
)
|
||||
(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input br_flush_i,
|
||||
input csr_flush_i,
|
||||
input load_stall_i,
|
||||
input m_ext_stall_i,
|
||||
input a_ext_stall_i,
|
||||
|
||||
input [31:0] br_target_i,
|
||||
input br_taken_i,
|
||||
|
||||
input fs_to_ds_bus_ready_i,
|
||||
output [FS_TO_DS_BUS_WIDTH-1:0] fs_to_ds_bus_data_o,
|
||||
output fs_to_ds_bus_valid_o,
|
||||
|
||||
output inst_sram_en_o,
|
||||
output [ 3:0] inst_sram_wen_o,
|
||||
output [31:0] inst_sram_addr_o,
|
||||
output [31:0] inst_sram_wdata_o,
|
||||
input [31:0] inst_sram_rdata_i
|
||||
);
|
||||
|
||||
reg pre_fs_to_fs_valid;
|
||||
reg [31:0] fs_pc;
|
||||
reg fs_excp_inst_addr_misalign;
|
||||
|
||||
wire fs_pipeline_stall;
|
||||
wire fs_pipeline_flush;
|
||||
|
||||
wire pre_fs_to_fs_ready;
|
||||
wire fs_to_ds_bus_valid;
|
||||
|
||||
wire pre_fs_to_fs_valid_internal;
|
||||
|
||||
wire [31:0] fs_next_pc;
|
||||
|
||||
wire [31:0] fs_inst;
|
||||
|
||||
assign fs_pipeline_stall = load_stall_i || m_ext_stall_i || a_ext_stall_i;
|
||||
assign fs_pipeline_flush = br_flush_i;
|
||||
|
||||
assign fs_inst = inst_sram_rdata_i;
|
||||
|
||||
pre_if_stage inst_pre_if_stage(
|
||||
.rstn_i (rstn_i),
|
||||
.pre_fs_to_fs_ready_i (pre_fs_to_fs_ready),
|
||||
.pre_fs_to_fs_pc_o (fs_next_pc),
|
||||
.pre_fs_to_fs_valid_o (pre_fs_to_fs_valid_internal),
|
||||
|
||||
.load_stall_i (load_stall_i),
|
||||
.m_ext_stall_i (m_ext_stall_i),
|
||||
.a_ext_stall_i (a_ext_stall_i),
|
||||
|
||||
.br_target_i (br_target_i),
|
||||
.br_taken_i (br_taken_i),
|
||||
|
||||
.fs_pc_i (fs_pc),
|
||||
|
||||
.inst_sram_en_o (inst_sram_en_o),
|
||||
.inst_sram_wen_o (inst_sram_wen_o),
|
||||
.inst_sram_addr_o (inst_sram_addr_o),
|
||||
.inst_sram_data_o (inst_sram_wdata_o)
|
||||
);
|
||||
|
||||
assign fs_to_ds_bus_valid = !fs_pipeline_stall;
|
||||
assign pre_fs_to_fs_ready = !pre_fs_to_fs_valid || (fs_to_ds_bus_valid && fs_to_ds_bus_ready_i);
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
pre_fs_to_fs_valid <= 1'b0;
|
||||
end
|
||||
else if (fs_pipeline_flush) begin
|
||||
pre_fs_to_fs_valid <= 1'b0;
|
||||
end
|
||||
else if (pre_fs_to_fs_ready) begin
|
||||
pre_fs_to_fs_valid <= pre_fs_to_fs_valid_internal;
|
||||
end
|
||||
else begin
|
||||
pre_fs_to_fs_valid <= pre_fs_to_fs_valid;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
fs_pc <= 32'h7fff_fffc;
|
||||
end
|
||||
else if (pre_fs_to_fs_valid_internal && pre_fs_to_fs_ready) begin
|
||||
fs_pc <= fs_next_pc;
|
||||
end
|
||||
else begin
|
||||
fs_pc <= fs_pc;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
fs_excp_inst_addr_misalign <= 1'b0;
|
||||
end
|
||||
else if(pre_fs_to_fs_valid_internal && pre_fs_to_fs_ready) begin
|
||||
if (fs_next_pc[1:0] != 2'b00) begin
|
||||
fs_excp_inst_addr_misalign <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fs_excp_inst_addr_misalign <= 1'b0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
fs_excp_inst_addr_misalign <= fs_excp_inst_addr_misalign;
|
||||
end
|
||||
end
|
||||
|
||||
assign fs_to_ds_bus_data_o = {
|
||||
fs_excp_inst_addr_misalign, // 64:64
|
||||
fs_inst, // 63:32
|
||||
fs_pc // 31:0
|
||||
};
|
||||
assign fs_to_ds_bus_valid_o = pre_fs_to_fs_valid && fs_to_ds_bus_valid;
|
||||
|
||||
endmodule
|
||||
180
rv_cpu.srcs/sources_1/new/mem_stage.v
Normal file
180
rv_cpu.srcs/sources_1/new/mem_stage.v
Normal file
@@ -0,0 +1,180 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 10:24:07
|
||||
// Design Name:
|
||||
// Module Name: mem_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module mem_stage #(
|
||||
parameter ES_TO_MS_BUS_WIDTH = 164,
|
||||
parameter MS_TO_WS_BUS_WIDTH = 70,
|
||||
parameter MS_TO_DS_FWD_BUS_WIDTH = 38
|
||||
)(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input csr_flush_i,
|
||||
|
||||
output es_to_ms_bus_ready_o,
|
||||
input [ES_TO_MS_BUS_WIDTH-1:0] es_to_ms_bus_data_i,
|
||||
input es_to_ms_bus_valid_i,
|
||||
|
||||
input ms_to_ws_bus_ready_i,
|
||||
output [MS_TO_WS_BUS_WIDTH-1:0] ms_to_ws_bus_data_o,
|
||||
output ms_to_ws_bus_valid_o,
|
||||
|
||||
input [ 31:0] data_sram_rdata_i,
|
||||
output data_sram_en_o,
|
||||
output [ 3:0] data_sram_wen_o,
|
||||
output [31:0] data_sram_addr_o,
|
||||
output [31:0] data_sram_wdata_o,
|
||||
|
||||
output a_ext_stall_o,
|
||||
// fowarding bus to ID stage
|
||||
output [MS_TO_DS_FWD_BUS_WIDTH-1:0] ms_to_ds_fwd_bus_data_o
|
||||
);
|
||||
|
||||
reg es_to_ms_bus_valid;
|
||||
reg [ES_TO_MS_BUS_WIDTH-1:0] es_to_ms_bus_data;
|
||||
|
||||
wire ms_to_ws_bus_valid;
|
||||
|
||||
wire [ 2:0] ms_result_sel;
|
||||
wire [ 31:0] ms_es_result;
|
||||
wire [ 31:0] ms_calc_src2;
|
||||
wire [ 31:0] ms_calc_src1;
|
||||
wire [ 11:0] ms_amo_op;
|
||||
wire [ 5:0] ms_load_op;
|
||||
wire [ 4:0] ms_rd;
|
||||
wire [ 4:0] ms_rs2;
|
||||
wire [ 4:0] ms_rs1;
|
||||
wire [ 31:0] ms_pc;
|
||||
|
||||
wire [ 31:0] ms_lb_result;
|
||||
wire [ 31:0] ms_lh_result;
|
||||
wire [ 31:0] ms_lw_result;
|
||||
|
||||
wire [ 31:0] ms_load_result;
|
||||
wire [ 31:0] ms_amo_result;
|
||||
wire [ 31:0] ms_result;
|
||||
|
||||
wire [ 31:0] ms_rf_wdata;
|
||||
wire [ 4:0] ms_rf_waddr;
|
||||
wire ms_rf_we;
|
||||
|
||||
assign {
|
||||
ms_result_sel, // 163:161 (3 bits)
|
||||
ms_es_result, // 160:129 (32 bits)
|
||||
ms_calc_src2, // 128:97 (32 bits)
|
||||
ms_calc_src1, // 96:65 (32 bits)
|
||||
ms_amo_op, // 64:53 (12 bits)
|
||||
ms_load_op, // 52:47 (6 bits)
|
||||
ms_rd, // 46:42 (5 bits)
|
||||
ms_rs2, // 41:37 (5 bits)
|
||||
ms_rs1, // 36:32 (5 bits)
|
||||
ms_pc // 31:0 (32 bits)
|
||||
} = es_to_ms_bus_data;
|
||||
|
||||
assign ms_to_ws_bus_valid = 1'b1;
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
es_to_ms_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (csr_flush_i) begin
|
||||
es_to_ms_bus_valid <= 1'b0;
|
||||
end
|
||||
else if (es_to_ms_bus_ready_o) begin
|
||||
es_to_ms_bus_valid <= es_to_ms_bus_valid_i;
|
||||
end
|
||||
else begin
|
||||
es_to_ms_bus_valid <= es_to_ms_bus_valid;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
es_to_ms_bus_data <= {ES_TO_MS_BUS_WIDTH{1'b0}};
|
||||
end
|
||||
else if (es_to_ms_bus_valid_i && es_to_ms_bus_ready_o) begin
|
||||
es_to_ms_bus_data <= es_to_ms_bus_data_i;
|
||||
end
|
||||
else begin
|
||||
es_to_ms_bus_data <= es_to_ms_bus_data;
|
||||
end
|
||||
end
|
||||
|
||||
assign ms_lb_result = ({32{(ms_es_result[1:0] == 2'b00)}} & {{24{ms_load_op[0] ? data_sram_rdata_i[ 7] : 1'b0 }}, data_sram_rdata_i[ 7:0 ]})
|
||||
| ({32{(ms_es_result[1:0] == 2'b01)}} & {{24{ms_load_op[0] ? data_sram_rdata_i[15] : 1'b0 }}, data_sram_rdata_i[15:8 ]})
|
||||
| ({32{(ms_es_result[1:0] == 2'b10)}} & {{24{ms_load_op[0] ? data_sram_rdata_i[23] : 1'b0 }}, data_sram_rdata_i[23:16]})
|
||||
| ({32{(ms_es_result[1:0] == 2'b11)}} & {{24{ms_load_op[0] ? data_sram_rdata_i[31] : 1'b0 }}, data_sram_rdata_i[31:24]});
|
||||
assign ms_lh_result = ({32{(ms_es_result[1:0] == 2'b00)}} & {{16{ms_load_op[1] ? data_sram_rdata_i[15] : 1'b0 }}, data_sram_rdata_i[15:0 ]})
|
||||
| ({32{(ms_es_result[1:0] == 2'b10)}} & {{16{ms_load_op[1] ? data_sram_rdata_i[31] : 1'b0 }}, data_sram_rdata_i[31:16]});
|
||||
assign ms_lw_result = data_sram_rdata_i;
|
||||
|
||||
assign ms_load_result = ({32{ms_load_op[0] || ms_load_op[3]}} & ms_lb_result)
|
||||
| ({32{ms_load_op[1] || ms_load_op[4]}} & ms_lh_result)
|
||||
| ({32{ms_load_op[2] }} & ms_lw_result);
|
||||
assign ms_amo_result = data_sram_rdata_i;
|
||||
|
||||
assign ms_result = {32{ms_result_sel[0]}} & ms_es_result
|
||||
| {32{ms_result_sel[1]}} & ms_load_result
|
||||
| {32{ms_result_sel[2]}} & ms_amo_result;
|
||||
|
||||
assign ms_rf_wdata = ms_result;
|
||||
assign ms_rf_waddr = ms_rd;
|
||||
assign ms_rf_we = es_to_ms_bus_valid && |ms_result_sel;
|
||||
|
||||
assign ms_to_ws_bus_data_o = {
|
||||
ms_rf_we, // 69:69
|
||||
ms_rf_waddr, // 68:64
|
||||
ms_rf_wdata, // 63:32
|
||||
ms_pc // 31:0
|
||||
};
|
||||
|
||||
assign es_to_ms_bus_ready_o = !es_to_ms_bus_valid || (ms_to_ws_bus_valid && ms_to_ws_bus_ready_i);
|
||||
assign ms_to_ws_bus_valid_o = es_to_ms_bus_valid && ms_to_ws_bus_valid;
|
||||
|
||||
assign ms_to_ds_fwd_bus_data_o = {
|
||||
ms_rf_we, // 37:37
|
||||
ms_rf_waddr, // 36:32
|
||||
ms_rf_wdata // 31:0
|
||||
};
|
||||
|
||||
wire ms_mem_lt_rs2;
|
||||
wire ms_mem_lt_rs2u;
|
||||
|
||||
assign ms_mem_lt_rs2 = ($signed(data_sram_rdata_i) < $signed(ms_calc_src2));
|
||||
assign ms_mem_lt_rs2u = (data_sram_rdata_i < ms_calc_src2);
|
||||
|
||||
assign data_sram_en_o = es_to_ms_bus_valid && (|ms_result_sel || |ms_amo_op[9:0]);
|
||||
assign data_sram_wen_o = {4{es_to_ms_bus_valid && |ms_amo_op[9:0]}};
|
||||
assign data_sram_addr_o = ms_calc_src1;
|
||||
assign data_sram_wdata_o = {32{ms_amo_op[0]}} & (({32{ ms_mem_lt_rs2u}} & ms_calc_src2) | ({32{!ms_mem_lt_rs2u}} & data_sram_rdata_i)) // inst_amomaxu_w
|
||||
| {32{ms_amo_op[1]}} & (({32{!ms_mem_lt_rs2u}} & ms_calc_src2) | ({32{ ms_mem_lt_rs2u}} & data_sram_rdata_i)) // inst_amominu_w
|
||||
| {32{ms_amo_op[2]}} & (({32{ ms_mem_lt_rs2 }} & ms_calc_src2) | ({32{!ms_mem_lt_rs2 }} & data_sram_rdata_i)) // inst_amomax_w
|
||||
| {32{ms_amo_op[3]}} & (({32{!ms_mem_lt_rs2 }} & ms_calc_src2) | ({32{ ms_mem_lt_rs2 }} & data_sram_rdata_i)) // inst_amomin_w
|
||||
| {32{ms_amo_op[4]}} & (data_sram_rdata_i | ms_calc_src2) // inst_amoor_w
|
||||
| {32{ms_amo_op[5]}} & (data_sram_rdata_i & ms_calc_src2) // inst_amoand_w
|
||||
| {32{ms_amo_op[6]}} & (data_sram_rdata_i ^ ms_calc_src2) // inst_amoxor_w
|
||||
| {32{ms_amo_op[7]}} & (data_sram_rdata_i + ms_calc_src2) // inst_amoadd_w
|
||||
| {32{ms_amo_op[8]}} & (ms_calc_src2) // inst_amoswap_w
|
||||
| {32{ms_amo_op[9]}} & (ms_calc_src2); // inst_sc_w
|
||||
|
||||
assign a_ext_stall_o = ms_to_ws_bus_valid && |ms_amo_op;
|
||||
endmodule
|
||||
116
rv_cpu.srcs/sources_1/new/sub_unit/alu.v
Normal file
116
rv_cpu.srcs/sources_1/new/sub_unit/alu.v
Normal file
@@ -0,0 +1,116 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 00:11:46
|
||||
// Design Name:
|
||||
// Module Name: alu
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module alu(
|
||||
input [10:0] alu_op_i ,
|
||||
input [31:0] alu_src1_i ,
|
||||
input [31:0] alu_src2_i ,
|
||||
|
||||
output [31:0] alu_result_o
|
||||
);
|
||||
wire op_lui;
|
||||
wire op_add;
|
||||
wire op_sub;
|
||||
wire op_or;
|
||||
wire op_slt;
|
||||
wire op_sltu;
|
||||
wire op_xor;
|
||||
wire op_and;
|
||||
wire op_sll;
|
||||
wire op_srl;
|
||||
wire op_sra;
|
||||
|
||||
assign {
|
||||
op_lui,
|
||||
op_add,
|
||||
op_sub,
|
||||
op_slt,
|
||||
op_sltu,
|
||||
op_xor,
|
||||
op_or,
|
||||
op_and,
|
||||
op_sll,
|
||||
op_srl,
|
||||
op_sra
|
||||
} = alu_op_i;
|
||||
|
||||
|
||||
wire [31:0] lui_result;
|
||||
wire [31:0] add_sub_result;
|
||||
wire [31:0] slt_result;
|
||||
wire [31:0] sltu_result;
|
||||
wire [31:0] xor_result;
|
||||
wire [31:0] or_result;
|
||||
wire [31:0] and_result;
|
||||
wire [31:0] sll_result;
|
||||
wire [31:0] sr64_result;
|
||||
wire [31:0] sr_result;
|
||||
|
||||
// 32-bit adder
|
||||
wire [31:0] adder_a;
|
||||
wire [31:0] adder_b;
|
||||
wire adder_cin;
|
||||
wire [31:0] adder_result;
|
||||
wire adder_cout;
|
||||
|
||||
assign adder_a = alu_src1_i;
|
||||
assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2_i : alu_src2_i;
|
||||
assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
|
||||
assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin;
|
||||
|
||||
// ADD, SUB result
|
||||
assign add_sub_result = adder_result;
|
||||
|
||||
// SLT result
|
||||
assign slt_result[31:1] = 31'b0;
|
||||
assign slt_result[0] = (alu_src1_i[31] & ~alu_src2_i[31])
|
||||
| ((alu_src1_i[31] ~^ alu_src2_i[31]) & adder_result[31]);
|
||||
|
||||
// SLTU result
|
||||
assign sltu_result[31:1] = 31'b0;
|
||||
assign sltu_result[0] = ~adder_cout;
|
||||
|
||||
// bitwise operation
|
||||
assign or_result = alu_src1_i | alu_src2_i;
|
||||
assign and_result = alu_src1_i & alu_src2_i;
|
||||
assign xor_result = alu_src1_i ^ alu_src2_i;
|
||||
assign lui_result = alu_src2_i;
|
||||
|
||||
// SLL result
|
||||
assign sll_result = alu_src1_i << alu_src2_i[4:0];
|
||||
|
||||
// SRL, SRA result
|
||||
assign sr64_result = {{32{op_sra & alu_src1_i[31]}}, alu_src1_i[31:0]} >> alu_src2_i[4:0];
|
||||
|
||||
assign sr_result = sr64_result[31:0];
|
||||
|
||||
// final result mux
|
||||
assign alu_result_o = ({32{op_add|op_sub}} & add_sub_result)
|
||||
| ({32{op_slt }} & slt_result)
|
||||
| ({32{op_sltu }} & sltu_result)
|
||||
| ({32{op_or }} & or_result)
|
||||
| ({32{op_xor }} & xor_result)
|
||||
| ({32{op_and }} & and_result)
|
||||
| ({32{op_lui }} & lui_result)
|
||||
| ({32{op_sll }} & sll_result)
|
||||
| ({32{op_srl|op_sra}} & sr_result);
|
||||
endmodule
|
||||
387
rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v
Normal file
387
rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v
Normal file
@@ -0,0 +1,387 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/19 09:13:42
|
||||
// Design Name:
|
||||
// Module Name: csr_csr_reg_file
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module csr_reg_file(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input csr_pc_i,
|
||||
input csr_inst_i,
|
||||
|
||||
input [ 2:0] csr_op_i,
|
||||
input [11:0] csr_addr_i,
|
||||
input [31:0] csr_wdata_i,
|
||||
output [31:0] csr_rdata_o,
|
||||
input [ 4:0] csr_intr_vec_i,
|
||||
input [31:0] csr_excp_vec_i,
|
||||
|
||||
output [ 1:0] csr_mpp_o,
|
||||
|
||||
output csr_taken_o,
|
||||
output [31:0] csr_target_o
|
||||
);
|
||||
|
||||
reg [31:0] csr_mstatus_reg; // 0x300
|
||||
reg [31:0] csr_misa_reg; // 0x301
|
||||
reg [31:0] csr_medeleg_reg; // 0x302 not used
|
||||
reg [31:0] csr_mideleg_reg; // 0x303 not used
|
||||
reg [31:0] csr_mie_reg; // 0x304
|
||||
reg [31:0] csr_mtvec_reg; // 0x305
|
||||
reg [31:0] csr_mcounteren_reg; // 0x306 not used
|
||||
reg [31:0] csr_medelegh_reg; // 0x312 not used
|
||||
reg [31:0] csr_mepc_reg; // 0x341
|
||||
reg [31:0] csr_mcause_reg; // 0x342
|
||||
reg [31:0] csr_mtval_reg; // 0x343
|
||||
reg [31:0] csr_mip_reg; // 0x344
|
||||
reg [31:0] csr_mscratch_reg; // 0x340
|
||||
|
||||
reg [31:0] csr_pmpcfg0_reg; // 0x3A0 not used
|
||||
reg [31:0] csr_pmpcfg1_reg; // 0x3A1 not used
|
||||
reg [31:0] csr_pmpcfg2_reg; // 0x3A2 not used
|
||||
reg [31:0] csr_pmpcfg3_reg; // 0x3A3 not used
|
||||
reg [31:0] csr_pmpcfg4_reg; // 0x3A4 not used
|
||||
reg [31:0] csr_pmpcfg5_reg; // 0x3A5 not used
|
||||
reg [31:0] csr_pmpcfg6_reg; // 0x3A6 not used
|
||||
reg [31:0] csr_pmpcfg7_reg; // 0x3A7 not used
|
||||
reg [31:0] csr_pmpcfg8_reg; // 0x3A8 not used
|
||||
reg [31:0] csr_pmpcfg9_reg; // 0x3A9 not used
|
||||
reg [31:0] csr_pmpcfg10_reg; // 0x3AA not used
|
||||
reg [31:0] csr_pmpcfg11_reg; // 0x3AB not used
|
||||
reg [31:0] csr_pmpcfg12_reg; // 0x3AC not used
|
||||
reg [31:0] csr_pmpcfg13_reg; // 0x3AD not used
|
||||
reg [31:0] csr_pmpcfg14_reg; // 0x3AE not used
|
||||
reg [31:0] csr_pmpcfg15_reg; // 0x3AF not used
|
||||
reg [31:0] csr_pmpaddr0_reg; // 0x3B0 not used
|
||||
reg [31:0] csr_pmpaddr1_reg; // 0x3B1 not used
|
||||
reg [31:0] csr_pmpaddr2_reg; // 0x3B2 not used
|
||||
reg [31:0] csr_pmpaddr3_reg; // 0x3B3 not used
|
||||
reg [31:0] csr_pmpaddr4_reg; // 0x3B4 not used
|
||||
reg [31:0] csr_pmpaddr5_reg; // 0x3B5 not used
|
||||
reg [31:0] csr_pmpaddr6_reg; // 0x3B6 not used
|
||||
reg [31:0] csr_pmpaddr7_reg; // 0x3B7 not used
|
||||
reg [31:0] csr_pmpaddr8_reg; // 0x3B8 not used
|
||||
reg [31:0] csr_pmpaddr9_reg; // 0x3B9 not used
|
||||
reg [31:0] csr_pmpaddr10_reg; // 0x3BA not used
|
||||
reg [31:0] csr_pmpaddr11_reg; // 0x3BB not used
|
||||
reg [31:0] csr_pmpaddr12_reg; // 0x3BC not used
|
||||
reg [31:0] csr_pmpaddr13_reg; // 0x3BD not used
|
||||
reg [31:0] csr_pmpaddr14_reg; // 0x3BE not used
|
||||
reg [31:0] csr_pmpaddr15_reg; // 0x3BF not used
|
||||
reg [31:0] csr_pmpaddr16_reg; // 0x3C0 not used
|
||||
reg [31:0] csr_pmpaddr17_reg; // 0x3C1 not used
|
||||
reg [31:0] csr_pmpaddr18_reg; // 0x3C2 not used
|
||||
reg [31:0] csr_pmpaddr19_reg; // 0x3C3 not used
|
||||
reg [31:0] csr_pmpaddr20_reg; // 0x3C4 not used
|
||||
reg [31:0] csr_pmpaddr21_reg; // 0x3C5 not used
|
||||
reg [31:0] csr_pmpaddr22_reg; // 0x3C6 not used
|
||||
reg [31:0] csr_pmpaddr23_reg; // 0x3C7 not used
|
||||
reg [31:0] csr_pmpaddr24_reg; // 0x3C8 not used
|
||||
reg [31:0] csr_pmpaddr25_reg; // 0x3C9 not used
|
||||
reg [31:0] csr_pmpaddr26_reg; // 0x3CA not used
|
||||
reg [31:0] csr_pmpaddr27_reg; // 0x3CB not used
|
||||
reg [31:0] csr_pmpaddr28_reg; // 0x3CC not used
|
||||
reg [31:0] csr_pmpaddr29_reg; // 0x3CD not used
|
||||
reg [31:0] csr_pmpaddr30_reg; // 0x3CE not used
|
||||
reg [31:0] csr_pmpaddr31_reg; // 0x3CF not used
|
||||
reg [31:0] csr_pmpaddr32_reg; // 0x3D0 not used
|
||||
reg [31:0] csr_pmpaddr33_reg; // 0x3D1 not used
|
||||
reg [31:0] csr_pmpaddr34_reg; // 0x3D2 not used
|
||||
reg [31:0] csr_pmpaddr35_reg; // 0x3D3 not used
|
||||
reg [31:0] csr_pmpaddr36_reg; // 0x3D4 not used
|
||||
reg [31:0] csr_pmpaddr37_reg; // 0x3D5 not used
|
||||
reg [31:0] csr_pmpaddr38_reg; // 0x3D6 not used
|
||||
reg [31:0] csr_pmpaddr39_reg; // 0x3D7 not used
|
||||
reg [31:0] csr_pmpaddr40_reg; // 0x3D8 not used
|
||||
reg [31:0] csr_pmpaddr41_reg; // 0x3D9 not used
|
||||
reg [31:0] csr_pmpaddr42_reg; // 0x3DA not used
|
||||
reg [31:0] csr_pmpaddr43_reg; // 0x3DB not used
|
||||
reg [31:0] csr_pmpaddr44_reg; // 0x3DC not used
|
||||
reg [31:0] csr_pmpaddr45_reg; // 0x3DD not used
|
||||
reg [31:0] csr_pmpaddr46_reg; // 0x3DE not used
|
||||
reg [31:0] csr_pmpaddr47_reg; // 0x3DF not used
|
||||
reg [31:0] csr_pmpaddr48_reg; // 0x3E0 not used
|
||||
reg [31:0] csr_pmpaddr49_reg; // 0x3E1 not used
|
||||
reg [31:0] csr_pmpaddr50_reg; // 0x3E2 not used
|
||||
reg [31:0] csr_pmpaddr51_reg; // 0x3E3 not used
|
||||
reg [31:0] csr_pmpaddr52_reg; // 0x3E4 not used
|
||||
reg [31:0] csr_pmpaddr53_reg; // 0x3E5 not used
|
||||
reg [31:0] csr_pmpaddr54_reg; // 0x3E6 not used
|
||||
reg [31:0] csr_pmpaddr55_reg; // 0x3E7 not used
|
||||
reg [31:0] csr_pmpaddr56_reg; // 0x3E8 not used
|
||||
reg [31:0] csr_pmpaddr57_reg; // 0x3E9 not used
|
||||
reg [31:0] csr_pmpaddr58_reg; // 0x3EA not used
|
||||
reg [31:0] csr_pmpaddr59_reg; // 0x3EB not used
|
||||
reg [31:0] csr_pmpaddr60_reg; // 0x3EC not used
|
||||
reg [31:0] csr_pmpaddr61_reg; // 0x3ED not used
|
||||
reg [31:0] csr_pmpaddr62_reg; // 0x3EE not used
|
||||
reg [31:0] csr_pmpaddr63_reg; // 0x3EF not used
|
||||
|
||||
reg [31:0] csr_rdata_internal;
|
||||
|
||||
wire csr_we;
|
||||
|
||||
wire excp_inst_addr_misalign;
|
||||
wire excp_inst_access_fault; // not used
|
||||
wire excp_illegal_inst;
|
||||
wire excp_breakpoint;
|
||||
wire excp_load_addr_misalign; // hardware solved
|
||||
wire excp_load_access_fault; // not used
|
||||
wire excp_store_addr_misalign; // hardware solved
|
||||
wire excp_store_access_fault; // not used
|
||||
wire excp_env_call_from_u; // not used
|
||||
wire excp_env_call_from_s;
|
||||
wire excp_reserved_code_10; // reserved
|
||||
wire excp_env_call_from_m;
|
||||
wire excp_inst_page_fault; // not used
|
||||
wire excp_load_page_fault; // not used
|
||||
wire excp_reserved_code_14; // reserved
|
||||
wire excp_store_page_fault; // not used
|
||||
wire [15:0] excp_reserved; // reserved
|
||||
|
||||
wire [31:0] csr_wdata_internal;
|
||||
wire csr_excp;
|
||||
wire [ 4:0] csr_excp_code;
|
||||
|
||||
wire csr_mstatus_uie;
|
||||
wire csr_mstatus_sie;
|
||||
wire csr_mstatus_mie;
|
||||
wire csr_mstatus_upie;
|
||||
wire csr_mstatus_spie;
|
||||
wire csr_mstatus_mpie;
|
||||
wire csr_mstatus_spp;
|
||||
wire [1:0] csr_mstatus_mpp;
|
||||
wire [1:0] csr_mstatus_fs;
|
||||
wire [1:0] csr_mstatus_xs;
|
||||
wire csr_mstatus_mprv;
|
||||
wire csr_mstatus_sum;
|
||||
wire csr_mstatus_mxr;
|
||||
wire csr_mstatus_tvm;
|
||||
wire csr_mstatus_tw;
|
||||
wire csr_mstatus_tsr;
|
||||
wire csr_mstatus_sd;
|
||||
|
||||
assign csr_we = (csr_op_i[0] ) // read & write
|
||||
|| (csr_op_i[1] && (|csr_wdata_i)) // if wdata == 0, only read
|
||||
|| (csr_op_i[2] && (|csr_wdata_i)); // if wdata == 0, only read
|
||||
|
||||
assign {
|
||||
excp_reserved,
|
||||
excp_store_page_fault,
|
||||
excp_reserved_code_14,
|
||||
excp_load_page_fault,
|
||||
excp_inst_page_fault,
|
||||
excp_reserved_code_10,
|
||||
excp_env_call_from_m,
|
||||
excp_env_call_from_s,
|
||||
excp_env_call_from_u,
|
||||
excp_store_access_fault,
|
||||
excp_store_addr_misalign,
|
||||
excp_load_access_fault,
|
||||
excp_load_addr_misalign,
|
||||
excp_breakpoint,
|
||||
excp_illegal_inst,
|
||||
excp_inst_access_fault,
|
||||
excp_inst_addr_misalign
|
||||
} = csr_excp_vec_i;
|
||||
|
||||
assign csr_mstatus_uie = csr_mstatus_reg[ 0]; // not used in current design
|
||||
assign csr_mstatus_sie = csr_mstatus_reg[ 1];
|
||||
assign csr_mstatus_mie = csr_mstatus_reg[ 3];
|
||||
assign csr_mstatus_upie = csr_mstatus_reg[ 4]; // not used in current design
|
||||
assign csr_mstatus_spie = csr_mstatus_reg[ 5];
|
||||
assign csr_mstatus_mpie = csr_mstatus_reg[ 7];
|
||||
assign csr_mstatus_spp = csr_mstatus_reg[ 8];
|
||||
assign csr_mstatus_mpp = csr_mstatus_reg[12:11];
|
||||
assign csr_mstatus_fs = csr_mstatus_reg[14:13]; // not used in current design
|
||||
assign csr_mstatus_xs = csr_mstatus_reg[16:15]; // not used in current design
|
||||
assign csr_mstatus_mprv = csr_mstatus_reg[17]; // not used in current design
|
||||
assign csr_mstatus_sum = csr_mstatus_reg[18];
|
||||
assign csr_mstatus_mxr = csr_mstatus_reg[19];
|
||||
assign csr_mstatus_tvm = csr_mstatus_reg[20];
|
||||
assign csr_mstatus_tw = csr_mstatus_reg[21]; // not used in current design
|
||||
assign csr_mstatus_tsr = csr_mstatus_reg[22];
|
||||
assign csr_mstatus_sd = csr_mstatus_reg[31]; // not used in current design
|
||||
|
||||
assign csr_wdata_internal = {32{csr_op_i[0]}} & csr_wdata_i
|
||||
| {32{csr_op_i[1]}} & (csr_rdata_internal | csr_wdata_i)
|
||||
| {32{csr_op_i[2]}} & (csr_rdata_internal & ~csr_wdata_i);
|
||||
|
||||
assign csr_excp = |csr_excp_vec_i;
|
||||
|
||||
// csr read logic
|
||||
always @(*) begin
|
||||
case (csr_addr_i)
|
||||
// 0x300-0x3FF Standard read/write
|
||||
12'h300: begin // mstatus
|
||||
csr_rdata_internal = csr_mstatus_reg;
|
||||
end
|
||||
12'h301: begin // misa
|
||||
csr_rdata_internal = csr_misa_reg;
|
||||
end
|
||||
12'h304: begin // mie
|
||||
csr_rdata_internal = csr_mie_reg;
|
||||
end
|
||||
12'h305: begin // mtvec
|
||||
csr_rdata_internal = csr_mtvec_reg;
|
||||
end
|
||||
12'h340: begin // mscratch
|
||||
csr_rdata_internal = csr_mscratch_reg;
|
||||
end
|
||||
12'h341: begin // mepc
|
||||
csr_rdata_internal = csr_mepc_reg;
|
||||
end
|
||||
12'h342: begin // mcause
|
||||
csr_rdata_internal = csr_mcause_reg;
|
||||
end
|
||||
12'h343: begin // mtval
|
||||
csr_rdata_internal = csr_mtval_reg;
|
||||
end
|
||||
12'h344: begin // mip
|
||||
csr_rdata_internal = csr_mip_reg;
|
||||
end
|
||||
default: begin
|
||||
csr_rdata_internal = 32'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
onehot32_to_hex5_decoder inst_onehot32_to_hex5_decoder(
|
||||
.onehot_i (csr_excp_vec_i),
|
||||
.hex_o (csr_excp_code)
|
||||
);
|
||||
|
||||
// csr write logic
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
// Reset mstatus: MPP is set to M-mode (2'b11 at bits 12:11), other fields are typically 0.
|
||||
// 32'h00001800 corresponds to:
|
||||
// MPP (bits 12:11) = 2'b11 (Machine mode)
|
||||
// All other implemented bits are 0.
|
||||
// For RV32, SD bit (bit 31) is 0. FS and XS fields (bits 14:13, 16:15) are 0 (initial/dirty).
|
||||
csr_mstatus_reg <= 32'h0000_1800;
|
||||
//csr_misa_reg <= 32'h4000_1101; // RV32IMA
|
||||
csr_misa_reg <= 32'h4040_1101; // test only
|
||||
csr_mie_reg <= 32'b0;
|
||||
csr_mtvec_reg <= 32'b0;
|
||||
csr_mscratch_reg <= 32'b0;
|
||||
csr_mepc_reg <= 32'b0;
|
||||
csr_mcause_reg <= 32'b0;
|
||||
csr_mtval_reg <= 32'b0;
|
||||
csr_mip_reg <= 32'b0;
|
||||
end
|
||||
else if(csr_excp) begin
|
||||
csr_mstatus_reg <= {
|
||||
csr_mstatus_sd,
|
||||
8'b0, // reserved
|
||||
csr_mstatus_tsr,
|
||||
csr_mstatus_tw,
|
||||
csr_mstatus_tvm,
|
||||
csr_mstatus_mxr,
|
||||
csr_mstatus_sum,
|
||||
csr_mstatus_mprv,
|
||||
csr_mstatus_xs,
|
||||
csr_mstatus_fs,
|
||||
2'b11, // MPP (bits 12:11) set to M-mode (2'b11)
|
||||
2'b0, // reserved
|
||||
csr_mstatus_spp, // Bit 8 (SPP, typically unchanged or reflects S-mode if coming from S)
|
||||
csr_mstatus_mie, // MPIE (bit 7) gets the old MIE (bit 3) value
|
||||
1'b0, // reserved
|
||||
csr_mstatus_spie,
|
||||
csr_mstatus_upie,
|
||||
1'b0, // MIE (bit 3) is cleared
|
||||
1'b0, // reserved
|
||||
csr_mstatus_sie,
|
||||
csr_mstatus_uie
|
||||
};
|
||||
csr_mepc_reg <= csr_pc_i;
|
||||
csr_mcause_reg <= {1'b0, 26'b0, csr_excp_code}; // {excp_sign, reserved, excp_code}
|
||||
csr_mtval_reg <= {32{excp_inst_addr_misalign}} & csr_pc_i
|
||||
| {32{excp_illegal_inst }} & csr_inst_i
|
||||
| {32{excp_breakpoint }} & 32'b0
|
||||
| {32{excp_env_call_from_m }} & 32'b0;
|
||||
end
|
||||
else begin
|
||||
case({32{csr_we}} & csr_addr_i)
|
||||
// 0x300-0x3FF Standard read/write
|
||||
12'h300: begin // mstatus
|
||||
csr_mstatus_reg <= {
|
||||
csr_mstatus_sd, // read-only
|
||||
8'b0, // reserved
|
||||
csr_wdata_internal[22], // TSR
|
||||
csr_mstatus_tw, // not used
|
||||
csr_wdata_internal[20], // TVM
|
||||
csr_wdata_internal[19], // MXR
|
||||
csr_wdata_internal[18], // SUM
|
||||
csr_mstatus_mprv, // not used
|
||||
csr_mstatus_xs, // not used
|
||||
csr_mstatus_fs, // not used
|
||||
csr_wdata_internal[12:11], // MPP
|
||||
2'b0, // reserved
|
||||
csr_wdata_internal[8], // SPP
|
||||
csr_wdata_internal[7], // MPIE
|
||||
1'b0, // reserved
|
||||
csr_wdata_internal[5], // SPIE
|
||||
csr_mstatus_upie, // not used
|
||||
csr_wdata_internal[3], // MIE
|
||||
1'b0, // reserved
|
||||
csr_wdata_internal[1], // SIE
|
||||
csr_mstatus_uie // not used
|
||||
}; // WARL
|
||||
end
|
||||
12'h301: begin // misa
|
||||
csr_misa_reg <= {2'b01, 4'b0, 13'b0, csr_wdata_internal[12], 3'b0, csr_wdata_internal[8], 7'b0, csr_wdata_internal[0]}; // WARL
|
||||
end
|
||||
12'h304: begin // mie
|
||||
csr_mie_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h305: begin // mtvec
|
||||
csr_mtvec_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h340: begin // mscratch
|
||||
csr_mscratch_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h341: begin // mepc
|
||||
csr_mepc_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h342: begin // mcause
|
||||
csr_mcause_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h343: begin // mtval
|
||||
csr_mtval_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h344: begin // mip
|
||||
csr_mip_reg <= csr_wdata_internal;
|
||||
end
|
||||
default: begin
|
||||
// do nothing
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign csr_mpp_o = csr_mstatus_mpp;
|
||||
|
||||
assign csr_taken_o = csr_excp;
|
||||
assign csr_target_o = csr_mtvec_reg;
|
||||
|
||||
assign csr_rdata_o = csr_rdata_internal;
|
||||
endmodule
|
||||
@@ -0,0 +1,31 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/21 15:47:30
|
||||
// Design Name:
|
||||
// Module Name: onehot_i32_to_hex_o5_decoder
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module onehot32_to_hex5_decoder (
|
||||
input [31:0] onehot_i,
|
||||
output [ 4:0] hex_o
|
||||
);
|
||||
assign hex_o[0] = |(onehot_i & 32'haaaa_aaaa);
|
||||
assign hex_o[1] = |(onehot_i & 32'hcccc_cccc);
|
||||
assign hex_o[2] = |(onehot_i & 32'hf0f0_f0f0);
|
||||
assign hex_o[3] = |(onehot_i & 32'hff00_ff00);
|
||||
assign hex_o[4] = |(onehot_i & 32'hffff_0000);
|
||||
endmodule
|
||||
266
rv_cpu.srcs/sources_1/new/sub_unit/csr_reg_file.v
Normal file
266
rv_cpu.srcs/sources_1/new/sub_unit/csr_reg_file.v
Normal file
@@ -0,0 +1,266 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/19 09:13:42
|
||||
// Design Name:
|
||||
// Module Name: csr_csr_reg_file
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module csr_reg_file(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input csr_pc_i,
|
||||
input csr_inst_i,
|
||||
|
||||
input [ 2:0] csr_op_i,
|
||||
input [11:0] csr_addr_i,
|
||||
input [31:0] csr_wdata_i,
|
||||
output [31:0] csr_rdata_o,
|
||||
input [31:0] csr_excp_vec_i,
|
||||
|
||||
output csr_taken_o,
|
||||
output [31:0] csr_target_o
|
||||
);
|
||||
|
||||
reg [31:0] csr_mstatus_reg;
|
||||
reg [31:0] csr_mie_reg;
|
||||
reg [31:0] csr_mtvec_reg;
|
||||
reg [31:0] csr_mepc_reg;
|
||||
reg [31:0] csr_mcause_reg;
|
||||
reg [31:0] csr_mtval_reg;
|
||||
reg [31:0] csr_mip_reg;
|
||||
reg [31:0] csr_mscratch_reg;
|
||||
|
||||
reg [31:0] csr_rdata_internal;
|
||||
|
||||
wire csr_re;
|
||||
wire csr_we;
|
||||
|
||||
wire excp_inst_addr_misalign;
|
||||
wire excp_inst_access_fault; // not used in current design
|
||||
wire excp_illegal_inst;
|
||||
wire excp_breakpoint;
|
||||
wire excp_load_addr_misalign; // hardware solved
|
||||
wire excp_load_access_fault; // not used in current design
|
||||
wire excp_store_addr_misalign; // hardware solved
|
||||
wire excp_store_access_fault; // not used in current design
|
||||
wire excp_env_call_from_u; // not used in current design
|
||||
wire excp_env_call_from_s; // not used in current design
|
||||
wire excp_reserved_code_10; // not used in current design
|
||||
wire excp_env_call_from_m;
|
||||
wire excp_inst_page_fault; // not used in current design
|
||||
wire excp_load_page_fault; // not used in current design
|
||||
wire excp_reserved_code_14; // not used in current design
|
||||
wire excp_store_page_fault; // not used in current design
|
||||
wire [15:0] excp_reserved; // not used in current design
|
||||
|
||||
wire [31:0] csr_wdata_internal;
|
||||
wire csr_excp;
|
||||
wire [ 4:0] csr_excp_code;
|
||||
|
||||
wire csr_mstatus_uie;
|
||||
wire csr_mstatus_sie;
|
||||
wire csr_mstatus_mie;
|
||||
wire csr_mstatus_upie;
|
||||
wire csr_mstatus_spie;
|
||||
wire csr_mstatus_mpie;
|
||||
wire csr_mstatus_spp;
|
||||
wire [1:0] csr_mstatus_mpp;
|
||||
wire [1:0] csr_mstatus_fs;
|
||||
wire [1:0] csr_mstatus_xs;
|
||||
wire csr_mstatus_mprv;
|
||||
wire csr_mstatus_sum;
|
||||
wire csr_mstatus_mxr;
|
||||
wire csr_mstatus_tvm;
|
||||
wire csr_mstatus_tw;
|
||||
wire csr_mstatus_tsr;
|
||||
wire csr_mstatus_sd;
|
||||
|
||||
assign csr_re = |csr_op_i;
|
||||
assign csr_we = |csr_op_i;
|
||||
|
||||
assign {
|
||||
excp_reserved,
|
||||
excp_store_page_fault,
|
||||
excp_reserverd_code_14,
|
||||
excp_load_page_fault,
|
||||
excp_inst_page_fault,
|
||||
excp_reserved_code_10,
|
||||
excp_env_call_from_m,
|
||||
excp_env_call_from_s,
|
||||
excp_env_call_from_u,
|
||||
excp_store_access_fault,
|
||||
excp_store_addr_misalign,
|
||||
excp_load_access_fault,
|
||||
excp_load_addr_misalign,
|
||||
excp_breakpoint,
|
||||
excp_illegal_inst,
|
||||
excp_inst_access_fault,
|
||||
excp_inst_addr_misalign
|
||||
} = csr_excp_vec_i;
|
||||
|
||||
assign csr_mstatus_uie = csr_mstatus_reg[ 0];
|
||||
assign csr_mstatus_sie = csr_mstatus_reg[ 1];
|
||||
assign csr_mstatus_mie = csr_mstatus_reg[ 3];
|
||||
assign csr_mstatus_upie = csr_mstatus_reg[ 4];
|
||||
assign csr_mstatus_spie = csr_mstatus_reg[ 5];
|
||||
assign csr_mstatus_mpie = csr_mstatus_reg[ 7];
|
||||
assign csr_mstatus_spp = csr_mstatus_reg[ 8];
|
||||
assign csr_mstatus_mpp = csr_mstatus_reg[12:11];
|
||||
assign csr_mstatus_fs = csr_mstatus_reg[14:13];
|
||||
assign csr_mstatus_xs = csr_mstatus_reg[16:15];
|
||||
assign csr_mstatus_mprv = csr_mstatus_reg[17];
|
||||
assign csr_mstatus_sum = csr_mstatus_reg[18];
|
||||
assign csr_mstatus_mxr = csr_mstatus_reg[19];
|
||||
assign csr_mstatus_tvm = csr_mstatus_reg[20];
|
||||
assign csr_mstatus_tw = csr_mstatus_reg[21];
|
||||
assign csr_mstatus_tsr = csr_mstatus_reg[22];
|
||||
assign csr_mstatus_sd = csr_mstatus_reg[31];
|
||||
|
||||
assign csr_wdata_internal = {32{csr_op_i[0]}} & csr_wdata_i
|
||||
| {32{csr_op_i[1]}} & (csr_rdata_internal | csr_wdata_i)
|
||||
| {32{csr_op_i[2]}} & (csr_rdata_internal & ~csr_wdata_i);
|
||||
|
||||
assign csr_excp = |csr_excp_vec_i;
|
||||
|
||||
// csr read logic
|
||||
always @(*) begin
|
||||
case (csr_addr_i)
|
||||
// 0x300-0x3FF Standard read/write
|
||||
12'h300: begin // mstatus
|
||||
csr_rdata_internal = csr_mstatus_reg;
|
||||
end
|
||||
12'h304: begin // mie
|
||||
csr_rdata_internal = csr_mie_reg;
|
||||
end
|
||||
12'h305: begin // mtvec
|
||||
csr_rdata_internal = csr_mtvec_reg;
|
||||
end
|
||||
12'h341: begin // mepc
|
||||
csr_rdata_internal = csr_mepc_reg;
|
||||
end
|
||||
12'h342: begin // mcause
|
||||
csr_rdata_internal = csr_mcause_reg;
|
||||
end
|
||||
12'h343: begin // mtval
|
||||
csr_rdata_internal = csr_mtval_reg;
|
||||
end
|
||||
12'h344: begin // mip
|
||||
csr_rdata_internal = csr_mip_reg;
|
||||
end
|
||||
12'h340: begin // mscratch
|
||||
csr_rdata_internal = csr_mscratch_reg;
|
||||
end
|
||||
default: begin
|
||||
csr_rdata_internal = 32'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
onehot32_to_hex5_decoder inst_onehot32_to_hex5_decoder(
|
||||
.onehot_i (csr_excp_vec_i),
|
||||
.hex_o (csr_excp_code)
|
||||
);
|
||||
|
||||
// csr write logic
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
// Reset mstatus: MPP is set to M-mode (2'b11 at bits 12:11), other fields are typically 0.
|
||||
// 32'h00001800 corresponds to:
|
||||
// MPP (bits 12:11) = 2'b11 (Machine mode)
|
||||
// All other implemented bits are 0.
|
||||
// For RV32, SD bit (bit 31) is 0. FS and XS fields (bits 14:13, 16:15) are 0 (initial/dirty).
|
||||
csr_mstatus_reg <= 32'h00001800;
|
||||
csr_mie_reg <= 32'b0;
|
||||
csr_mtvec_reg <= 32'b0;
|
||||
csr_mepc_reg <= 32'b0;
|
||||
csr_mcause_reg <= 32'b0;
|
||||
csr_mtval_reg <= 32'b0;
|
||||
csr_mip_reg <= 32'b0;
|
||||
csr_mscratch_reg <= 32'b0;
|
||||
end
|
||||
else if(csr_excp) begin
|
||||
csr_mstatus_reg <= {
|
||||
csr_mstatus_sd,
|
||||
csr_mstatus_reg[30:23], // hard wired, keep old value
|
||||
csr_mstatus_tsr,
|
||||
csr_mstatus_tw,
|
||||
csr_mstatus_tvm,
|
||||
csr_mstatus_mxr,
|
||||
csr_mstatus_sum,
|
||||
csr_mstatus_mprv,
|
||||
csr_mstatus_xs,
|
||||
csr_mstatus_fs,
|
||||
2'b11, // MPP (bits 12:11) set to M-mode (2'b11)
|
||||
csr_mstatus_reg[10:9], // hard wired, keep old value
|
||||
csr_mstatus_spp, // Bit 8 (SPP, typically unchanged or reflects S-mode if coming from S)
|
||||
csr_mstatus_mie, // MPIE (bit 7) gets the old MIE (bit 3) value
|
||||
csr_mstatus_reg[6], // hard wired, keep old value
|
||||
csr_mstatus_spie,
|
||||
csr_mstatus_upie,
|
||||
1'b0, // MIE (bit 3) is cleared
|
||||
csr_mstatus_reg[2], // hard wired, keep old value
|
||||
csr_mstatus_sie,
|
||||
csr_mstatus_uie
|
||||
};
|
||||
csr_mepc_reg <= csr_pc_i;
|
||||
csr_mcause_reg <= {1'b0, 26'b0, csr_excp_code}; // {excp_sign, reserved, excp_code}
|
||||
csr_mtval_reg <= {32{excp_inst_addr_misalign}} & csr_pc_i
|
||||
| {32{excp_illegal_inst }} & csr_inst_i
|
||||
| {32{excp_breakpoint }} & 32'b0
|
||||
| {32{excp_env_call_from_m }} & 32'b0;
|
||||
end
|
||||
else begin
|
||||
case({32{csr_we}} & csr_addr_i)
|
||||
// 0x300-0x3FF Standard read/write
|
||||
12'h300: begin // mstatus
|
||||
csr_mstatus_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h304: begin // mie
|
||||
csr_mie_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h305: begin // mtvec
|
||||
csr_mtvec_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h341: begin // mepc
|
||||
csr_mepc_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h342: begin // mcause
|
||||
csr_mcause_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h343: begin // mtval
|
||||
csr_mtval_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h344: begin // mip
|
||||
csr_mip_reg <= csr_wdata_internal;
|
||||
end
|
||||
12'h340: begin // mscratch
|
||||
csr_mscratch_reg <= csr_wdata_internal;
|
||||
end
|
||||
default: begin
|
||||
// do nothing
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign csr_taken_o = csr_excp;
|
||||
assign csr_target_o = csr_mtvec_reg;
|
||||
|
||||
assign csr_rdata_o = csr_rdata_internal;
|
||||
endmodule
|
||||
336
rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v
Normal file
336
rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v
Normal file
@@ -0,0 +1,336 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/16 20:10:16
|
||||
// Design Name:
|
||||
// Module Name: inst_decoder
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module inst_decoder(
|
||||
input [31:0] inst_i,
|
||||
|
||||
output [ 4:0] rs1_o,
|
||||
output [ 4:0] rs2_o,
|
||||
output [ 4:0] rd_o,
|
||||
output [31:0] imm_o,
|
||||
output [ 4:0] shamt_o,
|
||||
output [ 3:0] pred_o, // reserved
|
||||
output [ 3:0] succ_o, // reserved
|
||||
output [11:0] csr_o,
|
||||
output [ 4:0] zimm_o,
|
||||
|
||||
output [10:0] alu_op_o,
|
||||
output [ 3:0] calc_src1_sel_o,
|
||||
output [ 3:0] calc_src2_sel_o,
|
||||
|
||||
output [ 1:0] jump_op_o,
|
||||
output [ 5:0] load_op_o,
|
||||
output [ 2:0] store_op_o,
|
||||
output [ 5:0] branch_op_o,
|
||||
|
||||
output [ 7:0] m_ext_op_o,
|
||||
output [ 2:0] csr_op_o,
|
||||
|
||||
output [11:0] amo_op_o,
|
||||
|
||||
output amo_aq_o, // reserved
|
||||
output amo_rl_o, // reserved
|
||||
|
||||
output excp_illegal_inst_o,
|
||||
output excp_breakpoint_o,
|
||||
output excp_env_call_o
|
||||
);
|
||||
|
||||
wire [ 7:0] opcode;
|
||||
wire [ 2:0] funct3;
|
||||
wire [ 4:0] funct5;
|
||||
wire [ 6:0] funct7;
|
||||
|
||||
wire [ 1:0] r_type;
|
||||
wire [ 4:0] i_type;
|
||||
wire [ 0:0] s_type;
|
||||
wire [ 0:0] b_type;
|
||||
wire [ 1:0] u_type;
|
||||
wire [ 0:0] j_type;
|
||||
|
||||
wire [31:0] i_type_imm;
|
||||
wire [31:0] s_type_imm;
|
||||
wire [31:0] b_type_imm;
|
||||
wire [31:0] u_type_imm;
|
||||
wire [31:0] j_type_imm;
|
||||
|
||||
wire inst_lui;
|
||||
wire inst_auipc;
|
||||
wire inst_jal;
|
||||
wire inst_jalr;
|
||||
wire inst_beq;
|
||||
wire inst_bne;
|
||||
wire inst_blt;
|
||||
wire inst_bge;
|
||||
wire inst_bltu;
|
||||
wire inst_bgeu;
|
||||
wire inst_lb;
|
||||
wire inst_lh;
|
||||
wire inst_lw;
|
||||
wire inst_lbu;
|
||||
wire inst_lhu;
|
||||
wire inst_sb;
|
||||
wire inst_sh;
|
||||
wire inst_sw;
|
||||
wire inst_addi;
|
||||
wire inst_slti;
|
||||
wire inst_sltiu;
|
||||
wire inst_xori;
|
||||
wire inst_ori;
|
||||
wire inst_andi;
|
||||
wire inst_slli;
|
||||
wire inst_srli;
|
||||
wire inst_srai;
|
||||
wire inst_add;
|
||||
wire inst_sub;
|
||||
wire inst_sll;
|
||||
wire inst_slt;
|
||||
wire inst_sltu;
|
||||
wire inst_xor;
|
||||
wire inst_srl;
|
||||
wire inst_sra;
|
||||
wire inst_or;
|
||||
wire inst_and;
|
||||
|
||||
wire inst_fence;
|
||||
wire inst_fence_i;
|
||||
wire inst_ecall;
|
||||
wire inst_ebreak;
|
||||
wire inst_mret; // TODO
|
||||
wire inst_sret; // TODO
|
||||
wire inst_csrrw;
|
||||
wire inst_csrrs;
|
||||
wire inst_csrrc;
|
||||
wire inst_csrrwi;
|
||||
wire inst_csrrsi;
|
||||
wire inst_csrrci;
|
||||
|
||||
wire inst_mul;
|
||||
wire inst_mulh;
|
||||
wire inst_mulhsu;
|
||||
wire inst_mulhu;
|
||||
wire inst_div;
|
||||
wire inst_divu;
|
||||
wire inst_rem;
|
||||
wire inst_remu;
|
||||
|
||||
wire inst_lr_w;
|
||||
wire inst_sc_w;
|
||||
wire inst_amoswap_w;
|
||||
wire inst_amoadd_w;
|
||||
wire inst_amoxor_w;
|
||||
wire inst_amoand_w;
|
||||
wire inst_amoor_w;
|
||||
wire inst_amomin_w;
|
||||
wire inst_amomax_w;
|
||||
wire inst_amominu_w;
|
||||
wire inst_amomaxu_w;
|
||||
|
||||
wire calc_src1_is_rs1;
|
||||
wire calc_src1_is_pc;
|
||||
wire calc_src1_is_zero;
|
||||
wire calc_src1_is_zimm;
|
||||
|
||||
wire calc_src2_is_rs2;
|
||||
wire calc_src2_is_imm;
|
||||
wire calc_src2_is_4;
|
||||
|
||||
assign opcode = inst_i[6:0];
|
||||
assign funct3 = inst_i[14:12];
|
||||
assign funct5 = inst_i[31:27];
|
||||
assign funct7 = inst_i[31:25];
|
||||
|
||||
assign r_type = {(opcode == 7'b0101111), (opcode == 7'b0110011)};
|
||||
assign i_type = {(opcode == 7'b1110011), (opcode == 7'b0001111), (opcode == 7'b0010011), (opcode == 7'b0000011), (opcode == 7'b1100111)};
|
||||
assign s_type = {(opcode == 7'b0100011)};
|
||||
assign b_type = {(opcode == 7'b1100011)};
|
||||
assign u_type = {(opcode == 7'b0110111), (opcode == 7'b0010111)};
|
||||
assign j_type = {(opcode == 7'b1101111)};
|
||||
|
||||
// basic instructions
|
||||
assign inst_lui = u_type[1];
|
||||
assign inst_auipc = u_type[0];
|
||||
assign inst_jal = j_type[0];
|
||||
assign inst_jalr = i_type[0];
|
||||
assign inst_beq = b_type[0] && (funct3 == 3'b000);
|
||||
assign inst_bne = b_type[0] && (funct3 == 3'b001);
|
||||
assign inst_blt = b_type[0] && (funct3 == 3'b100);
|
||||
assign inst_bge = b_type[0] && (funct3 == 3'b101);
|
||||
assign inst_bltu = b_type[0] && (funct3 == 3'b110);
|
||||
assign inst_bgeu = b_type[0] && (funct3 == 3'b111);
|
||||
assign inst_lb = i_type[1] && (funct3 == 3'b000);
|
||||
assign inst_lh = i_type[1] && (funct3 == 3'b001);
|
||||
assign inst_lw = i_type[1] && (funct3 == 3'b010);
|
||||
assign inst_lbu = i_type[1] && (funct3 == 3'b100);
|
||||
assign inst_lhu = i_type[1] && (funct3 == 3'b101);
|
||||
assign inst_sb = s_type[0] && (funct3 == 3'b000);
|
||||
assign inst_sh = s_type[0] && (funct3 == 3'b001);
|
||||
assign inst_sw = s_type[0] && (funct3 == 3'b010);
|
||||
assign inst_addi = i_type[2] && (funct3 == 3'b000);
|
||||
assign inst_slti = i_type[2] && (funct3 == 3'b010);
|
||||
assign inst_sltiu = i_type[2] && (funct3 == 3'b011);
|
||||
assign inst_xori = i_type[2] && (funct3 == 3'b100);
|
||||
assign inst_ori = i_type[2] && (funct3 == 3'b110);
|
||||
assign inst_andi = i_type[2] && (funct3 == 3'b111);
|
||||
assign inst_slli = i_type[2] && (funct3 == 3'b001) && (funct7 == 7'b0000000);
|
||||
assign inst_srli = i_type[2] && (funct3 == 3'b101) && (funct7 == 7'b0000000);
|
||||
assign inst_srai = i_type[2] && (funct3 == 3'b101) && (funct7 == 7'b0100000);
|
||||
assign inst_add = r_type[0] && (funct3 == 3'b000) && (funct7 == 7'b0000000);
|
||||
assign inst_sub = r_type[0] && (funct3 == 3'b000) && (funct7 == 7'b0100000);
|
||||
assign inst_sll = r_type[0] && (funct3 == 3'b001) && (funct7 == 7'b0000000);
|
||||
assign inst_slt = r_type[0] && (funct3 == 3'b010) && (funct7 == 7'b0000000);
|
||||
assign inst_sltu = r_type[0] && (funct3 == 3'b011) && (funct7 == 7'b0000000);
|
||||
assign inst_xor = r_type[0] && (funct3 == 3'b100) && (funct7 == 7'b0000000);
|
||||
assign inst_srl = r_type[0] && (funct3 == 3'b101) && (funct7 == 7'b0000000);
|
||||
assign inst_sra = r_type[0] && (funct3 == 3'b101) && (funct7 == 7'b0100000);
|
||||
assign inst_or = r_type[0] && (funct3 == 3'b110) && (funct7 == 7'b0000000);
|
||||
assign inst_and = r_type[0] && (funct3 == 3'b111) && (funct7 == 7'b0000000);
|
||||
|
||||
// csr instructions
|
||||
assign inst_fence = i_type[3] && (funct3 == 3'b000);
|
||||
assign inst_fence_i = i_type[3] && (funct3 == 3'b001);
|
||||
assign inst_ecall = i_type[4] && (funct3 == 3'b000) && (funct7 == 7'b0000000);
|
||||
assign inst_ebreak = i_type[4] && (funct3 == 3'b000) && (funct7 == 7'b0000001);
|
||||
assign inst_mret = i_type[4] && (funct3 == 3'b000) && (funct7 == 7'b0011000);
|
||||
assign inst_sret = i_type[4] && (funct3 == 3'b000) && (funct7 == 7'b0011001);
|
||||
assign inst_csrrw = i_type[4] && (funct3 == 3'b001);
|
||||
assign inst_csrrs = i_type[4] && (funct3 == 3'b010);
|
||||
assign inst_csrrc = i_type[4] && (funct3 == 3'b011);
|
||||
assign inst_csrrwi = i_type[4] && (funct3 == 3'b101);
|
||||
assign inst_csrrsi = i_type[4] && (funct3 == 3'b110);
|
||||
assign inst_csrrci = i_type[4] && (funct3 == 3'b111);
|
||||
|
||||
// m_extension instructions
|
||||
assign inst_mul = r_type[0] && (funct3 == 3'b000) && (funct7 == 7'b0000001);
|
||||
assign inst_mulh = r_type[0] && (funct3 == 3'b001) && (funct7 == 7'b0000001);
|
||||
assign inst_mulhsu = r_type[0] && (funct3 == 3'b010) && (funct7 == 7'b0000001);
|
||||
assign inst_mulhu = r_type[0] && (funct3 == 3'b011) && (funct7 == 7'b0000001);
|
||||
assign inst_div = r_type[0] && (funct3 == 3'b100) && (funct7 == 7'b0000001);
|
||||
assign inst_divu = r_type[0] && (funct3 == 3'b101) && (funct7 == 7'b0000001);
|
||||
assign inst_rem = r_type[0] && (funct3 == 3'b110) && (funct7 == 7'b0000001);
|
||||
assign inst_remu = r_type[0] && (funct3 == 3'b111) && (funct7 == 7'b0000001);
|
||||
|
||||
// a_extension instructions
|
||||
assign inst_lr_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b00010);
|
||||
assign inst_sc_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b00011);
|
||||
assign inst_amoswap_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b00001);
|
||||
assign inst_amoadd_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b00000);
|
||||
assign inst_amoxor_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b00100);
|
||||
assign inst_amoand_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b01100);
|
||||
assign inst_amoor_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b01000);
|
||||
assign inst_amomin_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b10000);
|
||||
assign inst_amomax_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b10100);
|
||||
assign inst_amominu_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b11000);
|
||||
assign inst_amomaxu_w = r_type[1] && (funct3 == 3'b010) && (funct5 == 5'b11100);
|
||||
|
||||
|
||||
assign i_type_imm = {{20{inst_i[31]}}, inst_i[31:20]};
|
||||
assign s_type_imm = {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]};
|
||||
assign b_type_imm = {{20{inst_i[31]}}, inst_i[7], inst_i[30:25], inst_i[11:8], 1'b0};
|
||||
assign u_type_imm = {inst_i[31:12], 12'b0};
|
||||
assign j_type_imm = {{12{inst_i[31]}}, inst_i[19:12], inst_i[20], inst_i[30:21], 1'b0};
|
||||
|
||||
assign calc_src1_is_rs1 = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_sb | inst_sh | inst_sw
|
||||
| inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi
|
||||
| inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
|
||||
| inst_slli | inst_srli | inst_srai
|
||||
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
|
||||
| inst_csrrw | inst_csrrs | inst_csrrc
|
||||
| inst_lr_w | inst_sc_w
|
||||
| inst_amoswap_w | inst_amoadd_w | inst_amoxor_w | inst_amoand_w | inst_amoor_w | inst_amomin_w | inst_amomax_w | inst_amominu_w | inst_amomaxu_w;
|
||||
assign calc_src1_is_pc = inst_auipc | inst_jal | inst_jalr;
|
||||
assign calc_src1_is_zero = inst_lui;
|
||||
assign calc_src1_is_zimm = inst_csrrwi | inst_csrrsi | inst_csrrci;
|
||||
|
||||
assign calc_src2_is_rs2 = inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
|
||||
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
|
||||
| inst_sc_w
|
||||
| inst_amoswap_w | inst_amoadd_w | inst_amoxor_w | inst_amoand_w | inst_amoor_w | inst_amomin_w | inst_amomax_w | inst_amominu_w | inst_amomaxu_w;
|
||||
assign calc_src2_is_imm = inst_lui | inst_auipc | inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu
|
||||
| inst_sb | inst_sh | inst_sw | inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi;
|
||||
assign calc_src2_is_4 = inst_jal | inst_jalr;
|
||||
assign calc_src2_is_shamt = inst_slli | inst_srli | inst_srai;
|
||||
|
||||
|
||||
assign rs1_o = inst_i[19:15];
|
||||
assign rs2_o = inst_i[24:20];
|
||||
assign rd_o = inst_i[11:7];
|
||||
assign imm_o = ({32{|i_type}} & i_type_imm)
|
||||
| ({32{|s_type}} & s_type_imm)
|
||||
| ({32{|b_type}} & b_type_imm)
|
||||
| ({32{|u_type}} & u_type_imm)
|
||||
| ({32{|j_type}} & j_type_imm);
|
||||
assign shamt_o = inst_i[24:20];
|
||||
assign pred_o = inst_i[27:24];
|
||||
assign succ_o = inst_i[23:20];
|
||||
assign csr_o = inst_i[31:20];
|
||||
assign zimm_o = inst_i[19:15];
|
||||
|
||||
assign alu_op_o = {
|
||||
// op_lui
|
||||
inst_lui,
|
||||
// op_add
|
||||
inst_auipc | inst_jal | inst_jalr | inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_sb | inst_sh | inst_sw | inst_addi | inst_add,
|
||||
// op_sub
|
||||
inst_sub,
|
||||
// op_slt
|
||||
inst_slti | inst_slt,
|
||||
// op_sltu
|
||||
inst_sltiu | inst_sltu,
|
||||
// op_xor
|
||||
inst_xori | inst_xor,
|
||||
// op_or
|
||||
inst_ori | inst_or,
|
||||
// op_and
|
||||
inst_andi | inst_and,
|
||||
// op_sll
|
||||
inst_slli | inst_sll,
|
||||
// op_srl
|
||||
inst_srli | inst_srl,
|
||||
// op_sra
|
||||
inst_srai | inst_sra
|
||||
};
|
||||
|
||||
assign calc_src1_sel_o = {calc_src1_is_zimm, calc_src1_is_zero, calc_src1_is_pc, calc_src1_is_rs1};
|
||||
assign calc_src2_sel_o = {calc_src2_is_shamt, calc_src2_is_4, calc_src2_is_imm, calc_src2_is_rs2};
|
||||
|
||||
assign jump_op_o = {inst_jalr, inst_jal};
|
||||
assign branch_op_o = {inst_bgeu, inst_bltu, inst_bge, inst_blt, inst_bne, inst_beq};
|
||||
assign load_op_o = {inst_lhu, inst_lbu, inst_lw, inst_lh, inst_lb};
|
||||
assign store_op_o = {inst_sw, inst_sh, inst_sb};
|
||||
|
||||
assign m_ext_op_o = {inst_mul, inst_mulh, inst_mulhsu, inst_mulhu, inst_div, inst_divu, inst_rem, inst_remu};
|
||||
assign csr_op_o = {
|
||||
inst_csrrci | inst_csrrc,
|
||||
inst_csrrsi | inst_csrrs,
|
||||
inst_csrrwi | inst_csrrw
|
||||
};
|
||||
|
||||
assign amo_op_o = {1'b0, inst_lr_w, inst_sc_w, inst_amoswap_w, inst_amoadd_w, inst_amoxor_w, inst_amoand_w, inst_amoor_w, inst_amomin_w, inst_amomax_w, inst_amominu_w, inst_amomaxu_w};
|
||||
|
||||
assign amo_aq_o = inst_i[26];
|
||||
assign amo_rl_o = inst_i[25];
|
||||
|
||||
assign excp_illegal_inst_o = !(r_type || i_type || s_type || b_type || u_type || j_type);
|
||||
assign excp_breakpoint_o = inst_ebreak;
|
||||
assign excp_env_call_o = inst_ecall;
|
||||
endmodule
|
||||
274
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/divider.v
Normal file
274
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/divider.v
Normal file
@@ -0,0 +1,274 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 23:19:17
|
||||
// Design Name:
|
||||
// Module Name: divider
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define TEST_PROG_DIV_0_NO_CONSIDER_SIGN
|
||||
|
||||
module divider(
|
||||
// Inputs
|
||||
input wire clk_i,
|
||||
input wire rstn_i,
|
||||
input wire start_i, // Start signal for division
|
||||
input wire signed_mode_i, // 0 for unsigned, 1 for signed
|
||||
input wire [31:0] dividend_i, // 被除数
|
||||
input wire [31:0] divisor_i, // 除数
|
||||
|
||||
// Outputs
|
||||
output reg [31:0] quotient_o, // 商
|
||||
output reg [31:0] remainder_o, // 余数
|
||||
output reg done_o, // Calculation done signal
|
||||
output reg busy_o, // Divider is busy
|
||||
output reg div_by_zero_o // Division by zero error
|
||||
);
|
||||
|
||||
localparam DATA_WIDTH = 32;
|
||||
|
||||
// FSM States
|
||||
localparam S_IDLE = 3'd0; // Increased state reg width slightly for safety if more states added
|
||||
localparam S_PREPARE = 3'd1;
|
||||
localparam S_DIV_STEP = 3'd2;
|
||||
localparam S_ADJUST_SIGN = 3'd3;
|
||||
localparam S_FINISH = 3'd4;
|
||||
|
||||
reg [2:0] current_state_reg;
|
||||
reg [2:0] next_state_reg;
|
||||
|
||||
// Internal Registers for algorithm
|
||||
reg [DATA_WIDTH-1:0] dividend_abs_reg; // Holds dividend, then quotient bits are shifted in
|
||||
reg [DATA_WIDTH-1:0] divisor_abs_reg; // Absolute value of divisor
|
||||
reg [DATA_WIDTH:0] partial_remainder_reg; // Partial remainder (N+1 bits for subtract sign)
|
||||
|
||||
reg [5:0] iter_count_reg; // Iteration counter (0 to DATA_WIDTH)
|
||||
|
||||
reg original_dividend_sign;
|
||||
reg original_divisor_sign;
|
||||
reg is_signed_mode_reg;
|
||||
reg div_by_zero_flag;
|
||||
|
||||
// Temporary variables for calculations within clocked always block (module scope Verilog regs)
|
||||
reg [DATA_WIDTH:0] p_shifted_in_A_msb_temp;
|
||||
reg [DATA_WIDTH:0] subtract_result_temp;
|
||||
reg new_quotient_bit_temp;
|
||||
reg [DATA_WIDTH-1:0] final_quotient_temp;
|
||||
reg [DATA_WIDTH-1:0] final_remainder_temp;
|
||||
reg quotient_sign_temp;
|
||||
reg remainder_sign_temp;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// FSM State Register
|
||||
//--------------------------------------------------------------------------
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
current_state_reg <= S_IDLE;
|
||||
end else begin
|
||||
current_state_reg <= next_state_reg;
|
||||
end
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// FSM Next State Logic & Combinational Output (done_o)
|
||||
//--------------------------------------------------------------------------
|
||||
always @(*) begin // Verilog-2001 equivalent of always_comb
|
||||
next_state_reg = current_state_reg; // Default: stay in current state
|
||||
done_o = 1'b0; // Default done_o to low
|
||||
|
||||
case (current_state_reg)
|
||||
S_IDLE: begin
|
||||
if (start_i) begin
|
||||
next_state_reg = S_PREPARE;
|
||||
end
|
||||
end
|
||||
|
||||
S_PREPARE: begin
|
||||
if (div_by_zero_flag) begin
|
||||
next_state_reg = S_FINISH;
|
||||
end else begin
|
||||
next_state_reg = S_DIV_STEP;
|
||||
end
|
||||
end
|
||||
|
||||
S_DIV_STEP: begin
|
||||
if (iter_count_reg == DATA_WIDTH) begin // Completed N iterations
|
||||
next_state_reg = S_ADJUST_SIGN;
|
||||
end else begin
|
||||
next_state_reg = S_DIV_STEP; // Stay for next iteration
|
||||
end
|
||||
end
|
||||
|
||||
S_ADJUST_SIGN: begin
|
||||
next_state_reg = S_FINISH;
|
||||
end
|
||||
|
||||
S_FINISH: begin
|
||||
done_o = 1'b1; // Assert done for one cycle
|
||||
next_state_reg = S_IDLE;
|
||||
end
|
||||
|
||||
default: begin
|
||||
next_state_reg = S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Datapath Logic (Sequential - Register Updates)
|
||||
//--------------------------------------------------------------------------
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
busy_o <= 1'b0;
|
||||
div_by_zero_o <= 1'b0;
|
||||
quotient_o <= {DATA_WIDTH{1'b0}};
|
||||
remainder_o <= {DATA_WIDTH{1'b0}};
|
||||
|
||||
dividend_abs_reg <= {DATA_WIDTH{1'b0}};
|
||||
divisor_abs_reg <= {DATA_WIDTH{1'b0}};
|
||||
partial_remainder_reg <= {DATA_WIDTH+1{1'b0}};
|
||||
iter_count_reg <= 6'd0;
|
||||
original_dividend_sign <= 1'b0;
|
||||
original_divisor_sign <= 1'b0;
|
||||
is_signed_mode_reg <= 1'b0;
|
||||
div_by_zero_flag <= 1'b0;
|
||||
|
||||
end else begin
|
||||
// busy_o is set high when IDLE sees start_i and calculation begins
|
||||
// busy_o is set low when FSM transitions out of S_FINISH (or after done pulse)
|
||||
if (current_state_reg == S_FINISH && next_state_reg == S_IDLE) begin
|
||||
busy_o <= 1'b0;
|
||||
end
|
||||
|
||||
case (current_state_reg)
|
||||
S_IDLE: begin
|
||||
if (start_i) begin
|
||||
busy_o <= 1'b1;
|
||||
div_by_zero_o <= 1'b0;
|
||||
quotient_o <= {DATA_WIDTH{1'b0}};
|
||||
remainder_o <= {DATA_WIDTH{1'b0}};
|
||||
|
||||
is_signed_mode_reg <= signed_mode_i;
|
||||
if (divisor_i == {DATA_WIDTH{1'b0}}) begin
|
||||
div_by_zero_flag <= 1'b1;
|
||||
// For div by zero, abs regs don't matter as much, but init them
|
||||
dividend_abs_reg <= dividend_i; // Store original dividend for remainder
|
||||
original_dividend_sign <= signed_mode_i ? dividend_i[DATA_WIDTH-1] : 1'b0;
|
||||
end else begin
|
||||
div_by_zero_flag <= 1'b0;
|
||||
if (signed_mode_i) begin
|
||||
original_dividend_sign <= dividend_i[DATA_WIDTH-1];
|
||||
original_divisor_sign <= divisor_i[DATA_WIDTH-1];
|
||||
dividend_abs_reg <= (dividend_i[DATA_WIDTH-1]) ? -dividend_i : dividend_i;
|
||||
divisor_abs_reg <= (divisor_i[DATA_WIDTH-1]) ? -divisor_i : divisor_i;
|
||||
end else begin
|
||||
original_dividend_sign <= 1'b0; // Unused for unsigned
|
||||
original_divisor_sign <= 1'b0; // Unused for unsigned
|
||||
dividend_abs_reg <= dividend_i;
|
||||
divisor_abs_reg <= divisor_i;
|
||||
end
|
||||
partial_remainder_reg <= {DATA_WIDTH+1{1'b0}}; // P = 0
|
||||
iter_count_reg <= 6'd0;
|
||||
end
|
||||
end
|
||||
end // S_IDLE
|
||||
|
||||
S_PREPARE: begin
|
||||
// This state is mainly for FSM transition;
|
||||
// actual data loading happens in S_IDLE based on start_i.
|
||||
// If div_by_zero_flag was set, next_state_reg (combinatorially) points to S_FINISH.
|
||||
end
|
||||
|
||||
S_DIV_STEP: begin
|
||||
if (iter_count_reg < DATA_WIDTH) begin
|
||||
// Temporary variables are calculated based on current reg values
|
||||
p_shifted_in_A_msb_temp = {partial_remainder_reg[DATA_WIDTH-1:0], dividend_abs_reg[DATA_WIDTH-1]};
|
||||
subtract_result_temp = p_shifted_in_A_msb_temp - {1'b0, divisor_abs_reg};
|
||||
|
||||
if (subtract_result_temp[DATA_WIDTH] == 1'b0) begin // No borrow / P_trial >= 0
|
||||
partial_remainder_reg <= subtract_result_temp; // Update P
|
||||
new_quotient_bit_temp = 1'b1;
|
||||
end else begin // Borrow / P_trial < 0
|
||||
partial_remainder_reg <= p_shifted_in_A_msb_temp; // Restore P
|
||||
new_quotient_bit_temp = 1'b0;
|
||||
end
|
||||
// Shift A (dividend_abs_reg) and place new quotient bit
|
||||
dividend_abs_reg <= {dividend_abs_reg[DATA_WIDTH-2:0], new_quotient_bit_temp};
|
||||
iter_count_reg <= iter_count_reg + 1;
|
||||
end
|
||||
end // S_DIV_STEP
|
||||
|
||||
S_ADJUST_SIGN: begin
|
||||
// Use temporary regs for calculation before assigning to outputs
|
||||
final_quotient_temp = dividend_abs_reg; // Now contains absolute quotient
|
||||
final_remainder_temp = partial_remainder_reg[DATA_WIDTH-1:0]; // Lower N bits of P
|
||||
|
||||
if (is_signed_mode_reg) begin
|
||||
quotient_sign_temp = original_dividend_sign ^ original_divisor_sign;
|
||||
remainder_sign_temp = original_dividend_sign; // Remainder sign matches dividend
|
||||
|
||||
if (quotient_sign_temp && final_quotient_temp != {DATA_WIDTH{1'b0}}) begin
|
||||
final_quotient_temp = -final_quotient_temp;
|
||||
end
|
||||
if (remainder_sign_temp && final_remainder_temp != {DATA_WIDTH{1'b0}}) begin
|
||||
final_remainder_temp = -final_remainder_temp;
|
||||
end
|
||||
end
|
||||
// Assign to outputs here, they will be stable when S_FINISH asserts done_o
|
||||
quotient_o <= final_quotient_temp;
|
||||
remainder_o <= final_remainder_temp;
|
||||
end // S_ADJUST_SIGN
|
||||
|
||||
S_FINISH: begin
|
||||
// Outputs (quotient_o, remainder_o) were assigned in S_ADJUST_SIGN.
|
||||
// Handle div_by_zero case outputs specifically for this state if they weren't already.
|
||||
if (div_by_zero_flag) begin
|
||||
div_by_zero_o <= 1'b1;
|
||||
// Define output values for division by zero
|
||||
|
||||
`ifdef TEST_PROG_DIV_0_NO_CONSIDER_SIGN
|
||||
quotient_o <= {DATA_WIDTH{1'b1}};
|
||||
remainder_o <= dividend_abs_reg;
|
||||
`else
|
||||
if (is_signed_mode_reg) begin
|
||||
// Example: if dividend was negative -> INT_MIN, else INT_MAX
|
||||
quotient_o <= (original_dividend_sign) ? {1'b1, {(DATA_WIDTH-1){1'b0}}} : {1'b0, {(DATA_WIDTH-1){1'b1}}};
|
||||
end else begin
|
||||
quotient_o <= {DATA_WIDTH{1'b1}}; // Max unsigned
|
||||
end
|
||||
// Remainder for div by zero is often the original dividend.
|
||||
// dividend_abs_reg was loaded with original dividend_i if div_by_zero was detected early.
|
||||
// For signed remainder, apply original_dividend_sign.
|
||||
if (is_signed_mode_reg && original_dividend_sign && dividend_abs_reg != 0) begin
|
||||
remainder_o <= -dividend_abs_reg;
|
||||
end else begin
|
||||
remainder_o <= dividend_abs_reg; // Which was set to dividend_i in S_IDLE for div_by_zero
|
||||
end
|
||||
`endif
|
||||
|
||||
end else begin
|
||||
div_by_zero_o <= 1'b0;
|
||||
// quotient_o and remainder_o already set by S_ADJUST_SIGN
|
||||
end
|
||||
// busy_o will be de-asserted when FSM actually transitions from S_FINISH to S_IDLE
|
||||
// (handled at the top of the clocked always block)
|
||||
end // S_FINISH
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
109
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/m_ext_unit.v
Normal file
109
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/m_ext_unit.v
Normal file
@@ -0,0 +1,109 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/18 00:30:20
|
||||
// Design Name:
|
||||
// Module Name: m_ext_unit
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Module to encapsulate multiplier and divider units.
|
||||
//
|
||||
// Dependencies: multiplier, divider
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module m_ext_unit(
|
||||
// Global Signals
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
input [ 7:0] m_ext_op_i,
|
||||
input [31:0] m_ext_src1_i,
|
||||
input [31:0] m_ext_src2_i,
|
||||
|
||||
output [31:0] m_ext_result_o,
|
||||
output m_ext_valid_o,
|
||||
|
||||
output m_ext_stall_o
|
||||
);
|
||||
|
||||
reg [ 7:0] m_ext_op;
|
||||
reg m_ext_valid;
|
||||
|
||||
wire [ 3:0] div_op;
|
||||
wire [ 4:0] mult_op;
|
||||
|
||||
// Multiplier Interface
|
||||
wire [63:0] mult_product;
|
||||
wire mult_done;
|
||||
wire mult_busy;
|
||||
|
||||
// Divider Interface
|
||||
wire [31:0] div_quotient;
|
||||
wire [31:0] div_remainder;
|
||||
wire div_done;
|
||||
wire div_busy;
|
||||
wire div_by_zero;
|
||||
|
||||
assign div_op = m_ext_op_i[3:0];
|
||||
assign mult_op = m_ext_op_i[7:4];
|
||||
|
||||
// Instantiate Multiplier
|
||||
multiplier u_multiplier (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
.start_i (!m_ext_valid && |mult_op),
|
||||
.signed_mode_i ({mult_op[1], mult_op[2] || mult_op[3]}),
|
||||
.operand_a_i (m_ext_src1_i),
|
||||
.operand_b_i (m_ext_src2_i),
|
||||
.product_o (mult_product),
|
||||
.done_o (mult_done),
|
||||
.busy_o (mult_busy)
|
||||
);
|
||||
|
||||
// Instantiate Divider
|
||||
divider u_divider (
|
||||
.clk_i (clk_i),
|
||||
.rstn_i (rstn_i),
|
||||
.start_i (!m_ext_valid && |div_op),
|
||||
.signed_mode_i (div_op[1] || div_op[3]),
|
||||
.dividend_i (m_ext_src1_i),
|
||||
.divisor_i (m_ext_src2_i),
|
||||
.quotient_o (div_quotient),
|
||||
.remainder_o (div_remainder),
|
||||
.done_o (div_done),
|
||||
.busy_o (div_busy),
|
||||
.div_by_zero_o (div_by_zero)
|
||||
);
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
m_ext_valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
m_ext_valid <= mult_done || div_done;
|
||||
end
|
||||
end
|
||||
|
||||
// If any m_ext_op_i bit is set (meaning an operation is requested for the current cycle),
|
||||
// or if either the multiplier or divider is busy from a previous start,
|
||||
// then the m_ext_unit should signal stall.
|
||||
assign m_ext_stall_o = !m_ext_valid && (|m_ext_op_i || mult_busy || div_busy);
|
||||
assign m_ext_valid_o = m_ext_valid;
|
||||
assign m_ext_result_o = ({32{m_ext_op_i[7]}} & mult_product[31:0 ]) // MUL
|
||||
| ({32{m_ext_op_i[6]}} & mult_product[63:32]) // MULH
|
||||
| ({32{m_ext_op_i[5]}} & mult_product[63:32]) // MULHSU
|
||||
| ({32{m_ext_op_i[4]}} & mult_product[63:32]) // MULHU
|
||||
| ({32{m_ext_op_i[3]}} & div_quotient ) // DIV
|
||||
| ({32{m_ext_op_i[2]}} & div_quotient ) // DIVU
|
||||
| ({32{m_ext_op_i[1]}} & div_remainder ) // REM
|
||||
| ({32{m_ext_op_i[0]}} & div_remainder );// REMU
|
||||
|
||||
endmodule
|
||||
231
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/multiplier.v
Normal file
231
rv_cpu.srcs/sources_1/new/sub_unit/m_ext_unit/multiplier.v
Normal file
@@ -0,0 +1,231 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 23:37:37
|
||||
// Design Name:
|
||||
// Module Name: multiplier
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module multiplier(
|
||||
// Inputs
|
||||
input wire clk_i,
|
||||
input wire rstn_i,
|
||||
input wire start_i, // Start signal for multiplication
|
||||
input wire [ 1:0] signed_mode_i, // 0 for unsigned, 1 for signed
|
||||
input wire [31:0] operand_a_i, // 32-bit Operand A (Multiplicand)
|
||||
input wire [31:0] operand_b_i, // 32-bit Operand B (Multiplier)
|
||||
|
||||
// Outputs
|
||||
output reg [63:0] product_o, // 64-bit Product
|
||||
output reg done_o, // Calculation done signal
|
||||
output reg busy_o // Multiplier is busy
|
||||
// No div_by_zero for multiplier
|
||||
);
|
||||
|
||||
localparam DATA_WIDTH = 32;
|
||||
localparam PRODUCT_WIDTH = 64;
|
||||
|
||||
// FSM States
|
||||
localparam S_IDLE = 3'd0;
|
||||
localparam S_PREPARE = 3'd1;
|
||||
localparam S_MULTIPLY_STEP = 3'd2;
|
||||
localparam S_ADJUST_SIGN = 3'd3;
|
||||
localparam S_FINISH = 3'd4;
|
||||
|
||||
reg [2:0] current_state_reg, next_state_reg;
|
||||
|
||||
// Internal Registers for algorithm
|
||||
reg [DATA_WIDTH-1:0] m_reg; // Stores Multiplicand's absolute value
|
||||
reg [DATA_WIDTH-1:0] q_reg; // Stores Multiplier's absolute value, shifts right
|
||||
reg [DATA_WIDTH-1:0] acc_reg; // Accumulator for upper part of product
|
||||
|
||||
reg [5:0] iter_count_reg; // Iteration counter (0 to DATA_WIDTH-1)
|
||||
|
||||
reg operand_a_sign_reg;
|
||||
reg operand_b_sign_reg;
|
||||
reg [1:0] is_signed_mode_reg_internal;
|
||||
|
||||
// Temporary registers for calculations within clocked always block
|
||||
reg [DATA_WIDTH:0] adder_result_temp; // Holds {carry, sum} from ACC + M
|
||||
reg [DATA_WIDTH-1:0] final_prod_abs_q_part_temp;
|
||||
reg [DATA_WIDTH-1:0] final_prod_abs_acc_part_temp;
|
||||
|
||||
reg [PRODUCT_WIDTH-1:0] final_product_abs;
|
||||
reg final_product_sign;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// FSM State Register
|
||||
//--------------------------------------------------------------------------
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
current_state_reg <= S_IDLE;
|
||||
end else begin
|
||||
current_state_reg <= next_state_reg;
|
||||
end
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// FSM Next State Logic & Combinational Output (done_o)
|
||||
//--------------------------------------------------------------------------
|
||||
always @(*) begin // Verilog-2001: sensitive to all RHS signals
|
||||
next_state_reg = current_state_reg; // Default
|
||||
done_o = 1'b0; // Default
|
||||
|
||||
case (current_state_reg)
|
||||
S_IDLE: begin
|
||||
if (start_i) begin
|
||||
next_state_reg = S_PREPARE;
|
||||
end
|
||||
end
|
||||
S_PREPARE: begin
|
||||
next_state_reg = S_MULTIPLY_STEP;
|
||||
end
|
||||
S_MULTIPLY_STEP: begin
|
||||
if (iter_count_reg == DATA_WIDTH - 1) begin // After N iterations (0 to N-1)
|
||||
next_state_reg = S_ADJUST_SIGN;
|
||||
end else begin
|
||||
next_state_reg = S_MULTIPLY_STEP; // Continue iteration
|
||||
end
|
||||
end
|
||||
S_ADJUST_SIGN: begin
|
||||
next_state_reg = S_FINISH;
|
||||
end
|
||||
S_FINISH: begin
|
||||
done_o = 1'b1; // Assert done for one cycle
|
||||
next_state_reg = S_IDLE;
|
||||
end
|
||||
default: begin
|
||||
next_state_reg = S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Datapath Logic (Sequential - Register Updates)
|
||||
//--------------------------------------------------------------------------
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
busy_o <= 1'b0;
|
||||
product_o <= {PRODUCT_WIDTH{1'b0}};
|
||||
|
||||
m_reg <= {DATA_WIDTH{1'b0}};
|
||||
q_reg <= {DATA_WIDTH{1'b0}};
|
||||
acc_reg <= {DATA_WIDTH{1'b0}};
|
||||
iter_count_reg <= 6'd0;
|
||||
|
||||
operand_a_sign_reg <= 1'b0;
|
||||
operand_b_sign_reg <= 1'b0;
|
||||
is_signed_mode_reg_internal <= 2'b0;
|
||||
end else begin
|
||||
// busy_o is set high when IDLE sees start_i
|
||||
// busy_o is set low when FSM transitions out of S_FINISH
|
||||
if (current_state_reg == S_FINISH && next_state_reg == S_IDLE) begin
|
||||
busy_o <= 1'b0;
|
||||
end
|
||||
|
||||
case (current_state_reg)
|
||||
S_IDLE: begin
|
||||
if (start_i) begin
|
||||
busy_o <= 1'b1;
|
||||
product_o <= {PRODUCT_WIDTH{1'b0}}; // Clear previous product
|
||||
|
||||
is_signed_mode_reg_internal <= signed_mode_i;
|
||||
if (signed_mode_i[0]) begin
|
||||
operand_a_sign_reg <= operand_a_i[DATA_WIDTH-1];
|
||||
operand_b_sign_reg <= operand_b_i[DATA_WIDTH-1];
|
||||
m_reg <= operand_a_i[DATA_WIDTH-1] ? -operand_a_i : operand_a_i; // Abs A
|
||||
q_reg <= operand_b_i[DATA_WIDTH-1] ? -operand_b_i : operand_b_i; // Abs B
|
||||
end
|
||||
else if(signed_mode_i[1]) begin
|
||||
operand_a_sign_reg <= operand_a_i[DATA_WIDTH-1];
|
||||
operand_b_sign_reg <= 1'b0; // Unused in unsigned mode
|
||||
m_reg <= operand_a_i[DATA_WIDTH-1] ? -operand_a_i : operand_a_i; // Abs A
|
||||
q_reg <= operand_b_i; // B is unsigned
|
||||
end
|
||||
else begin
|
||||
operand_a_sign_reg <= 1'b0; // Unused
|
||||
operand_b_sign_reg <= 1'b0; // Unused
|
||||
m_reg <= operand_a_i;
|
||||
q_reg <= operand_b_i;
|
||||
end
|
||||
acc_reg <= {DATA_WIDTH{1'b0}}; // ACC = 0
|
||||
iter_count_reg <= 6'd0;
|
||||
end
|
||||
end // S_IDLE
|
||||
|
||||
S_PREPARE: begin
|
||||
// Data loading happened in S_IDLE based on start_i.
|
||||
// This state ensures one cycle for setup before iterations.
|
||||
end
|
||||
|
||||
S_MULTIPLY_STEP: begin
|
||||
if (iter_count_reg < DATA_WIDTH) begin
|
||||
// Calculate ACC + M if Q[0] is 1
|
||||
if (q_reg[0] == 1'b1) begin
|
||||
// {Carry, Sum} = ACC + M
|
||||
adder_result_temp = {1'b0, acc_reg} + {1'b0, m_reg}; // Zero-extend for N+1 bit sum
|
||||
end else begin
|
||||
adder_result_temp = {1'b0, acc_reg}; // ACC + 0
|
||||
end
|
||||
|
||||
// Shift right {Carry_from_adder, ACC_from_adder, Q}
|
||||
// New ACC MSB is carry_from_adder
|
||||
// New Q MSB is ACC_from_adder LSB
|
||||
acc_reg <= {adder_result_temp[DATA_WIDTH], adder_result_temp[DATA_WIDTH-1:1]};
|
||||
q_reg <= {adder_result_temp[0], q_reg[DATA_WIDTH-1:1]};
|
||||
|
||||
iter_count_reg <= iter_count_reg + 1;
|
||||
end
|
||||
end // S_MULTIPLY_STEP
|
||||
|
||||
S_ADJUST_SIGN: begin
|
||||
// Iteration complete. {acc_reg, q_reg} is the absolute product.
|
||||
final_prod_abs_acc_part_temp = acc_reg;
|
||||
final_prod_abs_q_part_temp = q_reg;
|
||||
// product_o will be assigned in S_FINISH after sign adjustment
|
||||
end // S_ADJUST_SIGN
|
||||
|
||||
S_FINISH: begin
|
||||
final_product_abs = {final_prod_abs_acc_part_temp, final_prod_abs_q_part_temp};
|
||||
|
||||
// Check for signed multiplication modes
|
||||
if (is_signed_mode_reg_internal[0]) begin // Mode: operand_a signed, operand_b signed (e.g., MULH)
|
||||
final_product_sign = operand_a_sign_reg ^ operand_b_sign_reg;
|
||||
if (final_product_sign && final_product_abs != {PRODUCT_WIDTH{1'b0}}) begin
|
||||
product_o <= -final_product_abs; // Two's complement
|
||||
end else begin
|
||||
product_o <= final_product_abs;
|
||||
end
|
||||
end else if (is_signed_mode_reg_internal[1]) begin // Mode: operand_a signed, operand_b unsigned (e.g., MULHSU)
|
||||
// For MULHSU, only operand_a's sign affects the final product's sign.
|
||||
// operand_b is treated as unsigned, so its original sign bit (operand_b_sign_reg) is irrelevant here.
|
||||
final_product_sign = operand_a_sign_reg; // Sign is determined by operand_a only
|
||||
if (final_product_sign && final_product_abs != {PRODUCT_WIDTH{1'b0}}) begin
|
||||
product_o <= -final_product_abs; // Two's complement
|
||||
end else begin
|
||||
product_o <= final_product_abs;
|
||||
end
|
||||
end else begin // Mode: Both unsigned (e.g., MULHU or standard MUL lower part)
|
||||
product_o <= final_product_abs;
|
||||
end
|
||||
// busy_o will be de-asserted when FSM actually transitions from S_FINISH to S_IDLE
|
||||
end // S_FINISH
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
67
rv_cpu.srcs/sources_1/new/sub_unit/pre_if_stage.v
Normal file
67
rv_cpu.srcs/sources_1/new/sub_unit/pre_if_stage.v
Normal file
@@ -0,0 +1,67 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/19 20:28:17
|
||||
// Design Name:
|
||||
// Module Name: pre_if_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module pre_if_stage(
|
||||
input rstn_i,
|
||||
|
||||
input pre_fs_to_fs_ready_i, // no use in this module, cause pre_if_stage is the first stage
|
||||
output [31:0] pre_fs_to_fs_pc_o,
|
||||
output pre_fs_to_fs_valid_o,
|
||||
|
||||
input [31:0] fs_pc_i,
|
||||
|
||||
input [31:0] br_target_i,
|
||||
input br_taken_i,
|
||||
|
||||
input load_stall_i,
|
||||
input m_ext_stall_i,
|
||||
input a_ext_stall_i,
|
||||
|
||||
output inst_sram_en_o,
|
||||
output [ 3:0] inst_sram_wen_o,
|
||||
output [31:0] inst_sram_addr_o,
|
||||
output [31:0] inst_sram_data_o
|
||||
);
|
||||
|
||||
wire pre_fs_valid;
|
||||
wire [31:0] pre_fs_next_pc;
|
||||
|
||||
wire pre_fs_pipeline_stall;
|
||||
|
||||
wire [31:0] seq_pc;
|
||||
|
||||
assign pre_fs_pipeline_stall = load_stall_i || m_ext_stall_i || a_ext_stall_i;
|
||||
|
||||
assign seq_pc = fs_pc_i + 4;
|
||||
assign pre_fs_next_pc = br_taken_i ? br_target_i :
|
||||
pre_fs_pipeline_stall ? fs_pc_i :
|
||||
seq_pc;
|
||||
|
||||
assign pre_fs_valid = rstn_i && !pre_fs_pipeline_stall;
|
||||
assign pre_fs_to_fs_pc_o = pre_fs_next_pc;
|
||||
assign pre_fs_to_fs_valid_o = pre_fs_valid;
|
||||
|
||||
assign inst_sram_en_o = pre_fs_valid;
|
||||
assign inst_sram_wen_o = 4'b0000; // Read only
|
||||
assign inst_sram_addr_o = pre_fs_next_pc;
|
||||
assign inst_sram_data_o = 32'h00000000; // No write data needed
|
||||
endmodule
|
||||
63
rv_cpu.srcs/sources_1/new/sub_unit/reg_file.v
Normal file
63
rv_cpu.srcs/sources_1/new/sub_unit/reg_file.v
Normal file
@@ -0,0 +1,63 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 02:15:22
|
||||
// Design Name:
|
||||
// Module Name: reg_file
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module reg_file(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
// READ PORT 1
|
||||
input [ 4:0] raddr1_i,
|
||||
output [31:0] rdata1_o,
|
||||
// READ PORT 2
|
||||
input [ 4:0] raddr2_i,
|
||||
output [31:0] rdata2_o,
|
||||
// WRITE PORT
|
||||
input we_i,
|
||||
input [ 4:0] waddr_i,
|
||||
input [31:0] wdata_i
|
||||
);
|
||||
|
||||
reg [31:0] register[31:0];
|
||||
integer i = 0;
|
||||
|
||||
//WRITE
|
||||
always @(posedge clk_i) begin
|
||||
if (!rstn_i) begin
|
||||
for(i = 0; i < 32; i = i + 1) begin
|
||||
register[i] <= 32'b0;
|
||||
end
|
||||
end
|
||||
else if (we_i && (waddr_i != 5'b0)) begin
|
||||
register[waddr_i]<= wdata_i;
|
||||
end
|
||||
end
|
||||
|
||||
//READ OUT 1
|
||||
assign rdata1_o = ( raddr1_i == 5'b0 ) ? 32'b0 :
|
||||
(we_i & (raddr1_i == waddr_i)) ? wdata_i :
|
||||
register[raddr1_i];
|
||||
|
||||
//READ OUT 2
|
||||
assign rdata2_o = ( raddr2_i == 5'b0 ) ? 32'b0 :
|
||||
(we_i & (raddr2_i == waddr_i)) ? wdata_i :
|
||||
register[raddr2_i];
|
||||
|
||||
endmodule
|
||||
98
rv_cpu.srcs/sources_1/new/wb_stage.v
Normal file
98
rv_cpu.srcs/sources_1/new/wb_stage.v
Normal file
@@ -0,0 +1,98 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2025/05/17 12:29:36
|
||||
// Design Name:
|
||||
// Module Name: wb_stage
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module wb_stage #(
|
||||
parameter MS_TO_WS_BUS_WIDTH = 70,
|
||||
parameter WS_TO_DS_BUS_WIDTH = 38
|
||||
)(
|
||||
input clk_i,
|
||||
input rstn_i,
|
||||
|
||||
output ms_to_ws_bus_ready_o,
|
||||
input [MS_TO_WS_BUS_WIDTH-1:0] ms_to_ws_bus_data_i,
|
||||
input ms_to_ws_bus_valid_i,
|
||||
|
||||
output [WS_TO_DS_BUS_WIDTH-1:0] ws_to_ds_bus_data_o,
|
||||
output ws_to_ds_bus_valid_o,
|
||||
|
||||
output [31:0] debug_wb_pc_o,
|
||||
output [ 3:0] debug_wb_rf_wen_o,
|
||||
output [ 4:0] debug_wb_rf_waddr_o,
|
||||
output [31:0] debug_wb_rf_wdata_o
|
||||
);
|
||||
|
||||
reg ms_to_ws_bus_valid;
|
||||
reg [MS_TO_WS_BUS_WIDTH-1:0] ms_to_ws_bus_data;
|
||||
|
||||
wire ws_to_ds_bus_valid;
|
||||
wire ws_rf_we;
|
||||
wire [ 4:0] ws_rf_addr;
|
||||
wire [31:0] ws_rf_wdata;
|
||||
wire [31:0] ws_pc;
|
||||
|
||||
assign {
|
||||
ws_rf_we, // 69:69
|
||||
ws_rf_addr, // 68:64
|
||||
ws_rf_wdata, // 63:32
|
||||
ws_pc // 31:0
|
||||
} = ms_to_ws_bus_data;
|
||||
|
||||
assign ws_to_ds_bus_valid = 1'b1;
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
ms_to_ws_bus_valid <= 1'b0;
|
||||
end
|
||||
else if(ms_to_ws_bus_ready_o) begin
|
||||
ms_to_ws_bus_valid <= ms_to_ws_bus_valid_i;
|
||||
end
|
||||
else begin
|
||||
ms_to_ws_bus_valid <= ms_to_ws_bus_valid;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
ms_to_ws_bus_data <= {MS_TO_WS_BUS_WIDTH{1'b0}};
|
||||
end
|
||||
else if(ms_to_ws_bus_valid_i && ms_to_ws_bus_ready_o) begin
|
||||
ms_to_ws_bus_data <= ms_to_ws_bus_data_i;
|
||||
end
|
||||
else begin
|
||||
ms_to_ws_bus_data <= ms_to_ws_bus_data;
|
||||
end
|
||||
end
|
||||
|
||||
assign ws_to_ds_bus_data_o = {
|
||||
ws_rf_we, // 37:37
|
||||
ws_rf_addr, // 36:32
|
||||
ws_rf_wdata // 31:0
|
||||
};
|
||||
|
||||
assign ms_to_ws_bus_ready_o = !ms_to_ws_bus_valid || ws_to_ds_bus_valid;
|
||||
assign ws_to_ds_bus_valid_o = ms_to_ws_bus_valid && ws_to_ds_bus_valid;
|
||||
|
||||
assign debug_wb_pc_o = ws_pc;
|
||||
assign debug_wb_rf_wen_o = {4{ms_to_ws_bus_valid && ws_rf_we}};
|
||||
assign debug_wb_rf_waddr_o = ws_rf_addr;
|
||||
assign debug_wb_rf_wdata_o = ws_rf_wdata;
|
||||
endmodule
|
||||
302
rv_cpu.xpr
Normal file
302
rv_cpu.xpr
Normal file
@@ -0,0 +1,302 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Product Version: Vivado v2022.2.2 (64-bit) -->
|
||||
<!-- -->
|
||||
<!-- Copyright 1986-2023 Xilinx, Inc. All Rights Reserved. -->
|
||||
|
||||
<Project Version="7" Minor="61" Path="D:/Project/Vivado/AXKU15/rv_cpu/rv_cpu.xpr">
|
||||
<DefaultLaunch Dir="$PRUNDIR"/>
|
||||
<Configuration>
|
||||
<Option Name="Id" Val="9057efca55624d1197d61829bb5a855e"/>
|
||||
<Option Name="Part" Val="xcku15p-ffve1517-2-i"/>
|
||||
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
|
||||
<Option Name="CompiledLibDirXSim" Val=""/>
|
||||
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
|
||||
<Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
|
||||
<Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
|
||||
<Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
|
||||
<Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
|
||||
<Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
|
||||
<Option Name="SimulatorInstallDirModelSim" Val=""/>
|
||||
<Option Name="SimulatorInstallDirQuesta" Val=""/>
|
||||
<Option Name="SimulatorInstallDirXcelium" Val=""/>
|
||||
<Option Name="SimulatorInstallDirVCS" Val=""/>
|
||||
<Option Name="SimulatorInstallDirRiviera" Val=""/>
|
||||
<Option Name="SimulatorInstallDirActiveHdl" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirModelSim" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirQuesta" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirXcelium" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirVCS" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirRiviera" Val=""/>
|
||||
<Option Name="SimulatorGccInstallDirActiveHdl" Val=""/>
|
||||
<Option Name="SimulatorVersionXsim" Val="2022.2"/>
|
||||
<Option Name="SimulatorVersionModelSim" Val="2022.2"/>
|
||||
<Option Name="SimulatorVersionQuesta" Val="2022.2"/>
|
||||
<Option Name="SimulatorVersionXcelium" Val="21.09.009"/>
|
||||
<Option Name="SimulatorVersionVCS" Val="S-2021.09"/>
|
||||
<Option Name="SimulatorVersionRiviera" Val="2022.04"/>
|
||||
<Option Name="SimulatorVersionActiveHdl" Val="13.0"/>
|
||||
<Option Name="SimulatorGccVersionXsim" Val="6.2.0"/>
|
||||
<Option Name="SimulatorGccVersionModelSim" Val="7.4.0"/>
|
||||
<Option Name="SimulatorGccVersionQuesta" Val="7.4.0"/>
|
||||
<Option Name="SimulatorGccVersionXcelium" Val="9.3.0"/>
|
||||
<Option Name="SimulatorGccVersionVCS" Val="9.2.0"/>
|
||||
<Option Name="SimulatorGccVersionRiviera" Val="9.3.0"/>
|
||||
<Option Name="SimulatorGccVersionActiveHdl" Val="9.3.0"/>
|
||||
<Option Name="BoardPart" Val=""/>
|
||||
<Option Name="ActiveSimSet" Val="sim_1"/>
|
||||
<Option Name="DefaultLib" Val="xil_defaultlib"/>
|
||||
<Option Name="ProjectType" Val="Default"/>
|
||||
<Option Name="IPOutputRepo" Val="$PCACHEDIR/ip"/>
|
||||
<Option Name="IPDefaultOutputPath" Val="$PGENDIR/sources_1"/>
|
||||
<Option Name="IPCachePermission" Val="read"/>
|
||||
<Option Name="IPCachePermission" Val="write"/>
|
||||
<Option Name="EnableCoreContainer" Val="FALSE"/>
|
||||
<Option Name="EnableResourceEstimation" Val="FALSE"/>
|
||||
<Option Name="SimCompileState" Val="TRUE"/>
|
||||
<Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
|
||||
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="1"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
<Option Name="WTVcsLaunchSim" Val="0"/>
|
||||
<Option Name="WTRivieraLaunchSim" Val="0"/>
|
||||
<Option Name="WTActivehdlLaunchSim" Val="0"/>
|
||||
<Option Name="WTXSimExportSim" Val="0"/>
|
||||
<Option Name="WTModelSimExportSim" Val="0"/>
|
||||
<Option Name="WTQuestaExportSim" Val="0"/>
|
||||
<Option Name="WTIesExportSim" Val="0"/>
|
||||
<Option Name="WTVcsExportSim" Val="0"/>
|
||||
<Option Name="WTRivieraExportSim" Val="0"/>
|
||||
<Option Name="WTActivehdlExportSim" Val="0"/>
|
||||
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
|
||||
<Option Name="XSimRadix" Val="hex"/>
|
||||
<Option Name="XSimTimeUnit" Val="ns"/>
|
||||
<Option Name="XSimArrayDisplayLimit" Val="1024"/>
|
||||
<Option Name="XSimTraceLimit" Val="65536"/>
|
||||
<Option Name="SimTypes" Val="rtl"/>
|
||||
<Option Name="SimTypes" Val="bfm"/>
|
||||
<Option Name="SimTypes" Val="tlm"/>
|
||||
<Option Name="SimTypes" Val="tlm_dpi"/>
|
||||
<Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
|
||||
<Option Name="DcpsUptoDate" Val="TRUE"/>
|
||||
<Option Name="ClassicSocBoot" Val="FALSE"/>
|
||||
<Option Name="LocalIPRepoLeafDirName" Val="ip_repo"/>
|
||||
</Configuration>
|
||||
<FileSets Version="1" Minor="31">
|
||||
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1" RelGenDir="$PGENDIR/sources_1">
|
||||
<Filter Type="Srcs"/>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/alu.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/m_ext_unit/divider.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/exe_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/id_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/if_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/inst_decoder.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/m_ext_unit/m_ext_unit.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/mem_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/m_ext_unit/multiplier.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/pre_if_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/reg_file.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/wb_stage.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/cpu_top.v">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PSRCDIR/sources_1/new/sub_unit/csr_reg_file.v">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="cpu_top"/>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1">
|
||||
<Filter Type="Constrs"/>
|
||||
<Config>
|
||||
<Option Name="ConstrsType" Val="XDC"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1" RelGenDir="$PGENDIR/sim_1">
|
||||
<Filter Type="Srcs"/>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="cpu_top"/>
|
||||
<Option Name="TopLib" Val="xil_defaultlib"/>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
<Option Name="TransportPathDelay" Val="0"/>
|
||||
<Option Name="TransportIntDelay" Val="0"/>
|
||||
<Option Name="SelectedSimModel" Val="rtl"/>
|
||||
<Option Name="PamDesignTestbench" Val=""/>
|
||||
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
|
||||
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
|
||||
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
|
||||
<Option Name="SrcSet" Val="sources_1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1" RelGenDir="$PGENDIR/utils_1">
|
||||
<Filter Type="Utils"/>
|
||||
<Config>
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
</FileSets>
|
||||
<Simulators>
|
||||
<Simulator Name="XSim">
|
||||
<Option Name="Description" Val="Vivado Simulator"/>
|
||||
<Option Name="CompiledLib" Val="0"/>
|
||||
</Simulator>
|
||||
<Simulator Name="ModelSim">
|
||||
<Option Name="Description" Val="ModelSim Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Questa">
|
||||
<Option Name="Description" Val="Questa Advanced Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="Riviera">
|
||||
<Option Name="Description" Val="Riviera-PRO Simulator"/>
|
||||
</Simulator>
|
||||
<Simulator Name="ActiveHDL">
|
||||
<Option Name="Description" Val="Active-HDL Simulator"/>
|
||||
</Simulator>
|
||||
</Simulators>
|
||||
<Runs Version="1" Minor="19">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xcku15p-ffve1517-2-i" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xcku15p-ffve1517-2-i" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
</Runs>
|
||||
<Board/>
|
||||
<DashboardSummary Version="1" Minor="0">
|
||||
<Dashboards>
|
||||
<Dashboard Name="default_dashboard">
|
||||
<Gadgets>
|
||||
<Gadget Name="drc_1" Type="drc" Version="1" Row="2" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_drc_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="methodology_1" Type="methodology" Version="1" Row="2" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_methodology_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="power_1" Type="power" Version="1" Row="1" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_power_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
|
||||
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
|
||||
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
|
||||
</Gadget>
|
||||
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
|
||||
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
|
||||
</Gadget>
|
||||
</Gadgets>
|
||||
</Dashboard>
|
||||
<CurrentDashboard>default_dashboard</CurrentDashboard>
|
||||
</Dashboards>
|
||||
</DashboardSummary>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user