fpga/rfnoc: Add license checker block

Original-commit: 5dad6c370f776981987afc2770d8a0ed0fb29575
This commit is contained in:
Martin Braun
2024-05-27 17:05:06 +02:00
committed by joergho
parent cc28ffff60
commit 77d07a9714
7 changed files with 775 additions and 5 deletions
+31 -5
View File
@@ -43,6 +43,12 @@
// ID that was written. Bit 31 tells us if the feature
// was unlocked. The rest tells us which feature index
// it is.
// - RB_FID_ADDR (BASE_ADDR+12): Readback, will return a feature flag this
// module was compiled with. On the next read,
// it will return the next feature ID. To
// learn all feature IDs that this module knows,
// keep reading this register until values
// repeat.
//
// Parameters:
//
@@ -64,8 +70,7 @@ module license_check #(
parameter SERIAL_W = 96,
parameter NUM_FEATURES = 1,
parameter [(32*NUM_FEATURES)-1:0] FEATURE_IDS = {32'hC0DE},
parameter [PKEY_W-1:0] PRIVATE_KEY = 0,
parameter DEVICE_TYPE = "ULTRASCALE"
parameter [PKEY_W-1:0] PRIVATE_KEY = 0
)(
input wire clk,
input wire rst,
@@ -113,6 +118,7 @@ module license_check #(
localparam FID_ADDR = BASE_ADDR;
localparam KEY_ADDR = BASE_ADDR + 4;
localparam RB_ADDR = BASE_ADDR + 8;
localparam RB_FID_ADDR = BASE_ADDR + 12;
// States
typedef enum logic [2:0] {
@@ -123,6 +129,11 @@ module license_check #(
ST_CTRLPORT_ERROR
} state_t;
typedef enum logic {
ST_RB_ENABLED,
ST_RB_FIDS
} rb_state_t;
// Registers & Wires
state_t state = ST_IDLE;
reg key_valid = 1'b0; // Tracks if current hash matches
@@ -130,6 +141,9 @@ module license_check #(
reg [2:0] word_cnt = 3'd7; // Track which word we are currently comparing
// The index of the feature ID we're hashing/comparing
reg [FIDXREG_W-1:0] feature_idx = NO_FID;
// The index of the last feature ID we returned on RB_FID_ADDR
reg [FIDXREG_W-1:0] rb_feature_idx = (NUM_FEATURES - 1);
reg rb_last_req = ST_RB_ENABLED;
wire fid_wr_req = (s_ctrlport_req_wr && (s_ctrlport_req_addr == FID_ADDR));
wire key_wr_req = (s_ctrlport_req_wr && (s_ctrlport_req_addr == KEY_ADDR));
@@ -172,6 +186,8 @@ module license_check #(
// On reset, all features are disabled. Otherwise, they always stay on.
feature_enabled <= {NUM_FEATURES{1'b0}};
feature_idx <= NO_FID;
// Reset the readback feature index
rb_feature_idx <= (NUM_FEATURES - 1);
end else case (state)
ST_IDLE : begin
//// Idle state: We're waiting on input via CtrlPort.
@@ -225,6 +241,14 @@ module license_check #(
// Handle readback
end else if (s_ctrlport_req_rd && (s_ctrlport_req_addr == RB_ADDR)) begin
state <= ST_ACK;
rb_last_req <= ST_RB_ENABLED;
end else if (s_ctrlport_req_rd && (s_ctrlport_req_addr == RB_FID_ADDR)) begin
state <= ST_ACK;
rb_last_req <= ST_RB_FIDS;
rb_feature_idx <= rb_feature_idx == (NUM_FEATURES-1)
? {FIDXREG_W{1'b0}}
: (rb_feature_idx + 1);
// Any other read/write request is ignored
end else begin
@@ -257,9 +281,11 @@ module license_check #(
assign s_ctrlport_resp_status =
(state == ST_CTRLPORT_ERROR) ? CTRL_STS_CMDERR : CTRL_STS_OKAY;
assign s_ctrlport_resp_data = (feature_idx == NO_FID)
? 32'b0
: {feature_enabled[feature_idx], {(31-FIDXREG_W){1'b0}}, feature_idx};
assign s_ctrlport_resp_data = (rb_last_req == ST_RB_ENABLED) ?
((feature_idx == NO_FID)
? 32'b0
: {feature_enabled[feature_idx], {(31-FIDXREG_W){1'b0}}, feature_idx})
: (FEATURE_IDS[(32*rb_feature_idx) +: 32]);
endmodule