diff --git a/rtl/hwpe_ctrl_package.sv b/rtl/hwpe_ctrl_package.sv index 980d398..b2784a7 100644 --- a/rtl/hwpe_ctrl_package.sv +++ b/rtl/hwpe_ctrl_package.sv @@ -73,6 +73,7 @@ package hwpe_ctrl_package; logic is_critical; logic is_testset; logic is_trigger; + logic is_commit; logic is_working; logic [$clog2(REGFILE_N_CONTEXT)-1:0] pointer_context; logic [$clog2(REGFILE_N_CONTEXT)-1:0] running_context; diff --git a/rtl/hwpe_ctrl_slave.sv b/rtl/hwpe_ctrl_slave.sv index 6af0a10..c19912b 100644 --- a/rtl/hwpe_ctrl_slave.sv +++ b/rtl/hwpe_ctrl_slave.sv @@ -51,8 +51,8 @@ module hwpe_ctrl_slave regfile_in_t regfile_in; regfile_out_t regfile_out; - enum logic [1:0] {idle, running, starting} running_state; - enum logic {idle_c, trigger} context_state; + enum logic [1:0] {RUN_IDLE, RUN_RUN, RUN_STARTING} running_state; + enum logic {CXT_IDLE, CXT_PROGRAM} context_state; flags_regfile_t regfile_flags; @@ -66,6 +66,8 @@ module hwpe_ctrl_slave logic [1:0] s_clear_regfile; logic clear_regfile; + logic triggered_q; + always_ff @(posedge clk_i or negedge rst_ni) begin if(rst_ni == 1'b0) @@ -77,6 +79,21 @@ module hwpe_ctrl_slave end end + always_ff @(posedge clk_i or negedge rst_ni) + begin + if(rst_ni == 1'b0) + triggered_q <= '0; + else if(clear_o) begin + triggered_q <= '0; + end + else if(regfile_flags.is_trigger) begin + triggered_q <= '1; + end + else if(running_context == pointer_context && regfile_flags.full_context == '0 && regfile_flags.true_done == 1) begin + triggered_q <= '0; + end + end + assign flags_o.done = regfile_flags.true_done; generate @@ -92,7 +109,7 @@ module hwpe_ctrl_slave end else begin - if (regfile_flags.is_trigger == 1) + if (regfile_flags.is_commit == 1) begin for(int i=0; i N_MANDATORY_REGS+N_RESERVED_REGS+N_MAX_GENERIC_REGS-1) ? 1 : 0; // Accessed reg is contexted regfile_flags.is_read = (cfg.req == 1'b1 && cfg.wen == 1'b1); regfile_flags.is_testset = (cfg.req == 1'b1 && cfg.wen == 1'b1 && cfg.add[LOG_REGS+2-1:2] == REGFILE_MANDATORY_ACQUIRE) ? 1 : 0; // Operation is a test&set to register context_ts - regfile_flags.is_trigger = (cfg.req == 1'b1 && cfg.wen == 1'b0 && cfg.add[LOG_REGS+2-1:2] == REGFILE_MANDATORY_TRIGGER) ? 1 : 0; // Operation is a trigger + regfile_flags.is_trigger = (cfg.req == 1'b1 && cfg.wen == 1'b0 && cfg.add[LOG_REGS+2-1:2] == REGFILE_MANDATORY_TRIGGER && cfg.data == '0) ? 1 : 0; // Operation is a trigger + regfile_flags.is_commit = (cfg.req == 1'b1 && cfg.wen == 1'b0 && cfg.add[LOG_REGS+2-1:2] == REGFILE_MANDATORY_TRIGGER) ? 1 : 0; // Operation is a commit (or commit & trigger) regfile_flags.true_done = ctrl_i.done & flags_o.is_working; // This is necessary because sometimes done is asserted as soon as rst_ni becomes 1 flags_o.enable = s_enable_after[3]; // Enable after three cycles from rst_ni end @@ -238,15 +256,6 @@ module hwpe_ctrl_slave assign cfg.r_data = regfile_out.rdata; - logic start_context; - generate - if(N_CONTEXT>1) - assign start_context = (running_context==pointer_context && regfile_flags.full_context==0) ? 1 : 0; - else - assign start_context = (regfile_flags.is_trigger==1 && flags_o.is_working==0) ? 1 : 0; - - endgenerate - // Extension read and write enable, accessing ID LSB logic ext_access; logic [4:0] ext_id_n; @@ -287,49 +296,49 @@ module hwpe_ctrl_slave always_ff @(posedge clk_i or negedge rst_ni) begin : fsm_running if (rst_ni==0) begin - running_state <= idle; + running_state <= RUN_IDLE; flags_o.start <= 0; flags_o.is_working <= 0; end else if(clear_o == 1'b1) begin - running_state <= idle; + running_state <= RUN_IDLE; flags_o.start <= 0; flags_o.is_working <= 0; end else begin case (running_state) - idle : begin + RUN_IDLE : begin if (running_context == pointer_context && regfile_flags.full_context == 0) begin - running_state <= idle; + running_state <= RUN_IDLE; flags_o.start <= 0; flags_o.is_working <= 0; end - else begin - running_state <= starting; + else if(regfile_flags.is_trigger | triggered_q) begin + running_state <= RUN_STARTING; flags_o.start <= 0; flags_o.is_working <= 1; end end - starting : begin - // just to separate idle and running by an additional cycle - running_state <= running; + RUN_STARTING : begin + // just to separate RUN_IDLE and running by an additional cycle + running_state <= RUN_RUN; flags_o.start <= 1; flags_o.is_working <= 1; end - running : begin + RUN_RUN : begin if (regfile_flags.true_done == 1) begin - running_state <= idle; + running_state <= RUN_IDLE; flags_o.start <= 0; flags_o.is_working <= 0; end else begin - running_state <= running; + running_state <= RUN_RUN; flags_o.start <= 0; flags_o.is_working <= 1; end end default : begin - running_state <= idle; + running_state <= RUN_IDLE; flags_o.start <= 0; flags_o.is_working <= 0; end @@ -342,32 +351,32 @@ module hwpe_ctrl_slave begin : fsm_context if (rst_ni==0) begin regfile_flags.is_critical <= 0; - context_state <= idle_c; + context_state <= CXT_IDLE; end else if(clear_o == 1'b1) begin regfile_flags.is_critical <= 0; - context_state <= idle_c; + context_state <= CXT_IDLE; end else begin case (context_state) - idle_c : begin + CXT_IDLE : begin if (regfile_flags.is_testset == 1 && regfile_flags.full_context==0) begin regfile_flags.is_critical <= 1; - context_state <= trigger; + context_state <= CXT_PROGRAM; end else begin regfile_flags.is_critical <= 0; - context_state <= idle_c; + context_state <= CXT_IDLE; end end - trigger : begin - if (regfile_flags.is_trigger == 1) begin + CXT_PROGRAM : begin + if (regfile_flags.is_commit == 1) begin regfile_flags.is_critical <= 0; - context_state <= idle_c; + context_state <= CXT_IDLE; end else begin regfile_flags.is_critical <= 1; - context_state <= trigger; + context_state <= CXT_PROGRAM; end end endcase