diff --git a/lib/rfnoc/utils/ctrlport_combiner.v b/lib/rfnoc/utils/ctrlport_combiner.v index b589514..e7c77de 100644 --- a/lib/rfnoc/utils/ctrlport_combiner.v +++ b/lib/rfnoc/utils/ctrlport_combiner.v @@ -109,25 +109,15 @@ module ctrlport_combiner #( reg [ NUM_MASTERS-1:0] req_has_time; reg [64*NUM_MASTERS-1:0] req_time; - always @(posedge ctrlport_clk) begin + always @(posedge ctrlport_clk) begin : input_buffer_block + integer i; if (ctrlport_rst) begin req_valid <= 0; end else begin : input_reg_gen - integer i; for (i = 0; i < NUM_MASTERS; i = i + 1) begin if (s_ctrlport_req_wr[i] | s_ctrlport_req_rd[i]) begin // Mark this slave's request valid and save the request information - req_valid[i] <= 1'b1; - req_wr[i] <= s_ctrlport_req_wr[i]; - req_rd[i] <= s_ctrlport_req_rd[i]; - req_addr[20*i+:20] <= s_ctrlport_req_addr[20*i+:20]; - req_portid[10*i+:10] <= s_ctrlport_req_portid[10*i+:10]; - req_rem_epid[16*i+:16] <= s_ctrlport_req_rem_epid[16*i+:16]; - req_rem_portid[10*i+:10] <= s_ctrlport_req_rem_portid[10*i+:10]; - req_data[32*i+:32] <= s_ctrlport_req_data[32*i+:32]; - req_byte_en[4*i+:4] <= s_ctrlport_req_byte_en[4*i+:4]; - req_has_time[i] <= s_ctrlport_req_has_time[i]; - req_time[64*i+:64] <= s_ctrlport_req_time[64*i+:64]; + req_valid[i] <= 1'b1; end end @@ -136,6 +126,22 @@ module ctrlport_combiner #( req_valid[slave_sel] <= 1'b0; end end + + // Buffer request information without reset + for (i = 0; i < NUM_MASTERS; i = i + 1) begin + if (s_ctrlport_req_wr[i] | s_ctrlport_req_rd[i]) begin + req_wr[i] <= s_ctrlport_req_wr[i]; + req_rd[i] <= s_ctrlport_req_rd[i]; + req_addr[20*i+:20] <= s_ctrlport_req_addr[20*i+:20]; + req_portid[10*i+:10] <= s_ctrlport_req_portid[10*i+:10]; + req_rem_epid[16*i+:16] <= s_ctrlport_req_rem_epid[16*i+:16]; + req_rem_portid[10*i+:10] <= s_ctrlport_req_rem_portid[10*i+:10]; + req_data[32*i+:32] <= s_ctrlport_req_data[32*i+:32]; + req_byte_en[4*i+:4] <= s_ctrlport_req_byte_en[4*i+:4]; + req_has_time[i] <= s_ctrlport_req_has_time[i]; + req_time[64*i+:64] <= s_ctrlport_req_time[64*i+:64]; + end + end end @@ -217,42 +223,46 @@ module ctrlport_combiner #( // //--------------------------------------------------------------------------- - always @(posedge ctrlport_clk) begin + always @(posedge ctrlport_clk) begin : output_reg_gen + integer i; + + // ---------- Request -------------- + // Load the active request + if (req_load_output) begin + m_ctrlport_req_wr <= req_wr [slave_sel]; + m_ctrlport_req_rd <= req_rd [slave_sel]; + m_ctrlport_req_addr <= req_addr [20*slave_sel +: 20]; + m_ctrlport_req_portid <= req_portid [10*slave_sel +: 10]; + m_ctrlport_req_rem_epid <= req_rem_epid [16*slave_sel +: 16]; + m_ctrlport_req_rem_portid <= req_rem_portid[10*slave_sel +: 10]; + m_ctrlport_req_data <= req_data [32*slave_sel +: 32]; + m_ctrlport_req_byte_en <= req_byte_en [ 4*slave_sel +: 4]; + m_ctrlport_req_has_time <= req_has_time [slave_sel]; + m_ctrlport_req_time <= req_time [64*slave_sel +: 64]; + end else begin + m_ctrlport_req_wr <= 1'b0; + m_ctrlport_req_rd <= 1'b0; + end + if (ctrlport_rst) begin m_ctrlport_req_wr <= 1'b0; m_ctrlport_req_rd <= 1'b0; - end else begin : output_reg_gen - integer i; + end - // Load the active request - if (req_load_output) begin - m_ctrlport_req_wr <= req_wr [slave_sel]; - m_ctrlport_req_rd <= req_rd [slave_sel]; - m_ctrlport_req_addr <= req_addr [20*slave_sel +: 20]; - m_ctrlport_req_portid <= req_portid [10*slave_sel +: 10]; - m_ctrlport_req_rem_epid <= req_rem_epid [16*slave_sel +: 16]; - m_ctrlport_req_rem_portid <= req_rem_portid[10*slave_sel +: 10]; - m_ctrlport_req_data <= req_data [32*slave_sel +: 32]; - m_ctrlport_req_byte_en <= req_byte_en [ 4*slave_sel +: 4]; - m_ctrlport_req_has_time <= req_has_time [slave_sel]; - m_ctrlport_req_time <= req_time [64*slave_sel +: 64]; + // ---------- Response -------------- + // Output any response to the master that made the request + for (i = 0; i < NUM_MASTERS; i = i + 1) begin + // Give the response data to all the slaves (no demux, to save logic) + s_ctrlport_resp_status[2*i +: 2] <= m_ctrlport_resp_status; + s_ctrlport_resp_data[32*i +: 32] <= m_ctrlport_resp_data; + + // Give the ack only to the master that made the request (use a demux) + if (ctrlport_rst) begin + s_ctrlport_resp_ack[i] <= 1'b0; + end else if (i == slave_sel && m_ctrlport_resp_ack) begin + s_ctrlport_resp_ack[i] <= 1'b1; end else begin - m_ctrlport_req_wr <= 1'b0; - m_ctrlport_req_rd <= 1'b0; - end - - // Output any response to the master that made the request - for (i = 0; i < NUM_MASTERS; i = i + 1) begin - // Give the response data to all the slaves (no demux, to save logic) - s_ctrlport_resp_status[2*i +: 2] <= m_ctrlport_resp_status; - s_ctrlport_resp_data[32*i +: 32] <= m_ctrlport_resp_data; - - // Give the ack only to the master that made the request (use a demux) - if (i == slave_sel && m_ctrlport_resp_ack) begin - s_ctrlport_resp_ack[i] <= 1'b1; - end else begin - s_ctrlport_resp_ack[i] <= 1'b0; - end + s_ctrlport_resp_ack[i] <= 1'b0; end end end diff --git a/lib/rfnoc/utils/ctrlport_decoder.v b/lib/rfnoc/utils/ctrlport_decoder.v index 489e208..312a920 100644 --- a/lib/rfnoc/utils/ctrlport_decoder.v +++ b/lib/rfnoc/utils/ctrlport_decoder.v @@ -101,18 +101,18 @@ module ctrlport_decoder #( // Mask WR and RD based on address decoding m_ctrlport_req_wr[i] <= s_ctrlport_req_wr & decoder[i]; m_ctrlport_req_rd[i] <= s_ctrlport_req_rd & decoder[i]; - - // Other values pass through to all slaves, but should be ignored - // unless the corresponding WR or RD is not asserted. - m_ctrlport_req_data [32*i +: 32] <= s_ctrlport_req_data; - m_ctrlport_req_byte_en [4*i +: 4] <= s_ctrlport_req_byte_en; - m_ctrlport_req_has_time[i] <= s_ctrlport_req_has_time; - m_ctrlport_req_time [64*i +: 64] <= s_ctrlport_req_time; - - // Pass through only the relevant slave bits - m_ctrlport_req_addr[20*i+:20] <= 20'b0; - m_ctrlport_req_addr[20*i+:SLAVE_ADDR_W] <= s_ctrlport_req_addr[SLAVE_ADDR_W-1:0]; end + + // Other values pass through to all slaves, but should be ignored + // unless the corresponding WR or RD is not asserted. + m_ctrlport_req_data [32*i +: 32] <= s_ctrlport_req_data; + m_ctrlport_req_byte_en [4*i +: 4] <= s_ctrlport_req_byte_en; + m_ctrlport_req_has_time[i] <= s_ctrlport_req_has_time; + m_ctrlport_req_time [64*i +: 64] <= s_ctrlport_req_time; + + // Pass through only the relevant slave bits + m_ctrlport_req_addr[20*i+:20] <= 20'b0; + m_ctrlport_req_addr[20*i+:SLAVE_ADDR_W] <= s_ctrlport_req_addr[SLAVE_ADDR_W-1:0]; end end endgenerate @@ -144,10 +144,11 @@ module ctrlport_decoder #( if (ctrlport_rst) begin s_ctrlport_resp_ack <= 0; end else begin - s_ctrlport_resp_data <= data; - s_ctrlport_resp_status <= status; - s_ctrlport_resp_ack <= ack; + s_ctrlport_resp_ack <= ack; end + + s_ctrlport_resp_data <= data; + s_ctrlport_resp_status <= status; end endmodule diff --git a/lib/rfnoc/utils/ctrlport_decoder_param.v b/lib/rfnoc/utils/ctrlport_decoder_param.v index e00c91a..1fa31b4 100644 --- a/lib/rfnoc/utils/ctrlport_decoder_param.v +++ b/lib/rfnoc/utils/ctrlport_decoder_param.v @@ -7,18 +7,18 @@ // // Description: // -// This block splits a single control port interface into multiple. It is -// used when you have a single master that needs to access multiple slaves. -// For example, a NoC block where the registers are implemented in multiple +// This block splits a single control port interface into multiple. It is +// used when you have a single master that needs to access multiple slaves. +// For example, a NoC block where the registers are implemented in multiple // submodules that must be read/written by a single NoC shell. // -// This version also implements address decoding. The request is passed to a -// slave only if the address falls within that slave's address space. Each -// slave can have a unique base address and address space size. The address +// This version also implements address decoding. The request is passed to a +// slave only if the address falls within that slave's address space. Each +// slave can have a unique base address and address space size. The address // space is broken up as follows. // // PORT_BASE[0*20 +: 20] = Port 0 base address -// │ ┐ +// │ ┐ // │ ├── 2**PORT_ADDR_W[0*32 +: 32] bytes for slave 0 // │ ┘ // . @@ -30,23 +30,23 @@ // . // . // -// When passed to the slave, the base address is stripped from the request +// When passed to the slave, the base address is stripped from the request // address so that only the PORT_ADDR_W-bit address is passed through. // // Parameters: // // NUM_SLAVES : The number of slaves to connect to a master. // -// PORT_BASE : Base addresses to use fore each slave. This is a -// concatenation of 20-bit addresses, where the right-most -// (least-significant) 20 bits corresponds to slave 0. Each -// address must be a multiple of 2**PORT_ADDR_W, where -// PORT_ADDR_W is the number of address bits allocated to that +// PORT_BASE : Base addresses to use fore each slave. This is a +// concatenation of 20-bit addresses, where the right-most +// (least-significant) 20 bits corresponds to slave 0. Each +// address must be a multiple of 2**PORT_ADDR_W, where +// PORT_ADDR_W is the number of address bits allocated to that // slave. // -// PORT_ADDR_W : Number of address bits to allocate to each slave. This is a -// concatenation of 32-bit integers, where the right-most -// (least-significant) 32 bits corresponds to the address space +// PORT_ADDR_W : Number of address bits to allocate to each slave. This is a +// concatenation of 32-bit integers, where the right-most +// (least-significant) 32 bits corresponds to the address space // for slave 0. // @@ -119,18 +119,18 @@ module ctrlport_decoder_param #( // Mask WR and RD based on address decoding m_ctrlport_req_wr[i] <= s_ctrlport_req_wr & dec_mask[i]; m_ctrlport_req_rd[i] <= s_ctrlport_req_rd & dec_mask[i]; - - // Other values pass through to all slaves, but should be ignored - // unless WR or RD is asserted. - m_ctrlport_req_data [32*i +: 32] <= s_ctrlport_req_data; - m_ctrlport_req_byte_en [4*i +: 4] <= s_ctrlport_req_byte_en; - m_ctrlport_req_has_time[i] <= s_ctrlport_req_has_time; - m_ctrlport_req_time [64*i +: 64] <= s_ctrlport_req_time; - - // Mask the address bits to that of the slaves address space. - m_ctrlport_req_addr[20*i +: 20] <= 20'b0; - m_ctrlport_req_addr[20*i +: ADDR_W] <= s_ctrlport_req_addr[ADDR_W-1 : 0]; end + + // Other values pass through to all slaves, but should be ignored + // unless WR or RD is asserted. + m_ctrlport_req_data [32*i +: 32] <= s_ctrlport_req_data; + m_ctrlport_req_byte_en [4*i +: 4] <= s_ctrlport_req_byte_en; + m_ctrlport_req_has_time[i] <= s_ctrlport_req_has_time; + m_ctrlport_req_time [64*i +: 64] <= s_ctrlport_req_time; + + // Mask the address bits to that of the slaves address space. + m_ctrlport_req_addr[20*i +: 20] <= 20'b0; + m_ctrlport_req_addr[20*i +: ADDR_W] <= s_ctrlport_req_addr[ADDR_W-1 : 0]; end end endgenerate @@ -161,10 +161,11 @@ module ctrlport_decoder_param #( if (ctrlport_rst) begin s_ctrlport_resp_ack <= 0; end else begin - s_ctrlport_resp_data <= data; - s_ctrlport_resp_status <= status; - s_ctrlport_resp_ack <= ack; + s_ctrlport_resp_ack <= ack; end + + s_ctrlport_resp_data <= data; + s_ctrlport_resp_status <= status; end endmodule diff --git a/lib/rfnoc/utils/ctrlport_gate.v b/lib/rfnoc/utils/ctrlport_gate.v index 863cefc..27c9b36 100644 --- a/lib/rfnoc/utils/ctrlport_gate.v +++ b/lib/rfnoc/utils/ctrlport_gate.v @@ -52,27 +52,28 @@ module ctrlport_gate ( `include "../core/ctrlport.vh" always @(posedge ctrlport_clk) begin + // Forward all signals by default + m_ctrlport_req_wr <= s_ctrlport_req_wr; + m_ctrlport_req_rd <= s_ctrlport_req_rd; + m_ctrlport_req_addr <= s_ctrlport_req_addr; + m_ctrlport_req_portid <= s_ctrlport_req_portid; + m_ctrlport_req_rem_epid <= s_ctrlport_req_rem_epid; + m_ctrlport_req_rem_portid <= s_ctrlport_req_rem_portid; + m_ctrlport_req_data <= s_ctrlport_req_data; + m_ctrlport_req_byte_en <= s_ctrlport_req_byte_en; + m_ctrlport_req_has_time <= s_ctrlport_req_has_time; + m_ctrlport_req_time <= s_ctrlport_req_time; + + s_ctrlport_resp_ack <= m_ctrlport_resp_ack; + s_ctrlport_resp_status <= m_ctrlport_resp_status; + s_ctrlport_resp_data <= m_ctrlport_resp_data; + + // Handle reset and disabled case if (ctrlport_rst) begin m_ctrlport_req_wr <= 1'b0; m_ctrlport_req_rd <= 1'b0; s_ctrlport_resp_ack <= 1'b0; end else begin - // Forward all signals by default - m_ctrlport_req_wr <= s_ctrlport_req_wr; - m_ctrlport_req_rd <= s_ctrlport_req_rd; - m_ctrlport_req_addr <= s_ctrlport_req_addr; - m_ctrlport_req_portid <= s_ctrlport_req_portid; - m_ctrlport_req_rem_epid <= s_ctrlport_req_rem_epid; - m_ctrlport_req_rem_portid <= s_ctrlport_req_rem_portid; - m_ctrlport_req_data <= s_ctrlport_req_data; - m_ctrlport_req_byte_en <= s_ctrlport_req_byte_en; - m_ctrlport_req_has_time <= s_ctrlport_req_has_time; - m_ctrlport_req_time <= s_ctrlport_req_time; - - s_ctrlport_resp_ack <= m_ctrlport_resp_ack; - s_ctrlport_resp_status <= m_ctrlport_resp_status; - s_ctrlport_resp_data <= m_ctrlport_resp_data; - // Overwrite default assignments in case of disabled interface if (m_ctrlport_req_rd || m_ctrlport_req_wr) begin if (~enable) begin diff --git a/lib/rfnoc/utils/ctrlport_resp_combine.v b/lib/rfnoc/utils/ctrlport_resp_combine.v index e3461cb..ca858b4 100644 --- a/lib/rfnoc/utils/ctrlport_resp_combine.v +++ b/lib/rfnoc/utils/ctrlport_resp_combine.v @@ -7,14 +7,14 @@ // // Description: // -// This module combines the control-port responses from multiple slave blocks -// into a single response for the master. This is done by using ack bit to -// mask all bits of the responses then ORing all the results together onto a -// single response bus. This is valid because only one block is allowed to +// This module combines the control-port responses from multiple slave blocks +// into a single response for the master. This is done by using ack bit to +// mask all bits of the responses then ORing all the results together onto a +// single response bus. This is valid because only one block is allowed to // respond to a single request. // -// Note that no special logic is required to split the requests from the -// master among multiple slaves. A single master request interface can be +// Note that no special logic is required to split the requests from the +// master among multiple slaves. A single master request interface can be // directly connected to all the slaves without issue. // // Parameters: @@ -40,30 +40,29 @@ module ctrlport_resp_combine #( output reg [31:0] s_ctrlport_resp_data ); - always @(posedge ctrlport_clk) begin + always @(posedge ctrlport_clk) begin : or_reg_resp + reg [31:0] data; + reg [ 1:0] status; + reg ack; + integer s; + + // Take the responses and mask them with ack then OR them together + data = 0; + status = 0; + ack = 0; + for (s = 0; s < NUM_SLAVES; s = s+1) begin + data = data | (m_ctrlport_resp_data [s*32 +: 32] & {32{m_ctrlport_resp_ack[s]}}); + status = status | (m_ctrlport_resp_status[s* 2 +: 2] & { 2{m_ctrlport_resp_ack[s]}}); + ack = ack | m_ctrlport_resp_ack[s]; + end + + // Register the output to break combinatorial path + s_ctrlport_resp_data <= data; + s_ctrlport_resp_status <= status; + s_ctrlport_resp_ack <= ack; + if (ctrlport_rst) begin - s_ctrlport_resp_data <= 0; - s_ctrlport_resp_ack <= 0; - end else begin : or_reg_resp - reg [31:0] data; - reg [ 1:0] status; - reg ack; - integer s; - - // Take the responses and mask them with ack then OR them together - data = 0; - status = 0; - ack = 0; - for (s = 0; s < NUM_SLAVES; s = s+1) begin - data = data | (m_ctrlport_resp_data [s*32 +: 32] & {32{m_ctrlport_resp_ack[s]}}); - status = status | (m_ctrlport_resp_status[s* 2 +: 2] & { 2{m_ctrlport_resp_ack[s]}}); - ack = ack | m_ctrlport_resp_ack[s]; - end - - // Register the output to break combinatorial path - s_ctrlport_resp_data <= data; - s_ctrlport_resp_status <= status; - s_ctrlport_resp_ack <= ack; + s_ctrlport_resp_ack <= 0; end end diff --git a/lib/rfnoc/utils/ctrlport_splitter.v b/lib/rfnoc/utils/ctrlport_splitter.v index bb424f3..ac2f015 100644 --- a/lib/rfnoc/utils/ctrlport_splitter.v +++ b/lib/rfnoc/utils/ctrlport_splitter.v @@ -117,12 +117,12 @@ module ctrlport_splitter #( // Register the output to break combinatorial path always @(posedge ctrlport_clk) begin : response_reg + s_ctrlport_resp_data <= data; + s_ctrlport_resp_status <= status; + s_ctrlport_resp_ack <= ack; + if (ctrlport_rst) begin s_ctrlport_resp_ack <= 0; - end else begin - s_ctrlport_resp_data <= data; - s_ctrlport_resp_status <= status; - s_ctrlport_resp_ack <= ack; end end end