mirror of
https://github.com/olofk/serv.git
synced 2025-04-20 11:57:07 -04:00
Compressed Extension for SERV
This commit is contained in:
parent
4ddd154b24
commit
2655861447
14 changed files with 462 additions and 36 deletions
|
@ -94,7 +94,7 @@ Run the compliance tests
|
|||
|
||||
cd riscv-arch-test && make TARGETDIR=$SERV/riscv-target RISCV_TARGET=serv RISCV_DEVICE=I TARGET_SIM=$WORKSPACE/build/servant_1.1.0/verilator_tb-verilator/Vservant_sim
|
||||
|
||||
The above will run all tests in the rv32i test suite. Since SERV also implement the `M`, `privilege` and `Zifencei` extensions, these can also be tested by choosing any of them instead of `I` as the `RISCV_DEVICE` variable.
|
||||
The above will run all tests in the rv32i test suite. Since SERV also implement the `M`, `C`, `privilege` and `Zifencei` extensions, these can also be tested by choosing any of them instead of `I` as the `RISCV_DEVICE` variable.
|
||||
|
||||
## Run on hardware
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ module servant_sim
|
|||
parameter memfile = "";
|
||||
parameter memsize = 8192;
|
||||
parameter with_csr = 1;
|
||||
parameter compressed = 0;
|
||||
parameter align = compressed;
|
||||
|
||||
reg [1023:0] firmware_file;
|
||||
initial
|
||||
|
@ -19,7 +21,9 @@ module servant_sim
|
|||
#(.memfile (memfile),
|
||||
.memsize (memsize),
|
||||
.sim (1),
|
||||
.with_csr (with_csr))
|
||||
.with_csr (with_csr),
|
||||
.compress (compressed[0:0]),
|
||||
.align (align[0:0]))
|
||||
dut(wb_clk, wb_rst, q);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
`verilator_config
|
||||
// Bits [1:0] in i_ibus_rdt are not used at all
|
||||
lint_off -rule UNUSED -file "*/serv_top.v" -lines 53
|
||||
// Bits [1:0] in i_wb_rdt are not used at all
|
||||
lint_off -rule UNUSED -file "*/serv_top.v" -lines 178
|
||||
|
||||
//Some bits in the instruction word are not used in serv_decode but it's easier
|
||||
//to just send in the whole word than picking out bits
|
||||
lint_off -rule UNUSED -file "*/serv_decode.v" -lines 7
|
||||
lint_off -rule UNUSED -file "*/serv_decode.v" -lines 8
|
||||
|
||||
lint_off -rule UNUSED -file "*/serv_top.v" -lines 177
|
||||
|
||||
//Some variables are only used when we connect an Extension with serv_decode
|
||||
lint_off -rule UNUSED -file "*/serv_top.v" -lines 65
|
||||
lint_off -rule UNUSED -file "*/serv_bufreg.v" -lines 10
|
||||
lint_off -rule UNUSED -file "*/serv_decode.v" -lines 8
|
||||
lint_off -rule UNUSED -file "*/serv_decode.v" -lines 69
|
||||
lint_off -rule UNUSED -file "*/serv_mem_if.v" -lines 23
|
||||
lint_off -rule UNUSED -file "*/serv_mem_if.v" -lines 71
|
||||
lint_off -rule UNUSED -file "*/serv_state.v" -lines 47
|
||||
lint_off -rule UNUSED -file "*/serv_state.v" -lines 49
|
||||
lint_off -rule UNUSED -file "*/serv_top.v" -lines 67
|
||||
|
||||
|
||||
|
|
26
riscv-target/serv/device/rv32i_m/C/Makefile.include
Normal file
26
riscv-target/serv/device/rv32i_m/C/Makefile.include
Normal file
|
@ -0,0 +1,26 @@
|
|||
TARGET_SIM ?= server
|
||||
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
|
||||
$(error Target simulator executable '$(TARGET_SIM)` not found)
|
||||
endif
|
||||
|
||||
RUN_TARGET=\
|
||||
$(TARGET_SIM) \
|
||||
+timeout=100000000000 \
|
||||
+signature=$(*).signature.output \
|
||||
+firmware=$(<).hex 2> $@
|
||||
|
||||
RISCV_PREFIX ?= riscv32-unknown-elf-
|
||||
RISCV_GCC ?= $(RISCV_PREFIX)gcc
|
||||
RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy
|
||||
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump
|
||||
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
|
||||
|
||||
COMPILE_TARGET=\
|
||||
$$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \
|
||||
-I$(ROOTDIR)/riscv-test-env/ \
|
||||
-I$(TARGETDIR)/$(RISCV_TARGET)/ \
|
||||
-T$(TARGETDIR)/$(RISCV_TARGET)/link.ld $$< \
|
||||
-o $$@; \
|
||||
$$(RISCV_OBJCOPY) -O binary $$@ $$@.bin; \
|
||||
$$(RISCV_OBJDUMP) -D $$@ > $$@.objdump; \
|
||||
python3 $(TARGETDIR)/$(RISCV_TARGET)/makehex.py $$@.bin 524288 > $$@.hex;
|
67
rtl/serv_aligner.v
Normal file
67
rtl/serv_aligner.v
Normal file
|
@ -0,0 +1,67 @@
|
|||
module serv_aligner
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
// serv_top
|
||||
input wire [31:0] i_ibus_adr,
|
||||
input wire i_ibus_cyc,
|
||||
output wire [31:0] o_ibus_rdt,
|
||||
output wire o_ibus_ack,
|
||||
// serv_rf_top
|
||||
output wire [31:0] o_wb_ibus_adr,
|
||||
output wire o_wb_ibus_cyc,
|
||||
input wire [31:0] i_wb_ibus_rdt,
|
||||
input wire i_wb_ibus_ack);
|
||||
|
||||
wire [31:0] ibus_rdt_concat;
|
||||
wire ack_en;
|
||||
|
||||
reg [15:0] lower_hw;
|
||||
reg ctrl_misal ;
|
||||
|
||||
/* From SERV core to Memory
|
||||
|
||||
o_wb_ibus_adr: Carries address of instruction to memory. In case of misaligned access,
|
||||
which is caused by pc+2 due to compressed instruction, next instruction is fetched
|
||||
by pc+4 and concatenation is done to make the instruction aligned.
|
||||
|
||||
o_wb_ibus_cyc: Simply forwarded from SERV to Memory and is only altered by memory or SERV core.
|
||||
*/
|
||||
assign o_wb_ibus_adr = ctrl_misal ? (i_ibus_adr+32'b100) : i_ibus_adr;
|
||||
assign o_wb_ibus_cyc = i_ibus_cyc;
|
||||
|
||||
/* From Memory to SERV core
|
||||
|
||||
o_ibus_ack: Instruction bus acknowledge is send to SERV only when the aligned instruction,
|
||||
either compressed or un-compressed, is ready to dispatch.
|
||||
|
||||
o_ibus_rdt: Carries the instruction from memory to SERV core. It can be either aligned
|
||||
instruction coming from memory or made aligned by two bus transactions and concatenation.
|
||||
*/
|
||||
assign o_ibus_ack = i_wb_ibus_ack & ack_en;
|
||||
assign o_ibus_rdt = ctrl_misal ? ibus_rdt_concat : i_wb_ibus_rdt;
|
||||
|
||||
/* 16-bit register used to hold the upper half word of the current instruction in-case
|
||||
concatenation will be required with the upper half word of upcoming instruction
|
||||
*/
|
||||
always @(posedge clk) begin
|
||||
if(i_wb_ibus_ack)begin
|
||||
lower_hw <= i_wb_ibus_rdt[31:16];
|
||||
end
|
||||
end
|
||||
|
||||
assign ibus_rdt_concat = {i_wb_ibus_rdt[15:0],lower_hw};
|
||||
|
||||
/* Two control signals: ack_en, ctrl_misal are set to control the bus transactions between
|
||||
SERV core and the memory
|
||||
*/
|
||||
assign ack_en = !(i_ibus_adr[1] & !ctrl_misal);
|
||||
|
||||
always @(posedge clk ) begin
|
||||
if(rst)
|
||||
ctrl_misal <= 0;
|
||||
else if(i_wb_ibus_ack & i_ibus_adr[1])
|
||||
ctrl_misal <= !ctrl_misal;
|
||||
end
|
||||
|
||||
endmodule
|
234
rtl/serv_compdec.v
Normal file
234
rtl/serv_compdec.v
Normal file
|
@ -0,0 +1,234 @@
|
|||
/* Copyright lowRISC contributors.
|
||||
Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
|
||||
Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
* Adapted to SERV by @Abdulwadoodd as part of the project under spring '22 LFX Mentorship program */
|
||||
|
||||
/* Decodes RISC-V compressed instructions into their RV32i equivalent. */
|
||||
|
||||
module serv_compdec
|
||||
(
|
||||
input wire i_clk,
|
||||
input wire [31:0] i_instr,
|
||||
input wire i_ack,
|
||||
output wire [31:0] o_instr,
|
||||
output reg o_iscomp);
|
||||
|
||||
localparam OPCODE_LOAD = 7'h03;
|
||||
localparam OPCODE_OP_IMM = 7'h13;
|
||||
localparam OPCODE_STORE = 7'h23;
|
||||
localparam OPCODE_OP = 7'h33;
|
||||
localparam OPCODE_LUI = 7'h37;
|
||||
localparam OPCODE_BRANCH = 7'h63;
|
||||
localparam OPCODE_JALR = 7'h67;
|
||||
localparam OPCODE_JAL = 7'h6f;
|
||||
|
||||
reg [31:0] comp_instr;
|
||||
reg illegal_instr;
|
||||
|
||||
assign o_instr = illegal_instr ? i_instr : comp_instr;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if(i_ack)
|
||||
o_iscomp <= !illegal_instr;
|
||||
end
|
||||
|
||||
always @ (*) begin
|
||||
// By default, forward incoming instruction, mark it as legal.
|
||||
comp_instr = i_instr;
|
||||
illegal_instr = 1'b0;
|
||||
|
||||
// Check if incoming instruction is compressed.
|
||||
case (i_instr[1:0])
|
||||
// C0
|
||||
2'b00: begin
|
||||
case (i_instr[15:14])
|
||||
2'b00: begin
|
||||
// c.addi4spn -> addi rd', x2, imm
|
||||
comp_instr = {2'b0, i_instr[10:7], i_instr[12:11], i_instr[5],
|
||||
i_instr[6], 2'b00, 5'h02, 3'b000, 2'b01, i_instr[4:2], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
2'b01: begin
|
||||
// c.lw -> lw rd', imm(rs1')
|
||||
comp_instr = {5'b0, i_instr[5], i_instr[12:10], i_instr[6],
|
||||
2'b00, 2'b01, i_instr[9:7], 3'b010, 2'b01, i_instr[4:2], {OPCODE_LOAD}};
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
// c.sw -> sw rs2', imm(rs1')
|
||||
comp_instr = {5'b0, i_instr[5], i_instr[12], 2'b01, i_instr[4:2],
|
||||
2'b01, i_instr[9:7], 3'b010, i_instr[11:10], i_instr[6],
|
||||
2'b00, {OPCODE_STORE}};
|
||||
end
|
||||
|
||||
2'b10: begin
|
||||
illegal_instr = 1'b1;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
// C1
|
||||
|
||||
// Register address checks for RV32E are performed in the regular instruction decoder.
|
||||
// If this check fails, an illegal instruction exception is triggered and the controller
|
||||
// writes the actual faulting instruction to mtval.
|
||||
2'b01: begin
|
||||
case (i_instr[15:13])
|
||||
3'b000: begin
|
||||
// c.addi -> addi rd, rd, nzimm
|
||||
// c.nop
|
||||
comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2],
|
||||
i_instr[11:7], 3'b0, i_instr[11:7], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
3'b001, 3'b101: begin
|
||||
// 001: c.jal -> jal x1, imm
|
||||
// 101: c.j -> jal x0, imm
|
||||
comp_instr = {i_instr[12], i_instr[8], i_instr[10:9], i_instr[6],
|
||||
i_instr[7], i_instr[2], i_instr[11], i_instr[5:3],
|
||||
{9 {i_instr[12]}}, 4'b0, ~i_instr[15], {OPCODE_JAL}};
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
// c.li -> addi rd, x0, nzimm
|
||||
// (c.li hints are translated into an addi hint)
|
||||
comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2], 5'b0,
|
||||
3'b0, i_instr[11:7], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
3'b011: begin
|
||||
// c.lui -> lui rd, imm
|
||||
// (c.lui hints are translated into a lui hint)
|
||||
comp_instr = {{15 {i_instr[12]}}, i_instr[6:2], i_instr[11:7], {OPCODE_LUI}};
|
||||
|
||||
if (i_instr[11:7] == 5'h02) begin
|
||||
// c.addi16sp -> addi x2, x2, nzimm
|
||||
comp_instr = {{3 {i_instr[12]}}, i_instr[4:3], i_instr[5], i_instr[2],
|
||||
i_instr[6], 4'b0, 5'h02, 3'b000, 5'h02, {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
3'b100: begin
|
||||
case (i_instr[11:10])
|
||||
2'b00,
|
||||
2'b01: begin
|
||||
// 00: c.srli -> srli rd, rd, shamt
|
||||
// 01: c.srai -> srai rd, rd, shamt
|
||||
// (c.srli/c.srai hints are translated into a srli/srai hint)
|
||||
comp_instr = {1'b0, i_instr[10], 5'b0, i_instr[6:2], 2'b01, i_instr[9:7],
|
||||
3'b101, 2'b01, i_instr[9:7], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
2'b10: begin
|
||||
// c.andi -> andi rd, rd, imm
|
||||
comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2], 2'b01, i_instr[9:7],
|
||||
3'b111, 2'b01, i_instr[9:7], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
case (i_instr[6:5])
|
||||
2'b00: begin
|
||||
// c.sub -> sub rd', rd', rs2'
|
||||
comp_instr = {2'b01, 5'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7],
|
||||
3'b000, 2'b01, i_instr[9:7], {OPCODE_OP}};
|
||||
end
|
||||
|
||||
2'b01: begin
|
||||
// c.xor -> xor rd', rd', rs2'
|
||||
comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b100,
|
||||
2'b01, i_instr[9:7], {OPCODE_OP}};
|
||||
end
|
||||
|
||||
2'b10: begin
|
||||
// c.or -> or rd', rd', rs2'
|
||||
comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b110,
|
||||
2'b01, i_instr[9:7], {OPCODE_OP}};
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
// c.and -> and rd', rd', rs2'
|
||||
comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b111,
|
||||
2'b01, i_instr[9:7], {OPCODE_OP}};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
3'b110, 3'b111: begin
|
||||
// 0: c.beqz -> beq rs1', x0, imm
|
||||
// 1: c.bnez -> bne rs1', x0, imm
|
||||
comp_instr = {{4 {i_instr[12]}}, i_instr[6:5], i_instr[2], 5'b0, 2'b01,
|
||||
i_instr[9:7], 2'b00, i_instr[13], i_instr[11:10], i_instr[4:3],
|
||||
i_instr[12], {OPCODE_BRANCH}};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// C2
|
||||
|
||||
// Register address checks for RV32E are performed in the regular instruction decoder.
|
||||
// If this check fails, an illegal instruction exception is triggered and the controller
|
||||
// writes the actual faulting instruction to mtval.
|
||||
2'b10: begin
|
||||
case (i_instr[15:14])
|
||||
2'b00: begin
|
||||
// c.slli -> slli rd, rd, shamt
|
||||
// (c.ssli hints are translated into a slli hint)
|
||||
comp_instr = {7'b0, i_instr[6:2], i_instr[11:7], 3'b001, i_instr[11:7], {OPCODE_OP_IMM}};
|
||||
end
|
||||
|
||||
2'b01: begin
|
||||
// c.lwsp -> lw rd, imm(x2)
|
||||
comp_instr = {4'b0, i_instr[3:2], i_instr[12], i_instr[6:4], 2'b00, 5'h02,
|
||||
3'b010, i_instr[11:7], OPCODE_LOAD};
|
||||
end
|
||||
|
||||
2'b10: begin
|
||||
if (i_instr[12] == 1'b0) begin
|
||||
if (i_instr[6:2] != 5'b0) begin
|
||||
// c.mv -> add rd/rs1, x0, rs2
|
||||
// (c.mv hints are translated into an add hint)
|
||||
comp_instr = {7'b0, i_instr[6:2], 5'b0, 3'b0, i_instr[11:7], {OPCODE_OP}};
|
||||
end else begin
|
||||
// c.jr -> jalr x0, rd/rs1, 0
|
||||
comp_instr = {12'b0, i_instr[11:7], 3'b0, 5'b0, {OPCODE_JALR}};
|
||||
end
|
||||
end else begin
|
||||
if (i_instr[6:2] != 5'b0) begin
|
||||
// c.add -> add rd, rd, rs2
|
||||
// (c.add hints are translated into an add hint)
|
||||
comp_instr = {7'b0, i_instr[6:2], i_instr[11:7], 3'b0, i_instr[11:7], {OPCODE_OP}};
|
||||
end else begin
|
||||
if (i_instr[11:7] == 5'b0) begin
|
||||
// c.ebreak -> ebreak
|
||||
comp_instr = {32'h00_10_00_73};
|
||||
end else begin
|
||||
// c.jalr -> jalr x1, rs1, 0
|
||||
comp_instr = {12'b0, i_instr[11:7], 3'b000, 5'b00001, {OPCODE_JALR}};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
// c.swsp -> sw rs2, imm(x2)
|
||||
comp_instr = {4'b0, i_instr[8:7], i_instr[12], i_instr[6:2], 5'h02, 3'b010,
|
||||
i_instr[11:9], 2'b00, {OPCODE_STORE}};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// Incoming instruction is not compressed.
|
||||
2'b11: illegal_instr = 1'b1;
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -10,6 +10,7 @@ module serv_ctrl
|
|||
input wire i_pc_en,
|
||||
input wire i_cnt12to31,
|
||||
input wire i_cnt0,
|
||||
input wire i_cnt1,
|
||||
input wire i_cnt2,
|
||||
//Control
|
||||
input wire i_jump,
|
||||
|
@ -17,6 +18,7 @@ module serv_ctrl
|
|||
input wire i_utype,
|
||||
input wire i_pc_rel,
|
||||
input wire i_trap,
|
||||
input wire i_iscomp,
|
||||
//Data
|
||||
input wire i_imm,
|
||||
input wire i_buf,
|
||||
|
@ -42,7 +44,7 @@ module serv_ctrl
|
|||
wire offset_a;
|
||||
wire offset_b;
|
||||
|
||||
assign plus_4 = i_cnt2;
|
||||
assign plus_4 = i_iscomp ? i_cnt1 : i_cnt2;
|
||||
|
||||
assign o_bad_pc = pc_plus_offset_aligned;
|
||||
|
||||
|
|
|
@ -109,10 +109,11 @@ module serv_decode
|
|||
wire co_ctrl_jal_or_jalr = opcode[4] & opcode[0];
|
||||
|
||||
//PC-relative operations
|
||||
//True for jal, b* auipc
|
||||
//True for jal, b* auipc, ebreak
|
||||
//False for jalr, lui
|
||||
wire co_ctrl_pc_rel = (opcode[2:0] == 3'b000) |
|
||||
(opcode[1:0] == 2'b11) |
|
||||
wire co_ctrl_pc_rel = (opcode[2:0] == 3'b000) |
|
||||
(opcode[1:0] == 2'b11) |
|
||||
(opcode[4] & opcode[2]) & op20|
|
||||
(opcode[4:3] == 2'b00);
|
||||
//Write to RD
|
||||
//True for OP-IMM, AUIPC, OP, LUI, SYSTEM, JALR, JAL, LOAD
|
||||
|
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
module serv_rf_top
|
||||
#(parameter RESET_PC = 32'd0,
|
||||
/* COMPRESSED=1: Enable the compressed decoder and allowed misaligned jump of pc
|
||||
COMPRESSED=0: Disable the compressed decoder and does not allow the misaligned jump of pc
|
||||
*/
|
||||
parameter [0:0] COMPRESSED = 0,
|
||||
/*
|
||||
ALIGN = 1: Fetch the aligned instruction by making two bus transactions if the misaligned address
|
||||
is given to the instruction bus.
|
||||
*/
|
||||
parameter [0:0] ALIGN = 0,
|
||||
/* Multiplication and Division Unit
|
||||
This parameter enables the interface for connecting SERV and MDU
|
||||
*/
|
||||
|
@ -133,7 +142,9 @@ module serv_rf_top
|
|||
.PRE_REGISTER (PRE_REGISTER),
|
||||
.RESET_STRATEGY (RESET_STRATEGY),
|
||||
.WITH_CSR (WITH_CSR),
|
||||
.MDU(MDU))
|
||||
.MDU(MDU),
|
||||
.COMPRESSED(COMPRESSED),
|
||||
.ALIGN(ALIGN))
|
||||
cpu
|
||||
(
|
||||
.clk (clk),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module serv_state
|
||||
#(parameter RESET_STRATEGY = "MINI",
|
||||
parameter [0:0] WITH_CSR = 1,
|
||||
parameter [0:0] COMPRESSED =0,
|
||||
parameter [0:0] MDU = 0)
|
||||
(
|
||||
input wire i_clk,
|
||||
|
@ -114,7 +115,7 @@ module serv_state
|
|||
shift : Shift in during phase 1. Continue shifting between phases (except
|
||||
for the first cycle after init). Shift out during phase 2
|
||||
*/
|
||||
assign o_bufreg_en = (o_cnt_en & (o_init | o_ctrl_trap | i_branch_op)) | (i_shift_op & !stage_two_req & (i_sh_right | i_sh_done_r) & init_done);
|
||||
assign o_bufreg_en = (o_cnt_en & (o_init | ((o_ctrl_trap | i_branch_op) & i_two_stage_op))) | (i_shift_op & !stage_two_req & (i_sh_right | i_sh_done_r) & init_done);
|
||||
|
||||
assign o_ibus_cyc = ibus_cyc & !i_rst;
|
||||
|
||||
|
@ -186,7 +187,7 @@ module serv_state
|
|||
|
||||
//trap_pending is only guaranteed to have correct value during the
|
||||
// last cycle of the init stage
|
||||
wire trap_pending = WITH_CSR & ((take_branch & i_ctrl_misalign) |
|
||||
wire trap_pending = WITH_CSR & ((take_branch & i_ctrl_misalign & !COMPRESSED) |
|
||||
(i_dbus_en & i_mem_misalign));
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
|
|
|
@ -5,7 +5,9 @@ module serv_top
|
|||
parameter PRE_REGISTER = 1,
|
||||
parameter RESET_STRATEGY = "MINI",
|
||||
parameter RESET_PC = 32'd0,
|
||||
parameter [0:0] MDU = 1'b0)
|
||||
parameter [0:0] MDU = 1'b0,
|
||||
parameter [0:0] COMPRESSED=0,
|
||||
parameter [0:0] ALIGN = 0)
|
||||
(
|
||||
input wire clk,
|
||||
input wire i_rst,
|
||||
|
@ -104,6 +106,7 @@ module serv_top
|
|||
wire imm;
|
||||
wire trap;
|
||||
wire pc_rel;
|
||||
wire iscomp;
|
||||
|
||||
wire init;
|
||||
wire cnt_en;
|
||||
|
@ -171,11 +174,57 @@ module serv_top
|
|||
|
||||
wire [1:0] lsb;
|
||||
|
||||
wire [31:0] i_wb_rdt;
|
||||
|
||||
wire [31:0] wb_ibus_adr;
|
||||
wire wb_ibus_cyc;
|
||||
wire [31:0] wb_ibus_rdt;
|
||||
wire wb_ibus_ack;
|
||||
|
||||
generate
|
||||
if (ALIGN) begin
|
||||
serv_aligner align
|
||||
(
|
||||
.clk(clk),
|
||||
.rst(i_rst),
|
||||
// serv_rf_top
|
||||
.i_ibus_adr(wb_ibus_adr),
|
||||
.i_ibus_cyc(wb_ibus_cyc),
|
||||
.o_ibus_rdt(wb_ibus_rdt),
|
||||
.o_ibus_ack(wb_ibus_ack),
|
||||
// servant_arbiter
|
||||
.o_wb_ibus_adr(o_ibus_adr),
|
||||
.o_wb_ibus_cyc(o_ibus_cyc),
|
||||
.i_wb_ibus_rdt(i_ibus_rdt),
|
||||
.i_wb_ibus_ack(i_ibus_ack));
|
||||
end else begin
|
||||
assign o_ibus_adr = wb_ibus_adr;
|
||||
assign o_ibus_cyc = wb_ibus_cyc;
|
||||
assign wb_ibus_rdt = i_ibus_rdt;
|
||||
assign wb_ibus_ack = i_ibus_ack;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (COMPRESSED) begin
|
||||
serv_compdec compdec
|
||||
(
|
||||
.i_clk(clk),
|
||||
.i_instr(wb_ibus_rdt),
|
||||
.i_ack(wb_ibus_ack),
|
||||
.o_instr(i_wb_rdt),
|
||||
.o_iscomp(iscomp));
|
||||
end else begin
|
||||
assign i_wb_rdt = wb_ibus_rdt;
|
||||
assign iscomp = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
serv_state
|
||||
#(.RESET_STRATEGY (RESET_STRATEGY),
|
||||
.WITH_CSR (WITH_CSR),
|
||||
.MDU(MDU))
|
||||
.MDU(MDU),
|
||||
.COMPRESSED(COMPRESSED))
|
||||
state
|
||||
(
|
||||
.i_clk (clk),
|
||||
|
@ -221,8 +270,8 @@ module serv_top
|
|||
//External
|
||||
.o_dbus_cyc (o_dbus_cyc),
|
||||
.i_dbus_ack (i_dbus_ack),
|
||||
.o_ibus_cyc (o_ibus_cyc),
|
||||
.i_ibus_ack (i_ibus_ack),
|
||||
.o_ibus_cyc (wb_ibus_cyc),
|
||||
.i_ibus_ack (wb_ibus_ack),
|
||||
//RF Interface
|
||||
.o_rf_rreq (o_rf_rreq),
|
||||
.o_rf_wreq (o_rf_wreq),
|
||||
|
@ -236,8 +285,8 @@ module serv_top
|
|||
(
|
||||
.clk (clk),
|
||||
//Input
|
||||
.i_wb_rdt (i_ibus_rdt[31:2]),
|
||||
.i_wb_en (i_ibus_ack),
|
||||
.i_wb_rdt (i_wb_rdt[31:2]),
|
||||
.i_wb_en (wb_ibus_ack),
|
||||
//To state
|
||||
.o_bne_or_bge (bne_or_bge),
|
||||
.o_cond_branch (cond_branch),
|
||||
|
@ -312,8 +361,8 @@ module serv_top
|
|||
.o_csr_imm (csr_imm),
|
||||
.o_imm (imm),
|
||||
//External
|
||||
.i_wb_en (i_ibus_ack),
|
||||
.i_wb_rdt (i_ibus_rdt[31:7]));
|
||||
.i_wb_en (wb_ibus_ack),
|
||||
.i_wb_rdt (i_wb_rdt[31:7]));
|
||||
|
||||
serv_bufreg
|
||||
#(.MDU(MDU))
|
||||
|
@ -376,6 +425,7 @@ module serv_top
|
|||
.i_pc_en (ctrl_pc_en),
|
||||
.i_cnt12to31 (cnt12to31),
|
||||
.i_cnt0 (cnt0),
|
||||
.i_cnt1 (cnt1),
|
||||
.i_cnt2 (cnt2),
|
||||
//Control
|
||||
.i_jump (jump),
|
||||
|
@ -383,6 +433,7 @@ module serv_top
|
|||
.i_utype (utype),
|
||||
.i_pc_rel (pc_rel),
|
||||
.i_trap (trap | mret),
|
||||
.i_iscomp (iscomp),
|
||||
//Data
|
||||
.i_imm (imm),
|
||||
.i_buf (bufreg_q),
|
||||
|
@ -390,7 +441,7 @@ module serv_top
|
|||
.o_rd (ctrl_rd),
|
||||
.o_bad_pc (bad_pc),
|
||||
//External
|
||||
.o_ibus_adr (o_ibus_adr));
|
||||
.o_ibus_adr (wb_ibus_adr));
|
||||
|
||||
serv_alu alu
|
||||
(
|
||||
|
@ -430,7 +481,7 @@ module serv_top
|
|||
//Trap interface
|
||||
.i_trap (trap),
|
||||
.i_mret (mret),
|
||||
.i_mepc (o_ibus_adr[0]),
|
||||
.i_mepc (wb_ibus_adr[0]),
|
||||
.i_mtval_pc (mtval_pc),
|
||||
.i_bufreg_q (bufreg_q),
|
||||
.i_bad_pc (bad_pc),
|
||||
|
@ -535,8 +586,8 @@ module serv_top
|
|||
rvfi_order <= rvfi_order + {63'd0,rvfi_valid};
|
||||
|
||||
/* Get instruction word when it's fetched from ibus */
|
||||
if (o_ibus_cyc & i_ibus_ack)
|
||||
rvfi_insn <= i_ibus_rdt;
|
||||
if (wb_ibus_cyc & wb_ibus_ack)
|
||||
rvfi_insn <= i_wb_rdt;
|
||||
|
||||
/* Store data written to rd */
|
||||
if (o_wen0)
|
||||
|
@ -580,14 +631,14 @@ module serv_top
|
|||
rvfi_mem_rdata <= i_dbus_rdt;
|
||||
rvfi_mem_wdata <= o_dbus_dat;
|
||||
end
|
||||
if (i_ibus_ack) begin
|
||||
if (wb_ibus_ack) begin
|
||||
rvfi_mem_rmask <= 4'b0000;
|
||||
rvfi_mem_wmask <= 4'b0000;
|
||||
end
|
||||
end
|
||||
/* verilator lint_off COMBDLY */
|
||||
always @(o_ibus_adr)
|
||||
rvfi_pc_wdata <= o_ibus_adr;
|
||||
always @(wb_ibus_adr)
|
||||
rvfi_pc_wdata <= wb_ibus_adr;
|
||||
/* verilator lint_on COMBDLY */
|
||||
|
||||
|
||||
|
|
15
serv.core
15
serv.core
|
@ -20,6 +20,8 @@ filesets:
|
|||
- rtl/serv_state.v
|
||||
- rtl/serv_top.v
|
||||
- rtl/serv_rf_top.v
|
||||
- rtl/serv_aligner.v
|
||||
- rtl/serv_compdec.v
|
||||
file_type : verilogSource
|
||||
|
||||
openlane:
|
||||
|
@ -31,6 +33,8 @@ targets:
|
|||
default:
|
||||
filesets : [core]
|
||||
parameters :
|
||||
- "is_toplevel? (ALIGN)"
|
||||
- "is_toplevel? (COMPRESSED)"
|
||||
- "is_toplevel? (MDU)"
|
||||
- "is_toplevel? (PRE_REGISTER)"
|
||||
- "is_toplevel? (RESET_STRATEGY)"
|
||||
|
@ -80,3 +84,14 @@ parameters:
|
|||
WITH_CSR:
|
||||
datatype : int
|
||||
paramtype : vlogparam
|
||||
|
||||
COMPRESSED:
|
||||
datatype : int
|
||||
description : Enable/Disable the support for Compressed instructions
|
||||
paramtype : vlogparam
|
||||
|
||||
ALIGN:
|
||||
datatype : int
|
||||
paramtype : vlogparam
|
||||
description : Enable/Disable the support of misaligned instructions
|
||||
|
||||
|
|
13
servant.core
13
servant.core
|
@ -442,6 +442,8 @@ targets:
|
|||
- uart_baudrate
|
||||
- vcd
|
||||
- vcd_start
|
||||
- compressed
|
||||
- align
|
||||
tools:
|
||||
verilator:
|
||||
verilator_options : [--trace]
|
||||
|
@ -536,6 +538,17 @@ parameters:
|
|||
datatype : int
|
||||
description : Delay start of VCD dumping until the specified time
|
||||
paramtype : plusarg
|
||||
|
||||
compressed:
|
||||
datatype : int
|
||||
description : Enable/Disable the Compressed extension
|
||||
paramtype : vlogparam
|
||||
|
||||
align:
|
||||
datatype : int
|
||||
description : Enable/Disable the Misaligned access of instruction
|
||||
paramtype : vlogparam
|
||||
|
||||
|
||||
generate:
|
||||
icebreaker_pll:
|
||||
|
|
|
@ -10,6 +10,8 @@ module servant
|
|||
parameter reset_strategy = "MINI";
|
||||
parameter sim = 0;
|
||||
parameter with_csr = 1;
|
||||
parameter [0:0] compress = 0;
|
||||
parameter [0:0] align = 0;
|
||||
|
||||
wire timer_irq;
|
||||
|
||||
|
@ -159,7 +161,9 @@ module servant
|
|||
`ifdef MDU
|
||||
.MDU(1),
|
||||
`endif
|
||||
.WITH_CSR (with_csr))
|
||||
.WITH_CSR (with_csr),
|
||||
.COMPRESSED(compress),
|
||||
.ALIGN(align))
|
||||
cpu
|
||||
(
|
||||
.clk (wb_clk),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue