1 |
4 |
fafa1971 |
/*
|
2 |
|
|
* Bridge from SPARC Core to Wishbone Master
|
3 |
|
|
*
|
4 |
|
|
* (C) 2007 Simply RISC LLP
|
5 |
|
|
* AUTHOR: Fabrizio Fazzino <fabrizio.fazzino@srisc.com>
|
6 |
|
|
*
|
7 |
|
|
* LICENSE:
|
8 |
|
|
* This is a Free Hardware Design; you can redistribute it and/or
|
9 |
|
|
* modify it under the terms of the GNU General Public License
|
10 |
|
|
* version 2 as published by the Free Software Foundation.
|
11 |
|
|
* The above named program is distributed in the hope that it will
|
12 |
|
|
* be useful, but WITHOUT ANY WARRANTY; without even the implied
|
13 |
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14 |
|
|
* See the GNU General Public License for more details.
|
15 |
|
|
*
|
16 |
|
|
* DESCRIPTION:
|
17 |
|
|
* This block implements a bridge from one SPARC Core of the
|
18 |
|
|
* OpenSPARC T1 to a master interface that makes use of the
|
19 |
|
|
* Wishbone interconnect protocol.
|
20 |
|
|
* For informations about Sun Microsystems' OpenSPARC T1
|
21 |
|
|
* refer to the web site http://www.opensparc.net
|
22 |
|
|
* For informations about OpenCores' Wishbone interconnect
|
23 |
|
|
* please refer to the web site http://www.opencores.org
|
24 |
|
|
*/
|
25 |
|
|
|
26 |
|
|
`include "s1_defs.h"
|
27 |
|
|
|
28 |
|
|
module spc2wbm (
|
29 |
|
|
|
30 |
99 |
fafa1971 |
/*
|
31 |
|
|
* Inputs
|
32 |
|
|
*/
|
33 |
4 |
fafa1971 |
|
34 |
99 |
fafa1971 |
// System inputs
|
35 |
|
|
input sys_clock_i, // System Clock
|
36 |
|
|
input sys_reset_i, // System Reset
|
37 |
|
|
input[5:0] sys_interrupt_source_i, // Encoded Interrupt Source
|
38 |
4 |
fafa1971 |
|
39 |
99 |
fafa1971 |
// SPARC-side inputs connected to the PCX (Processor-to-Cache Xbar) outputs of the SPARC Core
|
40 |
|
|
input[4:0] spc_req_i, // Request
|
41 |
|
|
input spc_atom_i, // Atomic Request
|
42 |
|
|
input[(`PCX_WIDTH-1):0] spc_packetout_i, // Outgoing Packet
|
43 |
4 |
fafa1971 |
|
44 |
99 |
fafa1971 |
// Wishbone Master interface inputs
|
45 |
|
|
input wbm_ack_i, // Ack
|
46 |
|
|
input[(`WB_DATA_WIDTH-1):0] wbm_data_i, // Data In
|
47 |
4 |
fafa1971 |
|
48 |
99 |
fafa1971 |
/*
|
49 |
|
|
* Outputs
|
50 |
|
|
*/
|
51 |
4 |
fafa1971 |
|
52 |
99 |
fafa1971 |
// SPARC-side outputs connected to the CPX (Cache-to-Processor Xbar) inputs of the SPARC Core
|
53 |
|
|
output reg[4:0] spc_grant_o, // Grant
|
54 |
|
|
output reg spc_ready_o, // Ready
|
55 |
|
|
output reg[`CPX_WIDTH-1:0] spc_packetin_o, // Incoming Packet
|
56 |
|
|
output reg spc_stall_o, // Stall Requests
|
57 |
|
|
output reg spc_resume_o, // Resume Requests
|
58 |
4 |
fafa1971 |
|
59 |
99 |
fafa1971 |
// Wishbone Master interface outputs
|
60 |
|
|
output reg wbm_cycle_o, // Cycle Start
|
61 |
|
|
output reg wbm_strobe_o, // Strobe Request
|
62 |
|
|
output reg wbm_we_o, // Write Enable
|
63 |
|
|
output reg[`WB_ADDR_WIDTH-1:0] wbm_addr_o, // Address Bus
|
64 |
|
|
output reg[`WB_DATA_WIDTH-1:0] wbm_data_o, // Data Out
|
65 |
|
|
output reg[`WB_DATA_WIDTH/8-1:0] wbm_sel_o // Select Output
|
66 |
4 |
fafa1971 |
|
67 |
99 |
fafa1971 |
);
|
68 |
|
|
|
69 |
|
|
|
70 |
4 |
fafa1971 |
/*
|
71 |
|
|
* Registers
|
72 |
|
|
*/
|
73 |
|
|
|
74 |
|
|
// Registers to latch requests from SPARC Core to Wishbone Master
|
75 |
|
|
reg[3:0] state;
|
76 |
|
|
reg[4:0] spc2wbm_region; // Target region number (one-hot encoded)
|
77 |
12 |
fafa1971 |
reg spc2wbm_atomic; // Request is Atomic
|
78 |
4 |
fafa1971 |
reg[(`PCX_WIDTH-1):0] spc2wbm_packet; // Latched Packet
|
79 |
|
|
|
80 |
|
|
// Wishbone Master to SPARC Core info used to encode the return packet
|
81 |
|
|
reg wbm2spc_valid; // Valid
|
82 |
|
|
reg[(`CPX_RQ_HI-`CPX_RQ_LO):0] wbm2spc_type; // Request type
|
83 |
12 |
fafa1971 |
reg wbm2spc_miss; // L2 Miss
|
84 |
|
|
reg[(`CPX_ERR_HI-`CPX_ERR_LO-1):0] wbm2spc_error; // Error
|
85 |
11 |
fafa1971 |
reg wbm2spc_nc; // Non-Cacheable
|
86 |
4 |
fafa1971 |
reg[(`CPX_TH_HI-`CPX_TH_LO):0] wbm2spc_thread; // Thread
|
87 |
11 |
fafa1971 |
reg wbm2spc_way_valid; // L2 Way Valid
|
88 |
|
|
reg[(`CPX_WY_HI-`CPX_WY_LO):0] wbm2spc_way; // Replaced L2 Way
|
89 |
12 |
fafa1971 |
reg wbm2spc_boot_fetch; // Fetch for Boot
|
90 |
|
|
reg wbm2spc_atomic; // Atomic LD/ST or 2nd IFill packet
|
91 |
|
|
reg wbm2spc_pfl; // PFL
|
92 |
4 |
fafa1971 |
reg[(`CPX_DA_HI-`CPX_DA_LO):0] wbm2spc_data; // Load Data
|
93 |
11 |
fafa1971 |
reg[6:0] wbm2spc_interrupt_source; // Encoded Interrupt Source
|
94 |
|
|
reg wbm2spc_interrupt_new; // New Interrupt Pending
|
95 |
|
|
|
96 |
4 |
fafa1971 |
/*
|
97 |
|
|
* Wires
|
98 |
|
|
*/
|
99 |
|
|
|
100 |
|
|
// Decoded SPARC Core to Wishbone Master info
|
101 |
|
|
wire spc2wbm_req; // Request
|
102 |
|
|
wire spc2wbm_valid; // Valid
|
103 |
|
|
wire[(`PCX_RQ_HI-`PCX_RQ_LO):0] spc2wbm_type; // Request type
|
104 |
11 |
fafa1971 |
wire spc2wbm_nc; // Non-Cacheable
|
105 |
4 |
fafa1971 |
wire[(`PCX_CP_HI-`PCX_CP_LO):0] spc2wbm_cpu_id; // CPU ID
|
106 |
|
|
wire[(`PCX_TH_HI-`PCX_TH_LO):0] spc2wbm_thread; // Thread
|
107 |
11 |
fafa1971 |
wire spc2wbm_invalidate; // Invalidate all
|
108 |
|
|
wire[(`PCX_WY_HI-`PCX_WY_LO):0] spc2wbm_way; // Replaced L1 Way
|
109 |
4 |
fafa1971 |
wire[(`PCX_SZ_HI-`PCX_SZ_LO):0] spc2wbm_size; // Load/Store size
|
110 |
|
|
wire[(`PCX_AD_HI-`PCX_AD_LO):0] spc2wbm_addr; // Address
|
111 |
|
|
wire[(`PCX_DA_HI-`PCX_DA_LO):0] spc2wbm_data; // Store Data
|
112 |
|
|
|
113 |
|
|
// Return packets assembled with various fields
|
114 |
11 |
fafa1971 |
wire[`CPX_WIDTH-1:0] wbm2spc_packet; // Incoming Packet
|
115 |
4 |
fafa1971 |
|
116 |
|
|
/*
|
117 |
|
|
* Encode/decode incoming info
|
118 |
|
|
*
|
119 |
|
|
* Legenda: available constants for some of the PCX/CPX fields.
|
120 |
|
|
*
|
121 |
|
|
* spc2wbm_size (3 bits) is one of:
|
122 |
|
|
* - PCX_SZ_1B
|
123 |
|
|
* - PCX_SZ_2B
|
124 |
|
|
* - PCX_SZ_4B
|
125 |
|
|
* - PCX_SZ_8B
|
126 |
|
|
* - PCX_SZ_16B (Read accesses only)
|
127 |
|
|
*
|
128 |
|
|
* spc2wbm_type (5 bits) is one of:
|
129 |
|
|
* { LOAD_RQ, IMISS_RQ, STORE_RQ, CAS1_RQ, CAS2_RQ, SWAP_RQ, STRLOAD_RQ, STRST_RQ, STQ_RQ,
|
130 |
|
|
* INT_RQ, FWD_RQ, FWD_RPY, RSVD_RQ }
|
131 |
|
|
*
|
132 |
|
|
* wbm2spc_type (4 bits) is one of:
|
133 |
|
|
* { LOAD_RET, INV_RET, ST_ACK, AT_ACK, INT_RET, TEST_RET, FP_RET, IFILL_RET, EVICT_REQ,
|
134 |
|
|
* ERR_RET, STRLOAD_RET, STRST_ACK, FWD_RQ_RET, FWD_RPY_RET, RSVD_RET }
|
135 |
|
|
*
|
136 |
|
|
*/
|
137 |
|
|
|
138 |
|
|
// Decode info arriving from the SPC side
|
139 |
|
|
assign spc2wbm_req = ( spc_req_i[4] | spc_req_i[3] | spc_req_i[2] | spc_req_i[1] | spc_req_i[0] );
|
140 |
|
|
assign spc2wbm_valid = spc2wbm_packet[`PCX_VLD];
|
141 |
|
|
assign spc2wbm_type = spc2wbm_packet[`PCX_RQ_HI:`PCX_RQ_LO];
|
142 |
11 |
fafa1971 |
assign spc2wbm_nc = spc2wbm_packet[`PCX_NC];
|
143 |
4 |
fafa1971 |
assign spc2wbm_cpu_id = spc2wbm_packet[`PCX_CP_HI:`PCX_CP_LO];
|
144 |
|
|
assign spc2wbm_thread = spc2wbm_packet[`PCX_TH_HI:`PCX_TH_LO];
|
145 |
11 |
fafa1971 |
assign spc2wbm_invalidate = spc2wbm_packet[`PCX_INVALL];
|
146 |
|
|
assign spc2wbm_way = spc2wbm_packet[`PCX_WY_HI:`PCX_WY_LO];
|
147 |
4 |
fafa1971 |
assign spc2wbm_size = spc2wbm_packet[`PCX_SZ_HI:`PCX_SZ_LO];
|
148 |
|
|
assign spc2wbm_addr = spc2wbm_packet[`PCX_AD_HI:`PCX_AD_LO];
|
149 |
|
|
assign spc2wbm_data = spc2wbm_packet[`PCX_DA_HI:`PCX_DA_LO];
|
150 |
|
|
|
151 |
|
|
// Encode info going to the SPC side assembling return packets
|
152 |
12 |
fafa1971 |
assign wbm2spc_packet = { wbm2spc_valid, wbm2spc_type, wbm2spc_miss, wbm2spc_error, wbm2spc_nc, wbm2spc_thread,
|
153 |
|
|
wbm2spc_way_valid, wbm2spc_way, wbm2spc_boot_fetch, wbm2spc_atomic, wbm2spc_pfl, wbm2spc_data };
|
154 |
4 |
fafa1971 |
|
155 |
|
|
/*
|
156 |
|
|
* State Machine
|
157 |
|
|
*/
|
158 |
|
|
|
159 |
|
|
always @(posedge sys_clock_i) begin
|
160 |
|
|
|
161 |
|
|
// Initialization
|
162 |
|
|
if(sys_reset_i==1) begin
|
163 |
|
|
|
164 |
|
|
// Clear outputs going to SPARC Core inputs
|
165 |
51 |
fafa1971 |
spc_grant_o <= 5'b00000;
|
166 |
|
|
spc_ready_o <= 0;
|
167 |
|
|
spc_packetin_o <= 0;
|
168 |
99 |
fafa1971 |
spc_stall_o <= 0;
|
169 |
|
|
spc_resume_o <= 0;
|
170 |
4 |
fafa1971 |
|
171 |
|
|
// Clear Wishbone Master interface outputs
|
172 |
51 |
fafa1971 |
wbm_cycle_o <= 0;
|
173 |
|
|
wbm_strobe_o <= 0;
|
174 |
|
|
wbm_we_o <= 0;
|
175 |
|
|
wbm_addr_o <= 64'b0;
|
176 |
|
|
wbm_data_o <= 64'b0;
|
177 |
|
|
wbm_sel_o <= 8'b0;
|
178 |
4 |
fafa1971 |
|
179 |
|
|
// Prepare wakeup packet for SPARC Core, the resulting output is
|
180 |
51 |
fafa1971 |
// spc_packetin_o <= `CPX_WIDTH'h1700000000000000000000000000000010001;
|
181 |
|
|
wbm2spc_valid <= 1;
|
182 |
|
|
wbm2spc_type <= `INT_RET;
|
183 |
|
|
wbm2spc_miss <= 0;
|
184 |
|
|
wbm2spc_error <= 0;
|
185 |
|
|
wbm2spc_nc <= 0;
|
186 |
|
|
wbm2spc_thread <= 0;
|
187 |
|
|
wbm2spc_way_valid <= 0;
|
188 |
|
|
wbm2spc_way <= 0;
|
189 |
|
|
wbm2spc_boot_fetch <= 0;
|
190 |
|
|
wbm2spc_atomic <= 0;
|
191 |
|
|
wbm2spc_pfl <= 0;
|
192 |
|
|
wbm2spc_data <= 64'h10001;
|
193 |
|
|
wbm2spc_interrupt_source <= 7'h0;
|
194 |
|
|
wbm2spc_interrupt_new <= 1'b0;
|
195 |
|
|
|
196 |
4 |
fafa1971 |
// Clear state machine
|
197 |
51 |
fafa1971 |
state <= `STATE_WAKEUP;
|
198 |
4 |
fafa1971 |
|
199 |
|
|
end else begin
|
200 |
|
|
|
201 |
|
|
// FSM State 0: STATE_WAKEUP
|
202 |
|
|
// Send to the SPARC Core the wakeup packet
|
203 |
|
|
if(state==`STATE_WAKEUP) begin
|
204 |
|
|
|
205 |
|
|
// Send wakeup packet
|
206 |
51 |
fafa1971 |
spc_ready_o <= 1;
|
207 |
|
|
spc_packetin_o <= wbm2spc_packet;
|
208 |
4 |
fafa1971 |
|
209 |
|
|
// synopsys translate_off
|
210 |
|
|
// Display comment
|
211 |
51 |
fafa1971 |
`ifdef DEBUG
|
212 |
4 |
fafa1971 |
$display("INFO: SPC2WBM: SPARC Core to Wishbone Master bridge starting...");
|
213 |
|
|
$display("INFO: SPC2WBM: Wakeup packet sent to SPARC Core");
|
214 |
51 |
fafa1971 |
`endif
|
215 |
4 |
fafa1971 |
// synopsys translate_on
|
216 |
|
|
|
217 |
|
|
// Unconditional state change
|
218 |
51 |
fafa1971 |
state <= `STATE_IDLE;
|
219 |
4 |
fafa1971 |
|
220 |
|
|
// FSM State 1: STATE_IDLE
|
221 |
|
|
// Wait for a request from the SPARC Core
|
222 |
|
|
// If available send an interrupt packet to the Core
|
223 |
|
|
end else if(state==`STATE_IDLE) begin
|
224 |
|
|
|
225 |
|
|
// Check if there's an incoming request
|
226 |
|
|
if(spc2wbm_req==1) begin
|
227 |
|
|
|
228 |
|
|
// Clear previously modified outputs
|
229 |
51 |
fafa1971 |
spc_ready_o <= 0;
|
230 |
|
|
spc_packetin_o <= 0;
|
231 |
4 |
fafa1971 |
|
232 |
|
|
// Stall other requests from the SPARC Core
|
233 |
99 |
fafa1971 |
spc_stall_o <= 1;
|
234 |
4 |
fafa1971 |
|
235 |
|
|
// Latch target region and atomicity
|
236 |
51 |
fafa1971 |
spc2wbm_region <= spc_req_i;
|
237 |
|
|
spc2wbm_atomic <= spc_atom_i;
|
238 |
4 |
fafa1971 |
|
239 |
|
|
// Jump to next state
|
240 |
51 |
fafa1971 |
state <= `STATE_REQUEST_LATCHED;
|
241 |
4 |
fafa1971 |
|
242 |
|
|
// See if the interrupt vector has changed
|
243 |
|
|
end else if(sys_interrupt_source_i!=wbm2spc_interrupt_source) begin
|
244 |
|
|
|
245 |
|
|
// Set the flag for next cycle
|
246 |
51 |
fafa1971 |
wbm2spc_interrupt_new <= 1;
|
247 |
4 |
fafa1971 |
|
248 |
|
|
// Prepare the interrupt packet for the SPARC Core
|
249 |
51 |
fafa1971 |
wbm2spc_valid <= 1;
|
250 |
|
|
wbm2spc_type <= `INT_RET;
|
251 |
|
|
wbm2spc_miss <= 0;
|
252 |
|
|
wbm2spc_error <= 0;
|
253 |
|
|
wbm2spc_nc <= 0;
|
254 |
|
|
wbm2spc_thread <= 0;
|
255 |
|
|
wbm2spc_way_valid <= 0;
|
256 |
|
|
wbm2spc_way <= 0;
|
257 |
|
|
wbm2spc_boot_fetch <= 0;
|
258 |
|
|
wbm2spc_atomic <= 0;
|
259 |
|
|
wbm2spc_pfl <= 0;
|
260 |
4 |
fafa1971 |
|
261 |
|
|
// Next cycle see if there's an int to be forwarded to the Core
|
262 |
11 |
fafa1971 |
end else if(wbm2spc_interrupt_source!=6'b000000 && wbm2spc_interrupt_new) begin
|
263 |
4 |
fafa1971 |
|
264 |
|
|
// Clean the flag
|
265 |
51 |
fafa1971 |
wbm2spc_interrupt_new <= 0;
|
266 |
4 |
fafa1971 |
|
267 |
|
|
// Send the interrupt packet to the Core
|
268 |
51 |
fafa1971 |
spc_ready_o <= 1;
|
269 |
|
|
spc_packetin_o <= wbm2spc_packet;
|
270 |
4 |
fafa1971 |
|
271 |
|
|
// Stay in this state
|
272 |
51 |
fafa1971 |
state <= `STATE_IDLE;
|
273 |
4 |
fafa1971 |
|
274 |
|
|
// Nothing to do, stay idle
|
275 |
|
|
end else begin
|
276 |
|
|
|
277 |
|
|
// Clear previously modified outputs
|
278 |
51 |
fafa1971 |
spc_ready_o <= 0;
|
279 |
|
|
spc_packetin_o <= 0;
|
280 |
4 |
fafa1971 |
|
281 |
99 |
fafa1971 |
// Clear stall/resume signals
|
282 |
|
|
spc_stall_o <= 0;
|
283 |
|
|
spc_resume_o <= 0;
|
284 |
|
|
|
285 |
4 |
fafa1971 |
// Stay in this state
|
286 |
51 |
fafa1971 |
state <= `STATE_IDLE;
|
287 |
4 |
fafa1971 |
|
288 |
|
|
end
|
289 |
|
|
|
290 |
|
|
// FSM State 2: STATE_REQUEST_LATCHED
|
291 |
|
|
// We've just latched the request
|
292 |
|
|
// Now we latch the packet
|
293 |
|
|
// Start granting the request
|
294 |
|
|
end else if(state==`STATE_REQUEST_LATCHED) begin
|
295 |
|
|
|
296 |
|
|
// Latch the incoming packet
|
297 |
51 |
fafa1971 |
spc2wbm_packet <= spc_packetout_i;
|
298 |
4 |
fafa1971 |
|
299 |
|
|
// Grant the request to the SPARC Core
|
300 |
51 |
fafa1971 |
spc_grant_o <= spc2wbm_region;
|
301 |
4 |
fafa1971 |
|
302 |
99 |
fafa1971 |
// Clear the stall signal
|
303 |
|
|
spc_stall_o <= 0;
|
304 |
|
|
|
305 |
4 |
fafa1971 |
// synopsys translate_off
|
306 |
|
|
// Print details of SPARC Core request
|
307 |
51 |
fafa1971 |
`ifdef DEBUG
|
308 |
4 |
fafa1971 |
$display("INFO: SPC2WBM: *** NEW REQUEST FROM SPARC CORE ***");
|
309 |
|
|
if(spc2wbm_region[0]==1) $display("INFO: SPC2WBM: Request to RAM Bank 0");
|
310 |
|
|
else if(spc2wbm_region[1]==1) $display("INFO: SPC2WBM: Request to RAM Bank 1");
|
311 |
|
|
else if(spc2wbm_region[2]==1) $display("INFO: SPC2WBM: Request to RAM Bank 2");
|
312 |
|
|
else if(spc2wbm_region[3]==1) $display("INFO: SPC2WBM: Request to RAM Bank 3");
|
313 |
|
|
else if(spc2wbm_region[4]==1) $display("INFO: SPC2WBM: Request targeted to I/O Block");
|
314 |
|
|
else $display("INFO: SPC2WBM: Request to target region unknown");
|
315 |
12 |
fafa1971 |
if(spc2wbm_atomic==1) $display("INFO: SPC2WBM: Request is ATOMIC");
|
316 |
4 |
fafa1971 |
else $display("INFO: SPC2WBM: Request is not atomic");
|
317 |
51 |
fafa1971 |
`endif
|
318 |
4 |
fafa1971 |
// synopsys translate_on
|
319 |
|
|
|
320 |
|
|
// Unconditional state change
|
321 |
51 |
fafa1971 |
state <= `STATE_PACKET_LATCHED;
|
322 |
4 |
fafa1971 |
|
323 |
|
|
// FSM State 3: STATE_PACKET_LATCHED
|
324 |
|
|
// The packet has already been latched
|
325 |
|
|
// Decode this packet to build the request for the Wishbone bus
|
326 |
|
|
// The grant of the request to the SPARC Core has been completed
|
327 |
|
|
end else if(state==`STATE_PACKET_LATCHED) begin
|
328 |
|
|
|
329 |
|
|
// Clear previously modified outputs
|
330 |
51 |
fafa1971 |
spc_grant_o <= 5'b0;
|
331 |
4 |
fafa1971 |
|
332 |
|
|
// Issue a request on the Wishbone bus
|
333 |
51 |
fafa1971 |
wbm_cycle_o <= 1;
|
334 |
|
|
wbm_strobe_o <= 1;
|
335 |
|
|
wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:3], 3'b000 };
|
336 |
|
|
wbm_data_o <= spc2wbm_data;
|
337 |
4 |
fafa1971 |
|
338 |
|
|
// Handle write enable and byte select
|
339 |
|
|
if(spc2wbm_type==`IMISS_RQ) begin
|
340 |
|
|
|
341 |
|
|
// For instruction miss always read memory
|
342 |
51 |
fafa1971 |
wbm_we_o <= 0;
|
343 |
4 |
fafa1971 |
if(spc2wbm_region==5'b10000)
|
344 |
|
|
// For accesses to SSI ROM only 32 bits are required
|
345 |
51 |
fafa1971 |
wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
|
346 |
4 |
fafa1971 |
else
|
347 |
|
|
// For accesses to RAM 256 bits are expected (2 ret packets)
|
348 |
51 |
fafa1971 |
wbm_sel_o <= 8'b11111111;
|
349 |
4 |
fafa1971 |
|
350 |
11 |
fafa1971 |
end else if(spc2wbm_type==`LOAD_RQ) begin
|
351 |
|
|
|
352 |
|
|
// For data load use the provided data
|
353 |
51 |
fafa1971 |
wbm_we_o <= 0;
|
354 |
11 |
fafa1971 |
case(spc2wbm_size)
|
355 |
51 |
fafa1971 |
`PCX_SZ_1B: wbm_sel_o <= (1'b1<<spc2wbm_addr[2:0]);
|
356 |
|
|
`PCX_SZ_2B: wbm_sel_o <= (2'b11<<(spc2wbm_addr[2:1]<<1));
|
357 |
|
|
`PCX_SZ_4B: wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
|
358 |
|
|
`PCX_SZ_8B: wbm_sel_o <= 8'b11111111;
|
359 |
|
|
`PCX_SZ_16B: wbm_sel_o <= 8'b11111111; // Requires a 2nd access
|
360 |
|
|
default: wbm_sel_o <= 8'b00000000;
|
361 |
11 |
fafa1971 |
endcase
|
362 |
4 |
fafa1971 |
|
363 |
11 |
fafa1971 |
end else if(spc2wbm_type==`STORE_RQ) begin
|
364 |
|
|
|
365 |
|
|
// For data store use the provided data
|
366 |
51 |
fafa1971 |
wbm_we_o <= 1;
|
367 |
4 |
fafa1971 |
case(spc2wbm_size)
|
368 |
51 |
fafa1971 |
`PCX_SZ_1B: wbm_sel_o <= (1'b1<<spc2wbm_addr[2:0]);
|
369 |
|
|
`PCX_SZ_2B: wbm_sel_o <= (2'b11<<(spc2wbm_addr[2:1]<<1));
|
370 |
|
|
`PCX_SZ_4B: wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
|
371 |
|
|
`PCX_SZ_8B: wbm_sel_o <= 8'b11111111;
|
372 |
|
|
`PCX_SZ_16B: wbm_sel_o <= 8'b11111111; // Requires a 2nd access
|
373 |
|
|
default: wbm_sel_o <= 8'b00000000;
|
374 |
4 |
fafa1971 |
endcase
|
375 |
|
|
|
376 |
11 |
fafa1971 |
end else begin
|
377 |
|
|
|
378 |
51 |
fafa1971 |
wbm_we_o <= 1;
|
379 |
|
|
wbm_sel_o <= 8'b00000000;
|
380 |
11 |
fafa1971 |
|
381 |
4 |
fafa1971 |
end
|
382 |
|
|
|
383 |
|
|
// synopsys translate_off
|
384 |
|
|
// Print details of request packet
|
385 |
51 |
fafa1971 |
`ifdef DEBUG
|
386 |
11 |
fafa1971 |
$display("INFO: SPC2WBM: Valid bit is %X", spc2wbm_valid);
|
387 |
4 |
fafa1971 |
case(spc2wbm_type)
|
388 |
|
|
`LOAD_RQ: $display("INFO: SPC2WBM: Request of Type LOAD_RQ");
|
389 |
|
|
`IMISS_RQ: $display("INFO: SPC2WBM: Request of Type IMISS_RQ");
|
390 |
|
|
`STORE_RQ: $display("INFO: SPC2WBM: Request of Type STORE_RQ");
|
391 |
|
|
`CAS1_RQ: $display("INFO: SPC2WBM: Request of Type CAS1_RQ");
|
392 |
|
|
`CAS2_RQ: $display("INFO: SPC2WBM: Request of Type CAS2_RQ");
|
393 |
|
|
`SWAP_RQ: $display("INFO: SPC2WBM: Request of Type SWAP_RQ");
|
394 |
|
|
`STRLOAD_RQ: $display("INFO: SPC2WBM: Request of Type STRLOAD_RQ");
|
395 |
|
|
`STRST_RQ: $display("INFO: SPC2WBM: Request of Type STRST_RQ");
|
396 |
|
|
`STQ_RQ: $display("INFO: SPC2WBM: Request of Type STQ_RQ");
|
397 |
|
|
`INT_RQ: $display("INFO: SPC2WBM: Request of Type INT_RQ");
|
398 |
|
|
`FWD_RQ: $display("INFO: SPC2WBM: Request of Type FWD_RQ");
|
399 |
|
|
`FWD_RPY: $display("INFO: SPC2WBM: Request of Type FWD_RPY");
|
400 |
|
|
`RSVD_RQ: $display("INFO: SPC2WBM: Request of Type RSVD_RQ");
|
401 |
|
|
default: $display("INFO: SPC2WBM: Request of Type Unknown");
|
402 |
11 |
fafa1971 |
endcase
|
403 |
12 |
fafa1971 |
$display("INFO: SPC2WBM: Non-Cacheable bit is %X", spc2wbm_nc);
|
404 |
11 |
fafa1971 |
$display("INFO: SPC2WBM: CPU-ID is %X", spc2wbm_cpu_id);
|
405 |
4 |
fafa1971 |
$display("INFO: SPC2WBM: Thread is %X", spc2wbm_thread);
|
406 |
11 |
fafa1971 |
$display("INFO: SPC2WBM: Invalidate All is %X", spc2wbm_invalidate);
|
407 |
|
|
$display("INFO: SPC2WBM: Replaced L1 Way is %X", spc2wbm_way);
|
408 |
4 |
fafa1971 |
case(spc2wbm_size)
|
409 |
|
|
`PCX_SZ_1B: $display("INFO: SPC2WBM: Request size is 1 Byte");
|
410 |
|
|
`PCX_SZ_2B: $display("INFO: SPC2WBM: Request size is 2 Bytes");
|
411 |
|
|
`PCX_SZ_4B: $display("INFO: SPC2WBM: Request size is 4 Bytes");
|
412 |
|
|
`PCX_SZ_8B: $display("INFO: SPC2WBM: Request size is 8 Bytes");
|
413 |
|
|
`PCX_SZ_16B: $display("INFO: SPC2WBM: Request size is 16 Bytes");
|
414 |
|
|
default: $display("INFO: SPC2WBM: Request size is Unknown");
|
415 |
|
|
endcase
|
416 |
|
|
$display("INFO: SPC2WBM: Address is %X", spc2wbm_addr);
|
417 |
|
|
$display("INFO: SPC2WBM: Data is %X", spc2wbm_data);
|
418 |
51 |
fafa1971 |
`endif
|
419 |
4 |
fafa1971 |
// synopsys translate_on
|
420 |
|
|
|
421 |
|
|
// Unconditional state change
|
422 |
51 |
fafa1971 |
state <= `STATE_REQUEST_GRANTED;
|
423 |
4 |
fafa1971 |
|
424 |
|
|
// FSM State 4: STATE_REQUEST_GRANTED
|
425 |
|
|
// Wishbone access completed, latch the incoming data
|
426 |
|
|
end else if(state==`STATE_REQUEST_GRANTED) begin
|
427 |
|
|
|
428 |
|
|
// Wait until Wishbone access completes
|
429 |
|
|
if(wbm_ack_i==1) begin
|
430 |
|
|
|
431 |
|
|
// Clear previously modified outputs
|
432 |
51 |
fafa1971 |
if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
|
433 |
|
|
wbm_strobe_o <= 0;
|
434 |
|
|
wbm_we_o <= 0;
|
435 |
|
|
wbm_addr_o <= 64'b0;
|
436 |
|
|
wbm_data_o <= 64'b0;
|
437 |
|
|
wbm_sel_o <= 8'b0;
|
438 |
4 |
fafa1971 |
|
439 |
|
|
// Latch the data and set up the return packet for the SPARC Core
|
440 |
51 |
fafa1971 |
wbm2spc_valid <= 1;
|
441 |
4 |
fafa1971 |
case(spc2wbm_type)
|
442 |
|
|
`IMISS_RQ: begin
|
443 |
51 |
fafa1971 |
wbm2spc_type <= `IFILL_RET; // I-Cache Miss
|
444 |
|
|
wbm2spc_atomic <= 0;
|
445 |
4 |
fafa1971 |
end
|
446 |
|
|
`LOAD_RQ: begin
|
447 |
51 |
fafa1971 |
wbm2spc_type <= `LOAD_RET; // Load
|
448 |
|
|
wbm2spc_atomic <= spc2wbm_atomic;
|
449 |
4 |
fafa1971 |
end
|
450 |
|
|
`STORE_RQ: begin
|
451 |
51 |
fafa1971 |
wbm2spc_type <= `ST_ACK; // Store
|
452 |
|
|
wbm2spc_atomic <= spc2wbm_atomic;
|
453 |
4 |
fafa1971 |
end
|
454 |
|
|
endcase
|
455 |
51 |
fafa1971 |
wbm2spc_miss <= 0;
|
456 |
|
|
wbm2spc_error <= 0;
|
457 |
|
|
wbm2spc_nc <= spc2wbm_nc;
|
458 |
|
|
wbm2spc_thread <= spc2wbm_thread;
|
459 |
|
|
wbm2spc_way_valid <= 0;
|
460 |
|
|
wbm2spc_way <= 0;
|
461 |
|
|
if(spc2wbm_region==5'b10000) wbm2spc_boot_fetch <= 1;
|
462 |
|
|
else wbm2spc_boot_fetch <= 0;
|
463 |
|
|
wbm2spc_pfl <= 0;
|
464 |
|
|
if(spc2wbm_addr[3]==0) wbm2spc_data <= { wbm_data_i, 64'b0 };
|
465 |
|
|
else wbm2spc_data <= { 64'b0, wbm_data_i };
|
466 |
4 |
fafa1971 |
|
467 |
|
|
// See if other 64-bit Wishbone accesses are required
|
468 |
|
|
if(
|
469 |
|
|
// Instruction miss directed to RAM expects 256 bits
|
470 |
|
|
( (spc2wbm_type==`IMISS_RQ)&&(spc2wbm_region!=5'b10000) ) ||
|
471 |
|
|
// Data access of 128 bits
|
472 |
|
|
( (spc2wbm_type==`LOAD_RQ)&&(spc2wbm_size==`PCX_SZ_16B) )
|
473 |
|
|
)
|
474 |
51 |
fafa1971 |
state <= `STATE_ACCESS2_BEGIN;
|
475 |
4 |
fafa1971 |
else
|
476 |
51 |
fafa1971 |
state <= `STATE_PACKET_READY;
|
477 |
4 |
fafa1971 |
|
478 |
51 |
fafa1971 |
end else state <= `STATE_REQUEST_GRANTED;
|
479 |
4 |
fafa1971 |
|
480 |
|
|
// FSM State 5: STATE_ACCESS2_BEGIN
|
481 |
|
|
// If needed start a second read access to the Wishbone bus
|
482 |
|
|
end else if(state==`STATE_ACCESS2_BEGIN) begin
|
483 |
|
|
|
484 |
|
|
// Issue a second request on the Wishbone bus
|
485 |
51 |
fafa1971 |
wbm_cycle_o <= 1;
|
486 |
|
|
wbm_strobe_o <= 1;
|
487 |
|
|
wbm_we_o <= 0;
|
488 |
|
|
wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:4], 4'b1000 }; // 2nd doubleword inside the same quadword
|
489 |
|
|
wbm_data_o <= 64'b0;
|
490 |
|
|
wbm_sel_o <= 8'b11111111;
|
491 |
4 |
fafa1971 |
|
492 |
|
|
// Unconditional state change
|
493 |
51 |
fafa1971 |
state <= `STATE_ACCESS2_END;
|
494 |
4 |
fafa1971 |
|
495 |
|
|
// FSM State 6: STATE_ACCESS2_END
|
496 |
|
|
// Latch the second data returning from Wishbone when ready
|
497 |
|
|
end else if(state==`STATE_ACCESS2_END) begin
|
498 |
|
|
|
499 |
|
|
// Wait until Wishbone access completes
|
500 |
|
|
if(wbm_ack_i==1) begin
|
501 |
|
|
|
502 |
|
|
// Clear previously modified outputs
|
503 |
51 |
fafa1971 |
if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
|
504 |
|
|
wbm_strobe_o <= 0;
|
505 |
|
|
wbm_we_o <= 0;
|
506 |
|
|
wbm_addr_o <= 64'b0;
|
507 |
|
|
wbm_data_o <= 64'b0;
|
508 |
|
|
wbm_sel_o <= 8'b0;
|
509 |
4 |
fafa1971 |
|
510 |
|
|
// Latch the data and set up the return packet for the SPARC Core
|
511 |
51 |
fafa1971 |
wbm2spc_data[63:0] <= wbm_data_i;
|
512 |
4 |
fafa1971 |
|
513 |
|
|
// See if two return packets are required or just one
|
514 |
|
|
if(spc2wbm_type==`IMISS_RQ && spc2wbm_region==5'b10000)
|
515 |
51 |
fafa1971 |
state <= `STATE_PACKET_READY;
|
516 |
4 |
fafa1971 |
else
|
517 |
51 |
fafa1971 |
state <= `STATE_ACCESS3_BEGIN;
|
518 |
4 |
fafa1971 |
|
519 |
51 |
fafa1971 |
end else state <= `STATE_ACCESS2_END;
|
520 |
4 |
fafa1971 |
|
521 |
|
|
// FSM State 7: STATE_ACCESS3_BEGIN
|
522 |
|
|
// If needed start a third read access to the Wishbone bus
|
523 |
|
|
// In the meanwhile we can return the first 128-bit packet
|
524 |
|
|
end else if(state==`STATE_ACCESS3_BEGIN) begin
|
525 |
|
|
|
526 |
|
|
// Return the packet to the SPARC Core
|
527 |
51 |
fafa1971 |
spc_ready_o <= 1;
|
528 |
|
|
spc_packetin_o <= wbm2spc_packet;
|
529 |
4 |
fafa1971 |
|
530 |
|
|
// Issue a third request on the Wishbone bus
|
531 |
51 |
fafa1971 |
wbm_cycle_o <= 1;
|
532 |
|
|
wbm_strobe_o <= 1;
|
533 |
|
|
wbm_we_o <= 0;
|
534 |
|
|
wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:5], 5'b10000 }; // 3nd doubleword inside the same 256-bit data
|
535 |
|
|
wbm_data_o <= 64'b0;
|
536 |
|
|
wbm_sel_o <= 8'b11111111;
|
537 |
4 |
fafa1971 |
|
538 |
|
|
// synopsys translate_off
|
539 |
|
|
// Print details of return packet
|
540 |
51 |
fafa1971 |
`ifdef DEBUG
|
541 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: *** RETURN PACKET TO SPARC CORE ***");
|
542 |
|
|
$display("INFO: WBM2SPC: Valid bit is %X", wbm2spc_valid);
|
543 |
4 |
fafa1971 |
case(wbm2spc_type)
|
544 |
|
|
`IFILL_RET: $display("INFO: WBM2SPC: Return Packet of Type IFILL_RET");
|
545 |
|
|
`LOAD_RET: $display("INFO: WBM2SPC: Return Packet of Type LOAD_RET");
|
546 |
|
|
`ST_ACK: $display("INFO: WBM2SPC: Return Packet of Type ST_ACK");
|
547 |
|
|
default: $display("INFO: WBM2SPC: Return Packet of Type Unknown");
|
548 |
|
|
endcase
|
549 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: L2 Miss is %X", wbm2spc_miss);
|
550 |
11 |
fafa1971 |
$display("INFO: WBM2SPC: Error is %X", wbm2spc_error);
|
551 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: Non-Cacheable bit is %X", wbm2spc_nc);
|
552 |
4 |
fafa1971 |
$display("INFO: WBM2SPC: Thread is %X", wbm2spc_thread);
|
553 |
11 |
fafa1971 |
$display("INFO: WBM2SPC: Way Valid is %X", wbm2spc_way_valid);
|
554 |
|
|
$display("INFO: WBM2SPC: Replaced L2 Way is %X", wbm2spc_way);
|
555 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: Fetch for Boot is %X", wbm2spc_boot_fetch);
|
556 |
|
|
$display("INFO: WBM2SPC: Atomic LD/ST or 2nd IFill Packet is %X", wbm2spc_atomic);
|
557 |
|
|
$display("INFO: WBM2SPC: PFL is %X", wbm2spc_pfl);
|
558 |
4 |
fafa1971 |
$display("INFO: WBM2SPC: Data is %X", wbm2spc_data);
|
559 |
51 |
fafa1971 |
`endif
|
560 |
4 |
fafa1971 |
// synopsys translate_on
|
561 |
|
|
|
562 |
|
|
// Unconditional state change
|
563 |
51 |
fafa1971 |
state <= `STATE_ACCESS3_END;
|
564 |
4 |
fafa1971 |
|
565 |
|
|
// FSM State 8: STATE_ACCESS3_END
|
566 |
|
|
// Latch the second data returning from Wishbone when ready
|
567 |
|
|
end else if(state==`STATE_ACCESS3_END) begin
|
568 |
|
|
|
569 |
|
|
// Clear previously modified outputs
|
570 |
51 |
fafa1971 |
spc_ready_o <= 0;
|
571 |
4 |
fafa1971 |
|
572 |
|
|
// Wait until Wishbone access completes
|
573 |
|
|
if(wbm_ack_i==1) begin
|
574 |
|
|
|
575 |
|
|
// Clear previously modified outputs
|
576 |
51 |
fafa1971 |
if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
|
577 |
|
|
wbm_strobe_o <= 0;
|
578 |
|
|
wbm_we_o <= 0;
|
579 |
|
|
wbm_addr_o <= 64'b0;
|
580 |
|
|
wbm_data_o <= 64'b0;
|
581 |
|
|
wbm_sel_o <= 8'b0;
|
582 |
4 |
fafa1971 |
|
583 |
|
|
// Latch the data and set up the return packet for the SPARC Core
|
584 |
51 |
fafa1971 |
wbm2spc_data <= { wbm_data_i, 64'b0 };
|
585 |
4 |
fafa1971 |
|
586 |
|
|
// Jump to next state
|
587 |
51 |
fafa1971 |
state <= `STATE_ACCESS4_BEGIN;
|
588 |
4 |
fafa1971 |
|
589 |
51 |
fafa1971 |
end else state <= `STATE_ACCESS3_END;
|
590 |
4 |
fafa1971 |
|
591 |
|
|
// FSM State 9: STATE_ACCESS4_BEGIN
|
592 |
|
|
// If needed start a second read access to the Wishbone bus
|
593 |
|
|
end else if(state==`STATE_ACCESS4_BEGIN) begin
|
594 |
|
|
|
595 |
|
|
// Issue a fourth request on the Wishbone bus
|
596 |
51 |
fafa1971 |
wbm_cycle_o <= 1;
|
597 |
|
|
wbm_strobe_o <= 1;
|
598 |
|
|
wbm_we_o <= 0;
|
599 |
|
|
wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:5], 5'b11000 }; // 4th doubleword inside the same 256-bit data
|
600 |
|
|
wbm_data_o <= 64'b0;
|
601 |
|
|
wbm_sel_o <= 8'b11111111;
|
602 |
4 |
fafa1971 |
|
603 |
|
|
// Unconditional state change
|
604 |
51 |
fafa1971 |
state <= `STATE_ACCESS4_END;
|
605 |
4 |
fafa1971 |
|
606 |
|
|
// FSM State 10: STATE_ACCESS4_END
|
607 |
|
|
// Latch the second data returning from Wishbone when ready
|
608 |
|
|
end else if(state==`STATE_ACCESS4_END) begin
|
609 |
|
|
|
610 |
|
|
// Wait until Wishbone access completes
|
611 |
|
|
if(wbm_ack_i==1) begin
|
612 |
|
|
|
613 |
|
|
// Clear previously modified outputs
|
614 |
51 |
fafa1971 |
if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
|
615 |
|
|
wbm_strobe_o <= 0;
|
616 |
|
|
wbm_we_o <= 0;
|
617 |
|
|
wbm_addr_o <= 64'b0;
|
618 |
|
|
wbm_data_o <= 64'b0;
|
619 |
|
|
wbm_sel_o <= 8'b0;
|
620 |
4 |
fafa1971 |
|
621 |
|
|
// Latch the data and set up the return packet for the SPARC Core
|
622 |
51 |
fafa1971 |
wbm2spc_atomic <= 1;
|
623 |
|
|
wbm2spc_data[63:0] <= wbm_data_i;
|
624 |
4 |
fafa1971 |
|
625 |
|
|
// Jump to next state
|
626 |
51 |
fafa1971 |
state <= `STATE_PACKET_READY;
|
627 |
4 |
fafa1971 |
|
628 |
51 |
fafa1971 |
end else state <= `STATE_ACCESS4_END;
|
629 |
4 |
fafa1971 |
|
630 |
|
|
// FSM State 11: STATE_PACKET_READY
|
631 |
|
|
// We can start returning the packet to the SPARC Core
|
632 |
|
|
end else if(state==`STATE_PACKET_READY) begin
|
633 |
|
|
|
634 |
|
|
// Return the packet to the SPARC Core
|
635 |
51 |
fafa1971 |
spc_ready_o <= 1;
|
636 |
|
|
spc_packetin_o <= wbm2spc_packet;
|
637 |
4 |
fafa1971 |
|
638 |
99 |
fafa1971 |
// Resume requests
|
639 |
|
|
spc_resume_o <= 1;
|
640 |
|
|
|
641 |
4 |
fafa1971 |
// Unconditional state change
|
642 |
51 |
fafa1971 |
state <= `STATE_IDLE;
|
643 |
4 |
fafa1971 |
|
644 |
|
|
// synopsys translate_off
|
645 |
|
|
// Print details of return packet
|
646 |
51 |
fafa1971 |
`ifdef DEBUG
|
647 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: *** RETURN PACKET TO SPARC CORE ***");
|
648 |
11 |
fafa1971 |
$display("INFO: WBM2SPC: Valid bit is %X", wbm2spc_valid);
|
649 |
4 |
fafa1971 |
case(wbm2spc_type)
|
650 |
|
|
`IFILL_RET: $display("INFO: WBM2SPC: Return Packet of Type IFILL_RET");
|
651 |
|
|
`LOAD_RET: $display("INFO: WBM2SPC: Return Packet of Type LOAD_RET");
|
652 |
|
|
`ST_ACK: $display("INFO: WBM2SPC: Return Packet of Type ST_ACK");
|
653 |
|
|
default: $display("INFO: WBM2SPC: Return Packet of Type Unknown");
|
654 |
|
|
endcase
|
655 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: L2 Miss is %X", wbm2spc_miss);
|
656 |
11 |
fafa1971 |
$display("INFO: WBM2SPC: Error is %X", wbm2spc_error);
|
657 |
|
|
$display("INFO: WBM2SPC: Non-Cacheable bit is %X", wbm2spc_nc);
|
658 |
4 |
fafa1971 |
$display("INFO: WBM2SPC: Thread is %X", wbm2spc_thread);
|
659 |
11 |
fafa1971 |
$display("INFO: WBM2SPC: Way Valid is %X", wbm2spc_way_valid);
|
660 |
|
|
$display("INFO: WBM2SPC: Replaced L2 Way is %X", wbm2spc_way);
|
661 |
12 |
fafa1971 |
$display("INFO: WBM2SPC: Fetch for Boot is %X", wbm2spc_boot_fetch);
|
662 |
|
|
$display("INFO: WBM2SPC: Atomic LD/ST or 2nd IFill Packet is %X", wbm2spc_atomic);
|
663 |
|
|
$display("INFO: WBM2SPC: PFL is %X", wbm2spc_pfl);
|
664 |
4 |
fafa1971 |
$display("INFO: WBM2SPC: Data is %X", wbm2spc_data);
|
665 |
51 |
fafa1971 |
`endif
|
666 |
4 |
fafa1971 |
// synopsys translate_on
|
667 |
|
|
|
668 |
|
|
end
|
669 |
|
|
end
|
670 |
|
|
end
|
671 |
|
|
|
672 |
|
|
endmodule
|
673 |
|
|
|