From 276fa5c919786237c3b45c60fa11772cd3b4a071 Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Thu, 21 May 2020 03:34:03 -0400 Subject: [PATCH 1/2] optimize generic_queue to support simple model for smaller size queues --- hw/rtl/libs/VX_generic_queue.v | 185 +++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 78 deletions(-) diff --git a/hw/rtl/libs/VX_generic_queue.v b/hw/rtl/libs/VX_generic_queue.v index 8a89c666..ee1bb665 100644 --- a/hw/rtl/libs/VX_generic_queue.v +++ b/hw/rtl/libs/VX_generic_queue.v @@ -2,7 +2,8 @@ module VX_generic_queue #( parameter DATAW, - parameter SIZE = 16 + parameter SIZE = 16, + parameter BUFFERED_OUTPUT = (SIZE >= 8) ) ( `IGNORE_WARNINGS_BEGIN input wire clk, @@ -31,7 +32,6 @@ module VX_generic_queue #( reg [DATAW-1:0] data [SIZE-1:0]; `endif - reg [DATAW-1:0] head_r; reg [`LOG2UP(SIZE+1)-1:0] size_r; wire reading; wire writing; @@ -39,7 +39,9 @@ module VX_generic_queue #( assign reading = pop && !empty; assign writing = push && !full; - if (SIZE == 1) begin + if (SIZE == 1) begin // (SIZE == 1) + + reg [DATAW-1:0] head_r; always @(posedge clk) begin if (reset) begin @@ -58,86 +60,113 @@ module VX_generic_queue #( end end - assign data_out = head_r; - assign empty = (size_r == 0); - assign full = (size_r != 0); - assign size = size_r; + assign data_out = head_r; + assign empty = (size_r == 0); + assign full = (size_r != 0); + assign size = size_r; end else begin // (SIZE > 1) - reg [DATAW-1:0] curr_r; - reg [`LOG2UP(SIZE)-1:0] wr_ctr_r; - reg [`LOG2UP(SIZE)-1:0] rd_ptr_r; - reg [`LOG2UP(SIZE)-1:0] rd_next_ptr_r; - reg empty_r; - reg full_r; - reg bypass_r; - - always @(posedge clk) begin - if (reset) begin - wr_ctr_r <= 0; - end else begin - if (writing) - wr_ctr_r <= wr_ctr_r + 1; + if (0 == BUFFERED_OUTPUT) begin + + reg [`LOG2UP(SIZE):0] wr_ptr_r; + reg [`LOG2UP(SIZE):0] rd_ptr_r; + + wire [`LOG2UP(SIZE)-1:0] wr_ptr_a = wr_ptr_r[`LOG2UP(SIZE)-1:0]; + wire [`LOG2UP(SIZE)-1:0] rd_ptr_a = rd_ptr_r[`LOG2UP(SIZE)-1:0]; + + always @(posedge clk) begin + if (reset) begin + rd_ptr_r <= 0; + wr_ptr_r <= 0; + size_r <= 0; + end else begin + if (writing) begin + data[wr_ptr_a] <= data_in; + wr_ptr_r <= wr_ptr_r + 1; + if (!reading) begin + size_r <= size_r + 1; + end + end + + if (reading) begin + rd_ptr_r <= rd_ptr_r + 1; + if (!writing) begin + size_r <= size_r - 1; + end + end + end + end + + assign data_out = data[rd_ptr_a]; + assign empty = (wr_ptr_r == rd_ptr_r); + assign full = (wr_ptr_a == rd_ptr_a) && (wr_ptr_r[`LOG2UP(SIZE)] != rd_ptr_r[`LOG2UP(SIZE)]); + assign size = size_r; + + end else begin + + reg [DATAW-1:0] head_r; + reg [DATAW-1:0] curr_r; + reg [`LOG2UP(SIZE)-1:0] wr_ctr_r; + reg [`LOG2UP(SIZE)-1:0] rd_ptr_r; + reg [`LOG2UP(SIZE)-1:0] rd_next_ptr_r; + reg empty_r; + reg full_r; + reg bypass_r; + + always @(posedge clk) begin + if (reset) begin + size_r <= 0; + empty_r <= 1; + full_r <= 0; + wr_ctr_r <= 0; + curr_r <= 0; + rd_ptr_r <= 0; + rd_next_ptr_r <= 1; + bypass_r <= 0; + end else begin + if (writing) begin + data[wr_ctr_r] <= data_in; + wr_ctr_r <= wr_ctr_r + 1; + + if (!reading) begin + size_r <= size_r + 1; + empty_r <= 0; + if (size_r == SIZE-1) begin + full_r <= 1; + end + end + end + + if (reading) begin + if (SIZE == 2) begin + rd_ptr_r <= rd_next_ptr_r; + rd_next_ptr_r <= ~rd_next_ptr_r; + end else if (SIZE > 2) begin + rd_ptr_r <= rd_next_ptr_r; + rd_next_ptr_r <= rd_ptr_r + 2; + end + + if (!writing) begin + size_r <= size_r - 1; + if (size_r == 1) begin + empty_r <= 1; + end; + full_r <= 0; + end + end + + bypass_r <= writing && (empty_r || (1 == size_r) && reading); + curr_r <= data_in; + head_r <= data[reading ? rd_next_ptr_r : rd_ptr_r]; + end end + + assign data_out = bypass_r ? curr_r : head_r; + assign empty = empty_r; + assign full = full_r; + assign size = size_r; end - - always @(posedge clk) begin - if (reset) begin - size_r <= 0; - empty_r <= 1; - full_r <= 0; - end else begin - if (writing && !reading) begin - size_r <= size_r + 1; - empty_r <= 0; - if (size_r == SIZE-1) begin - full_r <= 1; - end - end else - if (reading && !writing) begin - size_r <= size_r - 1; - if (size_r == 1) begin - empty_r <= 1; - end; - full_r <= 0; - end - end - end - - always @(posedge clk) begin - if (writing) begin - data[wr_ctr_r] <= data_in; - end - end - - always @(posedge clk) begin - if (reset) begin - curr_r <= 0; - rd_ptr_r <= 0; - rd_next_ptr_r <= 1; - bypass_r <= 0; - end else begin - if (reading) begin - if (SIZE == 2) begin - rd_ptr_r <= rd_next_ptr_r; - rd_next_ptr_r <= ~rd_next_ptr_r; - end else if (SIZE > 2) begin - rd_ptr_r <= rd_next_ptr_r; - rd_next_ptr_r <= rd_ptr_r + 2; - end - end - - bypass_r <= writing && (empty_r || (1 == size_r) && reading); - curr_r <= data_in; - head_r <= data[reading ? rd_next_ptr_r : rd_ptr_r]; - end - end - - assign data_out = bypass_r ? curr_r : head_r; - assign empty = empty_r; - assign full = full_r; - assign size = size_r; end end From d12c40131e93609e281fed82f59d462727c7ad42 Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Thu, 21 May 2020 04:04:27 -0400 Subject: [PATCH 2/2] optimize generic_queue to support simple model for smaller size queues --- hw/rtl/libs/VX_generic_queue.v | 54 ++++++++++++++++------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/hw/rtl/libs/VX_generic_queue.v b/hw/rtl/libs/VX_generic_queue.v index ee1bb665..0a307a16 100644 --- a/hw/rtl/libs/VX_generic_queue.v +++ b/hw/rtl/libs/VX_generic_queue.v @@ -3,7 +3,7 @@ module VX_generic_queue #( parameter DATAW, parameter SIZE = 16, - parameter BUFFERED_OUTPUT = (SIZE >= 8) + parameter BUFFERED_OUTPUT = 1 ) ( `IGNORE_WARNINGS_BEGIN input wire clk, @@ -19,10 +19,10 @@ module VX_generic_queue #( ); if (SIZE == 0) begin - assign empty = 1; - assign data_out = data_in; - assign full = 0; - assign size = 0; + assign empty = 1; + assign data_out = data_in; + assign full = 0; + assign size = 0; end else begin // (SIZE > 0) @@ -45,8 +45,8 @@ module VX_generic_queue #( always @(posedge clk) begin if (reset) begin - size_r <= 0; head_r <= 0; + size_r <= 0; end else begin if (writing && !reading) begin size_r <= 1; @@ -81,7 +81,7 @@ module VX_generic_queue #( wr_ptr_r <= 0; size_r <= 0; end else begin - if (writing) begin + if (writing) begin data[wr_ptr_a] <= data_in; wr_ptr_r <= wr_ptr_r + 1; if (!reading) begin @@ -96,7 +96,7 @@ module VX_generic_queue #( end end end - end + end assign data_out = data[rd_ptr_a]; assign empty = (wr_ptr_r == rd_ptr_r); @@ -107,9 +107,9 @@ module VX_generic_queue #( reg [DATAW-1:0] head_r; reg [DATAW-1:0] curr_r; - reg [`LOG2UP(SIZE)-1:0] wr_ctr_r; + reg [`LOG2UP(SIZE)-1:0] wr_ptr_r; reg [`LOG2UP(SIZE)-1:0] rd_ptr_r; - reg [`LOG2UP(SIZE)-1:0] rd_next_ptr_r; + reg [`LOG2UP(SIZE)-1:0] rd_ptr_next_r; reg empty_r; reg full_r; reg bypass_r; @@ -119,46 +119,42 @@ module VX_generic_queue #( size_r <= 0; empty_r <= 1; full_r <= 0; - wr_ctr_r <= 0; - curr_r <= 0; + wr_ptr_r <= 0; rd_ptr_r <= 0; - rd_next_ptr_r <= 1; - bypass_r <= 0; + rd_ptr_next_r <= 1; end else begin - if (writing) begin - data[wr_ctr_r] <= data_in; - wr_ctr_r <= wr_ctr_r + 1; - - if (!reading) begin - size_r <= size_r + 1; + if (writing) begin + data[wr_ptr_r] <= data_in; + wr_ptr_r <= wr_ptr_r + 1; + if (!reading) begin empty_r <= 0; if (size_r == SIZE-1) begin full_r <= 1; end + size_r <= size_r + 1; end end if (reading) begin - if (SIZE == 2) begin - rd_ptr_r <= rd_next_ptr_r; - rd_next_ptr_r <= ~rd_next_ptr_r; + rd_ptr_r <= rd_ptr_next_r; + if (SIZE == 2) begin + rd_ptr_next_r <= ~rd_ptr_next_r; end else if (SIZE > 2) begin - rd_ptr_r <= rd_next_ptr_r; - rd_next_ptr_r <= rd_ptr_r + 2; + rd_ptr_next_r <= rd_ptr_r + 2; end - if (!writing) begin - size_r <= size_r - 1; + if (!writing) begin if (size_r == 1) begin empty_r <= 1; end; full_r <= 0; + size_r <= size_r - 1; end end bypass_r <= writing && (empty_r || (1 == size_r) && reading); - curr_r <= data_in; - head_r <= data[reading ? rd_next_ptr_r : rd_ptr_r]; + curr_r <= data_in; + head_r <= data[reading ? rd_ptr_next_r : rd_ptr_r]; end end