forked from SJTU-YONGFU-RESEARCH-GRP/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrossbar_switch.v
More file actions
executable file
·111 lines (103 loc) · 4.91 KB
/
crossbar_switch.v
File metadata and controls
executable file
·111 lines (103 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Crossbar Switch
*
* This module implements a crossbar switch (also known as a crosspoint switch)
* that can route any input to any output. Crossbar switches provide non-blocking
* connectivity, making them ideal for high-performance interconnects.
*
* Key Features:
* - Non-blocking: Any input can connect to any output simultaneously
* - Configurable routing: Per-output selection of input source
* - Multiple connections: Multiple outputs can connect to same input
* - Single-cycle routing: Routing occurs in one clock cycle
*
* Crossbar Architecture:
* - NUM_INPUTS input ports, each DATA_WIDTH bits wide
* - NUM_OUTPUTS output ports, each DATA_WIDTH bits wide
* - Selection matrix: Each output selects which input to connect to
* - No blocking: All connections can occur simultaneously
*
* Routing:
* - Each output has a select signal: select[output_index]
* - select[output_index] specifies which input to connect
* - Multiple outputs can connect to the same input (broadcast)
* - Each output can connect to a different input (unicast)
*
* Use Cases:
* - Network-on-Chip (NoC) routers
* - Multiprocessor interconnects
* - High-speed data routing
* - Memory controllers
* - Communication switches
*
* @param NUM_INPUTS Number of input ports (default: 4)
* @param NUM_OUTPUTS Number of output ports (default: 4)
* @param DATA_WIDTH Width of data on each port (default: 8 bits)
*
* @input clk Clock signal
* @input rst_n Active-low reset signal
* @input data_in[(NUM_INPUTS*DATA_WIDTH)-1:0] Input data (flattened array)
* @input select[(NUM_OUTPUTS*log2(NUM_INPUTS))-1:0] Selection matrix (flattened)
* Each output's selection: select[output*log2(NUM_INPUTS) +: log2(NUM_INPUTS)]
* @output data_out[(NUM_OUTPUTS*DATA_WIDTH)-1:0] Output data (flattened array)
*/
module crossbar_switch #(
parameter NUM_INPUTS = 4,
parameter NUM_OUTPUTS = 4,
parameter DATA_WIDTH = 8
)(
input wire clk,
input wire rst_n,
// Input data ports (flattened for Verilator compatibility)
input wire [(NUM_INPUTS*DATA_WIDTH)-1:0] data_in,
// Selection matrix: each output selects which input to connect to
input wire [(NUM_OUTPUTS*$clog2(NUM_INPUTS))-1:0] select,
// Output data ports (flattened for Verilator compatibility)
output reg [(NUM_OUTPUTS*DATA_WIDTH)-1:0] data_out
);
// ============================================================================
// Crossbar Switching Logic
// ============================================================================
// Routes inputs to outputs based on selection matrix
integer i; // Loop counter
reg [$clog2(NUM_INPUTS)-1:0] sel_idx; // Selected input index for current output
reg [DATA_WIDTH-1:0] selected_data; // Selected input data
/* verilator lint_off BLKSEQ */
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// ====================================================================
// Reset State
// ====================================================================
// Reset all outputs to zero
for (i = 0; i < NUM_OUTPUTS; i = i + 1) begin
data_out[(i*DATA_WIDTH) +: DATA_WIDTH] <= {DATA_WIDTH{1'b0}};
end
end else begin
// ====================================================================
// Routing Logic
// ====================================================================
// Route each output to its selected input
// All outputs are routed simultaneously (non-blocking)
for (i = 0; i < NUM_OUTPUTS; i = i + 1) begin
// ================================================================
// Extract Selection
// ================================================================
// Get the selection value for output i
// Selection specifies which input to connect to this output
sel_idx = select[(i*$clog2(NUM_INPUTS)) +: $clog2(NUM_INPUTS)];
// ================================================================
// Get Selected Input Data
// ================================================================
// Extract data from the selected input port
// sel_idx specifies which input (0 to NUM_INPUTS-1)
selected_data = data_in[(sel_idx*DATA_WIDTH) +: DATA_WIDTH];
// ================================================================
// Assign to Output
// ================================================================
// Route selected input data to output i
data_out[(i*DATA_WIDTH) +: DATA_WIDTH] <= selected_data;
end
end
end
/* verilator lint_on BLKSEQ */
endmodule