[entropy_src/rtl] field enable has only 2 value states

For a 4 bit field, logic has been added to only respond to a value of 0xa and a value of 0x5.

Signed-off-by: Mark Branstad <mark.branstad@wdc.com>
diff --git a/hw/ip/entropy_src/entropy_src.core b/hw/ip/entropy_src/entropy_src.core
index 4b95d56..5002ec7 100644
--- a/hw/ip/entropy_src/entropy_src.core
+++ b/hw/ip/entropy_src/entropy_src.core
@@ -19,6 +19,7 @@
       - rtl/entropy_src_reg_pkg.sv
       - rtl/entropy_src_reg_top.sv
       - rtl/entropy_src_watermark_reg.sv
+      - rtl/entropy_src_field_en.sv
       - rtl/entropy_src_cntr_reg.sv
       - rtl/entropy_src_ack_sm.sv
       - rtl/entropy_src_main_sm.sv
diff --git a/hw/ip/entropy_src/rtl/entropy_src.sv b/hw/ip/entropy_src/rtl/entropy_src.sv
index 664b47a..f0c9449 100644
--- a/hw/ip/entropy_src/rtl/entropy_src.sv
+++ b/hw/ip/entropy_src/rtl/entropy_src.sv
@@ -211,7 +211,6 @@
       stub_hw2reg = '0;
 
       // as long as enable is 1, do not allow registers to be written
-      stub_hw2reg.regwen.d = ~|reg2hw.conf.enable.q;
       stub_hw2reg.fw_ov_rd_data.d = stub_lfsr_value[31:0];
       stub_hw2reg.entropy_data.d = stub_lfsr_value[31:0];
       stub_hw2reg.debug_status.main_sm_idle.d = 1'b1;
diff --git a/hw/ip/entropy_src/rtl/entropy_src_core.sv b/hw/ip/entropy_src/rtl/entropy_src_core.sv
index 9e0a90e..647235e 100644
--- a/hw/ip/entropy_src/rtl/entropy_src_core.sv
+++ b/hw/ip/entropy_src/rtl/entropy_src_core.sv
@@ -62,8 +62,7 @@
   localparam int ObserveFifoDepth = 64;
   localparam int PreCondWidth = 64;
   localparam int Clog2ObserveFifoDepth = $clog2(ObserveFifoDepth);
-  // TODO: remove or enable below
-  // localparam int FieldEnableWidth = 4;
+  localparam int FieldEnableWidth = 4;
 
   //-----------------------
   // SHA3 parameters
@@ -443,50 +442,39 @@
   // set up secure enable bits
   //--------------------------------------------
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_es_enable (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.enable.qe),
-//    .wdata_i                (reg2hw.conf.enable.q),
-//    .enable_o               (es_enable_pfe)
-//  );
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_es_enable (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.enable.qe),
+    .wdata_i                (reg2hw.conf.enable.q),
+    .enable_o               (es_enable_pfe)
+  );
 
-  assign es_enable_pfe = (es_enb_e'(reg2hw.conf.enable.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_lfsr_enable (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.lfsr_enable.qe),
+    .wdata_i                (reg2hw.conf.lfsr_enable.q),
+    .enable_o               (lfsr_enable_pfe)
+  );
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_lfsr_enable (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.lfsr_enable.qe),
-//    .wdata_i                (reg2hw.conf.lfsr_enable.q),
-//    .enable_o               (lfsr_enable_pfe)
-//  );
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_entropy_data_reg_en (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.entropy_data_reg_enable.qe),
+    .wdata_i                (reg2hw.conf.entropy_data_reg_enable.q),
+    .enable_o               (entropy_data_reg_en_pfe)
+  );
 
