Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ RISCOF_CONFIG := $(RISCOF_DIR)/config.ini

UTOSS_RISCV_CONFIG ?= RV32I

UTOSS_RISCV_VERILATOR_DEFINES := $(if $(findstring B,$(UTOSS_RISCV_CONFIG)),-DUTOSS_RISCV_ENABLE_B_EXT)
UTOSS_RISCV_VERILATOR_DEFINES := $(if $(findstring B,$(UTOSS_RISCV_CONFIG)),-DUTOSS_RISCV_ENABLE_B_EXT) $(if $(findstring C,$(UTOSS_RISCV_CONFIG)),-DUTOSS_RISCV_ENABLE_C_EXT)
UTOSS_RISCV_RISCOF_VERILATOR_DEFINES := -DUTOSS_PIPELINE_LOGGER

# ===========================
Expand Down Expand Up @@ -100,7 +100,7 @@ run_tb: build_tb

# Pattern rule for building individual testbenches
$(OUT_DIR)/%_tb_sim: $(TB_DIR)/%_tb.sv $(TB_UTILS) $(SRCS)
$(VERILATOR) $(VERILATOR_FLAGS) $(TB_DEFINES) \
$(VERILATOR) $(VERILATOR_FLAGS) $(TB_DEFINES) $(if $(findstring fetch_rvc_,$*),-DUTOSS_RISCV_ENABLE_C_EXT) \
--top-module $(basename $(notdir $<)) \
--Mdir $(BUILD_DIR)/$(basename $(notdir $@)) \
-o $(basename $(notdir $@)) \
Expand Down
2 changes: 2 additions & 0 deletions envs/de1-soc/quartus/utoss-risc-v.qsf
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/modules/Instruction_
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/modules/Instruction_Decode/MemoryLoader.sv
set_global_assignment -name VERILOG_FILE ../../../src/modules/Instruction_Decode/registerFile.v
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/modules/ControlFSM.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/ext/c/instruction_reader.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/ext/c/fetch_compressed.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/packages/pkg_control_fsm.svh
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/stages/decode_stage.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../../src/stages/execute_stage.sv
Expand Down
202 changes: 202 additions & 0 deletions src/ext/c/fetch_compressed.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
`include "src/timescale.svh"
`include "src/headers/params.svh"
`include "src/headers/types.svh"
`include "src/interfaces/if_to_id_if.svh"
`include "src/interfaces/ex_to_if_if.svh"

module fetch_compressed
( output if_to_id_t if_to_id
, input ex_to_if_t ex_to_if
, input wire clk
, input wire reset
, input wire stall_f
, input wire flush_f
, output addr_t imem__address
, input data_t imem__data
);

addr_t pc_prev;
addr_t pc_cur;
addr_t pc_next;

instr_t stalled_instr;
logic stalled_instr_valid;

instr_t final_instr;
logic final_illegal;
instr_t decompressed_instr;
logic compressed_illegal;

logic reader_inst_is_compressed;
logic reader_inst_is_split;
instr_t reader_instr_raw;
addr_t reader_instr_pc;
addr_t reader_next_pc;

logic split_wait_valid;
data_t split_wait_cur_word;
addr_t split_wait_pc;
data_t split_wait_next_word;
logic split_wait_next_word_valid;

logic need_split_wait;
logic buffer_after_split;
logic hold_pc_for_split_buffer;

localparam instr_t NOP = 32'h00000013;

logic buffered_word_valid;
data_t buffered_word;
addr_t buffered_pc;

logic use_buffer;
logic buffer_next_same_word;

addr_t reader_pc_i;
data_t reader_cur_word_i;
data_t reader_next_word;

wire unused = &{
ex_to_if.pc_old
, ex_to_if.imm_ext
, final_illegal
};

always_comb
case (ex_to_if.pc_src)
PC_SRC__INCREMENT: pc_next = {pc_cur[31:2], 2'b00} + 32'd4;
PC_SRC__ALU_RESULT: pc_next = ex_to_if.pc_target;
default: pc_next = 32'hx;
endcase

always_ff @ (posedge clk)
if (reset)
{stalled_instr, stalled_instr_valid} <= {instr_t'(0), 1'b0};
else if (flush_f)
{stalled_instr, stalled_instr_valid} <= {stalled_instr, 1'b0};
else if (stall_f && !stalled_instr_valid)
{stalled_instr, stalled_instr_valid} <= {instr_t'(imem__data), 1'b1};
else if (!stall_f && stalled_instr_valid)
{stalled_instr, stalled_instr_valid} <= {stalled_instr, 1'b0};

assign imem__address = {pc_cur[31:2], 2'b00};

instruction_reader u_reader
( .pc_i (reader_pc_i)
, .cur_word_i (reader_cur_word_i)
, .next_word_i (reader_next_word)
, .instr_raw_o (reader_instr_raw)
, .instr_pc_o (reader_instr_pc)
, .instr_next_pc_o (reader_next_pc)
, .instr_is_compressed_o (reader_inst_is_compressed)
, .instr_is_split_o (reader_inst_is_split)
);

assign decompressed_instr = NOP;
assign compressed_illegal = 1'b0;

always_ff @ (posedge clk)
if (reset)
pc_cur <= addr_t'(0);
else if (!stall_f && !hold_pc_for_split_buffer)
pc_cur <= pc_next;

always_ff @ (posedge clk)
if (reset)
pc_prev <= addr_t'(0);
else if (!stall_f && !hold_pc_for_split_buffer)
pc_prev <= pc_cur;

always_ff @ (posedge clk)
if (reset || flush_f)
{ split_wait_valid
, split_wait_cur_word
, split_wait_pc
, split_wait_next_word
, split_wait_next_word_valid
} <= {1'b0, data_t'(0), addr_t'(0), data_t'(0), 1'b0};

else if (!stall_f && split_wait_valid)
{ split_wait_valid
, split_wait_next_word
, split_wait_next_word_valid
} <= {1'b0, data_t'(0), 1'b0};

else if (!stall_f && need_split_wait)
{ split_wait_valid
, split_wait_cur_word
, split_wait_pc
, split_wait_next_word
, split_wait_next_word_valid
} <= {1'b1, reader_cur_word_i, reader_instr_pc, data_t'(0), 1'b0};

else if (stall_f && split_wait_valid && !split_wait_next_word_valid)
{split_wait_next_word, split_wait_next_word_valid} <= {imem__data, 1'b1};

always_ff @ (posedge clk)
if (reset || flush_f)
{buffered_word_valid, buffered_word, buffered_pc}
<= {1'b0, data_t'(0), addr_t'(0)};

else if (!stall_f && buffer_after_split)
{buffered_word_valid, buffered_word, buffered_pc}
<= {1'b1, reader_next_word, reader_next_pc};

else if (!stall_f && use_buffer)
buffered_word_valid <= 1'b0;

else if (!stall_f && buffer_next_same_word)
{buffered_word_valid, buffered_word, buffered_pc}
<= {1'b1, reader_cur_word_i, reader_next_pc};

assign use_buffer = buffered_word_valid;

assign reader_pc_i =
split_wait_valid ? split_wait_pc :
use_buffer ? buffered_pc :
pc_prev;

assign reader_cur_word_i =
split_wait_valid ? split_wait_cur_word :
use_buffer ? buffered_word :
stalled_instr_valid ? data_t'(stalled_instr) :
imem__data;

assign reader_next_word =
split_wait_valid ?
(split_wait_next_word_valid ? split_wait_next_word : imem__data) :
use_buffer ?
imem__data :
data_t'(0);

assign buffer_next_same_word =
reader_inst_is_compressed &&
(reader_next_pc[31:2] == reader_instr_pc[31:2]);

assign need_split_wait =
reader_inst_is_split && !split_wait_valid;

assign buffer_after_split =
split_wait_valid &&
reader_inst_is_split &&
(reader_next_pc[31:2] == (reader_instr_pc[31:2] + 30'd1));

assign hold_pc_for_split_buffer =
buffer_after_split;

assign final_instr =
reader_inst_is_compressed ? decompressed_instr : reader_instr_raw;

assign final_illegal =
reader_inst_is_compressed && compressed_illegal;

assign if_to_id.instruction =
need_split_wait ? NOP : final_instr;

assign if_to_id.pc_cur =
reader_instr_pc;

assign if_to_id.pc_plus_4 =
reader_next_pc;

endmodule
36 changes: 36 additions & 0 deletions src/ext/c/instruction_reader.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
`include "src/timescale.svh"
Comment thread
SiddharthShroff-dotcom marked this conversation as resolved.
`include "src/headers/params.svh"
`include "src/headers/types.svh"

