@@ -63,6 +63,14 @@ 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
+
72
+ // TODO: proper write asserts!
73
+
66
74
// Width of the bank select signal.
67
75
localparam int unsigned SelWidth = cf_math_pkg :: idx_width (NumOut);
68
76
typedef logic [SelWidth- 1 : 0 ] select_t ;
@@ -88,7 +96,7 @@ module snitch_tcdm_interconnect #(
88
96
logic [NumInp- 1 : 0 ] req_q_valid_flat, rsp_q_ready_flat;
89
97
logic [NumOut- 1 : 0 ] mem_q_valid_flat, mem_q_ready_flat;
90
98
91
- // The usual struct packing unpacking.
99
+ // The usual struct packing unpacking; also check write stability here .
92
100
for (genvar i = 0 ; i < NumInp; i++ ) begin : gen_flat_inp
93
101
assign req_q_valid_flat[i] = req_i[i].q_valid;
94
102
assign rsp_o[i].q_ready = rsp_q_ready_flat[i];
@@ -100,6 +108,22 @@ module snitch_tcdm_interconnect #(
100
108
strb: req_i[i].q.strb,
101
109
user: req_i[i].q.user
102
110
} ;
111
+
112
+ // Write data must also be stable during AMOs, so include this case in assertions.
113
+ logic in_req_alters_mem;
114
+ assign in_req_alters_mem = in_req[i].write | (in_req[i].amo != reqrsp_pkg :: AMONone);
115
+
116
+ // TODO: we could clean this up with an additional common_cells assertion macro.
117
+ `ifndef VERILATOR
118
+ `ifndef SYNTHESIS
119
+ assert property (@ (posedge clk_i) disable iff (~ rst_ni) (req_q_valid_flat[i] &&
120
+ ! rsp_q_ready_flat[i] && in_req_alters_mem | => $stable (in_req[i].data))) else
121
+ $error (" write data during non-read is unstable at input: %0d " , i);
122
+ assert property (@ (posedge clk_i) disable iff (~ rst_ni) (req_q_valid_flat[i] &&
123
+ ! rsp_q_ready_flat[i] && in_req_alters_mem | => $stable (in_req[i].strb))) else
124
+ $error (" write strobe during non-read is unstable at input: %0d " , i);
125
+ `endif
126
+ `endif
103
127
end
104
128
105
129
for (genvar i = 0 ; i < NumOut; i++ ) begin : gen_flat_oup
@@ -121,7 +145,8 @@ module snitch_tcdm_interconnect #(
121
145
.OutSpillReg ( 1'b0 ),
122
146
.ExtPrio ( 1'b0 ),
123
147
.AxiVldRdy ( 1'b1 ),
124
- .LockIn ( 1'b1 )
148
+ .LockIn ( 1'b1 ),
149
+ .AxiVldMask ( MemReqAsrtMask )
125
150
) i_stream_xbar (
126
151
.clk_i,
127
152
.rst_ni,
@@ -198,7 +223,8 @@ module snitch_tcdm_interconnect #(
198
223
.SpillReg ( 1'b0 ),
199
224
.AxiVldRdy ( 1'b1 ),
200
225
.LockIn ( 1'b1 ),
201
- .Radix ( Radix )
226
+ .Radix ( Radix ),
227
+ .AxiVldMask ( MemReqAsrtMask )
202
228
) i_stream_omega_net (
203
229
.clk_i,
204
230
.rst_ni,
0 commit comments