Add Wishbone datasheets
[AGH_computer_science_engineering_thesis.git] / design / slave_dispatcher.v
blob4da0dbd80be7ffcd8740789df18a7f1d2e94d501
1 `default_nettype none
3 module slave_dispatcher
5 input wire CLK,
6 input wire RST,
8 input wire S0_ACK_O,
9 output wire [17:0] S0_ADR_I,
10 output wire [15:0] S0_DAT_I,
11 input wire [15:0] S0_DAT_O,
12 output wire S0_STB_I,
13 output wire S0_WE_I,
14 input wire S0_STALL_O,
16 input wire S1_ACK_O,
17 output wire [17:0] S1_ADR_I,
18 output wire [15:0] S1_DAT_I,
19 input wire [15:0] S1_DAT_O,
20 output wire S1_STB_I,
21 output wire S1_WE_I,
22 input wire S1_STALL_O,
24 input wire S2_ACK_O,
25 output wire [16:0] S2_ADR_I,
26 output wire [15:0] S2_DAT_I,
27 input wire [15:0] S2_DAT_O,
28 output wire S2_STB_I,
29 output wire S2_WE_I,
30 input wire S2_STALL_O,
32 input wire S3_ACK_O,
33 output wire [16:0] S3_ADR_I,
34 output wire [15:0] S3_DAT_I,
35 input wire [15:0] S3_DAT_O,
36 output wire S3_STB_I,
37 output wire S3_WE_I,
38 input wire S3_STALL_O,
40 input wire S4_ACK_O,
41 output wire [16:0] S4_ADR_I,
42 output wire [15:0] S4_DAT_I,
43 input wire [15:0] S4_DAT_O,
44 output wire S4_STB_I,
45 output wire S4_WE_I,
46 input wire S4_STALL_O,
48 input wire S5_ACK_O,
49 output wire [16:0] S5_ADR_I,
50 output wire [15:0] S5_DAT_I,
51 input wire [15:0] S5_DAT_O,
52 output wire S5_STB_I,
53 output wire S5_WE_I,
54 input wire S5_STALL_O,
56 output wire S_COMBINED_ACK_O,
57 input wire [19:0] S_COMBINED_ADR_I,
58 input wire [15:0] S_COMBINED_DAT_I,
59 output wire [15:0] S_COMBINED_DAT_O,
60 input wire S_COMBINED_STB_I,
61 input wire S_COMBINED_WE_I,
62 output wire S_COMBINED_STALL_O
65 wire [0:5] acks;
66 wire [0:5] stalls;
67 wire [15:0] datas [0:5];
68 assign acks = {S0_ACK_O, S1_ACK_O, S2_ACK_O, S3_ACK_O, S4_ACK_O, S5_ACK_O};
69 assign stalls = {S0_STALL_O, S1_STALL_O, S2_STALL_O,
70 S3_STALL_O, S4_STALL_O, S5_STALL_O};
71 assign datas[0] = S0_DAT_O;
72 assign datas[1] = S1_DAT_O;
73 assign datas[2] = S2_DAT_O;
74 assign datas[3] = S3_DAT_O;
75 assign datas[4] = S4_DAT_O;
76 assign datas[5] = S5_DAT_O;
78 reg [1:0] commands_awaiting;
79 reg [2:0] slave_last_accessed;
81 wire working;
82 wire [2:0] slave_accessed;
83 wire [2:0] slave_requested;
84 wire slave_switch;
85 wire [1:0] commands_awaiting_next_tick;
86 assign working = commands_awaiting || S_COMBINED_STB_I;
87 assign slave_requested = S_COMBINED_ADR_I[19] ?
88 /* one of 4 smaller slaves */
89 S_COMBINED_ADR_I[18:17] + 2 :
90 /* one of 2 bigger slaves */
91 S_COMBINED_ADR_I[19:18];
92 assign slave_accessed = commands_awaiting ? slave_last_accessed :
93 slave_requested;
94 assign S_COMBINED_ACK_O = acks[slave_accessed] && working;
95 assign S_COMBINED_DAT_O = datas[slave_accessed];
96 assign slave_switch = slave_accessed != slave_requested;
97 assign S_COMBINED_STALL_O = stalls[slave_accessed] || slave_switch ||
98 (commands_awaiting == 3 && !S_COMBINED_ACK_O);
99 assign commands_awaiting_next_tick
100 = commands_awaiting - S_COMBINED_ACK_O +
101 (S_COMBINED_STB_I && !S_COMBINED_STALL_O);
103 `ifdef SIMULATION
104 /* anything could be latched here, this is just to avoid undefined values */
105 initial begin
106 slave_last_accessed <= 0;
107 commands_awaiting <= 2; /* It is supposed to be driven low by RST */
109 `endif
111 always @ (posedge CLK) begin
112 slave_last_accessed <= slave_accessed;
114 if (RST)
115 commands_awaiting <= 0;
116 else
117 commands_awaiting <= commands_awaiting_next_tick;
120 assign S0_ADR_I = S_COMBINED_ADR_I[17:0];
121 assign S1_ADR_I = S_COMBINED_ADR_I[17:0];
122 assign S2_ADR_I = S_COMBINED_ADR_I[16:0];
123 assign S3_ADR_I = S_COMBINED_ADR_I[16:0];
124 assign S4_ADR_I = S_COMBINED_ADR_I[16:0];
125 assign S5_ADR_I = S_COMBINED_ADR_I[16:0];
127 assign S0_DAT_I = S_COMBINED_DAT_I;
128 assign S1_DAT_I = S_COMBINED_DAT_I;
129 assign S2_DAT_I = S_COMBINED_DAT_I;
130 assign S3_DAT_I = S_COMBINED_DAT_I;
131 assign S4_DAT_I = S_COMBINED_DAT_I;
132 assign S5_DAT_I = S_COMBINED_DAT_I;
134 wire pass_strobe;
135 assign pass_strobe = S_COMBINED_STB_I && !slave_switch &&
136 (commands_awaiting != 3 || S_COMBINED_ACK_O);
138 assign S0_STB_I = slave_accessed == 0 && pass_strobe;
139 assign S1_STB_I = slave_accessed == 1 && pass_strobe;
140 assign S2_STB_I = slave_accessed == 2 && pass_strobe;
141 assign S3_STB_I = slave_accessed == 3 && pass_strobe;
142 assign S4_STB_I = slave_accessed == 4 && pass_strobe;
143 assign S5_STB_I = slave_accessed == 5 && pass_strobe;
145 assign S0_WE_I = S_COMBINED_WE_I;
146 assign S1_WE_I = S_COMBINED_WE_I;
147 assign S2_WE_I = S_COMBINED_WE_I;
148 assign S3_WE_I = S_COMBINED_WE_I;
149 assign S4_WE_I = S_COMBINED_WE_I;
150 assign S5_WE_I = S_COMBINED_WE_I;
151 endmodule // slave_dispatcher