module instruction_reader
( input addr_t pc_i
, input data_t cur_word_i
, input data_t next_word_i
, output instr_t instr_raw_o
, output addr_t instr_pc_o
, output addr_t instr_next_pc_o
, output logic instr_is_compressed_o
, output logic instr_is_split_o
);

wire unused_next_word =
&{1'b0, next_word_i[31:16]};
logic [15:0] selected_halfword;
logic selected_is_32b;
assign selected_halfword =
pc_i[1] ? cur_word_i[31:16] : cur_word_i[15:0];
assign selected_is_32b =
selected_halfword[1:0] == 2'b11;
assign instr_pc_o =
pc_i;
Comment on lines +24 to +25

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we can drop this passthrough

assign instr_is_compressed_o =
!selected_is_32b;
assign instr_is_split_o =
selected_is_32b && pc_i[1];
assign instr_next_pc_o =
pc_i + (instr_is_compressed_o ? 32'd2 : 32'd4);
assign instr_raw_o =
instr_is_compressed_o ? {16'b0, selected_halfword} :
instr_is_split_o ? {next_word_i[15:0], cur_word_i[31:16]} :
cur_word_i;
endmodule
40 changes: 20 additions & 20 deletions src/headers/params.svh
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@

// Opcodes
/* verilator lint_off UNUSEDPARAM */
parameter RType = 7'b0110011;
parameter IType_logic = 7'b0010011;
parameter IType_load = 7'b0000011;
parameter SType = 7'b0100011;
parameter BType = 7'b1100011;
parameter JType = 7'b1101111;
parameter UType_auipc = 7'b0010111;
parameter UType_lui = 7'b0110111;
parameter IType_jalr = 7'b1100111;
parameter FENCE = 7'b0001111;
localparam bit [6:0] RType = 7'b0110011;
localparam bit [6:0] IType_logic = 7'b0010011;
localparam bit [6:0] IType_load = 7'b0000011;
localparam bit [6:0] SType = 7'b0100011;
localparam bit [6:0] BType = 7'b1100011;
localparam bit [6:0] JType = 7'b1101111;
localparam bit [6:0] UType_auipc = 7'b0010111;
localparam bit [6:0] UType_lui = 7'b0110111;
localparam bit [6:0] IType_jalr = 7'b1100111;
localparam bit [6:0] FENCE = 7'b0001111;
/* verilator lint_on UNUSEDPARAM */

//ALU Operation Control Codes: Implemented as ENUM in params.svh
/*
parameter ALUAdd = 4'b0000;
parameter ALUSub = 4'b0001;
parameter ALUSLL = 4'b0010;
parameter ALUSLT = 4'b0011;
parameter ALUSLTU = 4'b0100;
parameter ALUXOR = 4'b0101;
parameter ALUSRL = 4'b0110;
parameter ALUSRA = 4'b0111;
parameter ALUOR = 4'b1000;
parameter ALUAND = 4'b1001;
localparam ALUAdd = 4'b0000;
localparam ALUSub = 4'b0001;
localparam ALUSLL = 4'b0010;
localparam ALUSLT = 4'b0011;
localparam ALUSLTU = 4'b0100;
localparam ALUXOR = 4'b0101;
localparam ALUSRL = 4'b0110;
localparam ALUSRA = 4'b0111;
localparam ALUOR = 4'b1000;
localparam ALUAND = 4'b1001;
*/

`endif // PARAMS_VH
Loading
Loading