diff --git a/Readme.md b/Readme.md index 6f283d3..345ef2f 100644 --- a/Readme.md +++ b/Readme.md @@ -11,6 +11,7 @@ Hazard3 is a 3-stage RISC-V processor, implementing the `RV32I` instruction set * `Zbc`: carry-less multiplication * `Zbs`: single-bit manipulation * `Zbkb`: basic bit manipulation for scalar cryptography +* `Zcb`: basic additional compressed instructions *(experimental)* * Debug, Machine and User privilege/execution modes * Privileged instructions `ECALL`, `EBREAK`, `MRET` and `WFI` * Physical memory protection (PMP) with up to 16 naturally aligned regions diff --git a/doc/sections/configuration_and_integration.adoc b/doc/sections/configuration_and_integration.adoc index 1cc2927..9c5bd16 100644 --- a/doc/sections/configuration_and_integration.adoc +++ b/doc/sections/configuration_and_integration.adoc @@ -105,6 +105,17 @@ Requires: <>. (Since Zbb and Zbkb have a large overlap, thi Default value: 0 +[[param-EXTENSION_ZCB]] +===== EXTENSION_ZCB: + +Support for Zcb basic additional compressed instructions + +Requires: <>. (Some Zcb instructions also require Zbb or M, as they are 16-bit aliases of 32-bit instructions present in those extensions.) + +Note Zca is equivalent to C, as we do not support the F extension. + +Default value: 0 + [[param-EXTENSION_ZIFENCEI]] ===== EXTENSION_ZIFENCEI diff --git a/hdl/hazard3_config.vh b/hdl/hazard3_config.vh index cc385ac..f8b1078 100644 --- a/hdl/hazard3_config.vh +++ b/hdl/hazard3_config.vh @@ -58,6 +58,11 @@ parameter EXTENSION_ZBS = 0, // Requires: Zbb. (This flag enables instructions in Zbkb which aren't in Zbb.) parameter EXTENSION_ZBKB = 0, +// EXTENSION_ZCB: Support for ZCB basic additional compressed instructions +// Requires: C. (Some Zcb instructions also require Zbb or M.) +// Note Zca is equivalent to C, as we do not support the F extension. +parameter EXTENSION_ZCB = 0, + // EXTENSION_ZIFENCEI: Support for the fence.i instruction // Optional, since a plain branch/jump will also flush the prefetch queue. parameter EXTENSION_ZIFENCEI = 0, diff --git a/hdl/hazard3_config_inst.vh b/hdl/hazard3_config_inst.vh index 63f76cf..e41a378 100644 --- a/hdl/hazard3_config_inst.vh +++ b/hdl/hazard3_config_inst.vh @@ -22,6 +22,7 @@ .EXTENSION_ZBC (EXTENSION_ZBC), .EXTENSION_ZBS (EXTENSION_ZBS), .EXTENSION_ZBKB (EXTENSION_ZBKB), +.EXTENSION_ZCB (EXTENSION_ZCB), .EXTENSION_ZIFENCEI (EXTENSION_ZIFENCEI), .EXTENSION_XH3BEXTM (EXTENSION_XH3BEXTM), .EXTENSION_XH3IRQ (EXTENSION_XH3IRQ), diff --git a/hdl/hazard3_decode.v b/hdl/hazard3_decode.v index 65e7653..0669efb 100644 --- a/hdl/hazard3_decode.v +++ b/hdl/hazard3_decode.v @@ -76,7 +76,7 @@ reg d_invalid_32bit; wire d_invalid = d_invalid_16bit || d_invalid_32bit; hazard3_instr_decompress #( - .PASSTHROUGH(!EXTENSION_C) +`include "hazard3_config_inst.vh" ) decomp ( .instr_in (fd_cir), .instr_is_32bit (d_instr_is_32bit), diff --git a/hdl/hazard3_instr_decompress.v b/hdl/hazard3_instr_decompress.v index 7d8aba6..e633258 100644 --- a/hdl/hazard3_instr_decompress.v +++ b/hdl/hazard3_instr_decompress.v @@ -6,7 +6,7 @@ `default_nettype none module hazard3_instr_decompress #( - parameter PASSTHROUGH = 0 +`include "hazard3_config.vh" ) ( input wire [31:0] instr_in, output reg instr_is_32bit, @@ -17,6 +17,7 @@ module hazard3_instr_decompress #( `include "rv_opcodes.vh" localparam W_REGADDR = 5; +localparam PASSTHROUGH = ~|EXTENSION_C; // Long-register formats: cr, ci, css // Short-register formats: ciw, cl, cs, cb, cj @@ -60,6 +61,20 @@ wire [31:0] imm_cb ={ 7'h00 }; +wire [31:0] imm_c_lb = { + 10'h0, + instr_in[5], + instr_in[6], + 20'h00000 +}; + +wire [31:0] imm_c_lh = { + 10'h000, + instr_in[5], + 1'b0, + 20'h00000 +}; + function [31:0] rfmt_rd; input [4:0] rd; begin rfmt_rd = {20'h00000, rd, 7'h00}; end endfunction function [31:0] rfmt_rs1; input [4:0] rs1; begin rfmt_rs1 = {12'h000, rs1, 15'h0000}; end endfunction function [31:0] rfmt_rs2; input [4:0] rs2; begin rfmt_rs2 = {7'h00, rs2, 20'h00000}; end endfunction @@ -137,6 +152,53 @@ end else begin: instr_decompress | {4'h0, instr_in[8:7], instr_in[12], 13'h0000, instr_in[11:9], 2'b00, 7'h00}; `RVOPC_C_BEQZ: instr_out = `RVOPC_NOZ_BEQ | rfmt_rs1(rs1_s) | imm_cb; `RVOPC_C_BNEZ: instr_out = `RVOPC_NOZ_BNE | rfmt_rs1(rs1_s) | imm_cb; + + // Optional Zbc instructions: + `RVOPC_C_LBU: begin + instr_out = `RVOPC_NOZ_LBU | rfmt_rd(rd_s) | rfmt_rs1(rs1_s) | imm_c_lb; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_LHU: begin + instr_out = `RVOPC_NOZ_LHU | rfmt_rd(rd_s) | rfmt_rs1(rs1_s) | imm_c_lh; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_LH: begin + instr_out = `RVOPC_NOZ_LH | rfmt_rd(rd_s) | rfmt_rs1(rs1_s) | imm_c_lh; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_SB: begin + instr_out = `RVOPC_NOZ_SB | rfmt_rd(rd_s) | rfmt_rs1(rs1_s) | imm_c_lb; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_SH: begin + instr_out = `RVOPC_NOZ_SH | rfmt_rd(rd_s) | rfmt_rs1(rs1_s) | imm_c_lh; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_ZEXT_B: begin + instr_out = `RVOPC_NOZ_ANDI | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s) | 32'h0ff00000; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_SEXT_B: begin + instr_out = `RVOPC_NOZ_SEXT_B | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s); + invalid = ~|EXTENSION_ZCB || ~|EXTENSION_ZBB; + end + `RVOPC_C_ZEXT_H: begin + instr_out = `RVOPC_NOZ_ZEXT_H | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s); + invalid = ~|EXTENSION_ZCB || ~|EXTENSION_ZBB; + end + `RVOPC_C_SEXT_H: begin + instr_out = `RVOPC_NOZ_SEXT_H | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s); + invalid = ~|EXTENSION_ZCB || ~|EXTENSION_ZBB; + end + `RVOPC_C_NOT: begin + instr_out = `RVOPC_NOZ_XORI | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s) | 32'hfff00000; + invalid = ~|EXTENSION_ZCB; + end + `RVOPC_C_MUL: begin + instr_out = `RVOPC_NOZ_MUL | rfmt_rd(rs1_s) | rfmt_rs1(rs1_s) | rfmt_rs2(rs2_s); + invalid = ~|EXTENSION_ZCB || ~|EXTENSION_M; + end + default: invalid = 1'b1; endcase end @@ -146,4 +208,6 @@ endgenerate endmodule +`ifndef YOSYS `default_nettype wire +`endif diff --git a/hdl/rv_opcodes.vh b/hdl/rv_opcodes.vh index 73aa4cc..0df9356 100644 --- a/hdl/rv_opcodes.vh +++ b/hdl/rv_opcodes.vh @@ -181,6 +181,19 @@ localparam RV_RD_BITS = 5; `define RVOPC_C_LWSP 16'b010???????????10 `define RVOPC_C_SWSP 16'b110???????????10 +// Zcb simple additional compressed instructions +`define RVOPC_C_LBU 16'b100000????????00 +`define RVOPC_C_LHU 16'b100001???0????00 +`define RVOPC_C_LH 16'b100001???1????00 +`define RVOPC_C_SB 16'b100010????????00 +`define RVOPC_C_SH 16'b100011???0????00 +`define RVOPC_C_ZEXT_B 16'b100111???1100001 +`define RVOPC_C_SEXT_B 16'b100111???1100101 +`define RVOPC_C_ZEXT_H 16'b100111???1101001 +`define RVOPC_C_SEXT_H 16'b100111???1101101 +`define RVOPC_C_NOT 16'b100111???1110101 +`define RVOPC_C_MUL 16'b100111???10???01 + // Copies provided here with 0 instead of ? so that these can be used to build 32-bit instructions in the decompressor `define RVOPC_NOZ_BEQ 32'b00000000000000000000000001100011 @@ -232,4 +245,10 @@ localparam RV_RD_BITS = 5; `define RVOPC_NOZ_CSRRCI 32'b00000000000000000111000001110011 `define RVOPC_NOZ_SYSTEM 32'b00000000000000000000000001110011 +// Non-RV32I instructions for Zcb: +`define RVOPC_NOZ_MUL 32'b00000010000000000000000000110011 +`define RVOPC_NOZ_SEXT_B 32'b01100000010000000001000000010011 +`define RVOPC_NOZ_SEXT_H 32'b01100000010100000001000000010011 +`define RVOPC_NOZ_ZEXT_H 32'b00001000000000000100000000110011 + `endif diff --git a/test/sim/tb_cxxrtl/config_default.vh b/test/sim/tb_cxxrtl/config_default.vh index 866e3e7..324e60b 100644 --- a/test/sim/tb_cxxrtl/config_default.vh +++ b/test/sim/tb_cxxrtl/config_default.vh @@ -10,6 +10,7 @@ localparam EXTENSION_ZBB = 1; localparam EXTENSION_ZBC = 1; localparam EXTENSION_ZBS = 1; localparam EXTENSION_ZBKB = 1; +localparam EXTENSION_ZCB = 1; localparam EXTENSION_ZIFENCEI = 1; localparam EXTENSION_XH3BEXTM = 1; localparam EXTENSION_XH3IRQ = 1; diff --git a/test/sim/tb_cxxrtl/config_min.vh b/test/sim/tb_cxxrtl/config_min.vh index ca13d08..c79fbae 100644 --- a/test/sim/tb_cxxrtl/config_min.vh +++ b/test/sim/tb_cxxrtl/config_min.vh @@ -10,6 +10,7 @@ localparam EXTENSION_ZBB = 0; localparam EXTENSION_ZBC = 0; localparam EXTENSION_ZBS = 0; localparam EXTENSION_ZBKB = 0; +localparam EXTENSION_ZCB = 0; localparam EXTENSION_ZIFENCEI = 0; localparam EXTENSION_XH3BEXTM = 0; localparam EXTENSION_XH3IRQ = 0;