|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | // | 
|  | // AES reg status | 
|  | // | 
|  | // This module tracks the collective status of multiple registers. | 
|  |  | 
|  | module aes_reg_status #( | 
|  | parameter int Width = 1 | 
|  | ) ( | 
|  | input  logic             clk_i, | 
|  | input  logic             rst_ni, | 
|  |  | 
|  | input  logic [Width-1:0] we_i, | 
|  | input  logic             use_i, | 
|  | input  logic             clear_i, | 
|  | input  logic             arm_i, | 
|  | output logic             new_o, | 
|  | output logic             new_pulse_o, | 
|  | output logic             clean_o | 
|  | ); | 
|  |  | 
|  | logic [Width-1:0] we_d, we_q; | 
|  | logic             armed_d, armed_q; | 
|  | logic             all_written; | 
|  | logic             none_written; | 
|  | logic             new_d, new_q; | 
|  | logic             clean_d, clean_q; | 
|  |  | 
|  | // Collect write operations. Upon clear or use, we start over. If armed, the next write will | 
|  | // restart the tracking. | 
|  | assign we_d    = (clear_i || use_i) ? '0   : | 
|  | (armed_q && |we_i) ? we_i : (we_q | we_i); | 
|  | assign armed_d = (clear_i || use_i) ? 1'b0 : | 
|  | (armed_q && |we_i) ? 1'b0 : armed_q | arm_i; | 
|  |  | 
|  | always_ff @(posedge clk_i or negedge rst_ni) begin : reg_ops | 
|  | if (!rst_ni) begin | 
|  | we_q    <= '0; | 
|  | armed_q <= 1'b0; | 
|  | end else begin | 
|  | we_q    <= we_d; | 
|  | armed_q <= armed_d; | 
|  | end | 
|  | end | 
|  |  | 
|  | // Status tracking | 
|  | assign all_written  =  &we_d; | 
|  | assign none_written = ~|we_d; | 
|  |  | 
|  | // We have a complete new value if all registers have been written at least once. | 
|  | assign new_d   = (clear_i || use_i) ? 1'b0 : all_written; | 
|  |  | 
|  | // We have a clean value, if either: | 
|  | // - all registers have been written at least once, or | 
|  | // - no registers have been written but the value was clean previsously. | 
|  | // A value is NOT clean, if either: | 
|  | // - we get a clear or reset, or | 
|  | // - some but not all registers have been written. | 
|  | assign clean_d =  clear_i      ? 1'b0    : | 
|  | all_written  ? 1'b1    : | 
|  | none_written ? clean_q : 1'b0; | 
|  |  | 
|  | always_ff @(posedge clk_i or negedge rst_ni) begin : reg_status | 
|  | if (!rst_ni) begin | 
|  | new_q   <= 1'b0; | 
|  | clean_q <= 1'b0; | 
|  | end else begin | 
|  | new_q   <= new_d; | 
|  | clean_q <= clean_d; | 
|  | end | 
|  | end | 
|  |  | 
|  | assign new_o       = new_q; | 
|  | assign new_pulse_o = new_d & ~new_q; | 
|  | assign clean_o     = clean_q; | 
|  |  | 
|  | endmodule |