blob: 0ee014dd70c02a1bd3b9914d846ee18c5a7f0268 [file] [log] [blame]
module ibex_dummy_instr (
clk_i,
rst_ni,
dummy_instr_en_i,
dummy_instr_mask_i,
dummy_instr_seed_en_i,
dummy_instr_seed_i,
fetch_valid_i,
id_in_ready_i,
insert_dummy_instr_o,
dummy_instr_data_o
);
input wire clk_i;
input wire rst_ni;
input wire dummy_instr_en_i;
input wire [2:0] dummy_instr_mask_i;
input wire dummy_instr_seed_en_i;
input wire [31:0] dummy_instr_seed_i;
input wire fetch_valid_i;
input wire id_in_ready_i;
output wire insert_dummy_instr_o;
output wire [31:0] dummy_instr_data_o;
localparam [31:0] TIMEOUT_CNT_W = 5;
localparam [31:0] OP_W = 5;
localparam [31:0] LFSR_OUT_W = ((2 + OP_W) + OP_W) + TIMEOUT_CNT_W;
wire [(((2 + OP_W) + OP_W) + TIMEOUT_CNT_W) - 1:0] lfsr_data;
wire [TIMEOUT_CNT_W - 1:0] dummy_cnt_incr;
wire [TIMEOUT_CNT_W - 1:0] dummy_cnt_threshold;
wire [TIMEOUT_CNT_W - 1:0] dummy_cnt_d;
reg [TIMEOUT_CNT_W - 1:0] dummy_cnt_q;
wire dummy_cnt_en;
wire lfsr_en;
wire [LFSR_OUT_W - 1:0] lfsr_state;
wire insert_dummy_instr;
reg [6:0] dummy_set;
reg [2:0] dummy_opcode;
wire [31:0] dummy_instr;
reg [31:0] dummy_instr_seed_q;
wire [31:0] dummy_instr_seed_d;
assign lfsr_en = insert_dummy_instr & id_in_ready_i;
assign dummy_instr_seed_d = dummy_instr_seed_q ^ dummy_instr_seed_i;
always @(posedge clk_i or negedge rst_ni)
if (!rst_ni)
dummy_instr_seed_q <= {32 {1'sb0}};
else if (dummy_instr_seed_en_i)
dummy_instr_seed_q <= dummy_instr_seed_d;
prim_lfsr #(
.LfsrDw(32),
.StateOutDw(LFSR_OUT_W)
) lfsr_i(
.clk_i(clk_i),
.rst_ni(rst_ni),
.seed_en_i(dummy_instr_seed_en_i),
.seed_i(dummy_instr_seed_d),
.lfsr_en_i(lfsr_en),
.entropy_i('0),
.state_o(lfsr_state)
);
function automatic [(((2 + OP_W) + OP_W) + TIMEOUT_CNT_W) - 1:0] sv2v_cast_4AF33;
input reg [(((2 + OP_W) + OP_W) + TIMEOUT_CNT_W) - 1:0] inp;
sv2v_cast_4AF33 = inp;
endfunction
assign lfsr_data = sv2v_cast_4AF33(lfsr_state);
assign dummy_cnt_threshold = lfsr_data[TIMEOUT_CNT_W - 1-:TIMEOUT_CNT_W] & {dummy_instr_mask_i, {TIMEOUT_CNT_W - 3 {1'b1}}};
assign dummy_cnt_incr = dummy_cnt_q + {{TIMEOUT_CNT_W - 1 {1'b0}}, 1'b1};
assign dummy_cnt_d = (insert_dummy_instr ? {TIMEOUT_CNT_W {1'sb0}} : dummy_cnt_incr);
assign dummy_cnt_en = (dummy_instr_en_i & id_in_ready_i) & (fetch_valid_i | insert_dummy_instr);
always @(posedge clk_i or negedge rst_ni)
if (!rst_ni)
dummy_cnt_q <= {TIMEOUT_CNT_W {1'sb0}};
else if (dummy_cnt_en)
dummy_cnt_q <= dummy_cnt_d;
assign insert_dummy_instr = dummy_instr_en_i & (dummy_cnt_q == dummy_cnt_threshold);
localparam [1:0] DUMMY_ADD = 2'b00;
localparam [1:0] DUMMY_AND = 2'b11;
localparam [1:0] DUMMY_DIV = 2'b10;
localparam [1:0] DUMMY_MUL = 2'b01;
always @(*)
case (lfsr_data[2 + (OP_W + (OP_W + (TIMEOUT_CNT_W - 1)))-:((2 + (OP_W + (OP_W + (TIMEOUT_CNT_W - 1)))) - (OP_W + (OP_W + TIMEOUT_CNT_W))) + 1])
DUMMY_ADD: begin
dummy_set = 7'b0000000;
dummy_opcode = 3'b000;
end
DUMMY_MUL: begin
dummy_set = 7'b0000001;
dummy_opcode = 3'b000;
end
DUMMY_DIV: begin
dummy_set = 7'b0000001;
dummy_opcode = 3'b100;
end
DUMMY_AND: begin
dummy_set = 7'b0000000;
dummy_opcode = 3'b111;
end
default: begin
dummy_set = 7'b0000000;
dummy_opcode = 3'b000;
end
endcase
assign dummy_instr = {dummy_set, lfsr_data[OP_W + (OP_W + (TIMEOUT_CNT_W - 1))-:((OP_W + (OP_W + (TIMEOUT_CNT_W - 1))) - (OP_W + TIMEOUT_CNT_W)) + 1], lfsr_data[OP_W + (TIMEOUT_CNT_W - 1)-:((OP_W + (TIMEOUT_CNT_W - 1)) - TIMEOUT_CNT_W) + 1], dummy_opcode, 5'h00, 7'h33};
assign insert_dummy_instr_o = insert_dummy_instr;
assign dummy_instr_data_o = dummy_instr;
endmodule