`include "../VX_define.v" module VX_priority_encoder_sm #( parameter NB = 4, parameter BITS_PER_BANK = 3, parameter NUM_REQ = 3 ) ( //INPUTS input wire clk, input wire reset, input wire[`NT_M1:0] in_valid, input wire[`NT_M1:0][31:0] in_address, input wire[`NT_M1:0][31:0] in_data, // OUTPUTS // To SM Module output reg[NB:0] out_valid, output reg[NB:0][31:0] out_address, output reg[NB:0][31:0] out_data, // To Processor output wire[NB:0][`CLOG2(NUM_REQ) - 1:0] req_num, output reg stall, output wire send_data // Finished all of the requests ); reg[`NT_M1:0] left_requests; reg[`NT_M1:0] serviced; wire[`NT_M1:0] use_valid; wire requests_left = (|left_requests); assign use_valid = (requests_left) ? left_requests : in_valid; wire[NB:0][`NT_M1:0] bank_valids; VX_bank_valids #(.NB(NB), .BITS_PER_BANK(BITS_PER_BANK)) vx_bank_valid( .in_valids(use_valid), .in_addr(in_address), .bank_valids(bank_valids) ); wire[NB:0] more_than_one_valid; genvar curr_bank; generate for (curr_bank = 0; curr_bank <= NB; curr_bank = curr_bank + 1) begin wire[`CLOG2(`NT):0] num_valids; VX_countones #(.N(`NT)) valids_counter ( .valids(bank_valids[curr_bank]), .count (num_valids) ); assign more_than_one_valid[curr_bank] = num_valids > 1; // assign more_than_one_valid[curr_bank] = $countones(bank_valids[curr_bank]) > 1; end endgenerate assign stall = (|more_than_one_valid); assign send_data = (!stall) && (|in_valid); // change wire[NB:0][(`CLOG2(NUM_REQ)) - 1:0] internal_req_num; wire[NB:0] internal_out_valid; // There's one or less valid per bank genvar curr_bank_o; for (curr_bank_o = 0; curr_bank_o <= NB; curr_bank_o = curr_bank_o + 1) begin VX_generic_priority_encoder #(.N(NUM_REQ)) vx_priority_encoder( .valids(bank_valids[curr_bank_o]), .index(internal_req_num[curr_bank_o]), .found(internal_out_valid[curr_bank_o]) ); assign out_address[curr_bank_o] = internal_out_valid[curr_bank_o] ? in_address[internal_req_num[curr_bank_o]] : 0; assign out_data[curr_bank_o] = internal_out_valid[curr_bank_o] ? in_data[internal_req_num[curr_bank_o]] : 0; end integer curr_b; always @(*) begin serviced = 0; for (curr_b = 0; curr_b <= NB; curr_b=curr_b+1) begin serviced[internal_req_num[curr_b]] = 1; end end assign req_num = internal_req_num; assign out_valid = internal_out_valid; wire[`NT_M1:0] serviced_qual = in_valid & (serviced); wire[`NT_M1:0] new_left_requests = (left_requests == 0) ? (in_valid & ~serviced_qual) : (left_requests & ~ serviced_qual); // wire[`NT_M1:0] new_left_requests = left_requests & ~(serviced_qual); always @(posedge clk, posedge reset) begin if (reset) begin left_requests <= 0; // serviced = 0; end else begin if (!stall) left_requests <= 0; else left_requests <= new_left_requests; end end endmodule