-  assign lfsr_enable_pfe = (es_enb_e'(reg2hw.conf.lfsr_enable.q) == ES_FIELD_ON);
-
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_entropy_data_reg_en (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.entropy_data_reg_enable.qe),
-//    .wdata_i                (reg2hw.conf.entropy_data_reg_enable.q),
-//    .enable_o               (entropy_data_reg_en_pfe)
-//  );
-
-  assign entropy_data_reg_en_pfe =
-         (es_enb_e'(reg2hw.conf.entropy_data_reg_enable.q) == ES_FIELD_ON);
-
-//  assign es_enable_d = reg2hw.conf.enable.q;  // TODO: remove
   assign es_enable_d = {lfsr_enable_pfe,es_enable_pfe};
   assign es_enable_early = lfsr_enable_pfe || es_enable_pfe;
   assign es_enable = (|es_enable_q);
@@ -495,34 +483,27 @@
   assign load_seed = !es_enable;
   assign observe_fifo_thresh = reg2hw.observe_fifo_thresh.q;
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_fw_ov_mode (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.fw_ov_control.fw_ov_mode.qe),
-//    .wdata_i                (reg2hw.fw_ov_control.fw_ov_mode.q),
-//    .enable_o               (fw_ov_mode_pfe)
-//  );
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_fw_ov_mode (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.fw_ov_control.fw_ov_mode.qe),
+    .wdata_i                (reg2hw.fw_ov_control.fw_ov_mode.q),
+    .enable_o               (fw_ov_mode_pfe)
+  );
 
-  assign fw_ov_mode_pfe = (es_enb_e'(reg2hw.fw_ov_control.fw_ov_mode.q) == ES_FIELD_ON);
-
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_fw_ov_entropy_insert (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.fw_ov_control.fw_ov_entropy_insert.qe),
-//    .wdata_i                (reg2hw.fw_ov_control.fw_ov_entropy_insert.q),
-//    .enable_o               (fw_ov_entropy_insert_pfe)
-//  );
-
-  assign fw_ov_entropy_insert_pfe =
-         (es_enb_e'(reg2hw.fw_ov_control.fw_ov_entropy_insert.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_fw_ov_entropy_insert (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.fw_ov_control.fw_ov_entropy_insert.qe),
+    .wdata_i                (reg2hw.fw_ov_control.fw_ov_entropy_insert.q),
+    .enable_o               (fw_ov_entropy_insert_pfe)
+  );
 
   // firmware override controls
   assign fw_ov_mode = efuse_es_sw_ov_en_i && fw_ov_mode_pfe;
@@ -793,19 +774,16 @@
 
   // pack esrng bus into signal bit packer
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_rng_bit_en (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.rng_bit_enable.qe),
-//    .wdata_i                (reg2hw.conf.rng_bit_enable.q),
-//    .enable_o               (rng_bit_en_pfe)
-//  );
-
-  assign rng_bit_en_pfe = (es_enb_e'(reg2hw.conf.rng_bit_enable.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_rng_bit_en (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.rng_bit_enable.qe),
+    .wdata_i                (reg2hw.conf.rng_bit_enable.q),
+    .enable_o               (rng_bit_en_pfe)
+  );
 
   assign rng_bit_en = rng_bit_en_pfe;
   assign rng_bit_sel = reg2hw.conf.rng_bit_sel.q;
@@ -857,19 +835,16 @@
   assign markov_active = es_enable;
   assign extht_active = es_enable;
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_health_test_clr (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.health_test_clr.qe),
-//    .wdata_i                (reg2hw.conf.health_test_clr.q),
-//    .enable_o               (health_test_clr_pfe)
-//  );
-
-  assign health_test_clr_pfe = (es_enb_e'(reg2hw.conf.health_test_clr.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_health_test_clr (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.health_test_clr.qe),
+    .wdata_i                (reg2hw.conf.health_test_clr.q),
+    .enable_o               (health_test_clr_pfe)
+  );
 
   assign health_test_clr = health_test_clr_pfe;
 
@@ -1240,47 +1215,38 @@
   assign event_es_health_test_failed = es_main_sm_alert;
   assign event_es_observe_fifo_ready = observe_fifo_thresh_met;
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_es_route (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.entropy_control.es_route.qe),
-//    .wdata_i                (reg2hw.entropy_control.es_route.q),
-//    .enable_o               (es_route_pfe)
-//  );
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_es_route (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.entropy_control.es_route.qe),
+    .wdata_i                (reg2hw.entropy_control.es_route.q),
+    .enable_o               (es_route_pfe)
+  );
 
-  assign es_route_pfe = (es_enb_e'(reg2hw.entropy_control.es_route.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_es_type (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.entropy_control.es_type.qe),
+    .wdata_i                (reg2hw.entropy_control.es_type.q),
+    .enable_o               (es_type_pfe)
+  );
 
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_es_type (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.entropy_control.es_type.qe),
-//    .wdata_i                (reg2hw.entropy_control.es_type.q),
-//    .enable_o               (es_type_pfe)
-//  );
-
-  assign es_type_pfe = (es_enb_e'(reg2hw.entropy_control.es_type.q) == ES_FIELD_ON);
-
-  // TODO: remove or enable prim_field_enable
-//  prim_field_enable #(
-//    .FieldW(FieldEnableWidth),
-//    .FieldEnVal(int'(ES_FIELD_ON))
-//  ) u_prim_field_enable_boot_bypass_dis (
-//    .clk_i                  (clk_i),
-//    .rst_ni                 (rst_ni),
-//    .wvalid_i               (reg2hw.conf.boot_bypass_disable.qe),
-//    .wdata_i                (reg2hw.conf.boot_bypass_disable.q),
-//    .enable_o               (boot_bypass_dis_pfe)
-//  );
-
-  assign boot_bypass_dis_pfe = (es_enb_e'(reg2hw.conf.boot_bypass_disable.q) == ES_FIELD_ON);
+  entropy_src_field_en #(
+    .FieldW(FieldEnableWidth),
+    .FieldEnVal(int'(ES_FIELD_ON))
+  ) u_entropy_src_field_en_boot_bypass_dis (
+    .clk_i                  (clk_i),
+    .rst_ni                 (rst_ni),
+    .wvalid_i               (reg2hw.conf.boot_bypass_disable.qe),
+    .wdata_i                (reg2hw.conf.boot_bypass_disable.q),
+    .enable_o               (boot_bypass_dis_pfe)
+  );
 
   assign es_route_to_sw = es_route_pfe;
   assign es_bypass_to_sw = es_type_pfe;
diff --git a/hw/ip/entropy_src/rtl/entropy_src_field_en.sv b/hw/ip/entropy_src/rtl/entropy_src_field_en.sv
new file mode 100644
index 0000000..70d75b7
--- /dev/null
+++ b/hw/ip/entropy_src/rtl/entropy_src_field_en.sv
@@ -0,0 +1,54 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Supports writing a field that enables
+// a function within a module.
+// Requirements are that the function will
+// only be enabled when the field is written
+// the it is the inverse of the current field
+// setting. The can only toggle between the
+// the on value and the off value.
+
+
+module entropy_src_field_en #(
+  parameter int FieldW  = 4,
+  parameter int FieldEnVal = 'ha
+) (
+  input logic clk_i ,
+  input logic rst_ni,
+  input logic               wvalid_i,
+  input logic [FieldW-1:0]  wdata_i,
+
+  output logic              enable_o
+);
+
+  // signal
+  logic  field_update;
+  logic [FieldW-1:0] field_value;
+  logic [FieldW-1:0] field_value_invert;
+
+  // flops
+  logic [FieldW-1:0] field_q, field_d;
+
+  assign  field_value = FieldEnVal;
+  assign  field_value_invert = ~field_value;
+
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      field_q <= field_value_invert;
+    end else begin
+      field_q <= field_d;
+    end
+  end
+
+  assign field_update = wvalid_i && (field_q == ~wdata_i) &&
+                        ((wdata_i == field_value) ||
+                         (wdata_i == field_value_invert));
+
+  assign field_d = field_update ? wdata_i : field_q;
+
+  assign enable_o = (field_q == field_value);
+
+
+endmodule