Added all RiscV CSR manipulation instructions, major update and cleanup

This commit is contained in:
Sven Stucki 2015-06-01 01:01:33 +02:00
parent c0c5b5f8a1
commit 60a842c81d
7 changed files with 380 additions and 152 deletions

View file

@ -79,8 +79,9 @@ module controller
output logic prepost_useincr_o, // When not active bypass the alu result=op_a
input logic data_misaligned_i,
output logic sp_we_o, // Write enable to special purpose register
input logic sp_we_ex_i, // Manipulated sp_we from ex stage : FW
// CSR manipulation
output logic csr_access_o,
output logic [1:0] csr_op_o,
// LD/ST unit signals
output logic data_we_o, // Write enable to data memory
@ -171,8 +172,6 @@ module controller
logic lsu_stall;
logic misalign_stall;
logic mtspr_stall;
logic mfspr_stall;
logic instr_ack_stall;
logic load_stall;
logic jr_stall;
@ -225,7 +224,7 @@ module controller
mult_use_carry_o = 1'b0;
mult_mac_en_o = 1'b0;
regfile_wdata_mux_sel_o = 1'b1;
regfile_wdata_mux_sel_o = 1'b1; // TODO: Remove, no longer used
regfile_we = 1'b0;
regfile_alu_we = 1'b0;
regfile_alu_waddr_mux_sel_o = 2'b01;
@ -237,7 +236,8 @@ module controller
hwloop_cnt_mux_sel_o = 2'b00;
immediate_mux_sel_o = `IMM_I;
sp_we_o = 1'b0;
csr_access_o = 1'b0;
csr_op_o = `CSR_OP_NONE;
data_we = 1'b0;
data_type_o = 2'b00;
@ -311,6 +311,7 @@ module controller
begin
unique case (instr_rdata_i[6:0])
/*
`OPCODE_CUST0: begin // Custom-0 opcode: Get core id
// TODO: Temporary hack?
alu_op_a_mux_sel_o = `OP_A_ZERO;
@ -324,6 +325,7 @@ module controller
// TODO: Replace with WFI instruction as soon as compiler support available
pipe_flush_o = 1'b1;
end
*/
//////////////////////////////////////
@ -431,7 +433,6 @@ module controller
immediate_mux_sel_o = `IMM_I;
alu_operator = `ALU_ADD;
data_req = 1'b1;
regfile_wdata_mux_sel_o = 1'b1;
regfile_we = 1'b1;
rega_used = 1'b1;
data_type_o = 2'b00;
@ -934,63 +935,56 @@ module controller
*/
`OPCODE_SYSTEM: begin
unique case (instr_rdata_i) inside
`INSTR_EBREAK: begin
// debugger trap
trap_insn_o = 1'b1;
end
`INSTR_ERET: begin
pc_mux_sel_o = `PC_ERET;
restore_sr_o = 1'b1; // TODO: Check if needed
clear_isr_running_o = 1'b1; // TODO: Check if needed
end
`INSTR_WFI: begin
// flush pipeline
pipe_flush_o = 1'b1;
end
default: illegal_insn_o = 1'b1;
endcase // unique case (instr_rdata_i)
end
/*
`OPCODE_MTSPR: begin // Move To Special-Purpose Register
alu_operator = `ALU_OR;
alu_op_b_mux_sel_o = `OP_B_IMM;
sp_we_o = 1'b1;
rega_used = 1'b1;
regb_used = 1'b1;
end
`OPCODE_MFSPR: begin // Move From Special-Purpose Register
alu_operator = `ALU_OR;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_16;
regfile_wdata_mux_sel_o = 1'b0;
regfile_we = 1'b1;
rega_used = 1'b1;
end
`OPCODE_SYNC:
begin
if (instr_rdata_i[25] == 1'b1) // sync operation
begin // l.psync, flush pipeline. Actually this also does l.msync
pipe_flush_o = 1'b1;
if (instr_rdata_i[14:12] == 3'b000)
begin
// non CSR realted SYSTEM instructions
unique case (instr_rdata_i) inside
`INSTR_EBREAK: begin
// debugger trap
trap_insn_o = 1'b1;
end
`INSTR_ERET: begin
pc_mux_sel_o = `PC_ERET;
clear_isr_running_o = 1'b1;
end
`INSTR_WFI: begin
// flush pipeline
pipe_flush_o = 1'b1;
end
default: illegal_insn_o = 1'b1;
endcase // unique case (instr_rdata_i)
end
else
begin
if (instr_rdata_i[24:16] == 9'h100)
begin
// l.trap
// Currently we ignore the immediate
trap_insn_o = 1'b1;
// instructions to read/modify CSRs
csr_access_o = 1'b1;
regfile_alu_we = 1'b1;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_I; // CSR address is encoded in I imm
if (instr_rdata_i[14] == 1'b1) begin
// rs1 field is immediate
alu_op_a_mux_sel_o = `OP_A_ZIMM;
end else begin
rega_used = 1'b1;
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
end
else
illegal_insn_o = 1'b1;
unique case (instr_rdata_i[13:12])
2'b01: csr_op_o = `CSR_OP_WRITE;
2'b10: csr_op_o = `CSR_OP_SET;
2'b11: csr_op_o = `CSR_OP_CLEAR;
default: illegal_insn_o = 1'b1;
endcase
end
end
/*
///////////////////////////////////////////////
// _ ___ ___ ___ ___ ____ //
// | | | \ \ / / | / _ \ / _ \| _ \ //
@ -1113,30 +1107,10 @@ module controller
////////////////////////////////////////////////////////////////////////////////////////////
always_comb
begin
mfspr_stall = 1'b0;
mtspr_stall = 1'b0;
load_stall = 1'b0;
jr_stall = 1'b0;
deassert_we = 1'b0;
/*
// Stall because of l.mfspr with dependency
if ((regfile_wdata_mux_sel_ex_i == 1'b0) && (regfile_we_ex_i == 1'b1) &&
((reg_d_ex_is_reg_a_id == 1'b1) || (reg_d_ex_is_reg_b_id == 1'b1) || (reg_d_ex_is_reg_c_id == 1'b1)) )
begin
deassert_we = 1'b1;
mfspr_stall = 1'b1;
end
// Stall because of l.mtspr (always...)
// mtspr in ex stage, normal instruction in id stage which can change an spr reg
if ((sp_we_ex_i == 1'b1) && (instr_rdata_i[31:26] != `OPCODE_MTSPR))
begin
deassert_we = 1'b1;
mtspr_stall = 1'b1;
end
*/
// Stall because of load operation
if ((data_req_ex_i == 1'b1) && (regfile_we_ex_i == 1'b1) &&
((reg_d_ex_is_reg_a_id == 1'b1) || (reg_d_ex_is_reg_b_id == 1'b1) || (reg_d_ex_is_reg_c_id == 1'b1)) )
@ -1200,8 +1174,8 @@ module controller
// we unstall the if_stage if the debug unit wants to set a new
// pc, so that the new value gets written into current_pc_if and is
// used by the instr_core_interface
stall_if_o = instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_halt | dbg_stall_i | (~pc_valid_i);
stall_id_o = instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_halt | dbg_stall_i;
stall_if_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_halt | dbg_stall_i | (~pc_valid_i);
stall_id_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_halt | dbg_stall_i;
stall_ex_o = instr_ack_stall | lsu_stall | dbg_stall_i;
stall_wb_o = lsu_stall | dbg_stall_i;
end

166
cs_registers.sv Normal file
View file

@ -0,0 +1,166 @@
////////////////////////////////////////////////////////////////////////////////
// Company: IIS @ ETHZ - Federal Institute of Technology //
// //
// Engineer: Sven Stucki - svstucki@student.ethz.ch.ch //
// //
// Additional contributions by: //
// //
// //
// Create Date: 25/05/2015 //
// Design Name: Pipelined Processor //
// Module Name: cs_registers.sv //
// Project Name: Processor //
// Language: SystemVerilog //
// //
// Description: Control and Status Registers (CSRs) loosely following the //
// RiscV draft priviledged instruction set spec (v1.7) //
// //
// //
// Revision: //
// //
// //
// //
////////////////////////////////////////////////////////////////////////////////
`include "defines.sv"
module cs_registers
(
// Clock and Reset
input logic clk,
input logic rst_n,
// Core and Cluster ID
input logic [4:0] core_id_i,
input logic [4:0] cluster_id_i,
// Interface to special purpose registers (SRAM like)
input logic [11:0] csr_addr_i,
input logic [31:0] csr_wdata_i,
input logic [1:0] csr_op_i,
output logic [31:0] csr_rdata_o,
// Interrupts
input logic [31:0] curr_pc_if_i,
input logic [31:0] curr_pc_id_i,
input logic save_pc_if_i,
input logic save_pc_id_i, // TODO: check if both IF/ID pc save is needed
output logic [31:0] epcr_o,
output logic irq_enable_o, // TODO: check if needed
// HWLoop Signals
input logic [`HWLOOP_REGS-1:0] [31:0] hwlp_start_addr_i,
input logic [`HWLOOP_REGS-1:0] [31:0] hwlp_end_addr_i,
input logic [`HWLOOP_REGS-1:0] [31:0] hwlp_counter_i,
output logic [31:0] hwlp_start_o,
output logic [31:0] hwlp_end_o,
output logic [31:0] hwlp_counter_o,
output logic [1:0] hwlp_regid_o,
output logic [2:0] hwlp_we_o,
// Signals for NPC register
output logic [31:0] npc_o, // TODO: check if needed
output logic set_npc_o // TODO: check if needed
);
logic is_constant;
logic is_register;
logic [31:0] constant_rdata_int;
logic [31:0] register_rdata_int;
logic is_readonly;
logic illegal_address;
// CSRs and index of CSR to access
int csr_index; // TODO: check synthesis result
logic [31:0] csr [0:`CSR_MAX_IDX];
assign is_readonly = (csr_addr_i[11:10] == 2'b11);
assign illegal_address = ~is_constant && ~is_register;
// output mux
always_comb
begin
csr_rdata_o = 32'bx;
if (is_constant == 1'b1)
csr_rdata_o = constant_rdata_int;
else if (is_register == 1'b1)
csr_rdata_o = register_rdata_int;
end
// address decoder for constant CSRs
always_comb
begin
is_constant = 1'b1;
unique case (csr_addr_i)
12'hF00: constant_rdata_int = 32'h00_00_01_00; // mcpuid: RV32I
12'hF01: constant_rdata_int = 32'h00_00_80_00; // mimpid: PULP3, anonymous source (no allocated ID)
12'hF10: constant_rdata_int = {22'b0, cluster_id_i, core_id_i}; // mhartid: unique hardware thread id
default: is_constant = 1'b0;
endcase
end
// address decoder for regular CSRs
always_comb
begin
is_register = 1'b1;
unique case (csr_addr_i)
12'h340: csr_index = `CSR_IDX_MSCRATCH;
12'h341: csr_index = `CSR_IDX_MEPC;
default: is_register = 1'b0;
endcase
end
assign register_rdata_int = csr[csr_index];
// directly output some registers
assign epcr_o = csr[`CSR_IDX_MEPC];
// actual registers
always_ff @(posedge clk, negedge rst_n)
begin
if (rst_n == 1'b0)
begin
csr <= '{default: 32'b0}; // new SV syntax TODO: check synthesis result
end
else
begin
// write CSR through instruction
if (is_readonly == 1'b0) begin
unique case (csr_op_i)
`CSR_OP_NONE: ;
`CSR_OP_WRITE: csr[csr_index] <= csr_wdata_i;
`CSR_OP_SET: csr[csr_index] <= csr_wdata_i | register_rdata_int;
`CSR_OP_CLEAR: csr[csr_index] <= csr_wdata_i & ~(register_rdata_int);
endcase
end
// writes from exception controller get priority
// write exception PC
if (save_pc_if_i == 1'b1)
csr[`CSR_IDX_MEPC] <= curr_pc_if_i;
else if (save_pc_id_i == 1'b1)
csr[`CSR_IDX_MEPC] <= curr_pc_id_i;
end
end
// synopsys translate_off
// make sure decoding works correctly
//assert property (!((is_constant == 1'b1) && (is_register == 1'b1))); // not supported by ModelSim :/
// synopsys translate_on
endmodule

View file

@ -35,10 +35,9 @@
// wb = writeback
// sp = special registers
`include "defines.sv"
module ex_stage
(
input logic clk,
@ -88,7 +87,9 @@ module ex_stage
input logic set_overflow_i,
input logic set_carry_i,
input logic sp_we_i,
// CSR access
input logic csr_access_i,
input logic [31:0] csr_rdata_i,
// Output of EX stage pipeline
@ -101,7 +102,6 @@ module ex_stage
output logic set_overflow_o,
output logic set_carry_o,
output logic [15:0] sp_addr_wb_o,
output logic [4:0] regfile_waddr_wb_o,
output logic regfile_wdata_mux_sel_wb_o,
output logic regfile_we_wb_o,
@ -111,8 +111,6 @@ module ex_stage
output logic [31:0] hwloop_end_data_o,
output logic [31:0] hwloop_cnt_data_o,
output logic sp_we_wb_o,
// Forwarding ports : to ID stage
output logic [4:0] regfile_alu_waddr_fw_o,
output logic regfile_alu_we_fw_o,
@ -149,7 +147,18 @@ module ex_stage
assign regfile_alu_we_fw_o = regfile_alu_we_i;
assign regfile_alu_waddr_fw_o = regfile_alu_waddr_i;
assign regfile_alu_wdata_fw_o = (mult_en_i == 1'b0) ? alu_result : mult_result;
always_comb
begin
regfile_alu_wdata_fw_o = alu_result;
if (mult_en_i == 1'b1)
regfile_alu_wdata_fw_o = mult_result;
if (csr_access_i == 1'b1)
regfile_alu_wdata_fw_o = csr_rdata_i;
end
// assign regfile_alu_wdata_fw_o = (mult_en_i == 1'b0) ? alu_result : mult_result;
// generate flags: goes to special purpose register
assign set_overflow_o = (stall_ex_i == 1'b0) ? set_overflow_i : 1'b0;
@ -244,23 +253,19 @@ module ex_stage
begin : EX_WB_Pipeline_Register
if (rst_n == 1'b0)
begin
sp_addr_wb_o <= 16'h0000;
regfile_waddr_wb_o <= 5'b0_0000;
regfile_wdata_mux_sel_wb_o <= 1'b0;
regfile_we_wb_o <= 1'b0;
regfile_rb_data_wb_o <= 32'h0000_0000;
sp_we_wb_o <= 1'b0;
end
else
begin
if (stall_wb_i == 1'b0)
begin
sp_addr_wb_o <= alu_result[15:0]; // this is only used for SPR address
regfile_we_wb_o <= regfile_we_i;
regfile_waddr_wb_o <= regfile_waddr_i;
regfile_wdata_mux_sel_wb_o <= regfile_wdata_mux_sel_i;
regfile_rb_data_wb_o <= regfile_rb_data_i;
sp_we_wb_o <= sp_we_i;
end
end
end

View file

@ -7,16 +7,17 @@
// Additional contributions by: //
// Igor Loi - igor.loi@unibo.it //
// Andreas Traber - atraber@student.ethz.ch //
// Sven Stucki - svstucki@student.ethz.ch //
// //
// //
// Create Date: 19/09/2013 //
// Design Name: Decode stage //
// Module Name: id_stage.sv //
// Project Name: OR10N //
// Project Name: RiscV //
// Language: SystemVerilog //
// //
// Description: Decode stage of the OR10N core. It decodes the instructions//
// and hosts the register file and the pipe controller //
// Description: Decode stage of the core. It decodes the instructions //
// and hosts the register file. //
// //
// Revision: //
// Revision v0.1 - File Created //
@ -38,8 +39,6 @@ module id_stage
input logic clk,
input logic rst_n,
input logic [4:0] core_id_i,
input logic fetch_enable_i,
output logic core_busy_o,
@ -106,7 +105,8 @@ module id_stage
output logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt_o,
output logic [31:0] hwloop_targ_addr_o,
output logic sp_we_ex_o,
output logic csr_access_ex_o,
output logic [1:0] csr_op_ex_o,
// Interface to load store unit
output logic data_we_ex_o,
@ -241,9 +241,6 @@ module id_stage
logic regfile_we_id;
logic [1:0] regfile_alu_waddr_mux_sel; // TODO: FixMe -> 1bit
// Special-Purpose Register Write Control
logic sp_we_id;
// Data Memory Control
logic data_we_id;
logic [1:0] data_type_id;
@ -260,6 +257,10 @@ module id_stage
logic hwloop_jump;
logic hwloop_enable;
// CSR control
logic csr_access;
logic [1:0] csr_op;
// Supervision Register
logic set_flag;
logic set_carry;
@ -295,6 +296,9 @@ module id_stage
assign imm_uj_type = { {20 {instr_rdata_i[31]}}, instr_rdata_i[19:12],
instr_rdata_i[20], instr_rdata_i[30:21], 1'b0 };
// immediate for CSR manipulatin (zero extended)
assign imm_z_type = { 27'b0, instr_rdata_i[`REG_S1] };
// source registers
assign regfile_addr_ra_id = instr_rdata_i[`REG_S1];
assign regfile_addr_rb_id = instr_rdata_i[`REG_S2];
@ -342,7 +346,7 @@ module id_stage
begin : hwloop_cnt_mux
case (hwloop_cnt_mux_sel)
2'b00: hwloop_cnt = 32'b0;
//2'b01: hwloop_cnt = immediate21z_id; // TODO: FixMe
//2'b01: hwloop_cnt = immediate21z_id; // TODO: FIXME use correct immediate when adding hwloops
//2'b10: hwloop_cnt = immediate13z_id;
2'b11: hwloop_cnt = operand_a_fw_id;
default: hwloop_cnt = 32'b0;
@ -388,6 +392,7 @@ module id_stage
default: alu_operand_a = operand_a_fw_id;
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
`OP_A_CURRPC: alu_operand_a = current_pc;
`OP_A_ZIMM: alu_operand_a = imm_z_type;
`OP_A_ZERO: alu_operand_a = 32'b0;
endcase; // case (alu_op_a_mux_sel)
end
@ -421,7 +426,6 @@ module id_stage
`IMM_S: immediate_b = imm_s_type;
`IMM_U: immediate_b = imm_u_type;
`IMM_HEX4: immediate_b = 32'h4;
`IMM_CID: immediate_b = core_id_i; // TODO: Temporary hack
default: immediate_b = 32'h4;
endcase; // case (immediate_mux_sel)
end
@ -432,7 +436,7 @@ module id_stage
case (alu_op_b_mux_sel)
default: operand_b = operand_b_fw_id;
`OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
//`OP_B_REGC_OR_FWD: operand_b = alu_operand_c;
// `OP_B_REGC_OR_FWD: operand_b = alu_operand_c;
`OP_B_IMM: operand_b = immediate_b;
endcase // case (alu_op_b_mux_sel)
end
@ -580,9 +584,9 @@ module id_stage
.prepost_useincr_o ( prepost_useincr ),
.data_misaligned_i ( data_misaligned_i ),
// SP register signals
.sp_we_o ( sp_we_id ),
.sp_we_ex_i ( sp_we_ex_o ),
// CSR control signals
.csr_access_o ( csr_access ),
.csr_op_o ( csr_op ),
// Data bus interface
.data_we_o ( data_we_id ),
@ -773,7 +777,6 @@ module id_stage
mult_use_carry_ex_o <= 1'b0;
mult_mac_en_ex_o <= 1'b0;
regfile_waddr_ex_o <= 5'b0;
regfile_wdata_mux_sel_ex_o <= 1'b0;
regfile_we_ex_o <= 1'b0;
@ -782,7 +785,8 @@ module id_stage
regfile_alu_we_ex_o <= 1'b0;
prepost_useincr_ex_o <= 1'b0;
sp_we_ex_o <= 1'b0;
csr_access_ex_o <= 1'b0;
csr_op_ex_o <= 2'b0;
data_we_ex_o <= 1'b0;
data_type_ex_o <= 2'b0;
@ -854,8 +858,8 @@ module id_stage
prepost_useincr_ex_o <= prepost_useincr;
sp_we_ex_o <= sp_we_id;
csr_access_ex_o <= csr_access;
csr_op_ex_o <= csr_op;
data_we_ex_o <= data_we_id;
data_type_ex_o <= data_type_id;

View file

@ -102,6 +102,12 @@
`define INSTR_FENCE { 4'b0000, {8 {1'b?}}, {13 {1'b0}}, `OPCODE_FENCE }
`define INSTR_FENCEI { {17 {1'b0}}, 3'b001, {5 {1'b0}}, `OPCODE_FENCE }
// SYSTEM
`define INSTR_CSRRW { {17 {1'b?}}, 3'b001, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_CSRRS { {17 {1'b?}}, 3'b010, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_CSRRC { {17 {1'b?}}, 3'b011, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_CSRRWI { {17 {1'b?}}, 3'b101, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_CSRRSI { {17 {1'b?}}, 3'b110, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_CSRRCI { {17 {1'b?}}, 3'b111, {5 {1'b?}}, `OPCODE_SYSTEM }
`define INSTR_ECALL { 12'b000000000000, {13 {1'b0}}, `OPCODE_SYSTEM }
`define INSTR_EBREAK { 12'b000000000001, {13 {1'b0}}, `OPCODE_SYSTEM }
`define INSTR_ERET { 12'b000100000000, {13 {1'b0}}, `OPCODE_SYSTEM }
@ -245,20 +251,27 @@ endfunction // prettyPrintInstruction
`define ALU_CMP_ALL 2'b10
////////////////////////////////////////////////////////
// ____ ____ ____ _ _ //
// / ___|| _ \ | _ \ ___ __ _(_)___| |_ ___ _ __ //
// \___ \| |_) | | |_) / _ \/ _` | / __| __/ _ \ '__| //
// ___) | __/ | _ < __/ (_| | \__ \ || __/ | //
// |____/|_| |_| \_\___|\__, |_|___/\__\___|_| //
// |___/ //
////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// ____ ____ ____ _ _ //
// / ___/ ___| | _ \ ___ __ _(_)___| |_ ___ _ __ //
// | | \___ \ | |_) / _ \/ _` | / __| __/ _ \ '__| //
// | |___ ___) | | _ < __/ (_| | \__ \ || __/ | //
// \____|____/ |_| \_\___|\__, |_|___/\__\___|_| //
// |___/ //
/////////////////////////////////////////////////////////
// internal CSR addresses
`define CSR_IDX_MSCRATCH 0
`define CSR_IDX_MEPC 1
`define CSR_MAX_IDX 1
// CSR operations
`define CSR_OP_NONE 2'b00
`define CSR_OP_WRITE 2'b01
`define CSR_OP_SET 2'b10
`define CSR_OP_CLEAR 2'b11
// Special-Purpose Register Addresses
// see OpenRISC manual p. 22ff
`define SP_GRP_SYS 5'h00
@ -301,8 +314,8 @@ endfunction // prettyPrintInstruction
// operand a selection
`define OP_A_REGA_OR_FWD 2'b00
`define OP_A_CURRPC 2'b10
`define OP_A_IMM16 2'b11
`define OP_A_CURRPC 2'b01
`define OP_A_ZIMM 2'b10
`define OP_A_ZERO 2'b11
// operand b selection
@ -315,12 +328,10 @@ endfunction // prettyPrintInstruction
`define OP_C_JT 1'b1
// operand b immediate selection
`define IMM_I 3'b000
`define IMM_S 3'b001
`define IMM_U 3'b010
`define IMM_HEX4 3'b011
`define IMM_CID 3'b100 // core id
`define IMM_CLID 3'b100 // cluster id
`define IMM_I 2'b00
`define IMM_S 2'b01
`define IMM_U 2'b10
`define IMM_HEX4 2'b11
// PC mux selector defines
`define PC_INCR 3'b000

View file

@ -148,14 +148,14 @@ module riscv_core
logic regfile_alu_we_fw;
logic [31:0] regfile_alu_wdata_fw;
// Special-Purpose Register Control
logic sp_we_ex; // Output of ID_stage to EX stage
logic sp_we_wb;
logic [31:0] sp_rdata;
logic [11:0] sp_addr;
logic [31:0] sp_wdata;
logic sp_we;
// CSR control
logic csr_access_ex;
logic [1:0] csr_op_ex;
logic [1:0] csr_op;
logic [11:0] csr_addr;
logic [31:0] csr_rdata;
logic [31:0] csr_wdata;
// Data Memory Control: From ID stage (id-ex pipe) <--> load store unit
logic data_we_ex;
@ -181,9 +181,6 @@ module riscv_core
logic sr_flag_fw;
logic carry_sp;
// Calculation Result
logic [15:0] sp_addr_wb;
// Signals between instruction core interface and pipe (if and id stages)
logic [31:0] instr_rdata_int; // read instruction from the instruction core interface to if_stage
logic instr_req_int; // Id stage asserts a req to instruction core interface
@ -241,7 +238,7 @@ module riscv_core
logic dbg_reg_mux;
logic dbg_sp_mux;
logic dbg_reg_we;
logic [15:0] dbg_reg_addr;
logic [11:0] dbg_reg_addr;
logic [31:0] dbg_reg_wdata;
logic [31:0] dbg_reg_rdata;
logic [31:0] dbg_rdata;
@ -354,8 +351,6 @@ module riscv_core
.clk ( clk ),
.rst_n ( rst_n ),
.core_id_i ( core_id_i ), // TODO: Temporary hack
// Processor Enable
.fetch_enable_i ( fetch_enable_i ),
@ -412,6 +407,10 @@ module riscv_core
.regfile_alu_we_ex_o ( regfile_alu_we_ex ),
.regfile_alu_waddr_ex_o ( regfile_alu_waddr_ex ),
// CSR ID/EX
.csr_access_ex_o ( csr_access_ex ),
.csr_op_ex_o ( csr_op_ex ),
// hwloop signals
.hwloop_we_ex_o ( hwlp_we_ex ),
.hwloop_regid_ex_o ( hwlp_regid_ex ),
@ -420,8 +419,6 @@ module riscv_core
.hwloop_dec_cnt_o ( hwlp_dec_cnt ),
.hwloop_targ_addr_o ( hwlp_targ_addr ),
.sp_we_ex_o ( sp_we_ex ),
.prepost_useincr_ex_o ( useincr_addr_ex ),
.data_misaligned_i ( data_misaligned ),
@ -515,11 +512,16 @@ module riscv_core
.mult_use_carry_i ( mult_use_carry_ex ),
.mult_mac_en_i ( mult_mac_en_ex ),
/*
// interface with Special registers
.carry_o ( carry_ex ),
.overflow_o ( overflow_ex ),
.set_overflow_o ( set_overflow_fw_ex ), // to special registers
.set_carry_o ( set_carry_fw_ex ), // to special registers
*/
// interface with CSRs
.csr_access_i ( csr_access_ex ),
.csr_rdata_i ( csr_rdata ),
// input from ID stage
.stall_ex_i ( stall_ex ),
@ -545,11 +547,8 @@ module riscv_core
.set_carry_i ( set_carry_ex ),
.regfile_rb_data_i ( regfile_rb_data_ex ),
.sp_we_i ( sp_we_ex ),
// Output of ex stage pipeline
.sp_addr_wb_o ( sp_addr_wb ),
.regfile_waddr_wb_o ( regfile_waddr_fw_wb_o ),
.regfile_wdata_mux_sel_wb_o ( regfile_wdata_mux_sel_wb ),
.regfile_we_wb_o ( regfile_we_wb ),
@ -562,8 +561,6 @@ module riscv_core
.hwloop_end_data_o ( hwlp_end_data_ex ),
.hwloop_cnt_data_o ( hwlp_cnt_data_ex ),
.sp_we_wb_o ( sp_we_wb ),
// To IF: Jump and branch target and decision
.jump_target_o ( jump_target ),
.branch_decision_o ( branch_decision ),
@ -593,7 +590,6 @@ module riscv_core
// Mux selector of regfile wdata
.regfile_wdata_mux_sel_i ( regfile_wdata_mux_sel_wb ),
// Mux inputs
.sp_rdata_i ( sp_rdata ),
.data_rdata_i ( data_rdata_int ),
.lsu_data_reg_i ( lsu_data_reg ),
// Mux output
@ -662,10 +658,56 @@ module riscv_core
.core_id_i ( core_id_i ),
.cluster_id_i ( cluster_id_i ),
// Interface to Special register (SRAM LIKE)
.csr_addr_i ( csr_addr ),
.csr_wdata_i ( csr_wdata ),
.csr_op_i ( csr_op ),
.csr_rdata_o ( csr_rdata ),
// HWLoop signals
.hwlp_start_addr_i ( hwlp_start_addr ),
.hwlp_end_addr_i ( hwlp_end_addr ),
.hwlp_counter_i ( hwlp_counter ),
.hwlp_start_o ( sp_hwlp_start ),
.hwlp_end_o ( sp_hwlp_end ),
.hwlp_counter_o ( sp_hwlp_cnt ),
.hwlp_regid_o ( sp_hwlp_regid ),
.hwlp_we_o ( sp_hwlp_we ),
.curr_pc_if_i ( current_pc_if ), // from IF stage
.curr_pc_id_i ( current_pc_id ), // from IF stage
.save_pc_if_i ( save_pc_if ),
.save_pc_id_i ( save_pc_id ),
.epcr_o ( epcr ),
.irq_enable_o ( irq_enable ),
.npc_o ( dbg_npc ), // PC from debug unit
.set_npc_o ( dbg_set_npc ) // set PC to new value
);
// Mux for SPR access through Debug Unit
assign csr_addr = (dbg_sp_mux == 1'b0) ? alu_operand_b_ex[11:0] : dbg_reg_addr;
assign csr_wdata = (dbg_sp_mux == 1'b0) ? alu_operand_a_ex : dbg_reg_wdata;
assign csr_op = (dbg_sp_mux == 1'b0) ? csr_op_ex
: (dbg_reg_we == 1'b1 ? `CSR_OP_WRITE : `CSR_OP_NONE);
assign dbg_rdata = (dbg_sp_mux == 1'b0) ? dbg_reg_rdata : csr_rdata;
/*
sp_registers sp_registers_i
(
.clk ( clk ),
.rst_n ( rst_n ),
// Core and Cluster ID from outside
.core_id_i ( core_id_i ),
.cluster_id_i ( cluster_id_i ),
// Interface to Special register (SRAM LIKE)
.sp_addr_i ( sp_addr ),
.sp_wdata_i ( sp_wdata ),
.sp_we_i ( sp_we ),
.sp_op_i ( sp_op ),
.sp_rdata_o ( sp_rdata ),
// Stall direct write
@ -698,8 +740,10 @@ module riscv_core
// Mux for SPR access through Debug Unit
assign sp_addr = (dbg_sp_mux == 1'b0) ? sp_addr_wb : dbg_reg_addr;
assign sp_wdata = (dbg_sp_mux == 1'b0) ? regfile_rb_data_wb : dbg_reg_wdata;
assign sp_we = (dbg_sp_mux == 1'b0) ? sp_we_wb : dbg_reg_we;
assign sp_op = (dbg_sp_mux == 1'b0) ? sp_op_wb
: (dbg_reg_we == 1'b1 ? `CSR_OP_WRITE : `CSR_OP_NONE);
assign dbg_rdata = (dbg_sp_mux == 1'b0) ? dbg_reg_rdata : sp_rdata;
*/
/*
@ -884,10 +928,18 @@ module riscv_core
// FENCE
`INSTR_FENCE: printMnemonic("FENCE");
`INSTR_FENCEI: printMnemonic("FENCEI");
// SYSTEM
// SYSTEM (CSR manipulation)
`INSTR_CSRRW: printCSRInstr("CSRRW");
`INSTR_CSRRS: printCSRInstr("CSRRS");
`INSTR_CSRRC: printCSRInstr("CSRRC");
`INSTR_CSRRWI: printCSRInstr("CSRRWI");
`INSTR_CSRRSI: printCSRInstr("CSRRSI");
`INSTR_CSRRCI: printCSRInstr("CSRRCI");
// SYSTEM (others)
`INSTR_ECALL: printMnemonic("ECALL");
`INSTR_EBREAK: printMnemonic("EBREAK");
`INSTR_ERET: printMnemonic("ERET");
`INSTR_WFI: printMnemonic("WFI");
`INSTR_RDCYCLE: printRDInstr("RDCYCLE");
`INSTR_RDCYCLEH: printRDInstr("RDCYCLEH");
`INSTR_RDTIME: printRDInstr("RDTIME");
@ -916,7 +968,7 @@ module riscv_core
function void printRInstr(input string mnemonic);
begin
riscv_core.mnemonic = mnemonic;
$fdisplay(f, "%s\tx%0d, x%d (0x%h), x%0d (0x%h)", mnemonic,
$fdisplay(f, "%s\tx%0d, x%0d (0x%h), x%0d (0x%h)", mnemonic,
rd, rs1, rs1_value, rs2, rs2_value);
end
endfunction // printRInstr
@ -963,6 +1015,22 @@ module riscv_core
end
endfunction // printRDInstr
function void printCSRInstr(input string mnemonic);
logic [11:0] csr;
begin
riscv_core.mnemonic = mnemonic;
imm = id_stage_i.imm_z_type;
csr = instr[31:20];
if (instr[14] == 1'b0) begin
$fdisplay(f, "%s\tx%0d, 0x%h (csr), x%0d (0x%h)", mnemonic, rd, csr,
rs1, rs1_value);
end else begin
$fdisplay(f, "%s\tx%0d, 0x%h (csr), 0x%h (imm)", mnemonic, rd, csr, imm);
end
end
endfunction // printCSRInstr
`endif // TRACE_EXECUTION
// synopsys translate_on

View file

@ -41,14 +41,14 @@ module wb_stage
input logic regfile_wdata_mux_sel_i, // Comes from the controller (thru id-ex and ex-wb pipe)
// MUX INPUTS
input logic [31:0] sp_rdata_i, // From the read port of the special register
input logic [31:0] data_rdata_i, // read Data from data memory system
input logic [31:0] lsu_data_reg_i, // read data registered in LSU
input logic [31:0] lsu_data_reg_i, // TODO: remove; read data registered in LSU
// MUX OUTPUT
output logic [31:0] regfile_wdata_o // write data for register file
);
// TODO: Remove this mux and the associated signals
// Register Write Data Selection --> Data to write in the regfile
// Select between:
// 0: From Special Register
@ -56,7 +56,7 @@ module wb_stage
always_comb
begin : REGFILE_WDATA_MUX
casex (regfile_wdata_mux_sel_i)
1'b0: begin regfile_wdata_o <= sp_rdata_i; end
//1'b0: begin regfile_wdata_o <= sp_rdata_i; end
1'b1: begin regfile_wdata_o <= data_rdata_i; end
endcase; // case (regfile_wdata_mux_sel_i)
end