`define LFSR_HIGH_16BIT_ENABLE module LFSR #(parameter NUM_BITS) ( input i_Clk, input i_Enable, //Optional Seed Value input i_Seed_DV, input [NUM_BITS-1:0] i_Seed_Data, output[NUM_BITS-1:0] o_LFSR_Data, output o_LFSR_Done ); reg [NUM_BITS:1] r_LFSR = 0; reg r_XNOR; always @(posedge i_Clk or negedge i_Enable) begin if(~i_Enable) begin r_LFSR <= i_Seed_Data; end else if (i_Seed_DV == 1'b1) begin r_LFSR <= i_Seed_Data; end else begin r_LFSR <= {r_LFSR[NUM_BITS-1:1],r_XNOR}; end end // Linear Feedback Shift Register Taps refer to https://docs.xilinx.com/v/u/en-US/xapp052 // use same or becaure the default seed can be '0, and should not be '1 always @(*) begin case (NUM_BITS) 2: begin r_XNOR = r_LFSR[2] ^ ~r_LFSR[1]; end 3: begin r_XNOR = r_LFSR[3] ^ ~r_LFSR[2]; end 4: begin r_XNOR = r_LFSR[4] ^ ~r_LFSR[3]; end 5: begin r_XNOR = r_LFSR[5] ^ ~r_LFSR[3]; end 6: begin r_XNOR = r_LFSR[6] ^ ~r_LFSR[5]; end 7: begin r_XNOR = r_LFSR[7] ^ ~r_LFSR[6]; end 8: begin r_XNOR = r_LFSR[8] ^ ~r_LFSR[6] ^ ~r_LFSR[5] ^ ~r_LFSR[4]; end 9: begin r_XNOR = r_LFSR[9] ^ ~r_LFSR[5]; end 10: begin r_XNOR = r_LFSR[10] ^ ~r_LFSR[7]; end 11: begin r_XNOR = r_LFSR[11] ^ ~r_LFSR[9]; end 12: begin r_XNOR = r_LFSR[12] ^ ~r_LFSR[6] ^ ~r_LFSR[4] ^ ~r_LFSR[1]; end 13: begin r_XNOR = r_LFSR[13] ^ ~r_LFSR[4] ^ ~r_LFSR[3] ^ ~r_LFSR[1]; end 14: begin r_XNOR = r_LFSR[14] ^ ~r_LFSR[5] ^ ~r_LFSR[3] ^ ~r_LFSR[1]; end 15: begin r_XNOR = r_LFSR[15] ^ ~r_LFSR[14]; end 16: begin r_XNOR = r_LFSR[16] ^ ~r_LFSR[15] ^ ~r_LFSR[13] ^ ~r_LFSR[4]; end `ifdef LFSR_HIGH_16BIT_ENABLE 17: begin r_XNOR = r_LFSR[17] ^ ~r_LFSR[14]; end 18: begin r_XNOR = r_LFSR[18] ^ ~r_LFSR[11]; end 19: begin r_XNOR = r_LFSR[19] ^ ~r_LFSR[6] ^ ~r_LFSR[2] ^ ~r_LFSR[1]; end 20: begin r_XNOR = r_LFSR[20] ^ ~r_LFSR[17]; end 21: begin r_XNOR = r_LFSR[21] ^ ~r_LFSR[19]; end 22: begin r_XNOR = r_LFSR[22] ^ ~r_LFSR[21]; end 23: begin r_XNOR = r_LFSR[23] ^ ~r_LFSR[18]; end 24: begin r_XNOR = r_LFSR[24] ^ ~r_LFSR[23] ^ ~r_LFSR[22] ^ ~r_LFSR[17]; end 25: begin r_XNOR = r_LFSR[25] ^ ~r_LFSR[22]; end 26: begin r_XNOR = r_LFSR[26] ^ ~r_LFSR[6] ^ ~r_LFSR[2] ^ ~r_LFSR[1]; end 27: begin r_XNOR = r_LFSR[27] ^ ~r_LFSR[5] ^ ~r_LFSR[2] ^ ~r_LFSR[1]; end 28: begin r_XNOR = r_LFSR[28] ^ ~r_LFSR[25]; end 29: begin r_XNOR = r_LFSR[29] ^ ~r_LFSR[27]; end 30: begin r_XNOR = r_LFSR[30] ^ ~r_LFSR[6] ^ ~r_LFSR[4] ^ ~r_LFSR[1]; end 31: begin r_XNOR = r_LFSR[31] ^ ~r_LFSR[28]; end 32: begin r_XNOR = r_LFSR[32] ^ ~r_LFSR[22] ^ ~r_LFSR[2] ^ ~r_LFSR[1]; end 64: begin r_XNOR = r_LFSR[64] ^ ~r_LFSR[63] ^ ~r_LFSR[61] ^ ~r_LFSR[60]; end 80: begin r_XNOR = r_LFSR[80] ^ ~r_LFSR[79] ^ ~r_LFSR[43] ^ ~r_LFSR[42]; end 128: begin r_XNOR = r_LFSR[128] ^ ~r_LFSR[126] ^ ~r_LFSR[101] ^ ~r_LFSR[99]; end 168: begin r_XNOR = r_LFSR[168] ^ ~r_LFSR[166] ^ ~r_LFSR[153] ^ ~r_LFSR[151]; end `endif default: begin r_XNOR = '0; end endcase end assign o_LFSR_Data = r_LFSR[NUM_BITS:1]; assign o_LFSR_Done = (r_LFSR[NUM_BITS:1] == i_Seed_Data) ? 1'b1 : 1'b0; endmodule module id_pool_2w1r #( parameter depth=8, parameter width=32, parameter ptr_sz=$clog2(depth) ) ( input logic clk, input logic rst_n, input logic [1:0] c_srdy, output logic [1:0] c_drdy, input logic [1:0][width-1:0] c_data, output logic p_srdy, input logic p_drdy, output logic [width-1:0] p_data, output logic [ptr_sz:0] usage ); localparam depth_sub_1 = depth-1; localparam depth_sub_2 = depth-2; logic [ptr_sz-1:0] wr_addr_d; logic [ptr_sz-1:0] rd_addr_d; logic [ptr_sz-1:0] wr_addr_q; logic [ptr_sz-1:0] rd_addr_q; logic [depth-1:0][width-1:0] array_d; logic [depth-1:0][width-1:0] array_q; logic [ptr_sz:0] occupy_cnt_d; logic [ptr_sz:0] occupy_cnt_q; logic full; logic empty; logic wr_2_en; logic wr_2_vld; logic wr_en; logic rd_en; logic [ptr_sz-1:0] wr_addr_p1; assign c_drdy = wr_2_vld ? 2'b11 : (occupy_cnt_q == depth_sub_1) ? ((c_srdy == 2'b10) ? 2'b10 : 2'b01) : '0; assign p_srdy = ~empty; assign p_data = array_q[rd_addr_q]; assign empty = (occupy_cnt_q == '0); assign full = (occupy_cnt_q == depth[ptr_sz:0]); assign rd_en = p_drdy & ~empty; assign wr_en = (c_srdy[0] | c_srdy[1]) & ~full; assign wr_2_vld = (occupy_cnt_q < depth_sub_1); assign wr_2_en = (c_srdy == 2'b11) & wr_2_vld; assign rd_addr_d = rd_en ? ((rd_addr_q == depth_sub_1) ? '0 : rd_addr_q+1) : rd_addr_q; assign wr_addr_p1 = (wr_addr_q == depth_sub_1) ? '0 : wr_addr_q+1; assign wr_addr_d = wr_2_en ? ((wr_addr_q == depth_sub_1) ? ptr_sz'('d1) : (wr_addr_q == depth_sub_2) ? '0 : wr_addr_q+2) : wr_en ? wr_addr_p1 : wr_addr_q; always_comb begin occupy_cnt_d = occupy_cnt_q; case ({wr_2_en,wr_en,rd_en}) 3'b110: begin occupy_cnt_d = occupy_cnt_q+{{(ptr_sz-1){1'b0}},2'd2}; end 3'b111: begin occupy_cnt_d = occupy_cnt_q+{{(ptr_sz){1'b0}},1'b1}; end 3'b010: begin occupy_cnt_d = occupy_cnt_q+{{(ptr_sz){1'b0}},1'b1}; end 3'b001: begin occupy_cnt_d = occupy_cnt_q-{{(ptr_sz){1'b0}},1'b1}; end endcase end std_dffr #(ptr_sz) FF_WR_ADDR (.clk(clk) ,.rstn(rst_n),.d(wr_addr_d),.q(wr_addr_q)); std_dffr #(ptr_sz) FF_RD_ADDR (.clk(clk) ,.rstn(rst_n),.d(rd_addr_d),.q(rd_addr_q)); std_dffrve #(ptr_sz+1) FF_OCCUPY_CNT (.clk(clk),.rstn(rst_n),.rst_val(depth),.en(1'b1),.d(occupy_cnt_d),.q(occupy_cnt_q)); generate for (genvar ii=0; ii rff_last_grt_id) begin // vld_with_priority[i - rff_last_grt_id - 1'b1] = vld[i]; // end else begin // vld_with_priority[N_INPUT - rff_last_grt_id - 1'b1 + i] = vld[i]; // end // end // end // end // //grt_with_priority // always_comb begin // grt_with_priority = {N_INPUT{1'b0}}: // if (|vld_with_priority) begin // for (int i = 0; i < N_INPUT; i++) begin // if (vld_with_priority[i] == 1'b1) begin // grt_with_priority[i] = 1'b1; // break; // end // end // end // end // // next_grt // always_comb begin // if(rff_last_grt_id == N_INPUT_BITS'(N_INPUT-1)) begin // next_grt = grt_with_priority; // end else begin // for(int i = 0; i < N_INPUT;i++) begin // if(i > rff_last_grt_id) begin // next_grt[i] = grt_with_priority[i - rff_last_grt_id - 1'b1]; // end else begin // next_grt[i] = grt_with_priority[N_INPUT - rff_last_grt_id - 1'b1 + i]; // end // end // end // end // // Grant Update // always_ff @(posedge clk or negedge rstn) begin // if (!rstn) begin // rff_grt <= '0; // end else begin // if (do_save_grt) begin // rff_grt <= grt; // end // end // end // always_ff @(posedge clk or negedge rstn ) begin // if (!rstn) begin // rff_last_grt_id <= N_INPUT_BITS'(N_INPUT-1); // end else begin // if ((|grt) & rdy) begin // rff_last_grt_id <= grt_id; // end // end // end // always_ff @(posedge clk or negedge rstn) begin // if(!rstn) begin // rff_state <= ST_PASS_THROUGH; // end else begin // rff_state <= next_state; // end // end // always_comb begin // case (rff_state) // ST_HOLD: begin // do_save_grt = '0; // if (rdy) begin // next_state = ST_PASS_THROUGH; // end else begin // next_state = ST_HOLD; // end // end // default: begin // if((|grt) & ~rdy) begin // do_save_grt = '1; // next_state = ST_HOLD; // end else begin // do_save_grt = '0; // next_state = ST_PASS_THROUGH; // end // end // endcase // end // assign grt = (rff_state == ST_HOLD) ? rff_grt: next_grt; // end // endgenerate //endmodule