5353//
5454//
5555`default_nettype none
56- //
57- `define CMD_SUB_RD 2'b00
58- `define CMD_SUB_WR 2'b01
59- `define CMD_SUB_BUS 1'b0
60- `define CMD_SUB_ADDR 2'b10
61- `define CMD_SUB_SPECIAL 2'b11
62- //
63- `define RSP_SUB_DATA 2'b00
64- `define RSP_SUB_ACK 2'b01
65- `define RSP_SUB_ADDR 2'b10
66- `define RSP_SUB_SPECIAL 2'b11
67- //
56+
57+ /* -------------------------------------------------------------------------- */
58+ /* Request "opcodes" */
59+ /* -------------------------------------------------------------------------- */
60+
61+ `define CMD_SUB_RD 2'b00 // Read request
62+ `define CMD_SUB_WR 2'b01 // Write request
63+ `define CMD_SUB_BUS 1'b0 // A request in general
64+ `define CMD_SUB_ADDR 2'b10 // Set an address
65+ `define CMD_SUB_SPECIAL 2'b11 // Bus reset
66+
67+ /* -------------------------------------------------------------------------- */
68+ /* Response "opcodes" */
69+ /* -------------------------------------------------------------------------- */
70+
71+ `define RSP_SUB_DATA 2'b00 // Result of data read from the bus
72+ `define RSP_SUB_ACK 2'b01 // Acknowledgement
73+ `define RSP_SUB_ADDR 2'b10 // Acknowledge new address
74+ `define RSP_SUB_SPECIAL 2'b11 // Either a bus reset, or an error (see below)
75+
76+ /* -------------------------------------------------------------------------- */
77+ /* Possible responses */
78+ /* -------------------------------------------------------------------------- */
79+ // Write acknowledgement
6880`define RSP_WRITE_ACKNOWLEDGEMENT { `RSP_SUB_ACK, 32'h0 }
81+ // Bus reset
82+ // (This causes us to abandon any bus cycle we may be in the middle of)
6983`define RSP_RESET { `RSP_SUB_SPECIAL, 3'h0 , 29'h00 }
84+ // Bus error
7085`define RSP_BUS_ERROR { `RSP_SUB_SPECIAL, 3'h1 , 29'h00 }
71- // }}}
86+
87+ /* -------------------------------------------------------------------------- */
88+ /* The actual manager module */
89+ /* -------------------------------------------------------------------------- */
90+
7291module hbexec #(
7392 // {{{
7493 parameter ADDRESS_WIDTH= 30 ,
7594 localparam AW= ADDRESS_WIDTH, // Shorthand for address width
7695 CW= 34 // Command word width
7796 // }}}
7897 ) (
79- // {{{
8098 input wire i_clk, i_reset,
81- // The input command channel
82- // {{{
99+
100+ /* ------------------------------------------------------------------------ */
101+ /* The input command channel */
102+ /* ------------------------------------------------------------------------ */
103+
83104 input wire i_cmd_stb,
84- input wire [(CW- 1 ):0 ] i_cmd_word,
105+
106+ // `i_cmd_word` is a 34-bit word containing the command (read/write, etc.)
107+ // We use the top 2 bits of the 34-bit word to indicate what type
108+ // of command we're issuing.
109+ // We then use the bottom 32 bits for passing data values.
110+ // The encoding is as follows:
111+ // 33 32 31 - 0
112+ // 0 0 Read request, ignore the rest of the 32-bits, ACK on output
113+ // 0 1 Write request, the 32-bit data contains the word to be written
114+ // 1 0 Set an address. If bit 31 is set, we’ll add this value to the current bus address.
115+ // If bit 30 is set, the address will be incremented upon each bus access
116+ // 1 1 4’h0, 28’hxx, Bus Reset
117+ input wire [(CW- 1 ):0 ] i_cmd_word,
118+
119+ // `o_cmd_busy` is true any time the bus is active
85120 output wire o_cmd_busy,
86- // }}}
87- // The return command channel
88- // {{{
121+
122+
123+ /* ------------------------------------------------------------------------ */
124+ /* The return command channel */
125+ /* ------------------------------------------------------------------------ */
126+ // `o_rsp_stb` is true whenever the output references a valid codeword
89127 output reg o_rsp_stb,
128+
129+ // The 34-bit output codeword, encoded as follows:
130+ // 33 32 31 - 0
131+ // 0 0 Acknowledge a write. The 32-bit value contains number of writes to acknowledge
132+ // 0 1 Read response, the 32 data bits are the word that was read
133+ // 1 0 Acknowledge an address that has been set, with two zero bits and 30 address bits
134+ // 1 1 N/A
135+ // 1 1 3’h0, 29’hxx, Bus Reset acknowledgement
136+ // 1 1 3’h1, 29’hxx, Bus Error
90137 output reg [(CW- 1 ):0 ] o_rsp_word,
91- // }}}
92- // Wishbone outputs
93- // {{{
138+
139+ /* ------------------------------------------------------------------------ */
140+ /* Wishbone outputs */
141+ /* ------------------------------------------------------------------------ */
94142 output reg o_wb_cyc, o_wb_stb, o_wb_we,
95143 output reg [(AW- 1 ):0 ] o_wb_addr,
96144 output reg [31 :0 ] o_wb_data,
97145 output wire [3 :0 ] o_wb_sel,
98- // }}}
99- // Wishbone inputs
100- // {{{
146+
147+ /* ------------------------------------------------------------------------ */
148+ /* Wishbone inputs */
149+ /* ------------------------------------------------------------------------ */
150+
101151 input wire i_wb_stall, i_wb_ack, i_wb_err,
102152 input wire [31 :0 ] i_wb_data
103- // }}}
104- // }}}
105153 );
106154
107155 // Local declarations
108- // {{{
109156 reg newaddr, inc;
110157 wire i_cmd_addr, i_cmd_wr, i_cmd_rd, i_cmd_bus;
111- // }}}
112158
113- //
114- // Decode our input commands
115- // {{{
159+ /* ------------------------------------------------------------------------- */
160+ /* Decode input commands */
161+ /* ------------------------------------------------------------------------- */
162+
163+ // Decode our input commands (represented using a 34-bit word `i_cmd_word`)
164+ // Input commands are valid only when `i_cmd_stb` is valid,
165+ // and the commands are accepted only when `o_cmd_busy` is false
166+
167+ // Set address
168+ // If bit 31 is set, we add the value to the current bus address
169+ // If bit 30 is set, the address is incremented upon each bus access
116170 assign i_cmd_addr = (i_cmd_stb)&& (i_cmd_word[33 :32 ] == `CMD_SUB_ADDR);
171+
172+ // Read request (ignore lower 32 bits of word)
117173 assign i_cmd_rd = (i_cmd_stb)&& (i_cmd_word[33 :32 ] == `CMD_SUB_RD);
174+
175+ // Write request (lower 32 bits of word containing the data to be written)
118176 assign i_cmd_wr = (i_cmd_stb)&& (i_cmd_word[33 :32 ] == `CMD_SUB_WR);
177+
178+ // We use `i_cmd_bus` to capture whether we have a read or write request
119179 assign i_cmd_bus = (i_cmd_stb)&& (i_cmd_word[33 ] == `CMD_SUB_BUS);
120- // }}}
121180
122- // o_wb_cyc, o_wb_stb
123- // {{{
124- // These two linse control our state
181+ /* ------------------------------------------------------------------------- */
182+ /* Logic for updating `cyc` and `stb` */
183+ /* ------------------------------------------------------------------------- */
184+
185+ // Initialize the `cyc` and `stb` signals to 0 at time 0
186+ // The `initial` keyword is only for simulation / testbench purposes
125187 initial o_wb_cyc = 1'b0 ;
126188 initial o_wb_stb = 1'b0 ;
189+
127190 always @(posedge i_clk)
128191 if ((i_reset)|| ((i_wb_err)&& (o_wb_cyc)))
129192 begin
130- // On any error or reset, then clear the bus.
193+ // Set `cyc` & `stb` both to 0 on any error or reset, then clear the bus.
131194 o_wb_cyc <= 1'b0 ;
132195 o_wb_stb <= 1'b0 ;
133196 end else if (o_wb_stb)
134197 begin
135- //
136- // BUS REQUEST state
137- //
198+
199+ /* ------------------------------------------------------------------------ */
200+ /* BUS REQUEST state (cyc = 1, stb = 1) */
201+ /* ------------------------------------------------------------------------ */
202+
138203 if (! i_wb_stall)
139204 // If we are only going to do one transaction,
140- // then as soon as the stall line is lowered, we are
141- // done.
205+ // as soon as the stall line is lowered, we are
206+ // done, in which case set `stb = 0`
142207 o_wb_stb <= 1'b0 ;
143208
144209 // While not likely, it is possible that a slave might ACK
@@ -154,25 +219,28 @@ module hbexec #(
154219 o_wb_cyc <= 1'b0 ;
155220 end else if (o_wb_cyc)
156221 begin
157- //
158- // BUS WAIT
159- //
222+
223+ /* ------------------------------------------------------------------------ */
224+ /* BUS WAIT state (cyc = 1, stb = 0) */
225+ /* ------------------------------------------------------------------------ */
160226 if (i_wb_ack)
161227 // Once the slave acknowledges our request, we are done.
162228 o_wb_cyc <= 1'b0 ;
163229 end else begin
164- //
165- // IDLE state
166- //
230+
231+ /* ------------------------------------------------------------------------ */
232+ /* IDLE state (cyc = 0, syb = 0) */
233+ /* ------------------------------------------------------------------------ */
234+
167235 if (i_cmd_bus)
168236 begin
169237 // We've been asked to start a bus cycle from our
170- // command word, either RD or WR
238+ // command word, i.e. we're performing a read/write request.
239+ // Either way, we need to set `cyc` and `stb` both to 1
171240 o_wb_cyc <= 1'b1 ;
172241 o_wb_stb <= 1'b1 ;
173242 end
174243 end
175- // }}}
176244
177245 // For now, we'll use the bus cycle line as an indication of whether
178246 // or not we are too busy to accept anything else from the command
@@ -182,20 +250,24 @@ module hbexec #(
182250 assign o_cmd_busy = o_wb_cyc;
183251
184252
185- //
186- // The bus WE (write enable) line, governing wishbone direction
187- //
188- // We'll never change direction mid bus-cycle--at least not in this
253+ /* ------------------------------------------------------------------------- */
254+ /* Logic for detemrining the output bus WE (write enable) line */
255+ /* ------------------------------------------------------------------------- */
256+ // `o_wb_we` determines the request direction
257+ // We only accept commands when we are in the idle state,
258+ // and we only transition to the bus request state on a read/write command,
259+ // so the following `always` block is sufficient.
260+ // Also, we'll never change direction mid bus-cycle--at least not in this
189261 // implementation (atomic accesses may require it at a later date).
190262 // Hence, if CYC is low we can set the direction.
191263 always @(posedge i_clk)
192264 if (! o_wb_cyc)
193265 o_wb_we <= (i_cmd_wr);
194266
195- // o_wb_addr
196- // {{{
197- // The bus ADDRESS lines
198- //
267+
268+ /* ------------------------------------------------------------------------- */
269+ /* Logic for updating `o_wb_addr` (the bus ADDRESS line) */
270+ /* ------------------------------------------------------------------------- * /
199271 initial newaddr = 1'b0 ;
200272 always @(posedge i_clk)
201273 begin
@@ -214,12 +286,12 @@ module hbexec #(
214286 else
215287 o_wb_addr <= i_cmd_word[AW+ 1 :2 ] + o_wb_addr;
216288
217- //
218289 // We'll allow that bus requests can either increment
219290 // the address, or leave it the same. One bit in the
220291 // command word will tell us which, and we'll set this
221292 // bit on any set address command.
222293 inc <= ! i_cmd_word[0 ];
294+
223295 end else if ((o_wb_stb)&& (! i_wb_stall))
224296 // The address lines are used while the bus is active,
225297 // and referenced any time STB && !STALL are true.
@@ -242,14 +314,11 @@ module hbexec #(
242314 // returned via the command link.
243315 newaddr <= ((! i_reset)&& (i_cmd_addr)&& (! o_cmd_busy));
244316 end
245- // }}}
246317
247- //
248- // The bus DATA (output) lines
249- //
250-
251- // o_wb_data
252- // {{{
318+ /* ------------------------------------------------------------------------- */
319+ /* Logic for setting `o_wb_data` (The bus DATA (output) lines) */
320+ /* ------------------------------------------------------------------------- */
321+
253322 always @(posedge i_clk)
254323 begin
255324 // This may look a touch confusing ... what's important is that:
@@ -271,24 +340,20 @@ module hbexec #(
271340 if ((! o_wb_stb)|| (! i_wb_stall))
272341 o_wb_data <= i_cmd_word[31 :0 ];
273342 end
274- // }}}
275343
276- //
344+
277345 // For this command bus channel, we'll only ever direct word addressing.
278- //
279346 assign o_wb_sel = 4'hf ;
280347
281- //
282- // The COMMAND RESPONSE return channel
283- //
284-
285- // o_rsp_stb, o_rsp_word
286- // {{{
348+ /* ------------------------------------------------------------------------- */
349+ /* Logic for updating `o_rsp_stb`, `o_rsp_word` */
350+ /* (The COMMAND RESPONSE return channel) */
351+ /* ------------------------------------------------------------------------- */
287352 // This is where we set o_rsp_stb and o_rsp_word for the return channel.
288353 // The logic is set so that o_rsp_stb will be true for any one clock
289354 // where we have data to reutrn, and zero otherwise. If o_rsp_stb is
290355 // true, then o_rsp_word is the response we want to return. In all
291- // other cases, o_rsp_word is a don't care .
356+ // other cases, o_rsp_word is DontCare .
292357 initial o_rsp_stb = 1'b1 ;
293358 initial o_rsp_word = `RSP_RESET;
294359 always @(posedge i_clk)
@@ -301,24 +366,22 @@ module hbexec #(
301366 o_rsp_stb <= 1'b1 ;
302367 o_rsp_word <= `RSP_BUS_ERROR;
303368 end else if (o_wb_cyc) begin
304- //
369+
305370 // We're either in the BUS REQUEST or BUS WAIT states
306- //
307371 // Either way, we want to return a response on our command
308372 // channel if anything gets ack'd
309373 o_rsp_stb <= (i_wb_ack);
310- //
311- //
374+
375+ // If write-enable is set, the response is a Write Acknowledgement.
376+ // Otherwise, return the data word in the response.
312377 if (o_wb_we)
313378 o_rsp_word <= `RSP_WRITE_ACKNOWLEDGEMENT;
314379 else
315380 o_rsp_word <= { `RSP_SUB_DATA, i_wb_data };
316381 end else begin
317- //
382+
318383 // We are in the IDLE state.
319- //
320- // Echo any new addresses back up the command chain
321- //
384+ // Echo any new addresses back up the command chain.
322385 o_rsp_stb <= newaddr;
323386 o_rsp_word <= { `RSP_SUB_ADDR,
324387 {(30 - ADDRESS_WIDTH){1'b0 }}, o_wb_addr, 1'b0 , ! inc };
0 commit comments