Skip to content

Commit ab0564f

Browse files
etterlinasahlpa
authored andcommitted
[kmac,rtl] Add bypass to message FIFO to support 2 shares
The FIFO only supports one share. This adds an at runtime selectable bypass mode so two shares can directly be send towards the hashing backend. This feature is current not used and thus the 2nd share is fixed to '0. Signed-off-by: Pascal Etterli <pascal.etterli@lowrisc.org>
1 parent dfd9c25 commit ab0564f

3 files changed

Lines changed: 120 additions & 53 deletions

File tree

hw/ip/kmac/rtl/kmac.sv

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,6 @@ module kmac
217217
logic [kmac_pkg::MsgStrbW-1:0] msgfifo_strb ;
218218
logic msgfifo_ready ;
219219

220-
if (EnMasking) begin : gen_msgfifo_data_masked
221-
// In Masked mode, the input message data is split into two shares.
222-
// Only concern, however, here is the secret key. So message can be
223-
// put into only one share and other is 0.
224-
assign msgfifo_data[1] = '0;
225-
end
226-
227220
// TL-UL Adapter(MSG_FIFO) signals
228221
logic tlram_req;
229222
logic tlram_gnt;
@@ -244,7 +237,7 @@ module kmac
244237

245238
// KeyMgr interface to MSG_FIFO
246239
logic mux2fifo_valid;
247-
logic [kmac_pkg::MsgWidth-1:0] mux2fifo_data;
240+
logic [kmac_pkg::MsgWidth-1:0] mux2fifo_data[Share];
248241
logic [kmac_pkg::MsgWidth-1:0] mux2fifo_strb;
249242
logic mux2fifo_ready;
250243

@@ -1146,9 +1139,10 @@ module kmac
11461139
.fifo_data_i (mux2fifo_data),
11471140
.fifo_strb_i (mux2fifo_strb),
11481141
.fifo_ready_o (mux2fifo_ready),
1142+
.fifo_bypass_i('0),
11491143

11501144
.msg_valid_o (msgfifo_valid),
1151-
.msg_data_o (msgfifo_data[0]),
1145+
.msg_data_o (msgfifo_data),
11521146
.msg_strb_o (msgfifo_strb),
11531147
.msg_ready_i (msgfifo_ready),
11541148

hw/ip/kmac/rtl/kmac_app.sv

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module kmac_app
5151

5252
// to MSG_FIFO
5353
output logic kmac_valid_o,
54-
output logic [MsgWidth-1:0] kmac_data_o,
54+
output logic [MsgWidth-1:0] kmac_data_o[Share],
5555
// This strobe is on bit level for the packer. The FIFO will then convert it again to byte level.
5656
output logic [MsgWidth-1:0] kmac_strb_o,
5757
input kmac_ready_i,
@@ -616,14 +616,14 @@ module kmac_app
616616
sw_ready_o = 1'b 1;
617617

618618
kmac_valid_o = 1'b 0;
619-
kmac_data_o = '0;
619+
kmac_data_o = '{default:'0};
620620
kmac_strb_o = '0;
621621

622622
unique case (mux_sel_buf_kmac)
623623
SelApp: begin
624624
// app_id is valid at this time
625-
kmac_valid_o = app_i[app_id].valid;
626-
kmac_data_o = app_i[app_id].data;
625+
kmac_valid_o = app_i[app_id].valid;
626+
kmac_data_o[0] = app_i[app_id].data;
627627
// Expand strb to bits. prim_packer inside MSG_FIFO accepts the bit masks
628628
for (int i = 0 ; i < $bits(app_i[app_id].strb) ; i++) begin
629629
kmac_strb_o[8*i+:8] = {8{app_i[app_id].strb[i]}};
@@ -633,21 +633,21 @@ module kmac_app
633633

634634
SelOutLen: begin
635635
// Write encoded output length value
636-
kmac_valid_o = 1'b 1; // always write
637-
kmac_data_o = MsgWidth'(encoded_outlen);
638-
kmac_strb_o = MsgWidth'(encoded_outlen_strb);
636+
kmac_valid_o = 1'b 1; // always write
637+
kmac_data_o[0] = MsgWidth'(encoded_outlen);
638+
kmac_strb_o = MsgWidth'(encoded_outlen_strb);
639639
end
640640

641641
SelSw: begin
642-
kmac_valid_o = sw_valid_i;
643-
kmac_data_o = sw_data_i ;
644-
kmac_strb_o = sw_strb_i ;
645-
sw_ready_o = kmac_ready_i ;
642+
kmac_valid_o = sw_valid_i;
643+
kmac_data_o[0] = sw_data_i ;
644+
kmac_strb_o = sw_strb_i ;
645+
sw_ready_o = kmac_ready_i ;
646646
end
647647

