I'm looking to simplify an expression for decoding the opcode for a risc v microcontroller:
always @ * begin
case (opcode)
LOAD | LOAD_FP | MISC_MEM | OP_IMM OP_IMM_32 : begin // I_TYPE
imm[0] <= inst[20];
imm[4:1] <= inst[24:21];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
STORE | STORE_FP | AMO : begin // S_TYPE
imm[0] <= inst[7];
imm[4:1] <= inst[11:8];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
BRANCH, JALR : begin // B_TYPE
imm[0] <= 0;
imm[4:1] <= inst[11:8];
imm[10:5] <= inst[30:25];
imm[11] <= inst[7];
imm[31:12] <= inst[31];
end
AUIPC, LUI, OP_32 : begin // U_TYPE
imm[11:0] <= 0;
imm[19:12] <= inst[19:12];
imm[30:20] <= inst[30:25];
imm[31] <= inst[31];
end
JAL, SYSTEM : begin // J_TYPE
imm[0] <= 0;
imm[4:1] <= inst[24:21];
imm[10:5] <= inst[30:25];
imm[11] <= inst[20];
imm[19:12] <= inst[19:12];
imm[31:20] <= inst[30];
end
default :
imm <= 0;
endcase
end
to somewthing like this:
always @ * begin
case (opcode)
I_TYPE : begin
imm[0] <= inst[20];
imm[4:1] <= inst[24:21];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
S_TYPE : begin
imm[0] <= inst[7];
imm[4:1] <= inst[11:8];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
// ...continued
default :
imm <= 0;
endcase
end
Is this possible, can I add methods to an enum/class like in c , is this worth doing, if so how? this is my enum:
typedef enum logic [6:2] {
LOAD = 5'b00_000, LOAD_FP = 5'b00_001, CUSTOM_0 = 5'b00_010, MISC_MEM = 5'b00_011, OP_IMM = 5'b00_100, AUIPC = 5'b00_101, OP_IMM_32 = 5'b00_110, OP_48_1 = 5'b00_111,
STORE = 5'b01_000, STORE_FP = 5'b01_001, CUSTOM_1 = 5'b01_010, AMO = 5'b01_011, OP = 5'b01_100, LUI = 5'b01_101, OP_32 = 5'b01_110, OP_64 = 5'b01_111,
MADD = 5'b10_000, MSUB = 5'b10_001, NMSUB = 5'b10_010, NMADD = 5'b10_011, OP_FP = 5'b10_100, RESERVED_6 = 5'b10_101, CUSTOM_2 = 5'b10_110, OP_48_2 = 5'b10_111,
BRANCH = 5'b11_000, JALR = 5'b11_001, RESERVED_A = 5'b11_010, JAL = 5'b11_011, SYSTEM = 5'b11_100, RESERVED_D = 5'b11_101, CUSTOM_3 = 5'b11_110, OP_80 = 5'b11_111
} base_opcode_map;
If not can somebody tell me the kind of pattern I need to follow?
CodePudding user response:
There are a few things you can do. You can use a let
construct
let I_TYPE = opcode inside {LOAD, LOAD_FP, MISC_MEM, OP_IMM, OP_IMM_32};
let S_TYPE = opcode inside {STORE, STORE_FP, AMO};
...
let
is a shorthand for defining a simple function
function bit I_TYPE;
return opcode inside {LOAD, LOAD_FP, MISC_MEM, OP_IMM, OP_IMM_32};
endfunction
function bit S_TYPE;
return opcode inside {STORE, STORE_FP, AMO};
endfunction
Then you can write a case
statement
always @ * begin
case (1'b1)
I_TYPE : begin
imm[0] <= inst[20];
imm[4:1] <= inst[24:21];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
S_TYPE : begin
imm[0] <= inst[7];
imm[4:1] <= inst[11:8];
imm[10:5] <= inst[30:25];
imm[31:11] <= inst[31];
end
// ...continued
default :
imm <= 0;
endcase
end