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