648648
default: begin // Incl. SelNone
649649
kmac_valid_o = 1'b 0;
650-
kmac_data_o = '0;
650+
kmac_data_o = '{default:'0};
651651
kmac_strb_o = '0;
652652
end
653653

hw/ip/kmac/rtl/kmac_msgfifo.sv

Lines changed: 105 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ module kmac_msgfifo
1515
// pushing to MsgFIFO
1616
parameter int OutWidth = 64,
1717

18-
parameter bit EnMasking = 1'b 1,
18+
parameter bit EnMasking = 1'b 1,
19+
localparam int Share = (EnMasking) ? 2 : 1, // derived parameter
1920

2021
// Internal MsgFIFO Entry count
2122
parameter int MsgDepth = 9,
@@ -25,16 +26,17 @@ module kmac_msgfifo
2526
input rst_ni,
2627

2728
// from REG or KeyMgr Intf input
28-
input fifo_valid_i,
29-
input [OutWidth-1:0] fifo_data_i,
29+
input logic fifo_valid_i,
30+
input [OutWidth-1:0] fifo_data_i[Share],
3031
input [OutWidth-1:0] fifo_strb_i,
31-
output fifo_ready_o,
32+
output logic fifo_ready_o,
33+
input logic fifo_bypass_i,
3234

3335
// MSG interface
3436
output logic msg_valid_o,
35-
output logic [OutWidth-1:0] msg_data_o,
37+
output logic [OutWidth-1:0] msg_data_o[Share],
3638
output logic [OutWidth/8-1:0] msg_strb_o,
37-
input msg_ready_i,
39+
input logic msg_ready_i,
3840

3941
output logic fifo_empty_o,
4042
output logic fifo_full_o,
@@ -43,14 +45,52 @@ module kmac_msgfifo
4345
// Control
4446
input prim_mubi_pkg::mubi4_t clear_i,
4547

46-
// process_i --> process_o
47-
// process_o asserted after all internal messages are flushed out to MSG interface
48-
input process_i,
48+
// When process_i is asserted, packer and FIFO are flushed. Once flushed, process_o is asserted.
49+
// When bypassing, nothing must be flushed.
50+
input logic process_i,
4951
output logic process_o,
5052

5153
err_t err_o
5254
);
5355

56+
//////////////////
57+
// Bypass logic //
58+
//////////////////
59+
// The packing and FIFO only support one share. These can be bypassed if operating with shares.
60+
logic fifo_valid;
61+
logic fifo_ready;
62+
logic [OutWidth/8-1:0] fifo_strb_byte;
63+
logic msg_valid;
64+
logic msg_ready;
65+
logic [OutWidth-1:0] msg_data[Share];
66+
logic [OutWidth/8-1:0] msg_strb;
67+
68+
// Reduce strobe from bit to byte level as KMAC core operates on byte strobes.
69+
always_comb begin
70+
fifo_strb_byte = '0;
71+
for (int i = 0; i < $bits(fifo_strb_byte); i++) begin
72+
fifo_strb_byte[i] = |fifo_strb_i[8 * i +: 8];
73+
end
74+
end
75+
76+
assign fifo_valid = fifo_bypass_i ? '0 : fifo_valid_i;
77+
assign fifo_ready_o = fifo_bypass_i ? msg_ready_i : fifo_ready;
78+
assign msg_valid_o = fifo_bypass_i ? fifo_valid_i : msg_valid;
79+
assign msg_ready = fifo_bypass_i ? '0 : msg_ready_i;
80+
assign msg_strb_o = fifo_bypass_i ? fifo_strb_byte : msg_strb;
81+
82+
for (genvar i = 0; i < Share; i++) begin : g_msg_data_bypass_mux
83+
assign msg_data_o[i] = fifo_bypass_i ? fifo_data_i[i] : msg_data[i];
84+
end
85+
86+
// If bypassing, packer and FIFO must not be flushed so we can gate the flush signal and
87+
// feed it directly to process_o.
88+
logic process_to_fifo;
89+
logic process_from_fifo;
90+
91+
assign process_to_fifo = fifo_bypass_i ? '0 : process_i;
92+
assign process_o = fifo_bypass_i ? process_i : process_from_fifo;
93+
5494
/////////////////
5595
// Definitions //
5696
/////////////////
@@ -99,37 +139,41 @@ module kmac_msgfifo
99139

100140
// packer flush to msg_fifo, then msg_fifo empty out the internals
101141
// then assert msgfifo_flush_done
142+
logic packer_flush;
102143
logic packer_flush_done;
103144
logic msgfifo_flush_done;
104145

105146
logic packer_err;
106147

148+
assign packer_flush = process_to_fifo;
149+
107150
// SEC_CM: PACKER.CTR.REDUN
108151
prim_packer #(
109-
.InW (OutWidth),
110-
.OutW (OutWidth),
111-
.HintByteData (1),
152+
.InW(OutWidth),
153+
.OutW(OutWidth),
154+
.HintByteData(1),
112155

