util_cic: Allow partial gating of CIC comb and int stages

Allow to split a CIC int or comb block into multiple stages and be able to
dynamically gate some of the stages. Also prevent carry propagation in
gated stages to keep the adder output constant.

This is useful for multi-rate filter where not all bits are needed all the
time.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2017-04-04 15:44:20 +02:00
parent 3e7325b29a
commit 17dff9ce90
2 changed files with 46 additions and 16 deletions

View File

@ -37,10 +37,13 @@
module cic_comb #(
parameter DATA_WIDTH = 32,
parameter SEQ = 1
parameter SEQ = 1,
parameter STAGE_WIDTH = 1,
parameter NUM_STAGES = 1
) (
input clk,
input ce,
input [NUM_STAGES-1:0] enable,
input [DATA_WIDTH-1:0] data_in,
output [DATA_WIDTH-1:0] data_out
);
@ -76,8 +79,10 @@ end
end
endgenerate
wire [DATA_WIDTH-1:0] mask;
reg [DATA_WIDTH-1:0] data_in_seq;
wire [DATA_WIDTH-1:0] storage_out;
wire [DATA_WIDTH-1:0] diff = (data_in_seq | ~mask) - (storage_out & mask);
always @(*) begin
if (ce == 1'b1) begin
@ -87,18 +92,19 @@ always @(*) begin
end
end
always @(posedge clk) begin
if (ce == 1'b1 || active == 1'b1) begin
state <= data_in_seq - storage_out;
end
end
generate
genvar i;
genvar i, j;
for (i = 0; i < DATA_WIDTH; i = i + 1) begin: shift_r
for (j = 0; j < NUM_STAGES; j = j + 1) begin
localparam k = NUM_STAGES - j - 1;
localparam H = DATA_WIDTH - STAGE_WIDTH * j - 1;
localparam L = k == 0 ? 0 : DATA_WIDTH - STAGE_WIDTH * (j+1);
assign mask[H:L] = {{H-L{1'b1}},k != 0 ? enable[k] : 1'b1};
for (i = L; i <= H; i = i + 1) begin: shift_r
always @(posedge clk) begin
if (ce == 1'b1 || active == 1'b1) begin
if (enable[k] == 1'b1 && (ce == 1'b1 || active == 1'b1)) begin
if (SEQ > 1) begin
storage[i] <= {storage[i][SEQ-2:0],data_in_seq[i]};
end else begin
@ -108,7 +114,16 @@ generate
end
assign storage_out[i] = storage[i][SEQ-1];
end
always @(posedge clk) begin
if (enable[k] == 1'b1 && (ce == 1'b1 || active == 1'b1)) begin
state[H:L] <= diff[H:L];
end
end
end
endgenerate
assign data_out = state;

View File

@ -36,24 +36,39 @@
// ***************************************************************************
module cic_int #(
parameter DATA_WIDTH = 12
parameter DATA_WIDTH = 12,
parameter STAGE_WIDTH = 1,
parameter NUM_STAGES = 1
) (
input clk,
input ce,
input [NUM_STAGES-1:0] ce,
input [DATA_WIDTH-1:0] data_in,
output [DATA_WIDTH-1:0] data_out
);
reg [DATA_WIDTH-1:0] state = 'h00;
wire [DATA_WIDTH-1:0] sum;
wire [DATA_WIDTH-1:0] mask;
assign data_out = state;
assign sum = data_in + state;
assign sum = (data_in & mask) + (state & mask);
generate
genvar i;
always @(posedge clk) begin
if (ce == 1'b1) begin
state <= sum;
for (i = 0; i < NUM_STAGES; i = i + 1) begin
localparam j = NUM_STAGES - i - 1;
localparam H = DATA_WIDTH - STAGE_WIDTH * i - 1;
localparam L = j == 0 ? 0 : DATA_WIDTH - STAGE_WIDTH * (i+1);
assign mask[H:L] = {{H-L{1'b1}},j != 0 ? ce[j] : 1'b1};
always @(posedge clk) begin
if (ce[j] == 1'b1) begin
state[H:L] <= sum[H:L];
end
end
end
endgenerate
endmodule