cva6/core/macro_decoder.sv
Guillaume Chauvon 2ef1c1b1fc
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Update ID stage to support ZCMP, ZCMT and CVXIF with Superscalar (#2756)
Add support for Superscalar with ZCMP, ZCMT and CVXIF.
ZCMP decoder, ZCMT decoder and CVXIF interface driver are using port 0.
Standard RVC and 32 bits instruction can take port 0 or 1.
2025-02-03 13:40:02 +01:00

765 lines
25 KiB
Systemverilog

// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Rohan Arshid, 10xEngineers
// Date: 22.01.2024
// Description: Contains the logic for decoding cm.push, cm.pop, cm.popret,
// cm.popretz, cm.mvsa01, and cm.mva01s instructions of the
// Zcmp Extension
module macro_decoder #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty
) (
input logic [31:0] instr_i,
input logic clk_i, // Clock
input logic rst_ni, // Synchronous reset
input logic is_macro_instr_i, // Intruction is of macro extension
input logic illegal_instr_i, // From compressed decoder
input logic is_compressed_i,
input logic issue_ack_i, // Check if the intruction is acknowledged
output logic [31:0] instr_o,
output logic illegal_instr_o,
output logic is_compressed_o,
output logic fetch_stall_o, //Wait while push/pop/move instructions expand
output logic is_last_macro_instr_o,
output logic is_double_rd_macro_instr_o
);
// FSM States
enum logic [2:0] {
IDLE,
INIT,
PUSH_ADDI,
POPRETZ_1,
MOVE,
PUSH_POP_INSTR_2
}
state_d, state_q;
// Instruction Types
enum logic [2:0] {
PUSH,
POP,
POPRETZ,
POPRET,
MVA01S,
MVSA01
} macro_instr_type;
// Temporary registers
logic [3:0] reg_numbers, reg_numbers_q, reg_numbers_d;
logic [11:0] stack_adj;
logic [4:0] xreg1, xreg2, store_reg, store_reg_q, store_reg_d;
logic [1:0] popretz_inst_q, popretz_inst_d;
logic [11:0] offset_reg, offset_q, offset_d;
logic [31:0] instr_o_reg;
riscv::itype_t itype_inst;
assign instr_o = instr_o_reg;
always_comb begin
illegal_instr_o = 1'b0;
fetch_stall_o = 1'b0;
is_last_macro_instr_o = 1'b0;
is_double_rd_macro_instr_o = 1'b0;
is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i;
reg_numbers = '0;
stack_adj = '0;
state_d = state_q;
offset_d = offset_q;
reg_numbers_d = reg_numbers_q;
store_reg_d = store_reg_q;
popretz_inst_d = popretz_inst_q;
if (is_macro_instr_i) begin
unique case (instr_i[12:10])
// push or pop
3'b110: begin
unique case (instr_i[9:8])
2'b00: begin
macro_instr_type = PUSH;
end
2'b10: begin
macro_instr_type = POP;
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
// popret or popretz
3'b111: begin
unique case (instr_i[9:8])
2'b00: begin
macro_instr_type = POPRETZ;
end
2'b10: begin
macro_instr_type = POPRET;
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
// mvq01s or mvsa01
3'b011: begin
unique case (instr_i[6:5])
2'b01: begin
macro_instr_type = MVSA01;
end
2'b11: begin
macro_instr_type = MVA01S;
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
// Calculate xreg1 & xreg2 for move instructions
if (macro_instr_type == MVSA01 || macro_instr_type == MVA01S) begin
if (instr_i[9:7] != instr_i[4:2]) begin
xreg1 = {instr_i[9:8] > 0, instr_i[9:8] == 0, instr_i[9:7]};
xreg2 = {instr_i[4:3] > 0, instr_i[4:3] == 0, instr_i[4:2]};
end else begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
end else begin
xreg1 = '0;
xreg2 = '0;
end
// push/pop/popret/popretz instructions
unique case (instr_i[7:4])
4'b0100: reg_numbers = 4'b0001; // 4
4'b0101: reg_numbers = 4'b0010; // 5
4'b0110: reg_numbers = 4'b0011; // 6
4'b0111: reg_numbers = 4'b0100; // 7
4'b1000: reg_numbers = 4'b0101; // 8
4'b1001: reg_numbers = 4'b0110; // 9
4'b1010: reg_numbers = 4'b0111; // 10
4'b1011: reg_numbers = 4'b1000; // 11
4'b1100: reg_numbers = 4'b1001; // 12
4'b1101: reg_numbers = 4'b1010; // 13
4'b1110: reg_numbers = 4'b1011; // 14
4'b1111: reg_numbers = 4'b1100; // 15
default: reg_numbers = '0;
endcase
if (CVA6Cfg.XLEN == 32) begin
unique case (instr_i[7:4])
4'b0100, 4'b0101, 4'b0110, 4'b0111: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 16;
2'b01: stack_adj = 32;
2'b10: stack_adj = 48;
2'b11: stack_adj = 64;
endcase
end
4'b1000, 4'b1001, 4'b1010, 4'b1011: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 32;
2'b01: stack_adj = 48;
2'b10: stack_adj = 64;
2'b11: stack_adj = 80;
endcase
end
4'b1100, 4'b1101, 4'b1110: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 48;
2'b01: stack_adj = 64;
2'b10: stack_adj = 80;
2'b11: stack_adj = 96;
endcase
end
4'b1111: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 64;
2'b01: stack_adj = 80;
2'b10: stack_adj = 96;
2'b11: stack_adj = 112;
endcase
end
default: ;
endcase
end else begin
unique case (instr_i[7:4])
4'b0100, 4'b0101: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 16;
2'b01: stack_adj = 32;
2'b10: stack_adj = 48;
2'b11: stack_adj = 64;
endcase
end
4'b0110, 4'b0111: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 32;
2'b01: stack_adj = 48;
2'b10: stack_adj = 64;
2'b11: stack_adj = 80;
endcase
end
4'b1000, 4'b1001: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 48;
2'b01: stack_adj = 64;
2'b10: stack_adj = 80;
2'b11: stack_adj = 96;
endcase
end
4'b1010, 4'b1011: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 64;
2'b01: stack_adj = 80;
2'b10: stack_adj = 96;
2'b11: stack_adj = 112;
endcase
end
4'b1100, 4'b1101: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 80;
2'b01: stack_adj = 96;
2'b10: stack_adj = 112;
2'b11: stack_adj = 128;
endcase
end
4'b1110: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 96;
2'b01: stack_adj = 112;
2'b10: stack_adj = 128;
2'b11: stack_adj = 144;
endcase
end
4'b1111: begin
unique case (instr_i[3:2])
2'b00: stack_adj = 112;
2'b01: stack_adj = 128;
2'b10: stack_adj = 144;
2'b11: stack_adj = 160;
endcase
end
endcase
end
//Take 2's compliment in case of PUSH instruction
if (macro_instr_type == PUSH) begin
itype_inst.imm = ~stack_adj + 1'b1;
end else begin
itype_inst.imm = stack_adj - 12'h4;
end
end else begin
illegal_instr_o = illegal_instr_i;
instr_o_reg = instr_i;
end
unique case (state_q)
IDLE: begin
if (is_macro_instr_i) begin
reg_numbers_d = reg_numbers - 1'b1;
state_d = issue_ack_i ? INIT : IDLE;
case (macro_instr_type)
PUSH: begin
offset_d = 12'hFFC + 12'hFFC;
end
POP, POPRETZ, POPRET: begin
offset_d = itype_inst.imm + 12'hFFC;
offset_reg = itype_inst.imm;
case (macro_instr_type)
POPRETZ: begin
popretz_inst_d = 2'b11;
end
POPRET: begin
popretz_inst_d = 2'b01;
end
default: begin
popretz_inst_d = 'b0;
end
endcase
end
default: ;
endcase
// when rlist is 4, max reg is x18 i.e. 14(const) + 4
// when rlist is 12, max reg is x27 i.e. 15(const) + 12
if (reg_numbers == 4'b1100) begin
store_reg_d = 4'b1110 + reg_numbers;
store_reg = 4'b1111 + reg_numbers;
end else begin
store_reg_d = 4'b1101 + reg_numbers;
store_reg = 4'b1110 + reg_numbers;
end
if (macro_instr_type == MVSA01) begin
fetch_stall_o = 1;
is_double_rd_macro_instr_o = 1;
// addi xreg1, a0, 0
instr_o_reg = {12'h0, 5'hA, 3'h0, xreg1, riscv::OpcodeOpImm};
state_d = MOVE;
end
if (macro_instr_type == MVA01S) begin
fetch_stall_o = 1;
is_double_rd_macro_instr_o = 1;
// addi a0, xreg1, 0
instr_o_reg = {12'h0, xreg1, 3'h0, 5'hA, riscv::OpcodeOpImm};
state_d = MOVE;
end
if (macro_instr_type == PUSH) begin
fetch_stall_o = 1'b1; // stall inst fetch
if (reg_numbers == 4'b0001) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
7'b1111111, 5'h1, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore
}; // sd store_reg, -4(sp)
end else begin
instr_o_reg = {
7'b1111111, 5'h1, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore
}; // sw store_reg, -4(sp)
end
state_d = PUSH_ADDI;
end
if (reg_numbers == 4'b0010) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {7'b1111111, 5'h8, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore};
end else begin
instr_o_reg = {7'b1111111, 5'h8, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore};
end
end
if (reg_numbers == 4'b0011) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {7'b1111111, 5'h9, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore};
end else begin
instr_o_reg = {7'b1111111, 5'h9, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore};
end
end
if (reg_numbers >= 4 && reg_numbers <= 12) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {7'b1111111, store_reg, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore};
end else begin
instr_o_reg = {7'b1111111, store_reg, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore};
end
if (reg_numbers == 12) begin
state_d = PUSH_POP_INSTR_2;
end
end
end
if ((macro_instr_type == POP || macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin
fetch_stall_o = 1; // stall inst fetch
if (reg_numbers == 1) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_reg - 12'h4, 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad
}; // ld store_reg, Imm(sp)
end else begin
instr_o_reg = {
offset_reg, 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad
}; // lw store_reg, Imm(sp)
end
unique case (macro_instr_type)
PUSH, POP, POPRET: begin
state_d = PUSH_ADDI;
end
POPRETZ: begin
state_d = POPRETZ_1;
end
default: ;
endcase
end
if (reg_numbers == 2) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad};
end else begin
instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h8, riscv::OpcodeLoad};
end
end
if (reg_numbers == 3) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad};
end else begin
instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h9, riscv::OpcodeLoad};
end
end
if (reg_numbers >= 4 && reg_numbers <= 12) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, store_reg, riscv::OpcodeLoad};
end else begin
instr_o_reg = {offset_reg, 5'h2, 3'h2, store_reg, riscv::OpcodeLoad};
end
if (reg_numbers == 12) begin
state_d = PUSH_POP_INSTR_2;
end
end
end
end
end
INIT: begin
fetch_stall_o = is_macro_instr_i; // stall inst fetch
if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin
if (reg_numbers_q == 4'b0001) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:5],
5'h1,
5'h2,
3'h3,
offset_d[4:3],
1'b0,
offset_d[1:0],
riscv::OpcodeStore
};
end else begin
instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore};
end
state_d = PUSH_ADDI;
end
if (reg_numbers_q == 4'b0010) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:5],
5'h8,
5'h2,
3'h3,
offset_d[4:3],
1'b0,
offset_d[1:0],
riscv::OpcodeStore
};
end else begin
instr_o_reg = {offset_d[11:5], 5'h8, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore};
end
reg_numbers_d = reg_numbers_q - 1;
offset_d = offset_q + 12'hFFC; // decrement offset by -4 i.e. add 2's compilment of 4
end
if (reg_numbers_q == 4'b0011) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:5],
5'h9,
5'h2,
3'h3,
offset_d[4:3],
1'b0,
offset_d[1:0],
riscv::OpcodeStore
};
end else begin
instr_o_reg = {offset_d[11:5], 5'h9, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore};
end
reg_numbers_d = reg_numbers_q - 1;
offset_d = offset_q + 12'hFFC;
end
if (reg_numbers_q >= 4 && reg_numbers_q <= 12) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:5],
store_reg_q,
5'h2,
3'h3,
offset_d[4:3],
1'b0,
offset_d[1:0],
riscv::OpcodeStore
};
end else begin
instr_o_reg = {
offset_d[11:5], store_reg_q, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore
};
end
reg_numbers_d = reg_numbers_q - 1;
store_reg_d = store_reg_q - 1;
offset_d = offset_q + 12'hFFC;
if (reg_numbers_q == 12) begin
state_d = PUSH_POP_INSTR_2;
end
end
end
if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POP || macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin
if (reg_numbers_q == 1) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad
};
end else begin
instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad};
end
unique case (macro_instr_type)
PUSH, POP, POPRET: begin
state_d = PUSH_ADDI;
end
POPRETZ: begin
state_d = POPRETZ_1;
end
default: ;
endcase
end
if (reg_numbers_q == 2) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad
};
end else begin
instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h8, riscv::OpcodeLoad};
end
reg_numbers_d = reg_numbers_q - 1;
offset_d = offset_q + 12'hFFC; // decrement offset by -4 i.e. add 2's compilment of 4
end
if (reg_numbers_q == 3) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad
};
end else begin
instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h9, riscv::OpcodeLoad};
end
reg_numbers_d = reg_numbers_q - 1;
offset_d = offset_q + 12'hFFC;
end
if (reg_numbers_q >= 4 && reg_numbers_q <= 12) begin
if (CVA6Cfg.XLEN == 64) begin
instr_o_reg = {
offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, store_reg_q, riscv::OpcodeLoad
};
end else begin
instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, store_reg_q, riscv::OpcodeLoad};
end
reg_numbers_d = reg_numbers_q - 1;
store_reg_d = store_reg_q - 1;
offset_d = offset_q + 12'hFFC;
if (reg_numbers_q == 12) begin
state_d = PUSH_POP_INSTR_2;
end
end
end
end
MOVE: begin
case (macro_instr_type)
MVSA01: begin
if (issue_ack_i) begin
// addi xreg2, a1, 0
instr_o_reg = {12'h0, 5'hB, 3'h0, xreg2, riscv::OpcodeOpImm};
fetch_stall_o = 0;
is_last_macro_instr_o = 1;
is_double_rd_macro_instr_o = 1;
state_d = IDLE;
end
end
MVA01S: begin
if (issue_ack_i) begin
// addi a1, xreg2, 0
instr_o_reg = {12'h0, xreg2, 3'h0, 5'hB, riscv::OpcodeOpImm};
fetch_stall_o = 0;
is_last_macro_instr_o = 1;
is_double_rd_macro_instr_o = 1;
state_d = IDLE;
end
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
PUSH_ADDI: begin
if (CVA6Cfg.XLEN == 64) begin
if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin
// addi sp, sp, stack_adj
instr_o_reg = {itype_inst.imm - 12'h4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm};
end else begin
if (issue_ack_i) begin
instr_o_reg = {stack_adj - 12'h4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm};
end
end
if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin
state_d = POPRETZ_1;
fetch_stall_o = 1;
end else begin
if (issue_ack_i) begin
state_d = IDLE;
fetch_stall_o = 0;
is_last_macro_instr_o = 1;
end else begin
fetch_stall_o = 1;
end
end
end else begin
if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin
// addi sp, sp, stack_adj
instr_o_reg = {itype_inst.imm, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm};
end else begin
if (issue_ack_i) begin
instr_o_reg = {stack_adj, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm};
end
end
if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin
state_d = POPRETZ_1;
fetch_stall_o = 1;
end else begin
if (issue_ack_i) begin
state_d = IDLE;
fetch_stall_o = 0;
is_last_macro_instr_o = 1;
end else begin
fetch_stall_o = 1;
end
end
end
end
PUSH_POP_INSTR_2: begin
if (CVA6Cfg.XLEN == 64) begin
case (macro_instr_type)
PUSH: begin
if (issue_ack_i) begin
instr_o_reg = {
offset_d[11:5],
store_reg_q,
5'h2,
3'h3,
offset_d[4:3],
1'b0,
offset_d[1:0],
riscv::OpcodeStore
};
offset_d = offset_q + 12'hFFC;
store_reg_d = store_reg_q - 1;
state_d = INIT;
end
end
POP, POPRETZ, POPRET: begin
if (issue_ack_i) begin
instr_o_reg = {
offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, store_reg_q, riscv::OpcodeLoad
};
offset_d = offset_q + 12'hFFC;
store_reg_d = store_reg_q - 1;
state_d = INIT;
end
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end else begin
case (macro_instr_type)
PUSH: begin
if (issue_ack_i) begin
instr_o_reg = {
offset_d[11:5], store_reg_q, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore
};
offset_d = offset_q + 12'hFFC;
store_reg_d = store_reg_q - 1;
state_d = INIT;
end
end
POP, POPRETZ, POPRET: begin
if (issue_ack_i) begin
instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, store_reg_q, riscv::OpcodeLoad};
offset_d = offset_q + 12'hFFC;
store_reg_d = store_reg_q - 1;
state_d = INIT;
end
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
fetch_stall_o = 1;
end
POPRETZ_1: begin
unique case (popretz_inst_q)
2'b11: begin
if (issue_ack_i) begin
instr_o_reg = {20'h0, 5'hA, riscv::OpcodeLui}; //lui a0, 0x0
popretz_inst_d = popretz_inst_q - 1;
end
fetch_stall_o = 1;
end
2'b10: begin
if (issue_ack_i) begin
instr_o_reg = {12'h0, 5'hA, 3'h0, 5'hA, riscv::OpcodeOpImm}; //addi a0, a0, 0x0
popretz_inst_d = popretz_inst_q - 1;
state_d = PUSH_ADDI;
end
fetch_stall_o = 1;
end
2'b01: begin
if (issue_ack_i) begin
instr_o_reg = {12'h0, 5'h1, 3'h0, 5'h0, riscv::OpcodeJalr}; //ret - jalr x0, x1, 0
state_d = IDLE;
fetch_stall_o = 0;
is_last_macro_instr_o = 1;
popretz_inst_d = popretz_inst_q - 1;
end
end
default: begin
illegal_instr_o = 1'b1;
instr_o_reg = instr_i;
end
endcase
end
default: begin
state_d = IDLE;
end
endcase
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
state_q <= IDLE;
offset_q <= '0;
popretz_inst_q <= '0;
reg_numbers_q <= '0;
store_reg_q <= '0;
end else begin
state_q <= state_d;
offset_q <= offset_d;
reg_numbers_q <= reg_numbers_d;
store_reg_q <= store_reg_d;
popretz_inst_q <= popretz_inst_d;
end
end
endmodule