113156
// Turn on dup counter when EnMasking is set
114-
.EnProtection (EnMasking)
157+
.EnProtection(EnMasking)
115158
) u_packer (
116159
.clk_i,
117160
.rst_ni,
118161

119-
.valid_i (fifo_valid_i),
120-
.data_i (fifo_data_i),
121-
.mask_i (fifo_strb_i),
122-
.ready_o (fifo_ready_o),
162+
.valid_i(fifo_valid),
163+
// FIFO operates only on one share
164+
.data_i (fifo_data_i[0]),
165+
.mask_i (fifo_strb_i),
166+
.ready_o(fifo_ready),
123167

124-
.valid_o (packer_wvalid),
125-
.data_o (packer_wdata),
126-
.mask_o (packer_wmask),
127-
.ready_i (packer_wready),
168+
.valid_o(packer_wvalid),
169+
.data_o (packer_wdata),
170+
.mask_o (packer_wmask),
171+
.ready_i(packer_wready),
128172

129-
.flush_i (process_i),
130-
.flush_done_o (packer_flush_done),
173+
.flush_i (packer_flush),
174+
.flush_done_o(packer_flush_done),
131175

132-
.err_o (packer_err)
176+
.err_o(packer_err)
133177
);
134178

135179
// Assign packer wdata and wmask to FIFO struct
@@ -171,10 +215,13 @@ module kmac_msgfifo
171215
assign fifo_wvalid = packer_wvalid;
172216
assign packer_wready = fifo_wready;
173217

174-
assign msg_valid_o = fifo_rvalid;
175-
assign fifo_rready = msg_ready_i;
176-
assign msg_data_o = fifo_rdata.data;
177-
assign msg_strb_o = fifo_rdata.strb;
218+
assign msg_valid = fifo_rvalid;
219+
assign fifo_rready = msg_ready;
220+
assign msg_strb = fifo_rdata.strb;
221+
assign msg_data[0] = fifo_rdata.data;
222+
for (genvar i = 1; i < Share; i++) begin : g_msg_data_mask_assignment
223+
assign msg_data[i] = '0;
224+
end
178225

179226
assign fifo_empty_o = !fifo_rvalid;
180227

@@ -196,7 +243,9 @@ module kmac_msgfifo
196243

197244
unique case (flush_st)
198245
FlushIdle: begin
199-
if (process_i) begin
246+
// Only enter packer-flush sequence when not in bypass mode.
247+
// In bypass mode, process_o is driven directly from process_i below.
248+
if (packer_flush) begin
200249
flush_st_d = FlushPacker;
201250
end else begin
202251
flush_st_d = FlushIdle;
@@ -235,7 +284,7 @@ module kmac_msgfifo
235284
endcase
236285
end
237286

238-
assign process_o = msgfifo_flush_done;
287+
assign process_from_fifo = msgfifo_flush_done;
239288

240289
err_t error;
241290
assign err_o = error;
@@ -273,12 +322,36 @@ module kmac_msgfifo
273322
`ASSERT(FlushStInValid_A, flush_st inside {FlushIdle, FlushPacker, FlushFifo, FlushClear})
274323

275324
// Packer done signal is asserted at least one cycle later
276-
`ASSERT(PackerDoneDelay_A, $onehot0({process_i, packer_flush_done}))
325+
`ASSERT(PackerDoneDelay_A, $onehot0({packer_flush, packer_flush_done}))
277326

278327
// process_i not asserted during the flush operation
279-
`ASSUME(PackerDoneValid_a, process_i |-> flush_st == FlushIdle)
328+
`ASSUME(PackerDoneValid_a, packer_flush |-> flush_st == FlushIdle)
280329

281330
// No messages in between `process_i` and `clear_i`
282331
`ASSUME(MessageValid_a, fifo_valid_i |-> flush_st == FlushIdle)
283332

333+
`ifdef INC_ASSERT
334+
// INC_ASSERT is used to hide signal definitions that are only used for assertions.
335+
//VCS coverage off
336+
// pragma coverage off
337+
338+
// Assert that fifo_bypass_i remains stable once the first messages was handshaked until the FIFO
339+
// has been flushed or the full message is sent downstream, respectively.
340+
logic first_data_entered;
341+
always_ff @(posedge clk_i or negedge rst_ni) begin
342+
if (!rst_ni) begin
343+
first_data_entered <= 1'b0;
344+
end else if (fifo_valid_i && fifo_ready_o) begin
345+
first_data_entered <= 1'b1;
346+
end else if (process_o) begin
347+
first_data_entered <= 1'b0;
348+
end
349+
end
350+
351+
`ASSERT(BypassCtrlStable_A,
352+
first_data_entered && !process_o
353+
|-> fifo_bypass_i == $past(fifo_bypass_i))
354+
355+
`endif
356+
284357
endmodule

0 commit comments

Comments
 (0)