1
+ // This is the blackbox we are asking you to implement
2
+ // Assume TILEROWS=1, and TILECOLUMNS=1
3
+ module MeshBlackBox
4
+ #(parameter MESHROWS, MESHCOLUMNS, INPUT_BITWIDTH, OUTPUT_BITWIDTH, MAX_SIM_MM_LOG, ACC_BITWIDTH_LOG, TILEROWS= 1 , TILECOLUMNS= 1 )
5
+ (
6
+ input clock,
7
+ input reset,
8
+ input signed [INPUT_BITWIDTH- 1 :0 ] in_a[MESHROWS- 1 :0 ][TILEROWS- 1 :0 ],
9
+ input signed [INPUT_BITWIDTH- 1 :0 ] in_d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
10
+ input signed [INPUT_BITWIDTH- 1 :0 ] in_b[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
11
+ input in_control_dataflow[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
12
+ input in_control_propagate[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
13
+ input [ACC_BITWIDTH_LOG- 1 :0 ] in_control_shift[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
14
+ input in_valid[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
15
+ input [MAX_SIM_MM_LOG- 1 :0 ] in_id[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
16
+ input in_last[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
17
+ output signed [OUTPUT_BITWIDTH- 1 :0 ] out_c[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
18
+ output signed [OUTPUT_BITWIDTH- 1 :0 ] out_b[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
19
+ output out_valid[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
20
+ output out_control_dataflow[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
21
+ output out_control_propagate[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
22
+ output [ACC_BITWIDTH_LOG- 1 :0 ] out_control_shift[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
23
+ output [MAX_SIM_MM_LOG- 1 :0 ] out_id[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ],
24
+ output out_last[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ]
25
+ );
26
+
27
+ // ---------------------------------------------------------
28
+ // ---------------------------------------------------------
29
+ // DO NOT MODIFY ANYTHING ABOVE THIS
30
+ // ---------------------------------------------------------
31
+ // ---------------------------------------------------------
32
+
33
+ // **********************************************************
34
+ // **********************************************************
35
+ // **********************************************************
36
+ // ******************** FILL THIS ***************************
37
+ // **********************************************************
38
+ // **********************************************************
39
+ // **********************************************************
40
+
41
+
42
+ endmodule // MeshBlackBox
43
+
44
+ // **********************************************************
45
+ // **********************************************************
46
+ // **********************************************************
47
+ // ********** FEEL FREE TO ADD MODULES HERE *****************
48
+ // **********************************************************
49
+ // **********************************************************
50
+ // **********************************************************
51
+
52
+ // ---------------------------------------------------------
53
+ // ---------------------------------------------------------
54
+ // DO NOT MODIFY ANYTHING BELOW THIS
55
+ // ---------------------------------------------------------
56
+ // ---------------------------------------------------------
57
+
58
+ // We are providing this adapter, due to the format of Chisel-generated Verilog
59
+ // and it's compatibility with a blackbox interface.
60
+ //
61
+ // This adapter converts the Gemmini multiplication function into something
62
+ // more amenable to teaching:
63
+ //
64
+ // Assumed that bias matrix is 0.
65
+ //
66
+ // Originally Gemmini does:
67
+ // A*D + B => B
68
+ // 0 => C
69
+ //
70
+ // This adapter converts it to the following:
71
+ // A*B + D => C
72
+ // 0 => B
73
+ module MeshBlackBoxAdapter
74
+ #(parameter MESHROWS, MESHCOLUMNS, INPUT_BITWIDTH, OUTPUT_BITWIDTH, MAX_SIM_MM_LOG, ACC_BITWIDTH_LOG, TILEROWS= 1 , TILECOLUMNS= 1 )
75
+ (
76
+ input clock,
77
+ input reset,
78
+ input [MESHROWS* TILEROWS* INPUT_BITWIDTH- 1 :0 ] in_a,
79
+ input [MESHCOLUMNS* TILECOLUMNS* INPUT_BITWIDTH- 1 :0 ] in_d,
80
+ input [MESHCOLUMNS* TILECOLUMNS* INPUT_BITWIDTH- 1 :0 ] in_b,
81
+ input [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] in_control_dataflow,
82
+ input [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] in_control_propagate,
83
+ input [MESHCOLUMNS* TILECOLUMNS* ACC_BITWIDTH_LOG- 1 :0 ] in_control_shift,
84
+ input [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] in_valid,
85
+ input [MESHCOLUMNS* TILECOLUMNS* MAX_SIM_MM_LOG- 1 :0 ] in_id,
86
+ input [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] in_last,
87
+ output [MESHCOLUMNS* TILECOLUMNS* OUTPUT_BITWIDTH- 1 :0 ] out_c,
88
+ output [MESHCOLUMNS* TILECOLUMNS* OUTPUT_BITWIDTH- 1 :0 ] out_b,
89
+ output [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] out_valid,
90
+ output [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] out_control_dataflow,
91
+ output [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] out_control_propagate,
92
+ output [MESHCOLUMNS* TILECOLUMNS* ACC_BITWIDTH_LOG- 1 :0 ] out_control_shift,
93
+ output [MESHCOLUMNS* TILECOLUMNS* MAX_SIM_MM_LOG- 1 :0 ] out_id,
94
+ output [MESHCOLUMNS* TILECOLUMNS- 1 :0 ] out_last
95
+ );
96
+
97
+ wire signed [INPUT_BITWIDTH- 1 :0 ] in_a_2d[MESHROWS- 1 :0 ][TILEROWS- 1 :0 ];
98
+ wire signed [INPUT_BITWIDTH- 1 :0 ] in_d_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
99
+ wire signed [INPUT_BITWIDTH- 1 :0 ] in_b_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
100
+ wire in_control_dataflow_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
101
+ wire in_control_propagate_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
102
+ wire [ACC_BITWIDTH_LOG- 1 :0 ] in_control_shift_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
103
+ wire in_valid_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
104
+ wire [MAX_SIM_MM_LOG- 1 :0 ] in_id_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
105
+ wire in_last_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
106
+ wire signed [OUTPUT_BITWIDTH- 1 :0 ] out_c_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
107
+ wire signed [OUTPUT_BITWIDTH- 1 :0 ] out_b_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
108
+ wire out_valid_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
109
+ wire out_control_dataflow_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
110
+ wire out_control_propagate_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
111
+ wire [ACC_BITWIDTH_LOG- 1 :0 ] out_control_shift_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
112
+ wire [MAX_SIM_MM_LOG- 1 :0 ] out_id_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
113
+ wire out_last_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
114
+ reg signed [OUTPUT_BITWIDTH- 1 :0 ] reg_out_c_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
115
+ reg signed [OUTPUT_BITWIDTH- 1 :0 ] reg_out_b_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
116
+ reg reg_out_valid_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
117
+ reg reg_out_control_dataflow_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
118
+ reg reg_out_control_propagate_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
119
+ reg [ACC_BITWIDTH_LOG- 1 :0 ] reg_out_control_shift_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
120
+ reg [MAX_SIM_MM_LOG- 1 :0 ] reg_out_id_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
121
+ reg reg_out_last_2d[MESHCOLUMNS- 1 :0 ][TILECOLUMNS- 1 :0 ];
122
+
123
+ // Convert wide signals into "cleaner" 2D Verilog arrays
124
+ genvar i;
125
+ genvar j;
126
+ generate
127
+ for (i = 0 ; i < MESHROWS ; i++ ) begin
128
+ for (j = 0 ; j < TILEROWS ; j++ ) begin
129
+ assign in_a_2d[i][j] = in_a[i* (TILEROWS* INPUT_BITWIDTH)+ (j+ 1 )* (INPUT_BITWIDTH)- 1 :i* (TILEROWS* INPUT_BITWIDTH)+ j* (INPUT_BITWIDTH)];
130
+ end
131
+ end
132
+ endgenerate
133
+
134
+ generate
135
+ for (i = 0 ; i < MESHCOLUMNS ; i++ ) begin
136
+ for (j = 0 ; j < TILECOLUMNS ; j++ ) begin
137
+ assign in_d_2d[i][j] = in_d[i* (TILECOLUMNS* INPUT_BITWIDTH)+ (j+ 1 )* (INPUT_BITWIDTH)- 1 :i* (TILECOLUMNS* INPUT_BITWIDTH)+ j* (INPUT_BITWIDTH)];
138
+ assign in_b_2d[i][j] = in_b[i* (TILECOLUMNS* INPUT_BITWIDTH)+ (j+ 1 )* (INPUT_BITWIDTH)- 1 :i* (TILECOLUMNS* INPUT_BITWIDTH)+ j* (INPUT_BITWIDTH)];
139
+ assign in_control_dataflow_2d[i][j] = in_control_dataflow[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j];
140
+ assign in_control_propagate_2d[i][j] = in_control_propagate[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j];
141
+ assign in_control_shift_2d[i][j] = in_control_shift[i* (TILECOLUMNS* ACC_BITWIDTH_LOG)+ (j+ 1 )* (ACC_BITWIDTH_LOG)- 1 :i* (TILECOLUMNS* ACC_BITWIDTH_LOG)+ j* (ACC_BITWIDTH_LOG)];
142
+ assign in_valid_2d[i][j] = in_valid[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j];
143
+ assign in_id_2d[i][j] = in_id[i* (TILECOLUMNS* MAX_SIM_MM_LOG)+ (j+ 1 )* (MAX_SIM_MM_LOG)- 1 :i* (TILECOLUMNS* MAX_SIM_MM_LOG)+ j* (MAX_SIM_MM_LOG)];
144
+ assign in_last_2d[i][j] = in_last[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j];
145
+
146
+ assign out_c[i* (TILECOLUMNS* OUTPUT_BITWIDTH)+ (j+ 1 )* (OUTPUT_BITWIDTH)- 1 :i* (TILECOLUMNS* OUTPUT_BITWIDTH)+ j* (OUTPUT_BITWIDTH)] = reg_out_c_2d[i][j];
147
+ assign out_b[i* (TILECOLUMNS* OUTPUT_BITWIDTH)+ (j+ 1 )* (OUTPUT_BITWIDTH)- 1 :i* (TILECOLUMNS* OUTPUT_BITWIDTH)+ j* (OUTPUT_BITWIDTH)] = reg_out_b_2d[i][j];
148
+ assign out_valid[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j] = reg_out_valid_2d[i][j];
149
+
150
+ assign out_control_dataflow[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j] = reg_out_control_dataflow_2d[i][j];
151
+ assign out_control_propagate[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j] = reg_out_control_propagate_2d[i][j];
152
+ assign out_control_shift[i* (TILECOLUMNS* ACC_BITWIDTH_LOG)+ (j+ 1 )* (ACC_BITWIDTH_LOG)- 1 :i* (TILECOLUMNS* ACC_BITWIDTH_LOG)+ j* (ACC_BITWIDTH_LOG)] = reg_out_control_shift_2d[i][j];
153
+
154
+ assign out_id[i* (TILECOLUMNS* MAX_SIM_MM_LOG)+ (j+ 1 )* (MAX_SIM_MM_LOG)- 1 :i* (TILECOLUMNS* MAX_SIM_MM_LOG)+ j* (MAX_SIM_MM_LOG)] = reg_out_id_2d[i][j];
155
+ assign out_last[i* (TILECOLUMNS)+ (j+ 1 )- 1 :i* (TILECOLUMNS)+ j] = reg_out_last_2d[i][j];
156
+
157
+ always @(posedge clock) begin
158
+ if (reset) begin
159
+ // reset all values to 0
160
+ reg_out_c_2d[i][j] <= '0 ;
161
+ reg_out_b_2d[i][j] <= '0 ;
162
+ reg_out_valid_2d[i][j] <= '0 ;
163
+ reg_out_control_dataflow_2d[i][j] <= '0 ;
164
+ reg_out_control_propagate_2d[i][j] <= '0 ;
165
+ reg_out_control_shift_2d[i][j] <= '0 ;
166
+ reg_out_id_2d[i][j] <= '0 ;
167
+ reg_out_last_2d[i][j] <= '0 ;
168
+ end
169
+ else begin
170
+ // regnext the values
171
+ reg_out_c_2d[i][j] <= out_c_2d[i][j];
172
+ reg_out_b_2d[i][j] <= out_b_2d[i][j];
173
+ reg_out_valid_2d[i][j] <= out_valid_2d[i][j];
174
+ reg_out_control_dataflow_2d[i][j] <= out_control_dataflow_2d[i][j];
175
+ reg_out_control_propagate_2d[i][j] <= out_control_propagate_2d[i][j];
176
+ reg_out_control_shift_2d[i][j] <= out_control_shift_2d[i][j];
177
+ reg_out_id_2d[i][j] <= out_id_2d[i][j];
178
+ reg_out_last_2d[i][j] <= out_last_2d[i][j];
179
+ end
180
+ end
181
+ end
182
+ end
183
+ endgenerate
184
+
185
+ // Instantiate the Mesh BlackBox implementation (the one you are writing in
186
+ // this assignment)
187
+ // Note: This swaps signals around a bit:
188
+ // in_b <-> in_d
189
+ // out_c <-> out_b
190
+ MeshBlackBox #(.MESHROWS(MESHROWS),.TILEROWS(TILEROWS),.MESHCOLUMNS(MESHCOLUMNS),.MAX_SIM_MM_LOG(MAX_SIM_MM_LOG),.ACC_BITWIDTH_LOG(ACC_BITWIDTH_LOG), .TILECOLUMNS(TILECOLUMNS),.INPUT_BITWIDTH(INPUT_BITWIDTH),.OUTPUT_BITWIDTH(OUTPUT_BITWIDTH))
191
+ mesh_blackbox_inst (
192
+ .clock (clock),
193
+ .reset (reset),
194
+ .in_a (in_a_2d),
195
+ .in_d (in_b_2d),
196
+ .in_b (in_d_2d),
197
+ .in_control_dataflow (in_control_dataflow_2d),
198
+ .in_control_propagate (in_control_propagate_2d),
199
+ .in_control_shift (in_control_shift_2d),
200
+ .in_valid (in_valid_2d),
201
+ .in_id (in_id_2d),
202
+ .in_last (in_last_2d),
203
+ .out_c (out_b_2d),
204
+ .out_b (out_c_2d),
205
+ .out_valid (out_valid_2d),
206
+ .out_control_dataflow (out_control_dataflow_2d),
207
+ .out_control_propagate (out_control_propagate_2d),
208
+ .out_control_shift (out_control_shift_2d),
209
+ .out_id (out_id_2d),
210
+ .out_last (out_last_2d)
211
+ );
212
+
213
+ endmodule // MeshBlackBoxAdapter
0 commit comments