diff --git a/hw/ip/aes/pre_dv/aes_tb/aes_tb.core b/hw/ip/aes/pre_dv/aes_tb/aes_tb.core index b3fdffa07ffef3..a0a934bdce81c0 100644 --- a/hw/ip/aes/pre_dv/aes_tb/aes_tb.core +++ b/hw/ip/aes/pre_dv/aes_tb/aes_tb.core @@ -19,6 +19,7 @@ filesets: - rtl/aes_tb_pkg.sv - rtl/aes_tb_reqs.sv - rtl/aes_tb_c_dpi.sv + - rtl/dv_regs.sv - rtl/tlul_delayer.sv - rtl/tlul_adapter_tb_reqs.sv - rtl/aes_tb.sv diff --git a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d0.svh b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d0.svh index eb9a680fd6adda..e07689b428f16a 100644 --- a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d0.svh +++ b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d0.svh @@ -105,7 +105,7 @@ read_request(AES_DATA_OUT_2_OFFSET), \ read_request(AES_DATA_OUT_3_OFFSET), \ \ - /* Read Caliptra-specific register */ \ - read_caliptra(CALIPTRA_NAME_0_OFFSET), \ - read_caliptra(CALIPTRA_VERSION_0_OFFSET) \ + /* Read DV-specific register */ \ + read_dv(DV_NAME_0_OFFSET), \ + read_dv(DV_VERSION_0_OFFSET) \ }; diff --git a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d16.svh b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d16.svh index 3662a655d3daa7..dd4f3ddf582173 100644 --- a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d16.svh +++ b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a0_d16.svh @@ -131,7 +131,7 @@ read_request(AES_DATA_OUT_2_OFFSET), \ read_request(AES_DATA_OUT_3_OFFSET), \ \ - /* Read Caliptra-specific register */ \ - read_caliptra(CALIPTRA_NAME_0_OFFSET), \ - read_caliptra(CALIPTRA_VERSION_0_OFFSET) \ + /* Read DV-specific register */ \ + read_dv(DV_NAME_0_OFFSET), \ + read_dv(DV_VERSION_0_OFFSET) \ }; diff --git a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d60.svh b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d60.svh index 1619ce659bd26e..085569ad82be49 100644 --- a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d60.svh +++ b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d60.svh @@ -836,7 +836,7 @@ read_request(AES_DATA_OUT_2_OFFSET), \ read_request(AES_DATA_OUT_3_OFFSET), \ \ - /* Read Caliptra-specific register */ \ - read_caliptra(CALIPTRA_NAME_0_OFFSET), \ - read_caliptra(CALIPTRA_VERSION_0_OFFSET) \ + /* Read DV-specific register */ \ + read_dv(DV_NAME_0_OFFSET), \ + read_dv(DV_VERSION_0_OFFSET) \ }; diff --git a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d64.svh b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d64.svh index 642166d21b014f..16c563b38f45c7 100644 --- a/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d64.svh +++ b/hw/ip/aes/pre_dv/aes_tb/data/gcm_k128_a20_d64.svh @@ -247,7 +247,7 @@ read_request(AES_DATA_OUT_2_OFFSET), \ read_request(AES_DATA_OUT_3_OFFSET), \ \ - /* Read Caliptra-specific register */ \ - read_caliptra(CALIPTRA_NAME_0_OFFSET), \ - read_caliptra(CALIPTRA_VERSION_0_OFFSET) \ + /* Read DV-specific register */ \ + read_dv(DV_NAME_0_OFFSET), \ + read_dv(DV_VERSION_0_OFFSET) \ }; diff --git a/hw/ip/aes/pre_dv/aes_tb/data/modes_d64.svh b/hw/ip/aes/pre_dv/aes_tb/data/modes_d64.svh index 1c63a3ecf832c3..68390d29adf854 100644 --- a/hw/ip/aes/pre_dv/aes_tb/data/modes_d64.svh +++ b/hw/ip/aes/pre_dv/aes_tb/data/modes_d64.svh @@ -3600,7 +3600,7 @@ read_request(AES_DATA_OUT_3_OFFSET), \ read_request(AES_STATUS_OFFSET, 32'(1'b1) << AES_STATUS_IDLE_OFFSET), \ \ - /* Read Caliptra-specific register */ \ - read_caliptra(CALIPTRA_NAME_0_OFFSET), \ - read_caliptra(CALIPTRA_VERSION_0_OFFSET) \ + /* Read DV-specific register */ \ + read_dv(DV_NAME_0_OFFSET), \ + read_dv(DV_VERSION_0_OFFSET) \ }; diff --git a/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb.sv b/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb.sv index 57e1b466176913..aaffd9eb4ed65b 100644 --- a/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb.sv +++ b/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb.sv @@ -101,11 +101,11 @@ module aes_tb end aes_tb_reqs u_aes_tb_reqs ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .pop_req_i ( bus_pop ), - .req_o ( bus_req ), - .done_o ( bus_done ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .pop_req_i ( bus_pop ), + .req_o ( bus_req ), + .done_o ( bus_done ) ); // Every request that is not a `c_dpi_load` counts as a valid bus access. @@ -114,43 +114,89 @@ module aes_tb // The shim converts inputs from the valid-hold protocol into TLUL requests. if (ShimEnable) begin : gen_tlul_adapter_shim + + logic int_dv; + logic [top_pkg::TL_AW-1:0] int_addr; + logic int_write; + logic [top_pkg::TL_DW-1:0] int_wdata; + logic [top_pkg::TL_DBW-1:0] int_wstrb; + logic [2:0] int_size; + logic int_hld; + logic [top_pkg::TL_DW-1:0] int_rdata; + logic int_error; + logic int_last; + logic [31:0] int_user; + logic [top_pkg::TL_AIW-1:0] int_id; + tlul_adapter_shim #( .EnableDataIntgGen ( EnableDataIntgGen ), .EnableRspDataIntgCheck ( EnableRspDataIntgCheck ) ) u_tlul_adapter_shim ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .tl_i ( tl_d2h_delayed ), - .tl_o ( tl_h2d ), - .dv_i ( bus_en ), - .addr_i ( bus_req.addr ), - .write_i ( bus_req.write ), - .wdata_i ( bus_req.wdata ), - .wstrb_i ( 4'b1111 ), - .size_i ( 3'b010 ), - .hld_o ( bus_wait ), - .rdata_o ( bus_rdata ), - .error_o ( bus_error ), - .last_i ( 1'b0 ), - .user_i ( 32'(TL_A_USER_DEFAULT) ), - .id_i ( '0 ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .tl_i ( tl_d2h_delayed ), + .tl_o ( tl_h2d ), + // DV to TLUL + .dv_i ( bus_en ), + .addr_i ( bus_req.addr ), + .write_i ( bus_req.write ), + .wdata_i ( bus_req.wdata ), + .wstrb_i ( 4'b1111 ), + .size_i ( 3'b010 ), + .hld_o ( bus_wait ), + .rdata_o ( bus_rdata ), + .error_o ( bus_error ), + .last_i ( 1'b0 ), + .user_i ( 32'(TL_A_USER_DEFAULT) ), + .id_i ( '0 ), + // DV to internal register + .int_dv_o ( int_dv ), + .int_addr_o ( int_addr ), + .int_write_o ( int_write ), + .int_wdata_o ( int_wdata ), + .int_wstrb_o ( int_wstrb ), + .int_size_o ( int_size ), + .int_hld_i ( int_hld ), + .int_rdata_i ( int_rdata ), + .int_error_i ( int_error ), + .int_last_o ( int_last ), + .int_user_o ( int_user ), + .int_id_o ( int_id ) ); + + dv_regs u_dv_regs ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .dv_i ( int_dv ), + .addr_i ( int_addr ), + .write_i ( int_write ), + .wdata_i ( int_wdata ), + .wstrb_i ( int_wstrb ), + .size_i ( int_size ), + .hld_o ( int_hld ), + .rdata_o ( int_rdata ), + .error_o ( int_error ), + .last_i ( int_last ), + .user_i ( int_user ), + .id_i ( int_id ) + ); + end else begin : gen_tlul_adapter tlul_adapter_tb_reqs #( .EnableDataIntgGen ( EnableDataIntgGen ), .EnableRspDataIntgCheck ( EnableRspDataIntgCheck ) ) u_tlul_adapter_tb_reqs ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .tl_i ( tl_d2h_delayed ), - .tl_o ( tl_h2d ), - .en_i ( bus_en ), - .wait_o ( bus_wait ), - .addr_i ( bus_req.addr ), - .write_i ( bus_req.write ), - .wdata_i ( bus_req.wdata ), - .rdata_o ( bus_rdata ), - .error_o ( bus_error ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .tl_i ( tl_d2h_delayed ), + .tl_o ( tl_h2d ), + .en_i ( bus_en ), + .wait_o ( bus_wait ), + .addr_i ( bus_req.addr ), + .write_i ( bus_req.write ), + .wdata_i ( bus_req.wdata ), + .rdata_o ( bus_rdata ), + .error_o ( bus_error ) ); end @@ -228,7 +274,7 @@ module aes_tb end end - logic [31:0] data_mask; + logic [31:0] data_mask; assign data_mask = data_cntr_q >= 4 ? 32'hffff_ffff : data_cntr_q == 3 ? 32'h00ff_ffff : data_cntr_q == 2 ? 32'h0000_ffff : diff --git a/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb_pkg.sv b/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb_pkg.sv index e79da4420b22f9..3c758743bdc7eb 100644 --- a/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb_pkg.sv +++ b/hw/ip/aes/pre_dv/aes_tb/rtl/aes_tb_pkg.sv @@ -30,11 +30,11 @@ package aes_tb_pkg; parameter int AES_TRIGGER_DATA_OUT_CLEAR_OFFSET = 2; parameter int AES_TRIGGER_PRNG_RESEED_OFFSET = 3; - // Caliptra register offsets - parameter logic [11:0] CALIPTRA_NAME_0_OFFSET = 12'h100; - parameter logic [11:0] CALIPTRA_NAME_1_OFFSET = 12'h104; - parameter logic [11:0] CALIPTRA_VERSION_0_OFFSET = 12'h108; - parameter logic [11:0] CALIPTRA_VERSION_1_OFFSET = 12'h10c; + // DV register offsets + parameter logic [11:0] DV_NAME_0_OFFSET = 12'h100; + parameter logic [11:0] DV_NAME_1_OFFSET = 12'h104; + parameter logic [11:0] DV_VERSION_0_OFFSET = 12'h108; + parameter logic [11:0] DV_VERSION_1_OFFSET = 12'h10c; `include `REQUESTS_FILE @@ -98,10 +98,10 @@ package aes_tb_pkg; return req; endfunction - // read_caliptra returns a filled out `bus_request_t` struct for an internal Caliptra register. - // This is only useful if a TLUL-to-Shim adapter is configured otherwise the request will result - // in a zero-value being returned by the register file. - function automatic bus_request_t read_caliptra (logic [11:0] addr); + // read_dv returns a filled out `bus_request_t` struct for an internal register. This is only + // useful if a TLUL-to-Shim adapter is configured otherwise the request will result in a + // zero-value being returned by the register file. + function automatic bus_request_t read_dv (logic [11:0] addr); bus_request_t req = '{ c_dpi_load: 1'b0, write: 1'b0, diff --git a/hw/ip/aes/pre_dv/aes_tb/rtl/dv_regs.sv b/hw/ip/aes/pre_dv/aes_tb/rtl/dv_regs.sv new file mode 100644 index 00000000000000..6fadf235ec5a8a --- /dev/null +++ b/hw/ip/aes/pre_dv/aes_tb/rtl/dv_regs.sv @@ -0,0 +1,60 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Dummy placeholder module for a DV register file supporting same-cycle reads of name and version +// registers. + +module dv_regs + import tlul_pkg::*; +#( + parameter bit [31:0] DV_NAME_0 = 32'hDEADBEEF, + parameter bit [31:0] DV_NAME_1 = 32'hCAFEBABE, + parameter bit [31:0] DV_VERSION_0 = 32'h00000001, + parameter bit [31:0] DV_VERSION_1 = 32'h00000000, + + parameter int ADDR_WIDTH = top_pkg::TL_AW, + parameter int DATA_WIDTH = top_pkg::TL_DW, + parameter int MASK_WIDTH = DATA_WIDTH >> 3, + parameter int USER_WIDTH = 32, + parameter int ID_WIDTH = top_pkg::TL_AIW +) ( + input clk_i, + input rst_ni, + + input logic dv_i, + output logic hld_o, + input logic [ADDR_WIDTH-1:0] addr_i, + input logic write_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic [MASK_WIDTH-1:0] wstrb_i, + input logic [2:0] size_i, + output logic [DATA_WIDTH-1:0] rdata_o, + output logic error_o, + // Optional signals + input logic last_i, + input logic [USER_WIDTH-1:0] user_i, + input logic [ID_WIDTH-1:0] id_i +); + + always_comb begin + rdata_o = '0; + if (dv_i) begin + unique case (addr_i[3:0]) + 4'h0: rdata_o = DV_NAME_0; + 4'h4: rdata_o = DV_NAME_1; + 4'h8: rdata_o = DV_VERSION_0; + 4'hc: rdata_o = DV_VERSION_1; + default: rdata_o = '0; + endcase + end + end + + assign hld_o = 1'b0; + assign error_o = 1'b0; + + logic unused_signals; + assign unused_signals = ^{clk_i, rst_ni, addr_i[31:4], write_i, wdata_i, wstrb_i, size_i, last_i, + user_i, id_i}; + +endmodule diff --git a/hw/ip/tlul/rtl/tlul_adapter_shim.sv b/hw/ip/tlul/rtl/tlul_adapter_shim.sv index c17170a8572878..9c59796caa828c 100644 --- a/hw/ip/tlul/rtl/tlul_adapter_shim.sv +++ b/hw/ip/tlul/rtl/tlul_adapter_shim.sv @@ -8,21 +8,16 @@ module tlul_adapter_shim import tlul_pkg::*; import prim_mubi_pkg::mubi4_t; #( - parameter bit [31:0] SHIM_NAME_0 = 32'hDEADBEEF, - parameter bit [31:0] SHIM_NAME_1 = 32'hCAFEBABE, - parameter bit [31:0] SHIM_VERSION_0 = 32'h00000001, - parameter bit [31:0] SHIM_VERSION_1 = 32'h00000000, + parameter int ADDR_WIDTH = top_pkg::TL_AW, + parameter int DATA_WIDTH = top_pkg::TL_DW, + parameter int MASK_WIDTH = DATA_WIDTH >> 3, + parameter int USER_WIDTH = 32, + parameter int ID_WIDTH = top_pkg::TL_AIW, - parameter bit [11:0] SHIM_REGISTER_ADDRESS_OFFSET = 12'h100, + parameter bit [ADDR_WIDTH-1:0] DV_REGISTER_ADDRESS_OFFSET = 32'h0000_0100, - parameter int ADDR_WIDTH = top_pkg::TL_AW, - parameter int DATA_WIDTH = top_pkg::TL_DW, - parameter int MASK_WIDTH = DATA_WIDTH >> 3, - parameter int USER_WIDTH = 32, - parameter int ID_WIDTH = top_pkg::TL_AIW, - - parameter bit EnableDataIntgGen = 1, - parameter bit EnableRspDataIntgCheck = 1 + parameter bit EnableDataIntgGen = 1, + parameter bit EnableRspDataIntgCheck = 1 ) ( input clk_i, input rst_ni, @@ -30,7 +25,7 @@ module tlul_adapter_shim output tl_h2d_t tl_o, input tl_d2h_t tl_i, - // Shim interface + // DV device interface (DV to TLUL). input logic dv_i, output logic hld_o, input logic [ADDR_WIDTH-1:0] addr_i, @@ -40,21 +35,35 @@ module tlul_adapter_shim input logic [2:0] size_i, output logic [DATA_WIDTH-1:0] rdata_o, output logic error_o, - // Optional signals input logic last_i, input logic [USER_WIDTH-1:0] user_i, - input logic [ID_WIDTH-1:0] id_i + input logic [ID_WIDTH-1:0] id_i, + + // DV host interface (DV to internal registers). The signals from the DV device interface are + // routed to the DV host interface for every internal access, see the `internal_access` signal. + output logic int_dv_o, + input logic int_hld_i, + output logic [ADDR_WIDTH-1:0] int_addr_o, + output logic int_write_o, + output logic [DATA_WIDTH-1:0] int_wdata_o, + output logic [MASK_WIDTH-1:0] int_wstrb_o, + output logic [2:0] int_size_o, + input logic [DATA_WIDTH-1:0] int_rdata_i, + input logic int_error_i, + output logic int_last_o, + output logic [USER_WIDTH-1:0] int_user_o, + output logic [ID_WIDTH-1:0] int_id_o ); // Differentiate between two levels of acknowledgements: - // - `req_ack`: A host-to-device request is acknowledged by the device, - // meaning that the response is pending. + // - `req_ack`: A host-to-device request is acknowledged by the device, meaning that the response + // is pending. // - `resp_ack`: The device-to-host response is acknowledged. logic pending_d, pending_q; logic req_ack, resp_ack; - assign req_ack = dv_i & tl_i.a_ready & tl_o.a_valid & ~internal_read; - assign resp_ack = dv_i & tl_o.d_ready & tl_i.d_valid & ~internal_read; + assign req_ack = dv_i & tl_i.a_ready & tl_o.a_valid & ~internal_access; + assign resp_ack = dv_i & tl_o.d_ready & tl_i.d_valid & ~internal_access; always_comb begin pending_d = pending_q; @@ -73,12 +82,12 @@ module tlul_adapter_shim end end - // Only make a new request (through `a_valid`) to the device when none are - // pending. If the integrity checks are enabled, the `a_user` fields will be - // set by the corresponding module (see `tlul_cmd_intg_gen`). + // Only make a new request (through `a_valid`) to the device when none are pending. If the + // integrity checks are enabled, the `a_user` fields will be set by the corresponding module (see + // `tlul_cmd_intg_gen`). tlul_pkg::tl_h2d_t tl_o_pre; assign tl_o_pre = '{ - a_valid: dv_i & ~pending_q & ~internal_read, + a_valid: dv_i & ~pending_q & ~internal_access, a_opcode: ~write_i ? Get : (&wstrb_i ? PutFullData : PutPartialData), a_size: top_pkg::TL_SZW'(size_i), a_mask: wstrb_i, @@ -91,27 +100,28 @@ module tlul_adapter_shim a_param: 3'h0 }; - logic internal_read; - assign internal_read = |(addr_i[11:0] & SHIM_REGISTER_ADDRESS_OFFSET); - - // Accesses to shim internal registers have no latency. Accesses to device registers are - // acknowledged with the TLUL d-channel handshake. - assign hld_o = !pending_q && internal_read ? 1'b0 : - pending_q && tl_o.d_ready && tl_i.d_valid ? 1'b0 : 1'b1; - - // A read request to an internal register is resolved in the same clock cycle. - always_comb begin - rdata_o = tl_i.d_data; - if (internal_read) begin - unique case (addr_i[3:0]) - 4'h0: rdata_o = SHIM_NAME_0; - 4'h4: rdata_o = SHIM_NAME_1; - 4'h8: rdata_o = SHIM_VERSION_0; - 4'hc: rdata_o = SHIM_VERSION_1; - default: rdata_o = tl_i.d_data; - endcase - end - end + // The shim distinguishes between two types of DV accesses: those going to an internal register + // file and those targeting OpenTitan registers, with the latter ones being translated into TLUL + // requests while the other requests are relayed to the internal register file. + logic internal_access; + assign internal_access = |(addr_i & DV_REGISTER_ADDRESS_OFFSET); + + // Accesses to device registers are acknowledged with the TLUL d-channel handshake. + assign hld_o = !pending_q && internal_access && !int_hld_i ? 1'b0 : + pending_q && tl_o.d_ready && tl_i.d_valid ? 1'b0 : 1'b1; + + assign rdata_o = internal_access ? int_rdata_i : tl_i.d_data; + + // Route signals to the DV host interface. + assign int_dv_o = dv_i & internal_access; + assign int_addr_o = addr_i; + assign int_write_o = write_i; + assign int_wdata_o = wdata_i; + assign int_wstrb_o = wstrb_i; + assign int_size_o = size_i; + assign int_last_o = last_i; + assign int_user_o = user_i; + assign int_id_o = id_i; tlul_cmd_intg_gen #( .EnableDataIntgGen (EnableDataIntgGen) @@ -128,10 +138,7 @@ module tlul_adapter_shim .err_o ( intg_err_chk ) ); - assign error_o = tl_i.d_error | intg_err_chk; - - logic unused_signals; - assign unused_signals = ^{last_i, user_i, size_i[2]}; + assign error_o = tl_i.d_error | int_error_i | intg_err_chk; // Make sure the shim parameters are compatible with TLUL datapath widths. `ASSERT_INIT(TlInvalidAddrWidth_A, ADDR_WIDTH == top_pkg::TL_AW)