@@ -63,6 +63,12 @@ module snitch_tcdm_interconnect #(
63
63
typedef logic [StrbWidth- 1 : 0 ] strb_t ;
64
64
`MEM_TYPEDEF_REQ_CHAN_T (mem_req_chan_t, addr_t, data_t, strb_t, user_t);
65
65
66
+ // Do not assert unconditional stability on write data inside interconnects,
67
+ // as write data may freely change on (non-atomic) reads. We properly assert
68
+ // conditional write data stability below.
69
+ localparam mem_req_chan_t MemReqAsrtMask =
70
+ '{ data: '0 , strb: '0 , amo: reqrsp_pkg :: amo_op_e ' ('1 ), default : '1 } ;
71
+
66
72
// Width of the bank select signal.
67
73
localparam int unsigned SelWidth = cf_math_pkg :: idx_width (NumOut);
68
74
typedef logic [SelWidth- 1 : 0 ] select_t ;
@@ -88,7 +94,7 @@ module snitch_tcdm_interconnect #(
88
94
logic [NumInp- 1 : 0 ] req_q_valid_flat, rsp_q_ready_flat;
89
95
logic [NumOut- 1 : 0 ] mem_q_valid_flat, mem_q_ready_flat;
90
96
91
- // The usual struct packing unpacking.
97
+ // The usual struct packing unpacking; also check write stability here .
92
98
for (genvar i = 0 ; i < NumInp; i++ ) begin : gen_flat_inp
93
99
assign req_q_valid_flat[i] = req_i[i].q_valid;
94
100
assign rsp_o[i].q_ready = rsp_q_ready_flat[i];
@@ -100,6 +106,22 @@ module snitch_tcdm_interconnect #(
100
106
strb: req_i[i].q.strb,
101
107
user: req_i[i].q.user
102
108
} ;
109
+
110
+ // Write data must also be stable during AMOs, so include this case in assertions.
111
+ logic in_req_alters_mem;
112
+ assign in_req_alters_mem = in_req[i].write | (in_req[i].amo != reqrsp_pkg :: AMONone);
113
+
114
+ // TODO: we could clean this up with an additional common_cells assertion macro.
115
+ `ifndef VERILATOR
116
+ `ifndef SYNTHESIS
117
+ assert property (@ (posedge clk_i) disable iff (~ rst_ni) (req_q_valid_flat[i] &&
118
+ ! rsp_q_ready_flat[i] && in_req_alters_mem | => $stable (in_req[i].data))) else
119
+ $error (" write data during non-read is unstable at input: %0d " , i);
120
+ assert property (@ (posedge clk_i) disable iff (~ rst_ni) (req_q_valid_flat[i] &&
121
+ ! rsp_q_ready_flat[i] && in_req_alters_mem | => $stable (in_req[i].strb))) else
122
+ $error (" write strobe during non-read is unstable at input: %0d " , i);
123
+ `endif
124
+ `endif
103
125
end
104
126
105
127
for (genvar i = 0 ; i < NumOut; i++ ) begin : gen_flat_oup
@@ -121,7 +143,8 @@ module snitch_tcdm_interconnect #(
121
143
.OutSpillReg ( 1'b0 ),
122
144
.ExtPrio ( 1'b0 ),
123
145
.AxiVldRdy ( 1'b1 ),
124
- .LockIn ( 1'b1 )
146
+ .LockIn ( 1'b1 ),
147
+ .AxiVldMask ( MemReqAsrtMask )
125
148
) i_stream_xbar (
126
149
.clk_i,
127
150
.rst_ni,
@@ -200,7 +223,8 @@ module snitch_tcdm_interconnect #(
200
223
.SpillReg ( 1'b0 ),
201
224
.AxiVldRdy ( 1'b1 ),
202
225
.LockIn ( 1'b1 ),
203
- .Radix ( Radix )
226
+ .Radix ( Radix ),
227
+ .AxiVldMask ( MemReqAsrtMask )
204
228
) i_stream_omega_net (
205
229
.clk_i,
206
230
.rst_ni,
0 commit comments